re PR target/21723 (ICE while building libgfortran)
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>
Tue, 5 Jul 2005 01:57:01 +0000 (01:57 +0000)
committerJohn David Anglin <danglin@gcc.gnu.org>
Tue, 5 Jul 2005 01:57:01 +0000 (01:57 +0000)
PR target/21723
* pa.md: Remove fcpy alternative from movhi and movqi patterns.
* pa32-regs.h (HARD_REGNO_NREGS): Return two floating point registers
for complex modes when generating code for PA 1.0.
(VALID_FP_MODE_P): New macro.
(HARD_REGNO_MODE_OK): Use VALID_FP_MODE_P.  Use non-overlapping register
sets for all general and floating point modes.  Align wide floating
point modes to even register boundaries to comply with architectural
requirements.
(CLASS_MAX_NREGS): Update to align with change to HARD_REGNO_NREGS.
* pa64-regs.h (HARD_REGNO_NREGS): Update comment and formatting.
(VALID_FP_MODE_P): New macro.
(HARD_REGNO_MODE_OK): Use VALID_FP_MODE_P.  Use non-overlapping register
sets for all general and floating point modes.  Align wide floating
point modes to even register boundaries to comply with architectural
requirements.

From-SVN: r101613

gcc/ChangeLog
gcc/config/pa/pa.md
gcc/config/pa/pa32-regs.h
gcc/config/pa/pa64-regs.h

index 60a081b..00eaf5d 100644 (file)
@@ -1,3 +1,22 @@
+2005-07-04  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       PR target/21723
+       * pa.md: Remove fcpy alternative from movhi and movqi patterns.
+       * pa32-regs.h (HARD_REGNO_NREGS): Return two floating point registers
+       for complex modes when generating code for PA 1.0.
+       (VALID_FP_MODE_P): New macro.
+       (HARD_REGNO_MODE_OK): Use VALID_FP_MODE_P.  Use non-overlapping register
+       sets for all general and floating point modes.  Align wide floating
+       point modes to even register boundaries to comply with architectural
+       requirements.
+       (CLASS_MAX_NREGS): Update to align with change to HARD_REGNO_NREGS.
+       * pa64-regs.h (HARD_REGNO_NREGS): Update comment and formatting.
+       (VALID_FP_MODE_P): New macro.
+       (HARD_REGNO_MODE_OK): Use VALID_FP_MODE_P.  Use non-overlapping register
+       sets for all general and floating point modes.  Align wide floating
+       point modes to even register boundaries to comply with architectural
+       requirements.
+
 2005-07-04  Diego Novillo  <dnovillo@redhat.com>
 
        * tree-dump.c (dump_files): Initialize dump number for .cgraph
index de5b75b..f724209 100644 (file)
 
 (define_insn ""
   [(set (match_operand:HI 0 "move_dest_operand"
-                         "=r,r,r,r,r,Q,!*q,!r,!*f")
+                         "=r,r,r,r,r,Q,!*q,!r")
        (match_operand:HI 1 "move_src_operand"
-                         "r,J,N,K,RQ,rM,!rM,!*q,!*fM"))]
+                         "r,J,N,K,RQ,rM,!rM,!*q"))]
   "register_operand (operands[0], HImode)
    || reg_or_0_operand (operands[1], HImode)"
   "@
    ldh%M1 %1,%0
    sth%M0 %r1,%0
    mtsar %r1
-   {mfctl|mfctl,w} %sar,%0
-   fcpy,sgl %f1,%0"
-  [(set_attr "type" "move,move,move,shift,load,store,move,move,fpalu")
+   {mfctl|mfctl,w} %sar,%0"
+  [(set_attr "type" "move,move,move,shift,load,store,move,move")
    (set_attr "pa_combine_type" "addmove")
-   (set_attr "length" "4,4,4,4,4,4,4,4,4")])
+   (set_attr "length" "4,4,4,4,4,4,4,4")])
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
 
 (define_insn ""
   [(set (match_operand:QI 0 "move_dest_operand"
-                         "=r,r,r,r,r,Q,!*q,!r,!*f")
+                         "=r,r,r,r,r,Q,!*q,!r")
        (match_operand:QI 1 "move_src_operand"
-                         "r,J,N,K,RQ,rM,!rM,!*q,!*fM"))]
+                         "r,J,N,K,RQ,rM,!rM,!*q"))]
   "register_operand (operands[0], QImode)
    || reg_or_0_operand (operands[1], QImode)"
   "@
    ldb%M1 %1,%0
    stb%M0 %r1,%0
    mtsar %r1
-   {mfctl|mfctl,w} %%sar,%0
-   fcpy,sgl %f1,%0"
-  [(set_attr "type" "move,move,move,shift,load,store,move,move,fpalu")
+   {mfctl|mfctl,w} %%sar,%0"
+  [(set_attr "type" "move,move,move,shift,load,store,move,move")
    (set_attr "pa_combine_type" "addmove")
-   (set_attr "length" "4,4,4,4,4,4,4,4,4")])
+   (set_attr "length" "4,4,4,4,4,4,4,4")])
 
 (define_insn ""
   [(set (match_operand:QI 0 "register_operand" "=r")
index d2ba2f6..e96032e 100644 (file)
    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.  For DImode, we
-   choose a set of general register 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 in patterns using this mode
-   is an early clobber.  */
+
+   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                 \
+     ? (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) == 2 * UNITS_PER_WORD                   \
          && ((((REGNO) & 1) == 1 && (REGNO) <= 25) || (REGNO) == 28))  \
       || (GET_MODE_SIZE (MODE) == 4 * UNITS_PER_WORD                   \
-         && (((REGNO) & 3) == 3 && (REGNO) <= 23))))
+         && ((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.
 
@@ -276,7 +313,9 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
    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.  */
index 65e594b..fe06c77 100644 (file)
@@ -145,11 +145,19 @@ Boston, MA 02110-1301, USA.  */
    This is ordinarily the length in words of a value of mode MODE
    but can be less for certain modes in special long registers.
 
-   For PA64, GPRs and FPRs hold 64 bits worth (we ignore the 32bit
-   addressability of the FPRs).  i.e., we pretend each register holds
-   precisely WORD_SIZE bits.  */
+   For PA64, GPRs and FPRs hold 64 bits worth.  We ignore the 32-bit
+   addressability of the FPRs and pretend each register holds precisely
+   WORD_SIZE bits.  Note that SCmode values are placed in a single FPR.
+   Thus, any patterns defined to operate on these values would have to
+   use the 32-bit addressability of the FPR registers.  */
 #define HARD_REGNO_NREGS(REGNO, MODE)                                  \
-   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+  ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* These are the valid FP modes.  */
+#define VALID_FP_MODE_P(MODE)                                           \
+  ((MODE) == SFmode || (MODE) == DFmode                                 \
+   || (MODE) == SCmode || (MODE) == DCmode                              \
+   || (MODE) == SImode || (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
@@ -158,8 +166,16 @@ Boston, MA 02110-1301, USA.  */
   ((REGNO) == 0                                                                \
    ? (MODE) == CCmode || (MODE) == CCFPmode                            \
    /* Make wide modes be in aligned registers.  */                     \
+   : FP_REGNO_P (REGNO)                                                        \
+     ? (VALID_FP_MODE_P (MODE)                                         \
+       && (GET_MODE_SIZE (MODE) <= 8                                   \
+           || (GET_MODE_SIZE (MODE) == 16 && ((REGNO) & 1) == 0)       \
+           || (GET_MODE_SIZE (MODE) == 32 && ((REGNO) & 3) == 0)))     \
    : (GET_MODE_SIZE (MODE) <= UNITS_PER_WORD                           \
-      || (GET_MODE_SIZE (MODE) <= 2 * 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)))
 
 /* How to renumber registers for dbx and gdb.