From 2de667ffb8645bede193a2ad7666fd4602394178 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 11 Aug 2021 17:15:39 +0100 Subject: [PATCH] redirect sv.bc to new svbranch in ISACaller add missing fields needed for sv.bc --- src/openpower/decoder/isa/caller.py | 14 +- .../decoder/isa/test_caller_svp64_bc.py | 130 ++++++++++++++++++ 2 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 src/openpower/decoder/isa/test_caller_svp64_bc.py diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index 8673d995..450f73f5 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -755,17 +755,21 @@ class ISACaller: self.namespace['srcstep'] = srcstep # sv.bc* need some extra fields - if self.is_svp64_mode and insn_name.startswith("bc"): + if self.is_svp64_mode and insn_name.startswith("sv.bc"): # blegh grab bits manually mode = yield self.dec2.rm_dec.rm_in.mode bc_vlset = (mode & SVP64MODE.BC_VLSET) != 0 bc_vli = (mode & SVP64MODE.BC_VLI) != 0 + bc_snz = (mode & SVP64MODE.BC_SNZ) != 0 bc_vsb = yield self.dec2.rm_dec.bc_vsb bc_lru = yield self.dec2.rm_dec.bc_lru + sz = yield self.dec2.rm_dec.pred_sz self.namespace['VSb'] = SelectableInt(bc_vsb, 1) self.namespace['LRu'] = SelectableInt(bc_lru, 1) self.namespace['VLSET'] = SelectableInt(bc_vlset, 1) self.namespace['VLI'] = SelectableInt(bc_vli, 1) + self.namespace['sz'] = SelectableInt(sz, 1) + self.namespace['SNZ'] = SelectableInt(bc_snz, 1) def handle_carry_(self, inputs, outputs, already_done): inv_a = yield self.dec2.e.do.invert_in @@ -1175,6 +1179,13 @@ class ISACaller: illegal = False ins_name = 'ffadds' + # branch-conditional redirects to sv.bc + if asmop.startswith('bc') and self.is_svp64_mode: + ins_name = 'sv.%s' % ins_name + + log(" post-processed name", ins_name, asmop) + + # illegal instructions call TRAP at 0x700 if illegal: print("illegal", ins_name, asmop) self.call_trap(0x700, PIb.ILLEG) @@ -1194,6 +1205,7 @@ class ISACaller: self.update_pc_next() return + # look up instruction in ISA.instrs, prepare namespace info = self.instrs[ins_name] yield from self.prep_namespace(ins_name, info.form, info.op_fields) diff --git a/src/openpower/decoder/isa/test_caller_svp64_bc.py b/src/openpower/decoder/isa/test_caller_svp64_bc.py new file mode 100644 index 00000000..983cde26 --- /dev/null +++ b/src/openpower/decoder/isa/test_caller_svp64_bc.py @@ -0,0 +1,130 @@ +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 tst_sv_load_store(self): + """>>> lst = ["addi 1, 0, 0x0010", + "addi 2, 0, 0x0008", + "addi 5, 0, 0x1234", + "addi 6, 0, 0x1235", + "sv.stw 5.v, 0(1.v)", + "sv.lwz 9.v, 0(1.v)"] + """ + lst = SVP64Asm(["addi 1, 0, 0x0010", + "addi 2, 0, 0x0008", + "addi 5, 0, 0x1234", + "addi 6, 0, 0x1235", + "sv.stw 5.v, 0(1.v)", + "sv.lwz 9.v, 0(1.v)"]) + lst = list(lst) + + # SVSTATE (in this case, VL=2) + svstate = SVP64State() + svstate.vl = 2 # VL + svstate.maxvl = 2 # MAXVL + print ("SVSTATE", bin(svstate.asint())) + + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, svstate=svstate) + print(sim.gpr(1)) + self.assertEqual(sim.gpr(9), SelectableInt(0x1234, 64)) + self.assertEqual(sim.gpr(10), SelectableInt(0x1235, 64)) + + def test_sv_branch_cond(self): + for i in [0]: #[0, 10]: + lst = SVP64Asm( + [f"addi 1, 0, {i}", # set r1 to i + "cmpi cr0, 1, 1, 10", # compare r1 with 10 and store to cr0 + "sv.bc 12, 2, 0x8", # beq 0x8 - + # branch if r1 equals 10 to the nop below + "addi 2, 0, 0x1234", # if r1 == 10 this shouldn't execute + "or 0, 0, 0"] # branch target + ) + lst = list(lst) + + # SVSTATE (in this case, VL=2) + svstate = SVP64State() + svstate.vl = 2 # VL + svstate.maxvl = 2 # MAXVL + print ("SVSTATE", bin(svstate.asint())) + + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, svstate=svstate) + if i == 10: + self.assertEqual(sim.gpr(2), SelectableInt(0, 64)) + else: + self.assertEqual(sim.gpr(2), SelectableInt(0x1234, 64)) + + def tst_sv_add_cr(self): + """>>> lst = ['sv.add. 1.v, 5.v, 9.v' + ] + + adds when Rc=1: TODO CRs higher up + * 1 = 5 + 9 => 0 = -1+1 CR0=0b100 + * 2 = 6 + 10 => 0x3334 = 0x2223+0x1111 CR1=0b010 + """ + isa = SVP64Asm(['sv.add. 1.v, 5.v, 9.v' + ]) + lst = list(isa) + print ("listing", lst) + + # initial values in GPR regfile + initial_regs = [0] * 32 + initial_regs[9] = 0xffffffffffffffff + initial_regs[10] = 0x1111 + initial_regs[5] = 0x1 + initial_regs[6] = 0x2223 + # SVSTATE (in this case, VL=2) + svstate = SVP64State() + svstate.vl = 2 # VL + svstate.maxvl = 2 # MAXVL + print ("SVSTATE", bin(svstate.asint())) + # copy before running + expected_regs = deepcopy(initial_regs) + expected_regs[1] = initial_regs[5] + initial_regs[9] # 0x0 + expected_regs[2] = initial_regs[6] + initial_regs[10] # 0x3334 + + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, initial_regs, svstate) + # XXX TODO, these need to move to higher range (offset) + cr0_idx = SVP64CROffs.CR0 + cr1_idx = SVP64CROffs.CR1 + CR0 = sim.crl[cr0_idx].get_range().value + CR1 = sim.crl[cr1_idx].get_range().value + print ("CR0", CR0) + print ("CR1", CR1) + self._check_regs(sim, expected_regs) + self.assertEqual(CR0, SelectableInt(2, 4)) + self.assertEqual(CR1, SelectableInt(4, 4)) + + 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