1 from openpower
.test
.common
import TestAccumulatorBase
, skip_case
2 from openpower
.sv
.trans
.svp64
import SVP64Asm
3 from openpower
.test
.state
import ExpectedState
4 from openpower
.simulator
.program
import Program
5 from openpower
.decoder
.isa
.caller
import SVP64State
6 from openpower
.fpscr
import FPSCRState
7 from openpower
.consts
import MSR
13 @functools.lru_cache()
14 def _cached_program(*instrs
):
15 return Program(list(SVP64Asm(list(instrs
))), bigendian
=False)
18 def bitcast_int_to_fp(bits
, bfp32
):
20 return struct
.unpack("<f", struct
.pack("<L", bits
))[0]
21 return struct
.unpack("<d", struct
.pack("<Q", bits
))[0]
24 def bitcast_fp_to_int(fp
, bfp32
):
26 return struct
.unpack("<L", struct
.pack("<f", fp
))[0]
27 return struct
.unpack("<Q", struct
.pack("<d", fp
))[0]
30 def fp_bits_add(fp
, amount
, bfp32
=False):
31 """add `amount` to the IEEE 754 bits representing `fp`"""
32 return bitcast_int_to_fp(amount
+ bitcast_fp_to_int(fp
, bfp32
), bfp32
)
36 """round v to the nearest integer, with ties rounding to the even integer
39 return int(v
- math
.remainder(v
, 1.0))
42 def do_round(v
, round_mode
):
51 assert False, "invalid round_mode"
54 class FMvFCvtCases(TestAccumulatorBase
):
55 def toint_helper(self
, *, inp
, expected
=None, test_title
="", inp_bits
=None,
56 signed
=True, _32bit
=True, CVM
, RN
, VE
):
58 round_mode
= 1 # trunc
70 inp_bits
= struct
.unpack("<Q", struct
.pack("<d", inp
))[0]
72 if CVM
>> 1 == 0: # openpower semantics
80 expected
= do_round(inp
, round_mode
)
81 elif CVM
>> 1 == 1: # saturating semantics
89 expected
= do_round(inp
, round_mode
)
90 elif CVM
>> 1 == 2: # js semantics
91 if math
.isfinite(inp
):
92 expected
= do_round(inp
, round_mode
)
97 if signed
and expected
>> 31:
100 IT
= (not signed
) + (not _32bit
) * 2
101 with self
.subTest(inp
=inp
.hex(), inp_bits
=hex(inp_bits
),
102 test_title
=test_title
,
103 signed
=signed
, _32bit
=_32bit
, CVM
=CVM
, RN
=RN
, VE
=VE
):
104 lst
= [f
"fcvttgo. 3,0,{CVM},{IT}"]
108 gprs
[3] = 0xabcdef9876543210
109 initial_fpscr
= FPSCRState()
110 initial_fpscr
.RN
= RN
111 initial_fpscr
.VE
= VE
112 e
= ExpectedState(pc
=4, int_regs
=gprs
, fp_regs
=fprs
)
113 fpscr
= FPSCRState(initial_fpscr
)
114 if math
.isnan(inp
) and (inp_bits
& 2 ** 51) == 0: # SNaN
118 if math
.isfinite(inp
):
119 overflow
= not (min_v
<= do_round(inp
, round_mode
) <= max_v
)
125 elif do_round(inp
, round_mode
) != inp
: # inexact
129 fpscr
.FPRF
= 0 # undefined value we happen to pick
131 fpscr
.FR
= abs(do_round(inp
, round_mode
)) > abs(inp
)
132 if overflow
and fpscr
.VE
:
133 # FIXME: #1087 proposes to change pseudocode of fcvt* to
134 # always write output, this implements reading RT when output
135 # isn't written, which is terrible
136 # https://bugs.libre-soc.org/show_bug.cgi?id=1087#c21
137 expected
= e
.intregs
[3]
139 e
.sprs
['SRR0'] = 0 # insn is at address 0
140 e
.sprs
['SRR1'] = e
.msr |
(1 << (63 - 43))
141 e
.msr
= 0x9000000000000001
142 lt
= bool(expected
& (1 << 63))
143 gt
= not lt
and expected
!= 0
145 e
.crregs
[0] = (lt
<< 3) |
(gt
<< 2) |
(eq
<< 1) | e
.so
146 e
.intregs
[3] = expected
147 with self
.subTest(expected_VXSNAN
=fpscr
.VXSNAN
,
148 expected_VXCVI
=fpscr
.VXCVI
,
149 expected_XX
=fpscr
.XX
,
150 expected_FI
=fpscr
.FI
,
151 expected
=hex(expected
)):
154 _cached_program(*lst
), gprs
, fpregs
=fprs
, expected
=e
,
155 initial_fpscr
=int(initial_fpscr
))
157 def toint(self
, inp
, expected
=None, test_title
="", inp_bits
=None,
158 signed
=True, _32bit
=True):
160 for RN
in range(1 if CVM
& 1 else 4):
163 inp
=inp
, expected
=expected
if CVM
== 5 else None,
164 test_title
=test_title
, inp_bits
=inp_bits
,
165 signed
=signed
, _32bit
=_32bit
, CVM
=CVM
, RN
=RN
, VE
=VE
)
167 def case_js_toint32(self
):
168 min_value
= pow(2, -1074)
170 # https://chromium.googlesource.com/v8/v8.git/+/d94dfc2b01f988566aa410ce871588cf23b1285d/test/mjsunit/toint32.js
171 # Copyright 2008 the V8 project authors. All rights reserved.
172 # Redistribution and use in source and binary forms, with or without
173 # modification, are permitted provided that the following conditions are
176 # * Redistributions of source code must retain the above copyright
177 # notice, this list of conditions and the following disclaimer.
178 # * Redistributions in binary form must reproduce the above
179 # copyright notice, this list of conditions and the following
180 # disclaimer in the documentation and/or other materials provided
181 # with the distribution.
182 # * Neither the name of Google Inc. nor the names of its
183 # contributors may be used to endorse or promote products derived
184 # from this software without specific prior written permission.
186 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
187 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
188 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
189 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
190 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
191 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
192 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
193 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
194 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
195 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
196 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
198 self
.toint(math
.inf
, 0, "Inf")
199 self
.toint(-math
.inf
, 0, "-Inf")
200 self
.toint(math
.nan
, 0, "NaN")
201 self
.toint(math
.nan
, 0, "SNaN", inp_bits
=0x7ff0_0000_0000_0001)
202 self
.toint(0.0, 0, "zero")
203 self
.toint(-0.0, 0, "-zero")
204 self
.toint(min_value
, 0)
205 self
.toint(-min_value
, 0)
208 self
.toint(1, 1, "one")
209 self
.toint(1.1, 1, "onepointone")
210 self
.toint(-1, -1, "-one")
211 self
.toint(0.6, 0, "truncate positive (0.6)")
212 self
.toint(1.6, 1, "truncate positive (1.6)")
213 self
.toint(-0.6, 0, "truncate negative (-0.6)")
214 self
.toint(-1.6, -1, "truncate negative (-1.6)")
215 self
.toint(2147483647, 2147483647)
216 self
.toint(2147483648, -2147483648)
217 self
.toint(2147483649, -2147483647)
218 self
.toint(4294967295, -1)
219 self
.toint(4294967296, 0)
220 self
.toint(4294967297, 1)
221 self
.toint(-2147483647, -2147483647)
222 self
.toint(-2147483648, -2147483648)
223 self
.toint(-2147483649, 2147483647)
224 self
.toint(-4294967295, 1)
225 self
.toint(-4294967296, 0)
226 self
.toint(-4294967297, -1)
227 self
.toint(2147483648.25, -2147483648)
228 self
.toint(2147483648.5, -2147483648)
229 self
.toint(2147483648.75, -2147483648)
230 self
.toint(4294967295.25, -1)
231 self
.toint(4294967295.5, -1)
232 self
.toint(4294967295.75, -1)
233 self
.toint(3000000000.25, -1294967296)
234 self
.toint(3000000000.5, -1294967296)
235 self
.toint(3000000000.75, -1294967296)
236 self
.toint(-2147483648.25, -2147483648)
237 self
.toint(-2147483648.5, -2147483648)
238 self
.toint(-2147483648.75, -2147483648)
239 self
.toint(-4294967295.25, 1)
240 self
.toint(-4294967295.5, 1)
241 self
.toint(-4294967295.75, 1)
242 self
.toint(-3000000000.25, 1294967296)
243 self
.toint(-3000000000.5, 1294967296)
244 self
.toint(-3000000000.75, 1294967296)
246 self
.toint(base
+ 0, 0)
247 self
.toint(base
+ 1117, 0)
248 self
.toint(base
+ 2234, 4096)
249 self
.toint(base
+ 3351, 4096)
250 self
.toint(base
+ 4468, 4096)
251 self
.toint(base
+ 5585, 4096)
252 self
.toint(base
+ 6702, 8192)
253 self
.toint(base
+ 7819, 8192)
254 self
.toint(base
+ 8936, 8192)
255 self
.toint(base
+ 10053, 8192)
256 self
.toint(base
+ 11170, 12288)
257 self
.toint(base
+ 12287, 12288)
258 self
.toint(base
+ 13404, 12288)
259 self
.toint(base
+ 14521, 16384)
260 self
.toint(base
+ 15638, 16384)
261 self
.toint(base
+ 16755, 16384)
262 self
.toint(base
+ 17872, 16384)
263 self
.toint(base
+ 18989, 20480)
264 self
.toint(base
+ 20106, 20480)
265 self
.toint(base
+ 21223, 20480)
266 self
.toint(base
+ 22340, 20480)
267 self
.toint(base
+ 23457, 24576)
268 self
.toint(base
+ 24574, 24576)
269 self
.toint(base
+ 25691, 24576)
270 self
.toint(base
+ 26808, 28672)
271 self
.toint(base
+ 27925, 28672)
272 self
.toint(base
+ 29042, 28672)
273 self
.toint(base
+ 30159, 28672)
274 self
.toint(base
+ 31276, 32768)
275 # bignum is (2 ^ 53 - 1) * 2 ^ 31 - highest number with bit 31 set.
276 bignum
= pow(2, 84) - pow(2, 31)
277 self
.toint(bignum
, -pow(2, 31))
278 self
.toint(-bignum
, -pow(2, 31))
279 self
.toint(2 * bignum
, 0)
280 self
.toint(-(2 * bignum
), 0)
281 self
.toint(bignum
- pow(2, 31), 0)
282 self
.toint(-(bignum
- pow(2, 31)), 0)
283 # max_fraction is largest number below 1.
284 max_fraction
= (1 - pow(2, -53))
285 self
.toint(max_fraction
, 0)
286 self
.toint(-max_fraction
, 0)
288 def case_js_touint32(self
):
289 min_value
= pow(2, -1074)
291 # https://chromium.googlesource.com/v8/v8.git/+/d94dfc2b01f988566aa410ce871588cf23b1285d/test/mjsunit/touint32.js
292 # with identical copyright notice as in case_js_toint32
293 self
.toint(0, 0, "0", signed
=False)
294 self
.toint(-0, 0, "-0", signed
=False)
295 self
.toint(math
.inf
, 0, "Infinity", signed
=False)
296 self
.toint(-math
.inf
, 0, "-Infinity", signed
=False)
297 self
.toint(math
.nan
, 0, "NaN", signed
=False)
298 self
.toint(math
.nan
, 0, "SNaN", inp_bits
=0x7ff0_0000_0000_0001,
300 self
.toint(min_value
, 0, "MIN", signed
=False)
301 self
.toint(-min_value
, 0, "-MIN", signed
=False)
302 self
.toint(0.1, 0, "0.1", signed
=False)
303 self
.toint(-0.1, 0, "-0.1", signed
=False)
304 self
.toint(1, 1, "1", signed
=False)
305 self
.toint(1.1, 1, "1.1", signed
=False)
306 self
.toint(-1, 4294967295, "-1", signed
=False)
307 self
.toint(-1.1, 4294967295, "-1.1", signed
=False)
308 self
.toint(2147483647, 2147483647, "2147483647", signed
=False)
309 self
.toint(2147483648, 2147483648, "2147483648", signed
=False)
310 self
.toint(2147483649, 2147483649, "2147483649", signed
=False)
311 self
.toint(4294967295, 4294967295, "4294967295", signed
=False)
312 self
.toint(4294967296, 0, "4294967296", signed
=False)
313 self
.toint(4294967297, 1, "4294967297", signed
=False)
314 self
.toint(-2147483647, 2147483649, "-2147483647", signed
=False)
315 self
.toint(-2147483648, 2147483648, "-2147483648", signed
=False)
316 self
.toint(-2147483649, 2147483647, "-2147483649", signed
=False)
317 self
.toint(-4294967295, 1, "-4294967295", signed
=False)
318 self
.toint(-4294967296, 0, "-4294967296", signed
=False)
319 self
.toint(-4294967297, 4294967295, "-4294967297", signed
=False)
321 def case_js_toint64(self
):
322 # 64-bit equivalent of javascript's toint32
323 min_value
= pow(2, -1074)
324 # test cases derived from:
325 # https://chromium.googlesource.com/v8/v8.git/+/d94dfc2b01f988566aa410ce871588cf23b1285d/test/mjsunit/toint32.js
326 # with identical copyright notice as in case_js_toint32
328 self
.toint(math
.inf
, 0, "Inf", _32bit
=False)
329 self
.toint(-math
.inf
, 0, "-Inf", _32bit
=False)
330 self
.toint(math
.nan
, 0, "NaN", _32bit
=False)
331 self
.toint(math
.nan
, 0, "SNaN",
332 inp_bits
=0x7ff0_0000_0000_0001, _32bit
=False)
333 self
.toint(0.0, 0, "zero", _32bit
=False)
334 self
.toint(-0.0, 0, "-zero", _32bit
=False)
335 self
.toint(min_value
, 0, _32bit
=False)
336 self
.toint(-min_value
, 0, _32bit
=False)
337 self
.toint(0.1, 0, _32bit
=False)
338 self
.toint(-0.1, 0, _32bit
=False)
339 self
.toint(1, 1, "one", _32bit
=False)
340 self
.toint(1.1, 1, "onepointone", _32bit
=False)
341 self
.toint(-1, -1, "-one", _32bit
=False)
342 self
.toint(0.6, 0, "truncate positive (0.6)", _32bit
=False)
343 self
.toint(1.6, 1, "truncate positive (1.6)", _32bit
=False)
344 self
.toint(-0.6, 0, "truncate negative (-0.6)", _32bit
=False)
345 self
.toint(-1.6, -1, "truncate negative (-1.6)", _32bit
=False)
346 self
.toint(fp_bits_add(2**63, -1), _32bit
=False)
347 self
.toint(2**63, _32bit
=False)
348 self
.toint(fp_bits_add(2**63, 1), _32bit
=False)
349 self
.toint(fp_bits_add(2**64, -1), _32bit
=False)
350 self
.toint(2**64, 0, _32bit
=False)
351 self
.toint(fp_bits_add(2**64, 1), _32bit
=False)
352 self
.toint(-fp_bits_add(2**63, -1), _32bit
=False)
353 self
.toint(-(2**63), _32bit
=False)
354 self
.toint(-fp_bits_add(2**63, 1), _32bit
=False)
355 self
.toint(-fp_bits_add(2**64, -1), _32bit
=False)
356 self
.toint(-(2**64), 0, _32bit
=False)
357 self
.toint(-fp_bits_add(2**64, 1), _32bit
=False)
358 self
.toint(2147483648.25, _32bit
=False)
359 self
.toint(2147483648.5, _32bit
=False)
360 self
.toint(2147483648.75, _32bit
=False)
361 self
.toint(4294967295.25, _32bit
=False)
362 self
.toint(4294967295.5, _32bit
=False)
363 self
.toint(4294967295.75, _32bit
=False)
364 self
.toint(3000000000.25, _32bit
=False)
365 self
.toint(3000000000.5, _32bit
=False)
366 self
.toint(3000000000.75, _32bit
=False)
367 self
.toint(-2147483648.25, _32bit
=False)
368 self
.toint(-2147483648.5, _32bit
=False)
369 self
.toint(-2147483648.75, _32bit
=False)
370 self
.toint(-4294967295.25, _32bit
=False)
371 self
.toint(-4294967295.5, _32bit
=False)
372 self
.toint(-4294967295.75, _32bit
=False)
373 self
.toint(-3000000000.25, _32bit
=False)
374 self
.toint(-3000000000.5, _32bit
=False)
375 self
.toint(-3000000000.75, _32bit
=False)
377 self
.toint(base
+ 0, _32bit
=False)
378 self
.toint(base
+ 1117, _32bit
=False)
379 self
.toint(base
+ 2234, _32bit
=False)
380 self
.toint(base
+ 3351, _32bit
=False)
381 self
.toint(base
+ 4468, _32bit
=False)
382 self
.toint(base
+ 5585, _32bit
=False)
383 self
.toint(base
+ 6702, _32bit
=False)
384 self
.toint(base
+ 7819, _32bit
=False)
385 self
.toint(base
+ 8936, _32bit
=False)
386 self
.toint(base
+ 10053, _32bit
=False)
387 self
.toint(base
+ 11170, _32bit
=False)
388 self
.toint(base
+ 12287, _32bit
=False)
389 self
.toint(base
+ 13404, _32bit
=False)
390 self
.toint(base
+ 14521, _32bit
=False)
391 self
.toint(base
+ 15638, _32bit
=False)
392 self
.toint(base
+ 16755, _32bit
=False)
393 self
.toint(base
+ 17872, _32bit
=False)
394 self
.toint(base
+ 18989, _32bit
=False)
395 self
.toint(base
+ 20106, _32bit
=False)
396 self
.toint(base
+ 21223, _32bit
=False)
397 self
.toint(base
+ 22340, _32bit
=False)
398 self
.toint(base
+ 23457, _32bit
=False)
399 self
.toint(base
+ 24574, _32bit
=False)
400 self
.toint(base
+ 25691, _32bit
=False)
401 self
.toint(base
+ 26808, _32bit
=False)
402 self
.toint(base
+ 27925, _32bit
=False)
403 self
.toint(base
+ 29042, _32bit
=False)
404 self
.toint(base
+ 30159, _32bit
=False)
405 self
.toint(base
+ 31276, _32bit
=False)
406 # bignum is (2 ^ 53 - 1) * 2 ^ 31 - highest number with bit 31 set.
407 bignum
= pow(2, 84) - pow(2, 31)
408 self
.toint(bignum
, _32bit
=False)
409 self
.toint(-bignum
, _32bit
=False)
410 self
.toint(2 * bignum
, _32bit
=False)
411 self
.toint(-(2 * bignum
), _32bit
=False)
412 self
.toint(bignum
- pow(2, 31), _32bit
=False)
413 self
.toint(-(bignum
- pow(2, 31)), _32bit
=False)
414 # max_fraction is largest number below 1.
415 max_fraction
= (1 - pow(2, -53))
416 self
.toint(max_fraction
, 0, _32bit
=False)
417 self
.toint(-max_fraction
, 0, _32bit
=False)
419 def case_js_touint64(self
):
420 # 64-bit equivalent of javascript's touint32
421 min_value
= pow(2, -1074)
422 # test cases derived from:
423 # https://chromium.googlesource.com/v8/v8.git/+/d94dfc2b01f988566aa410ce871588cf23b1285d/test/mjsunit/touint32.js
424 # with identical copyright notice as in case_js_toint32
425 self
.toint(0, 0, "0", signed
=False, _32bit
=False)
426 self
.toint(-0, 0, "-0", signed
=False, _32bit
=False)
427 self
.toint(math
.inf
, 0, "Infinity", signed
=False, _32bit
=False)
428 self
.toint(-math
.inf
, 0, "-Infinity", signed
=False, _32bit
=False)
429 self
.toint(math
.nan
, 0, "NaN", signed
=False, _32bit
=False)
430 self
.toint(math
.nan
, 0, "SNaN", inp_bits
=0x7ff0_0000_0000_0001,
431 signed
=False, _32bit
=False)
432 self
.toint(min_value
, 0, "MIN", signed
=False, _32bit
=False)
433 self
.toint(-min_value
, 0, "-MIN", signed
=False, _32bit
=False)
434 self
.toint(0.1, 0, "0.1", signed
=False, _32bit
=False)
435 self
.toint(-0.1, 0, "-0.1", signed
=False, _32bit
=False)
436 self
.toint(1, 1, "1", signed
=False, _32bit
=False)
437 self
.toint(1.1, 1, "1.1", signed
=False, _32bit
=False)
438 self
.toint(-1, 2**64 - 1, "-1", signed
=False, _32bit
=False)
439 self
.toint(-1.1, 2**64 - 1, "-1.1", signed
=False, _32bit
=False)
440 self
.toint(fp_bits_add(2**63, -1), signed
=False, _32bit
=False)
441 self
.toint(2**63, signed
=False, _32bit
=False)
442 self
.toint(fp_bits_add(2**63, 1), signed
=False, _32bit
=False)
443 self
.toint(fp_bits_add(2**64, -1), signed
=False, _32bit
=False)
444 self
.toint(2**64, 0, signed
=False, _32bit
=False)
445 self
.toint(fp_bits_add(2**64, 1), signed
=False, _32bit
=False)
446 self
.toint(-fp_bits_add(2**63, -1), signed
=False, _32bit
=False)
447 self
.toint(-(2**63), signed
=False, _32bit
=False)
448 self
.toint(-fp_bits_add(2**63, 1), signed
=False, _32bit
=False)
449 self
.toint(-fp_bits_add(2**64, -1), signed
=False, _32bit
=False)
450 self
.toint(-(2**64), 0, signed
=False, _32bit
=False)
451 self
.toint(-fp_bits_add(2**64, 1), signed
=False, _32bit
=False)
453 @skip_case("FIXME: WIP")
454 def fcvtfg_one(self
, inp
, bfp32
, IT
, Rc
, RN
):
456 inp_width
= 64 if IT
& 0b10 else 32
457 inp_value
= inp
% 2 ** inp_width
460 if inp_value
>> (inp_width
- 1):
462 inp_value
-= 2 ** inp_width
463 # cast to nearby f32/f64
464 inp_fp
= fp_bits_add(inp_value
, 0, bfp32
=bfp32
)
465 if inp_fp
== inp_value
: # exact conversion -- no rounding necessary
467 expected_bits
= bitcast_fp_to_int(expected_fp
, bfp32
=False)
469 # get the fp value on either side of the exact value.
470 # we need to get several values and select 2 because int -> fp
471 # conversion in fp_bits_add could be off by a bit due to
472 # rounding/double-rounding.
473 # we can ignore weirdness around infinity because input values
474 # can't get big enough to convert to infinity for bfp32/64.
475 # we can ignore weirdness around zero because small integers
476 # always convert exactly, and therefore don't reach this
479 fp_bits_add(inp_value
, i
, bfp32
=bfp32
) for i
in range(-2, 3))
480 while fp_values
[-2] > inp_value
:
482 prev_fp
= fp_values
[-2]
483 next_fp
= fp_values
[-1]
484 # if fp values are big enough to not be exact, they are always
486 prev_int
= int(prev_fp
)
487 next_int
= int(next_fp
)
488 prev_fp_is_even
= bitcast_fp_to_int(prev_fp
, bfp32
=bfp32
) & 1 == 0
489 halfway
= 2 * inp_value
== prev_int
+ next_int
490 next_is_closer
= 2 * inp_value
> prev_int
+ next_int
493 use_prev
= (halfway
and prev_fp_is_even
) or not next_is_closer
496 use_prev
= abs(prev_int
) < abs(next_int
)
501 assert RN
== 3, "invalid RN"
505 expected_fp
= prev_fp
507 expected_fp
= next_fp
508 expected_bits
= bitcast_fp_to_int(expected_fp
, bfp32
=False)
509 initial_fpscr
= FPSCRState()
510 initial_fpscr
.RN
= RN
511 fpscr
= FPSCRState(initial_fpscr
)
512 if expected_fp
!= inp_value
:
516 fpscr
.FR
= abs(expected_fp
) > abs(inp_value
)
518 fpscr
.FPRF
= "- Normal Number"
519 elif expected_fp
> 0:
520 fpscr
.FPRF
= "+ Normal Number"
522 # integer conversion never gives -0.0
523 fpscr
.FPRF
= "+ Zero"
524 if inp_width
== 32 and not bfp32
:
525 # defined to not modify FPSCR since the conversion is always exact
526 fpscr
= FPSCRState(initial_fpscr
)
527 cr1
= int(fpscr
.FX
) << 3
528 cr1 |
= int(fpscr
.FEX
) << 2
529 cr1 |
= int(fpscr
.VX
) << 1
532 inp
=hex(inp
), bfp32
=bfp32
, IT
=IT
, Rc
=Rc
, RN
=RN
,
533 expected_fp
=expected_fp
.hex(), expected_bits
=hex(expected_bits
),
534 XX
=fpscr
.XX
, FR
=fpscr
.FR
, FPRF
=bin(int(fpscr
.FPRF
)), CR1
=bin(cr1
),
536 s
= "s" if bfp32
else ""
537 rc_str
= "." if Rc
else ""
538 lst
= [f
"fcvtfg{s}{rc_str} 0,3,{IT}"]
542 e
= ExpectedState(pc
=4, int_regs
=gprs
, fp_regs
=fprs
)
544 e
.fpregs
[0] = expected_bits
547 _cached_program(*lst
), gprs
, fpregs
=fprs
, expected
=e
,
548 initial_fpscr
=int(initial_fpscr
))
550 def fcvtfg(self
, inp
):
551 for bfp32
in (False, True):
553 for Rc
in (False, True):
555 self
.fcvtfg_one(inp
, bfp32
, IT
, Rc
, RN
)
557 def case_fcvtfg(self
):
559 for sh
in (0, 22, 23, 24, 31, 52, 53, 54, 63):
560 for offset
in range(-2, 3):
561 for offset_sh
in range(64):
563 v
+= offset
<< offset_sh
566 for i
in sorted(inp_values
):
570 class SVP64FMvFCvtCases(TestAccumulatorBase
):
571 @skip_case("FIXME: rewrite to fmv/fcvt tests")
572 def case_sv_fmaxmag19(self
):
573 lst
= list(SVP64Asm(["sv.fmaxmag19 *32,*64,*96"]))
576 svstate
= SVP64State()
579 r
= range(svstate
.vl
)
580 for i
, rev_i
in zip(r
, reversed(r
)):
581 fprs
[64 + i
] = struct
.unpack("<Q", struct
.pack("<d", i
))[0]
582 fprs
[96 + i
] = struct
.unpack("<Q", struct
.pack("<d", rev_i
))[0]
583 e
= ExpectedState(pc
=8, int_regs
=gprs
, fp_regs
=fprs
)
584 e
.fpregs
[32] = 0x403f000000000000
585 e
.fpregs
[33] = 0x403e000000000000
586 e
.fpregs
[34] = 0x403d000000000000
587 e
.fpregs
[35] = 0x403c000000000000
588 e
.fpregs
[36] = 0x403b000000000000
589 e
.fpregs
[37] = 0x403a000000000000
590 e
.fpregs
[38] = 0x4039000000000000
591 e
.fpregs
[39] = 0x4038000000000000
592 e
.fpregs
[40] = 0x4037000000000000
593 e
.fpregs
[41] = 0x4036000000000000
594 e
.fpregs
[42] = 0x4035000000000000
595 e
.fpregs
[43] = 0x4034000000000000
596 e
.fpregs
[44] = 0x4033000000000000
597 e
.fpregs
[45] = 0x4032000000000000
598 e
.fpregs
[46] = 0x4031000000000000
599 e
.fpregs
[47] = 0x4030000000000000
600 e
.fpregs
[48] = 0x4030000000000000
601 e
.fpregs
[49] = 0x4031000000000000
602 e
.fpregs
[50] = 0x4032000000000000
603 e
.fpregs
[51] = 0x4033000000000000
604 e
.fpregs
[52] = 0x4034000000000000
605 e
.fpregs
[53] = 0x4035000000000000
606 e
.fpregs
[54] = 0x4036000000000000
607 e
.fpregs
[55] = 0x4037000000000000
608 e
.fpregs
[56] = 0x4038000000000000
609 e
.fpregs
[57] = 0x4039000000000000
610 e
.fpregs
[58] = 0x403a000000000000
611 e
.fpregs
[59] = 0x403b000000000000
612 e
.fpregs
[60] = 0x403c000000000000
613 e
.fpregs
[61] = 0x403d000000000000
614 e
.fpregs
[62] = 0x403e000000000000
615 e
.fpregs
[63] = 0x403f000000000000
616 self
.add_case(Program(lst
, False), gprs
, fpregs
=fprs
,
617 initial_svstate
=svstate
, expected
=e
)