diff options
-rw-r--r-- | gcc/ChangeLog | 29 | ||||
-rw-r--r-- | gcc/config/mips/constraints.md | 2 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 57 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 8 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 84 | ||||
-rw-r--r-- | gcc/config/mips/mips.opt | 4 |
6 files changed, 142 insertions, 42 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cdc49917ae5..9f790251cdc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,7 +1,32 @@ 2014-06-18 Robert Suchanek <robert.suchanek@imgtec.com> - * lra-constraints.c (base_to_reg): New function. - (process_address): Use new function. + * config/mips/constraints.md ("d"): BASE_REG_CLASS replaced by + "TARGET_MIPS16 ? M16_REGS : GR_REGS". + * config/mips/mips.c (mips_regno_to_class): Update for M16_SP_REGS. + (mips_regno_mode_ok_for_base_p): Remove use of !strict_p for MIPS16. + (mips_register_priority): New function that implements the target + hook TARGET_REGISTER_PRIORITY. + (mips_spill_class): Likewise for TARGET_SPILL_CLASS. + (mips_lra_p): Likewise for TARGET_LRA_P. + (TARGET_REGISTER_PRIORITY): Define macro. + (TARGET_SPILL_CLASS): Likewise. + (TARGET_LRA_P): Likewise. + * config/mips/mips.h (reg_class): Add M16_SP_REGS and SPILL_REGS + classes. + (REG_CLASS_NAMES): Likewise. + (REG_CLASS_CONTENTS): Likewise. + (BASE_REG_CLASS): Use M16_SP_REGS. + * config/mips/mips.md (*mul_acc_si): Add alternative tuned for LRA. + New set attribute to enable alternatives depending on the register + allocator used. + (*mul_acc_si_r3900, *mul_sub_si): Likewise. + (*lea64): Disable pattern for MIPS16. + * config/mips/mips.opt (mlra): New option. + +2014-06-18 Robert Suchanek <robert.suchanek@imgtec.com> + + * lra-constraints.c (base_to_reg): New function. + (process_address): Use new function. 2014-06-18 Tom de Vries <tom@codesourcery.com> diff --git a/gcc/config/mips/constraints.md b/gcc/config/mips/constraints.md index f6834fd1e94..fa33c305f8a 100644 --- a/gcc/config/mips/constraints.md +++ b/gcc/config/mips/constraints.md @@ -19,7 +19,7 @@ ;; Register constraints -(define_register_constraint "d" "BASE_REG_CLASS" +(define_register_constraint "d" "TARGET_MIPS16 ? M16_REGS : GR_REGS" "An address register. This is equivalent to @code{r} unless generating MIPS16 code.") diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index cff1d3817c7..1b1633ce046 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -661,7 +661,7 @@ const enum reg_class mips_regno_to_class[FIRST_PSEUDO_REGISTER] = { M16_REGS, M16_STORE_REGS, LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, T_REG, PIC_FN_ADDR_REG, LEA_REGS, LEA_REGS, - LEA_REGS, LEA_REGS, LEA_REGS, LEA_REGS, + LEA_REGS, M16_SP_REGS, LEA_REGS, LEA_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, FP_REGS, @@ -2260,22 +2260,9 @@ mips_regno_mode_ok_for_base_p (int regno, enum machine_mode mode, return true; /* In MIPS16 mode, the stack pointer can only address word and doubleword - values, nothing smaller. There are two problems here: - - (a) Instantiating virtual registers can introduce new uses of the - stack pointer. If these virtual registers are valid addresses, - the stack pointer should be too. - - (b) Most uses of the stack pointer are not made explicit until - FRAME_POINTER_REGNUM and ARG_POINTER_REGNUM have been eliminated. - We don't know until that stage whether we'll be eliminating to the - stack pointer (which needs the restriction) or the hard frame - pointer (which doesn't). - - All in all, it seems more consistent to only enforce this restriction - during and after reload. */ + values, nothing smaller. */ if (TARGET_MIPS16 && regno == STACK_POINTER_REGNUM) - return !strict_p || GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8; + return GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8; return TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno); } @@ -12100,6 +12087,18 @@ mips_register_move_cost (enum machine_mode mode, return 0; } +/* Implement TARGET_REGISTER_PRIORITY. */ + +static int +mips_register_priority (int hard_regno) +{ + /* Treat MIPS16 registers with higher priority than other regs. */ + if (TARGET_MIPS16 + && TEST_HARD_REG_BIT (reg_class_contents[M16_REGS], hard_regno)) + return 1; + return 0; +} + /* Implement TARGET_MEMORY_MOVE_COST. */ static int @@ -18898,6 +18897,25 @@ mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update) *update = build2 (COMPOUND_EXPR, void_type_node, *update, atomic_feraiseexcept_call); } + +/* Implement TARGET_SPILL_CLASS. */ + +static reg_class_t +mips_spill_class (reg_class_t rclass ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED) +{ + if (TARGET_MIPS16) + return SPILL_REGS; + return NO_REGS; +} + +/* Implement TARGET_LRA_P. */ + +static bool +mips_lra_p (void) +{ + return mips_lra_flag; +} /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP @@ -18961,6 +18979,8 @@ mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update) #define TARGET_VALID_POINTER_MODE mips_valid_pointer_mode #undef TARGET_REGISTER_MOVE_COST #define TARGET_REGISTER_MOVE_COST mips_register_move_cost +#undef TARGET_REGISTER_PRIORITY +#define TARGET_REGISTER_PRIORITY mips_register_priority #undef TARGET_MEMORY_MOVE_COST #define TARGET_MEMORY_MOVE_COST mips_memory_move_cost #undef TARGET_RTX_COSTS @@ -19138,6 +19158,11 @@ mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update) #undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS #define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true +#undef TARGET_SPILL_CLASS +#define TARGET_SPILL_CLASS mips_spill_class +#undef TARGET_LRA_P +#define TARGET_LRA_P mips_lra_p + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-mips.h" diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 38eea44c407..7029e046f9a 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -1869,10 +1869,12 @@ enum reg_class NO_REGS, /* no registers in set */ M16_STORE_REGS, /* microMIPS store registers */ M16_REGS, /* mips16 directly accessible registers */ + M16_SP_REGS, /* mips16 + $sp */ T_REG, /* mips16 T register ($24) */ M16_T_REGS, /* mips16 registers plus T register */ PIC_FN_ADDR_REG, /* SVR4 PIC function address register */ V1_REG, /* Register $v1 ($3) used for TLS access. */ + SPILL_REGS, /* All but $sp and call preserved regs are in here */ LEA_REGS, /* Every GPR except $25 */ GR_REGS, /* integer registers */ FP_REGS, /* floating point registers */ @@ -1907,10 +1909,12 @@ enum reg_class "NO_REGS", \ "M16_STORE_REGS", \ "M16_REGS", \ + "M16_SP_REGS", \ "T_REG", \ "M16_T_REGS", \ "PIC_FN_ADDR_REG", \ "V1_REG", \ + "SPILL_REGS", \ "LEA_REGS", \ "GR_REGS", \ "FP_REGS", \ @@ -1948,10 +1952,12 @@ enum reg_class { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \ { 0x000200fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* M16_STORE_REGS */ \ { 0x000300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* M16_REGS */ \ + { 0x200300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* M16_SP_REGS */ \ { 0x01000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* T_REG */ \ { 0x010300fc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* M16_T_REGS */ \ { 0x02000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* PIC_FN_ADDR_REG */ \ { 0x00000008, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* V1_REG */ \ + { 0x0303fffc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* SPILL_REGS */ \ { 0xfdffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* LEA_REGS */ \ { 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* GR_REGS */ \ { 0x00000000, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* FP_REGS */ \ @@ -1984,7 +1990,7 @@ enum reg_class valid base register must belong. A base register is one used in an address which is the register value plus a displacement. */ -#define BASE_REG_CLASS (TARGET_MIPS16 ? M16_REGS : GR_REGS) +#define BASE_REG_CLASS (TARGET_MIPS16 ? M16_SP_REGS : GR_REGS) /* A macro whose definition is the name of the class to which a valid index register must belong. An index register is one used diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 9912ddcb63a..7e23bd21066 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -1624,40 +1624,66 @@ ;; copy instructions. Reload therefore thinks that the second alternative ;; is two reloads more costly than the first. We add "*?*?" to the first ;; alternative as a counterweight. +;; +;; LRA simulates reload but the cost of reloading scratches is lower +;; than of the classic reload. For the time being, removing the counterweight +;; for LRA is more profitable. (define_insn "*mul_acc_si" - [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?") - (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") - (match_operand:SI 2 "register_operand" "d,d")) - (match_operand:SI 3 "register_operand" "0,d"))) - (clobber (match_scratch:SI 4 "=X,l")) - (clobber (match_scratch:SI 5 "=X,&d"))] + [(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d?") + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d") + (match_operand:SI 2 "register_operand" "d,d,d")) + (match_operand:SI 3 "register_operand" "0,0,d"))) + (clobber (match_scratch:SI 4 "=X,X,l")) + (clobber (match_scratch:SI 5 "=X,X,&d"))] "GENERATE_MADD_MSUB && !TARGET_MIPS16" "@ madd\t%1,%2 + madd\t%1,%2 #" [(set_attr "type" "imadd") (set_attr "accum_in" "3") (set_attr "mode" "SI") - (set_attr "insn_count" "1,2")]) + (set_attr "insn_count" "1,1,2") + (set (attr "enabled") + (cond [(and (eq_attr "alternative" "0") + (match_test "!mips_lra_flag")) + (const_string "yes") + (and (eq_attr "alternative" "1") + (match_test "mips_lra_flag")) + (const_string "yes") + (eq_attr "alternative" "2") + (const_string "yes")] + (const_string "no")))]) ;; The same idea applies here. The middle alternative needs one less ;; clobber than the final alternative, so we add "*?" as a counterweight. (define_insn "*mul_acc_si_r3900" - [(set (match_operand:SI 0 "register_operand" "=l*?*?,d*?,d?") - (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d") - (match_operand:SI 2 "register_operand" "d,d,d")) - (match_operand:SI 3 "register_operand" "0,l,d"))) - (clobber (match_scratch:SI 4 "=X,3,l")) - (clobber (match_scratch:SI 5 "=X,X,&d"))] + [(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d*?,d?") + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d,d") + (match_operand:SI 2 "register_operand" "d,d,d,d")) + (match_operand:SI 3 "register_operand" "0,0,l,d"))) + (clobber (match_scratch:SI 4 "=X,X,3,l")) + (clobber (match_scratch:SI 5 "=X,X,X,&d"))] "TARGET_MIPS3900 && !TARGET_MIPS16" "@ madd\t%1,%2 + madd\t%1,%2 madd\t%0,%1,%2 #" [(set_attr "type" "imadd") (set_attr "accum_in" "3") (set_attr "mode" "SI") - (set_attr "insn_count" "1,1,2")]) + (set_attr "insn_count" "1,1,1,2") + (set (attr "enabled") + (cond [(and (eq_attr "alternative" "0") + (match_test "!mips_lra_flag")) + (const_string "yes") + (and (eq_attr "alternative" "1") + (match_test "mips_lra_flag")) + (const_string "yes") + (eq_attr "alternative" "2,3") + (const_string "yes")] + (const_string "no")))]) ;; Split *mul_acc_si if both the source and destination accumulator ;; values are GPRs. @@ -1861,20 +1887,31 @@ ;; See the comment above *mul_add_si for details. (define_insn "*mul_sub_si" - [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?") - (minus:SI (match_operand:SI 1 "register_operand" "0,d") - (mult:SI (match_operand:SI 2 "register_operand" "d,d") - (match_operand:SI 3 "register_operand" "d,d")))) - (clobber (match_scratch:SI 4 "=X,l")) - (clobber (match_scratch:SI 5 "=X,&d"))] + [(set (match_operand:SI 0 "register_operand" "=l*?*?,l,d?") + (minus:SI (match_operand:SI 1 "register_operand" "0,0,d") + (mult:SI (match_operand:SI 2 "register_operand" "d,d,d") + (match_operand:SI 3 "register_operand" "d,d,d")))) + (clobber (match_scratch:SI 4 "=X,X,l")) + (clobber (match_scratch:SI 5 "=X,X,&d"))] "GENERATE_MADD_MSUB" "@ msub\t%2,%3 + msub\t%2,%3 #" [(set_attr "type" "imadd") (set_attr "accum_in" "1") (set_attr "mode" "SI") - (set_attr "insn_count" "1,2")]) + (set_attr "insn_count" "1,1,2") + (set (attr "enabled") + (cond [(and (eq_attr "alternative" "0") + (match_test "!mips_lra_flag")) + (const_string "yes") + (and (eq_attr "alternative" "1") + (match_test "mips_lra_flag")) + (const_string "yes") + (eq_attr "alternative" "2") + (const_string "yes")] + (const_string "no")))]) ;; Split *mul_sub_si if both the source and destination accumulator ;; values are GPRs. @@ -4141,7 +4178,10 @@ [(set (match_operand:DI 0 "register_operand" "=d") (match_operand:DI 1 "absolute_symbolic_operand" "")) (clobber (match_scratch:DI 2 "=&d"))] - "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS && cse_not_expected" + "!TARGET_MIPS16 + && TARGET_EXPLICIT_RELOCS + && ABI_HAS_64BIT_SYMBOLS + && cse_not_expected" "#" "&& reload_completed" [(set (match_dup 0) (high:DI (match_dup 3))) diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt index c992ceeb71d..dca4f808945 100644 --- a/gcc/config/mips/mips.opt +++ b/gcc/config/mips/mips.opt @@ -380,6 +380,10 @@ msynci Target Report Mask(SYNCI) Use synci instruction to invalidate i-cache +mlra +Target Report Var(mips_lra_flag) Init(1) Save +Use LRA instead of reload + mtune= Target RejectNegative Joined Var(mips_tune_option) ToLower Enum(mips_arch_opt_value) -mtune=PROCESSOR Optimize the output for PROCESSOR |