Commit 48156a39 by Nigel Stephens Committed by Richard Sandiford

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
parent b644e061
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> 2007-07-20 Richard Sandiford <richard@codesourcery.com>
* config/arm/arm.md (movsi): Use can_create_pseudo_p instead of * config/arm/arm.md (movsi): Use can_create_pseudo_p instead of
......
...@@ -30,10 +30,10 @@ ...@@ -30,10 +30,10 @@
(define_register_constraint "f" "TARGET_HARD_FLOAT ? FP_REGS : NO_REGS" (define_register_constraint "f" "TARGET_HARD_FLOAT ? FP_REGS : NO_REGS"
"A floating-point register (if available).") "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.") "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.") "The @code{lo} register.")
(define_register_constraint "x" "MD_REGS" (define_register_constraint "x" "MD_REGS"
......
...@@ -639,6 +639,7 @@ char mips_print_operand_punct[256]; ...@@ -639,6 +639,7 @@ char mips_print_operand_punct[256];
/* Map GCC register number to debugger register number. */ /* Map GCC register number to debugger register number. */
int mips_dbx_regno[FIRST_PSEUDO_REGISTER]; 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. */ /* A copy of the original flag_delayed_branch: see override_options. */
static int mips_flag_delayed_branch; static int mips_flag_delayed_branch;
...@@ -676,7 +677,7 @@ const enum reg_class mips_regno_to_class[] = ...@@ -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, 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, ST_REGS,
ST_REGS, ST_REGS, ST_REGS, NO_REGS, ST_REGS, ST_REGS, ST_REGS, NO_REGS,
NO_REGS, ALL_REGS, ALL_REGS, NO_REGS, NO_REGS, ALL_REGS, ALL_REGS, NO_REGS,
...@@ -2991,13 +2992,8 @@ mips_subword (rtx op, int high_p) ...@@ -2991,13 +2992,8 @@ mips_subword (rtx op, int high_p)
else else
byte = 0; byte = 0;
if (REG_P (op)) if (FP_REG_RTX_P (op))
{ return gen_rtx_REG (word_mode, high_p ? REGNO (op) + 1 : REGNO (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 (MEM_P (op)) if (MEM_P (op))
return mips_rewrite_small_data (adjust_address (op, word_mode, byte)); return mips_rewrite_small_data (adjust_address (op, word_mode, byte));
...@@ -5293,7 +5289,13 @@ override_options (void) ...@@ -5293,7 +5289,13 @@ override_options (void)
Ignore the special purpose register numbers. */ Ignore the special purpose register numbers. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 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; start = GP_DBX_FIRST - GP_REG_FIRST;
for (i = GP_REG_FIRST; i <= GP_REG_LAST; i++) for (i = GP_REG_FIRST; i <= GP_REG_LAST; i++)
...@@ -5303,8 +5305,16 @@ override_options (void) ...@@ -5303,8 +5305,16 @@ override_options (void)
for (i = FP_REG_FIRST; i <= FP_REG_LAST; i++) for (i = FP_REG_FIRST; i <= FP_REG_LAST; i++)
mips_dbx_regno[i] = i + start; 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[HI_REGNUM] = MD_DBX_FIRST + 0;
mips_dbx_regno[LO_REGNUM] = MD_DBX_FIRST + 1; 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. */ /* Set up array giving whether a given register can hold a given mode. */
...@@ -5362,9 +5372,11 @@ override_options (void) ...@@ -5362,9 +5372,11 @@ override_options (void)
else if (ACC_REG_P (regno)) else if (ACC_REG_P (regno))
temp = (INTEGRAL_MODE_P (mode) temp = (INTEGRAL_MODE_P (mode)
&& size <= UNITS_PER_WORD * 2
&& (size <= UNITS_PER_WORD && (size <= UNITS_PER_WORD
|| (ACC_HI_REG_P (regno) || regno == MD_REG_FIRST
&& size == 2 * UNITS_PER_WORD))); || (DSP_ACC_REG_P (regno)
&& ((regno - DSP_ACC_REG_FIRST) & 1) == 0)));
else if (ALL_COP_REG_P (regno)) else if (ALL_COP_REG_P (regno))
temp = (class == MODE_INT && size <= UNITS_PER_WORD); temp = (class == MODE_INT && size <= UNITS_PER_WORD);
...@@ -5509,6 +5521,29 @@ override_options (void) ...@@ -5509,6 +5521,29 @@ override_options (void)
target_flags |= MASK_FIX_R4400; 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. */ /* Implement CONDITIONAL_REGISTER_USAGE. */
void void
...@@ -5570,6 +5605,15 @@ mips_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) for (regno = FP_REG_FIRST + 21; regno <= FP_REG_FIRST + 31; regno+=2)
call_really_used_regs[regno] = call_used_regs[regno] = 1; 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. */ /* Allocate a chunk of memory for per-function machine-dependent data. */
...@@ -8485,17 +8529,6 @@ mips_cannot_change_mode_class (enum machine_mode from, ...@@ -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)) if (MAX_FPRS_PER_FMT > 1 && reg_classes_intersect_p (FP_REGS, class))
return true; 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 /* gcc assumes that each word of a multiword register can be accessed
......
...@@ -126,7 +126,8 @@ extern int set_nomacro; /* # of nested .set nomacro's */ ...@@ -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_noat; /* # of nested .set noat's */
extern int set_volatile; /* # of nested .set volatile's */ extern int set_volatile; /* # of nested .set volatile's */
extern int mips_branch_likely; /* emit 'l' after br (branch likely) */ 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 bool mips_split_p[];
extern GTY(()) rtx cmp_operands[2]; extern GTY(()) rtx cmp_operands[2];
extern enum processor_type mips_arch; /* which cpu to codegen for */ extern enum processor_type mips_arch; /* which cpu to codegen for */
...@@ -1010,11 +1011,10 @@ extern const struct mips_rtx_cost_data *mips_cost; ...@@ -1010,11 +1011,10 @@ extern const struct mips_rtx_cost_data *mips_cost;
#define DBX_CONTIN_LENGTH 1500 #define DBX_CONTIN_LENGTH 1500
/* How to renumber registers for dbx and gdb. */ /* 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. */ /* The mapping from gcc register number to DWARF 2 CFA column number. */
#define DWARF_FRAME_REGNUM(REG) \ #define DWARF_FRAME_REGNUM(REGNO) mips_dwarf_regno[REGNO]
((REG) == DWARF_ALT_FRAME_RETURN_COLUMN ? INVALID_REGNUM : (REG))
/* The DWARF 2 CFA column which tracks the return address. */ /* The DWARF 2 CFA column which tracks the return address. */
#define DWARF_FRAME_RETURN_COLUMN (GP_REG_FIRST + 31) #define DWARF_FRAME_RETURN_COLUMN (GP_REG_FIRST + 31)
...@@ -1393,14 +1393,8 @@ extern const struct mips_rtx_cost_data *mips_cost; ...@@ -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 DSP_ACC_REG_NUM (DSP_ACC_REG_LAST - DSP_ACC_REG_FIRST + 1)
#define AT_REGNUM (GP_REG_FIRST + 1) #define AT_REGNUM (GP_REG_FIRST + 1)
#define HI_REGNUM (MD_REG_FIRST + 0) #define HI_REGNUM (TARGET_BIG_ENDIAN ? MD_REG_FIRST : MD_REG_FIRST + 1)
#define LO_REGNUM (MD_REG_FIRST + 1) #define LO_REGNUM (TARGET_BIG_ENDIAN ? MD_REG_FIRST + 1 : MD_REG_FIRST)
#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)
/* FPSW_REGNUM is the single condition code used if !ISA_HAS_8CC. /* 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 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; ...@@ -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. */ /* Test if REGNO is hi, lo, or one of the 6 new DSP accumulators. */
#define ACC_REG_P(REGNO) \ #define ACC_REG_P(REGNO) \
(MD_REG_P (REGNO) || DSP_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))) #define FP_REG_RTX_P(X) (REG_P (X) && FP_REG_P (REGNO (X)))
...@@ -1562,8 +1552,8 @@ enum reg_class ...@@ -1562,8 +1552,8 @@ enum reg_class
LEA_REGS, /* Every GPR except $25 */ LEA_REGS, /* Every GPR except $25 */
GR_REGS, /* integer registers */ GR_REGS, /* integer registers */
FP_REGS, /* floating point registers */ FP_REGS, /* floating point registers */
HI_REG, /* hi register */ MD0_REG, /* first multiply/divide register */
LO_REG, /* lo register */ MD1_REG, /* second multiply/divide register */
MD_REGS, /* multiply/divide registers (hi/lo) */ MD_REGS, /* multiply/divide registers (hi/lo) */
COP0_REGS, /* generic coprocessor classes */ COP0_REGS, /* generic coprocessor classes */
COP2_REGS, COP2_REGS,
...@@ -1603,8 +1593,8 @@ enum reg_class ...@@ -1603,8 +1593,8 @@ enum reg_class
"LEA_REGS", \ "LEA_REGS", \
"GR_REGS", \ "GR_REGS", \
"FP_REGS", \ "FP_REGS", \
"HI_REG", \ "MD0_REG", \
"LO_REG", \ "MD1_REG", \
"MD_REGS", \ "MD_REGS", \
/* coprocessor registers */ \ /* coprocessor registers */ \
"COP0_REGS", \ "COP0_REGS", \
......
...@@ -4059,12 +4059,9 @@ ...@@ -4059,12 +4059,9 @@
(match_operand:GPR 2 "register_operand" "l,h")] (match_operand:GPR 2 "register_operand" "l,h")]
UNSPEC_MFHILO))] UNSPEC_MFHILO))]
"ISA_HAS_MACCHI" "ISA_HAS_MACCHI"
{ "@
if (REGNO (operands[1]) == HI_REGNUM) <d>macchi\t%0,%.,%.
return "<d>macchi\t%0,%.,%."; <d>macc\t%0,%.,%."
else
return "<d>macc\t%0,%.,%.";
}
[(set_attr "type" "mfhilo") [(set_attr "type" "mfhilo")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
......
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