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
)
132 # For these tests I tried to find power instructions that would let me
133 # isolate each of these helper operations. So for instance, when I was
134 # testing the MASK() function, I chose rlwinm and rldicl because if I
135 # set the shift equal to 0 and passed in a value of all ones, the
136 # result I got would be exactly the same as the output of MASK()
139 class HelperTests(unittest
.TestCase
):
141 # Verified using rlwinm, rldicl, rldicr in qemu
143 # rlwinm reg, 1, 0, 5, 15
144 self
.assertHex(MASK(5+32, 15+32), 0x7ff0000)
145 # rlwinm reg, 1, 0, 15, 5
146 self
.assertHex(MASK(15+32, 5+32), 0xfffffffffc01ffff)
147 self
.assertHex(MASK(30+32, 2+32), 0xffffffffe0000003)
148 # rldicl reg, 1, 0, 37
149 self
.assertHex(MASK(37, 63), 0x7ffffff)
150 self
.assertHex(MASK(10, 63), 0x3fffffffffffff)
151 self
.assertHex(MASK(58, 63), 0x3f)
152 # rldicr reg, 1, 0, 37
153 self
.assertHex(MASK(0, 37), 0xfffffffffc000000)
154 self
.assertHex(MASK(0, 10), 0xffe0000000000000)
155 self
.assertHex(MASK(0, 58), 0xffffffffffffffe0)
159 self
.assertHex(MASK(32, 63-5), 0xffffffe0)
161 self
.assertHex(MASK(32, 33), 0xc0000000)
162 self
.assertHex(MASK(32, 32), 0x80000000)
163 self
.assertHex(MASK(33, 33), 0x40000000)
165 def test_ROTL64(self
):
166 # r1 = 0xdeadbeef12345678
167 value
= 0xdeadbeef12345678
169 # rldicl reg, 1, 10, 0
170 self
.assertHex(ROTL64(value
, 10), 0xb6fbbc48d159e37a)
171 # rldicl reg, 1, 35, 0
172 self
.assertHex(ROTL64(value
, 35), 0x91a2b3c6f56df778)
173 self
.assertHex(ROTL64(value
, 58), 0xe37ab6fbbc48d159)
174 self
.assertHex(ROTL64(value
, 22), 0xbbc48d159e37ab6f)
176 def test_ROTL32(self
):
180 # rlwinm reg, 1, 10, 0, 31
181 self
.assertHex(ROTL32(value
, 10), 0xb6fbbf7a)
182 # rlwinm reg, 1, 17, 0, 31
183 self
.assertHex(ROTL32(value
, 17), 0x7ddfbd5b)
184 self
.assertHex(ROTL32(value
, 25), 0xdfbd5b7d)
185 self
.assertHex(ROTL32(value
, 30), 0xf7ab6fbb)
187 def test_EXTS64(self
):
188 value_a
= SelectableInt(0xdeadbeef, 32) # r1
189 value_b
= SelectableInt(0x73123456, 32) # r2
190 value_c
= SelectableInt(0x80000000, 32) # r3
193 self
.assertHex(EXTS64(value_a
), 0xffffffffdeadbeef)
195 self
.assertHex(EXTS64(value_b
), SelectableInt(value_b
.value
, 64))
197 self
.assertHex(EXTS64(value_c
), 0xffffffff80000000)
199 def assertHex(self
, a
, b
):
201 if isinstance(a
, SelectableInt
):
204 if isinstance(b
, SelectableInt
):
206 msg
= "{:x} != {:x}".format(a_val
, b_val
)
207 return self
.assertEqual(a
, b
, msg
)
210 if __name__
== '__main__':
211 print(SelectableInt
.__bases
__)