From 58fbc0dce7246f1d36babae958aed57de8a9a0f4 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sat, 29 May 2021 20:12:18 +0100 Subject: [PATCH] add unit-strided LD/ST ISACaller SVP64 unit test --- src/openpower/decoder/isa/caller.py | 32 ++++++++- .../decoder/isa/test_caller_svp64_ldst.py | 66 +++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/openpower/decoder/isa/test_caller_svp64_ldst.py diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index d2c68f54..c07003bb 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -23,7 +23,8 @@ from openpower.decoder.power_enums import (spr_dict, spr_byname, XER_bits, insns, MicrOp, In1Sel, In2Sel, In3Sel, OutSel, CROutSel, LDSTMode, SVP64RMMode, SVP64PredMode, - SVP64PredInt, SVP64PredCR) + SVP64PredInt, SVP64PredCR, + SVP64LDSTmode) from openpower.decoder.power_enums import SVPtype @@ -1138,6 +1139,35 @@ class ISACaller: self.namespace['NIA']) return + # in SVP64 mode for LD/ST work out immediate + replace_d = False # replace constant in pseudocode + if self.is_svp64_mode: + D = yield self.dec2.dec.fields.FormD.D[0:16] + D = exts(D, 16) # sign-extend to integer + ldstmode = yield self.dec2.rm_dec.ldstmode + # get the right step. LD is from srcstep, ST is dststep + op = yield self.dec2.e.do.insn_type + offsmul = 0 + if op == MicrOp.OP_LOAD.value: + offsmul = srcstep + log("D-field src", D, offsmul) + elif op == MicrOp.OP_STORE.value: + offsmul = dststep + log("D-field dst", D, offsmul) + # Unit-Strided LD/ST adds offset*width to immediate + if ldstmode == SVP64LDSTmode.UNITSTRIDE.value: + ldst_len = yield self.dec2.e.do.data_len + D = SelectableInt(D + offsmul * ldst_len, 32) + replace_d = True + # Element-strided multiplies the immediate by element step + elif ldstmode == SVP64LDSTmode.ELSTRIDE.value: + D = SelectableInt(D * offsmul, 32) + replace_d = True + log("LDSTmode", ldstmode, offsmul, D) + # new replacement D + if replace_d: + self.namespace['D'] = D + # main input registers (RT, RA ...) inputs = [] for name in input_names: diff --git a/src/openpower/decoder/isa/test_caller_svp64_ldst.py b/src/openpower/decoder/isa/test_caller_svp64_ldst.py new file mode 100644 index 00000000..a9f40a20 --- /dev/null +++ b/src/openpower/decoder/isa/test_caller_svp64_ldst.py @@ -0,0 +1,66 @@ +from nmigen import Module, Signal +from nmigen.back.pysim import Simulator, Delay, Settle +from nmutil.formaltest import FHDLTestCase +import unittest +from openpower.decoder.isa.caller import ISACaller +from openpower.decoder.power_decoder import (create_pdecode) +from openpower.decoder.power_decoder2 import (PowerDecode2) +from openpower.simulator.program import Program +from openpower.decoder.isa.caller import ISACaller, SVP64State +from openpower.decoder.selectable_int import SelectableInt +from openpower.decoder.orderedset import OrderedSet +from openpower.decoder.isa.all import ISA +from openpower.decoder.isa.test_caller import Register, run_tst +from openpower.sv.trans.svp64 import SVP64Asm +from openpower.consts import SVP64CROffs +from copy import deepcopy + + +class DecoderTestCase(FHDLTestCase): + + def _check_regs(self, sim, expected): + for i in range(32): + self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64)) + + def test_sv_load_store_unitstride(self): + """>>> lst = ["addi 1, 0, 0x0010", + "addi 2, 0, 0x0008", + "addi 5, 0, 0x1234", + "addi 6, 0, 0x1235", + "sv.stw 5.v, 8(1)", + "sv.lwz 9.v, 8(1)"] + """ + lst = SVP64Asm(["addi 1, 0, 0x0010", + "addi 2, 0, 0x0008", + "addi 5, 0, 0x1234", + "addi 6, 0, 0x1235", + "sv.stw 5.v, 8(1)", # scalar r1 + 8 + wordlen*offs + "sv.lwz 9.v, 8(1)"]) # scalar r1 + 8 + wordlen*offs + lst = list(lst) + + # SVSTATE (in this case, VL=2) + svstate = SVP64State() + svstate.vl[0:7] = 2 # VL + svstate.maxvl[0:7] = 2 # MAXVL + print ("SVSTATE", bin(svstate.spr.asint())) + + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, svstate=svstate) + mem = sim.mem.dump(printout=False) + print (mem) + self.assertEqual(mem, [(24, 0x123500001234)]) + print(sim.gpr(1)) + self.assertEqual(sim.gpr(9), SelectableInt(0x1234, 64)) + self.assertEqual(sim.gpr(10), SelectableInt(0x1235, 64)) + + def run_tst_program(self, prog, initial_regs=None, + svstate=None): + if initial_regs is None: + initial_regs = [0] * 32 + simulator = run_tst(prog, initial_regs, svstate=svstate) + simulator.gpr.dump() + return simulator + + +if __name__ == "__main__": + unittest.main() -- 2.30.2