add gbbd (bmatflip) test case - just the one for now
[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 from openpower.decoder.isa.caller import SVP64State
8 from openpower.util import log
9 import struct
10 import itertools
11
12 def bmatflip(ra):
13 result = 0
14 for j in range(8):
15 for k in range(8):
16 b = (ra >> (63-k*8-j)) & 1
17 result |= b << (63-j*8-k)
18 return result
19
20
21 class BitManipTestCase(TestAccumulatorBase):
22 def case_gbbd(self):
23 lst = ["gbbd 0, 1"]
24 lst = list(SVP64Asm(lst, bigendian))
25 initial_regs = [0] * 32
26 initial_regs[1] = 0x9231_5897_2083_ffff
27 e = ExpectedState(pc=4)
28 e.intregs[0] = bmatflip(initial_regs[1])
29 e.intregs[1] = initial_regs[1]
30 log("case_gbbd", bin(initial_regs[1]), bin(e.intregs[0]))
31 log("hex", hex(initial_regs[1]), hex(e.intregs[0]))
32
33 self.add_case(Program(lst, bigendian), initial_regs, expected=e)
34
35 def do_case_ternlogi(self, rc, rt, ra, rb, imm):
36 rc_dot = "." if rc else ""
37 lst = [f"ternlogi{rc_dot} 3, 4, 5, {imm}"]
38 initial_regs = [0] * 32
39 rt %= 2 ** 64
40 ra %= 2 ** 64
41 rb %= 2 ** 64
42 initial_regs[3] = rt
43 initial_regs[4] = ra
44 initial_regs[5] = rb
45 lst = list(SVP64Asm(lst, bigendian))
46 e = ExpectedState(pc=4)
47 expected = 0
48 for i in range(64):
49 lut_index = 0
50 if rb & 2 ** i:
51 lut_index |= 2 ** 0
52 if ra & 2 ** i:
53 lut_index |= 2 ** 1
54 if rt & 2 ** i:
55 lut_index |= 2 ** 2
56 if imm & 2 ** lut_index:
57 expected |= 2 ** i
58 e.intregs[3] = expected
59 e.intregs[4] = ra
60 e.intregs[5] = rb
61 if rc:
62 if expected & 2 ** 63: # sign extend
63 expected -= 2 ** 64
64 eq = expected == 0
65 gt = expected > 0
66 lt = expected < 0
67 e.crregs[0] = (eq << 1) | (gt << 2) | (lt << 3)
68 self.add_case(Program(lst, bigendian), initial_regs, expected=e)
69
70 def do_case_grev(self, w, is_imm, ra, rb):
71 bits = 32 if w else 64
72 masked_rb = rb % bits
73 if is_imm:
74 lst = [f"grev{'w' if w else ''}i. 3, 4, {masked_rb}"]
75 else:
76 lst = [f"grev{'w' if w else ''}. 3, 4, 5"]
77 initial_regs = [0] * 32
78 ra %= 2 ** 64
79 rb %= 2 ** 64
80 initial_regs[4] = ra
81 initial_regs[5] = rb
82 lst = list(SVP64Asm(lst, bigendian))
83 e = ExpectedState(pc=4)
84 expected = 0
85 for i in range(bits):
86 dest_bit = i ^ masked_rb
87 if ra & 2 ** i:
88 expected |= 2 ** dest_bit
89 e.intregs[3] = expected
90 e.intregs[4] = ra
91 e.intregs[5] = rb
92 if expected & 2 ** 63: # sign extend
93 expected -= 2 ** 64
94 eq = expected == 0
95 gt = expected > 0
96 lt = expected < 0
97 e.crregs[0] = (eq << 1) | (gt << 2) | (lt << 3)
98 self.add_case(Program(lst, bigendian), initial_regs, expected=e)
99
100 def case_ternlogi_0(self):
101 self.do_case_ternlogi(False,
102 0x8000_0000_FFFF_0000,
103 0x8000_0000_FF00_FF00,
104 0x8000_0000_F0F0_F0F0, 0x80)
105 self.do_case_ternlogi(True,
106 0x8000_0000_FFFF_0000,
107 0x8000_0000_FF00_FF00,
108 0x8000_0000_F0F0_F0F0, 0x80)
109
110 def case_ternlogi_FF(self):
111 self.do_case_ternlogi(False, 0, 0, 0, 0xFF)
112 self.do_case_ternlogi(True, 0, 0, 0, 0xFF)
113
114 def case_ternlogi_random(self):
115 for i in range(100):
116 rc = bool(hash_256(f"ternlogi rc {i}") & 1)
117 imm = hash_256(f"ternlogi imm {i}") & 0xFF
118 rt = hash_256(f"ternlogi rt {i}") % 2 ** 64
119 ra = hash_256(f"ternlogi ra {i}") % 2 ** 64
120 rb = hash_256(f"ternlogi rb {i}") % 2 ** 64
121 self.do_case_ternlogi(rc, rt, ra, rb, imm)
122
123 @skip_case("grev removed -- leaving code for later use in grevlut")
124 def case_grev_random(self):
125 for i in range(100):
126 w = hash_256(f"grev w {i}") & 1
127 is_imm = hash_256(f"grev is_imm {i}") & 1
128 ra = hash_256(f"grev ra {i}") % 2 ** 64
129 rb = hash_256(f"grev rb {i}") % 2 ** 64
130 self.do_case_grev(w, is_imm, ra, rb)
131
132 @skip_case("grev removed -- leaving code for later use in grevlut")
133 def case_grevi_1(self):
134 self.do_case_grev(False, True, 14361919363078703450,
135 8396479064514513069)
136
137 @skip_case("grev removed -- leaving code for later use in grevlut")
138 def case_grevi_2(self):
139 self.do_case_grev(True, True, 397097147229333315, 8326716970539357702)
140
141 @skip_case("grev removed -- leaving code for later use in grevlut")
142 def case_grevi_3(self):
143 self.do_case_grev(True, True, 0xFFFF_FFFF_0000_0000, 6)
144
145 def case_byterev(self):
146 """ brh/brw/brd """
147 options = (("HHHH", "brh"), ("LL", "brw"), ("Q", "brd"))
148 values = (0x0123456789ABCDEF, 0xFEDCBA9876543210)
149 for RS, (pack_str, mnemonic) in itertools.product(values, options):
150 prog = Program(list(SVP64Asm(["%s 3,4" % mnemonic])), bigendian)
151 chunks = struct.unpack("<" + pack_str, struct.pack("<Q", RS))
152 res = struct.unpack("<Q", struct.pack(">" + pack_str, *chunks))[0]
153 with self.subTest(mnemonic=mnemonic, RS=hex(RS), expected=hex(res)):
154 gprs = [0] * 32
155 gprs[4] = RS
156 e = ExpectedState(pc=4, int_regs=gprs)
157 e.intregs[3] = res
158 self.add_case(prog, gprs, expected=e)
159
160 def case_sv_byterev(self):
161 """ sv.brh/brw/brd """
162 options = (("HHHH", "brh"), ("LL", "brw"), ("Q", "brd"))
163 values = range(10)
164 for idx, (pack_str, mnemonic) in itertools.product(values, options):
165 listing = list(SVP64Asm(["sv.%s *10,*20" % mnemonic]))
166 prog = Program(listing, bigendian)
167 VL = 5
168 svstate = SVP64State()
169 svstate.vl = VL
170 svstate.maxvl = VL
171 gprs = [0] * 128
172 for elidx in range(VL):
173 k = "sv.%s %d %d r20" % (mnemonic, idx, elidx)
174 gprs[20 + elidx] = hash_256(k) % 2**64
175 e = ExpectedState(pc=8, int_regs=gprs)
176 for elidx in range(VL):
177 packed = struct.pack("<Q", gprs[20 + elidx])
178 chunks = struct.unpack( "<" + pack_str, packed)
179 packed = struct.pack(">" + pack_str, *chunks)
180 res = struct.unpack("<Q", packed)[0]
181 e.intregs[10 + elidx] = res
182 RS = [hex(gprs[20 + i]) for i in range(VL)],
183 res =[hex(e.intregs[10 + i]) for i in range(VL)]
184 with self.subTest(case_idx=idx, RS_in=RS, expected_RA=res):
185 self.add_case(prog, gprs, expected=e, initial_svstate=svstate)