mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-06 15:40:53 +08:00
avr.c (print_operand): Check that addr is a SYMBOL_REF before using SYMBOL_REF_FLAG (addr).
* config/avr/avr.c (print_operand): Check that addr is a SYMBOL_REF before using SYMBOL_REF_FLAG (addr). * config/avr/avr-protos.h (avr_io_address_p): Declare. * config/avr/avr.c (io_address_p): Rename to avr_io_address_p. Make non-static. Update all callers. * config/avr/avr.md (*cbi, *sbi, *sbix_branch, *sbix_branch_bit7): New insns to clear/set/test a single bit in I/O address space. From-SVN: r53359
This commit is contained in:
parent
fbdb9fcec9
commit
1a499b9250
@ -1,3 +1,14 @@
|
||||
2002-05-10 Marek Michalkiewicz <marekm@amelek.gda.pl>
|
||||
|
||||
* config/avr/avr.c (print_operand): Check that addr is a SYMBOL_REF
|
||||
before using SYMBOL_REF_FLAG (addr).
|
||||
|
||||
* config/avr/avr-protos.h (avr_io_address_p): Declare.
|
||||
* config/avr/avr.c (io_address_p): Rename to avr_io_address_p.
|
||||
Make non-static. Update all callers.
|
||||
* config/avr/avr.md (*cbi, *sbi, *sbix_branch, *sbix_branch_bit7):
|
||||
New insns to clear/set/test a single bit in I/O address space.
|
||||
|
||||
2002-05-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* rtl.h (ENABLE_RTL_FLAG_CHECKING): Also check for gcc >= 2.7.
|
||||
|
@ -141,6 +141,7 @@ extern int compare_eq_p PARAMS ((rtx insn));
|
||||
extern void out_shift_with_cnt PARAMS ((const char *template, rtx insn,
|
||||
rtx operands[], int *len,
|
||||
int t_len));
|
||||
extern int avr_io_address_p PARAMS ((rtx x, int size));
|
||||
extern int const_int_pow2_p PARAMS ((rtx x));
|
||||
extern int avr_peep2_scratch_safe PARAMS ((rtx reg_rtx));
|
||||
#endif /* RTX_CODE */
|
||||
|
@ -56,7 +56,6 @@ static int out_set_stack_ptr PARAMS ((FILE *, int, int));
|
||||
static RTX_CODE compare_condition PARAMS ((rtx insn));
|
||||
static int compare_sign_p PARAMS ((rtx insn));
|
||||
static int reg_was_0 PARAMS ((rtx insn, rtx op));
|
||||
static int io_address_p PARAMS ((rtx x, int size));
|
||||
void debug_hard_reg_set PARAMS ((HARD_REG_SET set));
|
||||
static tree avr_handle_progmem_attribute PARAMS ((tree *, tree, tree, int, bool *));
|
||||
static tree avr_handle_fndecl_attribute PARAMS ((tree *, tree, tree, int, bool *));
|
||||
@ -1001,7 +1000,8 @@ print_operand_address (file, addr)
|
||||
|
||||
default:
|
||||
if (CONSTANT_ADDRESS_P (addr)
|
||||
&& (SYMBOL_REF_FLAG (addr) || GET_CODE (addr) == LABEL_REF))
|
||||
&& ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
|
||||
|| GET_CODE (addr) == LABEL_REF))
|
||||
{
|
||||
fprintf (file, "pm(");
|
||||
output_addr_const (file,addr);
|
||||
@ -1802,7 +1802,7 @@ out_movqi_r_mr (insn, op, l)
|
||||
|
||||
if (CONSTANT_ADDRESS_P (x))
|
||||
{
|
||||
if (io_address_p (x, 1))
|
||||
if (avr_io_address_p (x, 1))
|
||||
{
|
||||
*l = 1;
|
||||
return AS2 (in,%0,%1-0x20);
|
||||
@ -1971,7 +1971,7 @@ out_movhi_r_mr (insn, op, l)
|
||||
}
|
||||
else if (CONSTANT_ADDRESS_P (base))
|
||||
{
|
||||
if (io_address_p (base, 2))
|
||||
if (avr_io_address_p (base, 2))
|
||||
{
|
||||
*l = 2;
|
||||
return (AS2 (in,%A0,%A1-0x20) CR_TAB
|
||||
@ -2514,7 +2514,7 @@ out_movqi_mr_r (insn, op, l)
|
||||
|
||||
if (CONSTANT_ADDRESS_P (x))
|
||||
{
|
||||
if (io_address_p (x, 1))
|
||||
if (avr_io_address_p (x, 1))
|
||||
{
|
||||
*l = 1;
|
||||
return AS2 (out,%0-0x20,%1);
|
||||
@ -2592,7 +2592,7 @@ out_movhi_mr_r (insn, op, l)
|
||||
l = &tmp;
|
||||
if (CONSTANT_ADDRESS_P (base))
|
||||
{
|
||||
if (io_address_p (base, 2))
|
||||
if (avr_io_address_p (base, 2))
|
||||
{
|
||||
*l = 2;
|
||||
return (AS2 (out,%B0-0x20,%B1) CR_TAB
|
||||
@ -4927,7 +4927,7 @@ avr_address_cost (x)
|
||||
return 18;
|
||||
if (CONSTANT_ADDRESS_P (x))
|
||||
{
|
||||
if (io_address_p (x, 1))
|
||||
if (avr_io_address_p (x, 1))
|
||||
return 2;
|
||||
return 4;
|
||||
}
|
||||
@ -5246,10 +5246,11 @@ reg_was_0 (insn, op)
|
||||
}
|
||||
|
||||
/* Returns 1 if X is a valid address for an I/O register of size SIZE
|
||||
(1 or 2). Used for lds/sts -> in/out optimization. */
|
||||
(1 or 2). Used for lds/sts -> in/out optimization. Add 0x20 to SIZE
|
||||
to check for the lower half of I/O space (for cbi/sbi/sbic/sbis). */
|
||||
|
||||
static int
|
||||
io_address_p (x, size)
|
||||
int
|
||||
avr_io_address_p (x, size)
|
||||
rtx x;
|
||||
int size;
|
||||
{
|
||||
|
@ -2230,6 +2230,105 @@
|
||||
[(set_attr "length" "1")
|
||||
(set_attr "cc" "compare")])
|
||||
|
||||
;; Clear/set/test a single bit in I/O address space.
|
||||
|
||||
(define_insn "*cbi"
|
||||
[(set (mem:QI (match_operand 0 "const_int_operand" "n"))
|
||||
(and:QI (mem:QI (match_dup 0))
|
||||
(match_operand 1 "const_int_operand" "n")))]
|
||||
"avr_io_address_p (operands[0], 1 + 0x20)
|
||||
&& exact_log2 (~INTVAL (operands[1]) & 0xff) >= 0"
|
||||
{
|
||||
operands[2] = GEN_INT (exact_log2 (~INTVAL (operands[1]) & 0xff));
|
||||
return AS2 (cbi,%0-0x20,%2);
|
||||
}
|
||||
[(set_attr "length" "1")
|
||||
(set_attr "cc" "none")])
|
||||
|
||||
(define_insn "*sbi"
|
||||
[(set (mem:QI (match_operand 0 "const_int_operand" "n"))
|
||||
(ior:QI (mem:QI (match_dup 0))
|
||||
(match_operand 1 "const_int_operand" "n")))]
|
||||
"avr_io_address_p (operands[0], 1 + 0x20)
|
||||
&& exact_log2 (INTVAL (operands[1]) & 0xff) >= 0"
|
||||
{
|
||||
operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1]) & 0xff));
|
||||
return AS2 (sbi,%0-0x20,%2);
|
||||
}
|
||||
[(set_attr "length" "1")
|
||||
(set_attr "cc" "none")])
|
||||
|
||||
(define_insn "*sbix_branch"
|
||||
[(set (pc)
|
||||
(if_then_else
|
||||
(match_operator 0 "comparison_operator"
|
||||
[(zero_extract
|
||||
(mem:QI (match_operand 1 "const_int_operand" "n"))
|
||||
(const_int 1)
|
||||
(match_operand 2 "const_int_operand" "n"))
|
||||
(const_int 0)])
|
||||
(label_ref (match_operand 3 "" ""))
|
||||
(pc)))]
|
||||
"(GET_CODE (operands[0]) == EQ || GET_CODE (operands[0]) == NE)
|
||||
&& avr_io_address_p (operands[1], 1 + 0x20)"
|
||||
{
|
||||
enum rtx_code comp = GET_CODE (operands[0]);
|
||||
int reverse = (get_attr_length (insn) == 4);
|
||||
|
||||
if (reverse)
|
||||
comp = reverse_condition (comp);
|
||||
if (comp == EQ)
|
||||
output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
|
||||
else
|
||||
output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
|
||||
if (!reverse)
|
||||
return AS1 (rjmp,%3);
|
||||
return (AS1 (rjmp,_PC_+4) CR_TAB
|
||||
AS1 (jmp,%3));
|
||||
}
|
||||
[(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")])
|
||||
|
||||
;; Tests of bit 7 are pessimized to sign tests, so we need this too...
|
||||
(define_insn "*sbix_branch_bit7"
|
||||
[(set (pc)
|
||||
(if_then_else
|
||||
(match_operator 0 "comparison_operator"
|
||||
[(mem:QI (match_operand 1 "const_int_operand" "n"))
|
||||
(const_int 0)])
|
||||
(label_ref (match_operand 2 "" ""))
|
||||
(pc)))]
|
||||
"(GET_CODE (operands[0]) == GE || GET_CODE (operands[0]) == LT)
|
||||
&& avr_io_address_p (operands[1], 1 + 0x20)"
|
||||
{
|
||||
enum rtx_code comp = GET_CODE (operands[0]);
|
||||
int reverse = (get_attr_length (insn) == 4);
|
||||
|
||||
if (reverse)
|
||||
comp = reverse_condition (comp);
|
||||
if (comp == GE)
|
||||
output_asm_insn (AS2 (sbis,%1-0x20,7), operands);
|
||||
else
|
||||
output_asm_insn (AS2 (sbic,%1-0x20,7), operands);
|
||||
if (!reverse)
|
||||
return AS1 (rjmp,%2);
|
||||
return (AS1 (rjmp,_PC_+4) CR_TAB
|
||||
AS1 (jmp,%2));
|
||||
}
|
||||
[(set (attr "length")
|
||||
(if_then_else (and (ge (minus (pc) (match_dup 2)) (const_int -2046))
|
||||
(le (minus (pc) (match_dup 2)) (const_int 2046)))
|
||||
(const_int 2)
|
||||
(if_then_else (eq_attr "mcu_mega" "no")
|
||||
(const_int 2)
|
||||
(const_int 4))))
|
||||
(set_attr "cc" "clobber")])
|
||||
|
||||
;; ************************* Peepholes ********************************
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user