diff options
author | Nigel Stephens <nigel@mips.com> | 2007-07-20 15:41:29 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2007-07-20 15:41:29 +0000 |
commit | 48156a3983a1d75aa5e797c42e2a30a2bb341f75 (patch) | |
tree | c9f674530498f77de7b6d6883767b9023b345c25 | |
parent | b644e061999f6186d4f0474f3dc2da3370869986 (diff) | |
download | gcc-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
-rw-r--r-- | gcc/ChangeLog | 24 | ||||
-rw-r--r-- | gcc/config/mips/constraints.md | 4 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 77 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 30 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 9 |
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>")]) |