From 7d9ad8df1a0c599e5a547e37b5c24a1dc04df11c Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 9 Oct 2022 00:11:15 +0100 Subject: [PATCH] add elwidth overrides on destination (write) in ISACaller. first two unit tests pass (sv.add/ew=8, sv.add/ew=32) --- src/openpower/decoder/isa/caller.py | 168 ++++++++++++++++++-------- src/openpower/test/alu/svp64_cases.py | 35 ++++++ 2 files changed, 152 insertions(+), 51 deletions(-) diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index 4842cda1..3822de35 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -125,12 +125,52 @@ class GPR(dict): def __call__(self, ridx, is_vec=False, offs=0, elwidth=64): if isinstance(ridx, SelectableInt): ridx = ridx.value - log("GPR call", ridx, "isvec", is_vec, "offs", offs, "elwid", elwidth) - return self[ridx] + if elwidth == 64: + return self[ridx] + # rrrright. start by breaking down into row/col, based on elwidth + gpr_offs = offs // (64//elwidth) + gpr_col = offs % (64//elwidth) + # now select the 64-bit register, but get its value (easier) + val = self[ridx+gpr_offs].value + # now shift down and mask out + val = val >> (gpr_col*elwidth) & ((1< 64: output = SelectableInt(output.value, 64) if name in fregs: - self.fpr[regnum] = output + self.fpr.write(regnum, output, is_vec, ew_dst) else: - self.gpr[regnum] = output + self.gpr.write(regnum, output, is_vec, ew_dst) def check_step_increment(self, rc_en, asmop, ins_name): # check if it is the SVSTATE.src/dest step that needs incrementing diff --git a/src/openpower/test/alu/svp64_cases.py b/src/openpower/test/alu/svp64_cases.py index 5c7b5efe..6c4b5289 100644 --- a/src/openpower/test/alu/svp64_cases.py +++ b/src/openpower/test/alu/svp64_cases.py @@ -34,6 +34,41 @@ class SVP64ALUElwidthTestCase(TestAccumulatorBase): initial_svstate=svstate, expected=e) + def case_2_sv_add_ew32(self): + """>>> lst = ['sv.add/w=32 *1, *5, *9'] + """ + isa = SVP64Asm(['sv.add/w=32 *1, *5, *9']) + lst = list(isa) + print("listing", lst) + + # initial values in GPR regfile + initial_regs = [0] * 32 + initial_regs[9] = 0x1000_1000_f000_1220 + initial_regs[10] = 0x2000_2000_8000_1111 + initial_regs[5] = 0x8000_43ff + initial_regs[6] = 0x9000_0000_0000_2223 + initial_regs[2] = 0x0000_0001_0000_0002 + # SVSTATE (in this case, VL=2) + svstate = SVP64State() + svstate.vl = 3 # VL + svstate.maxvl = 3 # MAXVL + print("SVSTATE", bin(svstate.asint())) + + # expected: each 32-bit add is completely independent + gprs = deepcopy(initial_regs) + mask = 0xffff_ffff + # GPR(1) gets overwritten completely, lo-32 element 0, hi-32 element 1 + gprs[1] = ((initial_regs[9]&mask) + (initial_regs[5]&mask)) & mask + gprs[1] += (((initial_regs[9]>>32) + (initial_regs[5]>>32)) & mask)<<32 + # GPR(2) is only overwritten in the lo-32 (element 2). hi-32 untouched + gprs[2] &= ~mask + gprs[2] += ((initial_regs[10]&mask) + (initial_regs[6]&mask)) & mask + e = ExpectedState(pc=8, int_regs=gprs) + + self.add_case(Program(lst, bigendian), initial_regs, + initial_svstate=svstate, expected=e) + + class SVP64ALUTestCase(TestAccumulatorBase): def case_1_sv_add(self): -- 2.30.2