use log function for warnings about .mdwn files in pagereader.py
[openpower-isa.git] / src / openpower / decoder / helpers.py
index a11081bc2478fefe8e38a4fddb303a3dc4bea608..a81c3f09f75d112e592b86f3f47da8f2786f0b6c 100644 (file)
@@ -41,7 +41,7 @@ def exts(value, bits):
 def EXTS(value):
     """ extends sign bit out from current MSB to all 256 bits
     """
-    log ("EXTS", value, type(value))
+    log("EXTS", value, type(value))
     assert isinstance(value, SelectableInt)
     return SelectableInt(exts(value.value, value.bits) & ((1 << 256)-1), 256)
 
@@ -108,6 +108,7 @@ def ROTL32(value, bits):
         value = SelectableInt(value.value, 64)
     return rotl(value | (value << 32), bits, 64)
 
+
 def MASK32(x, y):
     if isinstance(x, SelectableInt):
         x = x.value
@@ -115,6 +116,7 @@ def MASK32(x, y):
         y = y.value
     return MASK(x+32, y+32)
 
+
 def MASK(x, y):
     if isinstance(x, SelectableInt):
         x = x.value
@@ -183,37 +185,38 @@ def SINGLE(FRS):
     m = FRS[12:64]
     s = FRS[0]
 
-    log ("SINGLE", FRS)
-    log ("s e m", s.value, e.value, m.value)
-
-    #No Denormalization Required (includes Zero / Infinity / NaN)
-    if e.value > 896 or FRS[1:64].value  == 0:
-          log("nodenorm", FRS[0:2].value, hex(FRS[5:35].value))
-          WORD[0:2] = FRS[0:2]
-          WORD[2:32] = FRS[5:35]
-
-    #Denormalization Required
-    if e.value  >= 874 and e.value <= 896:
-          sign = FRS[0]
-          exp = e.value - 1023
-          frac = selectconcat(SelectableInt(1, 1), FRS[12:64])
-          log("exp, fract", exp, hex(frac.value))
-          # denormalize operand
-          while exp < -126:
-              frac[0:53] = selectconcat(SelectableInt(0, 1), frac[0:52])
-              exp = exp + 1
-          WORD[0] = sign
-          WORD[1:9] = SelectableInt(0, 8)
-          WORD[9:32] = frac[1:24]
-    #else WORD = undefined # return zeros
-
-    log ("WORD", WORD)
+    log("SINGLE", FRS)
+    log("s e m", s.value, e.value, m.value)
+
+    # No Denormalization Required (includes Zero / Infinity / NaN)
+    if e.value > 896 or FRS[1:64].value == 0:
+        log("nodenorm", FRS[0:2].value, hex(FRS[5:35].value))
+        WORD[0:2] = FRS[0:2]
+        WORD[2:32] = FRS[5:35]
+
+    # Denormalization Required
+    if e.value >= 874 and e.value <= 896:
+        sign = FRS[0]
+        exp = e.value - 1023
+        frac = selectconcat(SelectableInt(1, 1), FRS[12:64])
+        log("exp, fract", exp, hex(frac.value))
+        # denormalize operand
+        while exp < -126:
+            frac[0:53] = selectconcat(SelectableInt(0, 1), frac[0:52])
+            exp = exp + 1
+        WORD[0] = sign
+        WORD[1:9] = SelectableInt(0, 8)
+        WORD[9:32] = frac[1:24]
+    # else WORD = undefined # return zeros
+
+    log("WORD", WORD)
 
     return WORD
 
 # XXX NOTE: these are very quick hacked functions for utterly basic
 # FP support
 
+
 def signinv(res, sign):
     if sign == 1:
         return res
@@ -238,7 +241,7 @@ class ISAFPHelpers:
         result = math.sin(float(FRB))
         cvt = fp64toselectable(result)
         cvt = self.DOUBLE2SINGLE(cvt)
-        log ("FPSIN32", FRB, float(FRB), "=", result, cvt)
+        log("FPSIN32", FRB, float(FRB), "=", result, cvt)
         return cvt
 
     def FPCOS32(self, FRB):
@@ -246,106 +249,105 @@ class ISAFPHelpers:
         result = math.cos(float(FRB))
         cvt = fp64toselectable(result)
         cvt = self.DOUBLE2SINGLE(cvt)
-        log ("FPCOS32", FRB, float(FRB), "=", result, cvt)
+        log("FPCOS32", FRB, float(FRB), "=", result, cvt)
         return cvt
 
     def FPADD32(self, FRA, FRB):
-        #return FPADD64(FRA, FRB)
+        # return FPADD64(FRA, FRB)
         #FRA = DOUBLE(SINGLE(FRA))
         #FRB = DOUBLE(SINGLE(FRB))
         result = float(FRA) + float(FRB)
         cvt = fp64toselectable(result)
         cvt = self.DOUBLE2SINGLE(cvt)
-        log ("FPADD32", FRA, FRB, float(FRA), "+", float(FRB), "=", result, cvt)
+        log("FPADD32", FRA, FRB, float(FRA), "+", float(FRB), "=", result, cvt)
         return cvt
 
     def FPSUB32(self, FRA, FRB):
-        #return FPSUB64(FRA, FRB)
+        # return FPSUB64(FRA, FRB)
         #FRA = DOUBLE(SINGLE(FRA))
         #FRB = DOUBLE(SINGLE(FRB))
         result = float(FRA) - float(FRB)
         cvt = fp64toselectable(result)
         cvt = self.DOUBLE2SINGLE(cvt)
-        log ("FPSUB32", FRA, FRB, float(FRA), "-", float(FRB), "=", result, cvt)
+        log("FPSUB32", FRA, FRB, float(FRA), "-", float(FRB), "=", result, cvt)
         return cvt
 
     def FPMUL32(self, FRA, FRB, sign=1):
-        #return FPMUL64(FRA, FRB)
+        # return FPMUL64(FRA, FRB)
         FRA = self.DOUBLE(SINGLE(FRA))
         FRB = self.DOUBLE(SINGLE(FRB))
         result = signinv(float(FRA) * float(FRB), sign)
-        log ("FPMUL32", FRA, FRB, float(FRA), float(FRB), result, sign)
+        log("FPMUL32", FRA, FRB, float(FRA), float(FRB), result, sign)
         cvt = fp64toselectable(result)
         cvt = self.DOUBLE2SINGLE(cvt)
-        log ("      cvt", cvt)
+        log("      cvt", cvt)
         return cvt
 
     def FPMULADD32(self, FRA, FRC, FRB, mulsign, addsign):
-        #return FPMUL64(FRA, FRB)
+        # return FPMUL64(FRA, FRB)
         #FRA = DOUBLE(SINGLE(FRA))
         #FRB = DOUBLE(SINGLE(FRB))
         if addsign == 1:
             if mulsign == 1:
-                result = float(FRA) * float(FRC) + float(FRB) # fmadds
+                result = float(FRA) * float(FRC) + float(FRB)  # fmadds
             elif mulsign == -1:
                 result = -(float(FRA) * float(FRC) - float(FRB))  # fnmsubs
         elif addsign == -1:
             if mulsign == 1:
-                result = float(FRA) * float(FRC) - float(FRB) # fmsubs
+                result = float(FRA) * float(FRC) - float(FRB)  # fmsubs
             elif mulsign == -1:
                 result = -(float(FRA) * float(FRC) + float(FRB))  # fnmadds
         elif addsign == 0:
             result = 0.0
-        log ("FPMULADD32 FRA FRC FRB", FRA, FRC, FRB)
-        log ("      FRA", float(FRA))
-        log ("      FRC", float(FRC))
-        log ("      FRB", float(FRB))
-        log ("      (FRA*FRC)+FRB=", mulsign, addsign, result)
+        log("FPMULADD32 FRA FRC FRB", FRA, FRC, FRB)
+        log("      FRA", float(FRA))
+        log("      FRC", float(FRC))
+        log("      FRB", float(FRB))
+        log("      (FRA*FRC)+FRB=", mulsign, addsign, result)
         cvt = fp64toselectable(result)
         cvt = self.DOUBLE2SINGLE(cvt)
-        log ("      cvt", cvt)
+        log("      cvt", cvt)
         return cvt
 
     def FPDIV32(self, FRA, FRB, sign=1):
-        #return FPDIV64(FRA, FRB)
+        # return FPDIV64(FRA, FRB)
         #FRA = DOUBLE(SINGLE(FRA))
         #FRB = DOUBLE(SINGLE(FRB))
         result = signinv(float(FRA) / float(FRB), sign)
         cvt = fp64toselectable(result)
         cvt = self.DOUBLE2SINGLE(cvt)
-        log ("FPDIV32", FRA, FRB, result, cvt)
+        log("FPDIV32", FRA, FRB, result, cvt)
         return cvt
 
 
 def FPADD64(FRA, FRB):
     result = float(FRA) + float(FRB)
     cvt = fp64toselectable(result)
-    log ("FPADD64", FRA, FRB, result, cvt)
+    log("FPADD64", FRA, FRB, result, cvt)
     return cvt
 
 
 def FPSUB64(FRA, FRB):
     result = float(FRA) - float(FRB)
     cvt = fp64toselectable(result)
-    log ("FPSUB64", FRA, FRB, result, cvt)
+    log("FPSUB64", FRA, FRB, result, cvt)
     return cvt
 
 
 def FPMUL64(FRA, FRB, sign=1):
     result = signinv(float(FRA) * float(FRB), sign)
     cvt = fp64toselectable(result)
-    log ("FPMUL64", FRA, FRB, result, cvt, sign)
+    log("FPMUL64", FRA, FRB, result, cvt, sign)
     return cvt
 
 
 def FPDIV64(FRA, FRB, sign=1):
     result = signinv(float(FRA) / float(FRB), sign)
     cvt = fp64toselectable(result)
-    log ("FPDIV64", FRA, FRB, result, cvt, sign)
+    log("FPDIV64", FRA, FRB, result, cvt, sign)
     return cvt
 
 
-
 def bitrev(val, VL):
     """Returns the integer whose value is the reverse of the lowest
     'width' bits of the integer 'val'
@@ -358,6 +360,15 @@ def bitrev(val, VL):
     return result
 
 
+def log2(val):
+    """return the base-2 logarithm of `val`. Only works for powers of 2."""
+    if isinstance(val, SelectableInt):
+        val = val.value
+    retval = val.bit_length() - 1
+    assert val == 2 ** retval, "value is not a power of 2"
+    return retval
+
+
 # For these tests I tried to find power instructions that would let me
 # isolate each of these helper operations. So for instance, when I was
 # testing the MASK() function, I chose rlwinm and rldicl because if I
@@ -454,8 +465,25 @@ class ISACallerHelper:
         return SelectableInt(exts(value.value, self.XLEN), self.XLEN)
 
     def XLCASTU(self, value):
-        bits = min(value.bits, self.XLEN)
-        return SelectableInt(value.value & ((1 << bits) - 1), self.XLEN)
+        # SelectableInt already takes care of masking out the bits
+        return SelectableInt(value.value, self.XLEN)
+
+    def EXTSXL(self, value, bits):
+        return SelectableInt(exts(value.value, bits), self.XLEN)
+
+    def DOUBLE2SINGLE(self, FRS):
+        """ DOUBLE2SINGLE has been renamed to FRSP since it is the
+            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
 
     def __getattr__(self, attr):
         try: