OSDN Git Service

* sparc/sparc.c (v9_regcmp_p): New function.
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Feb 1995 20:07:24 +0000 (20:07 +0000)
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 8 Feb 1995 20:07:24 +0000 (20:07 +0000)
(v9_regcmp_op): Call it.
* sparc/sparc.md (movsicc): New pattern.
(movdicc, movsfcc, movdfcc, movtfcc): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@8895 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md

index 842276e..f93f794 100644 (file)
@@ -187,6 +187,21 @@ sparc64_fpconv_stack_temp ()
     return fpconv_stack_temp;
 }
 \f
+/* Miscellaneous utilities.  */
+
+/* Nonzero if CODE, a comparison, is suitable for use in v9 conditional move
+   or branch on register contents instructions.  */
+
+int
+v9_regcmp_p (code)
+     enum rtx_code code;
+{
+  return (code == EQ || code == NE || code == GE || code == LT
+         || code == LE || code == GT);
+}
+\f
+/* Operand constraints.  */
+
 /* Return non-zero only if OP is a register of mode MODE,
    or const0_rtx.  */
 int
@@ -524,8 +539,7 @@ v9_regcmp_op (op, mode)
   if (GET_RTX_CLASS (code) != '<')
     return 0;
 
-  return (code == EQ || code == NE || code == GE || code == LT
-         || code == LE || code == GT);
+  return v9_regcmp_p (code);
 }
 
 /* Return 1 if this is a SIGN_EXTEND or ZERO_EXTEND operation.  */
index 223740a..31f034f 100644 (file)
 \f
 ;; Sparc V9 conditional move instructions.
 
+;; We can handle larger constants here for some flavors, but for now we play
+;; it safe and only allow those constants supported by all flavours.
+
+(define_expand "movsicc"
+  [(set (match_operand:SI 0 "register_operand" "")
+       (if_then_else (match_operand 1 "comparison_operator" "")
+                     (match_operand:SI 2 "arith10_operand" "")
+                     (match_operand:SI 3 "arith10_operand" "")))]
+  "TARGET_V9"
+  "
+{
+  enum rtx_code code = GET_CODE (operands[1]);
+
+  if (sparc_compare_op1 == const0_rtx
+      && GET_CODE (sparc_compare_op0) == REG
+      && GET_MODE (sparc_compare_op0) == DImode
+      && v9_regcmp_p (code))
+    {
+      operands[1] = gen_rtx (code, DImode,
+                            sparc_compare_op0, sparc_compare_op1);
+    }
+  else
+    {
+      rtx cc_reg = gen_compare_reg (code,
+                                   sparc_compare_op0, sparc_compare_op1);
+      operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
+    }
+}")
+
+(define_expand "movdicc"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (if_then_else (match_operand 1 "comparison_operator" "")
+                     (match_operand:DI 2 "arith10_operand" "")
+                     (match_operand:DI 3 "arith10_operand" "")))]
+  "TARGET_V9"
+  "
+{
+  enum rtx_code code = GET_CODE (operands[1]);
+
+  if (sparc_compare_op1 == const0_rtx
+      && GET_CODE (sparc_compare_op0) == REG
+      && GET_MODE (sparc_compare_op0) == DImode
+      && v9_regcmp_p (code))
+    {
+      operands[1] = gen_rtx (code, DImode,
+                            sparc_compare_op0, sparc_compare_op1);
+    }
+  else
+    {
+      rtx cc_reg = gen_compare_reg (code,
+                                   sparc_compare_op0, sparc_compare_op1);
+      operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
+    }
+}")
+
+(define_expand "movsfcc"
+  [(set (match_operand:SF 0 "register_operand" "")
+       (if_then_else (match_operand 1 "comparison_operator" "")
+                     (match_operand:SF 2 "register_operand" "")
+                     (match_operand:SF 3 "register_operand" "")))]
+  "TARGET_V9"
+  "
+{
+  enum rtx_code code = GET_CODE (operands[1]);
+
+  if (sparc_compare_op1 == const0_rtx
+      && GET_CODE (sparc_compare_op0) == REG
+      && GET_MODE (sparc_compare_op0) == DImode
+      && v9_regcmp_p (code))
+    {
+      operands[1] = gen_rtx (code, DImode,
+                            sparc_compare_op0, sparc_compare_op1);
+    }
+  else
+    {
+      rtx cc_reg = gen_compare_reg (code,
+                                   sparc_compare_op0, sparc_compare_op1);
+      operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
+    }
+}")
+
+(define_expand "movdfcc"
+  [(set (match_operand:DF 0 "register_operand" "")
+       (if_then_else (match_operand 1 "comparison_operator" "")
+                     (match_operand:DF 2 "register_operand" "")
+                     (match_operand:DF 3 "register_operand" "")))]
+  "TARGET_V9"
+  "
+{
+  enum rtx_code code = GET_CODE (operands[1]);
+
+  if (sparc_compare_op1 == const0_rtx
+      && GET_CODE (sparc_compare_op0) == REG
+      && GET_MODE (sparc_compare_op0) == DImode
+      && v9_regcmp_p (code))
+    {
+      operands[1] = gen_rtx (code, DImode,
+                            sparc_compare_op0, sparc_compare_op1);
+    }
+  else
+    {
+      rtx cc_reg = gen_compare_reg (code,
+                                   sparc_compare_op0, sparc_compare_op1);
+      operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
+    }
+}")
+
+(define_expand "movtfcc"
+  [(set (match_operand:TF 0 "register_operand" "")
+       (if_then_else (match_operand 1 "comparison_operator" "")
+                     (match_operand:TF 2 "register_operand" "")
+                     (match_operand:TF 3 "register_operand" "")))]
+  "TARGET_V9"
+  "
+{
+  enum rtx_code code = GET_CODE (operands[1]);
+
+  if (sparc_compare_op1 == const0_rtx
+      && GET_CODE (sparc_compare_op0) == REG
+      && GET_MODE (sparc_compare_op0) == DImode
+      && v9_regcmp_p (code))
+    {
+      operands[1] = gen_rtx (code, DImode,
+                            sparc_compare_op0, sparc_compare_op1);
+    }
+  else
+    {
+      rtx cc_reg = gen_compare_reg (code,
+                                   sparc_compare_op0, sparc_compare_op1);
+      operands[1] = gen_rtx (code, GET_MODE (cc_reg), cc_reg, const0_rtx);
+    }
+}")
+
 ; ??? There is not actually a 32 bit version of this instruction.
 (define_insn "*movsi_cc_sp64"
   [(set (match_operand:SI 0 "register_operand" "=r")