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:
Marek Michalkiewicz 2002-05-10 14:22:36 +02:00 committed by Marek Michalkiewicz
parent fbdb9fcec9
commit 1a499b9250
4 changed files with 122 additions and 10 deletions

View File

@ -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.

View File

@ -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 */

View File

@ -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;
{

View File

@ -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 ********************************