# HG changeset patch # User Christian Kamm # Date 1241852321 -7200 # Node ID 1ad5a58b5c9d8343c62062f949821a491d00df85 # Parent acc5d68a21d309164b52c99433f34cb3a669062d Restrict second arg of certain floating-point stores to ST. Fix type postfix for the two argument form of fistp and fisttp. diff -r acc5d68a21d3 -r 1ad5a58b5c9d gen/asm-x86-32.h --- a/gen/asm-x86-32.h Thu May 07 21:49:58 2009 +0200 +++ b/gen/asm-x86-32.h Sat May 09 08:58:41 2009 +0200 @@ -454,7 +454,7 @@ /* 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, Next_Form, Op_FidR_P }, // push and pop, fild so also 64 bit - /* Op_FidR_P */ { D|mem,rfp, 0, 0, Clb_ST }, // push and pop, fild so also 64 bit + /* Op_FidR_P */ { D|mem,rfp, 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, " @@ -1723,6 +1723,16 @@ else mnemonic = opIdent->string; + // handle two-operand form where second arg is ignored. + // must be done before type_char detection + if ( op == Op_FidR_P || op == Op_fxch || op == Op_FfdRR_P ) + { + if (operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST ) + nOperands = 1; + else + stmt->error("instruction allows only ST as second argument"); + } + if ( opInfo->needsType ) { PtrType exact_type = Default_Ptr; @@ -1787,31 +1797,6 @@ if ( operands[0].dataSize == Far_Ptr ) // %% type=Far_Ptr not set by Seg:Ofss OTOH, we don't support that.. insnTemplate << 'l'; } - else if ( op == Op_fxch || op == Op_FfdRR_P || op == Op_FidR_P ) - { - if ( operands[0].cls == Opr_Mem && op == Op_FidR_P ) - { - nOperands = 1; - } - // gas won't accept the two-operand form - else 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 || operands[0].cls == Opr_Mem ) - { - nOperands = 1; - } - else if ( operands[0].cls == Opr_Reg && (operands[0].reg == Reg_ST || operands[0].reg == Reg_ST1 )) - { - //fix previous update to allow single operand form of fstp - } - else - { - stmt->error ( "invalid operands" ); - return false; - } - } else if ( op == Op_FMath0 || op == Op_FdST0ST1 ) { operands[0].cls = Opr_Reg; diff -r acc5d68a21d3 -r 1ad5a58b5c9d gen/asm-x86-64.h --- a/gen/asm-x86-64.h Thu May 07 21:49:58 2009 +0200 +++ b/gen/asm-x86-64.h Sat May 09 08:58:41 2009 +0200 @@ -1849,6 +1849,16 @@ else mnemonic = opIdent->string; + // handle two-operand form where second arg is ignored. + // must be done before type_char detection + if ( op == Op_FidR_P || op == Op_fxch || op == Op_FfdRR_P ) + { + if (operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST ) + nOperands = 1; + else + stmt->error("instruction allows only ST as second argument"); + } + if ( opInfo->needsType ) { PtrType exact_type = Default_Ptr; @@ -1913,27 +1923,6 @@ if ( operands[0].dataSize == Far_Ptr ) // %% type=Far_Ptr not set by Seg:Ofss OTOH, we don't support that.. insnTemplate << 'l'; } - else if ( op == Op_fxch || op == Op_FfdRR_P || op == Op_FidR_P ) - { - if ( operands[0].cls == Opr_Mem && op == Op_FidR_P ) - { - nOperands = 1; - } - // gas won't accept the two-operand form - else if ( operands[1].cls == Opr_Reg && operands[1].reg == Reg_ST ) - { - nOperands = 1; - } - else if ( operands[0].cls == Opr_Reg && (operands[0].reg == Reg_ST1 || operands[0].reg == Reg_ST )) - { - //fix previous update to allow single operand form of fstp - } - else - { - stmt->error ( "invalid operands" ); - return false; - } - } else if ( op == Op_FMath0 || op == Op_FdST0ST1 ) { operands[0].cls = Opr_Reg;