mips.h (mips_dwarf_regno): Declare.
authorNigel Stephens <nigel@mips.com>
Fri, 20 Jul 2007 15:41:29 +0000 (15:41 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 20 Jul 2007 15:41:29 +0000 (15:41 +0000)
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

gcc/ChangeLog
gcc/config/mips/constraints.md
gcc/config/mips/mips.c
gcc/config/mips/mips.h
gcc/config/mips/mips.md

index 5e3d0b150326ece9b4bc56a8c518bde7eb1e1350..ba96d763d9644b6958b4c596c39b3c542dea2c8b 100644 (file)
@@ -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
index 1388fc2cca1ed227bbd2b8c705bb2b5261e9cbce..5b184e2b69a4f0d772ec9fc1f5b42907b9a38e57 100644 (file)
 (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"
index b47f59fed2a5bf3f460ef808ed2167f161457933..ef9a8c068ca870f6b32b1f29a57e983905128d60 100644 (file)
@@ -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
index 3696ce7fe988a46e47c979b312715aea290fd4f8..46fa592ed8c30143cd56e17657258183892a006f 100644 (file)
@@ -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",                                                         \
index abac631848afc7184192614efdba41a1d181b73a..0a060aa19cf8f68bc93071588e9142f7ffc54469 100644 (file)
                     (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>")])