diff options
author | Paolo Bonzini <bonzini@gnu.org> | 2009-05-12 09:43:48 +0000 |
---|---|---|
committer | Paolo Bonzini <bonzini@gcc.gnu.org> | 2009-05-12 09:43:48 +0000 |
commit | f90b7a5a7913cc7239cce42f6ca328b9a741b387 (patch) | |
tree | 06c940a96a184a178bfadd53e04213225655a68d /gcc/config/rs6000/rs6000.md | |
parent | b7a0af68063c79655c561750e9863799bf846cae (diff) | |
download | gcc-f90b7a5a7913cc7239cce42f6ca328b9a741b387.zip gcc-f90b7a5a7913cc7239cce42f6ca328b9a741b387.tar.gz gcc-f90b7a5a7913cc7239cce42f6ca328b9a741b387.tar.bz2 |
Merge cond-optab branch.
From-SVN: r147425
Diffstat (limited to 'gcc/config/rs6000/rs6000.md')
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 307 |
1 files changed, 67 insertions, 240 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index cc37d91..9d4a960 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -11897,262 +11897,90 @@ ;; signed & unsigned, and one type of branch. ;; ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc -;; insns, and branches. We store the operands of compares until we see -;; how it is used. -(define_expand "cmp<mode>" - [(set (cc0) - (compare (match_operand:GPR 0 "gpc_reg_operand" "") - (match_operand:GPR 1 "reg_or_short_operand" "")))] +;; insns, and branches. + +(define_expand "cbranch<mode>4" + [(use (match_operator 0 "rs6000_cbranch_operator" + [(match_operand:GPR 1 "gpc_reg_operand" "") + (match_operand:GPR 2 "reg_or_short_operand" "")])) + (use (match_operand 3 ""))] "" " { - /* Take care of the possibility that operands[1] might be negative but + /* Take care of the possibility that operands[2] might be negative but this might be a logical operation. That insn doesn't exist. */ - if (GET_CODE (operands[1]) == CONST_INT - && INTVAL (operands[1]) < 0) - operands[1] = force_reg (<MODE>mode, operands[1]); - - rs6000_compare_op0 = operands[0]; - rs6000_compare_op1 = operands[1]; - rs6000_compare_fp_p = 0; - DONE; -}") + if (GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) < 0) + { + operands[2] = force_reg (<MODE>mode, operands[2]); + operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]), + GET_MODE (operands[0]), + operands[1], operands[2]); + } -(define_expand "cmp<mode>" - [(set (cc0) (compare (match_operand:FP 0 "gpc_reg_operand" "") - (match_operand:FP 1 "gpc_reg_operand" "")))] - "" - " -{ - rs6000_compare_op0 = operands[0]; - rs6000_compare_op1 = operands[1]; - rs6000_compare_fp_p = 1; + rs6000_emit_cbranch (<MODE>mode, operands); DONE; }") -(define_expand "beq" - [(use (match_operand 0 "" ""))] - "" - "{ rs6000_emit_cbranch (EQ, operands[0]); DONE; }") - -(define_expand "bne" - [(use (match_operand 0 "" ""))] - "" - "{ rs6000_emit_cbranch (NE, operands[0]); DONE; }") - -(define_expand "bge" - [(use (match_operand 0 "" ""))] - "" - "{ rs6000_emit_cbranch (GE, operands[0]); DONE; }") - -(define_expand "bgt" - [(use (match_operand 0 "" ""))] - "" - "{ rs6000_emit_cbranch (GT, operands[0]); DONE; }") - -(define_expand "ble" - [(use (match_operand 0 "" ""))] - "" - "{ rs6000_emit_cbranch (LE, operands[0]); DONE; }") - -(define_expand "blt" - [(use (match_operand 0 "" ""))] - "" - "{ rs6000_emit_cbranch (LT, operands[0]); DONE; }") - -(define_expand "bgeu" - [(use (match_operand 0 "" ""))] - "" - "{ rs6000_emit_cbranch (GEU, operands[0]); DONE; }") - -(define_expand "bgtu" - [(use (match_operand 0 "" ""))] - "" - "{ rs6000_emit_cbranch (GTU, operands[0]); DONE; }") - -(define_expand "bleu" - [(use (match_operand 0 "" ""))] - "" - "{ rs6000_emit_cbranch (LEU, operands[0]); DONE; }") - -(define_expand "bltu" - [(use (match_operand 0 "" ""))] - "" - "{ rs6000_emit_cbranch (LTU, operands[0]); DONE; }") - -(define_expand "bunordered" - [(use (match_operand 0 "" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_cbranch (UNORDERED, operands[0]); DONE; }") - -(define_expand "bordered" - [(use (match_operand 0 "" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_cbranch (ORDERED, operands[0]); DONE; }") - -(define_expand "buneq" - [(use (match_operand 0 "" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_cbranch (UNEQ, operands[0]); DONE; }") - -(define_expand "bunge" - [(use (match_operand 0 "" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_cbranch (UNGE, operands[0]); DONE; }") - -(define_expand "bungt" - [(use (match_operand 0 "" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_cbranch (UNGT, operands[0]); DONE; }") - -(define_expand "bunle" - [(use (match_operand 0 "" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_cbranch (UNLE, operands[0]); DONE; }") - -(define_expand "bunlt" - [(use (match_operand 0 "" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_cbranch (UNLT, operands[0]); DONE; }") - -(define_expand "bltgt" - [(use (match_operand 0 "" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_cbranch (LTGT, operands[0]); DONE; }") - -;; For SNE, we would prefer that the xor/abs sequence be used for integers. -;; For SEQ, likewise, except that comparisons with zero should be done -;; with an scc insns. However, due to the order that combine see the -;; resulting insns, we must, in fact, allow SEQ for integers. Fail in -;; the cases we don't want to handle. -(define_expand "seq" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "" - "{ rs6000_emit_sCOND (EQ, operands[0]); DONE; }") - -(define_expand "sne" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] +(define_expand "cbranch<mode>4" + [(use (match_operator 0 "rs6000_cbranch_operator" + [(match_operand:FP 1 "gpc_reg_operand" "") + (match_operand:FP 2 "gpc_reg_operand" "")])) + (use (match_operand 3 ""))] "" " { - if (! rs6000_compare_fp_p) - FAIL; - - rs6000_emit_sCOND (NE, operands[0]); + rs6000_emit_cbranch (<MODE>mode, operands); DONE; }") -;; A >= 0 is best done the portable way for A an integer. -(define_expand "sge" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] +(define_expand "cstore<mode>4" + [(use (match_operator 1 "rs6000_cbranch_operator" + [(match_operand:GPR 2 "gpc_reg_operand" "") + (match_operand:GPR 3 "reg_or_short_operand" "")])) + (clobber (match_operand:SI 0 "register_operand"))] "" " { - if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) - FAIL; - - rs6000_emit_sCOND (GE, operands[0]); - DONE; -}") + /* Take care of the possibility that operands[3] might be negative but + this might be a logical operation. That insn doesn't exist. */ + if (GET_CODE (operands[3]) == CONST_INT + && INTVAL (operands[3]) < 0) + { + operands[3] = force_reg (<MODE>mode, operands[3]); + operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), + GET_MODE (operands[1]), + operands[2], operands[3]); + } -;; A > 0 is best done using the portable sequence, so fail in that case. -(define_expand "sgt" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "" - " -{ - if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) + /* For SNE, we would prefer that the xor/abs sequence be used for integers. + For SEQ, likewise, except that comparisons with zero should be done + with an scc insns. However, due to the order that combine see the + resulting insns, we must, in fact, allow SEQ for integers. Fail in + the cases we don't want to handle or are best handled by portable + code. */ + if (GET_CODE (operands[1]) == NE) FAIL; - - rs6000_emit_sCOND (GT, operands[0]); - DONE; -}") - -;; A <= 0 is best done the portable way for A an integer. -(define_expand "sle" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "" - " -{ - if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) + if ((GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE + || GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE) + && operands[3] == const0_rtx) FAIL; - - rs6000_emit_sCOND (LE, operands[0]); + rs6000_emit_sCOND (<MODE>mode, operands); DONE; }") -;; A < 0 is best done in the portable way for A an integer. -(define_expand "slt" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] +(define_expand "cstore<mode>4" + [(use (match_operator 1 "rs6000_cbranch_operator" + [(match_operand:FP 2 "gpc_reg_operand" "") + (match_operand:FP 3 "gpc_reg_operand" "")])) + (clobber (match_operand:SI 0 "register_operand"))] "" " { - if (! rs6000_compare_fp_p && rs6000_compare_op1 == const0_rtx) - FAIL; - - rs6000_emit_sCOND (LT, operands[0]); + rs6000_emit_sCOND (<MODE>mode, operands); DONE; }") -(define_expand "sgeu" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "" - "{ rs6000_emit_sCOND (GEU, operands[0]); DONE; }") - -(define_expand "sgtu" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "" - "{ rs6000_emit_sCOND (GTU, operands[0]); DONE; }") - -(define_expand "sleu" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "" - "{ rs6000_emit_sCOND (LEU, operands[0]); DONE; }") - -(define_expand "sltu" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "" - "{ rs6000_emit_sCOND (LTU, operands[0]); DONE; }") - -(define_expand "sunordered" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_sCOND (UNORDERED, operands[0]); DONE; }") - -(define_expand "sordered" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_sCOND (ORDERED, operands[0]); DONE; }") - -(define_expand "suneq" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_sCOND (UNEQ, operands[0]); DONE; }") - -(define_expand "sunge" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_sCOND (UNGE, operands[0]); DONE; }") - -(define_expand "sungt" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_sCOND (UNGT, operands[0]); DONE; }") - -(define_expand "sunle" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_sCOND (UNLE, operands[0]); DONE; }") - -(define_expand "sunlt" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_sCOND (UNLT, operands[0]); DONE; }") - -(define_expand "sltgt" - [(clobber (match_operand:SI 0 "gpc_reg_operand" ""))] - "! (TARGET_HARD_FLOAT && !TARGET_FPRS)" - "{ rs6000_emit_sCOND (LTGT, operands[0]); DONE; }") (define_expand "stack_protect_set" [(match_operand 0 "memory_operand" "") @@ -12195,16 +12023,16 @@ (match_operand 2 "" "")] "" { + rtx test, op0, op1; #ifdef TARGET_THREAD_SSP_OFFSET rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2); rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); operands[1] = gen_rtx_MEM (Pmode, addr); #endif - rs6000_compare_op0 = operands[0]; - rs6000_compare_op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), - UNSPEC_SP_TEST); - rs6000_compare_fp_p = 0; - emit_jump_insn (gen_beq (operands[2])); + op0 = operands[0]; + op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST); + test = gen_rtx_EQ (VOIDmode, op0, op1); + emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2])); DONE; }) @@ -14775,17 +14603,16 @@ "{t 31,0,0|trap}" [(set_attr "type" "trap")]) -(define_expand "conditional_trap" - [(trap_if (match_operator 0 "trap_comparison_operator" - [(match_dup 2) (match_dup 3)]) - (match_operand 1 "const_int_operand" ""))] +(define_expand "ctrap<mode>4" + [(trap_if (match_operator 0 "ordered_comparison_operator" + [(match_operand:GPR 1 "register_operand") + (match_operand:GPR 2 "reg_or_short_operand")]) + (match_operand 3 "zero_constant" ""))] "" - "if (rs6000_compare_fp_p || operands[1] != const0_rtx) FAIL; - operands[2] = rs6000_compare_op0; - operands[3] = rs6000_compare_op1;") + "") (define_insn "" - [(trap_if (match_operator 0 "trap_comparison_operator" + [(trap_if (match_operator 0 "ordered_comparison_operator" [(match_operand:GPR 1 "register_operand" "r") (match_operand:GPR 2 "reg_or_short_operand" "rI")]) (const_int 0))] |