From 0d2e665fc426f2d46b97f52495215916bd5cafd9 Mon Sep 17 00:00:00 2001 From: Kelly Wilson Date: Tue, 10 Mar 2009 06:23:26 -0600 Subject: [PATCH 1/4] 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; From 5bb81ac3d2c6f53088ef15a9abee5c521edae1e3 Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 10 Mar 2009 09:13:13 -0400 Subject: [PATCH 2/4] Fix 32bit version of "jle short Label;" for 'short' or 'long'. --- gen/asm-x86-32.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/gen/asm-x86-32.h b/gen/asm-x86-32.h index 6b2130ad..97788803 100644 --- a/gen/asm-x86-32.h +++ b/gen/asm-x86-32.h @@ -449,7 +449,7 @@ namespace AsmParserx8632 /* 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_FfdRR_P }, // 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, " @@ -1377,7 +1377,15 @@ namespace AsmParserx8632 } if ( token->value == TOKcomma ) + { nextToken(); + } + else if ( token->value == TOKint16 || token->value == TOKint32 ) + { + //throw away the 'short' in "jle short label;". Works for 'long' also. + operands[0] = operands[1]; + return; + } else if ( token->value != TOKeof ) { ok = false; @@ -2784,6 +2792,10 @@ namespace AsmParserx8632 ident = Id::__dollar; goto do_dollar; break; + case TOKint16: + case TOKint32: + //This if for the 'short' in "jle short Label;" + return Handled; default: invalidExpression(); return Handled; From e59c7db6374aeecc6bccb5476a8152fd8acb5c78 Mon Sep 17 00:00:00 2001 From: Kelly Wilson Date: Tue, 10 Mar 2009 11:06:38 -0600 Subject: [PATCH 3/4] Properly fix fistp for x64 --- gen/asm-x86-64.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/gen/asm-x86-64.h b/gen/asm-x86-64.h index 5d2292db..5df0b782 100644 --- a/gen/asm-x86-64.h +++ b/gen/asm-x86-64.h @@ -525,8 +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, 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_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, 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, " @@ -817,8 +817,8 @@ namespace AsmParserx8664 { "fincstp",Op_F0_P }, { "finit", Op_F0_P }, { "fist", Op_Fid }, // only 16,32bit - { "fistp", Op_FidR_P }, - { "fisttp", Op_FidR_P }, + { "fistp", Op_Fid_P }, + { "fisttp", Op_Fid_P }, { "fisub", Op_Fis_ST }, { "fisubr", Op_Fis_ST }, { "fld", Op_fld }, @@ -1549,7 +1549,7 @@ namespace AsmParserx8664 classifyOperand ( & operands[i] ); while ( 1 ) - { + { if ( nOperands == opInfo->nOperands() ) { wrong_number = false; @@ -1886,14 +1886,14 @@ 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 || Op_FidR_P) + else if ( op == Op_fxch || op == Op_FfdRR_P || op == Op_FidR_P ) { - // gas won't accept the two-operand form - if ( operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST ) + if ( operands[0].cls == Opr_Mem && op == Op_FidR_P ) { nOperands = 1; } - else if ( operands[1].cls == Opr_Mem && operands[1].reg == Reg_ST ) + // gas won't accept the two-operand form + else if ( operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST ) { nOperands = 1; } From 2d114846490580059ca315f2e09ce6fa44806f96 Mon Sep 17 00:00:00 2001 From: Kelly Wilson Date: Tue, 10 Mar 2009 13:59:50 -0400 Subject: [PATCH 4/4] fix fistp properly for x32 --- gen/asm-x86-32.h | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/gen/asm-x86-32.h b/gen/asm-x86-32.h index 97788803..0a7de760 100644 --- a/gen/asm-x86-32.h +++ b/gen/asm-x86-32.h @@ -209,6 +209,7 @@ namespace AsmParserx8632 Op_Fis_P, Op_Fid, Op_Fid_P, + Op_FidR_P, Op_Ffd, Op_FfdR, Op_Ffd_P, @@ -449,7 +450,8 @@ namespace AsmParserx8632 /* 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, Op_FfdRR_P }, // push and pop, fild so also 64 bit + /* 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, 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, " @@ -1757,13 +1759,25 @@ namespace AsmParserx8632 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 == Op_FidR_P ) { + if ( operands[0].cls == Opr_Mem && op == Op_FidR_P ) + { + nOperands = 1; + } // gas won't accept the two-operand form - if ( operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST ) + 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" );