From: Jacob Lifshay Date: Wed, 17 May 2023 04:54:38 +0000 (-0700) Subject: test all fp -> int conversion modes X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=887d7fece7ee6d9c374f73a2e18150166e641532;p=openpower-isa.git test all fp -> int conversion modes --- diff --git a/src/openpower/test/fmv_fcvt/fmv_fcvt.py b/src/openpower/test/fmv_fcvt/fmv_fcvt.py index a3516c6f..3c2ff876 100644 --- a/src/openpower/test/fmv_fcvt/fmv_fcvt.py +++ b/src/openpower/test/fmv_fcvt/fmv_fcvt.py @@ -6,6 +6,12 @@ from openpower.decoder.isa.caller import SVP64State from openpower.fpscr import FPSCRState import struct import math +import functools + + +@functools.lru_cache() +def _cached_program(*instrs): + return Program(list(SVP64Asm(list(instrs))), bigendian=False) def fp_bits_add(fp, amount): @@ -15,50 +21,102 @@ def fp_bits_add(fp, amount): return struct.unpack(">= 32 + min_v = 0 + if signed: + max_v >>= 1 + min_v = ~max_v inp = float(inp) if inp_bits is None: inp_bits = struct.unpack("> 31: - expected -= 2 ** 32 + if CVM >> 1 == 0: # openpower semantics + if math.isnan(inp): + expected = min_v + elif inp > max_v: + expected = max_v + elif inp < min_v: + expected = min_v + else: + expected = do_round(inp, round_mode) + elif CVM >> 1 == 1: # saturating semantics + if math.isnan(inp): + expected = 0 + elif inp > max_v: + expected = max_v + elif inp < min_v: + expected = min_v + else: + expected = do_round(inp, round_mode) + elif CVM >> 1 == 2: # js semantics + if math.isfinite(inp): + expected = do_round(inp, round_mode) + else: + expected = 0 + if _32bit: + expected %= 2 ** 32 + if signed and expected >> 31: + expected -= 2 ** 32 expected %= 2 ** 64 IT = (not signed) + (not _32bit) * 2 with self.subTest(inp=inp.hex(), inp_bits=hex(inp_bits), expected=hex(expected), test_title=test_title, - signed=signed, _32bit=_32bit): - lst = list(SVP64Asm([f"fcvttg 3,0,5,{IT}"])) + signed=signed, _32bit=_32bit, CVM=CVM, RN=RN): + lst = [f"fcvttg 3,0,{CVM},{IT}"] gprs = [0] * 32 fprs = [0] * 32 fprs[0] = inp_bits + initial_fpscr = FPSCRState() + initial_fpscr.RN = RN e = ExpectedState(pc=4, int_regs=gprs, fp_regs=fprs) e.intregs[3] = expected - fpscr = FPSCRState() + fpscr = FPSCRState(initial_fpscr) if math.isnan(inp) and (inp_bits & 2 ** 51) == 0: # SNaN fpscr.VXSNAN = 1 fpscr.FX = 1 - max_v = 2 ** 64 - 1 - if _32bit: - max_v >>= 32 - min_v = 0 - if signed: - max_v >>= 1 - min_v = ~max_v if not math.isfinite(inp) or not ( - min_v <= math.trunc(inp) <= max_v): + min_v <= do_round(inp, round_mode) <= max_v): fpscr.VXCVI = 1 fpscr.FX = 1 - elif math.trunc(inp) != inp: # inexact + elif do_round(inp, round_mode) != inp: # inexact fpscr.XX = 1 fpscr.FX = 1 fpscr.FI = 1 @@ -70,7 +128,8 @@ class FMvFCvtCases(TestAccumulatorBase): expected_FI=fpscr.FI): e.fpscr = int(fpscr) self.add_case( - Program(lst, False), gprs, fpregs=fprs, expected=e) + _cached_program(*lst), gprs, fpregs=fprs, expected=e, + initial_fpscr=int(initial_fpscr)) def case_js_toint32(self): min_value = pow(2, -1074)