From 88d55cff664c8a6bde54071352c9a48c1a8e71b9 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 --- src/arch/power/isa/decoder.isa | 20 ++++++++++---------- src/arch/power/isa/formats/mem.isa | 4 ++++ src/arch/power/isa/formats/util.isa | 20 ++++++++++++++++++++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/arch/power/isa/decoder.isa b/src/arch/power/isa/decoder.isa index b9fc81167..e2b392961 100644 --- a/src/arch/power/isa/decoder.isa +++ b/src/arch/power/isa/decoder.isa @@ -128,7 +128,7 @@ decode PO default Unknown::unknown() { 34: lbz({{ Rt = Mem_ub; }}); 40: lhz({{ Rt = Mem_uh; }}); 42: lha({{ Rt = Mem_sh; }}); - 32: lwz({{ Rt = Mem; }}); + 32: lwz({{ Rt = Mem_uw; }}); } 58: decode DS_XO { @@ -141,19 +141,19 @@ decode PO default Unknown::unknown() { 35: lbzu({{ Rt = Mem_ub; }}); 41: lhzu({{ Rt = Mem_uh; }}); 43: lhau({{ Rt = Mem_sh; }}); - 33: lwzu({{ Rt = Mem; }}); + 33: lwzu({{ Rt = Mem_uw; }}); } format StoreDispOp { 38: stb({{ Mem_ub = Rs_ub; }}); 44: sth({{ Mem_uh = Rs_uh; }}); - 36: stw({{ Mem = Rs; }}); + 36: stw({{ Mem_uw = Rs_uw; }}); } format StoreDispUpdateOp { 39: stbu({{ Mem_ub = Rs_ub; }}); 45: sthu({{ Mem_uh = Rs_uh; }}); - 37: stwu({{ Mem = Rs; }}); + 37: stwu({{ Mem_uw = Rs_uw; }}); } format IntImmArithCheckRaOp { @@ -233,9 +233,9 @@ decode PO default Unknown::unknown() { 87: lbzx({{ Rt = Mem_ub; }}); 279: lhzx({{ Rt = Mem_uh; }}); 343: lhax({{ Rt = Mem_sh; }}); - 23: lwzx({{ Rt = Mem; }}); + 23: lwzx({{ Rt = Mem_uw; }}); 341: lwax({{ Rt = Mem_sw; }}); - 20: lwarx({{ Rt = Mem_sw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }}); + 20: lwarx({{ Rt = Mem_uw; Rsv = 1; RsvLen = 4; RsvAddr = EA; }}); 535: lfsx({{ Ft_sf = Mem_sf; }}); 599: lfdx({{ Ft = Mem_df; }}); 855: lfiwax({{ Ft_uw = Mem; }}); @@ -245,7 +245,7 @@ decode PO default Unknown::unknown() { 119: lbzux({{ Rt = Mem_ub; }}); 311: lhzux({{ Rt = Mem_uh; }}); 375: lhaux({{ Rt = Mem_sh; }}); - 55: lwzux({{ Rt = Mem; }}); + 55: lwzux({{ Rt = Mem_uw; }}); 373: lwaux({{ Rt = Mem_sw; }}); 567: lfsux({{ Ft_sf = Mem_sf; }}); 631: lfdux({{ Ft = Mem_df; }}); @@ -254,10 +254,10 @@ decode PO default Unknown::unknown() { format StoreIndexOp { 215: stbx({{ Mem_ub = Rs_ub; }}); 407: sthx({{ Mem_uh = Rs_uh; }}); - 151: stwx({{ Mem = Rs; }}); + 151: stwx({{ Mem_uw = Rs_uw; }}); 150: stwcx({{ bool store_performed = false; - Mem = Rs; + Mem_uw = Rs_uw; if (Rsv) { if (RsvLen == 4) { if (RsvAddr == EA) { @@ -276,7 +276,7 @@ decode PO default Unknown::unknown() { format StoreIndexUpdateOp { 247: stbux({{ Mem_ub = Rs_ub; }}); 439: sthux({{ Mem_uh = Rs_uh; }}); - 183: stwux({{ Mem = Rs; }}); + 183: stwux({{ Mem_uw = Rs_uw; }}); } format IntOp { diff --git a/src/arch/power/isa/formats/mem.isa b/src/arch/power/isa/formats/mem.isa index 1f6257143..1dd985406 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 + disp; }}, (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 + disp; }}, (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 99daeb34d..f836a1d69 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, -- 2.30.2