x86: implement x87 fp instruction fsincos
authorNilay Vaish <nilay@cs.wisc.edu>
Sun, 30 Dec 2012 18:45:45 +0000 (12:45 -0600)
committerNilay Vaish <nilay@cs.wisc.edu>
Sun, 30 Dec 2012 18:45:45 +0000 (12:45 -0600)
This patch implements the fsincos instruction. The code was originally written
by Vince Weaver. Gabe had made some comments about the code, but those were
never addressed. This patch addresses those comments.

src/arch/x86/isa/decoder/x87.isa
src/arch/x86/isa/insts/x87/transcendental_functions/trigonometric_functions.py
src/arch/x86/isa/microops/fpop.isa

index ace96fbf6e9802e2c4a47696eaf39fe016fe1ce6..4ed902192ea539168c1995c3021255ffb533eab1 100644 (file)
@@ -106,7 +106,7 @@ format WarnUnimpl {
                     0x0: fprem();
                     0x1: fyl2xp1();
                     0x2: fsqrt();
-                    0x3: fsincos();
+                    0x3: Inst::FSINCOS();
                     0x4: frndint();
                     0x5: fscale();
                     0x6: fsin();
index 437b47d70aefd76296f9a18b996aadb18f2ae905..05fd20829f12f7a33c306345d814af05a0c7b75d 100644 (file)
 microcode = '''
 # FSIN
 # FCOS
-# FSINCOS
+
+def macroop FSINCOS {
+    sinfp ufp1, st(0)
+    cosfp ufp2, st(0)
+    movfp st(0), ufp1
+    movfp st(-1), ufp2, spm=-1
+};
+
 # FPTAN
 # FPATAN
 '''
index 7acbe04eadff52441a3edcdc5692ff13a0e4099b..f6cbd203668604daa485389f03af95541d7fdde6 100644 (file)
@@ -174,8 +174,40 @@ let {{
 
             return cls
 
+    class FpUnaryOp(X86Microop):
+        __metaclass__ = FpOpMeta
+        # This class itself doesn't act as a microop
+        abstract = True
 
-    class FpOp(X86Microop):
+        # Default template parameter values
+        flag_code = ""
+        cond_check = "true"
+        else_code = ";"
+
+        def __init__(self, dest, src1, spm=0, \
+                SetStatus=False, dataSize="env.dataSize"):
+            self.dest = dest
+            self.src1 = src1
+            self.src2 = "InstRegIndex(0)"
+            self.spm = spm
+            self.dataSize = dataSize
+            if SetStatus:
+                self.className += "Flags"
+            if spm:
+                self.className += "Top"
+
+        def getAllocator(self, microFlags):
+            return '''new %(class_name)s(machInst, macrocodeBlock,
+                    %(flags)s, %(src1)s, %(src2)s, %(dest)s,
+                    %(dataSize)s, %(spm)d)''' % {
+                "class_name" : self.className,
+                "flags" : self.microFlagsText(microFlags),
+                "src1" : self.src1, "src2" : self.src2,
+                "dest" : self.dest,
+                "dataSize" : self.dataSize,
+                "spm" : self.spm}
+
+    class FpBinaryOp(X86Microop):
         __metaclass__ = FpOpMeta
         # This class itself doesn't act as a microop
         abstract = True
@@ -208,24 +240,27 @@ let {{
                 "dataSize" : self.dataSize,
                 "spm" : self.spm}
 
-    class Movfp(FpOp):
-        def __init__(self, dest, src1, spm=0, \
-                SetStatus=False, dataSize="env.dataSize"):
-            super(Movfp, self).__init__(dest, src1, "InstRegIndex(0)", \
-                    spm, SetStatus, dataSize)
+    class Movfp(FpUnaryOp):
         code = 'FpDestReg_uqw = FpSrcReg1_uqw;'
         else_code = 'FpDestReg_uqw = FpDestReg_uqw;'
         cond_check = "checkCondition(ccFlagBits | cfofBits | dfBit | \
                                      ecfBit | ezfBit, src2)"
 
-    class Xorfp(FpOp):
+    class Xorfp(FpBinaryOp):
         code = 'FpDestReg_uqw = FpSrcReg1_uqw ^ FpSrcReg2_uqw;'
 
-    class Sqrtfp(FpOp):
+    class Sqrtfp(FpBinaryOp):
         code = 'FpDestReg = sqrt(FpSrcReg2);'
 
+    class Cosfp(FpUnaryOp):
+        code = 'FpDestReg = cos(FpSrcReg1);'
+
+    class Sinfp(FpUnaryOp):
+        code = 'FpDestReg = sin(FpSrcReg1);'
+
+
     # Conversion microops
-    class ConvOp(FpOp):
+    class ConvOp(FpBinaryOp):
         abstract = True
         def __init__(self, dest, src1):
             super(ConvOp, self).__init__(dest, src1, \
@@ -258,19 +293,19 @@ let {{
 
     # These need to consider size at some point. They'll always use doubles
     # for the moment.
-    class addfp(FpOp):
+    class addfp(FpBinaryOp):
         code = 'FpDestReg = FpSrcReg1 + FpSrcReg2;'
 
-    class mulfp(FpOp):
+    class mulfp(FpBinaryOp):
         code = 'FpDestReg = FpSrcReg1 * FpSrcReg2;'
 
-    class divfp(FpOp):
+    class divfp(FpBinaryOp):
         code = 'FpDestReg = FpSrcReg1 / FpSrcReg2;'
 
-    class subfp(FpOp):
+    class subfp(FpBinaryOp):
         code = 'FpDestReg = FpSrcReg1 - FpSrcReg2;'
 
-    class Compfp(FpOp):
+    class Compfp(FpBinaryOp):
         def __init__(self, src1, src2, spm=0, setStatus=False, \
                 dataSize="env.dataSize"):
             super(Compfp, self).__init__("InstRegIndex(FLOATREG_MICROFP0)", \