(movsicc): New named pattern.
authorDoug Evans <dje@gnu.org>
Wed, 25 Jan 1995 04:11:29 +0000 (04:11 +0000)
committerDoug Evans <dje@gnu.org>
Wed, 25 Jan 1995 04:11:29 +0000 (04:11 +0000)
(movdicc, movsfcc, movdfcc): Likewise.
(SImode conditional move): New matcher.

From-SVN: r8796

gcc/config/alpha/alpha.md

index 459ca66160707b09f6905113df9183847c23784d..510ad3fdd5eecb8cd1071ae3fd4247049f9133b3 100644 (file)
   "cmple $31,%1,%0"
   [(set_attr "type" "icmp")])
 
+;; This pattern exists so conditional moves of SImode values are handled.
+;; Comparisons are still done in DImode though.
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
+       (if_then_else:DI
+        (match_operator 2 "signed_comparison_operator"
+                        [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J")
+                         (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")])
+        (match_operand:SI 1 "reg_or_8bit_operand" "rI,0,rI,0")
+        (match_operand:SI 5 "reg_or_8bit_operand" "0,rI,0,rI")))]
+  "operands[3] == const0_rtx || operands[4] == const0_rtx"
+  "@
+   cmov%C2 %r3,%1,%0
+   cmov%D2 %r3,%5,%0
+   cmov%c2 %r4,%1,%0
+   cmov%d2 %r4,%5,%0")
+
 (define_insn ""
   [(set (match_operand:DI 0 "register_operand" "=r,r,r,r")
        (if_then_else:DI
                         alpha_compare_op0);
 }")
 \f
+;; These are the main define_expand's used to make conditional moves.
+
+(define_expand "movsicc"
+  [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
+   (set (match_operand:SI 0 "register_operand" "")
+       (if_then_else:DI (match_dup 5)
+                        (match_operand:SI 2 "reg_or_8bit_operand" "")
+                        (match_operand:SI 3 "reg_or_8bit_operand" "")))]
+  ""
+  "
+{
+  rtx op0,op1;
+  enum rtx_code code = GET_CODE (operands[1]);
+
+  if (alpha_compare_fp_p)
+    FAIL;
+  switch (code)
+    {
+    case EQ: case NE: case LE: case LT:
+      op0 = alpha_compare_op0;
+      op1 = alpha_compare_op1;
+      break;
+    case GE:
+      code = LE;
+      op0 = force_reg (DImode, alpha_compare_op1);
+      op1 = alpha_compare_op0;
+      break;
+    case GT:
+      code = LT;
+      op0 = force_reg (DImode, alpha_compare_op1);
+      op1 = alpha_compare_op0;
+      break;
+    default:
+      FAIL;
+    }
+  operands[1] = gen_rtx (code, DImode, op0, op1);
+  operands[4] = gen_reg_rtx (DImode);
+  operands[5] = gen_rtx (NE, VOIDmode, operands[4], CONST0_RTX (DImode));
+}")
+
+(define_expand "movdicc"
+  [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
+   (set (match_operand:DI 0 "register_operand" "")
+       (if_then_else:DI (match_dup 5)
+                        (match_operand:DI 2 "reg_or_8bit_operand" "")
+                        (match_operand:DI 3 "reg_or_8bit_operand" "")))]
+  ""
+  "
+{
+  rtx op0,op1;
+  enum rtx_code code = GET_CODE (operands[1]);
+
+  if (alpha_compare_fp_p)
+    FAIL;
+  switch (code)
+    {
+    case EQ: case NE: case LE: case LT:
+      op0 = alpha_compare_op0;
+      op1 = alpha_compare_op1;
+      break;
+    case GE:
+      code = LE;
+      op0 = force_reg (DImode, alpha_compare_op1);
+      op1 = alpha_compare_op0;
+      break;
+    case GT:
+      code = LT;
+      op0 = force_reg (DImode, alpha_compare_op1);
+      op1 = alpha_compare_op0;
+      break;
+    default:
+      FAIL;
+    }
+  operands[1] = gen_rtx (code, DImode, op0, op1);
+  operands[4] = gen_reg_rtx (DImode);
+  operands[5] = gen_rtx (NE, VOIDmode, operands[4], CONST0_RTX (DImode));
+}")
+
+(define_expand "movsfcc"
+  [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
+   (set (match_operand:SF 0 "register_operand" "")
+       (if_then_else:SF (match_dup 5)
+                        (match_operand:SF 2 "reg_or_fp0_operand" "")
+                        (match_operand:SF 3 "reg_or_fp0_operand" "")))]
+  ""
+  "
+{
+  rtx op0,op1;
+  enum rtx_code code = GET_CODE (operands[1]), code2 = NE;
+
+  if (!alpha_compare_fp_p)
+    FAIL;
+  switch (code)
+    {
+    case EQ: case LE: case LT:
+      op0 = alpha_compare_op0;
+      op1 = alpha_compare_op1;
+      break;
+    case NE:
+      /* There isn't a cmptne insn.  */
+      code = code2 = EQ;
+      op0 = alpha_compare_op0;
+      op1 = alpha_compare_op1;
+      break;
+    case GE:
+      code = LE;
+      op0 = force_reg (DFmode, alpha_compare_op1);
+      op1 = alpha_compare_op0;
+      break;
+    case GT:
+      code = LT;
+      op0 = force_reg (DFmode, alpha_compare_op1);
+      op1 = alpha_compare_op0;
+      break;
+    default:
+      FAIL;
+    }
+  operands[1] = gen_rtx (code, DFmode, op0, op1);
+  operands[4] = gen_reg_rtx (DFmode);
+  operands[5] = gen_rtx (code2, VOIDmode, operands[4], CONST0_RTX (DFmode));
+}")
+
+(define_expand "movdfcc"
+  [(set (match_dup 4) (match_operand 1 "comparison_operator" ""))
+   (set (match_operand:DF 0 "register_operand" "")
+       (if_then_else:DF (match_dup 5)
+                        (match_operand:DF 2 "reg_or_fp0_operand" "")
+                        (match_operand:DF 3 "reg_or_fp0_operand" "")))]
+  ""
+  "
+{
+  rtx op0,op1;
+  enum rtx_code code = GET_CODE (operands[1]), code2 = NE;
+
+  if (!alpha_compare_fp_p)
+    FAIL;
+  switch (code)
+    {
+    case EQ: case LE: case LT:
+      op0 = alpha_compare_op0;
+      op1 = alpha_compare_op1;
+      break;
+    case NE:
+      /* There isn't a cmptne insn.  */
+      code = code2 = EQ;
+      op0 = alpha_compare_op0;
+      op1 = alpha_compare_op1;
+      break;
+    case GE:
+      code = LE;
+      op0 = force_reg (DFmode, alpha_compare_op1);
+      op1 = alpha_compare_op0;
+      break;
+    case GT:
+      code = LT;
+      op0 = force_reg (DFmode, alpha_compare_op1);
+      op1 = alpha_compare_op0;
+      break;
+    default:
+      FAIL;
+    }
+  operands[1] = gen_rtx (code, DFmode, op0, op1);
+  operands[4] = gen_reg_rtx (DFmode);
+  operands[5] = gen_rtx (code2, VOIDmode, operands[4], CONST0_RTX (DFmode));
+}")
+\f
 ;; These define_split definitions are used in cases when comparisons have
 ;; not be stated in the correct way and we need to reverse the second
 ;; comparison.  For example, x >= 7 has to be done as x < 6 with the