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