arch-power: Fix load-store instructions
authorSandipan Das <sandipan@linux.ibm.com>
Sat, 6 Feb 2021 11:47:08 +0000 (17:17 +0530)
committerSandipan Das <sandipan@linux.ibm.com>
Mon, 15 Feb 2021 08:32:38 +0000 (14:02 +0530)
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 <sandipan@linux.ibm.com>
src/arch/power/isa/decoder.isa
src/arch/power/isa/formats/mem.isa
src/arch/power/isa/formats/util.isa

index b9fc811678ab4bd22c0cdc2e0a91076b6df8b61c..e2b392961ee7d9a71c48f568bf4b47d4a2344f7b 100644 (file)
@@ -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 {
index 1f625714313b314d82341a931d0cdb223795f72d..1dd985406da6792830431333a8dfc5ecc3783ba4 100644 (file)
@@ -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')
 }};
index 99daeb34d120fb7541de2b233e8c590287bc7e78..f836a1d691f68fb372091efca380e04771c9b84e 100644 (file)
@@ -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,