From 37edd5add6dc06325739c690629c603f1f5af431 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Thu, 7 May 2009 21:01:44 +0200 Subject: [PATCH] Fix certain cases of floating point instruction mistranslation. --- gen/asm-x86-32.h | 13 +++++----- gen/asm-x86-64.h | 13 +++++----- tests/mini/compile_asm_fpinstr_compare.d | 31 ++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 tests/mini/compile_asm_fpinstr_compare.d diff --git a/gen/asm-x86-32.h b/gen/asm-x86-32.h index f82ca750..d09d8ae9 100644 --- a/gen/asm-x86-32.h +++ b/gen/asm-x86-32.h @@ -1880,15 +1880,11 @@ namespace AsmParserx8632 } break; - case Op_FMath0: - // the no-operand versions of floating point ops always pop - insnTemplate << mnemonic << "p"; - break; - default: // special case fdiv, fsub: see dmd 840, ldc 256 - if (strncmp(mnemonic, "fsub", 4) == 0 || - strncmp(mnemonic, "fdiv", 4) == 0) + if ((strncmp(mnemonic, "fsub", 4) == 0 || + strncmp(mnemonic, "fdiv", 4) == 0) && + operands[0].reg != Reg_ST) { // replace: // f{sub,div}r{p,} <-> f{sub,div}{p,} @@ -1907,6 +1903,9 @@ namespace AsmParserx8632 { insnTemplate << mnemonic; } + // the no-operand versions of floating point ops always pop + if (op == Op_FMath0) + insnTemplate << "p"; if ( type_char ) insnTemplate << type_char; break; diff --git a/gen/asm-x86-64.h b/gen/asm-x86-64.h index a895f261..9a79c8f5 100644 --- a/gen/asm-x86-64.h +++ b/gen/asm-x86-64.h @@ -2001,16 +2001,12 @@ namespace AsmParserx8664 insnTemplate.write(mnemonic, mlen-1) << tc_1 << type_char; } break; - - case Op_FMath0: - // the no-operand versions of floating point ops always pop - insnTemplate << mnemonic << "p"; - break; default: // special case fdiv, fsub: see dmd 840, ldc 256 - if (strncmp(mnemonic, "fsub", 4) == 0 || - strncmp(mnemonic, "fdiv", 4) == 0) + if ((strncmp(mnemonic, "fsub", 4) == 0 || + strncmp(mnemonic, "fdiv", 4) == 0) && + operands[0].reg != Reg_ST) { // replace: // f{sub,div}r{p,} <-> f{sub,div}{p,} @@ -2029,6 +2025,9 @@ namespace AsmParserx8664 { insnTemplate << mnemonic; } + // the no-operand versions of floating point ops always pop + if (op == Op_FMath0) + insnTemplate << "p"; if ( type_char ) insnTemplate << type_char; break; diff --git a/tests/mini/compile_asm_fpinstr_compare.d b/tests/mini/compile_asm_fpinstr_compare.d new file mode 100644 index 00000000..d354572e --- /dev/null +++ b/tests/mini/compile_asm_fpinstr_compare.d @@ -0,0 +1,31 @@ +void main() { +asm { + fmul; + fmul ST, ST(1); + fmul ST(1), ST; + fmulp; + fmulp ST(1), ST; + + fdiv; + fdiv ST, ST(1); + fdiv ST(1), ST; + fdivp; + fdivp ST(1), ST; + fdivr; + fdivr ST, ST(1); + fdivr ST(1), ST; + fdivrp; + fdivrp ST(1), ST; + + fsub; + fsub ST, ST(1); + fsub ST(1), ST; + fsubp; + fsubp ST(1), ST; + fsubr; + fsubr ST, ST(1); + fsubr ST(1), ST; + fsubrp; + fsubrp ST(1), ST; +} +} \ No newline at end of file