From 34f8d9e999ca352e06898ae0f6ab42c42ee55478 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Tue, 28 Nov 2023 22:13:25 -0800 Subject: [PATCH] ISACaller/parser: kludge: support (RA|0) when elwidth != 64 https://bugs.libre-soc.org/show_bug.cgi?id=1221 --- src/openpower/decoder/isa/caller.py | 16 ++++++++++++---- src/openpower/decoder/pseudo/parser.py | 3 ++- src/openpower/test/alu/svp64_cases.py | 26 ++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index 9a8c2481..3882193d 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -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) diff --git a/src/openpower/decoder/pseudo/parser.py b/src/openpower/decoder/pseudo/parser.py index b1086440..2d113f6e 100644 --- a/src/openpower/decoder/pseudo/parser.py +++ b/src/openpower/decoder/pseudo/parser.py @@ -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] diff --git a/src/openpower/test/alu/svp64_cases.py b/src/openpower/test/alu/svp64_cases.py index 638da111..b41ebab2 100644 --- a/src/openpower/test/alu/svp64_cases.py +++ b/src/openpower/test/alu/svp64_cases.py @@ -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'] """ -- 2.30.2