aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/avr
diff options
context:
space:
mode:
authorPaolo Bonzini <bonzini@gnu.org>2009-05-12 09:43:48 +0000
committerPaolo Bonzini <bonzini@gcc.gnu.org>2009-05-12 09:43:48 +0000
commitf90b7a5a7913cc7239cce42f6ca328b9a741b387 (patch)
tree06c940a96a184a178bfadd53e04213225655a68d /gcc/config/avr
parentb7a0af68063c79655c561750e9863799bf846cae (diff)
downloadgcc-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.h4
-rw-r--r--gcc/config/avr/avr.c43
-rw-r--r--gcc/config/avr/avr.md274
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 "" ""))