summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog29
-rw-r--r--gcc/config/mips/constraints.md2
-rw-r--r--gcc/config/mips/mips.c57
-rw-r--r--gcc/config/mips/mips.h8
-rw-r--r--gcc/config/mips/mips.md84
-rw-r--r--gcc/config/mips/mips.opt4
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