From 2cb88ba7019ea80498060621155179020ca543d5 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Fri, 23 Sep 2022 00:47:26 +0100 Subject: [PATCH] add first (correctly-working) ctr-mode sv.bc test --- openpower/isa/svbranch.mdwn | 15 ++++--- src/openpower/decoder/isa/caller.py | 2 +- .../decoder/isa/test_caller_svp64_bc.py | 44 ++++++++++++++++++- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/openpower/isa/svbranch.mdwn b/openpower/isa/svbranch.mdwn index bbc5aeda..e8b46e77 100644 --- a/openpower/isa/svbranch.mdwn +++ b/openpower/isa/svbranch.mdwn @@ -46,29 +46,30 @@ Pseudo-code: testbit = SNZ else testbit <- CR[BI+32] + # test CTR mode here + if (mode_is_64bit) then M <- 0 + else M <- 32 + if ¬BO[2] then CTR <- CTR - 1 + ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3]) # actual element test here cond_ok <- BO[0] | ¬(testbit ^ BO[1]) # test for VL to be set (and exit) - if VLSET & (cond_ok = VSb) then + if VLSET & ((cond_ok & ctr_ok) = VSb) then if VLI then SVSTATE[7:13] <- (srcstep+1) else - SVSTATE[7:13] <- srcstep+1 + SVSTATE[7:13] <- srcstep end_loop <- 0b1 # XXX if svstep_mode then # XXX SVSTATE.srcstep = new_srcstep # actual branch - if (mode_is_64bit) then M <- 0 - else M <- 32 - if ¬BO[2] then CTR <- CTR - 1 - ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3]) test_branch <- 0b1 if ALL then # in ALL mode only try branching at end of loop if ¬end_loop then test_branch <- 0b0 # test early-exit. ALL will exit if cond_ok fails - if ¬cond_ok then + if ¬(cond_ok & ctr_ok) then end_loop <- 0b1 test_branch <- 0b0 lr_ok <- LRu diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index 3ce81e90..7a27d12e 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -2086,7 +2086,7 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop): end_dst = dststep == vl-1 loopend = ((end_src and ssubstep == subvl) or (end_dst and dsubstep == subvl)) - log("loopend", loopend, end_src, end_dst, + log("loopend", svp64_is_vector, loopend, end_src, end_dst, ssubstep == subvl, dsubstep == subvl) if not svp64_is_vector or loopend: # reset loop to zero and update NIA diff --git a/src/openpower/decoder/isa/test_caller_svp64_bc.py b/src/openpower/decoder/isa/test_caller_svp64_bc.py index 1b814a65..ed2bb40c 100644 --- a/src/openpower/decoder/isa/test_caller_svp64_bc.py +++ b/src/openpower/decoder/isa/test_caller_svp64_bc.py @@ -104,6 +104,44 @@ class DecoderTestCase(FHDLTestCase): else: self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64)) + def test_sv_branch_ctr(self): + """XXX under development, seems to be good. + basically this will reduce CTR under a *vector* loop, where BO[0] + is 1 so there is no CR-bit-test, and BO[2] is 0 so there is a CTR-zero + test. when the CTR-zero test fails the loop is exited, with CTR + having been reduced by up to at least VL times. without VLSET + mode at the same time (which truncates VL at this same fail-point) + however this is not necessarily so useful, but at least the branch + occurs with CTR being reduced *at least* by VL. + """ + for i in [1,2,3]: + lst = SVP64Asm( + [ + "sv.bc/ctr/all 16, *0, 0xc", # branch, test CTR, reducing by VL + "addi 3, 0, 0x1234", # if tests fail 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())) + sprs = {'CTR': i} + + with Program(lst, bigendian=False) as program: + sim = self.run_tst_program(program, svstate=svstate, + initial_sprs=sprs) + sim.gpr.dump() + sim.spr.dump() + if i != 3: + self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64)) + self.assertEqual(sim.spr('CTR'), SelectableInt(0, 64)) + else: + self.assertEqual(sim.gpr(3), SelectableInt(0, 64)) + self.assertEqual(sim.spr('CTR'), SelectableInt(1, 64)) + def tst_sv_add_cr(self): """>>> lst = ['sv.add. *1, *5, *9' ] @@ -147,10 +185,12 @@ class DecoderTestCase(FHDLTestCase): self.assertEqual(CR1, SelectableInt(4, 4)) def run_tst_program(self, prog, initial_regs=None, - svstate=None): + svstate=None, + initial_sprs=None): if initial_regs is None: initial_regs = [0] * 32 - simulator = run_tst(prog, initial_regs, svstate=svstate) + simulator = run_tst(prog, initial_regs, svstate=svstate, + initial_sprs=initial_sprs) simulator.gpr.dump() return simulator -- 2.30.2