aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNigel Stephens <nigel@mips.com>2007-07-20 15:41:29 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2007-07-20 15:41:29 +0000
commit48156a3983a1d75aa5e797c42e2a30a2bb341f75 (patch)
treec9f674530498f77de7b6d6883767b9023b345c25 /gcc
parentb644e061999f6186d4f0474f3dc2da3370869986 (diff)
downloadgcc-48156a3983a1d75aa5e797c42e2a30a2bb341f75.zip
gcc-48156a3983a1d75aa5e797c42e2a30a2bb341f75.tar.gz
gcc-48156a3983a1d75aa5e797c42e2a30a2bb341f75.tar.bz2
mips.h (mips_dwarf_regno): Declare.
gcc/ 2007-07-20 Nigel Stephens <nigel@mips.com> Richard Sandiford <richard@codesourcery.com> * config/mips/mips.h (mips_dwarf_regno): Declare. (DBX_REGISTER_NUMBER): Remove redundant brackets. (HI_REGNUM, LO_REGNUM): Define in an endian-dependent way. (AC1HI_REGNUM, AC1LO_REGNUM, AC2HI_REGNUM, AC2LO_REGNUM) (AC3HI_REGNUM, AC3LO_REGNUM, ACC_HI_REG_P): Delete. (reg_class): Rename HI_REG to MD0_REG and LO_REG to MD1_REG. (REG_CLASS_NAMES): Update accordingly. * config/mips/mips.c (mips_dwarf_regno): New array. (mips_regno_to_class): Rename HI_REG to MD0_REG and LO_REG to MD1_REG. (mips_subword): Remove special handling for accumulator registers. (override_options): Initiailize mips_dwarf_regno. Remove use of ACC_HI_REG_P. (mips_swap_registers): New function. (mips_conditional_register_usage): Swap accumulator registers around if TARGET_LITTLE_ENDIAN. (mips_cannot_change_mode_class): Remove special treatment of ACC_REGS. * config/mips/constraints.md (h, l): Use the endianness to choose between MD0_REG and MD1_REG. * config/mips/mips.md (*mfhilo_<mode>_macc): Use a fixed-string, alternative-dependent template. Co-Authored-By: Richard Sandiford <richard@codesourcery.com> From-SVN: r126801
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog24
-rw-r--r--gcc/config/mips/constraints.md4
-rw-r--r--gcc/config/mips/mips.c77
-rw-r--r--gcc/config/mips/mips.h30
-rw-r--r--gcc/config/mips/mips.md9
5 files changed, 94 insertions, 50 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5e3d0b1..ba96d76 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,27 @@
+2007-07-20 Nigel Stephens <nigel@mips.com>
+ Richard Sandiford <richard@codesourcery.com>
+
+ * config/mips/mips.h (mips_dwarf_regno): Declare.
+ (DBX_REGISTER_NUMBER): Remove redundant brackets.
+ (HI_REGNUM, LO_REGNUM): Define in an endian-dependent way.
+ (AC1HI_REGNUM, AC1LO_REGNUM, AC2HI_REGNUM, AC2LO_REGNUM)
+ (AC3HI_REGNUM, AC3LO_REGNUM, ACC_HI_REG_P): Delete.
+ (reg_class): Rename HI_REG to MD0_REG and LO_REG to MD1_REG.
+ (REG_CLASS_NAMES): Update accordingly.
+ * config/mips/mips.c (mips_dwarf_regno): New array.
+ (mips_regno_to_class): Rename HI_REG to MD0_REG and LO_REG to MD1_REG.
+ (mips_subword): Remove special handling for accumulator registers.
+ (override_options): Initiailize mips_dwarf_regno. Remove use
+ of ACC_HI_REG_P.
+ (mips_swap_registers): New function.
+ (mips_conditional_register_usage): Swap accumulator registers
+ around if TARGET_LITTLE_ENDIAN.
+ (mips_cannot_change_mode_class): Remove special treatment of ACC_REGS.
+ * config/mips/constraints.md (h, l): Use the endianness to choose
+ between MD0_REG and MD1_REG.
+ * config/mips/mips.md (*mfhilo_<mode>_macc): Use a fixed-string,
+ alternative-dependent template.
+
2007-07-20 Richard Sandiford <richard@codesourcery.com>
* config/arm/arm.md (movsi): Use can_create_pseudo_p instead of
diff --git a/gcc/config/mips/constraints.md b/gcc/config/mips/constraints.md
index 1388fc2..5b184e2 100644
--- a/gcc/config/mips/constraints.md
+++ b/gcc/config/mips/constraints.md
@@ -30,10 +30,10 @@
(define_register_constraint "f" "TARGET_HARD_FLOAT ? FP_REGS : NO_REGS"
"A floating-point register (if available).")
-(define_register_constraint "h" "HI_REG"
+(define_register_constraint "h" "TARGET_BIG_ENDIAN ? MD0_REG : MD1_REG"
"The @code{hi} register.")
-(define_register_constraint "l" "LO_REG"
+(define_register_constraint "l" "TARGET_BIG_ENDIAN ? MD1_REG : MD0_REG"
"The @code{lo} register.")
(define_register_constraint "x" "MD_REGS"
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index b47f59f..ef9a8c0 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -639,6 +639,7 @@ char mips_print_operand_punct[256];
/* Map GCC register number to debugger register number. */
int mips_dbx_regno[FIRST_PSEUDO_REGISTER];
+int mips_dwarf_regno[FIRST_PSEUDO_REGISTER];
/* A copy of the original flag_delayed_branch: see override_options. */
static int mips_flag_delayed_branch;
@@ -676,7 +677,7 @@ const enum reg_class mips_regno_to_class[] =
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
FP_REGS, FP_REGS, FP_REGS, FP_REGS,
- HI_REG, LO_REG, NO_REGS, ST_REGS,
+ MD0_REG, MD1_REG, NO_REGS, ST_REGS,
ST_REGS, ST_REGS, ST_REGS, ST_REGS,
ST_REGS, ST_REGS, ST_REGS, NO_REGS,
NO_REGS, ALL_REGS, ALL_REGS, NO_REGS,
@@ -2991,13 +2992,8 @@ mips_subword (rtx op, int high_p)
else
byte = 0;
- if (REG_P (op))
- {
- if (FP_REG_P (REGNO (op)))
- return gen_rtx_REG (word_mode, high_p ? REGNO (op) + 1 : REGNO (op));
- if (ACC_HI_REG_P (REGNO (op)))
- return gen_rtx_REG (word_mode, high_p ? REGNO (op) : REGNO (op) + 1);
- }
+ if (FP_REG_RTX_P (op))
+ return gen_rtx_REG (word_mode, high_p ? REGNO (op) + 1 : REGNO (op));
if (MEM_P (op))
return mips_rewrite_small_data (adjust_address (op, word_mode, byte));
@@ -5293,7 +5289,13 @@ override_options (void)
Ignore the special purpose register numbers. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- mips_dbx_regno[i] = -1;
+ {
+ mips_dbx_regno[i] = INVALID_REGNUM;
+ if (GP_REG_P (i) || FP_REG_P (i) || ALL_COP_REG_P (i))
+ mips_dwarf_regno[i] = i;
+ else
+ mips_dwarf_regno[i] = INVALID_REGNUM;
+ }
start = GP_DBX_FIRST - GP_REG_FIRST;
for (i = GP_REG_FIRST; i <= GP_REG_LAST; i++)
@@ -5303,8 +5305,16 @@ override_options (void)
for (i = FP_REG_FIRST; i <= FP_REG_LAST; i++)
mips_dbx_regno[i] = i + start;
+ /* HI and LO debug registers use big-endian ordering. */
mips_dbx_regno[HI_REGNUM] = MD_DBX_FIRST + 0;
mips_dbx_regno[LO_REGNUM] = MD_DBX_FIRST + 1;
+ mips_dwarf_regno[HI_REGNUM] = MD_REG_FIRST + 0;
+ mips_dwarf_regno[LO_REGNUM] = MD_REG_FIRST + 1;
+ for (i = DSP_ACC_REG_FIRST; i <= DSP_ACC_REG_LAST; i += 2)
+ {
+ mips_dwarf_regno[i + TARGET_LITTLE_ENDIAN] = i;
+ mips_dwarf_regno[i + TARGET_BIG_ENDIAN] = i + 1;
+ }
/* Set up array giving whether a given register can hold a given mode. */
@@ -5362,9 +5372,11 @@ override_options (void)
else if (ACC_REG_P (regno))
temp = (INTEGRAL_MODE_P (mode)
+ && size <= UNITS_PER_WORD * 2
&& (size <= UNITS_PER_WORD
- || (ACC_HI_REG_P (regno)
- && size == 2 * UNITS_PER_WORD)));
+ || regno == MD_REG_FIRST
+ || (DSP_ACC_REG_P (regno)
+ && ((regno - DSP_ACC_REG_FIRST) & 1) == 0)));
else if (ALL_COP_REG_P (regno))
temp = (class == MODE_INT && size <= UNITS_PER_WORD);
@@ -5509,6 +5521,29 @@ override_options (void)
target_flags |= MASK_FIX_R4400;
}
+/* Swap the register information for registers I and I + 1, which
+ currently have the wrong endianness. Note that the registers'
+ fixedness and call-clobberedness might have been set on the
+ command line. */
+
+static void
+mips_swap_registers (unsigned int i)
+{
+ int tmpi;
+ const char *tmps;
+
+#define SWAP_INT(X, Y) (tmpi = (X), (X) = (Y), (Y) = tmpi)
+#define SWAP_STRING(X, Y) (tmps = (X), (X) = (Y), (Y) = tmps)
+
+ SWAP_INT (fixed_regs[i], fixed_regs[i + 1]);
+ SWAP_INT (call_used_regs[i], call_used_regs[i + 1]);
+ SWAP_INT (call_really_used_regs[i], call_really_used_regs[i + 1]);
+ SWAP_STRING (reg_names[i], reg_names[i + 1]);
+
+#undef SWAP_STRING
+#undef SWAP_INT
+}
+
/* Implement CONDITIONAL_REGISTER_USAGE. */
void
@@ -5570,6 +5605,15 @@ mips_conditional_register_usage (void)
for (regno = FP_REG_FIRST + 21; regno <= FP_REG_FIRST + 31; regno+=2)
call_really_used_regs[regno] = call_used_regs[regno] = 1;
}
+ /* Make sure that double-register accumulator values are correctly
+ ordered for the current endianness. */
+ if (TARGET_LITTLE_ENDIAN)
+ {
+ int regno;
+ mips_swap_registers (MD_REG_FIRST);
+ for (regno = DSP_ACC_REG_FIRST; regno <= DSP_ACC_REG_LAST; regno += 2)
+ mips_swap_registers (regno);
+ }
}
/* Allocate a chunk of memory for per-function machine-dependent data. */
@@ -8485,17 +8529,6 @@ mips_cannot_change_mode_class (enum machine_mode from,
if (MAX_FPRS_PER_FMT > 1 && reg_classes_intersect_p (FP_REGS, class))
return true;
}
- else
- {
- /* LO_REGNO == HI_REGNO + 1, so if a multi-word value is stored
- in LO and HI, the high word always comes first. We therefore
- can't allow values stored in HI to change between single-word
- and multi-word modes.
- This rule applies to both the original HI/LO pair and the new
- DSP accumulators. */
- if (reg_classes_intersect_p (ACC_REGS, class))
- return true;
- }
}
/* gcc assumes that each word of a multiword register can be accessed
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 3696ce7..46fa592 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -126,7 +126,8 @@ extern int set_nomacro; /* # of nested .set nomacro's */
extern int set_noat; /* # of nested .set noat's */
extern int set_volatile; /* # of nested .set volatile's */
extern int mips_branch_likely; /* emit 'l' after br (branch likely) */
-extern int mips_dbx_regno[]; /* Map register # to debug register # */
+extern int mips_dbx_regno[];
+extern int mips_dwarf_regno[];
extern bool mips_split_p[];
extern GTY(()) rtx cmp_operands[2];
extern enum processor_type mips_arch; /* which cpu to codegen for */
@@ -1010,11 +1011,10 @@ extern const struct mips_rtx_cost_data *mips_cost;
#define DBX_CONTIN_LENGTH 1500
/* How to renumber registers for dbx and gdb. */
-#define DBX_REGISTER_NUMBER(REGNO) mips_dbx_regno[ (REGNO) ]
+#define DBX_REGISTER_NUMBER(REGNO) mips_dbx_regno[REGNO]
/* The mapping from gcc register number to DWARF 2 CFA column number. */
-#define DWARF_FRAME_REGNUM(REG) \
- ((REG) == DWARF_ALT_FRAME_RETURN_COLUMN ? INVALID_REGNUM : (REG))
+#define DWARF_FRAME_REGNUM(REGNO) mips_dwarf_regno[REGNO]
/* The DWARF 2 CFA column which tracks the return address. */
#define DWARF_FRAME_RETURN_COLUMN (GP_REG_FIRST + 31)
@@ -1393,14 +1393,8 @@ extern const struct mips_rtx_cost_data *mips_cost;
#define DSP_ACC_REG_NUM (DSP_ACC_REG_LAST - DSP_ACC_REG_FIRST + 1)
#define AT_REGNUM (GP_REG_FIRST + 1)
-#define HI_REGNUM (MD_REG_FIRST + 0)
-#define LO_REGNUM (MD_REG_FIRST + 1)
-#define AC1HI_REGNUM (DSP_ACC_REG_FIRST + 0)
-#define AC1LO_REGNUM (DSP_ACC_REG_FIRST + 1)
-#define AC2HI_REGNUM (DSP_ACC_REG_FIRST + 2)
-#define AC2LO_REGNUM (DSP_ACC_REG_FIRST + 3)
-#define AC3HI_REGNUM (DSP_ACC_REG_FIRST + 4)
-#define AC3LO_REGNUM (DSP_ACC_REG_FIRST + 5)
+#define HI_REGNUM (TARGET_BIG_ENDIAN ? MD_REG_FIRST : MD_REG_FIRST + 1)
+#define LO_REGNUM (TARGET_BIG_ENDIAN ? MD_REG_FIRST + 1 : MD_REG_FIRST)
/* FPSW_REGNUM is the single condition code used if !ISA_HAS_8CC.
If ISA_HAS_8CC, it should not be used, and an arbitrary ST_REG
@@ -1431,10 +1425,6 @@ extern const struct mips_rtx_cost_data *mips_cost;
/* Test if REGNO is hi, lo, or one of the 6 new DSP accumulators. */
#define ACC_REG_P(REGNO) \
(MD_REG_P (REGNO) || DSP_ACC_REG_P (REGNO))
-/* Test if REGNO is HI or the first register of 3 new DSP accumulator pairs. */
-#define ACC_HI_REG_P(REGNO) \
- ((REGNO) == HI_REGNUM || (REGNO) == AC1HI_REGNUM || (REGNO) == AC2HI_REGNUM \
- || (REGNO) == AC3HI_REGNUM)
#define FP_REG_RTX_P(X) (REG_P (X) && FP_REG_P (REGNO (X)))
@@ -1562,8 +1552,8 @@ enum reg_class
LEA_REGS, /* Every GPR except $25 */
GR_REGS, /* integer registers */
FP_REGS, /* floating point registers */
- HI_REG, /* hi register */
- LO_REG, /* lo register */
+ MD0_REG, /* first multiply/divide register */
+ MD1_REG, /* second multiply/divide register */
MD_REGS, /* multiply/divide registers (hi/lo) */
COP0_REGS, /* generic coprocessor classes */
COP2_REGS,
@@ -1603,8 +1593,8 @@ enum reg_class
"LEA_REGS", \
"GR_REGS", \
"FP_REGS", \
- "HI_REG", \
- "LO_REG", \
+ "MD0_REG", \
+ "MD1_REG", \
"MD_REGS", \
/* coprocessor registers */ \
"COP0_REGS", \
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index abac631..0a060aa 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -4059,12 +4059,9 @@
(match_operand:GPR 2 "register_operand" "l,h")]
UNSPEC_MFHILO))]
"ISA_HAS_MACCHI"
-{
- if (REGNO (operands[1]) == HI_REGNUM)
- return "<d>macchi\t%0,%.,%.";
- else
- return "<d>macc\t%0,%.,%.";
-}
+ "@
+ <d>macchi\t%0,%.,%.
+ <d>macc\t%0,%.,%."
[(set_attr "type" "mfhilo")
(set_attr "mode" "<MODE>")])