2 from soc
.decoder
.selectable_int
import SelectableInt
, onebit
3 from nmutil
.divmod import trunc_divs
, trunc_rems
4 from operator
import floordiv
, mod
5 from soc
.decoder
.selectable_int
import selectltu
as ltu
6 from soc
.decoder
.selectable_int
import selectgtu
as gtu
7 from soc
.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."""
139 # For these tests I tried to find power instructions that would let me
140 # isolate each of these helper operations. So for instance, when I was
141 # testing the MASK() function, I chose rlwinm and rldicl because if I
142 # set the shift equal to 0 and passed in a value of all ones, the
143 # result I got would be exactly the same as the output of MASK()
146 class HelperTests(unittest
.TestCase
):
148 # Verified using rlwinm, rldicl, rldicr in qemu
150 # rlwinm reg, 1, 0, 5, 15
151 self
.assertHex(MASK(5+32, 15+32), 0x7ff0000)
152 # rlwinm reg, 1, 0, 15, 5
153 self
.assertHex(MASK(15+32, 5+32), 0xfffffffffc01ffff)
154 self
.assertHex(MASK(30+32, 2+32), 0xffffffffe0000003)
155 # rldicl reg, 1, 0, 37
156 self
.assertHex(MASK(37, 63), 0x7ffffff)
157 self
.assertHex(MASK(10, 63), 0x3fffffffffffff)
158 self
.assertHex(MASK(58, 63), 0x3f)
159 # rldicr reg, 1, 0, 37
160 self
.assertHex(MASK(0, 37), 0xfffffffffc000000)
161 self
.assertHex(MASK(0, 10), 0xffe0000000000000)
162 self
.assertHex(MASK(0, 58), 0xffffffffffffffe0)
166 self
.assertHex(MASK(32, 63-5), 0xffffffe0)
168 self
.assertHex(MASK(32, 33), 0xc0000000)
169 self
.assertHex(MASK(32, 32), 0x80000000)
170 self
.assertHex(MASK(33, 33), 0x40000000)
172 def test_ROTL64(self
):
173 # r1 = 0xdeadbeef12345678
174 value
= 0xdeadbeef12345678
176 # rldicl reg, 1, 10, 0
177 self
.assertHex(ROTL64(value
, 10), 0xb6fbbc48d159e37a)
178 # rldicl reg, 1, 35, 0
179 self
.assertHex(ROTL64(value
, 35), 0x91a2b3c6f56df778)
180 self
.assertHex(ROTL64(value
, 58), 0xe37ab6fbbc48d159)
181 self
.assertHex(ROTL64(value
, 22), 0xbbc48d159e37ab6f)
183 def test_ROTL32(self
):
187 # rlwinm reg, 1, 10, 0, 31
188 self
.assertHex(ROTL32(value
, 10), 0xb6fbbf7a)
189 # rlwinm reg, 1, 17, 0, 31
190 self
.assertHex(ROTL32(value
, 17), 0x7ddfbd5b)
191 self
.assertHex(ROTL32(value
, 25), 0xdfbd5b7d)
192 self
.assertHex(ROTL32(value
, 30), 0xf7ab6fbb)
194 def test_EXTS64(self
):
195 value_a
= SelectableInt(0xdeadbeef, 32) # r1
196 value_b
= SelectableInt(0x73123456, 32) # r2
197 value_c
= SelectableInt(0x80000000, 32) # r3
200 self
.assertHex(EXTS64(value_a
), 0xffffffffdeadbeef)
202 self
.assertHex(EXTS64(value_b
), SelectableInt(value_b
.value
, 64))
204 self
.assertHex(EXTS64(value_c
), 0xffffffff80000000)
206 def assertHex(self
, a
, b
):
208 if isinstance(a
, SelectableInt
):
211 if isinstance(b
, SelectableInt
):
213 msg
= "{:x} != {:x}".format(a_val
, b_val
)
214 return self
.assertEqual(a
, b
, msg
)
217 if __name__
== '__main__':
218 print(SelectableInt
.__bases
__)