From 8efab2c5eafbe0e3d43dccd13cbc57f62a4e672f Mon Sep 17 00:00:00 2001 From: Georg-Johann Lay <avr@gjlay.de> Date: Tue, 11 Oct 2011 18:34:16 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 15 +++++ gcc/config/avr/avr-protos.h | 2 + gcc/config/avr/avr.c | 116 +++++++++++++++++++++++++++++------- gcc/config/avr/avr.h | 20 ++----- 4 files changed, 114 insertions(+), 39 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2fabe682c149..29a49a0aac68 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +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 diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h index 06e412c96e53..a799fb2a9374 100644 --- a/gcc/config/avr/avr-protos.h +++ b/gcc/config/avr/avr-protos.h @@ -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 */ diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index afc3d61851c4..751f27abb2ca 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -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. diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index 51bd942cf56e..015f12b5fe51 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -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, \ -- GitLab