comparison gen/asm-x86-64.h @ 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 9c63438c3207
children 8cb5b746500c
comparison
equal deleted inserted replaced
1082:146d8dfa0043 1083:c1e9f612e2e2
15 Reg_EDX, 15 Reg_EDX,
16 Reg_ESI, 16 Reg_ESI,
17 Reg_EDI, 17 Reg_EDI,
18 Reg_EBP, 18 Reg_EBP,
19 Reg_ESP, 19 Reg_ESP,
20 Reg_ST, 20 Reg_ST, Reg_ST0,
21 Reg_ST1, Reg_ST2, Reg_ST3, Reg_ST4, Reg_ST5, Reg_ST6, Reg_ST7, 21 Reg_ST1, Reg_ST2, Reg_ST3, Reg_ST4, Reg_ST5, Reg_ST6, Reg_ST7,
22 Reg_MM0, Reg_MM1, Reg_MM2, Reg_MM3, Reg_MM4, Reg_MM5, Reg_MM6, Reg_MM7, 22 Reg_MM0, Reg_MM1, Reg_MM2, Reg_MM3, Reg_MM4, Reg_MM5, Reg_MM6, Reg_MM7,
23 Reg_XMM0, Reg_XMM1, Reg_XMM2, Reg_XMM3, Reg_XMM4, Reg_XMM5, Reg_XMM6, Reg_XMM7, 23 Reg_XMM0, Reg_XMM1, Reg_XMM2, Reg_XMM3, Reg_XMM4, Reg_XMM5, Reg_XMM6, Reg_XMM7,
24 24
25 Reg_RAX, Reg_RBX, Reg_RCX, Reg_RDX, Reg_RSI, Reg_RDI, Reg_RBP, Reg_RSP, 25 Reg_RAX, Reg_RBX, Reg_RCX, Reg_RDX, Reg_RSI, Reg_RDI, Reg_RBP, Reg_RSP,
43 Reg_CR0, Reg_CR2, Reg_CR3, Reg_CR4, 43 Reg_CR0, Reg_CR2, Reg_CR3, Reg_CR4,
44 Reg_DR0, Reg_DR1, Reg_DR2, Reg_DR3, Reg_DR6, Reg_DR7, 44 Reg_DR0, Reg_DR1, Reg_DR2, Reg_DR3, Reg_DR6, Reg_DR7,
45 Reg_TR3, Reg_TR4, Reg_TR5, Reg_TR6, Reg_TR7 45 Reg_TR3, Reg_TR4, Reg_TR5, Reg_TR6, Reg_TR7
46 } Reg; 46 } Reg;
47 47
48 static const int N_Regs = /*gp*/ 8 + /*fp*/ 8 + /*mmx*/ 8 + /*sse*/ 8 + 48 static const int N_Regs = /*gp*/ 8 + /*fp*/ 9 + /*mmx*/ 8 + /*sse*/ 8 +
49 /*seg*/ 6 + /*16bit*/ 8 + /*8bit*/ 8 + /*sys*/ 4+6+5 + /*flags*/ + 1 49 /*seg*/ 6 + /*16bit*/ 8 + /*8bit*/ 8 + /*sys*/ 4+6+5 + /*flags*/ + 1
50 + 8 /*RAX, etc*/ 50 + 8 /*RAX, etc*/
51 + 8 /*R8-15*/ 51 + 8 /*R8-15*/
52 + 4 /*SIL, etc. 8-bit*/ 52 + 4 /*SIL, etc. 8-bit*/
53 + 8 /*R8-15B*/ 53 + 8 /*R8-15B*/
76 { "ESI", NULL_TREE, NULL, 4, Reg_ESI }, 76 { "ESI", NULL_TREE, NULL, 4, Reg_ESI },
77 { "EDI", NULL_TREE, NULL, 4, Reg_EDI }, 77 { "EDI", NULL_TREE, NULL, 4, Reg_EDI },
78 { "EBP", NULL_TREE, NULL, 4, Reg_EBP }, 78 { "EBP", NULL_TREE, NULL, 4, Reg_EBP },
79 { "ESP", NULL_TREE, NULL, 4, Reg_ESP }, 79 { "ESP", NULL_TREE, NULL, 4, Reg_ESP },
80 { "ST", NULL_TREE, NULL, 10, Reg_ST }, 80 { "ST", NULL_TREE, NULL, 10, Reg_ST },
81 { "ST(0)", NULL_TREE, NULL, 10, Reg_ST0 },
81 { "ST(1)", NULL_TREE, NULL,10, Reg_ST1 }, 82 { "ST(1)", NULL_TREE, NULL,10, Reg_ST1 },
82 { "ST(2)", NULL_TREE, NULL,10, Reg_ST2 }, 83 { "ST(2)", NULL_TREE, NULL,10, Reg_ST2 },
83 { "ST(3)", NULL_TREE, NULL,10, Reg_ST3 }, 84 { "ST(3)", NULL_TREE, NULL,10, Reg_ST3 },
84 { "ST(4)", NULL_TREE, NULL,10, Reg_ST4 }, 85 { "ST(4)", NULL_TREE, NULL,10, Reg_ST4 },
85 { "ST(5)", NULL_TREE, NULL,10, Reg_ST5 }, 86 { "ST(5)", NULL_TREE, NULL,10, Reg_ST5 },
281 Op_Fis, 282 Op_Fis,
282 Op_Fis_ST, 283 Op_Fis_ST,
283 Op_Fis_P, 284 Op_Fis_P,
284 Op_Fid, 285 Op_Fid,
285 Op_Fid_P, 286 Op_Fid_P,
287 Op_FidR_P,
286 Op_Ffd, 288 Op_Ffd,
287 Op_FfdR, 289 Op_FfdR,
288 Op_Ffd_P, 290 Op_Ffd_P,
289 Op_FfdR_P, 291 Op_FfdR_P,
290 Op_FfdRR_P, 292 Op_FfdRR_P,
521 /* Op_Fs_P */ { mem, 0, 0, 0, Clb_ST }, // " 523 /* Op_Fs_P */ { mem, 0, 0, 0, Clb_ST }, // "
522 /* Op_Fis */ { mem, 0, 0, FPInt_Types }, // only 16bit and 32bit, DMD defaults to 16bit 524 /* Op_Fis */ { mem, 0, 0, FPInt_Types }, // only 16bit and 32bit, DMD defaults to 16bit
523 /* Op_Fis_ST */ { mem, 0, 0, FPInt_Types, Clb_ST }, // " 525 /* Op_Fis_ST */ { mem, 0, 0, FPInt_Types, Clb_ST }, // "
524 /* Op_Fis_P */ { mem, 0, 0, FPInt_Types, Clb_ST }, // push and pop, fild so also 64 bit 526 /* Op_Fis_P */ { mem, 0, 0, FPInt_Types, Clb_ST }, // push and pop, fild so also 64 bit
525 /* Op_Fid */ { D|mem, 0, 0, FPInt_Types }, // only 16bit and 32bit, DMD defaults to 16bit 527 /* Op_Fid */ { D|mem, 0, 0, FPInt_Types }, // only 16bit and 32bit, DMD defaults to 16bit
526 /* Op_Fid_P */ { D|mem, 0, 0, FPInt_Types, Clb_ST }, // push and pop, fild so also 64 bit 528 /* Op_Fid_P */ { D|mem, 0, 0, FPInt_Types, Clb_ST, Op_FidR_P }, // push and pop, fild so also 64 bit
529 /* Op_Fid_P */ { D|mem|mem,rfp, 0, 0, FPInt_Types, Clb_ST }, // push and pop, fild so also 64 bit
527 /* 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 530 /* 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
528 /* Op_FfdR */ { D|rfp, 0, 0 }, 531 /* Op_FfdR */ { D|rfp, 0, 0 },
529 /* Op_Ffd_P */ { D|mfp, 0, 0, FP_Types, Clb_ST, Next_Form, Op_FfdR_P }, // pop, fld so also 80 bit, " 532 /* Op_Ffd_P */ { D|mfp, 0, 0, FP_Types, Clb_ST, Next_Form, Op_FfdR_P }, // pop, fld so also 80 bit, "
530 /* Op_FfdR_P */ { D|rfp, 0, 0, 0, Clb_ST, Next_Form, Op_FfdRR_P }, 533 /* Op_FfdR_P */ { D|rfp, 0, 0, 0, Clb_ST, Next_Form, Op_FfdRR_P },
531 /* Op_FfdRR_P */ { D|mfp|rfp,rfp,0, 0, Clb_ST }, 534 /* Op_FfdRR_P */ { D|mfp|rfp,rfp,0, 0, Clb_ST },
812 { "fild", Op_Fis_P }, 815 { "fild", Op_Fis_P },
813 { "fimul", Op_Fis_ST }, 816 { "fimul", Op_Fis_ST },
814 { "fincstp",Op_F0_P }, 817 { "fincstp",Op_F0_P },
815 { "finit", Op_F0_P }, 818 { "finit", Op_F0_P },
816 { "fist", Op_Fid }, // only 16,32bit 819 { "fist", Op_Fid }, // only 16,32bit
817 { "fistp", Op_Fid_P }, 820 { "fistp", Op_FidR_P },
818 { "fisttp", Op_Fid_P }, 821 { "fisttp", Op_FidR_P },
819 { "fisub", Op_Fis_ST }, 822 { "fisub", Op_Fis_ST },
820 { "fisubr", Op_Fis_ST }, 823 { "fisubr", Op_Fis_ST },
821 { "fld", Op_fld }, 824 { "fld", Op_fld },
822 { "fld1", Op_F0_P }, 825 { "fld1", Op_F0_P },
823 { "fldcw", Op_SrcMemNT }, 826 { "fldcw", Op_SrcMemNT },
1881 else if ( op == Op_Branch ) 1884 else if ( op == Op_Branch )
1882 { 1885 {
1883 if ( operands[0].dataSize == Far_Ptr ) // %% type=Far_Ptr not set by Seg:Ofss OTOH, we don't support that.. 1886 if ( operands[0].dataSize == Far_Ptr ) // %% type=Far_Ptr not set by Seg:Ofss OTOH, we don't support that..
1884 insnTemplate->writebyte ( 'l' ); 1887 insnTemplate->writebyte ( 'l' );
1885 } 1888 }
1886 else if ( op == Op_fxch || op == Op_FfdRR_P) 1889 else if ( op == Op_fxch || op == Op_FfdRR_P || Op_FidR_P)
1887 { 1890 {
1888 // gas won't accept the two-operand form 1891 // gas won't accept the two-operand form
1889 if ( operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST ) 1892 if ( operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST )
1890 { 1893 {
1891 nOperands = 1; 1894 nOperands = 1;
1895 }
1896 else if ( operands[1].cls == Opr_Mem && operands[1].reg == Reg_ST )
1897 {
1898 nOperands = 1;
1899 }
1900 else if ( operands[0].cls == Opr_Reg && (operands[0].reg == Reg_ST1 || operands[0].reg == Reg_ST || operands[0].reg == Reg_ST0 ))
1901 {
1902 //fix previous update to to allow single operand form of fstp
1892 } 1903 }
1893 else 1904 else
1894 { 1905 {
1895 stmt->error ( "invalid operands" ); 1906 stmt->error ( "invalid operands" );
1896 return false; 1907 return false;
1996 asm statement leaves an arg pushed on the stack. 2007 asm statement leaves an arg pushed on the stack.
1997 Maybe if the statment had and input or output 2008 Maybe if the statment had and input or output
1998 operand it would work... In any case, clobbering 2009 operand it would work... In any case, clobbering
1999 all FP prevents incorrect code generation. */ 2010 all FP prevents incorrect code generation. */
2000 asmcode->regs[Reg_ST] = true; 2011 asmcode->regs[Reg_ST] = true;
2012 asmcode->regs[Reg_ST0] = true;
2001 asmcode->regs[Reg_ST1] = true; 2013 asmcode->regs[Reg_ST1] = true;
2002 asmcode->regs[Reg_ST2] = true; 2014 asmcode->regs[Reg_ST2] = true;
2003 asmcode->regs[Reg_ST3] = true; 2015 asmcode->regs[Reg_ST3] = true;
2004 asmcode->regs[Reg_ST4] = true; 2016 asmcode->regs[Reg_ST4] = true;
2005 asmcode->regs[Reg_ST5] = true; 2017 asmcode->regs[Reg_ST5] = true;