rs6000: Improve isel
authorSegher Boessenkool <segher@kernel.crashing.org>
Wed, 11 Oct 2017 22:40:52 +0000 (00:40 +0200)
committerSegher Boessenkool <segher@gcc.gnu.org>
Wed, 11 Oct 2017 22:40:52 +0000 (00:40 +0200)
This removes output_isel.  Instead, the define_insn's now output the
isel instructions directly.

It adds a reg_or_zero operand predicate, too, because the reg_or_cint
predicate is too lax here.  Also use it in the "reversed" variants of
the instructions.

* config/rs6000/predicates.md (zero_constant, all_ones_constant):
Move up in file.
(reg_or_cint_operand): Fix comment.
(reg_or_zero_operand): New predicate.
* config/rs6000/rs6000-protos.h (output_isel): Delete.
* config/rs6000/rs6000.c (output_isel): Delete.
* config/rs6000/rs6000.md (isel_signed_<mode>): Use reg_or_zero_operand
instead of reg_or_cint_operand.  Output instruction directly (not via
output_isel).
(isel_unsigned_<mode>): Ditto.
(*isel_reversed_signed_<mode>): Use reg_or_zero_operand instead of
gpc_reg_operand.  Add an instruction alternative for this.  Output
instruction directly.
(*isel_reversed_unsigned_<mode>): Ditto.

From-SVN: r253665

gcc/ChangeLog
gcc/config/rs6000/predicates.md
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md

index 4e0d71e9435878af16b35c803018966a2d55e9c7..bcc39c7b31d566af2624ff98329bbb553404502e 100644 (file)
@@ -1,3 +1,20 @@
+2017-10-11  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       * config/rs6000/predicates.md (zero_constant, all_ones_constant):
+       Move up in file.
+       (reg_or_cint_operand): Fix comment.
+       (reg_or_zero_operand): New predicate.
+       * config/rs6000/rs6000-protos.h (output_isel): Delete.
+       * config/rs6000/rs6000.c (output_isel): Delete.
+       * config/rs6000/rs6000.md (isel_signed_<mode>): Use reg_or_zero_operand
+       instead of reg_or_cint_operand.  Output instruction directly (not via
+       output_isel).
+       (isel_unsigned_<mode>): Ditto.
+       (*isel_reversed_signed_<mode>): Use reg_or_zero_operand instead of
+       gpc_reg_operand.  Add an instruction alternative for this.  Output
+       instruction directly.
+       (*isel_reversed_unsigned_<mode>): Ditto.
+
 2017-10-11  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.c (ix86_canonicalize_comparison): New function.
index 237b4323b4ced9b13805c4e8b8d466cfca46eb70..569158f4c355fb81a80d178fbeaa6f3dea47e9dc 100644 (file)
   return CA_REGNO_P (REGNO (op));
 })
 
+;; Return 1 if operand is constant zero (scalars and vectors).
+(define_predicate "zero_constant"
+  (and (match_code "const_int,const_double,const_wide_int,const_vector")
+       (match_test "op == CONST0_RTX (mode)")))
+
+;; Return 1 if operand is constant -1 (scalars and vectors).
+(define_predicate "all_ones_constant"
+  (and (match_code "const_int,const_double,const_wide_int,const_vector")
+       (match_test "op == CONSTM1_RTX (mode) && !FLOAT_MODE_P (mode)")))
+
 ;; Return 1 if op is a signed 5-bit constant integer.
 (define_predicate "s5bit_cint_operand"
   (and (match_code "const_int")
     (match_operand 0 "u_short_cint_operand")
     (match_operand 0 "gpc_reg_operand")))
 
-;; Return 1 if op is any constant integer 
-;; or non-special register.
+;; Return 1 if op is any constant integer or a non-special register.
 (define_predicate "reg_or_cint_operand"
   (ior (match_code "const_int")
        (match_operand 0 "gpc_reg_operand")))
 
+;; Return 1 if op is constant zero or a non-special register.
+(define_predicate "reg_or_zero_operand"
+  (ior (match_operand 0 "zero_constant")
+       (match_operand 0 "gpc_reg_operand")))
+
 ;; Return 1 if op is a constant integer valid for addition with addis, addi.
 (define_predicate "add_cint_operand"
   (and (match_code "const_int")
            (and (match_test "easy_altivec_constant (op, mode)")
                 (match_test "vspltis_shifted (op) != 0")))))
 
-;; Return 1 if operand is constant zero (scalars and vectors).
-(define_predicate "zero_constant"
-  (and (match_code "const_int,const_double,const_wide_int,const_vector")
-       (match_test "op == CONST0_RTX (mode)")))
-
-;; Return 1 if operand is constant -1 (scalars and vectors).
-(define_predicate "all_ones_constant"
-  (and (match_code "const_int,const_double,const_wide_int,const_vector")
-       (match_test "op == CONSTM1_RTX (mode) && !FLOAT_MODE_P (mode)")))
-
 ;; Return 1 if operand is a vector int register or is either a vector constant
 ;; of all 0 bits of a vector constant of all 1 bits.
 (define_predicate "vector_int_reg_or_same_bit"
index c6be5b1ef59f89a3807901018fbbaf9ec8d53d72..db0e692739c9b70f84210e8e1835ad28dc98c636 100644 (file)
@@ -209,7 +209,6 @@ extern void rs6000_emit_epilogue (int);
 extern void rs6000_expand_split_stack_prologue (void);
 extern void rs6000_split_stack_space_check (rtx, rtx);
 extern void rs6000_emit_eh_reg_restore (rtx, rtx);
-extern const char * output_isel (rtx *);
 extern void rs6000_call_aix (rtx, rtx, rtx, rtx);
 extern void rs6000_sibcall_aix (rtx, rtx, rtx, rtx);
 extern void rs6000_aix_asm_output_dwarf_table_ref (char *);
index 8b014e75fae553489bd9d2ce0edf0985e24374a4..e8684821c9858429bf6366de21772fa798665d20 100644 (file)
@@ -23255,24 +23255,6 @@ rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond)
   return 1;
 }
 
-const char *
-output_isel (rtx *operands)
-{
-  enum rtx_code code;
-
-  code = GET_CODE (operands[1]);
-
-  if (code == GE || code == GEU || code == LE || code == LEU || code == NE)
-    {
-      gcc_assert (GET_CODE (operands[2]) == REG
-                 && GET_CODE (operands[3]) == REG);
-      PUT_CODE (operands[1], reverse_condition (code));
-      return "isel %0,%3,%2,%j1";
-    }
-
-  return "isel %0,%2,%3,%j1";
-}
-
 void
 rs6000_emit_minmax (rtx dest, enum rtx_code code, rtx op0, rtx op1)
 {
index 6efc1134fc48c73d58a5eea372058e06e1ec5498..0a5a652fc3f673d9764c4eaa5987138e08eb507a 100644 (file)
         (match_operator 1 "scc_comparison_operator"
                         [(match_operand:CC 4 "cc_reg_operand" "y,y")
                          (const_int 0)])
-        (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
+        (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
         (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
   "TARGET_ISEL<sel>"
-  "*
-{ return output_isel (operands); }"
-  [(set_attr "type" "isel")
-   (set_attr "length" "4")])
+  "isel %0,%2,%3,%j1"
+  [(set_attr "type" "isel")])
 
 (define_insn "isel_unsigned_<mode>"
   [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
         (match_operator 1 "scc_comparison_operator"
                         [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
                          (const_int 0)])
-        (match_operand:GPR 2 "reg_or_cint_operand" "O,b")
+        (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
         (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
   "TARGET_ISEL<sel>"
-  "*
-{ return output_isel (operands); }"
-  [(set_attr "type" "isel")
-   (set_attr "length" "4")])
+  "isel %0,%2,%3,%j1"
+  [(set_attr "type" "isel")])
 
 ;; These patterns can be useful for combine; they let combine know that
 ;; isel can handle reversed comparisons so long as the operands are
 ;; registers.
 
 (define_insn "*isel_reversed_signed_<mode>"
-  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
        (if_then_else:GPR
         (match_operator 1 "scc_rev_comparison_operator"
-                        [(match_operand:CC 4 "cc_reg_operand" "y")
+                        [(match_operand:CC 4 "cc_reg_operand" "y,y")
                          (const_int 0)])
-        (match_operand:GPR 2 "gpc_reg_operand" "b")
-        (match_operand:GPR 3 "gpc_reg_operand" "b")))]
+        (match_operand:GPR 2 "gpc_reg_operand" "r,r")
+        (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
   "TARGET_ISEL<sel>"
-  "*
-{ return output_isel (operands); }"
-  [(set_attr "type" "isel")
-   (set_attr "length" "4")])
+{
+  PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
+  return "isel %0,%3,%2,%j1";
+}
+  [(set_attr "type" "isel")])
 
 (define_insn "*isel_reversed_unsigned_<mode>"
-  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
        (if_then_else:GPR
         (match_operator 1 "scc_rev_comparison_operator"
-                        [(match_operand:CCUNS 4 "cc_reg_operand" "y")
+                        [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
                          (const_int 0)])
-        (match_operand:GPR 2 "gpc_reg_operand" "b")
-        (match_operand:GPR 3 "gpc_reg_operand" "b")))]
+        (match_operand:GPR 2 "gpc_reg_operand" "r,r")
+        (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
   "TARGET_ISEL<sel>"
-  "*
-{ return output_isel (operands); }"
-  [(set_attr "type" "isel")
-   (set_attr "length" "4")])
+{
+  PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
+  return "isel %0,%3,%2,%j1";
+}
+  [(set_attr "type" "isel")])
 
 ;; Floating point conditional move
 (define_expand "mov<mode>cc"