changeset 1320:1ad5a58b5c9d

Restrict second arg of certain floating-point stores to ST. Fix type postfix for the two argument form of fistp and fisttp.
author Christian Kamm <kamm incasoftware de>
date Sat, 09 May 2009 08:58:41 +0200
parents acc5d68a21d3
children d55945bcb02d
files gen/asm-x86-32.h gen/asm-x86-64.h
diffstat 2 files changed, 21 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/gen/asm-x86-32.h	Thu May 07 21:49:58 2009 +0200
+++ b/gen/asm-x86-32.h	Sat May 09 08:58:41 2009 +0200
@@ -454,7 +454,7 @@
         /* Op_Fis_P     */  {   mem, 0,    0,    FPInt_Types, Clb_ST }, // push and pop, fild so also 64 bit
         /* Op_Fid       */  { D|mem, 0,    0,    FPInt_Types }, // only 16bit and 32bit, DMD defaults to 16bit
         /* Op_Fid_P     */  { D|mem, 0,    0,    FPInt_Types, Clb_ST, Next_Form, Op_FidR_P }, // push and pop, fild so also 64 bit
-        /* Op_FidR_P    */  { D|mem,rfp,   0,    0, Clb_ST }, // push and pop, fild so also 64 bit
+        /* Op_FidR_P    */  { D|mem,rfp,   0,    FPInt_Types, Clb_ST }, // push and pop, fild so also 64 bit
         /* Op_Ffd       */  { D|mfp, 0,    0,    FP_Types, 0, Next_Form, Op_FfdR }, // only 16bit and 32bit, DMD defaults to 16bit, reg form doesn't need type
         /* Op_FfdR      */  { D|rfp, 0,    0  },
         /* Op_Ffd_P     */  { D|mfp, 0,    0,    FP_Types, Clb_ST, Next_Form, Op_FfdR_P }, // pop, fld so also 80 bit, "
@@ -1723,6 +1723,16 @@
             else
                 mnemonic = opIdent->string;
 
+            // handle two-operand form where second arg is ignored.
+            // must be done before type_char detection
+            if ( op == Op_FidR_P || op == Op_fxch || op == Op_FfdRR_P )
+            {
+                if (operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST )
+                    nOperands = 1;
+                else
+                    stmt->error("instruction allows only ST as second argument");
+            }
+
             if ( opInfo->needsType )
             {
                 PtrType exact_type = Default_Ptr;
@@ -1787,31 +1797,6 @@
                 if ( operands[0].dataSize == Far_Ptr ) // %% type=Far_Ptr not set by Seg:Ofss OTOH, we don't support that..
                     insnTemplate << 'l';
             }
-            else if ( op == Op_fxch || op == Op_FfdRR_P || op == Op_FidR_P )
-            {
-	        if ( operands[0].cls == Opr_Mem && op == Op_FidR_P )
-		{
-                    nOperands = 1;
-                }
-                // gas won't accept the two-operand form
-                else if ( operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST )
-                {
-                    nOperands = 1;
-                }
-                else if ( operands[1].cls == Opr_Mem && operands[1].reg == Reg_ST || operands[0].cls == Opr_Mem )
-		{
-		    nOperands = 1;
-                }
-                else if ( operands[0].cls == Opr_Reg && (operands[0].reg == Reg_ST || operands[0].reg == Reg_ST1 ))
-		{
-		    //fix previous update to allow single operand form of fstp
-                }
-                else
-                {
-                    stmt->error ( "invalid operands" );
-                    return false;
-                }
-            }
             else if ( op == Op_FMath0 || op == Op_FdST0ST1 )
             {
                 operands[0].cls = Opr_Reg;
--- a/gen/asm-x86-64.h	Thu May 07 21:49:58 2009 +0200
+++ b/gen/asm-x86-64.h	Sat May 09 08:58:41 2009 +0200
@@ -1849,6 +1849,16 @@
             else
                 mnemonic = opIdent->string;
             
+            // handle two-operand form where second arg is ignored.
+            // must be done before type_char detection
+            if ( op == Op_FidR_P || op == Op_fxch || op == Op_FfdRR_P )
+            {
+                if (operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST )
+                    nOperands = 1;
+                else
+                    stmt->error("instruction allows only ST as second argument");
+            }
+
             if ( opInfo->needsType )
             {
                 PtrType exact_type = Default_Ptr;
@@ -1913,27 +1923,6 @@
                 if ( operands[0].dataSize == Far_Ptr ) // %% type=Far_Ptr not set by Seg:Ofss OTOH, we don't support that..
                     insnTemplate << 'l';
             }
-            else if ( op == Op_fxch || op == Op_FfdRR_P || op == Op_FidR_P )
-            {
-                if ( operands[0].cls == Opr_Mem && op == Op_FidR_P )
-                {
-                    nOperands = 1;
-                }
-                // gas won't accept the two-operand form
-                else if ( operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST )
-                {
-                    nOperands = 1;
-                }
-                else if ( operands[0].cls == Opr_Reg && (operands[0].reg == Reg_ST1 || operands[0].reg == Reg_ST ))
-                {
-                    //fix previous update to allow single operand form of fstp
-                }
-                else
-                {
-                    stmt->error ( "invalid operands" );
-                    return false;
-                }
-            }
             else if ( op == Op_FMath0 || op == Op_FdST0ST1 )
             {
                 operands[0].cls = Opr_Reg;