]> gcc.gnu.org Git - gcc.git/commitdiff
alpha.c (alpha_emit_conditional_move): If TARGET_FIX, handle cmove with mismatched...
authorRichard Henderson <rth@cygnus.com>
Sun, 19 Dec 1999 04:35:31 +0000 (20:35 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Sun, 19 Dec 1999 04:35:31 +0000 (20:35 -0800)
        * alpha.c (alpha_emit_conditional_move): If TARGET_FIX, handle
        cmove with mismatched test and data modes.

From-SVN: r31021

gcc/ChangeLog
gcc/config/alpha/alpha.c

index ddd592244667c6d4ffd1bb203f7efe563ba2d9f4..fc6058ad16399a0da4a77d0f8a45e124bb5ac15f 100644 (file)
@@ -1,3 +1,8 @@
+Sat Dec 18 20:34:00 1999  Richard Henderson  <rth@cygnus.com>
+
+       * alpha.c (alpha_emit_conditional_move): If TARGET_FIX, handle
+       cmove with mismatched test and data modes.
+
 Sat Dec 18 20:30:15 1999  Richard Henderson  <rth@cygnus.com>
 
        * c-typeck.c (c_expand_start_case): Don't warn for long switch
index b875c67d3d1e3f575836cd69872908ab45b96307..9dc2f733fbc2a454b66435ef5a3414be172021c1 100644 (file)
@@ -1580,18 +1580,63 @@ alpha_emit_conditional_move (cmp, mode)
     = (GET_MODE (op0) == VOIDmode ? DImode : GET_MODE (op0));
   enum machine_mode cmp_op_mode = fp_p ? DFmode : DImode;
   enum machine_mode cmov_mode = VOIDmode;
+  int local_fast_math = flag_fast_math;
   rtx tem;
 
   /* Zero the operands.  */
   memset (&alpha_compare, 0, sizeof (alpha_compare));
 
   if (fp_p != FLOAT_MODE_P (mode))
-    return 0;
+    {
+      enum rtx_code cmp_code;
+
+      if (! TARGET_FIX)
+       return 0;
+
+      /* If we have fp<->int register move instructions, do a cmov by
+        performing the comparison in fp registers, and move the
+        zero/non-zero value to integer registers, where we can then
+        use a normal cmov, or vice-versa.  */
+
+      switch (code)
+       {
+       case EQ: case LE: case LT: case LEU: case LTU:
+         /* We have these compares.  */
+         cmp_code = code, code = NE;
+         break;
+
+       case NE:
+         /* This must be reversed.  */
+         cmp_code = EQ, code = EQ;
+         break;
+
+       case GE: case GT: case GEU: case GTU:
+         /* These must be swapped.  */
+         cmp_code = swap_condition (code);
+         code = NE;
+         tem = op0, op0 = op1, op1 = tem;
+         break;
+
+       default:
+         abort ();
+       }
+
+      tem = gen_reg_rtx (cmp_op_mode);
+      emit_insn (gen_rtx_SET (VOIDmode, tem,
+                             gen_rtx_fmt_ee (cmp_code, cmp_op_mode,
+                                             op0, op1)));
+
+      cmp_mode = cmp_op_mode = fp_p ? DImode : DFmode;
+      op0 = gen_lowpart (cmp_op_mode, tem);
+      op1 = CONST0_RTX (cmp_op_mode);
+      fp_p = !fp_p;
+      local_fast_math = 1;
+    }
 
   /* We may be able to use a conditional move directly.
      This avoids emitting spurious compares. */
   if (signed_comparison_operator (cmp, cmp_op_mode)
-      && (!fp_p || flag_fast_math)
+      && (!fp_p || local_fast_math)
       && (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
     return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
 
@@ -1627,7 +1672,7 @@ alpha_emit_conditional_move (cmp, mode)
   /* ??? We mark the branch mode to be CCmode to prevent the compare
      and cmov from being combined, since the compare insn follows IEEE
      rules that the cmov does not.  */
-  if (fp_p && !flag_fast_math)
+  if (fp_p && !local_fast_math)
     cmov_mode = CCmode;
 
   tem = gen_reg_rtx (cmp_op_mode);
This page took 0.08913 seconds and 5 git commands to generate.