From 0d2e665fc426f2d46b97f52495215916bd5cafd9 Mon Sep 17 00:00:00 2001 From: Kelly Wilson Date: Tue, 10 Mar 2009 06:23:26 -0600 Subject: [PATCH] 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 --- gen/asm-x86-64.h | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/gen/asm-x86-64.h b/gen/asm-x86-64.h index e86912fd..5d2292db 100644 --- a/gen/asm-x86-64.h +++ b/gen/asm-x86-64.h @@ -17,7 +17,7 @@ namespace AsmParserx8664 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 @@ namespace AsmParserx8664 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 @@ namespace AsmParserx8664 { "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 @@ namespace AsmParserx8664 Op_Fis_P, Op_Fid, Op_Fid_P, + Op_FidR_P, Op_Ffd, Op_FfdR, Op_Ffd_P, @@ -523,7 +525,8 @@ namespace AsmParserx8664 /* 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 @@ namespace AsmParserx8664 { "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 @@ namespace AsmParserx8664 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 @@ namespace AsmParserx8664 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;