mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-20 15:20:59 +08:00
rs6000: Improve isel
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
This commit is contained in:
parent
3ff1b2b0a9
commit
e7d77cf92d
@ -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.
|
||||
|
@ -199,6 +199,16 @@
|
||||
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")
|
||||
@ -543,12 +553,16 @@
|
||||
(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")
|
||||
@ -744,16 +758,6 @@
|
||||
(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"
|
||||
|
@ -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 *);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -4938,13 +4938,11 @@
|
||||
(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")
|
||||
@ -4952,45 +4950,45 @@
|
||||
(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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user