Fix certain cases of floating point instruction mistranslation.

This commit is contained in:
Christian Kamm
2009-05-07 21:01:44 +02:00
parent 108309a579
commit 37edd5add6
3 changed files with 43 additions and 14 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}
}