b54bcfd86233f50a5467347458547c8e6fd7cec7
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 assert isinstance(value
, SelectableInt
)
29 return SelectableInt(exts(value
.value
, value
.bits
) & ((1 << 256)-1), 256)
33 """ extends sign bit out from current MSB to 64 bits
35 assert isinstance(value
, SelectableInt
)
36 return SelectableInt(exts(value
.value
, value
.bits
) & ((1 << 64)-1), 64)
40 """ extends sign bit out from current MSB to 128 bits
42 assert isinstance(value
, SelectableInt
)
43 return SelectableInt(exts(value
.value
, value
.bits
) & ((1 << 128)-1), 128)
46 # signed version of MUL
48 if isinstance(b
, int):
49 b
= SelectableInt(b
, self
.bits
)
50 b
= check_extsign(a
, b
)
51 a_s
= a
.value
& (1 << (a
.bits
-1)) != 0
52 b_s
= b
.value
& (1 << (b
.bits
-1)) != 0
53 result
= abs(a
) * abs(b
)
54 print("MULS", result
, a_s
, b_s
)
60 # XXX should this explicitly extend from 32 to 64?
62 if isinstance(value
, SelectableInt
):
64 return SelectableInt(value
& ((1 << 32)-1), 64)
67 def rotl(value
, bits
, wordlen
):
68 if isinstance(bits
, SelectableInt
):
70 mask
= (1 << wordlen
) - 1
71 bits
= bits
& (wordlen
- 1)
72 return ((value
<< bits
) |
(value
>> (wordlen
-bits
))) & mask
75 def ROTL64(value
, bits
):
76 return rotl(value
, bits
, 64)
79 def ROTL32(value
, bits
):
80 if isinstance(value
, SelectableInt
):
81 value
= SelectableInt(value
.value
, 64)
82 return rotl(value |
(value
<< 32), bits
, 64)
86 if isinstance(x
, SelectableInt
):
88 if isinstance(y
, SelectableInt
):
93 mask_a
= ((1 << x
) - 1) & ((1 << 64) - 1)
94 mask_b
= ((1 << y
) - 1) & ((1 << 64) - 1)
100 mask_a
= ((1 << x
) - 1) & ((1 << 64) - 1)
101 mask_b
= (~
((1 << y
) - 1)) & ((1 << 64) - 1)
102 return mask_a ^ mask_b
106 return onebit(a
!= b
)
110 return onebit(a
== b
)
118 return onebit(a
>= b
)
126 return onebit(a
<= b
)
134 """ function that, for Power spec purposes, returns undefined bits of
135 the same shape as the input bits. however, for purposes of matching
136 POWER9's behavior returns the input bits unchanged. this effectively
137 "marks" (tags) locations in the v3.0B spec that need to be submitted
142 # For these tests I tried to find power instructions that would let me
143 # isolate each of these helper operations. So for instance, when I was
144 # testing the MASK() function, I chose rlwinm and rldicl because if I
145 # set the shift equal to 0 and passed in a value of all ones, the
146 # result I got would be exactly the same as the output of MASK()
149 class HelperTests(unittest
.TestCase
):
151 # Verified using rlwinm, rldicl, rldicr in qemu
153 # rlwinm reg, 1, 0, 5, 15
154 self
.assertHex(MASK(5+32, 15+32), 0x7ff0000)
155 # rlwinm reg, 1, 0, 15, 5
156 self
.assertHex(MASK(15+32, 5+32), 0xfffffffffc01ffff)
157 self
.assertHex(MASK(30+32, 2+32), 0xffffffffe0000003)
158 # rldicl reg, 1, 0, 37
159 self
.assertHex(MASK(37, 63), 0x7ffffff)
160 self
.assertHex(MASK(10, 63), 0x3fffffffffffff)
161 self
.assertHex(MASK(58, 63), 0x3f)
162 # rldicr reg, 1, 0, 37
163 self
.assertHex(MASK(0, 37), 0xfffffffffc000000)
164 self
.assertHex(MASK(0, 10), 0xffe0000000000000)
165 self
.assertHex(MASK(0, 58), 0xffffffffffffffe0)
169 self
.assertHex(MASK(32, 63-5), 0xffffffe0)
171 self
.assertHex(MASK(32, 33), 0xc0000000)
172 self
.assertHex(MASK(32, 32), 0x80000000)
173 self
.assertHex(MASK(33, 33), 0x40000000)
175 def test_ROTL64(self
):
176 # r1 = 0xdeadbeef12345678
177 value
= 0xdeadbeef12345678
179 # rldicl reg, 1, 10, 0
180 self
.assertHex(ROTL64(value
, 10), 0xb6fbbc48d159e37a)
181 # rldicl reg, 1, 35, 0
182 self
.assertHex(ROTL64(value
, 35), 0x91a2b3c6f56df778)
183 self
.assertHex(ROTL64(value
, 58), 0xe37ab6fbbc48d159)
184 self
.assertHex(ROTL64(value
, 22), 0xbbc48d159e37ab6f)
186 def test_ROTL32(self
):
190 # rlwinm reg, 1, 10, 0, 31
191 self
.assertHex(ROTL32(value
, 10), 0xb6fbbf7a)
192 # rlwinm reg, 1, 17, 0, 31
193 self
.assertHex(ROTL32(value
, 17), 0x7ddfbd5b)
194 self
.assertHex(ROTL32(value
, 25), 0xdfbd5b7d)
195 self
.assertHex(ROTL32(value
, 30), 0xf7ab6fbb)
197 def test_EXTS64(self
):
198 value_a
= SelectableInt(0xdeadbeef, 32) # r1
199 value_b
= SelectableInt(0x73123456, 32) # r2
200 value_c
= SelectableInt(0x80000000, 32) # r3
203 self
.assertHex(EXTS64(value_a
), 0xffffffffdeadbeef)
205 self
.assertHex(EXTS64(value_b
), SelectableInt(value_b
.value
, 64))
207 self
.assertHex(EXTS64(value_c
), 0xffffffff80000000)
209 def assertHex(self
, a
, b
):
211 if isinstance(a
, SelectableInt
):
214 if isinstance(b
, SelectableInt
):
216 msg
= "{:x} != {:x}".format(a_val
, b_val
)
217 return self
.assertEqual(a
, b
, msg
)
220 if __name__
== '__main__':
221 print(SelectableInt
.__bases
__)