Mercurial > projects > ldc
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;