comparison gen/asm-x86-64.h @ 1091:20d96c148b39

Fix for fmul/div/add/sub with no operands. Revert explicit ST0 definition since a typo had caused the need for that.
author Kelly Wilson <wilsonk cpsc.ucalgary.ca>
date Tue, 10 Mar 2009 18:34:19 -0600
parents 8cb5b746500c
children cb868105a6b5
comparison
equal deleted inserted replaced
1090:6a19c36fc4a6 1091:20d96c148b39
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, Reg_ST0, 20 Reg_ST,
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*/ 9 + /*mmx*/ 8 + /*sse*/ 8 + 48 static const int N_Regs = /*gp*/ 8 + /*fp*/ 8 + /*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 },
82 { "ST(1)", NULL_TREE, NULL,10, Reg_ST1 }, 81 { "ST(1)", NULL_TREE, NULL,10, Reg_ST1 },
83 { "ST(2)", NULL_TREE, NULL,10, Reg_ST2 }, 82 { "ST(2)", NULL_TREE, NULL,10, Reg_ST2 },
84 { "ST(3)", NULL_TREE, NULL,10, Reg_ST3 }, 83 { "ST(3)", NULL_TREE, NULL,10, Reg_ST3 },
85 { "ST(4)", NULL_TREE, NULL,10, Reg_ST4 }, 84 { "ST(4)", NULL_TREE, NULL,10, Reg_ST4 },
86 { "ST(5)", NULL_TREE, NULL,10, Reg_ST5 }, 85 { "ST(5)", NULL_TREE, NULL,10, Reg_ST5 },
291 Op_FfdR_P, 290 Op_FfdR_P,
292 Op_FfdRR_P, 291 Op_FfdRR_P,
293 Op_Fd_P, 292 Op_Fd_P,
294 Op_FdST, 293 Op_FdST,
295 Op_FMath, 294 Op_FMath,
295 Op_FMath0,
296 Op_FMath2,
296 Op_FdSTiSTi, 297 Op_FdSTiSTi,
298 Op_FdST0ST1,
297 Op_FPMath, 299 Op_FPMath,
298 Op_FCmp, 300 Op_FCmp,
299 Op_FCmp1, 301 Op_FCmp1,
300 Op_FCmpP, 302 Op_FCmpP,
301 Op_FCmpP1, 303 Op_FCmpP1,
532 /* Op_Ffd_P */ { D|mfp, 0, 0, FP_Types, Clb_ST, Next_Form, Op_FfdR_P }, // pop, fld so also 80 bit, " 534 /* Op_Ffd_P */ { D|mfp, 0, 0, FP_Types, Clb_ST, Next_Form, Op_FfdR_P }, // pop, fld so also 80 bit, "
533 /* Op_FfdR_P */ { D|rfp, 0, 0, 0, Clb_ST, Next_Form, Op_FfdRR_P }, 535 /* Op_FfdR_P */ { D|rfp, 0, 0, 0, Clb_ST, Next_Form, Op_FfdRR_P },
534 /* Op_FfdRR_P */ { D|mfp|rfp,rfp,0, 0, Clb_ST }, 536 /* Op_FfdRR_P */ { D|mfp|rfp,rfp,0, 0, Clb_ST },
535 /* Op_Fd_P */ { D|mem, 0, 0, 0, Clb_ST }, // " 537 /* Op_Fd_P */ { D|mem, 0, 0, 0, Clb_ST }, // "
536 /* Op_FdST */ { D|rfp, 0, 0 }, 538 /* Op_FdST */ { D|rfp, 0, 0 },
537 /* Op_FMath */ { mfp, 0, 0, FP_Types, Clb_ST, Next_Form, Op_FdSTiSTi }, // and only single or double prec 539 /* Op_FMath */ { mfp, 0, 0, FP_Types, Clb_ST, Next_Form, Op_FMath0 }, // and only single or double prec
540 /* Op_FMath0 */ { 0, 0, 0, 0, Clb_ST, Next_Form, Op_FMath2 }, // pops
541 /* Op_FMath2 */ { D|rfp, rfp, 0, 0, Clb_ST, Next_Form, Op_FdST0ST1 }, // and only single or double prec
538 /* Op_FdSTiSTi */ { D|rfp, rfp, 0, }, 542 /* Op_FdSTiSTi */ { D|rfp, rfp, 0, },
543 /* Op_FdST0ST1 */ { 0, 0, 0, },
539 /* Op_FPMath */ { D|rfp, rfp, 0, 0, Clb_ST, Next_Form, Op_F0_P }, // pops 544 /* Op_FPMath */ { D|rfp, rfp, 0, 0, Clb_ST, Next_Form, Op_F0_P }, // pops
540 /* Op_FCmp */ { mfp, 0, 0, FP_Types, 0, Next_Form, Op_FCmp1 }, // DMD defaults to float ptr 545 /* Op_FCmp */ { mfp, 0, 0, FP_Types, 0, Next_Form, Op_FCmp1 }, // DMD defaults to float ptr
541 /* Op_FCmp1 */ { rfp, 0, 0, 0, 0, Next_Form, Op_0 }, 546 /* Op_FCmp1 */ { rfp, 0, 0, 0, 0, Next_Form, Op_0 },
542 /* Op_FCmpP */ { mfp, 0, 0, FP_Types, 0, Next_Form, Op_FCmpP1 }, // pops 547 /* Op_FCmpP */ { mfp, 0, 0, FP_Types, 0, Next_Form, Op_FCmpP1 }, // pops
543 /* Op_FCmpP1 */ { rfp, 0, 0, 0, 0, Next_Form, Op_F0_P }, // pops 548 /* Op_FCmpP1 */ { rfp, 0, 0, 0, 0, Next_Form, Op_F0_P }, // pops
1482 unsigned operand_i = 0; 1487 unsigned operand_i = 0;
1483 1488
1484 opInfo = & asmOpInfo[op]; 1489 opInfo = & asmOpInfo[op];
1485 memset ( operands, 0, sizeof ( operands ) ); 1490 memset ( operands, 0, sizeof ( operands ) );
1486 1491
1492 if ( token->value == TOKeof && ( op == Op_FMath0) )
1493 {
1494 for ( operand_i = 0; operand_i < 1; operand_i++)
1495 {
1496 operand = & operands[operand_i];
1497 operand->reg = operand->baseReg = operand->indexReg =
1498 operand->segmentPrefix = Reg_Invalid;
1499
1500 operand->cls = Opr_Reg;
1501 if ( operand_i == 0)
1502 {
1503 operand->reg = Reg_ST;
1504 }
1505 else
1506 {
1507 operand->reg = Reg_ST1;
1508 }
1509 operand->hasNumber = 0;
1510 operand->constDisplacement = 0;
1511 parseOperand();
1512
1513 if ( matchOperands ( operand_i ) )
1514 {
1515 AsmCode * asmcode = new AsmCode ( N_Regs );
1516
1517 if ( formatInstruction ( operand_i, asmcode ) )
1518 stmt->asmcode = ( code * ) asmcode;
1519 }
1520 }
1521 return;
1522 }
1523
1487 while ( token->value != TOKeof ) 1524 while ( token->value != TOKeof )
1488 { 1525 {
1489 if ( operand_i < Max_Operands ) 1526 if ( operand_i < Max_Operands )
1490 { 1527 {
1491 operand = & operands[operand_i]; 1528 operand = & operands[operand_i];
1547 1584
1548 for ( unsigned i = 0; i < nOperands; i++ ) 1585 for ( unsigned i = 0; i < nOperands; i++ )
1549 classifyOperand ( & operands[i] ); 1586 classifyOperand ( & operands[i] );
1550 1587
1551 while ( 1 ) 1588 while ( 1 )
1552 { 1589 {
1553 if ( nOperands == opInfo->nOperands() ) 1590 if ( nOperands == opInfo->nOperands() )
1554 { 1591 {
1555 wrong_number = false; 1592 wrong_number = false;
1556 /* Cases in which number of operands is not 1593 /* Cases in which number of operands is not
1557 enough for a match: Op_FCmp/Op_FCmp1, 1594 enough for a match: Op_FCmp/Op_FCmp1,
1708 return Opr_Invalid; 1745 return Opr_Invalid;
1709 } 1746 }
1710 1747
1711 return Opr_Mem; 1748 return Opr_Mem;
1712 } 1749 }
1713 1750
1714 if ( operand->reg != Reg_Invalid && ! operand->hasNumber ) 1751 if ( operand->reg != Reg_Invalid && ! operand->hasNumber )
1715 return Opr_Reg; 1752 return Opr_Reg;
1716 1753
1717 // should check immediate given (operand->hasNumber); 1754 // should check immediate given (operand->hasNumber);
1718 // 1755 //
1819 // %% todo: special case for something.. 1856 // %% todo: special case for something..
1820 if ( opInfo->linkType == Out_Mnemonic ) 1857 if ( opInfo->linkType == Out_Mnemonic )
1821 mnemonic = alternateMnemonics[opInfo->link]; 1858 mnemonic = alternateMnemonics[opInfo->link];
1822 else 1859 else
1823 mnemonic = opIdent->string; 1860 mnemonic = opIdent->string;
1824 1861
1825 if ( opInfo->needsType ) 1862 if ( opInfo->needsType )
1826 { 1863 {
1827 PtrType exact_type = Default_Ptr; 1864 PtrType exact_type = Default_Ptr;
1828 PtrType min_type = Default_Ptr; 1865 PtrType min_type = Default_Ptr;
1829 PtrType hint_type = Default_Ptr; 1866 PtrType hint_type = Default_Ptr;
1895 // gas won't accept the two-operand form 1932 // gas won't accept the two-operand form
1896 else if ( operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST ) 1933 else if ( operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST )
1897 { 1934 {
1898 nOperands = 1; 1935 nOperands = 1;
1899 } 1936 }
1900 else if ( operands[0].cls == Opr_Reg && (operands[0].reg == Reg_ST1 || operands[0].reg == Reg_ST || operands[0].reg == Reg_ST0 )) 1937 else if ( operands[0].cls == Opr_Reg && (operands[0].reg == Reg_ST1 || operands[0].reg == Reg_ST ))
1901 { 1938 {
1902 //fix previous update to to allow single operand form of fstp 1939 //fix previous update to allow single operand form of fstp
1903 } 1940 }
1904 else 1941 else
1905 { 1942 {
1906 stmt->error ( "invalid operands" ); 1943 stmt->error ( "invalid operands" );
1907 return false; 1944 return false;
1908 } 1945 }
1946 }
1947 else if ( op == Op_FMath0 || op == Op_FdST0ST1 )
1948 {
1949 operands[0].cls = Opr_Reg;
1950 operands[0].reg = Reg_ST;
1951 operands[1].cls = Opr_Reg;
1952 operands[1].reg = Reg_ST1;
1953 nOperands = 2;
1909 } 1954 }
1910 1955
1911 switch ( op ) 1956 switch ( op )
1912 { 1957 {
1913 case Op_SizedStack: 1958 case Op_SizedStack:
2007 asm statement leaves an arg pushed on the stack. 2052 asm statement leaves an arg pushed on the stack.
2008 Maybe if the statment had and input or output 2053 Maybe if the statment had and input or output
2009 operand it would work... In any case, clobbering 2054 operand it would work... In any case, clobbering
2010 all FP prevents incorrect code generation. */ 2055 all FP prevents incorrect code generation. */
2011 asmcode->regs[Reg_ST] = true; 2056 asmcode->regs[Reg_ST] = true;
2012 asmcode->regs[Reg_ST0] = true;
2013 asmcode->regs[Reg_ST1] = true; 2057 asmcode->regs[Reg_ST1] = true;
2014 asmcode->regs[Reg_ST2] = true; 2058 asmcode->regs[Reg_ST2] = true;
2015 asmcode->regs[Reg_ST3] = true; 2059 asmcode->regs[Reg_ST3] = true;
2016 asmcode->regs[Reg_ST4] = true; 2060 asmcode->regs[Reg_ST4] = true;
2017 asmcode->regs[Reg_ST5] = true; 2061 asmcode->regs[Reg_ST5] = true;
2936 case TOKint64: 2980 case TOKint64:
2937 //This is for the 'short' in "jle short Label;" 2981 //This is for the 'short' in "jle short Label;"
2938 return Handled; 2982 return Handled;
2939 break; 2983 break;
2940 default: 2984 default:
2985 if ( op == Op_FMath0 || op == Op_FdST0ST1 || op == Op_FMath )
2986 return Handled;
2941 invalidExpression(); 2987 invalidExpression();
2942 return Handled; 2988 return Handled;
2943 } 2989 }
2944 return e; 2990 return e;
2945 } 2991 }