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
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
21 lst
= list(SVP64Asm(lst
, bigendian
))
22 e
= ExpectedState(pc
=4)
32 if imm
& 2 ** lut_index
:
34 e
.intregs
[3] = expected
38 if expected
& 2 ** 63: # sign extend
43 e
.crregs
[0] = (eq
<< 1) |
(gt
<< 2) |
(lt
<< 3)
44 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
46 def do_case_grev(self
, w
, is_imm
, ra
, rb
):
47 bits
= 32 if w
else 64
50 lst
= [f
"grev{'w' if w else ''}i. 3, 4, {masked_rb}"]
52 lst
= [f
"grev{'w' if w else ''}. 3, 4, 5"]
53 initial_regs
= [0] * 32
58 lst
= list(SVP64Asm(lst
, bigendian
))
59 e
= ExpectedState(pc
=4)
62 dest_bit
= i ^ masked_rb
64 expected |
= 2 ** dest_bit
65 e
.intregs
[3] = expected
68 if expected
& 2 ** 63: # sign extend
73 e
.crregs
[0] = (eq
<< 1) |
(gt
<< 2) |
(lt
<< 3)
74 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
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)
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)
90 def case_ternlogi_random(self
):
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
)
99 @skip_case("invalid, replaced by grevlut")
100 def case_grev_random(self
):
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
)
108 @skip_case("invalid, replaced by grevlut")
109 def case_grevi_1(self
):
110 self
.do_case_grev(False, True, 14361919363078703450,
113 @skip_case("invalid, replaced by grevlut")
114 def case_grevi_2(self
):
115 self
.do_case_grev(True, True, 397097147229333315, 8326716970539357702)
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)
121 def case_byterev(self
):
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]
130 mnemonic
=mnemonic
, RS
=hex(RS
), expected
=hex(expected
),
134 e
= ExpectedState(pc
=4, int_regs
=gprs
)
135 e
.intregs
[3] = expected
136 self
.add_case(prog
, gprs
, expected
=e
)