From 0fd5b15bf193e1a13d78f650468d53c19598f50b Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Tue, 16 May 2023 21:54:38 -0700 Subject: [PATCH] test all fp -> int conversion modes --- src/openpower/test/fmv_fcvt/fmv_fcvt.py | 103 +++++++++++++++++++----- 1 file changed, 81 insertions(+), 22 deletions(-) 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) -- 2.30.2