x86: implement fild, fucomi, and fucomip x87 insts
authorSteve Reinhardt <steve.reinhardt@amd.com>
Wed, 7 Oct 2015 00:26:50 +0000 (17:26 -0700)
committerSteve Reinhardt <steve.reinhardt@amd.com>
Wed, 7 Oct 2015 00:26:50 +0000 (17:26 -0700)
fild loads an integer value into the x87 top of stack register.
fucomi/fucomip compare two x87 register values (the latter
also doing a stack pop).
These instructions are used by some versions of GNU libstdc++.

src/arch/x86/isa/decoder/x87.isa
src/arch/x86/isa/insts/x87/compare_and_test/floating_point_unordered_compare.py
src/arch/x86/isa/insts/x87/data_transfer_and_conversion/convert_and_load_or_store_integer.py
src/arch/x86/isa/microops/fpop.isa
src/arch/x86/isa/microops/ldstop.isa

index b53c48e786bd3785c0d209e4ffd0d1293a032799..4283d8d91c851d974891a787d8cbd443fb810e11 100644 (file)
@@ -1,5 +1,7 @@
 // Copyright (c) 2007 The Hewlett-Packard Development Company
 // Copyright (c) 2012-13 Mark D. Hill and David A. Wood
+// Copyright (c) 2015 Advanced Micro Devices, Inc.
+//
 // All rights reserved.
 //
 // The license below extends only to copyright in the software and shall
@@ -36,6 +38,7 @@
 //
 // Authors: Gabe Black
 //          Nilay Vaish
+//          Steve Reinhardt
 
 format WarnUnimpl {
     0x1B: decode OPCODE_OP_BOTTOM3 {
@@ -174,7 +177,7 @@ format WarnUnimpl {
         0x3: decode MODRM_REG {
             0x0: decode MODRM_MOD {
                 0x3: fcmovnb();
-                default: fild();
+                default: Inst::FILD(Md); // 32-bit int
             }
             0x1: decode MODRM_MOD {
                 0x3: fcmovne();
@@ -197,7 +200,9 @@ format WarnUnimpl {
                 default: Inst::UD2();
             }
             0x5: decode MODRM_MOD {
-                0x3: fucomi();
+                // 'R' insists on having a size qualifier, so I picked 'q',
+                // but I don't think it has any effect
+                0x3: Inst::FUCOMI(Rq);
                 // 80-bit load
                 default: Inst::FLD80(M);
             }
@@ -331,7 +336,7 @@ format WarnUnimpl {
                 // The ffreep instruction isn't entirely real. It should work
                 // the same as ffree but then also pop the register stack.
                 0x3: ffreep();
-                default: fild();
+                default: Inst::FILD(Mw); // 16-bit int
             }
             0x1: decode MODRM_MOD {
                 0x3: Inst::UD2();
@@ -353,8 +358,10 @@ format WarnUnimpl {
                 default: fbld();
             }
             0x5: decode MODRM_MOD {
-                0x3: fucomip();
-                default: fild();
+                // 'R' insists on having a size qualifier, so I picked 'q',
+                // but I don't think it has any effect
+                0x3: Inst::FUCOMIP(Rq);
+                default: Inst::FILD(Mq); // 64-bit int
             }
             0x6: decode MODRM_MOD {
                 0x3: fcomip();
index 8cca0582baa358f842f0ac6770033b4cd9a07ecf..7007c2d746c5d626a52fc59c2528dc47260cca81 100644 (file)
@@ -1,4 +1,6 @@
 # Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2015 Advanced Micro Devices, Inc.
+#
 # All rights reserved.
 #
 # The license below extends only to copyright in the software and shall
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #
 # Authors: Gabe Black
+#          Steve Reinhardt
 
 microcode = '''
 # FUCOM
 # FUCOMP
 # FUCOMPP
-# FUCOMI
-# FUCOMIP
+
+# fucomi
+def macroop FUCOMI_R {
+    compfp st(0), sti
+};
+
+# fucomi with stack pop (caused by spm=1)
+def macroop FUCOMIP_R {
+    compfp st(0), sti, spm=1
+};
+
 '''
index 38f179d7471863dba4994b34ef7cbf616e2d4677..9bf4ec614de51695d69031c58d55791ba0707e75 100644 (file)
@@ -1,4 +1,6 @@
 # Copyright (c) 2007 The Hewlett-Packard Development Company
+# Copyright (c) 2015 Advanced Micro Devices, Inc.
+#
 # All rights reserved.
 #
 # The license below extends only to copyright in the software and shall
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #
 # Authors: Gabe Black
+#          Steve Reinhardt
 
 microcode = '''
-# FILD
+# fild common case
+def macroop FILD_M {
+    ldifp87 ufp1, seg, sib, disp
+    movfp st(-1), ufp1, spm=-1
+};
+
+# fild with RIP-relative addressing
+def macroop FILD_P {
+    rdip t7
+    ldifp87 ufp1, seg, riprel, disp
+    movfp st(-1), ufp1, spm=-1
+};
+
 # FIST
 # FISTP
 # FISTTP
index 39162d3929ce17348d0aa8c3becaf7434ae706d1..6ba292977c4cea1f8a98dc9d4b008153fbdb7720 100644 (file)
@@ -1,5 +1,7 @@
 // Copyright (c) 2007 The Hewlett-Packard Development Company
 // Copyright (c) 2012-2013 Mark D. Hill and David A. Wood
+// Copyright (c) 2015 Advanced Micro Devices, Inc.
+//
 // All rights reserved.
 //
 // The license below extends only to copyright in the software and shall
index bccec36fe97ee745524cd508ff1b54756898a008..a7c201f441be645cf26278c384a5d7ebbcd43c2d 100644 (file)
@@ -427,6 +427,25 @@ let {{
         }
     ''', big = False)
 
+    # Load integer from memory into x87 top-of-stack register.
+    # Used to implement fild instruction.
+    defineMicroLoadOp('Ldifp87', code='''
+        switch (dataSize)
+        {
+          case 2:
+            FpData_df = (int64_t)sext<16>(Mem);
+            break;
+          case 4:
+            FpData_df = (int64_t)sext<32>(Mem);
+            break;
+          case 8:
+            FpData_df = (int64_t)Mem;
+            break;
+          default:
+            panic("Unhandled data size in LdIFp87.\\n");
+        }
+    ''', big = False)
+
     def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0"):
         global header_output
         global decoder_output