From 2600ac281e6a5a601fe847d385ddb8ba5f29916b Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Sat, 6 Feb 2021 17:17:08 +0530 Subject: [PATCH] arch-power: Fix load-store instructions Now that 64-bit registers and operands are being used, the instructions for words must read or write just one word at a time. This fixes the following instructions. * Load Word and Zero (lwz) * Load Word and Zero Indexed (lwzx) * Load Word and Zero with Update (lwzu) * Load Word and Zero with Update Indexed (lwzux) * Load Word And Reserve Indexed (lwarx) * Store Word (stw) * Store Word Indexed (stwx) * Store Word with Update (stwu) * Store Word with Update Indexed (stwux) * Store Word Conditional Indexed (stwcx.) This also fixes decoding of load-store update instructions for some special scenarios when RA is zero or RA and RT are the same. In such cases, the instruction is considered invalid. Change-Id: I6787d3614ba8f1b1cbf30a49f85ef422324d7c21 Signed-off-by: Sandipan Das Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40893 Reviewed-by: Boris Shingarov Maintainer: Jason Lowe-Power Tested-by: kokoro --- src/arch/power/isa/decoder.isa | 22 +++++++++++++--------- src/arch/power/isa/formats/mem.isa | 4 ++++ src/arch/power/isa/formats/util.isa | 20 ++++++++++++++++++++ 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa index 0cf6201cac..c81e65be46 100644 --- a/src/arch/power/isa/decoder.isa +++ b/src/arch/power/isa/decoder.isa @@ -196,8 +196,12 @@ decode PO default Unknown::unknown() { }}); format LoadIndexOp { - 20: lwarx({{ Rt = Mem_sw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }}); - 23: lwzx({{ Rt = Mem; }}); + 20: lwarx({{ + Rt = Mem_uw; + Rsv = 1; RsvLen = 4; RsvAddr = EA; + }}); + + 23: lwzx({{ Rt = Mem_uw; }}); } format IntLogicOp { @@ -219,7 +223,7 @@ decode PO default Unknown::unknown() { CR = insertCRField(CR, BF, cr); }}); - 55: LoadIndexUpdateOp::lwzux({{ Rt = Mem; }}); + 55: LoadIndexUpdateOp::lwzux({{ Rt = Mem_uw; }}); 60: IntLogicOp::andc({{ Ra = Rs & ~Rb; }}); 87: LoadIndexOp::lbzx({{ Rt = Mem_ub; }}); 119: LoadIndexUpdateOp::lbzux({{ Rt = Mem_ub; }}); @@ -228,7 +232,7 @@ decode PO default Unknown::unknown() { format StoreIndexOp { 150: stwcx({{ bool store_performed = false; - Mem = Rs; + Mem_uw = Rs_uw; if (Rsv) { if (RsvLen == 4) { if (RsvAddr == EA) { @@ -243,7 +247,7 @@ decode PO default Unknown::unknown() { Rsv = 0; }}); - 151: stwx({{ Mem = Rs; }}); + 151: stwx({{ Mem_uw = Rs_uw; }}); } 183: StoreIndexUpdateOp::stwux({{ Mem = Rs; }}); @@ -515,12 +519,12 @@ decode PO default Unknown::unknown() { } } - 32: LoadDispOp::lwz({{ Rt = Mem; }}); - 33: LoadDispUpdateOp::lwzu({{ Rt = Mem; }}); + 32: LoadDispOp::lwz({{ Rt = Mem_uw; }}); + 33: LoadDispUpdateOp::lwzu({{ Rt = Mem_uw; }}); 34: LoadDispOp::lbz({{ Rt = Mem_ub; }}); 35: LoadDispUpdateOp::lbzu({{ Rt = Mem_ub; }}); - 36: StoreDispOp::stw({{ Mem = Rs; }}); - 37: StoreDispUpdateOp::stwu({{ Mem = Rs; }}); + 36: StoreDispOp::stw({{ Mem_uw = Rs_uw; }}); + 37: StoreDispUpdateOp::stwu({{ Mem_uw = Rs_uw; }}); 38: StoreDispOp::stb({{ Mem_ub = Rs_ub; }}); 39: StoreDispUpdateOp::stbu({{ Mem_ub = Rs_ub; }}); 40: LoadDispOp::lhz({{ Rt = Mem_uh; }}); diff --git a/src/arch/power/isa/formats/mem.isa b/src/arch/power/isa/formats/mem.isa index 8e6567dfda..d2b3ab7cab 100644 --- a/src/arch/power/isa/formats/mem.isa +++ b/src/arch/power/isa/formats/mem.isa @@ -263,6 +263,7 @@ def format LoadIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, base_class = 'MemIndexOp', + decode_template = CheckRaRtDecode, exec_template_base = 'Load') }}; @@ -277,6 +278,7 @@ def format StoreIndexUpdateOp(memacc_code, ea_code = {{ EA = Ra + Rb; }}, (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, base_class = 'MemIndexOp', + decode_template = CheckRaZeroDecode, exec_template_base = 'Store') }}; @@ -319,6 +321,7 @@ def format LoadDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + d; }}, (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, base_class = 'MemDispOp', + decode_template = CheckRaRtDecode, exec_template_base = 'Load') }}; @@ -333,5 +336,6 @@ def format StoreDispUpdateOp(memacc_code, ea_code = {{ EA = Ra + d; }}, (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, base_class = 'MemDispOp', + decode_template = CheckRaZeroDecode, exec_template_base = 'Store') }}; diff --git a/src/arch/power/isa/formats/util.isa b/src/arch/power/isa/formats/util.isa index 529d07b27e..dbc6150b50 100644 --- a/src/arch/power/isa/formats/util.isa +++ b/src/arch/power/isa/formats/util.isa @@ -123,6 +123,26 @@ def template CheckBoLkDecode {{ } }}; +def template CheckRaRtDecode {{ + { + if ((RA == 0) || (RA == RT)) { + return new Unknown(machInst); + } else { + return new %(class_name)s(machInst); + } + } +}}; + +def template CheckRaZeroDecode {{ + { + if (RA == 0) { + return new Unknown(machInst); + } else { + return new %(class_name)s(machInst); + } + } +}}; + let {{ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,