Commit 8efab2c5 by Georg-Johann Lay Committed by Georg-Johann Lay

avr-protos.h (avr_mode_code_base_reg_class): New prototype.

	* config/avr/avr-protos.h (avr_mode_code_base_reg_class): New prototype.
	(avr_regno_mode_code_ok_for_base_p): New prototype.
	* config/avr/avr.h (BASE_REG_CLASS): Remove.
	(REGNO_OK_FOR_BASE_P): Remove.
	(REG_OK_FOR_BASE_NOSTRICT_P): Remove.
	(REG_OK_FOR_BASE_STRICT_P): Remove.
	(MODE_CODE_BASE_REG_CLASS): New define.
	(REGNO_MODE_CODE_OK_FOR_BASE_P): New define.
	* config/avr/avr.c (avr_mode_code_base_reg_class): New function.
	(avr_regno_mode_code_ok_for_base_p): New function.
	(avr_reg_ok_for_addr_p): New static function.
	(avr_legitimate_address_p): Use it.  Beautify.

From-SVN: r179817
parent 05058b6e
2011-10-11 Georg-Johann Lay <avr@gjlay.de>
* config/avr/avr-protos.h (avr_mode_code_base_reg_class): New prototype.
(avr_regno_mode_code_ok_for_base_p): New prototype.
* config/avr/avr.h (BASE_REG_CLASS): Remove.
(REGNO_OK_FOR_BASE_P): Remove.
(REG_OK_FOR_BASE_NOSTRICT_P): Remove.
(REG_OK_FOR_BASE_STRICT_P): Remove.
(MODE_CODE_BASE_REG_CLASS): New define.
(REGNO_MODE_CODE_OK_FOR_BASE_P): New define.
* config/avr/avr.c (avr_mode_code_base_reg_class): New function.
(avr_regno_mode_code_ok_for_base_p): New function.
(avr_reg_ok_for_addr_p): New static function.
(avr_legitimate_address_p): Use it. Beautify.
2011-10-11 Georg-Johann Lay <avr@gjlay.de>
PR target/50447
* config/avr/avr.md (cc): Add out_plus attribute alternative.
(addsi3): Use it. Adapt avr_out_plus to new prototype. Use
......@@ -106,6 +106,8 @@ extern int avr_simplify_comparison_p (enum machine_mode mode,
extern RTX_CODE avr_normalize_condition (RTX_CODE condition);
extern void out_shift_with_cnt (const char *templ, rtx insn,
rtx operands[], int *len, int t_len);
extern reg_class_t avr_mode_code_base_reg_class (enum machine_mode, RTX_CODE, RTX_CODE);
extern bool avr_regno_mode_code_ok_for_base_p (int, enum machine_mode, RTX_CODE, RTX_CODE);
extern rtx avr_incoming_return_addr_rtx (void);
extern rtx avr_legitimize_reload_address (rtx, enum machine_mode, int, int, int, int, rtx (*)(rtx,int));
#endif /* RTX_CODE */
......
......@@ -1202,43 +1202,68 @@ avr_cannot_modify_jumps_p (void)
}
/* Helper function for `avr_legitimate_address_p'. */
static inline bool
avr_reg_ok_for_addr_p (rtx reg, addr_space_t as ATTRIBUTE_UNUSED, int strict)
{
return (REG_P (reg)
&& (avr_regno_mode_code_ok_for_base_p (REGNO (reg),
QImode, MEM, UNKNOWN)
|| (!strict
&& REGNO (reg) >= FIRST_PSEUDO_REGISTER)));
}
/* Return nonzero if X (an RTX) is a legitimate memory address on the target
machine for a memory operand of mode MODE. */
bool
static bool
avr_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
{
reg_class_t r = NO_REGS;
if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
: REG_OK_FOR_BASE_NOSTRICT_P (x)))
r = POINTER_REGS;
if (REG_P (x)
&& avr_reg_ok_for_addr_p (x, ADDR_SPACE_GENERIC, strict))
{
r = POINTER_REGS;
}
else if (CONSTANT_ADDRESS_P (x))
r = ALL_REGS;
{
r = ALL_REGS;
}
else if (GET_CODE (x) == PLUS
&& REG_P (XEXP (x, 0))
&& GET_CODE (XEXP (x, 1)) == CONST_INT
&& INTVAL (XEXP (x, 1)) >= 0)
&& CONST_INT_P (XEXP (x, 1))
&& INTVAL (XEXP (x, 1)) >= 0)
{
int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
rtx reg = XEXP (x, 0);
bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
if (fit)
{
if (! strict
|| REGNO (XEXP (x,0)) == REG_X
|| REGNO (XEXP (x,0)) == REG_Y
|| REGNO (XEXP (x,0)) == REG_Z)
r = BASE_POINTER_REGS;
if (XEXP (x,0) == frame_pointer_rtx
|| XEXP (x,0) == arg_pointer_rtx)
r = BASE_POINTER_REGS;
}
else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
r = POINTER_Y_REGS;
{
if (! strict
|| REGNO (reg) == REG_X
|| REGNO (reg) == REG_Y
|| REGNO (reg) == REG_Z)
{
r = BASE_POINTER_REGS;
}
if (reg == frame_pointer_rtx
|| reg == arg_pointer_rtx)
{
r = BASE_POINTER_REGS;
}
}
else if (frame_pointer_needed && reg == frame_pointer_rtx)
{
r = POINTER_Y_REGS;
}
}
else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
&& REG_P (XEXP (x, 0))
&& (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
: REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
&& avr_reg_ok_for_addr_p (XEXP (x, 0), ADDR_SPACE_GENERIC, strict))
{
r = POINTER_REGS;
}
......@@ -1269,7 +1294,7 @@ avr_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
/* Attempts to replace X with a valid
memory address for an operand of mode MODE */
rtx
static rtx
avr_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
{
bool big_offset_p = false;
......@@ -7224,6 +7249,51 @@ avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
}
/* Implement `MODE_CODE_BASE_REG_CLASS'. */
reg_class_t
avr_mode_code_base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED,
RTX_CODE outer_code ATTRIBUTE_UNUSED,
RTX_CODE index_code ATTRIBUTE_UNUSED)
{
return reload_completed ? BASE_POINTER_REGS : POINTER_REGS;
}
/* Implement `REGNO_MODE_CODE_OK_FOR_BASE_P'. */
bool
avr_regno_mode_code_ok_for_base_p (int regno,
enum machine_mode mode ATTRIBUTE_UNUSED,
RTX_CODE outer_code ATTRIBUTE_UNUSED,
RTX_CODE index_code ATTRIBUTE_UNUSED)
{
if (regno < FIRST_PSEUDO_REGISTER
&& (regno == REG_X
|| regno == REG_Y
|| regno == REG_Z
|| regno == ARG_POINTER_REGNUM))
{
return true;
}
if (reg_renumber)
{
regno = reg_renumber[regno];
if (regno == REG_X
|| regno == REG_Y
|| regno == REG_Z
|| regno == ARG_POINTER_REGNUM)
{
return true;
}
}
return false;
}
/* A helper for `output_reload_insisf' and `output_reload_inhi'. */
/* Set 32-bit register OP[0] to compile-time constant OP[1].
CLOBBER_REG is a QI clobber register or NULL_RTX.
......
......@@ -308,21 +308,13 @@ enum reg_class {
#define REGNO_REG_CLASS(R) avr_regno_reg_class(R)
#define BASE_REG_CLASS (reload_completed ? BASE_POINTER_REGS : POINTER_REGS)
#define MODE_CODE_BASE_REG_CLASS(mode, outer_code, index_code) \
avr_mode_code_base_reg_class (mode, outer_code, index_code)
#define INDEX_REG_CLASS NO_REGS
#define REGNO_OK_FOR_BASE_P(r) (((r) < FIRST_PSEUDO_REGISTER \
&& ((r) == REG_X \
|| (r) == REG_Y \
|| (r) == REG_Z \
|| (r) == ARG_POINTER_REGNUM)) \
|| (reg_renumber \
&& (reg_renumber[r] == REG_X \
|| reg_renumber[r] == REG_Y \
|| reg_renumber[r] == REG_Z \
|| (reg_renumber[r] \
== ARG_POINTER_REGNUM))))
#define REGNO_MODE_CODE_OK_FOR_BASE_P(num, mode, outer_code, index_code) \
avr_regno_mode_code_ok_for_base_p (num, mode, outer_code, index_code)
#define REGNO_OK_FOR_INDEX_P(NUM) 0
......@@ -381,10 +373,6 @@ typedef struct avr_args {
#define MAX_REGS_PER_ADDRESS 1
#define REG_OK_FOR_BASE_NOSTRICT_P(X) \
(REGNO (X) >= FIRST_PSEUDO_REGISTER || REG_OK_FOR_BASE_STRICT_P(X))
#define REG_OK_FOR_BASE_STRICT_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_L,WIN) \
do { \
rtx new_x = avr_legitimize_reload_address (X, MODE, OPNUM, TYPE, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment