changeset 1310:85b80c4fe48a

Fix certain cases of floating point instruction mistranslation.
author Christian Kamm <kamm incasoftware de>
date Thu, 07 May 2009 21:01:44 +0200
parents b995c146366e
children 09c79cae1b86
files gen/asm-x86-32.h gen/asm-x86-64.h tests/mini/compile_asm_fpinstr_compare.d
diffstat 3 files changed, 43 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/gen/asm-x86-32.h	Wed May 06 19:56:33 2009 +0200
+++ b/gen/asm-x86-32.h	Thu May 07 21:01:44 2009 +0200
@@ -1880,15 +1880,11 @@
                 }
                 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 @@
                 {
                     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;
--- a/gen/asm-x86-64.h	Wed May 06 19:56:33 2009 +0200
+++ b/gen/asm-x86-64.h	Thu May 07 21:01:44 2009 +0200
@@ -2001,16 +2001,12 @@
                     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 @@
                 {
                     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;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/mini/compile_asm_fpinstr_compare.d	Thu May 07 21:01:44 2009 +0200
@@ -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