ISACaller/parser: kludge: support (RA|0) when elwidth != 64
authorJacob Lifshay <programmerjake@gmail.com>
Wed, 29 Nov 2023 06:13:25 +0000 (22:13 -0800)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 22 Dec 2023 19:26:21 +0000 (19:26 +0000)
https://bugs.libre-soc.org/show_bug.cgi?id=1221

src/openpower/decoder/isa/caller.py
src/openpower/decoder/pseudo/parser.py
src/openpower/test/alu/svp64_cases.py

index 9a8c24817c27f77ea51003ab2ecd1af39e271a93..3882193d61d4f0ec43daa61bcf92e36c1d5a7a6d 100644 (file)
@@ -217,9 +217,13 @@ class GPR(dict):
             rnum = rnum.value
         dict.__setitem__(self, rnum, value)
 
-    def getz(self, rnum):
+    def getz(self, rnum, rvalue=None):
         # rnum = rnum.value # only SelectableInt allowed
-        log("GPR getzero?", rnum)
+        log("GPR getzero?", rnum, rvalue)
+        if rvalue is not None:
+            if rnum == 0:
+                return SelectableInt(0, rvalue.bits)
+            return rvalue
         if rnum == 0:
             return SelectableInt(0, 64)
         return self[rnum]
@@ -2571,8 +2575,12 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
         regname = "_" + name
         if not self.is_svp64_mode or ew_src == 64:
             self.namespace[regname] = regnum
-        elif regname in self.namespace:
-            del self.namespace[regname]
+        else:
+            # FIXME: we're trying to access a sub-register, plain register
+            # numbers don't work for that.  for now, just pass something that
+            # can be compared to 0 and probably will cause an error if misused.
+            # see https://bugs.libre-soc.org/show_bug.cgi?id=1221
+            self.namespace[regname] = regnum * 10000
 
         if not self.is_svp64_mode or not self.pred_src_zero:
             log('reading reg %s %s' % (name, str(regnum)), is_vec)
index b1086440a1d8f17f3944cf10af9657d49fc8d5ab..2d113f6ee3d9124b3d8a95e57e3639cbf8bf88e0 100644 (file)
@@ -754,7 +754,8 @@ class PowerParser:
                 gprz = ast.Attribute(gprz, "getz", ast.Load())
                 # *sigh* see class GPR.  we need index itself not reg value
                 ridx = ast.Name("_%s" % rid, ast.Load())
-                p[0] = ast.Call(gprz, [ridx], [])
+                rvalue = ast.Name(rid, ast.Load())
+                p[0] = ast.Call(gprz, [ridx, rvalue], [])
                 print("tree", astor.dump_tree(p[0]))
             else:
                 p[0] = p[2]
index 638da111a93d2865d75e7de65fb52476d5ecf634..b41ebab225a14b980971f1d143693d2544510bec 100644 (file)
@@ -61,6 +61,32 @@ class SVP64ALUElwidthTestCase(TestAccumulatorBase):
                       initial_svstate=svstate, expected=e)
 
 
+    def case_sv_addi_test_ra_0_sw_8(self):
+        """test of (RA|0) with sw=8"""
+        l = ['sv.addi/sw=8 *4, *12, 0x12',
+             'sv.addi/sw=8 *8, *0, 0xAB']
+        prog = Program(list(SVP64Asm(l)), bigendian)
+
+        initial_regs = [0] * 32
+        initial_regs[12] = 0x123456789ABCDEF
+
+        svstate = SVP64State()
+        svstate.vl = 4  # VL
+        svstate.maxvl = 4  # MAXVL
+
+        e = ExpectedState(pc=0x10, int_regs=initial_regs)
+        e.intregs[4] = 0xEF + 0x12
+        e.intregs[5] = 0xCD + 0x12
+        e.intregs[6] = 0xAB + 0x12
+        e.intregs[7] = 0x89 + 0x12
+        e.intregs[8] = 0xAB
+        e.intregs[9] = 0xAB
+        e.intregs[10] = 0xAB
+        e.intregs[11] = 0xAB
+
+        self.add_case(prog, initial_regs, initial_svstate=svstate, expected=e)
+
+
     def case_2_sv_add_ew32(self):
         """>>> lst = ['sv.add/w=32 *1, *5, *9']
         """