From 7f64d55f36f19fe2c86b32565db0c88f4da41e31 Mon Sep 17 00:00:00 2001 From: Konstantinos Margaritis Date: Fri, 21 Jul 2023 14:05:54 +0000 Subject: [PATCH] Moved maddsubrs/maddrs/msubrs instructions to separate files As per Jacob's suggestion, simplified maddsubrs by removing masks and fixing overflow problems. --- openpower/isa/butterfly.mdwn | 75 ----------- openpower/isa/maddrs.mdwn | 27 ++++ openpower/isa/maddsubrs.mdwn | 35 ++++++ openpower/isa/msubrs.mdwn | 27 ++++ openpower/isatables/RM-1P-2S1D.csv | 1 + openpower/isatables/minor_22.csv | 1 + src/openpower/decoder/isa/.gitignore | 4 +- src/openpower/decoder/isa/caller.py | 2 +- .../decoder/isa/test_caller_maddrs.py | 27 ++++ src/openpower/decoder/power_decoder2.py | 1 + src/openpower/decoder/power_enums.py | 4 +- src/openpower/test/alu/maddrs_cases.py | 116 +++++++++++++++++ src/openpower/test/alu/maddsubrs_cases.py | 117 ++---------------- 13 files changed, 249 insertions(+), 188 deletions(-) delete mode 100644 openpower/isa/butterfly.mdwn create mode 100644 openpower/isa/maddrs.mdwn create mode 100644 openpower/isa/maddsubrs.mdwn create mode 100644 openpower/isa/msubrs.mdwn create mode 100644 src/openpower/decoder/isa/test_caller_maddrs.py create mode 100644 src/openpower/test/alu/maddrs_cases.py diff --git a/openpower/isa/butterfly.mdwn b/openpower/isa/butterfly.mdwn deleted file mode 100644 index 93a6c4bc..00000000 --- a/openpower/isa/butterfly.mdwn +++ /dev/null @@ -1,75 +0,0 @@ - - - - -# [DRAFT] Integer Butterfly Multiply Add/Sub FFT/DCT - -A-Form - -* maddsubrs RT,RA,SH,RB - -Pseudo-code: - - n <- SH - sum <- (RT) + (RA) - diff <- (RT) - (RA) - prod1 <- MULS(RB, sum) - prod2 <- MULS(RB, diff) - if n = 0 then - prod1_lo <- prod1[XLEN:(XLEN*2) - 1] - prod2_lo <- prod2[XLEN:(XLEN*2) - 1] - RT <- prod1_lo - RS <- prod2_lo - else - round <- [0]*(XLEN*2) - round[XLEN*2 - n] <- 1 - prod1 <- prod1 + round - prod2 <- prod2 + round - m <- MASK(XLEN - n - 2, XLEN - 1) - res1 <- prod1[XLEN - n:XLEN*2 - n - 1] - res2 <- prod2[XLEN - n:XLEN*2 - n - 1] - signbit1 <- prod1[0] - signbit2 <- prod2[0] - smask1 <- ([signbit1]*XLEN) & ¬m - smask2 <- ([signbit2]*XLEN) & ¬m - RT <- (res1 | smask1) - RS <- (res2 | smask2) - -Special Registers Altered: - - None - -# [DRAFT] Integer Butterfly Multiply Add and Accumulate FFT/DCT - -A-Form - -* maddrs RT,RA,SH,RB - -Pseudo-code: - - n <- SH - prod <- MULS(RB, RA) - if n = 0 then - prod_lo <- prod[XLEN:(XLEN*2) - 1] - RT <- (RT) + prod_lo - RS <- (RS) - prod_lo - else - res1[0:XLEN*2-1] <- (EXTSXL((RT)[0], 1) || (RT)) + prod - res2[0:XLEN*2-1] <- (EXTSXL((RS)[0], 1) || (RS)) - prod - round <- [0]*XLEN*2 - round[XLEN*2 - n] <- 1 - res1 <- res1 + round - res2 <- res2 + round - signbit1 <- res1[0] - signbit2 <- res2[0] - m <- MASK(XLEN -n - 2, XLEN - 1) - res1 <- res1[XLEN - n:XLEN*2 - n -1] - res2 <- res2[XLEN - n:XLEN*2 - n -1] - smask1 <- ([signbit1]*XLEN) & ¬m - smask2 <- ([signbit2]*XLEN) & ¬m - RT <- (res1 | smask1) - RS <- (res2 | smask2) - -Special Registers Altered: - - None diff --git a/openpower/isa/maddrs.mdwn b/openpower/isa/maddrs.mdwn new file mode 100644 index 00000000..f768044a --- /dev/null +++ b/openpower/isa/maddrs.mdwn @@ -0,0 +1,27 @@ + + + + +# [DRAFT] Integer Butterfly Multiply Add and Accumulate FFT/DCT + +A-Form + +* maddrs RT,RA,RB,SH + +Pseudo-code: + + n <- SH + prod <- MULS(RB, RA) + if n = 0 then + prod_lo <- prod[XLEN:(XLEN*2) - 1] + RT <- (RT) + prod_lo + else + res[0:XLEN*2-1] <- (EXTSXL((RT)[0], 1) || (RT)) + prod + round <- [0]*XLEN*2 + round[XLEN*2 - n] <- 1 + res <- res + round + RT <- res[XLEN - n:XLEN*2 - n -1] + +Special Registers Altered: + + None diff --git a/openpower/isa/maddsubrs.mdwn b/openpower/isa/maddsubrs.mdwn new file mode 100644 index 00000000..96efe5a5 --- /dev/null +++ b/openpower/isa/maddsubrs.mdwn @@ -0,0 +1,35 @@ + + + + +# [DRAFT] Integer Butterfly Multiply Add/Sub Round Shift for FFT/DCT + +A-Form + +* maddsubrs RT,RA,RB,SH + +Pseudo-code: + + n <- SH + sum <- (RT[0] || RT) + (RA[0] || RA) + diff <- (RT[0] || RT) - (RA[0] || RA) + prod1 <- MULS(RB, sum) + prod2 <- MULS(RB, diff) + if n = 0 then + prod1_lo <- prod1[XLEN+1:(XLEN*2)] + prod2_lo <- prod2[XLEN+1:(XLEN*2)] + RT <- prod1_lo + RS <- prod2_lo + else + round <- [0]*(XLEN*2 + 1) + round[XLEN*2 - n + 1] <- 1 + prod1 <- prod1 + round + prod2 <- prod2 + round + res1 <- prod1[XLEN - n + 1:XLEN*2 - n] + res2 <- prod2[XLEN - n + 1:XLEN*2 - n] + RT <- res1 + RS <- res2 + +Special Registers Altered: + + None diff --git a/openpower/isa/msubrs.mdwn b/openpower/isa/msubrs.mdwn new file mode 100644 index 00000000..a2d229dc --- /dev/null +++ b/openpower/isa/msubrs.mdwn @@ -0,0 +1,27 @@ + + + + +# [DRAFT] Integer Butterfly Multiply Add and Accumulate FFT/DCT + +A-Form + +* msubrs RT,RA,RB,SH + +Pseudo-code: + + n <- SH + prod <- MULS(RB, RA) + if n = 0 then + prod_lo <- prod[XLEN:(XLEN*2) - 1] + RT <- (RT) - prod_lo + else + res[0:XLEN*2-1] <- (EXTSXL((RT)[0], 1) || (RT)) - prod + round <- [0]*XLEN*2 + round[XLEN*2 - n] <- 1 + res <- res + round + RT <- res[XLEN - n:XLEN*2 - n -1] + +Special Registers Altered: + + None diff --git a/openpower/isatables/RM-1P-2S1D.csv b/openpower/isatables/RM-1P-2S1D.csv index 0de87cee..3a51f606 100644 --- a/openpower/isatables/RM-1P-2S1D.csv +++ b/openpower/isatables/RM-1P-2S1D.csv @@ -26,6 +26,7 @@ modsw,NORMAL,,1P,EXTRA3,NO,d:RT,s:RA,s:RB,0,RA,RB,0,RT,0,0,0 30/6=fmrgew,NORMAL,,1P,EXTRA3,NO,d:FRT,s:FRA,s:FRB,0,FRA,FRB,0,FRT,0,0,0 maddsubrs,NORMAL,,1P,EXTRA3,NO,s:RT;d:RT,s:RA,s:RB,0,RA,0,RB,RT,0,0,0 maddrs,NORMAL,,1P,EXTRA3,NO,s:RT;d:RT,s:RA,s:RB,0,RA,0,RB,RT,0,0,0 +msubrs,NORMAL,,1P,EXTRA3,NO,s:RT;d:RT,s:RA,s:RB,0,RA,0,RB,RT,0,0,0 rlwnm,NORMAL,,1P,EXTRA3,NO,d:RA;d:CR0,s:RB,s:RS,0,0,RB,RS,RA,0,CR0,0 minmax,NORMAL,,1P,EXTRA3,NO,d:RT;d:CR0,s:RA,s:RB,0,RA_OR_ZERO,RB,0,RT,0,CR0,0 sadd,NORMAL,,1P,EXTRA3,NO,d:RT;d:CR0,s:RA,s:RB,0,RA,RB,0,RT,0,CR0,0 diff --git a/openpower/isatables/minor_22.csv b/openpower/isatables/minor_22.csv index 5f14c358..adf1c3a0 100644 --- a/openpower/isatables/minor_22.csv +++ b/openpower/isatables/minor_22.csv @@ -42,3 +42,4 @@ opcode,unit,internal op,in1,in2,in3,out,CR in,CR out,inv A,inv out,cry in,cry ou -----01011-,ALU,OP_FISHMV,FRS,CONST_UI,NONE,FRS,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,0,0,NONE,0,0,fishmv,DX,,1,unofficial until submitted and approved/renumbered by the opf isa wg ------01000,ALU,OP_MADDSUBRS,RA,CONST_SH,RB,RT,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,1,0,NONE,0,0,maddsubrs,A,,1,unofficial until submitted and approved/renumbered by the opf isa wg ------01001,ALU,OP_MADDRS,RA,CONST_SH,RB,RT,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,1,0,NONE,0,0,maddrs,A,,1,unofficial until submitted and approved/renumbered by the opf isa wg +------01011,ALU,OP_MSUBRS,RA,CONST_SH,RB,RT,NONE,NONE,0,0,ZERO,0,NONE,0,0,0,0,1,0,NONE,0,0,msubrs,A,,1,unofficial until submitted and approved/renumbered by the opf isa wg diff --git a/src/openpower/decoder/isa/.gitignore b/src/openpower/decoder/isa/.gitignore index c72caceb..45f8711b 100644 --- a/src/openpower/decoder/isa/.gitignore +++ b/src/openpower/decoder/isa/.gitignore @@ -3,7 +3,6 @@ /bcd.py /bitmanip.py /branch.py -/butterfly.py /byterev.py /comparefixed.py /condition.py @@ -21,6 +20,9 @@ /fpmove.py /fpstore.py /fptrans.py +/maddsubrs.py +/maddrs.py +/msubrs.py /pifixedload.py /pifixedstore.py /sprset.py diff --git a/src/openpower/decoder/isa/caller.py b/src/openpower/decoder/isa/caller.py index 30f2e521..3b8d8694 100644 --- a/src/openpower/decoder/isa/caller.py +++ b/src/openpower/decoder/isa/caller.py @@ -1968,7 +1968,7 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop): "mffpr", "mffprs", "ctfpr", "ctfprs", "mtfpr", "mtfprs", - "maddsubrs", "maddrs" + "maddsubrs", "maddrs", "msubrs" ]: illegal = False ins_name = dotstrp diff --git a/src/openpower/decoder/isa/test_caller_maddrs.py b/src/openpower/decoder/isa/test_caller_maddrs.py new file mode 100644 index 00000000..a8903cfd --- /dev/null +++ b/src/openpower/decoder/isa/test_caller_maddrs.py @@ -0,0 +1,27 @@ +""" Decoder tests + +related bugs: + + * +""" + +import unittest + +from openpower.test.alu.maddrs_cases import MADDRSTestCase +from openpower.test.runner import TestRunnerBase + +# writing the test_caller invocation this way makes it work with pytest + + +class TestMADDRS(TestRunnerBase): + def __init__(self, test): + assert test == 'test' + super().__init__(MADDRSTestCase().test_data) + + def test(self): + # dummy function to make unittest try to test this class + pass + + +if __name__ == "__main__": + unittest.main() diff --git a/src/openpower/decoder/power_decoder2.py b/src/openpower/decoder/power_decoder2.py index a2ce4351..83b813a6 100644 --- a/src/openpower/decoder/power_decoder2.py +++ b/src/openpower/decoder/power_decoder2.py @@ -1082,6 +1082,7 @@ class PowerDecodeSubset(Elaboratable): with m.If((major == 22) & xo6.matches( '-01000', # maddsubrs '-01001', # maddrs + '-01011', # msubrs )): comb += self.implicit_rs.eq(1) comb += self.extend_rb_maxvl.eq(1) # extend RB diff --git a/src/openpower/decoder/power_enums.py b/src/openpower/decoder/power_enums.py index aa49b23b..44ad2f54 100644 --- a/src/openpower/decoder/power_enums.py +++ b/src/openpower/decoder/power_enums.py @@ -791,6 +791,7 @@ _insns = [ "maddhd", "maddhdu", "maddld", # INT multiply-and-add "maddsubrs", # Integer DCT Butterfly Add Sub and Round Shift "maddrs", # Integer DCT Butterfly Add and Accumulate and Round Shift + "msubrs", # Integer DCT Butterfly Subtract from and Round Shift "mcrf", "mcrxr", "mcrxrx", "mfcr/mfocrf", # CR mvs "mfmsr", "mfspr", "minmax", # AV bitmanip @@ -954,7 +955,8 @@ class MicrOp(Enum): OP_SHADD = 103 OP_MADDSUBRS = 104 OP_MADDRS = 105 - OP_BYTEREV = 106 + OP_MSUBRS = 106 + OP_BYTEREV = 107 class SelType(Enum): diff --git a/src/openpower/test/alu/maddrs_cases.py b/src/openpower/test/alu/maddrs_cases.py new file mode 100644 index 00000000..b31ed496 --- /dev/null +++ b/src/openpower/test/alu/maddrs_cases.py @@ -0,0 +1,116 @@ +from openpower.insndb.asm import SVP64Asm +from openpower.test.common import TestAccumulatorBase, skip_case +from openpower.endian import bigendian +from openpower.simulator.program import Program +from openpower.decoder.isa.caller import SVP64State +from openpower.test.state import ExpectedState +from nmutil.sim_util import hash_256 +import math +from fractions import Fraction + + +class MADDRSTestCase(TestAccumulatorBase): + def case_0_maddrs(self): + isa = SVP64Asm(["maddsubrs 1,10,11,0", + "maddrs 1,10,12,0", + "msubrs 2,10,12,0"]) + lst = list(isa) + + initial_regs = [0] * 32 + initial_regs[1] = 0x00000a71 + initial_regs[10] = 0x0000e6b8 + initial_regs[11] = 0x00002d41 + initial_regs[12] = 0x00000d00 + + e = ExpectedState(pc=12) + e.intregs[1] = 0x3658c869 + e.intregs[2] = 0xffffffffcd583ef9 + e.intregs[10] = 0x0000e6b8 + e.intregs[11] = 0x00002d41 + e.intregs[12] = 0x00000d00 + self.add_case(Program(lst, bigendian), initial_regs, expected=e) + + def case_1_maddrs(self): + isa = SVP64Asm(["maddsubrs 1,10,11,0", + "maddrs 1,10,12,14", + "msubrs 2,10,12,14"]) + lst = list(isa) + + initial_regs = [0] * 32 + initial_regs[1] = 0x00000a71 + initial_regs[10] = 0x0000e6b8 + initial_regs[11] = 0x00002d41 + initial_regs[12] = 0x00000d00 + + e = ExpectedState(pc=12) + e.intregs[1] = 0x0000d963 + e.intregs[2] = 0xffffffffffff3561 + e.intregs[10] = 0x0000e6b8 + e.intregs[11] = 0x00002d41 + e.intregs[12] = 0x00000d00 + self.add_case(Program(lst, bigendian), initial_regs, expected=e) + + def maddrs_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"maddrs {width} {shift} {case_idx}" + gprs[10] = hash_256(k + " r10") % 2**64 + gprs[11] = hash_256(k + " r11") % 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 + rs = (gprs[11] >> (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 rs >= 2 ** (width - 1): + rs -= 2 ** width # sign extend rs + if ra >= 2 ** (width - 1): + ra -= 2 ** width # sign extend ra + if rb >= 2 ** (width - 1): + rb -= 2 ** width # sign extend rb + prod = rb * ra + rt += prod + rs -= prod + factor = Fraction(1, 2 ** shift) # shr factor + round_up = Fraction(1, 2) + # round & shr + rt = math.floor(rt * factor + round_up) + rs = math.floor(rs * 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]), RS_in=hex(gprs[11]), + 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_maddrs_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.maddrs{w} *10,*20,*30,{shift}", + ])), bigendian) + + for case_idx in range(25): + self.maddrs_many_helper(width, shift, prog, case_idx) diff --git a/src/openpower/test/alu/maddsubrs_cases.py b/src/openpower/test/alu/maddsubrs_cases.py index c948272d..e2087fa7 100644 --- a/src/openpower/test/alu/maddsubrs_cases.py +++ b/src/openpower/test/alu/maddsubrs_cases.py @@ -11,7 +11,7 @@ from fractions import Fraction class MADDSUBRSTestCase(TestAccumulatorBase): def case_0_maddsubrs(self): - isa = SVP64Asm(["maddsubrs 1,10,14,11"]) + isa = SVP64Asm(["maddsubrs 1,10,11,14"]) lst = list(isa) initial_regs = [0] * 32 @@ -27,7 +27,7 @@ class MADDSUBRSTestCase(TestAccumulatorBase): self.add_case(Program(lst, bigendian), initial_regs, expected=e) def case_1_maddsubrs(self): - isa = SVP64Asm(["maddsubrs 1,10,0,11"]) + isa = SVP64Asm(["maddsubrs 1,10,11,0"]) lst = list(isa) initial_regs = [0] * 32 @@ -43,7 +43,7 @@ class MADDSUBRSTestCase(TestAccumulatorBase): self.add_case(Program(lst, bigendian), initial_regs, expected=e) def case_2_maddsubrs(self): - isa = SVP64Asm(["maddsubrs 1,10,2,11"]) + isa = SVP64Asm(["maddsubrs 1,10,11,2"]) lst = list(isa) initial_regs = [0] * 32 @@ -59,7 +59,7 @@ class MADDSUBRSTestCase(TestAccumulatorBase): self.add_case(Program(lst, bigendian), initial_regs, expected=e) def case_3_maddsubrs(self): - isa = SVP64Asm(["maddsubrs 1,10,16,11"]) + isa = SVP64Asm(["maddsubrs 1,10,11,16"]) lst = list(isa) initial_regs = [0] * 32 @@ -75,7 +75,7 @@ class MADDSUBRSTestCase(TestAccumulatorBase): self.add_case(Program(lst, bigendian), initial_regs, expected=e) def case_4_maddsubrs(self): - isa = SVP64Asm(["maddsubrs 1,10,1,11"]) + isa = SVP64Asm(["maddsubrs 1,10,11,1"]) lst = list(isa) initial_regs = [0] * 32 @@ -92,7 +92,7 @@ class MADDSUBRSTestCase(TestAccumulatorBase): def case_maddsubrs_16bit_s14(self): p = Program(list(SVP64Asm([ - "sv.maddsubrs/w=16 *10,*20,14,*30", + "sv.maddsubrs/w=16 *10,*20,*30,14", ])), bigendian) initial_regs = [0] * 32 @@ -189,111 +189,8 @@ class MADDSUBRSTestCase(TestAccumulatorBase): 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", + f"sv.maddsubrs{w} *10,*20,*30,{shift}", ])), 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"]) - lst = list(isa) - - initial_regs = [0] * 32 - initial_regs[1] = 0x00000a71 - initial_regs[10] = 0x0000e6b8 - initial_regs[11] = 0x00002d41 - initial_regs[12] = 0x00000d00 - - e = ExpectedState(pc=8) - e.intregs[1] = 0x3658c869 - e.intregs[2] = 0xffffffffcd583ef9 - e.intregs[10] = 0x0000e6b8 - e.intregs[11] = 0x00002d41 - e.intregs[12] = 0x00000d00 - self.add_case(Program(lst, bigendian), initial_regs, expected=e) - - def case_1_maddrs(self): - isa = SVP64Asm(["maddsubrs 1,10,0,11", - "maddrs 1,10,14,12"]) - lst = list(isa) - - initial_regs = [0] * 32 - initial_regs[1] = 0x00000a71 - initial_regs[10] = 0x0000e6b8 - initial_regs[11] = 0x00002d41 - initial_regs[12] = 0x00000d00 - - e = ExpectedState(pc=8) - e.intregs[1] = 0x0000d963 - e.intregs[2] = 0xffffffffffff3561 - e.intregs[10] = 0x0000e6b8 - e.intregs[11] = 0x00002d41 - e.intregs[12] = 0x00000d00 - self.add_case(Program(lst, bigendian), initial_regs, expected=e) - - def maddrs_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"maddrs {width} {shift} {case_idx}" - gprs[10] = hash_256(k + " r10") % 2**64 - gprs[11] = hash_256(k + " r11") % 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 - rs = (gprs[11] >> (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 rs >= 2 ** (width - 1): - rs -= 2 ** width # sign extend rs - if ra >= 2 ** (width - 1): - ra -= 2 ** width # sign extend ra - if rb >= 2 ** (width - 1): - rb -= 2 ** width # sign extend rb - prod = rb * ra - rt += prod - rs -= prod - factor = Fraction(1, 2 ** shift) # shr factor - round_up = Fraction(1, 2) - # round & shr - rt = math.floor(rt * factor + round_up) - rs = math.floor(rs * 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]), RS_in=hex(gprs[11]), - 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_maddrs_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.maddrs{w} *10,*20,{shift},*30", - ])), bigendian) - - for case_idx in range(25): - self.maddrs_many_helper(width, shift, prog, case_idx) -- 2.30.2