From 47494d1de46184d2cc86ccf6def71dc4e3f16807 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Thu, 20 Jul 2023 15:19:19 -0700 Subject: [PATCH] add much more exhaustive maddsubrs unit tests --- src/openpower/test/alu/maddsubrs_cases.py | 67 +++++++++++++++++++++-- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/src/openpower/test/alu/maddsubrs_cases.py b/src/openpower/test/alu/maddsubrs_cases.py index 7958e569..fecac44e 100644 --- a/src/openpower/test/alu/maddsubrs_cases.py +++ b/src/openpower/test/alu/maddsubrs_cases.py @@ -1,19 +1,15 @@ from openpower.insndb.asm import SVP64Asm -import random from openpower.test.common import TestAccumulatorBase, skip_case from openpower.endian import bigendian from openpower.simulator.program import Program -from openpower.decoder.selectable_int import SelectableInt -from openpower.decoder.power_enums import XER_bits from openpower.decoder.isa.caller import SVP64State -from openpower.decoder.helpers import exts from openpower.test.state import ExpectedState -import unittest +from nmutil.sim_util import hash_256 import math +from fractions import Fraction class MADDSUBRSTestCase(TestAccumulatorBase): - def case_0_maddsubrs(self): isa = SVP64Asm(["maddsubrs 1,10,14,11"]) lst = list(isa) @@ -140,6 +136,65 @@ class MADDSUBRSTestCase(TestAccumulatorBase): self.add_case(p, initial_regs, expected=e, initial_svstate=svstate) + def maddsubrs_many_helper(self, width, shift, prog, case_idx): + # if {'width': width, 'shift': shift, 'case_idx': case_idx} \ + # != {'width': 8, 'shift': 1, 'case_idx': 0}: + # return # for debugging + gprs = [0] * 32 + # make some reproducible random inputs + k = f"maddsubrs {width} {shift} {case_idx}" + gprs[10] = hash_256(k + " r10") % 2**64 + gprs[20] = hash_256(k + " r20") % 2**64 + gprs[30] = hash_256(k + " r30") % 2**64 + + svstate = SVP64State() + svstate.vl = 64 // width # one full 64-bit register + svstate.maxvl = 64 // width + + e = ExpectedState(pc=8, int_regs=gprs) + e.intregs[10] = 0 + e.intregs[11] = 0 + for i in range(svstate.vl): + # extract elements + rt = (gprs[10] >> (i * width)) % 2 ** width + ra = (gprs[20] >> (i * width)) % 2 ** width + rb = (gprs[30] >> (i * width)) % 2 ** width + if rt >= 2 ** (width - 1): + rt -= 2 ** width # sign extend rt + if ra >= 2 ** (width - 1): + ra -= 2 ** width # sign extend ra + if rb >= 2 ** (width - 1): + rb -= 2 ** width # sign extend rb + s = rt + ra + d = rt - ra + factor = Fraction(1, 2 ** shift) # shr factor + round_up = Fraction(1, 2) + # mul & round & shr + rt = math.floor((s * rb) * factor + round_up) + rs = math.floor((d * rb) * factor + round_up) + # insert elements + e.intregs[10] |= (rt % 2 ** width) << (width * i) + e.intregs[11] |= (rs % 2 ** width) << (width * i) + + with self.subTest( + width=width, shift=shift, case_idx=case_idx, + RT_in=hex(gprs[10]), RA_in=hex(gprs[20]), RB_in=hex(gprs[30]), + expected_RT=hex(e.intregs[10]), expected_RS=hex(e.intregs[11]), + ): + self.add_case(prog, gprs, expected=e, initial_svstate=svstate) + + def case_maddsubrs_many(self): + for width in 8, 16, 32, 64: + shift_end = min(32, width) + for shift in range(0, shift_end, shift_end // 8): + w = "" if width == 64 else f"/w={width}" + prog = Program(list(SVP64Asm([ + f"sv.maddsubrs{w} *10,*20,{shift},*30", + ])), bigendian) + + for case_idx in range(25): + self.maddsubrs_many_helper(width, shift, prog, case_idx) + def case_0_maddrs(self): isa = SVP64Asm(["maddsubrs 1,10,0,11", "maddrs 1,10,0,12"]) -- 2.30.2