aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>2005-07-05 01:57:01 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2005-07-05 01:57:01 +0000
commit47971fa72df77d42e1982ef2c118def77f1d3d8a (patch)
treeca9ac26e1b073140283691ca6509fb7b33a9d3fe
parentf94ac7b644698a627288b8b4d613cc6ba45e48bd (diff)
downloadgcc-47971fa72df77d42e1982ef2c118def77f1d3d8a.zip
gcc-47971fa72df77d42e1982ef2c118def77f1d3d8a.tar.gz
gcc-47971fa72df77d42e1982ef2c118def77f1d3d8a.tar.bz2
re PR target/21723 (ICE while building libgfortran)
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
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/config/pa/pa.md22
-rw-r--r--gcc/config/pa/pa32-regs.h69
-rw-r--r--gcc/config/pa/pa64-regs.h26
4 files changed, 104 insertions, 32 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 60a081b..00eaf5d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index de5b75b..f724209 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -2896,9 +2896,9 @@
(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)"
"@
@@ -2909,11 +2909,10 @@
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")
@@ -3021,9 +3020,9 @@
(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)"
"@
@@ -3034,11 +3033,10 @@
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")
diff --git a/gcc/config/pa/pa32-regs.h b/gcc/config/pa/pa32-regs.h
index d2ba2f6..e96032e 100644
--- a/gcc/config/pa/pa32-regs.h
+++ b/gcc/config/pa/pa32-regs.h
@@ -156,32 +156,69 @@
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. */
diff --git a/gcc/config/pa/pa64-regs.h b/gcc/config/pa/pa64-regs.h
index 65e594b..fe06c777 100644
--- a/gcc/config/pa/pa64-regs.h
+++ b/gcc/config/pa/pa64-regs.h
@@ -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.