bug 1034: add crbinlog and binlog, unit test binlog done
[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, CRFields
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_crternlogi(self, bf, bfa, bfb, imm, mask):
36 lst = [f"crternlogi 3,4,5,%d,%d" % (imm, mask)]
37 # set up CR
38 bf %= 2 ** 4
39 bfa %= 2 ** 4
40 bfb %= 2 ** 4
41 cr = CRFields()
42 cr.crl[3][0:4] = bf
43 cr.crl[4][0:4] = bfa
44 cr.crl[5][0:4] = bfb
45 initial_cr = cr.cr.asint()
46 print("initial cr", bin(initial_cr), bf, bfa, bfb)
47 print("mask tli", bin(mask), bin(imm))
48
49 lst = list(SVP64Asm(lst, bigendian))
50 e = ExpectedState(pc=4)
51 expected = bf&~mask # start at BF, mask overwrites masked bits only
52 checks = (bfb, bfa, bf) # LUT positions 1<<0=bfb 1<<1=bfa 1<<2=bf
53 for i in range(4):
54 lut_index = 0
55 for j, check in enumerate(checks):
56 if check & (1<<i):
57 lut_index |= 1<<j
58 maskbit = (mask >> i) & 0b1
59 if (imm & (1<<lut_index)) and maskbit:
60 expected |= 1<<i
61 e.crregs[3] = expected
62 e.crregs[4] = bfa
63 e.crregs[5] = bfb
64 self.add_case(Program(lst, bigendian), initial_regs=None, expected=e,
65 initial_cr=initial_cr)
66
67 def case_crternlogi_0(self):
68 self.do_case_crternlogi(0b1111,
69 0b1100,
70 0b1010,
71 0x80, 0b1111)
72
73 def case_crternlogi_random(self):
74 for i in range(100):
75 rc = bool(hash_256(f"crternlogi rc {i}") & 1)
76 imm = hash_256(f"crternlogi imm {i}") & 0xFF
77 bf = hash_256(f"crternlogi bf {i}") % 2 ** 4
78 bfa = hash_256(f"crternlogi bfa {i}") % 2 ** 4
79 bfb = hash_256(f"crternlogi bfb {i}") % 2 ** 4
80 msk = hash_256(f"crternlogi msk {i}") % 2 ** 4
81 self.do_case_crternlogi(bf, bfa, bfb, imm, msk)
82
83 def do_case_ternlogi(self, rc, rt, ra, rb, imm):
84 rc_dot = "." if rc else ""
85 lst = [f"ternlogi{rc_dot} 3, 4, 5, {imm}"]
86 initial_regs = [0] * 32
87 rt %= 2 ** 64
88 ra %= 2 ** 64
89 rb %= 2 ** 64
90 initial_regs[3] = rt
91 initial_regs[4] = ra
92 initial_regs[5] = rb
93 lst = list(SVP64Asm(lst, bigendian))
94 e = ExpectedState(pc=4)
95 expected = 0
96 for i in range(64):
97 lut_index = 0
98 if rb & 2 ** i:
99 lut_index |= 2 ** 0
100 if ra & 2 ** i:
101 lut_index |= 2 ** 1
102 if rt & 2 ** i:
103 lut_index |= 2 ** 2
104 if imm & 2 ** lut_index:
105 expected |= 2 ** i
106 e.intregs[3] = expected
107 e.intregs[4] = ra
108 e.intregs[5] = rb
109 if rc:
110 if expected & 2 ** 63: # sign extend
111 expected -= 2 ** 64
112 eq = expected == 0
113 gt = expected > 0
114 lt = expected < 0
115 e.crregs[0] = (eq << 1) | (gt << 2) | (lt << 3)
116 self.add_case(Program(lst, bigendian), initial_regs, expected=e)
117
118 def do_case_binlog(self, ra, rb, rc, nh):
119 lst = ["binlog 3, 4, 5, 6, %d" % nh]
120 initial_regs = [0] * 32
121 initial_regs[4] = ra
122 initial_regs[5] = rb
123 initial_regs[6] = rc
124 lut = rc & 0b11111111 # one of two 4-bit LUTs is in 1st 8 bits
125 if nh == 1: # top half (bits 4-7... sigh MSB 56-59) else 0-3 (60-63)
126 lut = lut >> 4
127 lut = lut & 0b1111
128 lst = list(SVP64Asm(lst, bigendian))
129 e = ExpectedState(pc=4)
130 expected = 0
131 for i in range(64):
132 lut_index = 0
133 if rb & 2 ** i:
134 lut_index |= 2 ** 0
135 if ra & 2 ** i:
136 lut_index |= 2 ** 1
137 if lut & 2 ** lut_index:
138 expected |= 2 ** i
139 e.intregs[3] = expected
140 e.intregs[4] = ra
141 e.intregs[5] = rb
142 e.intregs[6] = rc
143 self.add_case(Program(lst, bigendian), initial_regs, expected=e)
144
145 def case_binlog_0(self):
146 self.do_case_binlog(0x8000_0000_FFFF_0000,
147 0x8000_0000_FF00_FF00,
148 0x80, 1)
149 self.do_case_binlog(0x8000_0000_FFFF_0000,
150 0x8000_0000_FF00_FF00,
151 0x80, 0)
152
153 def case_binlog_random(self):
154 for i in range(100):
155 ra = hash_256(f"binlog ra {i}") % 2 ** 64
156 rb = hash_256(f"binlog rb {i}") % 2 ** 64
157 rc = hash_256(f"binlog rc {i}") % 2 ** 8
158 nh = hash_256(f"binlog nh {i}") & 0b1
159 self.do_case_binlog(ra, rb, rc, nh)
160
161 def do_case_grev(self, w, is_imm, ra, rb):
162 bits = 32 if w else 64
163 masked_rb = rb % bits
164 if is_imm:
165 lst = [f"grev{'w' if w else ''}i. 3, 4, {masked_rb}"]
166 else:
167 lst = [f"grev{'w' if w else ''}. 3, 4, 5"]
168 initial_regs = [0] * 32
169 ra %= 2 ** 64
170 rb %= 2 ** 64
171 initial_regs[4] = ra
172 initial_regs[5] = rb
173 lst = list(SVP64Asm(lst, bigendian))
174 e = ExpectedState(pc=4)
175 expected = 0
176 for i in range(bits):
177 dest_bit = i ^ masked_rb
178 if ra & 2 ** i:
179 expected |= 2 ** dest_bit
180 e.intregs[3] = expected
181 e.intregs[4] = ra
182 e.intregs[5] = rb
183 if expected & 2 ** 63: # sign extend
184 expected -= 2 ** 64
185 eq = expected == 0
186 gt = expected > 0
187 lt = expected < 0
188 e.crregs[0] = (eq << 1) | (gt << 2) | (lt << 3)
189 self.add_case(Program(lst, bigendian), initial_regs, expected=e)
190
191 def case_ternlogi_0(self):
192 self.do_case_ternlogi(False,
193 0x8000_0000_FFFF_0000,
194 0x8000_0000_FF00_FF00,
195 0x8000_0000_F0F0_F0F0, 0x80)
196 self.do_case_ternlogi(True,
197 0x8000_0000_FFFF_0000,
198 0x8000_0000_FF00_FF00,
199 0x8000_0000_F0F0_F0F0, 0x80)
200
201 def case_ternlogi_FF(self):
202 self.do_case_ternlogi(False, 0, 0, 0, 0xFF)
203 self.do_case_ternlogi(True, 0, 0, 0, 0xFF)
204
205 def case_ternlogi_random(self):
206 for i in range(100):
207 rc = bool(hash_256(f"ternlogi rc {i}") & 1)
208 imm = hash_256(f"ternlogi imm {i}") & 0xFF
209 rt = hash_256(f"ternlogi rt {i}") % 2 ** 64
210 ra = hash_256(f"ternlogi ra {i}") % 2 ** 64
211 rb = hash_256(f"ternlogi rb {i}") % 2 ** 64
212 self.do_case_ternlogi(rc, rt, ra, rb, imm)
213
214 @skip_case("grev removed -- leaving code for later use in grevlut")
215 def case_grev_random(self):
216 for i in range(100):
217 w = hash_256(f"grev w {i}") & 1
218 is_imm = hash_256(f"grev is_imm {i}") & 1
219 ra = hash_256(f"grev ra {i}") % 2 ** 64
220 rb = hash_256(f"grev rb {i}") % 2 ** 64
221 self.do_case_grev(w, is_imm, ra, rb)
222
223 @skip_case("grev removed -- leaving code for later use in grevlut")
224 def case_grevi_1(self):
225 self.do_case_grev(False, True, 14361919363078703450,
226 8396479064514513069)
227
228 @skip_case("grev removed -- leaving code for later use in grevlut")
229 def case_grevi_2(self):
230 self.do_case_grev(True, True, 397097147229333315, 8326716970539357702)
231
232 @skip_case("grev removed -- leaving code for later use in grevlut")
233 def case_grevi_3(self):
234 self.do_case_grev(True, True, 0xFFFF_FFFF_0000_0000, 6)
235
236 def case_byterev(self):
237 """ brh/brw/brd """
238 options = (("HHHH", "brh"), ("LL", "brw"), ("Q", "brd"))
239 values = (0x0123456789ABCDEF, 0xFEDCBA9876543210)
240 for RS, (pack_str, mnemonic) in itertools.product(values, options):
241 prog = Program(list(SVP64Asm(["%s 3,4" % mnemonic])), bigendian)
242 chunks = struct.unpack("<" + pack_str, struct.pack("<Q", RS))
243 res = struct.unpack("<Q", struct.pack(">" + pack_str, *chunks))[0]
244 with self.subTest(mnemonic=mnemonic, RS=hex(RS), expected=hex(res)):
245 gprs = [0] * 32
246 gprs[4] = RS
247 e = ExpectedState(pc=4, int_regs=gprs)
248 e.intregs[3] = res
249 self.add_case(prog, gprs, expected=e)
250
251 def case_sv_byterev(self):
252 """ sv.brh/brw/brd """
253 options = (("HHHH", "brh"), ("LL", "brw"), ("Q", "brd"))
254 values = range(10)
255 for idx, (pack_str, mnemonic) in itertools.product(values, options):
256 listing = list(SVP64Asm(["sv.%s *10,*20" % mnemonic]))
257 prog = Program(listing, bigendian)
258 VL = 5
259 svstate = SVP64State()
260 svstate.vl = VL
261 svstate.maxvl = VL
262 gprs = [0] * 128
263 for elidx in range(VL):
264 k = "sv.%s %d %d r20" % (mnemonic, idx, elidx)
265 gprs[20 + elidx] = hash_256(k) % 2**64
266 e = ExpectedState(pc=8, int_regs=gprs)
267 for elidx in range(VL):
268 packed = struct.pack("<Q", gprs[20 + elidx])
269 chunks = struct.unpack( "<" + pack_str, packed)
270 packed = struct.pack(">" + pack_str, *chunks)
271 res = struct.unpack("<Q", packed)[0]
272 e.intregs[10 + elidx] = res
273 RS = [hex(gprs[20 + i]) for i in range(VL)],
274 res =[hex(e.intregs[10 + i]) for i in range(VL)]
275 with self.subTest(case_idx=idx, RS_in=RS, expected_RA=res):
276 self.add_case(prog, gprs, expected=e, initial_svstate=svstate)