comparison gen/asm-x86-32.h @ 1320:1ad5a58b5c9d

Restrict second arg of certain floating-point stores to ST. Fix type postfix for the two argument form of fistp and fisttp.
author Christian Kamm <kamm incasoftware de>
date Sat, 09 May 2009 08:58:41 +0200
parents acc5d68a21d3
children 5a9dc345c70a
comparison
equal deleted inserted replaced
1314:acc5d68a21d3 1320:1ad5a58b5c9d
452 /* Op_Fis */ { mem, 0, 0, FPInt_Types }, // only 16bit and 32bit, DMD defaults to 16bit 452 /* Op_Fis */ { mem, 0, 0, FPInt_Types }, // only 16bit and 32bit, DMD defaults to 16bit
453 /* Op_Fis_ST */ { mem, 0, 0, FPInt_Types, Clb_ST }, // " 453 /* Op_Fis_ST */ { mem, 0, 0, FPInt_Types, Clb_ST }, // "
454 /* Op_Fis_P */ { mem, 0, 0, FPInt_Types, Clb_ST }, // push and pop, fild so also 64 bit 454 /* Op_Fis_P */ { mem, 0, 0, FPInt_Types, Clb_ST }, // push and pop, fild so also 64 bit
455 /* Op_Fid */ { D|mem, 0, 0, FPInt_Types }, // only 16bit and 32bit, DMD defaults to 16bit 455 /* Op_Fid */ { D|mem, 0, 0, FPInt_Types }, // only 16bit and 32bit, DMD defaults to 16bit
456 /* Op_Fid_P */ { D|mem, 0, 0, FPInt_Types, Clb_ST, Next_Form, Op_FidR_P }, // push and pop, fild so also 64 bit 456 /* Op_Fid_P */ { D|mem, 0, 0, FPInt_Types, Clb_ST, Next_Form, Op_FidR_P }, // push and pop, fild so also 64 bit
457 /* Op_FidR_P */ { D|mem,rfp, 0, 0, Clb_ST }, // push and pop, fild so also 64 bit 457 /* Op_FidR_P */ { D|mem,rfp, 0, FPInt_Types, Clb_ST }, // push and pop, fild so also 64 bit
458 /* 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 458 /* 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
459 /* Op_FfdR */ { D|rfp, 0, 0 }, 459 /* Op_FfdR */ { D|rfp, 0, 0 },
460 /* Op_Ffd_P */ { D|mfp, 0, 0, FP_Types, Clb_ST, Next_Form, Op_FfdR_P }, // pop, fld so also 80 bit, " 460 /* Op_Ffd_P */ { D|mfp, 0, 0, FP_Types, Clb_ST, Next_Form, Op_FfdR_P }, // pop, fld so also 80 bit, "
461 /* Op_FfdR_P */ { D|rfp, 0, 0, 0, Clb_ST, Next_Form, Op_FfdRR_P }, 461 /* Op_FfdR_P */ { D|rfp, 0, 0, 0, Clb_ST, Next_Form, Op_FfdRR_P },
462 /* Op_FfdRR_P */ { D|rfp, rfp, 0, 0, Clb_ST }, 462 /* Op_FfdRR_P */ { D|rfp, rfp, 0, 0, Clb_ST },
1721 if ( opInfo->linkType == Out_Mnemonic ) 1721 if ( opInfo->linkType == Out_Mnemonic )
1722 mnemonic = alternateMnemonics[opInfo->link]; 1722 mnemonic = alternateMnemonics[opInfo->link];
1723 else 1723 else
1724 mnemonic = opIdent->string; 1724 mnemonic = opIdent->string;
1725 1725
1726 // handle two-operand form where second arg is ignored.
1727 // must be done before type_char detection
1728 if ( op == Op_FidR_P || op == Op_fxch || op == Op_FfdRR_P )
1729 {
1730 if (operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST )
1731 nOperands = 1;
1732 else
1733 stmt->error("instruction allows only ST as second argument");
1734 }
1735
1726 if ( opInfo->needsType ) 1736 if ( opInfo->needsType )
1727 { 1737 {
1728 PtrType exact_type = Default_Ptr; 1738 PtrType exact_type = Default_Ptr;
1729 PtrType min_type = Default_Ptr; 1739 PtrType min_type = Default_Ptr;
1730 PtrType hint_type = Default_Ptr; 1740 PtrType hint_type = Default_Ptr;
1784 } 1794 }
1785 else if ( op == Op_Branch ) 1795 else if ( op == Op_Branch )
1786 { 1796 {
1787 if ( operands[0].dataSize == Far_Ptr ) // %% type=Far_Ptr not set by Seg:Ofss OTOH, we don't support that.. 1797 if ( operands[0].dataSize == Far_Ptr ) // %% type=Far_Ptr not set by Seg:Ofss OTOH, we don't support that..
1788 insnTemplate << 'l'; 1798 insnTemplate << 'l';
1789 }
1790 else if ( op == Op_fxch || op == Op_FfdRR_P || op == Op_FidR_P )
1791 {
1792 if ( operands[0].cls == Opr_Mem && op == Op_FidR_P )
1793 {
1794 nOperands = 1;
1795 }
1796 // gas won't accept the two-operand form
1797 else if ( operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST )
1798 {
1799 nOperands = 1;
1800 }
1801 else if ( operands[1].cls == Opr_Mem && operands[1].reg == Reg_ST || operands[0].cls == Opr_Mem )
1802 {
1803 nOperands = 1;
1804 }
1805 else if ( operands[0].cls == Opr_Reg && (operands[0].reg == Reg_ST || operands[0].reg == Reg_ST1 ))
1806 {
1807 //fix previous update to allow single operand form of fstp
1808 }
1809 else
1810 {
1811 stmt->error ( "invalid operands" );
1812 return false;
1813 }
1814 } 1799 }
1815 else if ( op == Op_FMath0 || op == Op_FdST0ST1 ) 1800 else if ( op == Op_FMath0 || op == Op_FdST0ST1 )
1816 { 1801 {
1817 operands[0].cls = Opr_Reg; 1802 operands[0].cls = Opr_Reg;
1818 operands[0].reg = Reg_ST1; 1803 operands[0].reg = Reg_ST1;