2 from openpower
.decoder
.selectable_int
import SelectableInt
, onebit
3 from nmutil
.divmod import trunc_divs
, trunc_rems
4 from operator
import floordiv
, mod
5 from openpower
.decoder
.selectable_int
import selectltu
as ltu
6 from openpower
.decoder
.selectable_int
import selectgtu
as gtu
7 from openpower
.decoder
.selectable_int
import check_extsign
16 * https://bugs.libre-soc.org/show_bug.cgi?id=324 - add trunc_div and trunc_rem
20 def exts(value
, bits
):
21 sign
= 1 << (bits
- 1)
22 return (value
& (sign
- 1)) - (value
& sign
)
26 """ extends sign bit out from current MSB to all 256 bits
28 print ("EXTS", value
, type(value
))
29 assert isinstance(value
, SelectableInt
)
30 return SelectableInt(exts(value
.value
, value
.bits
) & ((1 << 256)-1), 256)
34 """ extends sign bit out from current MSB to 64 bits
36 assert isinstance(value
, SelectableInt
)
37 return SelectableInt(exts(value
.value
, value
.bits
) & ((1 << 64)-1), 64)
41 """ extends sign bit out from current MSB to 128 bits
43 assert isinstance(value
, SelectableInt
)
44 return SelectableInt(exts(value
.value
, value
.bits
) & ((1 << 128)-1), 128)
47 # signed version of MUL
49 if isinstance(b
, int):
50 b
= SelectableInt(b
, self
.bits
)
51 b
= check_extsign(a
, b
)
52 a_s
= a
.value
& (1 << (a
.bits
-1)) != 0
53 b_s
= b
.value
& (1 << (b
.bits
-1)) != 0
54 result
= abs(a
) * abs(b
)
55 print("MULS", result
, a_s
, b_s
)
61 # XXX should this explicitly extend from 32 to 64?
63 if isinstance(value
, SelectableInt
):
65 return SelectableInt(value
& ((1 << 32)-1), 64)
68 def rotl(value
, bits
, wordlen
):
69 if isinstance(bits
, SelectableInt
):
71 mask
= (1 << wordlen
) - 1
72 bits
= bits
& (wordlen
- 1)
73 return ((value
<< bits
) |
(value
>> (wordlen
-bits
))) & mask
76 def ROTL64(value
, bits
):
77 return rotl(value
, bits
, 64)
80 def ROTL32(value
, bits
):
81 if isinstance(bits
, SelectableInt
):
83 if isinstance(value
, SelectableInt
):
84 value
= SelectableInt(value
.value
, 64)
85 return rotl(value |
(value
<< 32), bits
, 64)
88 if isinstance(x
, SelectableInt
):
90 if isinstance(y
, SelectableInt
):
92 return MASK(x
+32, y
+32)
95 if isinstance(x
, SelectableInt
):
97 if isinstance(y
, SelectableInt
):
102 mask_a
= ((1 << x
) - 1) & ((1 << 64) - 1)
103 mask_b
= ((1 << y
) - 1) & ((1 << 64) - 1)
109 mask_a
= ((1 << x
) - 1) & ((1 << 64) - 1)
110 mask_b
= (~
((1 << y
) - 1)) & ((1 << 64) - 1)
111 return mask_a ^ mask_b
115 return onebit(a
!= b
)
119 return onebit(a
== b
)
127 return onebit(a
>= b
)
135 return onebit(a
<= b
)
143 """ function that, for Power spec purposes, returns undefined bits of
144 the same shape as the input bits. however, for purposes of matching
145 POWER9's behavior returns the input bits unchanged. this effectively
146 "marks" (tags) locations in the v3.0B spec that need to be submitted
151 # For these tests I tried to find power instructions that would let me
152 # isolate each of these helper operations. So for instance, when I was
153 # testing the MASK() function, I chose rlwinm and rldicl because if I
154 # set the shift equal to 0 and passed in a value of all ones, the
155 # result I got would be exactly the same as the output of MASK()
158 class HelperTests(unittest
.TestCase
):
160 # Verified using rlwinm, rldicl, rldicr in qemu
162 # rlwinm reg, 1, 0, 5, 15
163 self
.assertHex(MASK(5+32, 15+32), 0x7ff0000)
164 # rlwinm reg, 1, 0, 15, 5
165 self
.assertHex(MASK(15+32, 5+32), 0xfffffffffc01ffff)
166 self
.assertHex(MASK(30+32, 2+32), 0xffffffffe0000003)
167 # rldicl reg, 1, 0, 37
168 self
.assertHex(MASK(37, 63), 0x7ffffff)
169 self
.assertHex(MASK(10, 63), 0x3fffffffffffff)
170 self
.assertHex(MASK(58, 63), 0x3f)
171 # rldicr reg, 1, 0, 37
172 self
.assertHex(MASK(0, 37), 0xfffffffffc000000)
173 self
.assertHex(MASK(0, 10), 0xffe0000000000000)
174 self
.assertHex(MASK(0, 58), 0xffffffffffffffe0)
178 self
.assertHex(MASK(32, 63-5), 0xffffffe0)
180 self
.assertHex(MASK(32, 33), 0xc0000000)
181 self
.assertHex(MASK(32, 32), 0x80000000)
182 self
.assertHex(MASK(33, 33), 0x40000000)
184 def test_ROTL64(self
):
185 # r1 = 0xdeadbeef12345678
186 value
= 0xdeadbeef12345678
188 # rldicl reg, 1, 10, 0
189 self
.assertHex(ROTL64(value
, 10), 0xb6fbbc48d159e37a)
190 # rldicl reg, 1, 35, 0
191 self
.assertHex(ROTL64(value
, 35), 0x91a2b3c6f56df778)
192 self
.assertHex(ROTL64(value
, 58), 0xe37ab6fbbc48d159)
193 self
.assertHex(ROTL64(value
, 22), 0xbbc48d159e37ab6f)
195 def test_ROTL32(self
):
199 # rlwinm reg, 1, 10, 0, 31
200 self
.assertHex(ROTL32(value
, 10), 0xb6fbbf7a)
201 # rlwinm reg, 1, 17, 0, 31
202 self
.assertHex(ROTL32(value
, 17), 0x7ddfbd5b)
203 self
.assertHex(ROTL32(value
, 25), 0xdfbd5b7d)
204 self
.assertHex(ROTL32(value
, 30), 0xf7ab6fbb)
206 def test_EXTS64(self
):
207 value_a
= SelectableInt(0xdeadbeef, 32) # r1
208 value_b
= SelectableInt(0x73123456, 32) # r2
209 value_c
= SelectableInt(0x80000000, 32) # r3
212 self
.assertHex(EXTS64(value_a
), 0xffffffffdeadbeef)
214 self
.assertHex(EXTS64(value_b
), SelectableInt(value_b
.value
, 64))
216 self
.assertHex(EXTS64(value_c
), 0xffffffff80000000)
218 def assertHex(self
, a
, b
):
220 if isinstance(a
, SelectableInt
):
223 if isinstance(b
, SelectableInt
):
225 msg
= "{:x} != {:x}".format(a_val
, b_val
)
226 return self
.assertEqual(a
, b
, msg
)
229 if __name__
== '__main__':
230 print(SelectableInt
.__bases
__)