# HG changeset patch # User Kelly Wilson # Date 1236687806 21600 # Node ID c1e9f612e2e27b3e37887da418e3e3d292f66753 # Parent 146d8dfa00433f36a84d282889885051ca1d1933 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 diff -r 146d8dfa0043 -r c1e9f612e2e2 gen/asm-x86-64.h --- 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;