mips.h (HI_AND_FP_REGS): New register class.
authorRichard Henderson <rth@redhat.com>
Mon, 14 Jan 2002 23:27:59 +0000 (15:27 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 14 Jan 2002 23:27:59 +0000 (15:27 -0800)
        * config/mips/mips.h (HI_AND_FP_REGS): New register class.
        (CLASS_CANNOT_CHANGE_MODE): Disallow HI in little-endian mode.

From-SVN: r48852

gcc/ChangeLog
gcc/config/mips/mips.h

index e72f1f06bb1c50c7bac72ca445f597d731db307c..0f70375f877ddf29c3ae3f5e1667f737c8e806a4 100644 (file)
@@ -1,3 +1,8 @@
+2002-01-14  Richard Henderson  <rth@redhat.com>
+
+       * config/mips/mips.h (HI_AND_FP_REGS): New register class.
+       (CLASS_CANNOT_CHANGE_MODE): Disallow HI in little-endian mode.
+
 2002-01-14  Hans-Peter Nilsson  <hp@bitrange.com>
 
        * reload1.c (reload_combine): Pass reg_sum replacement through
index 95df8369566e9fbde7bba02b303956e48b3c76c0..a6e572e04a8644a64b5ebab10640e6bac109eb54 100644 (file)
@@ -1942,6 +1942,7 @@ enum reg_class
   HI_AND_GR_REGS,              /* union classes */
   LO_AND_GR_REGS,
   HILO_AND_GR_REGS,
+  HI_AND_FP_REGS,
   ST_REGS,                     /* status registers (fp status) */
   ALL_REGS,                    /* all registers */
   LIM_REG_CLASSES              /* max value + 1 */
@@ -1971,6 +1972,7 @@ enum reg_class
   "HI_AND_GR_REGS",                                                    \
   "LO_AND_GR_REGS",                                                    \
   "HILO_AND_GR_REGS",                                                  \
+  "HI_AND_FP_REGS",                                                    \
   "ST_REGS",                                                           \
   "ALL_REGS"                                                           \
 }
@@ -2002,6 +2004,7 @@ enum reg_class
   { 0xffffffff, 0x00000000, 0x00000001 },      /* union classes */     \
   { 0xffffffff, 0x00000000, 0x00000002 },                              \
   { 0xffffffff, 0x00000000, 0x00000004 },                              \
+  { 0x00000000, 0xffffffff, 0x00000001 },                              \
   { 0x00000000, 0x00000000, 0x000007f8 },      /* status registers */  \
   { 0xffffffff, 0xffffffff, 0x000007ff }       /* all registers */     \
 }
@@ -2229,10 +2232,19 @@ extern enum reg_class mips_char_to_class[256];
    : CLASS_UNITS (MODE, UNITS_PER_WORD))
 
 /* If defined, gives a class of registers that cannot be used as the
-   operand of a SUBREG that changes the mode of the object illegally.  */
+   operand of a SUBREG that changes the mode of the object illegally.
 
-#define CLASS_CANNOT_CHANGE_MODE \
-  (TARGET_FLOAT64 && ! TARGET_64BIT ? FP_REGS : NO_REGS)
+   When FP regs are larger than integer regs... Er, anyone remember what
+   goes wrong?
+
+   In little-endian mode, the hi-lo registers are numbered backwards,
+   so (subreg:SI (reg:DI hi) 0) gets the high word instead of the low
+   word as intended.  */
+
+#define CLASS_CANNOT_CHANGE_MODE                                       \
+  (TARGET_BIG_ENDIAN                                                   \
+   ? (TARGET_FLOAT64 && ! TARGET_64BIT ? FP_REGS : NO_REGS)            \
+   : (TARGET_FLOAT64 && ! TARGET_64BIT ? HI_AND_FP_REGS : HI_REG))
 
 /* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE.  */