add first pass at DOUBLE helper function for FP ISACaller simulation
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 14 May 2021 16:31:35 +0000 (17:31 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 14 May 2021 16:31:35 +0000 (17:31 +0100)
src/openpower/decoder/helpers.py

index 70e05d9716fc503cc5a2e9a20d9c046d9ac85990..97a7d8ae4377ed45a115c08e0d27bcc8914a0383 100644 (file)
@@ -1,5 +1,6 @@
 import unittest
-from openpower.decoder.selectable_int import SelectableInt, onebit
+from openpower.decoder.selectable_int import (SelectableInt, onebit,
+                                              selectconcat)
 from nmutil.divmod import trunc_divs, trunc_rems
 from operator import floordiv, mod
 from openpower.decoder.selectable_int import selectltu as ltu
@@ -148,6 +149,45 @@ def undefined(v):
     """
     return v
 
+def DOUBLE(WORD):
+    """convert incoming WORD to double.  v3.0B p140 section 4.6.2
+    """
+    # result, FRT, start off all zeros
+    FRT = SelectableInt(0, 64)
+    z1 = SelectableInt(0, 1)
+    z29 = SelectableInt(0, 29)
+    # Normalized Operand
+    if WORD[1:9] > 0 and WORD[1:9] < 255:
+        FRT[0:2] = WORD[0:2]
+        FRT[2] = ~WORD[1]
+        FRT[3] = ~WORD[1]
+        FRT[4] = ~WORD[1]
+        FRT[5:64] = selectconcat(WORD[2:32], z29)
+
+    # Denormalized Operand
+    if WORD[1:9] == 0 and WORD[9:32] != 0:
+        sign = WORD[0]
+        exp = -126
+        frac[0:53] = selectconcat(z1, WORD[9:32], z29)
+        # normalize the operand
+        while frac[0] == 0:
+            frac[0:53] = selectconcat(frac[1:53], z1)
+            exp = exp - 1
+        FRT[0] = sign
+        FRT[1:12] = exp + 1023
+        FRT[12:64] = frac[1:53]
+
+    # Zero / Infinity / NaN
+    if WORD[1:9] == 255 or WORD[1:32] == 0:
+        FRT[0:2] = WORD[0:2]
+        FRT[2] = WORD[1]
+        FRT[3] = WORD[1]
+        FRT[4] = WORD[1]
+        FRT[5:64] = selectconcat(WORD[2:32], z29)
+
+    return FRT
+
+
 # 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