add byte reverse instructions from PowerISA v3.1B
[openpower-isa.git] / src / openpower / test / bitmanip / bitmanip_cases.py
1 from openpower.insndb.asm import SVP64Asm
2 from openpower.test.common import TestAccumulatorBase, skip_case
3 from openpower.endian import bigendian
4 from openpower.simulator.program import Program
5 from openpower.test.state import ExpectedState
6 from nmutil.sim_util import hash_256
7 import struct
8
9
10 class BitManipTestCase(TestAccumulatorBase):
11 def do_case_ternlogi(self, rc, rt, ra, rb, imm):
12 rc_dot = "." if rc else ""
13 lst = [f"ternlogi{rc_dot} 3, 4, 5, {imm}"]
14 initial_regs = [0] * 32
15 rt %= 2 ** 64
16 ra %= 2 ** 64
17 rb %= 2 ** 64
18 initial_regs[3] = rt
19 initial_regs[4] = ra
20 initial_regs[5] = rb
21 lst = list(SVP64Asm(lst, bigendian))
22 e = ExpectedState(pc=4)
23 expected = 0
24 for i in range(64):
25 lut_index = 0
26 if rb & 2 ** i:
27 lut_index |= 2 ** 0
28 if ra & 2 ** i:
29 lut_index |= 2 ** 1
30 if rt & 2 ** i:
31 lut_index |= 2 ** 2
32 if imm & 2 ** lut_index:
33 expected |= 2 ** i
34 e.intregs[3] = expected
35 e.intregs[4] = ra
36 e.intregs[5] = rb
37 if rc:
38 if expected & 2 ** 63: # sign extend
39 expected -= 2 ** 64
40 eq = expected == 0
41 gt = expected > 0
42 lt = expected < 0
43 e.crregs[0] = (eq << 1) | (gt << 2) | (lt << 3)
44 self.add_case(Program(lst, bigendian), initial_regs, expected=e)
45
46 def do_case_grev(self, w, is_imm, ra, rb):
47 bits = 32 if w else 64
48 masked_rb = rb % bits
49 if is_imm:
50 lst = [f"grev{'w' if w else ''}i. 3, 4, {masked_rb}"]
51 else:
52 lst = [f"grev{'w' if w else ''}. 3, 4, 5"]
53 initial_regs = [0] * 32
54 ra %= 2 ** 64
55 rb %= 2 ** 64
56 initial_regs[4] = ra
57 initial_regs[5] = rb
58 lst = list(SVP64Asm(lst, bigendian))
59 e = ExpectedState(pc=4)
60 expected = 0
61 for i in range(bits):
62 dest_bit = i ^ masked_rb
63 if ra & 2 ** i:
64 expected |= 2 ** dest_bit
65 e.intregs[3] = expected
66 e.intregs[4] = ra
67 e.intregs[5] = rb
68 if expected & 2 ** 63: # sign extend
69 expected -= 2 ** 64
70 eq = expected == 0
71 gt = expected > 0
72 lt = expected < 0
73 e.crregs[0] = (eq << 1) | (gt << 2) | (lt << 3)
74 self.add_case(Program(lst, bigendian), initial_regs, expected=e)
75
76 def case_ternlogi_0(self):
77 self.do_case_ternlogi(False,
78 0x8000_0000_FFFF_0000,
79 0x8000_0000_FF00_FF00,
80 0x8000_0000_F0F0_F0F0, 0x80)
81 self.do_case_ternlogi(True,
82 0x8000_0000_FFFF_0000,
83 0x8000_0000_FF00_FF00,
84 0x8000_0000_F0F0_F0F0, 0x80)
85
86 def case_ternlogi_FF(self):
87 self.do_case_ternlogi(False, 0, 0, 0, 0xFF)
88 self.do_case_ternlogi(True, 0, 0, 0, 0xFF)
89
90 def case_ternlogi_random(self):
91 for i in range(100):
92 rc = bool(hash_256(f"ternlogi rc {i}") & 1)
93 imm = hash_256(f"ternlogi imm {i}") & 0xFF
94 rt = hash_256(f"ternlogi rt {i}") % 2 ** 64
95 ra = hash_256(f"ternlogi ra {i}") % 2 ** 64
96 rb = hash_256(f"ternlogi rb {i}") % 2 ** 64
97 self.do_case_ternlogi(rc, rt, ra, rb, imm)
98
99 @skip_case("invalid, replaced by grevlut")
100 def case_grev_random(self):
101 for i in range(100):
102 w = hash_256(f"grev w {i}") & 1
103 is_imm = hash_256(f"grev is_imm {i}") & 1
104 ra = hash_256(f"grev ra {i}") % 2 ** 64
105 rb = hash_256(f"grev rb {i}") % 2 ** 64
106 self.do_case_grev(w, is_imm, ra, rb)
107
108 @skip_case("invalid, replaced by grevlut")
109 def case_grevi_1(self):
110 self.do_case_grev(False, True, 14361919363078703450,
111 8396479064514513069)
112
113 @skip_case("invalid, replaced by grevlut")
114 def case_grevi_2(self):
115 self.do_case_grev(True, True, 397097147229333315, 8326716970539357702)
116
117 @skip_case("invalid, replaced by grevlut")
118 def case_grevi_3(self):
119 self.do_case_grev(True, True, 0xFFFF_FFFF_0000_0000, 6)
120
121 def case_byterev(self):
122 """ brh/brw/brd """
123 for pack_str, mnemonic in ("HHHH", "brh"), ("LL", "brw"), ("Q", "brd"):
124 prog = Program(list(SVP64Asm([f"{mnemonic} 3,4"])), bigendian)
125 for RS in 0x0123456789ABCDEF, 0xFEDCBA9876543210:
126 chunks = struct.unpack("<" + pack_str, struct.pack("<Q", RS))
127 expected = struct.unpack(
128 "<Q", struct.pack(">" + pack_str, *chunks))[0]
129 with self.subTest(
130 mnemonic=mnemonic, RS=hex(RS), expected=hex(expected),
131 ):
132 gprs = [0] * 32
133 gprs[4] = RS
134 e = ExpectedState(pc=4, int_regs=gprs)
135 e.intregs[3] = expected
136 self.add_case(prog, gprs, expected=e)