]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - gcc/config/pa/pa32-regs.h
Imported gcc-4.4.3
[msp430-gcc.git] / gcc / config / pa / pa32-regs.h
index 2cd015452390f0deed7b8036eb3cfd3549bb9708..4463c631d38a2e05438210fa51a674e78f485ebc 100644 (file)
@@ -15,7 +15,7 @@
    HP-PA 1.1 has 32 fullword registers and 32 floating point
    registers. However, the floating point registers behave
    differently: the left and right halves of registers are addressable
-   as 32 bit registers. So, we will set things up like the 68k which
+   as 32-bit registers. So, we will set things up like the 68k which
    has different fp units: define separate register sets for the 1.0
    and 1.1 fp units.  */
 
    registers will generally not be allocated across a call).
 
    Experimentation has shown slightly better results by allocating
-   FP registers first.  
+   FP registers first.  We allocate the caller-saved registers more
+   or less in reverse order to their allocation as arguments.
 
    FP registers are ordered so that all L registers are selected before
    R registers.  This works around a false dependency interlock on the
  {                                     \
   /* caller-saved fp regs.  */         \
   68, 70, 72, 74, 76, 78, 80, 82,      \
-  84, 86, 40, 42, 44, 46, 32, 34,      \
-  36, 38,                              \
+  84, 86, 40, 42, 44, 46, 38, 36,      \
+  34, 32,                              \
   69, 71, 73, 75, 77, 79, 81, 83,      \
-  85, 87, 41, 43, 45, 47, 33, 35,      \
-  37, 39,                              \
+  85, 87, 41, 43, 45, 47, 39, 37,      \
+  35, 33,                              \
   /* caller-saved general regs.  */    \
-  19, 20, 21, 22, 23, 24, 25, 26,      \
-  27, 28, 29, 31,  2,                  \
+  28, 19, 20, 21, 22, 31, 27, 29,      \
+  23, 24, 25, 26,  2,                  \
   /* callee-saved fp regs.  */         \
   48, 50, 52, 54, 56, 58, 60, 62,      \
   64, 66,                              \
    This is ordinarily the length in words of a value of mode MODE
    but can be less for certain modes in special long registers.
 
-   On the HP-PA, ordinary registers hold 32 bits worth;
-   The floating point registers are 64 bits wide. Snake fp regs are 32
-   bits wide */
+   On the HP-PA, general registers are 32 bits wide.  The floating
+   point registers are 64 bits wide.  Snake fp regs are treated as
+   32 bits wide since the left and right parts are independently
+   accessible.  */
 #define HARD_REGNO_NREGS(REGNO, MODE)                                  \
   (FP_REGNO_P (REGNO)                                                  \
-   ? (!TARGET_PA_11 ? 1 : (GET_MODE_SIZE (MODE) + 4 - 1) / 4)          \
-   : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+   ? (!TARGET_PA_11                                                    \
+      ? COMPLEX_MODE_P (MODE) ? 2 : 1                                  \
+      : (GET_MODE_SIZE (MODE) + 4 - 1) / 4)                            \
+   : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* There are no instructions that use DImode in PA 1.0, so we only
+   allow it in PA 1.1 and later.  */
+#define VALID_FP_MODE_P(MODE)                                          \
+  ((MODE) == SFmode || (MODE) == DFmode                                        \
+   || (MODE) == SCmode || (MODE) == DCmode                             \
+   || (MODE) == SImode || (TARGET_PA_11 && (MODE) == DImode))
 
 /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
-   On the HP-PA, the cpu registers can hold any mode.  We
-   force this to be an even register is it cannot hold the full mode.  */
+
+   On the HP-PA, the cpu registers can hold any mode that fits in 32 bits.
+   For the 64-bit modes, we choose a set of non-overlapping general registers
+   that includes the incoming arguments and the return value.  We specify a
+   set with no overlaps so that we don't have to specify that the destination
+   register is an early clobber in patterns using this mode.  Except for the
+   return value, the starting registers are odd.  For 128 and 256 bit modes,
+   we similarly specify non-overlapping sets of cpu registers.  However,
+   there aren't any patterns defined for modes larger than 64 bits at the
+   moment.
+
+   We limit the modes allowed in the floating point registers to the
+   set of modes used in the machine definition.  In addition, we allow
+   the complex modes SCmode and DCmode.  The real and imaginary parts
+   of complex modes are allocated to separate registers.  This might
+   allow patterns to be defined in the future to operate on these values.
+
+   The PA 2.0 architecture specifies that quad-precision floating-point
+   values should start on an even floating point register.  Thus, we
+   choose non-overlapping sets of registers starting on even register
+   boundaries for large modes.  However, there is currently no support
+   in the machine definition for modes larger than 64 bits.  TFmode is
+   supported under HP-UX using libcalls.  Since TFmode values are passed
+   by reference, they never need to be loaded into the floating-point
+   registers.  */
 #define HARD_REGNO_MODE_OK(REGNO, MODE) \
   ((REGNO) == 0 ? (MODE) == CCmode || (MODE) == CCFPmode               \
-   /* On 1.0 machines, don't allow wide non-fp modes in fp regs.  */   \
    : !TARGET_PA_11 && FP_REGNO_P (REGNO)                               \
-     ? GET_MODE_SIZE (MODE) <= 4 || GET_MODE_CLASS (MODE) == MODE_FLOAT        \
+     ? (VALID_FP_MODE_P (MODE)                                         \
+       && (GET_MODE_SIZE (MODE) <= 8                                   \
+           || (GET_MODE_SIZE (MODE) == 16 && ((REGNO) & 3) == 0)))     \
    : FP_REGNO_P (REGNO)                                                        \
-     ? GET_MODE_SIZE (MODE) <= 4 || ((REGNO) & 1) == 0                 \
-   /* Make wide modes be in aligned registers.  */                     \
+     ? (VALID_FP_MODE_P (MODE)                                         \
+       && (GET_MODE_SIZE (MODE) <= 4                                   \
+           || (GET_MODE_SIZE (MODE) == 8 && ((REGNO) & 1) == 0)        \
+           || (GET_MODE_SIZE (MODE) == 16 && ((REGNO) & 3) == 0)       \
+           || (GET_MODE_SIZE (MODE) == 32 && ((REGNO) & 7) == 0)))     \
    : (GET_MODE_SIZE (MODE) <= UNITS_PER_WORD                           \
-      || (GET_MODE_SIZE (MODE) <= 4 * UNITS_PER_WORD && ((REGNO) & 1) == 0)))
+      || (GET_MODE_SIZE (MODE) == 2 * UNITS_PER_WORD                   \
+         && ((((REGNO) & 1) == 1 && (REGNO) <= 25) || (REGNO) == 28))  \
+      || (GET_MODE_SIZE (MODE) == 4 * UNITS_PER_WORD                   \
+         && ((REGNO) & 3) == 3 && (REGNO) <= 23)                       \
+      || (GET_MODE_SIZE (MODE) == 8 * UNITS_PER_WORD                   \
+         && ((REGNO) & 7) == 3 && (REGNO) <= 19)))
 
 /* How to renumber registers for dbx and gdb.
 
@@ -223,7 +266,7 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
 
 #define N_REG_CLASSES (int) LIM_REG_CLASSES
 
-/* Give names of register classes as strings for dump file.   */
+/* Give names of register classes as strings for dump file.  */
 
 #define REG_CLASS_NAMES \
   {"NO_REGS", "R1_REGS", "GENERAL_REGS", "FPUPPER_REGS", "FP_REGS", \
@@ -244,16 +287,25 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
   {0x00000000, 0x00000000, 0x01000000},        /* SHIFT_REGS */                \
   {0xfffffffe, 0xffffffff, 0x01ffffff}}        /* ALL_REGS */
 
-/* This may not actually be necessary anymore.  But until I can prove
-   otherwise it will stay.  */
-#define CLASS_CANNOT_CHANGE_MODE       NO_REGS
+/* The following macro defines cover classes for Integrated Register
+   Allocator.  Cover classes is a set of non-intersected register
+   classes covering all hard registers used for register allocation
+   purpose.  Any move between two registers of a cover class should be
+   cheaper than load or store of the registers.  The macro value is
+   array of register classes with LIM_REG_CLASSES used as the end
+   marker.  */
+
+#define IRA_COVER_CLASSES                                              \
+{                                                                      \
+  GENERAL_REGS, FP_REGS, SHIFT_REGS, LIM_REG_CLASSES                   \
+}
+
+/* Defines invalid mode changes.  */
 
-/* Defines illegal mode changes for CLASS_CANNOT_CHANGE_MODE.  */
-#define CLASS_CANNOT_CHANGE_MODE_P(FROM,TO) \
-  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO))
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+  pa_cannot_change_mode_class (FROM, TO, CLASS)
 
-/* The same information, inverted:
-   Return the class number of the smallest class containing
+/* Return the class number of the smallest class containing
    reg number REGNO.  This could be a conditional expression
    or could index an array.  */
 
@@ -263,25 +315,15 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
    : (REGNO) < 32 ? GENERAL_REGS                                       \
    : (REGNO) < 56 ? FP_REGS                                            \
    : (REGNO) < 88 ? FPUPPER_REGS                                       \
-   : (REGNO) < 88 ? FPUPPER_REGS                                       \
    : SHIFT_REGS)
 
-/* Get reg_class from a letter such as appears in the machine description.  */
-/* Keep 'x' for backward compatibility with user asm.   */
-#define REG_CLASS_FROM_LETTER(C) \
-  ((C) == 'f' ? FP_REGS :                                      \
-   (C) == 'y' ? FPUPPER_REGS :                                 \
-   (C) == 'y' ? FPUPPER_REGS :                                 \
-   (C) == 'x' ? FP_REGS :                                      \
-   (C) == 'q' ? SHIFT_REGS :                                   \
-   (C) == 'a' ? R1_REGS :                                      \
-   (C) == 'Z' ? ALL_REGS : NO_REGS)
-
 /* Return the maximum number of consecutive registers
    needed to represent mode MODE in a register of class CLASS.  */
 #define CLASS_MAX_NREGS(CLASS, MODE)                                   \
   ((CLASS) == FP_REGS || (CLASS) == FPUPPER_REGS                       \
-   ? (!TARGET_PA_11 ? 1 : (GET_MODE_SIZE (MODE) + 4 - 1) / 4)          \
+   ? (!TARGET_PA_11                                                    \
+      ? COMPLEX_MODE_P (MODE) ? 2 : 1                                  \
+      : (GET_MODE_SIZE (MODE) + 4 - 1) / 4)                            \
    : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
 
 /* 1 if N is a possible register number for function argument passing.  */