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
12 class BitManipTestCase(TestAccumulatorBase
):
13 def do_case_ternlogi(self
, rc
, rt
, ra
, rb
, imm
):
14 rc_dot
= "." if rc
else ""
15 lst
= [f
"ternlogi{rc_dot} 3, 4, 5, {imm}"]
16 initial_regs
= [0] * 32
23 lst
= list(SVP64Asm(lst
, bigendian
))
24 e
= ExpectedState(pc
=4)
34 if imm
& 2 ** lut_index
:
36 e
.intregs
[3] = expected
40 if expected
& 2 ** 63: # sign extend
45 e
.crregs
[0] = (eq
<< 1) |
(gt
<< 2) |
(lt
<< 3)
46 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
48 def do_case_grev(self
, w
, is_imm
, ra
, rb
):
49 bits
= 32 if w
else 64
52 lst
= [f
"grev{'w' if w else ''}i. 3, 4, {masked_rb}"]
54 lst
= [f
"grev{'w' if w else ''}. 3, 4, 5"]
55 initial_regs
= [0] * 32
60 lst
= list(SVP64Asm(lst
, bigendian
))
61 e
= ExpectedState(pc
=4)
64 dest_bit
= i ^ masked_rb
66 expected |
= 2 ** dest_bit
67 e
.intregs
[3] = expected
70 if expected
& 2 ** 63: # sign extend
75 e
.crregs
[0] = (eq
<< 1) |
(gt
<< 2) |
(lt
<< 3)
76 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
78 def case_ternlogi_0(self
):
79 self
.do_case_ternlogi(False,
80 0x8000_0000_FFFF_0000,
81 0x8000_0000_FF00_FF00,
82 0x8000_0000_F0F0_F0F0, 0x80)
83 self
.do_case_ternlogi(True,
84 0x8000_0000_FFFF_0000,
85 0x8000_0000_FF00_FF00,
86 0x8000_0000_F0F0_F0F0, 0x80)
88 def case_ternlogi_FF(self
):
89 self
.do_case_ternlogi(False, 0, 0, 0, 0xFF)
90 self
.do_case_ternlogi(True, 0, 0, 0, 0xFF)
92 def case_ternlogi_random(self
):
94 rc
= bool(hash_256(f
"ternlogi rc {i}") & 1)
95 imm
= hash_256(f
"ternlogi imm {i}") & 0xFF
96 rt
= hash_256(f
"ternlogi rt {i}") % 2 ** 64
97 ra
= hash_256(f
"ternlogi ra {i}") % 2 ** 64
98 rb
= hash_256(f
"ternlogi rb {i}") % 2 ** 64
99 self
.do_case_ternlogi(rc
, rt
, ra
, rb
, imm
)
101 @skip_case("grev removed -- leaving code for later use in grevlut")
102 def case_grev_random(self
):
104 w
= hash_256(f
"grev w {i}") & 1
105 is_imm
= hash_256(f
"grev is_imm {i}") & 1
106 ra
= hash_256(f
"grev ra {i}") % 2 ** 64
107 rb
= hash_256(f
"grev rb {i}") % 2 ** 64
108 self
.do_case_grev(w
, is_imm
, ra
, rb
)
110 @skip_case("grev removed -- leaving code for later use in grevlut")
111 def case_grevi_1(self
):
112 self
.do_case_grev(False, True, 14361919363078703450,
115 @skip_case("grev removed -- leaving code for later use in grevlut")
116 def case_grevi_2(self
):
117 self
.do_case_grev(True, True, 397097147229333315, 8326716970539357702)
119 @skip_case("grev removed -- leaving code for later use in grevlut")
120 def case_grevi_3(self
):
121 self
.do_case_grev(True, True, 0xFFFF_FFFF_0000_0000, 6)
123 def case_byterev(self
):
125 options
= (("HHHH", "brh"), ("LL", "brw"), ("Q", "brd"))
126 values
= (0x0123456789ABCDEF, 0xFEDCBA9876543210)
127 for RS
, (pack_str
, mnemonic
) in itertools
.product(values
, options
):
128 prog
= Program(list(SVP64Asm(["%s 3,4" % mnemonic
])), bigendian
)
129 chunks
= struct
.unpack("<" + pack_str
, struct
.pack("<Q", RS
))
130 res
= struct
.unpack("<Q", struct
.pack(">" + pack_str
, *chunks
))[0]
131 with self
.subTest(mnemonic
=mnemonic
, RS
=hex(RS
), expected
=hex(res
)):
134 e
= ExpectedState(pc
=4, int_regs
=gprs
)
136 self
.add_case(prog
, gprs
, expected
=e
)
138 def case_sv_byterev(self
):
139 """ sv.brh/brw/brd """
140 options
= (("HHHH", "brh"), ("LL", "brw"), ("Q", "brd"))
142 for idx
, (pack_str
, mnemonic
) in itertools
.product(values
, options
):
143 listing
= list(SVP64Asm(["sv.%s *10,*20" % mnemonic
]))
144 prog
= Program(listing
, bigendian
)
146 svstate
= SVP64State()
150 for elidx
in range(VL
):
151 k
= "sv.%s %d %d r20" % (mnemonic
, idx
, elidx
)
152 gprs
[20 + elidx
] = hash_256(k
) % 2**64
153 e
= ExpectedState(pc
=8, int_regs
=gprs
)
154 for elidx
in range(VL
):
155 packed
= struct
.pack("<Q", gprs
[20 + elidx
])
156 chunks
= struct
.unpack( "<" + pack_str
, packed
)
157 packed
= struct
.pack(">" + pack_str
, *chunks
)
158 res
= struct
.unpack("<Q", packed
)[0]
159 e
.intregs
[10 + elidx
] = res
160 RS
= [hex(gprs
[20 + i
]) for i
in range(VL
)],
161 res
=[hex(e
.intregs
[10 + i
]) for i
in range(VL
)]
162 with self
.subTest(case_idx
=idx
, RS_in
=RS
, expected_RA
=res
):
163 self
.add_case(prog
, gprs
, expected
=e
, initial_svstate
=svstate
)