re PR middle-end/19154 (miss-optimization of (x & pow2C) avr conditionals returning bool equivalent values)
PR middle-end/19154 * avr.md (QIDI): Add new mode iterator. (sbrx_branch<mode>): Create new zero extract bit, test and jump patterns for all QI-DI modes combinations. (sbrx_and_branch<mode>): Create new and based bit test and jump patterns for QI-SI modes. avr.c (avr_out_sbxx_branch): Use only bit number. From-SVN: r153530
This commit is contained in:
parent
8b583a0651
commit
ed1f5d718b
@ -5877,12 +5877,12 @@ avr_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Output a branch that tests a single bit of a register (QI, HI or SImode)
|
||||
/* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
|
||||
or memory location in the I/O space (QImode only).
|
||||
|
||||
Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
|
||||
Operand 1: register operand to test, or CONST_INT memory address.
|
||||
Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
|
||||
Operand 2: bit number.
|
||||
Operand 3: label to jump to if the test is true. */
|
||||
|
||||
const char *
|
||||
@ -5930,9 +5930,7 @@ avr_out_sbxx_branch (rtx insn, rtx operands[])
|
||||
else /* HImode or SImode */
|
||||
{
|
||||
static char buf[] = "sbrc %A1,0";
|
||||
int bit_nr = exact_log2 (INTVAL (operands[2])
|
||||
& GET_MODE_MASK (GET_MODE (operands[1])));
|
||||
|
||||
int bit_nr = INTVAL (operands[2]);
|
||||
buf[3] = (comp == EQ) ? 's' : 'c';
|
||||
buf[6] = 'A' + (bit_nr >> 3);
|
||||
buf[9] = '0' + (bit_nr & 7);
|
||||
|
@ -118,6 +118,7 @@
|
||||
|
||||
;; Define mode iterator
|
||||
(define_mode_iterator QISI [(QI "") (HI "") (SI "")])
|
||||
(define_mode_iterator QIDI [(QI "") (HI "") (SI "") (DI "")])
|
||||
|
||||
;;========================================================================
|
||||
;; The following is used by nonlocal_goto and setjmp.
|
||||
@ -2448,12 +2449,15 @@
|
||||
|
||||
|
||||
;; Test a single bit in a QI/HI/SImode register.
|
||||
(define_insn "*sbrx_branch"
|
||||
;; Combine will create zero extract patterns for single bit tests.
|
||||
;; permit any mode in source pattern by using VOIDmode.
|
||||
|
||||
(define_insn "*sbrx_branch<mode>"
|
||||
[(set (pc)
|
||||
(if_then_else
|
||||
(match_operator 0 "eqne_operator"
|
||||
[(zero_extract:HI
|
||||
(match_operand:QI 1 "register_operand" "r")
|
||||
[(zero_extract:QIDI
|
||||
(match_operand:VOID 1 "register_operand" "r")
|
||||
(const_int 1)
|
||||
(match_operand 2 "const_int_operand" "n"))
|
||||
(const_int 0)])
|
||||
@ -2470,39 +2474,27 @@
|
||||
(const_int 4))))
|
||||
(set_attr "cc" "clobber")])
|
||||
|
||||
(define_insn "*sbrx_and_branchhi"
|
||||
[(set (pc)
|
||||
(if_then_else
|
||||
(match_operator 0 "eqne_operator"
|
||||
[(and:HI
|
||||
(match_operand:HI 1 "register_operand" "r")
|
||||
(match_operand:HI 2 "single_one_operand" "n"))
|
||||
(const_int 0)])
|
||||
(label_ref (match_operand 3 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"* return avr_out_sbxx_branch (insn, operands);"
|
||||
[(set (attr "length")
|
||||
(if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
|
||||
(le (minus (pc) (match_dup 3)) (const_int 2046)))
|
||||
(const_int 2)
|
||||
(if_then_else (eq_attr "mcu_mega" "no")
|
||||
(const_int 2)
|
||||
(const_int 4))))
|
||||
(set_attr "cc" "clobber")])
|
||||
;; Same test based on Bitwise AND RTL. Keep this incase gcc changes patterns.
|
||||
;; or for old peepholes.
|
||||
;; Fixme - bitwise Mask will not work for DImode
|
||||
|
||||
(define_insn "*sbrx_and_branchsi"
|
||||
(define_insn "*sbrx_and_branch<mode>"
|
||||
[(set (pc)
|
||||
(if_then_else
|
||||
(match_operator 0 "eqne_operator"
|
||||
[(and:SI
|
||||
(match_operand:SI 1 "register_operand" "r")
|
||||
(match_operand:SI 2 "single_one_operand" "n"))
|
||||
[(and:QISI
|
||||
(match_operand:QISI 1 "register_operand" "r")
|
||||
(match_operand:QISI 2 "single_one_operand" "n"))
|
||||
(const_int 0)])
|
||||
(label_ref (match_operand 3 "" ""))
|
||||
(pc)))]
|
||||
""
|
||||
"* return avr_out_sbxx_branch (insn, operands);"
|
||||
{
|
||||
HOST_WIDE_INT bitnumber;
|
||||
bitnumber = exact_log2 (GET_MODE_MASK (<MODE>mode) & INTVAL (operands[2]));
|
||||
operands[2] = GEN_INT (bitnumber);
|
||||
return avr_out_sbxx_branch (insn, operands);
|
||||
}
|
||||
[(set (attr "length")
|
||||
(if_then_else (and (ge (minus (pc) (match_dup 3)) (const_int -2046))
|
||||
(le (minus (pc) (match_dup 3)) (const_int 2046)))
|
||||
|
Loading…
Reference in New Issue
Block a user