changeset 1083:c1e9f612e2e2

Fix for dual operand form of fistp, also make reg ST(0) explicit and fix lindquists previous code that allowed dual operand form of fstp but dissallowed the single operand form accidently
author Kelly Wilson <wilsonk cpsc.ucalgary.ca>
date Tue, 10 Mar 2009 06:23:26 -0600
parents 146d8dfa0043
children 56e56b3b9bb8 8cb5b746500c
files gen/asm-x86-64.h
diffstat 1 files changed, 18 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/gen/asm-x86-64.h	Tue Mar 10 10:46:15 2009 +0100
+++ b/gen/asm-x86-64.h	Tue Mar 10 06:23:26 2009 -0600
@@ -17,7 +17,7 @@
         Reg_EDI,
         Reg_EBP,
         Reg_ESP,
-        Reg_ST,
+        Reg_ST, Reg_ST0,
         Reg_ST1, Reg_ST2, Reg_ST3, Reg_ST4, Reg_ST5, Reg_ST6, Reg_ST7,
         Reg_MM0, Reg_MM1, Reg_MM2, Reg_MM3, Reg_MM4, Reg_MM5, Reg_MM6, Reg_MM7,
         Reg_XMM0, Reg_XMM1, Reg_XMM2, Reg_XMM3, Reg_XMM4, Reg_XMM5, Reg_XMM6, Reg_XMM7,
@@ -45,7 +45,7 @@
         Reg_TR3, Reg_TR4, Reg_TR5, Reg_TR6, Reg_TR7
     } Reg;
 
-    static const int N_Regs = /*gp*/ 8 + /*fp*/ 8 + /*mmx*/ 8 + /*sse*/ 8 +
+    static const int N_Regs = /*gp*/ 8 + /*fp*/ 9 + /*mmx*/ 8 + /*sse*/ 8 +
                                      /*seg*/ 6 + /*16bit*/ 8 + /*8bit*/ 8 + /*sys*/ 4+6+5 + /*flags*/ + 1
                                      + 8 /*RAX, etc*/
                                      + 8 /*R8-15*/
@@ -78,6 +78,7 @@
         { "EBP", NULL_TREE, NULL, 4,  Reg_EBP },
         { "ESP", NULL_TREE, NULL, 4,  Reg_ESP },
         { "ST", NULL_TREE, NULL,   10, Reg_ST },
+        { "ST(0)", NULL_TREE, NULL,   10, Reg_ST0 },
         { "ST(1)", NULL_TREE, NULL,10, Reg_ST1 },
         { "ST(2)", NULL_TREE, NULL,10, Reg_ST2 },
         { "ST(3)", NULL_TREE, NULL,10, Reg_ST3 },
@@ -283,6 +284,7 @@
         Op_Fis_P,
         Op_Fid,
         Op_Fid_P,
+        Op_FidR_P,
         Op_Ffd,
         Op_FfdR,
         Op_Ffd_P,
@@ -523,7 +525,8 @@
         /* Op_Fis_ST    */  {   mem, 0,    0,    FPInt_Types, Clb_ST }, // "
         /* 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 }, // push and pop, fild so also 64 bit
+        /* Op_Fid_P     */  { D|mem, 0,    0,    FPInt_Types, Clb_ST, Op_FidR_P }, // push and pop, fild so also 64 bit
+        /* Op_Fid_P     */  { D|mem|mem,rfp, 0,    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, "
@@ -814,8 +817,8 @@
         { "fincstp",Op_F0_P },
         { "finit",  Op_F0_P },
         { "fist",   Op_Fid }, // only 16,32bit
-        { "fistp",  Op_Fid_P },
-        { "fisttp", Op_Fid_P },
+        { "fistp",  Op_FidR_P },
+        { "fisttp", Op_FidR_P },
         { "fisub",  Op_Fis_ST },
         { "fisubr", Op_Fis_ST },
         { "fld",    Op_fld },
@@ -1883,13 +1886,21 @@
                 if ( operands[0].dataSize == Far_Ptr ) // %% type=Far_Ptr not set by Seg:Ofss OTOH, we don't support that..
                     insnTemplate->writebyte ( 'l' );
             }
-            else if ( op == Op_fxch || op == Op_FfdRR_P)
+            else if ( op == Op_fxch || op == Op_FfdRR_P || Op_FidR_P)
             {
                 // gas won't accept the two-operand form
                 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 )
+                {
+                    nOperands = 1;
+                }
+                else if ( operands[0].cls == Opr_Reg && (operands[0].reg == Reg_ST1 || operands[0].reg == Reg_ST || operands[0].reg == Reg_ST0 ))
+                {
+                    //fix previous update to to allow single operand form of fstp
+                }
                 else
                 {
                     stmt->error ( "invalid operands" );
@@ -1998,6 +2009,7 @@
                    operand it would work...  In any case, clobbering
                    all FP prevents incorrect code generation. */
                 asmcode->regs[Reg_ST] = true;
+                asmcode->regs[Reg_ST0] = true;
                 asmcode->regs[Reg_ST1] = true;
                 asmcode->regs[Reg_ST2] = true;
                 asmcode->regs[Reg_ST3] = true;