e.intregs[11] = 0x00002d41
e.intregs[12] = 0x00000d00
self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+
+ def maddrs_many_helper(self, width, shift, prog, case_idx):
+ # if {'width': width, 'shift': shift, 'case_idx': case_idx} \
+ # != {'width': 8, 'shift': 1, 'case_idx': 0}:
+ # return # for debugging
+ gprs = [0] * 32
+ # make some reproducible random inputs
+ k = f"maddrs {width} {shift} {case_idx}"
+ gprs[10] = hash_256(k + " r10") % 2**64
+ gprs[11] = hash_256(k + " r11") % 2**64
+ gprs[20] = hash_256(k + " r20") % 2**64
+ gprs[30] = hash_256(k + " r30") % 2**64
+
+ svstate = SVP64State()
+ svstate.vl = 64 // width # one full 64-bit register
+ svstate.maxvl = 64 // width
+
+ e = ExpectedState(pc=8, int_regs=gprs)
+ e.intregs[10] = 0
+ e.intregs[11] = 0
+ for i in range(svstate.vl):
+ # extract elements
+ rt = (gprs[10] >> (i * width)) % 2 ** width
+ rs = (gprs[11] >> (i * width)) % 2 ** width
+ ra = (gprs[20] >> (i * width)) % 2 ** width
+ rb = (gprs[30] >> (i * width)) % 2 ** width
+ if rt >= 2 ** (width - 1):
+ rt -= 2 ** width # sign extend rt
+ if rs >= 2 ** (width - 1):
+ rs -= 2 ** width # sign extend rs
+ if ra >= 2 ** (width - 1):
+ ra -= 2 ** width # sign extend ra
+ if rb >= 2 ** (width - 1):
+ rb -= 2 ** width # sign extend rb
+ prod = rb * ra
+ rt += prod
+ rs -= prod
+ factor = Fraction(1, 2 ** shift) # shr factor
+ round_up = Fraction(1, 2)
+ # round & shr
+ rt = math.floor(rt * factor + round_up)
+ rs = math.floor(rs * factor + round_up)
+ # insert elements
+ e.intregs[10] |= (rt % 2 ** width) << (width * i)
+ e.intregs[11] |= (rs % 2 ** width) << (width * i)
+
+ with self.subTest(
+ width=width, shift=shift, case_idx=case_idx,
+ RT_in=hex(gprs[10]), RS_in=hex(gprs[11]),
+ RA_in=hex(gprs[20]), RB_in=hex(gprs[30]),
+ expected_RT=hex(e.intregs[10]), expected_RS=hex(e.intregs[11]),
+ ):
+ self.add_case(prog, gprs, expected=e, initial_svstate=svstate)
+
+ def case_maddrs_many(self):
+ for width in 8, 16, 32, 64:
+ shift_end = min(32, width)
+ for shift in range(0, shift_end, shift_end // 8):
+ w = "" if width == 64 else f"/w={width}"
+ prog = Program(list(SVP64Asm([
+ f"sv.maddrs{w} *10,*20,{shift},*30",
+ ])), bigendian)
+
+ for case_idx in range(25):
+ self.maddrs_many_helper(width, shift, prog, case_idx)