+from openpower.sv.trans.svp64 import SVP64Asm
from openpower.test.common import TestAccumulatorBase, skip_case
from openpower.endian import bigendian
from openpower.simulator.program import Program
-from hashlib import sha256
-
-
-def hash_256(v):
- return int.from_bytes(
- sha256(bytes(v, encoding='utf-8')).digest(),
- byteorder='little'
- )
+from openpower.test.state import ExpectedState
+from nmutil.sim_util import hash_256
class BitManipTestCase(TestAccumulatorBase):
- def do_case_ternlogi(self, rt_v, ra_v, rb_v, imm):
- po = 5
- xo = 0
- rt = 3
- ra = 4
- rb = 5
- instr = po
- instr = (instr << 5) | rt
- instr = (instr << 5) | ra
- instr = (instr << 5) | rb
- instr = (instr << 8) | imm
- instr = (instr << 3) | xo
- asm = f"ternlogi {rt}, {ra}, {rb}, {imm}"
- lst = [f".4byte {hex(instr)} # {asm}"]
+ def do_case_ternlogi(self, rc, rt, ra, rb, imm):
+ rc_dot = "." if rc else ""
+ lst = [f"ternlogi{rc_dot} 3, 4, 5, {imm}"]
+ initial_regs = [0] * 32
+ rt %= 2 ** 64
+ ra %= 2 ** 64
+ rb %= 2 ** 64
+ initial_regs[3] = rt
+ initial_regs[4] = ra
+ initial_regs[5] = rb
+ lst = list(SVP64Asm(lst, bigendian))
+ e = ExpectedState(pc=4)
+ expected = 0
+ for i in range(64):
+ lut_index = 0
+ if rb & 2 ** i:
+ lut_index |= 2 ** 0
+ if ra & 2 ** i:
+ lut_index |= 2 ** 1
+ if rt & 2 ** i:
+ lut_index |= 2 ** 2
+ if imm & 2 ** lut_index:
+ expected |= 2 ** i
+ e.intregs[3] = expected
+ e.intregs[4] = ra
+ e.intregs[5] = rb
+ if rc:
+ if expected & 2 ** 63: # sign extend
+ expected -= 2 ** 64
+ eq = expected == 0
+ gt = expected > 0
+ lt = expected < 0
+ e.crregs[0] = (eq << 1) | (gt << 2) | (lt << 3)
+ self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+
+ def do_case_grev(self, w, is_imm, ra, rb):
+ bits = 32 if w else 64
+ masked_rb = rb % bits
+ if is_imm:
+ lst = [f"grev{'w' if w else ''}i. 3, 4, {masked_rb}"]
+ else:
+ lst = [f"grev{'w' if w else ''}. 3, 4, 5"]
initial_regs = [0] * 32
- initial_regs[3] = rt_v % 2 ** 64
- initial_regs[4] = ra_v % 2 ** 64
- initial_regs[5] = rb_v % 2 ** 64
- self.add_case(Program(lst, bigendian), initial_regs)
+ ra %= 2 ** 64
+ rb %= 2 ** 64
+ initial_regs[4] = ra
+ initial_regs[5] = rb
+ lst = list(SVP64Asm(lst, bigendian))
+ e = ExpectedState(pc=4)
+ expected = 0
+ for i in range(bits):
+ dest_bit = i ^ masked_rb
+ if ra & 2 ** i:
+ expected |= 2 ** dest_bit
+ e.intregs[3] = expected
+ e.intregs[4] = ra
+ e.intregs[5] = rb
+ if expected & 2 ** 63: # sign extend
+ expected -= 2 ** 64
+ eq = expected == 0
+ gt = expected > 0
+ lt = expected < 0
+ e.crregs[0] = (eq << 1) | (gt << 2) | (lt << 3)
+ self.add_case(Program(lst, bigendian), initial_regs, expected=e)
def case_ternlogi_0(self):
- self.do_case_ternlogi(0x8000_0000_FFFF_0000,
+ self.do_case_ternlogi(False,
+ 0x8000_0000_FFFF_0000,
+ 0x8000_0000_FF00_FF00,
+ 0x8000_0000_F0F0_F0F0, 0x80)
+ self.do_case_ternlogi(True,
+ 0x8000_0000_FFFF_0000,
0x8000_0000_FF00_FF00,
0x8000_0000_F0F0_F0F0, 0x80)
def case_ternlogi_FF(self):
- self.do_case_ternlogi(0, 0, 0, 0xFF)
+ self.do_case_ternlogi(False, 0, 0, 0, 0xFF)
+ self.do_case_ternlogi(True, 0, 0, 0, 0xFF)
def case_ternlogi_random(self):
for i in range(100):
+ rc = bool(hash_256(f"ternlogi rc {i}") & 1)
imm = hash_256(f"ternlogi imm {i}") & 0xFF
- rt_v = hash_256(f"ternlogi rt {i}") % 2 ** 64
- ra_v = hash_256(f"ternlogi ra {i}") % 2 ** 64
- rb_v = hash_256(f"ternlogi rb {i}") % 2 ** 64
- self.do_case_ternlogi(rt_v, ra_v, rb_v, imm)
+ rt = hash_256(f"ternlogi rt {i}") % 2 ** 64
+ ra = hash_256(f"ternlogi ra {i}") % 2 ** 64
+ rb = hash_256(f"ternlogi rb {i}") % 2 ** 64
+ self.do_case_ternlogi(rc, rt, ra, rb, imm)
+
+ def case_grev_random(self):
+ for i in range(100):
+ w = hash_256(f"grev w {i}") & 1
+ is_imm = hash_256(f"grev is_imm {i}") & 1
+ ra = hash_256(f"grev ra {i}") % 2 ** 64
+ rb = hash_256(f"grev rb {i}") % 2 ** 64
+ self.do_case_grev(w, is_imm, ra, rb)
+
+ def case_grevi_1(self):
+ self.do_case_grev(False, True, 14361919363078703450,
+ 8396479064514513069)
+
+ def case_grevi_2(self):
+ self.do_case_grev(True, True, 397097147229333315, 8326716970539357702)
+
+ def case_grevi_3(self):
+ self.do_case_grev(True, True, 0xFFFF_FFFF_0000_0000, 6)