Handle large 64-bit values, but only the low 64-bit half of the multiplication, add...
authorKonstantinos Margaritis <konstantinos.margaritis@vectorcamp.gr>
Sun, 30 Apr 2023 21:29:47 +0000 (21:29 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 2 Jun 2023 18:51:17 +0000 (19:51 +0100)
openpower/isa/butterfly.mdwn
src/openpower/test/alu/maddsubrs_cases.py

index 1446af112c15837291bfd6ced7bc41f43e389a86..65f4dc56564bb7c33197b8bf6e9b750eb8eeae15 100644 (file)
@@ -13,32 +13,29 @@ Pseudo-code:
     n <- SH
     sum <- (RT) + (RA)
     diff <- (RT) - (RA)
-    prod1 <- MULS(RB, sum)[XLEN:(XLEN*2)-1]
-    prod2 <- MULS(RB, diff)[XLEN:(XLEN*2)-1]
+    prod1 <- MULS(RB, sum)
+    prod1_lo <- prod1[XLEN:(XLEN*2)-1]
+    prod2 <- MULS(RB, diff)
+    prod2_lo <- prod2[XLEN:(XLEN*2)-1]
     if n = 0 then
-        #round <- EXTS([0]*(XLEN-1) || [1]*1)
-        #prod1 <- ROTL64(prod1, 1)
-        #prod2 <- ROTL64(prod2, 1)
-        #prod1 <- prod1 + round
-        #prod2 <- prod2 + round
-        #res1 <- ROTL64(prod1, XLEN-1)
-        #res2 <- ROTL64(prod2, XLEN-1)
-        #m <- MASK(1, (XLEN-1))
-        RT <- prod1
-        RS <- prod2
+        RT <- prod1_lo
+        RS <- prod2_lo
     else
-        round <- EXTS([0]*(XLEN -n -1) || [1]*1 || [0]*(n-1))
-        prod1 <- prod1 + round
-        prod2 <- prod2 + round
-        res1 <- ROTL64(prod1, XLEN-n)
-        res2 <- ROTL64(prod2, XLEN-n)
+        if n = 1 then
+            round <- [0]*(XLEN -n) || [1]*1
+        else
+            round <- [0]*(XLEN -n) || [1]*1 || [0]*(n-1)
+        prod1_lo <- prod1_lo + round
+        prod2_lo <- prod2_lo + round
         m <- MASK(n, (XLEN-1))
-        signbit1 <- prod1[0]
-        signbit2 <- prod2[0]
+        res1 <- ROTL64(prod1_lo, XLEN-n) & m
+        res2 <- ROTL64(prod2_lo, XLEN-n) & m
+        signbit1 <- prod1_lo[0]
+        signbit2 <- prod2_lo[0]
         smask1 <- ([signbit1]*XLEN) & ¬m
         smask2 <- ([signbit2]*XLEN) & ¬m
-        RT <- (res1 & m | smask1)
-        RS <- (res2 & m | smask2)
+        RT <- (res1 | smask1)
+        RS <- (res2 | smask2)
 
 Special Registers Altered:
 
index 56b61f82aff65e506e06b9d9732d1cb809749125..2a495f600f2c96e7e6c910d5717f6b72f8619fa3 100644 (file)
@@ -41,3 +41,48 @@ class MADDSUBRSTestCase(TestAccumulatorBase):
         e.intregs[2] = 0xffffffffd90f96f9
         e.intregs[3] = 0x00002d41
         self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+
+    def case_2_maddsubrs(self):
+        isa = SVP64Asm(["maddsubrs 1,2,2,3"])
+        lst = list(isa)
+
+        initial_regs = [0] * 32
+        initial_regs[1] = 0x100000000
+        initial_regs[2] = 0x000000003
+        initial_regs[3] = 0x10000000
+
+        e = ExpectedState(pc=4)
+        e.intregs[1] = 0x40000000c000000;
+        e.intregs[2] = 0x3fffffff4000000;
+        e.intregs[3] = 0x10000000;
+        self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+
+    def case_3_maddsubrs(self):
+        isa = SVP64Asm(["maddsubrs 1,2,16,3"])
+        lst = list(isa)
+
+        initial_regs = [0] * 32
+        initial_regs[1] = 0x100000000
+        initial_regs[2] = 0x000000003
+        initial_regs[3] = 0x10000000
+
+        e = ExpectedState(pc=4)
+        e.intregs[1] = 0x100000003000;
+        e.intregs[2] = 0x0fffffffd000;
+        e.intregs[3] = 0x10000000;
+        self.add_case(Program(lst, bigendian), initial_regs, expected=e)
+
+    def case_3_maddsubrs(self):
+        isa = SVP64Asm(["maddsubrs 1,2,1,3"])
+        lst = list(isa)
+
+        initial_regs = [0] * 32
+        initial_regs[1] = 0x100000000
+        initial_regs[2] = 0x000000003
+        initial_regs[3] = 0xff0000000
+
+        e = ExpectedState(pc=4)
+        e.intregs[1] = 0xf8000017e8000000;
+        e.intregs[2] = 0xf7ffffe818000000;
+        e.intregs[3] = 0xff0000000;
+        self.add_case(Program(lst, bigendian), initial_regs, expected=e)