access FPSCR through self
authorJacob Lifshay <programmerjake@gmail.com>
Tue, 9 May 2023 07:30:06 +0000 (00:30 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Tue, 9 May 2023 07:30:06 +0000 (00:30 -0700)
openpower/isafunctions/double2single.mdwn
src/openpower/decoder/helpers.py
src/openpower/decoder/isa/caller.py
src/openpower/decoder/pseudo/parser.py

index 1c88612a0ae394b51354ff27508aa28e5174de12..ea2d6f51bc87b16db23734a1cb80e016f88b1ef3 100644 (file)
@@ -5,34 +5,34 @@ Round to Single-Precision instruction.
 
 <!-- OPF_PowerISA_v3.1B.pdf Book I Section A.1 page 1031-1034 -->
 
-    def FRSP(FRB, FPSCR):
+    def FRSP(FRB):
         if ((FRB)[1:11] <u 897) & ((FRB)[1:63] >u 0) then
-            if FPSCR['UE'] = 0 then
-                return FRSP_Disabled_Exponent_Underflow(FRB, FPSCR)
-            if FPSCR['UE'] = 1 then
-                return FRSP_Enabled_Exponent_Underflow(FRB, FPSCR)
+            if FPSCR.UE = 0 then
+                return FRSP_Disabled_Exponent_Underflow(FRB)
+            if FPSCR.UE = 1 then
+                return FRSP_Enabled_Exponent_Underflow(FRB)
 
         if ((FRB)[1:11] >u 1150) & ((FRB)[1:11] <u 2047) then
-            if FPSCR['OE'] = 0 then
-                return FRSP_Disabled_Exponent_Overflow(FRB, FPSCR)
-            if FPSCR['OE'] = 1 then
-                return FRSP_Enabled_Exponent_Overflow(FRB, FPSCR)
+            if FPSCR.OE = 0 then
+                return FRSP_Disabled_Exponent_Overflow(FRB)
+            if FPSCR.OE = 1 then
+                return FRSP_Enabled_Exponent_Overflow(FRB)
 
         if ((FRB)[1:11] >u 896) & ((FRB)[1:11] <u 1151) then
-            return FRSP_Normal_Operand(FRB, FPSCR)
+            return FRSP_Normal_Operand(FRB)
 
         if (FRB)[1:63] = 0 then
-            return FRSP_Zero_Operand(FRB, FPSCR)
+            return FRSP_Zero_Operand(FRB)
 
         if (FRB)[1:11] = 2047 then
             if (FRB)[12:63] = 0 then
-                return FRSP_Infinity_Operand(FRB, FPSCR)
+                return FRSP_Infinity_Operand(FRB)
             if (FRB)[12] = 1 then
-                return FRSP_QNaN_Operand(FRB, FPSCR)
+                return FRSP_QNaN_Operand(FRB)
             if ((FRB)[12] = 0) & ((FRB)[13:63] >u 0) then
-                return FRSP_SNaN_Operand(FRB, FPSCR)
+                return FRSP_SNaN_Operand(FRB)
 
-    def FRSP_Disabled_Exponent_Underflow(FRB, FPSCR):
+    def FRSP_Disabled_Exponent_Underflow(FRB):
         sign <- (FRB)[0]
         frac[0:52] <- 0
         exp <- 0
@@ -54,22 +54,22 @@ Round to Single-Precision instruction.
             G <- frac[52]
             frac[0:52] <- 0b0 || frac[0:51]
 
-        FPSCR['UX'] <- (frac[24:52] || G || R || X) >u 0
-        exp, frac, FPSCR <- Round_Single(sign, exp, frac[0:52], G, R, X, FPSCR)
-        FPSCR['XX'] <- FPSCR['XX'] | FPSCR['FI']
+        FPSCR.UX <- (frac[24:52] || G || R || X) >u 0
+        exp, frac <- Round_Single(sign, exp, frac[0:52], G, R, X)
+        FPSCR.XX <- FPSCR.XX | FPSCR.FI
         FRT <- [0b0] * 64
         if frac[0:52] = 0 then
             FRT[0] <- sign
             FRT[1:63] <- 0
-            if sign = 0 then FPSCR['FPRF'] <- '+ zero'
-            if sign = 1 then FPSCR['FPRF'] <- '- zero'
+            if sign = 0 then FPSCR.FPRF <- '+ zero'
+            if sign = 1 then FPSCR.FPRF <- '- zero'
         if frac[0:52] >u 0 then
             if frac[0] = 1 then
-                if sign = 0 then FPSCR['FPRF'] <- '+ normal number'
-                if sign = 1 then FPSCR['FPRF'] <- '- normal number'
+                if sign = 0 then FPSCR.FPRF <- '+ normal number'
+                if sign = 1 then FPSCR.FPRF <- '- normal number'
             if frac[0] = 0 then
-                if sign = 0 then FPSCR['FPRF'] <- '+ denormalized number'
-                if sign = 1 then FPSCR['FPRF'] <- '- denormalized number'
+                if sign = 0 then FPSCR.FPRF <- '+ denormalized number'
+                if sign = 1 then FPSCR.FPRF <- '- denormalized number'
 
             # Normalize operand:
             do while frac[0] = 0
@@ -79,10 +79,10 @@ Round to Single-Precision instruction.
             FRT[0] <- sign
             FRT[1:11] <- exp + 1023
             FRT[12:63] <- frac[1:52]
-        return FRT, FPSCR
+        return FRT
 
-    def FRSP_Enabled_Exponent_Underflow(FRB, FPSCR):
-        FPSCR['UX'] <- 1
+    def FRSP_Enabled_Exponent_Underflow(FRB):
+        FPSCR.UX <- 1
         sign <- (FRB)[0]
         frac <- [0b0] * 53
         exp <- 0
@@ -98,132 +98,132 @@ Round to Single-Precision instruction.
             exp <- exp - 1
             frac[0:52] <- frac[1:52] || 0b0
 
-        exp, frac, FPSCR <- Round_Single(sign, exp, frac[0:52], 0b0, 0b0, 0b0, FPSCR)
-        FPSCR['XX'] <- FPSCR['XX'] | FPSCR['FI']
+        exp, frac <- Round_Single(sign, exp, frac[0:52], 0b0, 0b0, 0b0)
+        FPSCR.XX <- FPSCR.XX | FPSCR.FI
         exp <- exp + 192
         FRT <- [0b0] * 64
         FRT[0] <- sign
         FRT[1:11] <- exp + 1023
         FRT[12:63] <- frac[1:52]
-        if sign = 0 then FPSCR['FPRF'] <- '+ normal number'
-        if sign = 1 then FPSCR['FPRF'] <- '- normal number'
-        return FRT, FPSCR
+        if sign = 0 then FPSCR.FPRF <- '+ normal number'
+        if sign = 1 then FPSCR.FPRF <- '- normal number'
+        return FRT
 
-    def FRSP_Disabled_Exponent_Overflow(FRB, FPSCR):
-        FPSCR['OX'] <- 1
+    def FRSP_Disabled_Exponent_Overflow(FRB):
+        FPSCR.OX <- 1
         FRT <- [0b0] * 64
-        if FPSCR['RN'] = 0b00 then             # Round to Nearest
+        if FPSCR.RN = 0b00 then             # Round to Nearest
             if (FRB)[0] = 0 then FRT <- 0x7FF0_0000_0000_0000
             if (FRB)[0] = 1 then FRT <- 0xFFF0_0000_0000_0000
-            if (FRB)[0] = 0 then FPSCR['FPRF'] <- '+ infinity'
-            if (FRB)[0] = 1 then FPSCR['FPRF'] <- '- infinity'
-        if FPSCR['RN'] = 0b01 then             # Round toward Zero
+            if (FRB)[0] = 0 then FPSCR.FPRF <- '+ infinity'
+            if (FRB)[0] = 1 then FPSCR.FPRF <- '- infinity'
+        if FPSCR.RN = 0b01 then             # Round toward Zero
             if (FRB)[0] = 0 then FRT <- 0x47EF_FFFF_E000_0000
             if (FRB)[0] = 1 then FRT <- 0xC7EF_FFFF_E000_0000
-            if (FRB)[0] = 0 then FPSCR['FPRF'] <- '+ normal number'
-            if (FRB)[0] = 1 then FPSCR['FPRF'] <- '- normal number'
-        if FPSCR['RN'] = 0b10 then             # Round toward +Infinity
+            if (FRB)[0] = 0 then FPSCR.FPRF <- '+ normal number'
+            if (FRB)[0] = 1 then FPSCR.FPRF <- '- normal number'
+        if FPSCR.RN = 0b10 then             # Round toward +Infinity
             if (FRB)[0] = 0 then FRT <- 0x7FF0_0000_0000_0000
             if (FRB)[0] = 1 then FRT <- 0xC7EF_FFFF_E000_0000
-            if (FRB)[0] = 0 then FPSCR['FPRF'] <- '+ infinity'
-            if (FRB)[0] = 1 then FPSCR['FPRF'] <- '- normal number'
-        if FPSCR['RN'] = 0b11 then             # Round toward -Infinity
+            if (FRB)[0] = 0 then FPSCR.FPRF <- '+ infinity'
+            if (FRB)[0] = 1 then FPSCR.FPRF <- '- normal number'
+        if FPSCR.RN = 0b11 then             # Round toward -Infinity
             if (FRB)[0] = 0 then FRT <- 0x47EF_FFFF_E000_0000
             if (FRB)[0] = 1 then FRT <- 0xFFF0_0000_0000_0000
-            if (FRB)[0] = 0 then FPSCR['FPRF'] <- '+ normal number'
-            if (FRB)[0] = 1 then FPSCR['FPRF'] <- '- infinity'
-        FPSCR['FR'] <- undefined(0) # FIXME: figure out what values POWER9 uses
-        FPSCR['FI'] <- 1
-        FPSCR['XX'] <- 1
-        return FRT, FPSCR
+            if (FRB)[0] = 0 then FPSCR.FPRF <- '+ normal number'
+            if (FRB)[0] = 1 then FPSCR.FPRF <- '- infinity'
+        FPSCR.FR <- undefined(0) # FIXME: figure out what values POWER9 uses
+        FPSCR.FI <- 1
+        FPSCR.XX <- 1
+        return FRT
 
-    def FRSP_Enabled_Exponent_Overflow(FRB, FPSCR):
+    def FRSP_Enabled_Exponent_Overflow(FRB):
         sign <- (FRB)[0]
         exp <- (FRB)[1:11] - 1023
         frac <- [0b0] * 53
         frac[0:52] <- 0b1 || (FRB)[12:63]
-        exp, frac, FPSCR <- Round_Single(sign, exp, frac[0:52], 0b0, 0b0, 0b0, FPSCR)
-        FPSCR['XX'] <- FPSCR['XX'] | FPSCR['FI']
+        exp, frac <- Round_Single(sign, exp, frac[0:52], 0b0, 0b0, 0b0)
+        FPSCR.XX <- FPSCR.XX | FPSCR.FI
         # Enabled Overflow:
-        FPSCR['OX'] <- 1
+        FPSCR.OX <- 1
         exp <- exp - 192
         FRT <- [0b0] * 64
         FRT[0] <- sign
         FRT[1:11] <- exp + 1023
         FRT[12:63] <- frac[1:52]
-        if sign = 0 then FPSCR['FPRF'] <- '+ normal number'
-        if sign = 1 then FPSCR['FPRF'] <- '- normal number'
-        return FRT, FPSCR
+        if sign = 0 then FPSCR.FPRF <- '+ normal number'
+        if sign = 1 then FPSCR.FPRF <- '- normal number'
+        return FRT
 
-    def FRSP_Zero_Operand(FRB, FPSCR):
+    def FRSP_Zero_Operand(FRB):
         FRT <- (FRB)
-        if (FRB)[0] = 0 then FPSCR['FPRF'] <- '+ zero'
-        if (FRB)[0] = 1 then FPSCR['FPRF'] <- '- zero'
-        FPSCR['FRFI'] <- 0b00
-        return FRT, FPSCR
+        if (FRB)[0] = 0 then FPSCR.FPRF <- '+ zero'
+        if (FRB)[0] = 1 then FPSCR.FPRF <- '- zero'
+        FPSCR.FRFI <- 0b00
+        return FRT
 
-    def FRSP_Infinity_Operand(FRB, FPSCR):
+    def FRSP_Infinity_Operand(FRB):
         FRT <- (FRB)
-        if (FRB)[0] = 0 then FPSCR['FPRF'] <- '+ infinity'
-        if (FRB)[0] = 1 then FPSCR['FPRF'] <- '- infinity'
-        FPSCR['FRFI'] <- 0b00
-        return FRT, FPSCR
+        if (FRB)[0] = 0 then FPSCR.FPRF <- '+ infinity'
+        if (FRB)[0] = 1 then FPSCR.FPRF <- '- infinity'
+        FPSCR.FRFI <- 0b00
+        return FRT
 
-    def FRSP_QNaN_Operand(FRB, FPSCR):
+    def FRSP_QNaN_Operand(FRB):
         FRT <- (FRB)[0:34] || [0b0] * 29
-        FPSCR['FPRF'] <- 'QNaN'
-        FPSCR['FR'] <- 0b0
-        FPSCR['FI'] <- 0b0
-        return FRT, FPSCR
+        FPSCR.FPRF <- 'QNaN'
+        FPSCR.FR <- 0b0
+        FPSCR.FI <- 0b0
+        return FRT
 
-    def FRSP_SNaN_Operand(FRB, FPSCR):
-        FPSCR['VXSNAN'] <- 1
+    def FRSP_SNaN_Operand(FRB):
+        FPSCR.VXSNAN <- 1
         FRT <- [0b0] * 64
-        if FPSCR['VE'] = 0 then
+        if FPSCR.VE = 0 then
             FRT[0:11] <- (FRB)[0:11]
             FRT[12] <- 1
             FRT[13:63] <- (FRB)[13:34] || [0b0] * 29
-            FPSCR['FPRF'] <- 'QNaN'
-        FPSCR['FR'] <- 0b0
-        FPSCR['FI'] <- 0b0
-        return FRT, FPSCR
+            FPSCR.FPRF <- 'QNaN'
+        FPSCR.FR <- 0b0
+        FPSCR.FI <- 0b0
+        return FRT
 
-    def FRSP_Normal_Operand(FRB, FPSCR):
+    def FRSP_Normal_Operand(FRB):
         sign <- (FRB)[0]
         exp <- (FRB)[1:11] - 1023
         frac <- [0b0] * 53
         frac[0:52] <- 0b1 || (FRB)[12:63]
-        exp, frac, FPSCR <- Round_Single(sign, exp, frac[0:52], 0b0, 0b0, 0b0, FPSCR)
-        FPSCR['XX'] <- FPSCR['XX'] | FPSCR['FI']
-        if (exp > 127) & (FPSCR['OE'] = 0) then
-            return FRSP_Disabled_Exponent_Overflow(FRB, FPSCR)
-        if (exp > 127) & (FPSCR['OE'] = 1) then
-            return FRSP_Enabled_Overflow(FRB, FPSCR)
+        exp, frac <- Round_Single(sign, exp, frac[0:52], 0b0, 0b0, 0b0)
+        FPSCR.XX <- FPSCR.XX | FPSCR.FI
+        if (exp > 127) & (FPSCR.OE = 0) then
+            return FRSP_Disabled_Exponent_Overflow(FRB)
+        if (exp > 127) & (FPSCR.OE = 1) then
+            return FRSP_Enabled_Overflow(FRB)
         FRT <- [0b0] * 64
         FRT[0] <- sign
         FRT[1:11] <- exp + 1023
         FRT[12:63] <- frac[1:52]
-        if sign = 0 then FPSCR['FPRF'] <- '+ normal number'
-        if sign = 1 then FPSCR['FPRF'] <- '- normal number'
-        return FRT, FPSCR
+        if sign = 0 then FPSCR.FPRF <- '+ normal number'
+        if sign = 1 then FPSCR.FPRF <- '- normal number'
+        return FRT
 
-    def Round_Single(sign, exp, frac, G, R, X, FPSCR):
+    def Round_Single(sign, exp, frac, G, R, X):
         inc <- 0
         lsb <- frac[23]
         gbit <- frac[24]
         rbit <- frac[25]
         xbit <- (frac[26:52]||G||R||X) != 0
-        if FPSCR['RN'] = 0b00 then                       # Round to Nearest
+        if FPSCR.RN = 0b00 then                       # Round to Nearest
             # comparisons ignore u bits
             if (lsb || gbit) = 0b11 then inc <- 1
             if (lsb || gbit || rbit) = 0b011 then inc <- 1
             if (lsb || gbit || xbit) = 0b011 then inc <- 1
-        if FPSCR['RN'] = 0b10 then                       # Round toward + Infinity
+        if FPSCR.RN = 0b10 then                       # Round toward + Infinity
             # comparisons ignore u bits
             if (sign || gbit) = 0b01 then inc <- 1
             if (sign || rbit) = 0b01 then inc <- 1
             if (sign || xbit) = 0b01 then inc <- 1
-        if FPSCR['RN'] = 0b11 then                       # Round toward - Infinity
+        if FPSCR.RN = 0b11 then                       # Round toward - Infinity
             # comparisons ignore u bits
             if (sign || gbit) = 0b11 then inc <- 1
             if (sign || rbit) = 0b11 then inc <- 1
@@ -233,9 +233,9 @@ Round to Single-Precision instruction.
             frac[0:23] <- 0b1 || frac[0:22]
             exp <- exp + 1
         frac[24:52] <- [0b0] * 29
-        FPSCR['FR'] <- inc
-        FPSCR['FI'] <- gbit | rbit | xbit
-        return exp, frac, FPSCR
+        FPSCR.FR <- inc
+        FPSCR.FI <- gbit | rbit | xbit
+        return exp, frac
 
 <!-- Power ISA v3.0B p140 section 4.6.2 -->
 
index 9211e5ab34ed88ece16e7e772176f62d2ef49868..1a02a7c7dd8852d7e315f995c50ebadbd918d5dd 100644 (file)
@@ -8,6 +8,7 @@ from operator import floordiv, mod
 from openpower.decoder.selectable_int import selectltu as ltu
 from openpower.decoder.selectable_int import selectgtu as gtu
 from openpower.decoder.selectable_int import check_extsign
+from openpower.fpscr import FPSCRState
 
 from openpower.util import log
 import math
@@ -847,6 +848,12 @@ class ISACallerHelper:
     def XLEN(self):
         return self.__XLEN
 
+    @property
+    def FPSCR(self):
+        # fallback for when not used through ISACaller
+        self.__dict__["FPSCR"] = retval = FPSCRState()
+        return retval
+
     def EXTZXL(self, value, bits=None):
         if bits is None:
             bits = self.XLEN
@@ -870,14 +877,7 @@ class ISACallerHelper:
             implementation of the frsp instruction.
             use SINGLE() or FRSP() instead, or just use struct.pack/unpack
         """
-        FPSCR = {
-            'UE': SelectableInt(0, 1),
-            'OE': SelectableInt(0, 1),
-            'RN': SelectableInt(0, 2),  # round to nearest, ties to even
-            'XX': SelectableInt(0, 1),
-        }
-        FRT, FPSCR = self.FRSP(FRS, FPSCR)
-        return FRT
+        return self.FRSP(FRS)
 
     def ROTL32(self, value, bits):
         if isinstance(bits, SelectableInt):
index a4c26965f13fd82ab9130c9b90afe59a0a5e3d24..f1e9d6ee4c5fd581c8cc17f604d3b2c9d5873682 100644 (file)
@@ -1268,6 +1268,10 @@ class ISACaller(ISACallerHelper, ISAFPHelpers, StepLoop):
     def XLEN(self):
         return self.namespace["XLEN"]
 
+    @property
+    def FPSCR(self):
+        return self.fpscr
+
     def call_trap(self, trap_addr, trap_bit):
         """calls TRAP and sets up NIA to the new execution location.
         next instruction will begin at trap_addr.
index a88f993400951b619a236a475774d410e0c7632b..5f0300e78a847c6048b98f78035239a70a335778 100644 (file)
@@ -671,7 +671,7 @@ class PowerParser:
                     'SVSHAPE0', 'SVSHAPE1', 'SVSHAPE2', 'SVSHAPE3']:
             self.special_regs.add(name)
             self.write_regs.add(name)  # and add to list to write
-        if name in {'XLEN'}:
+        if name in ('XLEN', 'FPSCR'):
             attr = ast.Name("self", ast.Load())
             p[0] = ast.Attribute(attr, name, ast.Load(), lineno=p.lineno(1))
         else: