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/avr | |
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/avr')
-rw-r--r-- | gcc/config/avr/avr-protos.h | 4 | ||||
-rw-r--r-- | gcc/config/avr/avr.c | 43 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 274 |
3 files changed, 149 insertions, 172 deletions
diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h index 4424690..f4d2119 100644 --- a/gcc/config/avr/avr-protos.h +++ b/gcc/config/avr/avr-protos.h @@ -72,8 +72,8 @@ extern const char *out_movhi_mr_r (rtx insn, rtx op[], int *l); extern const char *out_movsi_r_mr (rtx insn, rtx op[], int *l); extern const char *out_movsi_mr_r (rtx insn, rtx op[], int *l); extern const char *output_movsisf (rtx insn, rtx operands[], int *l); -extern const char *out_tstsi (rtx insn, int *l); -extern const char *out_tsthi (rtx insn, int *l); +extern const char *out_tstsi (rtx insn, rtx src, int *l); +extern const char *out_tsthi (rtx insn, rtx src, int *l); extern const char *ret_cond_branch (rtx x, int len, int reverse); extern const char *ashlqi3_out (rtx insn, rtx operands[], int *len); diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 6bcc8e80..4811b92 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -2915,21 +2915,21 @@ compare_eq_p (rtx insn) /* Output test instruction for HImode. */ const char * -out_tsthi (rtx insn, int *l) +out_tsthi (rtx insn, rtx op, int *l) { if (compare_sign_p (insn)) { if (l) *l = 1; return AS1 (tst,%B0); } - if (reg_unused_after (insn, SET_SRC (PATTERN (insn))) + if (reg_unused_after (insn, op) && compare_eq_p (insn)) { /* Faster than sbiw if we can clobber the operand. */ if (l) *l = 1; return AS2 (or,%A0,%B0); } - if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn)))) + if (test_hard_reg_class (ADDW_REGS, op)) { if (l) *l = 1; return AS2 (sbiw,%0,0); @@ -2943,14 +2943,14 @@ out_tsthi (rtx insn, int *l) /* Output test instruction for SImode. */ const char * -out_tstsi (rtx insn, int *l) +out_tstsi (rtx insn, rtx op, int *l) { if (compare_sign_p (insn)) { if (l) *l = 1; return AS1 (tst,%D0); } - if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn)))) + if (test_hard_reg_class (ADDW_REGS, op)) { if (l) *l = 3; return (AS2 (sbiw,%A0,0) CR_TAB @@ -4367,8 +4367,8 @@ adjust_insn_length (rtx insn, int len) { switch (GET_MODE (op[1])) { - case HImode: out_tsthi (insn,&len); break; - case SImode: out_tstsi (insn,&len); break; + case HImode: out_tsthi (insn, op[1], &len); break; + case SImode: out_tstsi (insn, op[1], &len); break; default: break; } } @@ -5734,6 +5734,21 @@ avr_reorg (void) XEXP (pattern,1) = x; INSN_CODE (next) = -1; } + else if (true_regnum (XEXP (pattern, 0)) >= 0 + && XEXP (pattern, 1) == const0_rtx) + { + /* This is a tst insn, we can reverse it. */ + rtx next = next_real_insn (insn); + rtx pat = PATTERN (next); + rtx src = SET_SRC (pat); + rtx t = XEXP (src,0); + + PUT_CODE (t, swap_condition (GET_CODE (t))); + XEXP (pattern, 1) = XEXP (pattern, 0); + XEXP (pattern, 0) = const0_rtx; + INSN_CODE (next) = -1; + INSN_CODE (insn) = -1; + } else if (true_regnum (XEXP (pattern,0)) >= 0 && GET_CODE (XEXP (pattern,1)) == CONST_INT) { @@ -5753,20 +5768,6 @@ avr_reorg (void) } } } - else if (true_regnum (SET_SRC (pattern)) >= 0) - { - /* This is a tst insn */ - rtx next = next_real_insn (insn); - rtx pat = PATTERN (next); - rtx src = SET_SRC (pat); - rtx t = XEXP (src,0); - - PUT_CODE (t, swap_condition (GET_CODE (t))); - SET_SRC (pattern) = gen_rtx_COMPARE (GET_MODE (SET_SRC (pattern)), const0_rtx, - SET_SRC (pattern)); - INSN_CODE (next) = -1; - INSN_CODE (insn) = -1; - } } } } diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 269e2c5..86a217d 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -2202,53 +2202,65 @@ ;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=> ;; compare -(define_insn "tstqi" +; Optimize negated tests into reverse compare if overflow is undefined. +(define_insn "*negated_tstqi" [(set (cc0) - (match_operand:QI 0 "register_operand" "r"))] - "" - "tst %0" + (compare (neg:QI (match_operand:QI 0 "register_operand" "r")) + (const_int 0)))] + "(!flag_wrapv && !flag_trapv && flag_strict_overflow)" + "cp __zero_reg__,%0" [(set_attr "cc" "compare") (set_attr "length" "1")]) (define_insn "*reversed_tstqi" [(set (cc0) - (compare (const_int 0) + (compare (const_int 0) (match_operand:QI 0 "register_operand" "r")))] "" "cp __zero_reg__,%0" - [(set_attr "cc" "compare") - (set_attr "length" "1")]) +[(set_attr "cc" "compare") + (set_attr "length" "2")]) -(define_insn "tsthi" +(define_insn "*negated_tsthi" [(set (cc0) - (match_operand:HI 0 "register_operand" "!w,r"))] - "" - "* return out_tsthi (insn,NULL);" -[(set_attr "cc" "compare,compare") - (set_attr "length" "1,2")]) + (compare (neg:HI (match_operand:HI 0 "register_operand" "r")) + (const_int 0)))] + "(!flag_wrapv && !flag_trapv && flag_strict_overflow)" + "cp __zero_reg__,%A0 + cpc __zero_reg__,%B0" +[(set_attr "cc" "compare") + (set_attr "length" "2")]) +;; Leave here the clobber used by the cmphi pattern for simplicity, even +;; though it is unused, because this pattern is synthesized by avr_reorg. (define_insn "*reversed_tsthi" [(set (cc0) (compare (const_int 0) - (match_operand:HI 0 "register_operand" "r")))] + (match_operand:HI 0 "register_operand" "r"))) + (clobber (match_scratch:QI 1 "=X"))] "" "cp __zero_reg__,%A0 cpc __zero_reg__,%B0" [(set_attr "cc" "compare") (set_attr "length" "2")]) -(define_insn "tstsi" +(define_insn "*negated_tstsi" [(set (cc0) - (match_operand:SI 0 "register_operand" "r"))] - "" - "* return out_tstsi (insn,NULL);" + (compare (neg:SI (match_operand:SI 0 "register_operand" "r")) + (const_int 0)))] + "(!flag_wrapv && !flag_trapv && flag_strict_overflow)" + "cp __zero_reg__,%A0 + cpc __zero_reg__,%B0 + cpc __zero_reg__,%C0 + cpc __zero_reg__,%D0" [(set_attr "cc" "compare") (set_attr "length" "4")]) (define_insn "*reversed_tstsi" [(set (cc0) - (compare (const_int 0) - (match_operand:SI 0 "register_operand" "r")))] + (compare (const_int 0) + (match_operand:SI 0 "register_operand" "r"))) + (clobber (match_scratch:QI 1 "=X"))] "" "cp __zero_reg__,%A0 cpc __zero_reg__,%B0 @@ -2258,16 +2270,17 @@ (set_attr "length" "4")]) -(define_insn "cmpqi" +(define_insn "*cmpqi" [(set (cc0) - (compare (match_operand:QI 0 "register_operand" "r,d") - (match_operand:QI 1 "nonmemory_operand" "r,i")))] + (compare (match_operand:QI 0 "register_operand" "r,r,d") + (match_operand:QI 1 "nonmemory_operand" "L,r,i")))] "" "@ + tst %0 cp %0,%1 cpi %0,lo8(%1)" - [(set_attr "cc" "compare,compare") - (set_attr "length" "1,1")]) + [(set_attr "cc" "compare,compare,compare") + (set_attr "length" "1,1,1")]) (define_insn "*cmpqi_sign_extend" [(set (cc0) @@ -2279,19 +2292,22 @@ [(set_attr "cc" "compare") (set_attr "length" "1")]) -(define_insn "cmphi" +(define_insn "*cmphi" [(set (cc0) - (compare (match_operand:HI 0 "register_operand" "r,d,d,r,r") - (match_operand:HI 1 "nonmemory_operand" "r,M,i,M,i"))) - (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))] + (compare (match_operand:HI 0 "register_operand" "!w,r,r,d,d,r,r") + (match_operand:HI 1 "nonmemory_operand" "L,L,r,M,i,M,i"))) + (clobber (match_scratch:QI 2 "=X,X,X,X,&d,&d,&d"))] "" "*{ switch (which_alternative) { - case 0: + case 0: case 1: + return out_tsthi (insn, operands[0], NULL); + + case 2: return (AS2 (cp,%A0,%A1) CR_TAB AS2 (cpc,%B0,%B1)); - case 1: + case 3: if (reg_unused_after (insn, operands[0]) && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63 && test_hard_reg_class (ADDW_REGS, operands[0])) @@ -2299,7 +2315,7 @@ else return (AS2 (cpi,%0,%1) CR_TAB AS2 (cpc,%B0,__zero_reg__)); - case 2: + case 4: if (reg_unused_after (insn, operands[0])) return (AS2 (subi,%0,lo8(%1)) CR_TAB AS2 (sbci,%B0,hi8(%1))); @@ -2307,12 +2323,12 @@ return (AS2 (ldi, %2,hi8(%1)) CR_TAB AS2 (cpi, %A0,lo8(%1)) CR_TAB AS2 (cpc, %B0,%2)); - case 3: + case 5: return (AS2 (ldi, %2,lo8(%1)) CR_TAB AS2 (cp, %A0,%2) CR_TAB AS2 (cpc, %B0,__zero_reg__)); - case 4: + case 6: return (AS2 (ldi, %2,lo8(%1)) CR_TAB AS2 (cp, %A0,%2) CR_TAB AS2 (ldi, %2,hi8(%1)) CR_TAB @@ -2320,25 +2336,28 @@ } return \"bug\"; }" - [(set_attr "cc" "compare,compare,compare,compare,compare") - (set_attr "length" "2,2,3,3,4")]) + [(set_attr "cc" "compare,compare,compare,compare,compare,compare,compare") + (set_attr "length" "1,2,2,2,3,3,4")]) -(define_insn "cmpsi" +(define_insn "*cmpsi" [(set (cc0) - (compare (match_operand:SI 0 "register_operand" "r,d,d,r,r") - (match_operand:SI 1 "nonmemory_operand" "r,M,i,M,i"))) - (clobber (match_scratch:QI 2 "=X,X,&d,&d,&d"))] + (compare (match_operand:SI 0 "register_operand" "r,r,d,d,r,r") + (match_operand:SI 1 "nonmemory_operand" "L,r,M,i,M,i"))) + (clobber (match_scratch:QI 2 "=X,X,X,&d,&d,&d"))] "" "*{ switch (which_alternative) { case 0: + return out_tstsi (insn, operands[0], NULL); + + case 1: return (AS2 (cp,%A0,%A1) CR_TAB AS2 (cpc,%B0,%B1) CR_TAB AS2 (cpc,%C0,%C1) CR_TAB AS2 (cpc,%D0,%D1)); - case 1: + case 2: if (reg_unused_after (insn, operands[0]) && INTVAL (operands[1]) >= 0 && INTVAL (operands[1]) <= 63 && test_hard_reg_class (ADDW_REGS, operands[0])) @@ -2350,7 +2369,7 @@ AS2 (cpc,%B0,__zero_reg__) CR_TAB AS2 (cpc,%C0,__zero_reg__) CR_TAB AS2 (cpc,%D0,__zero_reg__)); - case 2: + case 3: if (reg_unused_after (insn, operands[0])) return (AS2 (subi,%A0,lo8(%1)) CR_TAB AS2 (sbci,%B0,hi8(%1)) CR_TAB @@ -2364,13 +2383,13 @@ AS2 (cpc, %C0,%2) CR_TAB AS2 (ldi, %2,hhi8(%1)) CR_TAB AS2 (cpc, %D0,%2)); - case 3: + case 4: return (AS2 (ldi,%2,lo8(%1)) CR_TAB AS2 (cp,%A0,%2) CR_TAB AS2 (cpc,%B0,__zero_reg__) CR_TAB AS2 (cpc,%C0,__zero_reg__) CR_TAB AS2 (cpc,%D0,__zero_reg__)); - case 4: + case 5: return (AS2 (ldi, %2,lo8(%1)) CR_TAB AS2 (cp, %A0,%2) CR_TAB AS2 (ldi, %2,hi8(%1)) CR_TAB @@ -2382,113 +2401,53 @@ } return \"bug\"; }" - [(set_attr "cc" "compare,compare,compare,compare,compare") - (set_attr "length" "4,4,7,5,8")]) - -; Optimize negated tests into reverse compare if overflow is undefined. -(define_insn_and_split "negated_tst<mode>" - [(set (cc0) - (neg:QISI (match_operand:QISI 0 "register_operand")))] + [(set_attr "cc" "compare,compare,compare,compare,compare,compare") + (set_attr "length" "4,4,4,7,5,8")]) - "(!flag_wrapv && !flag_trapv && flag_strict_overflow)" - "#" - "" - [(set (cc0) - (compare (const_int 0) - (match_dup 0)))] - "") ;; ---------------------------------------------------------------------- ;; JUMP INSTRUCTIONS ;; ---------------------------------------------------------------------- ;; Conditional jump instructions -(define_expand "beq" - [(set (pc) - (if_then_else (eq (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bne" - [(set (pc) - (if_then_else (ne (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bge" - [(set (pc) - (if_then_else (ge (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bgeu" - [(set (pc) - (if_then_else (geu (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "blt" - [(set (pc) - (if_then_else (lt (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bltu" - [(set (pc) - (if_then_else (ltu (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - - - -/**************************************************************** - AVR not have following conditional jumps: LE,LEU,GT,GTU. - Convert them all to proper jumps. -*****************************************************************/ - -(define_expand "ble" - [(set (pc) - (if_then_else (le (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") - -(define_expand "bleu" - [(set (pc) - (if_then_else (leu (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") +(define_expand "cbranchsi4" + [(parallel [(set (cc0) + (compare (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "nonmemory_operand" ""))) + (clobber (match_scratch:QI 4 ""))]) + (set (pc) + (if_then_else + (match_operator 0 "ordered_comparison_operator" [(cc0) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "") + +(define_expand "cbranchhi4" + [(parallel [(set (cc0) + (compare (match_operand:HI 1 "register_operand" "") + (match_operand:HI 2 "nonmemory_operand" ""))) + (clobber (match_scratch:QI 4 ""))]) + (set (pc) + (if_then_else + (match_operator 0 "ordered_comparison_operator" [(cc0) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "") -(define_expand "bgt" - [(set (pc) - (if_then_else (gt (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") +(define_expand "cbranchqi4" + [(set (cc0) + (compare (match_operand:QI 1 "register_operand" "") + (match_operand:QI 2 "nonmemory_operand" ""))) + (set (pc) + (if_then_else + (match_operator 0 "ordered_comparison_operator" [(cc0) + (const_int 0)]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "") -(define_expand "bgtu" - [(set (pc) - (if_then_else (gtu (cc0) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "") ;; Test a single bit in a QI/HI/SImode register. (define_insn "*sbrx_branch" @@ -2557,7 +2516,8 @@ ;; Convert sign tests to bit 7/15/31 tests that match the above insns. (define_peephole2 - [(set (cc0) (match_operand:QI 0 "register_operand" "")) + [(set (cc0) (compare (match_operand:QI 0 "register_operand" "") + (const_int 0))) (set (pc) (if_then_else (ge (cc0) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] @@ -2571,7 +2531,8 @@ "") (define_peephole2 - [(set (cc0) (match_operand:QI 0 "register_operand" "")) + [(set (cc0) (compare (match_operand:QI 0 "register_operand" "") + (const_int 0))) (set (pc) (if_then_else (lt (cc0) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] @@ -2585,7 +2546,9 @@ "") (define_peephole2 - [(set (cc0) (match_operand:HI 0 "register_operand" "")) + [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "") + (const_int 0))) + (clobber (match_operand:HI 2 ""))]) (set (pc) (if_then_else (ge (cc0) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] @@ -2597,7 +2560,9 @@ "") (define_peephole2 - [(set (cc0) (match_operand:HI 0 "register_operand" "")) + [(parallel [(set (cc0) (compare (match_operand:HI 0 "register_operand" "") + (const_int 0))) + (clobber (match_operand:HI 2 ""))]) (set (pc) (if_then_else (lt (cc0) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] @@ -2609,7 +2574,9 @@ "") (define_peephole2 - [(set (cc0) (match_operand:SI 0 "register_operand" "")) + [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "") + (const_int 0))) + (clobber (match_operand:SI 2 ""))]) (set (pc) (if_then_else (ge (cc0) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] @@ -2621,7 +2588,9 @@ "operands[2] = GEN_INT (-2147483647 - 1);") (define_peephole2 - [(set (cc0) (match_operand:SI 0 "register_operand" "")) + [(parallel [(set (cc0) (compare (match_operand:SI 0 "register_operand" "") + (const_int 0))) + (clobber (match_operand:SI 2 ""))]) (set (pc) (if_then_else (lt (cc0) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc)))] @@ -2650,6 +2619,11 @@ [(set_attr "type" "branch") (set_attr "cc" "clobber")]) +;; **************************************************************** +;; AVR does not have following conditional jumps: LE,LEU,GT,GTU. +;; Convert them all to proper jumps. +;; ****************************************************************/ + (define_insn "difficult_branch" [(set (pc) (if_then_else (match_operator 1 "difficult_comparison_operator" @@ -3150,7 +3124,9 @@ }") (define_peephole - [(set (cc0) (match_operand:QI 0 "register_operand" "")) + [(set (cc0) + (compare (match_operand:QI 0 "register_operand" "") + (const_int 0))) (set (pc) (if_then_else (eq (cc0) (const_int 0)) (label_ref (match_operand 1 "" "")) |