SVSTATE[7:13] <- (srcstep+1)
else
SVSTATE[7:13] <- srcstep+1
+ end_loop <- 0b1
# XXX if svstep_mode then
# XXX SVSTATE.srcstep = new_srcstep
# actual branch
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
+ end_loop <- 0b1
+ test_branch <- 0b0
lr_ok <- LRu
- if ctr_ok & cond_ok then
+ if test_branch & ctr_ok & cond_ok then
if AA then NIA <-iea EXTS(BD || 0b00)
else NIA <-iea CIA + EXTS(BD || 0b00)
lr_ok <- 0b1
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
+ bc_gate = yield self.dec2.rm_dec.bc_gate
sz = yield self.dec2.rm_dec.pred_sz
+ self.namespace['ALL'] = SelectableInt(bc_gate, 1)
self.namespace['VSb'] = SelectableInt(bc_vsb, 1)
self.namespace['LRu'] = SelectableInt(bc_lru, 1)
self.namespace['VLSET'] = SelectableInt(bc_vlset, 1)
if not self.respect_pc:
self.fake_pc += 4
- log("execute one, CIA NIA", self.pc.CIA.value, self.pc.NIA.value)
+ log("execute one, CIA NIA", hex(self.pc.CIA.value),
+ hex(self.pc.NIA.value))
def get_assembly_name(self):
# TODO, asmregs is from the spec, e.g. add RT,RA,RB
# this is our Sub-Program-Counter loop from 0 to VL-1
pre = False
post = False
+ nia_update = True
if self.allow_next_step_inc:
log("SVSTATE_NEXT: inc requested, mode",
self.svstate_next_mode, self.allow_next_step_inc)
else:
if self.allow_next_step_inc == 2:
log ("SVSTATE_NEXT: read")
- yield from self.svstate_post_inc(ins_name)
+ nia_update = (yield from self.svstate_post_inc(ins_name))
else:
log ("SVSTATE_NEXT: post-inc")
# use actual src/dst-step here to check end, do NOT
self.svstate.vfirst = 0
elif self.is_svp64_mode:
- yield from self.svstate_post_inc(ins_name)
+ nia_update = (yield from self.svstate_post_inc(ins_name))
else:
# XXX only in non-SVP64 mode!
# record state of whether the current operation was an svshape,
# to interrupt in between. sigh.
self.last_op_svshape = asmop == 'svremap'
- self.update_pc_next()
+ if nia_update:
+ self.update_pc_next()
def SVSTATE_NEXT(self, mode, submode):
"""explicitly moves srcstep/dststep on to next element, for
svp64_is_vector = (out_vec or in_vec)
else:
svp64_is_vector = out_vec
+ # check if this was an sv.bc* and if so did it succeed
+ if self.is_svp64_mode and insn_name.startswith("sv.bc"):
+ end_loop = self.namespace['end_loop']
+ log("branch %s end_loop" % insn_name, end_loop)
+ if end_loop.value:
+ self.svp64_reset_loop()
+ self.update_pc_next()
+ return False
if svp64_is_vector and srcstep != vl-1 and dststep != vl-1:
self.svstate.srcstep += SelectableInt(1, 7)
self.svstate.dststep += SelectableInt(1, 7)
self.namespace['SVSTATE'] = self.svstate
- # check if this was an sv.bc* and if so did it succeed
- if self.is_svp64_mode and insn_name.startswith("sv.bc"):
- end_loop = self.namespace['end_loop']
- log("branch %s end_loop" % insn_name, end_loop)
- if end_loop.value:
- self.svp64_reset_loop()
- self.update_pc_next()
- return True
# not an SVP64 branch, so fix PC (NIA==CIA) for next loop
# (by default, NIA is CIA+4 if v3.0B or CIA+8 if SVP64)
# this way we keep repeating the same instruction (with new steps)
log("args[0]", args[0].namespace['CIA'],
args[0].namespace['NIA'],
args[0].namespace['SVSTATE'])
+ if 'end_loop' in func_globals:
+ log("args[0] end_loop", func_globals['end_loop'])
args[0].namespace = func_globals
#exec (func.__code__, func_globals)
self.assertEqual(sim.gpr(10), SelectableInt(0x1235, 64))
def test_sv_branch_cond(self):
- for i in [0, 10]: #[0, 10]:
+ for i in [0, 10]: #, 10]: #[0, 10]:
lst = SVP64Asm(
[f"addi 1, 0, {i}", # set r1 to i
f"addi 2, 0, {i}", # set r2 to i
"cmpi cr0, 1, 1, 10", # compare r1 with 10 and store to cr0
"cmpi cr1, 1, 2, 10", # compare r2 with 10 and store to cr1
- "sv.bc 12, 2.v, 0x8", # beq 0x8 -
+ "sv.bc 12, 2.v, 0xc", # beq 0xc -
# branch if r1 equals 10 to the nop below
"addi 3, 0, 0x1234", # if r1 == 10 this shouldn't execute
"or 0, 0, 0"] # branch target
else:
self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64))
+ def test_sv_branch_cond_all(self):
+ for i in [7, 8, 9]:
+ lst = SVP64Asm(
+ [f"addi 1, 0, {i+1}", # set r1 to i
+ f"addi 2, 0, {i}", # set r2 to i
+ "cmpi cr0, 1, 1, 8", # compare r1 with 10 and store to cr0
+ "cmpi cr1, 1, 2, 8", # compare r2 with 10 and store to cr1
+ "sv.bc/all 12, 1.v, 0xc", # bgt 0xc - branch if BOTH
+ # r1 AND r2 greater 8 to the nop below
+ "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()))
+
+ with Program(lst, bigendian=False) as program:
+ sim = self.run_tst_program(program, svstate=svstate)
+ if i == 9:
+ self.assertEqual(sim.gpr(3), SelectableInt(0, 64))
+ else:
+ self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64))
+
def tst_sv_add_cr(self):
""">>> lst = ['sv.add. 1.v, 5.v, 9.v'
]
sv_mode = ((bc_svstep << SVP64MODE.MOD2_MSB) |
(bc_vlset << SVP64MODE.MOD2_LSB) |
(bc_snz << SVP64MODE.BC_SNZ))
- srcwid = (bc_brc << 1) | bc_vsb
- destwid = (bc_all << 1) | bc_lru
+ srcwid = (bc_vsb << 1) | bc_lru
+ destwid = (bc_lru << 1) | bc_all
else: