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
16 b
= (ra
>> (63-k
*8-j
)) & 1
17 result |
= b
<< (63-j
*8-k
)
21 class BitManipTestCase(TestAccumulatorBase
):
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]))
33 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
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
45 lst
= list(SVP64Asm(lst
, bigendian
))
46 e
= ExpectedState(pc
=4)
56 if imm
& 2 ** lut_index
:
58 e
.intregs
[3] = expected
62 if expected
& 2 ** 63: # sign extend
67 e
.crregs
[0] = (eq
<< 1) |
(gt
<< 2) |
(lt
<< 3)
68 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
70 def do_case_grev(self
, w
, is_imm
, ra
, rb
):
71 bits
= 32 if w
else 64
74 lst
= [f
"grev{'w' if w else ''}i. 3, 4, {masked_rb}"]
76 lst
= [f
"grev{'w' if w else ''}. 3, 4, 5"]
77 initial_regs
= [0] * 32
82 lst
= list(SVP64Asm(lst
, bigendian
))
83 e
= ExpectedState(pc
=4)
86 dest_bit
= i ^ masked_rb
88 expected |
= 2 ** dest_bit
89 e
.intregs
[3] = expected
92 if expected
& 2 ** 63: # sign extend
97 e
.crregs
[0] = (eq
<< 1) |
(gt
<< 2) |
(lt
<< 3)
98 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
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)
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)
114 def case_ternlogi_random(self
):
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
)
123 @skip_case("grev removed -- leaving code for later use in grevlut")
124 def case_grev_random(self
):
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
)
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,
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)
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)
145 def case_byterev(self
):
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
)):
156 e
= ExpectedState(pc
=4, int_regs
=gprs
)
158 self
.add_case(prog
, gprs
, expected
=e
)
160 def case_sv_byterev(self
):
161 """ sv.brh/brw/brd """
162 options
= (("HHHH", "brh"), ("LL", "brw"), ("Q", "brd"))
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
)
168 svstate
= SVP64State()
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
)