aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/pa
diff options
context:
space:
mode:
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>2007-12-09 18:02:08 +0000
committerJohn David Anglin <danglin@gcc.gnu.org>2007-12-09 18:02:08 +0000
commit6982c5d4c822b89dcfa6b5554505997ab183e39b (patch)
tree6c03efab36b85bc299f7ba354cfa23f643d60a6a /gcc/config/pa
parentfad0afd7d72cb63e47e70795baac30cb2880314a (diff)
downloadgcc-6982c5d4c822b89dcfa6b5554505997ab183e39b.zip
gcc-6982c5d4c822b89dcfa6b5554505997ab183e39b.tar.gz
gcc-6982c5d4c822b89dcfa6b5554505997ab183e39b.tar.bz2
re PR target/32889 (ICE in delete_output_reload, at reload1.c:7926)
PR middle-end/32889 PR target/34091 * pa.md: Consolidate HImode and QImode move patterns into one pattern each, eliminating floating-point alternatives. * pa-protos.h (pa_cannot_change_mode_class, pa_modes_tieable_p): Declare functions. * pa-64.h (SECONDARY_MEMORY_NEEDED): Define here. * pa.c (pa_secondary_reload): Use an intermediate general register for copies to/from floating-point register classes. Simplify code SHIFT_REGS class. Provide additional comments. (pa_cannot_change_mode_class, pa_modes_tieable_p): New functions. * pa.h (MODES_TIEABLE_P): Use pa_modes_tieable_p. (SECONDARY_MEMORY_NEEDED): Delete define. (INT14_OK_STRICT): Define. (MODE_OK_FOR_SCALED_INDEXING_P): Allow SFmode and DFmode when using soft float. (MODE_OK_FOR_UNSCALED_INDEXING_P): Likewise. (GO_IF_LEGITIMATE_ADDRESS): Use INT14_OK_STRICT in REG+D case for SFmode and DFmode. (LEGITIMIZE_RELOAD_ADDRESS): Use INT14_OK_STRICT in mask selection. Align DImode offsets when generating 64-bit code. * pa32-regs.h (VALID_FP_MODE_P): Remove QImode and HImode. (CANNOT_CHANGE_MODE_CLASS): Define. * pa64-regs.h (VALID_FP_MODE_P): Remove QImode and HImode. (CANNOT_CHANGE_MODE_CLASS): Define using pa_cannot_change_mode_class. From-SVN: r130725
Diffstat (limited to 'gcc/config/pa')
-rw-r--r--gcc/config/pa/pa-64.h14
-rw-r--r--gcc/config/pa/pa-protos.h3
-rw-r--r--gcc/config/pa/pa.c114
-rw-r--r--gcc/config/pa/pa.h74
-rw-r--r--gcc/config/pa/pa.md102
-rw-r--r--gcc/config/pa/pa32-regs.h8
-rw-r--r--gcc/config/pa/pa64-regs.h16
7 files changed, 169 insertions, 162 deletions
diff --git a/gcc/config/pa/pa-64.h b/gcc/config/pa/pa-64.h
index e3adcf3..67c8179 100644
--- a/gcc/config/pa/pa-64.h
+++ b/gcc/config/pa/pa-64.h
@@ -84,3 +84,17 @@ along with GCC; see the file COPYING3. If not see
want aggregates padded down. */
#define PAD_VARARGS_DOWN (!AGGREGATE_TYPE_P (type))
+
+/* In the PA architecture, it is not possible to directly move data
+ between GENERAL_REGS and FP_REGS. On the 32-bit port, we use the
+ location at SP-16 because PA 1.X only supports 5-bit immediates for
+ floating-point loads and stores. We don't expose this location in
+ the RTL to avoid scheduling related problems. For example, the
+ store and load could be separated by a call to a pure or const
+ function which has no frame and this function might also use SP-16.
+ We have 14-bit immediates on the 64-bit port, so we use secondary
+ memory for the copies. */
+#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
+ (MAYBE_FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2) \
+ || MAYBE_FP_REG_CLASS_P (CLASS2) != FP_REG_CLASS_P (CLASS1))
+
diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h
index ff621a3..7fc9dca 100644
--- a/gcc/config/pa/pa-protos.h
+++ b/gcc/config/pa/pa-protos.h
@@ -172,6 +172,9 @@ extern void pa_asm_output_aligned_local (FILE *, const char *,
unsigned HOST_WIDE_INT,
unsigned int);
extern void pa_hpux_asm_output_external (FILE *, tree, const char *);
+extern bool pa_cannot_change_mode_class (enum machine_mode, enum machine_mode,
+ enum reg_class);
+extern bool pa_modes_tieable_p (enum machine_mode, enum machine_mode);
extern const int magic_milli[];
extern int shadd_constant_p (int);
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 58122f6..b1f3a00 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -5687,12 +5687,49 @@ pa_secondary_reload (bool in_p, rtx x, enum reg_class class,
if (regno >= FIRST_PSEUDO_REGISTER || GET_CODE (x) == SUBREG)
regno = true_regnum (x);
- /* Handle out of range displacement for integer mode loads/stores of
- FP registers. */
- if (((regno >= FIRST_PSEUDO_REGISTER || regno == -1)
- && GET_MODE_CLASS (mode) == MODE_INT
- && FP_REG_CLASS_P (class))
- || (class == SHIFT_REGS && (regno <= 0 || regno >= 32)))
+ /* In order to allow 14-bit displacements in integer loads and stores,
+ we need to prevent reload from generating out of range integer mode
+ loads and stores to the floating point registers. Previously, we
+ used to call for a secondary reload and have emit_move_sequence()
+ fix the instruction sequence. However, reload occasionally wouldn't
+ generate the reload and we would end up with an invalid REG+D memory
+ address. So, now we use an intermediate general register for most
+ memory loads and stores. */
+ if ((regno >= FIRST_PSEUDO_REGISTER || regno == -1)
+ && GET_MODE_CLASS (mode) == MODE_INT
+ && FP_REG_CLASS_P (class))
+ {
+ /* Reload passes (mem:SI (reg/f:DI 30 %r30) when it wants to check
+ the secondary reload needed for a pseudo. It never passes a
+ REG+D address. */
+ if (GET_CODE (x) == MEM)
+ {
+ x = XEXP (x, 0);
+
+ /* We don't need an intermediate for indexed and LO_SUM DLT
+ memory addresses. When INT14_OK_STRICT is true, it might
+ appear that we could directly allow register indirect
+ memory addresses. However, this doesn't work because we
+ don't support SUBREGs in floating-point register copies
+ and reload doesn't tell us when it's going to use a SUBREG. */
+ if (IS_INDEX_ADDR_P (x)
+ || IS_LO_SUM_DLT_ADDR_P (x))
+ return NO_REGS;
+
+ /* Otherwise, we need an intermediate general register. */
+ return GENERAL_REGS;
+ }
+
+ /* Request a secondary reload with a general scratch register
+ for everthing else. ??? Could symbolic operands be handled
+ directly when generating non-pic PA 2.0 code? */
+ sri->icode = in_p ? reload_in_optab[mode] : reload_out_optab[mode];
+ return NO_REGS;
+ }
+
+ /* We need a secondary register (GPR) for copies between the SAR
+ and anything other than a general register. */
+ if (class == SHIFT_REGS && (regno <= 0 || regno >= 32))
{
sri->icode = in_p ? reload_in_optab[mode] : reload_out_optab[mode];
return NO_REGS;
@@ -5701,16 +5738,15 @@ pa_secondary_reload (bool in_p, rtx x, enum reg_class class,
/* A SAR<->FP register copy requires a secondary register (GPR) as
well as secondary memory. */
if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER
- && ((REGNO_REG_CLASS (regno) == SHIFT_REGS && FP_REG_CLASS_P (class))
- || (class == SHIFT_REGS
- && FP_REG_CLASS_P (REGNO_REG_CLASS (regno)))))
+ && (REGNO_REG_CLASS (regno) == SHIFT_REGS
+ && FP_REG_CLASS_P (class)))
{
sri->icode = in_p ? reload_in_optab[mode] : reload_out_optab[mode];
return NO_REGS;
}
/* Secondary reloads of symbolic operands require %r1 as a scratch
- register when we're generating PIC code and the operand isn't
+ register when we're generating PIC code and when the operand isn't
readonly. */
if (GET_CODE (x) == HIGH)
x = XEXP (x, 0);
@@ -9570,4 +9606,62 @@ pa_hpux_file_end (void)
}
#endif
+/* Return true if a change from mode FROM to mode TO for a register
+ in register class CLASS is invalid. */
+
+bool
+pa_cannot_change_mode_class (enum machine_mode from, enum machine_mode to,
+ enum reg_class class)
+{
+ if (from == to)
+ return false;
+
+ /* Reject changes to/from complex and vector modes. */
+ if (COMPLEX_MODE_P (from) || VECTOR_MODE_P (from)
+ || COMPLEX_MODE_P (to) || VECTOR_MODE_P (to))
+ return true;
+
+ if (GET_MODE_SIZE (from) == GET_MODE_SIZE (to))
+ return false;
+
+ /* There is no way to load QImode or HImode values directly from
+ memory. SImode loads to the FP registers are not zero extended.
+ On the 64-bit target, this conflicts with the definition of
+ LOAD_EXTEND_OP. Thus, we can't allow changing between modes
+ with different sizes in the floating-point registers. */
+ if (MAYBE_FP_REG_CLASS_P (class))
+ return true;
+
+ /* HARD_REGNO_MODE_OK places modes with sizes larger than a word
+ in specific sets of registers. Thus, we cannot allow changing
+ to a larger mode when it's larger than a word. */
+ if (GET_MODE_SIZE (to) > UNITS_PER_WORD
+ && GET_MODE_SIZE (to) > GET_MODE_SIZE (from))
+ return true;
+
+ return false;
+}
+
+/* Returns TRUE if it is a good idea to tie two pseudo registers
+ when one has mode MODE1 and one has mode MODE2.
+ If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
+ for any hard reg, then this must be FALSE for correct output.
+
+ We should return FALSE for QImode and HImode because these modes
+ are not ok in the floating-point registers. However, this prevents
+ tieing these modes to SImode and DImode in the general registers.
+ So, this isn't a good idea. We rely on HARD_REGNO_MODE_OK and
+ CANNOT_CHANGE_MODE_CLASS to prevent these modes from being used
+ in the floating-point registers. */
+
+bool
+pa_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
+{
+ /* Don't tie modes in different classes. */
+ if (GET_MODE_CLASS (mode1) != GET_MODE_CLASS (mode2))
+ return false;
+
+ return true;
+}
+
#include "gt-pa.h"
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 8a7fb63..f8cf9d2 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -349,7 +349,7 @@ typedef struct machine_function GTY(())
If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
for any hard reg, then this must be 0 for correct output. */
#define MODES_TIEABLE_P(MODE1, MODE2) \
- (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2))
+ pa_modes_tieable_p (MODE1, MODE2)
/* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */
@@ -497,17 +497,6 @@ extern struct rtx_def *hppa_pic_save_rtx (void);
#define MAYBE_FP_REG_CLASS_P(CLASS) \
reg_classes_intersect_p ((CLASS), FP_REGS)
-/* On the PA it is not possible to directly move data between
- GENERAL_REGS and FP_REGS. On the 32-bit port, we use the
- location at SP-16. We don't expose this location in the RTL to
- avoid scheduling related problems. For example, the store and
- load could be separated by a call to a pure or const function
- which has no frame and uses SP-16. */
-#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
- (TARGET_64BIT \
- && (MAYBE_FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2) \
- || MAYBE_FP_REG_CLASS_P (CLASS2) != FP_REG_CLASS_P (CLASS1)))
-
/* Stack layout; function entry, exit and calling. */
@@ -1116,6 +1105,24 @@ extern int may_call_alloca;
&& REG_OK_FOR_BASE_P (XEXP (OP, 0)) \
&& GET_CODE (XEXP (OP, 1)) == UNSPEC)
+/* Nonzero if 14-bit offsets can be used for all loads and stores.
+ This is not possible when generating PA 1.x code as floating point
+ loads and stores only support 5-bit offsets. Note that we do not
+ forbid the use of 14-bit offsets in GO_IF_LEGITIMATE_ADDRESS.
+ Instead, we use pa_secondary_reload() to reload integer mode
+ REG+D memory addresses used in floating point loads and stores.
+
+ FIXME: the ELF32 linker clobbers the LSB of the FP register number
+ in PA 2.0 floating-point insns with long displacements. This is
+ because R_PARISC_DPREL14WR and other relocations like it are not
+ yet supported by GNU ld. For now, we reject long displacements
+ on this target. */
+
+#define INT14_OK_STRICT \
+ (TARGET_SOFT_FLOAT \
+ || TARGET_DISABLE_FPREGS \
+ || (TARGET_PA_20 && !TARGET_ELF32))
+
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class.
We have two alternate definitions for each of them.
@@ -1134,16 +1141,18 @@ extern int may_call_alloca;
/* Nonzero if X is a hard reg that can be used as an index
or if it is a pseudo reg. */
#define REG_OK_FOR_INDEX_P(X) \
-(REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
+ (REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
+
/* Nonzero if X is a hard reg that can be used as a base reg
or if it is a pseudo reg. */
#define REG_OK_FOR_BASE_P(X) \
-(REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
+ (REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
#else
/* Nonzero if X is a hard reg that can be used as an index. */
#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
+
/* Nonzero if X is a hard reg that can be used as a base reg. */
#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
@@ -1195,11 +1204,7 @@ extern int may_call_alloca;
We treat a SYMBOL_REF as legitimate if it is part of the current
function's constant-pool, because such addresses can actually be
- output as REG+SMALLINT.
-
- Note we only allow 5-bit immediates for access to a constant address;
- doing so avoids losing for loading/storing a FP register at an address
- which will not fit in 5 bits. */
+ output as REG+SMALLINT. */
#define VAL_5_BITS_P(X) ((unsigned HOST_WIDE_INT)(X) + 0x10 < 0x20)
#define INT_5_BITS(X) VAL_5_BITS_P (INTVAL (X))
@@ -1227,7 +1232,8 @@ extern int may_call_alloca;
((TARGET_64BIT && (MODE) == DImode) \
|| (MODE) == SImode \
|| (MODE) == HImode \
- || (!TARGET_SOFT_FLOAT && ((MODE) == DFmode || (MODE) == SFmode)))
+ || (MODE) == SFmode \
+ || (MODE) == DFmode)
/* These are the modes that we allow for unscaled indexing. */
#define MODE_OK_FOR_UNSCALED_INDEXING_P(MODE) \
@@ -1235,7 +1241,8 @@ extern int may_call_alloca;
|| (MODE) == SImode \
|| (MODE) == HImode \
|| (MODE) == QImode \
- || (!TARGET_SOFT_FLOAT && ((MODE) == DFmode || (MODE) == SFmode)))
+ || (MODE) == SFmode \
+ || (MODE) == DFmode)
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ \
@@ -1269,20 +1276,10 @@ extern int may_call_alloca;
|| (INTVAL (index) % 8) == 0)) \
/* Similarly, the base register for SFmode/DFmode \
loads and stores with long displacements must \
- be aligned. \
- \
- FIXME: the ELF32 linker clobbers the LSB of \
- the FP register number in PA 2.0 floating-point \
- insns with long displacements. This is because \
- R_PARISC_DPREL14WR and other relocations like \
- it are not supported. For now, we reject long \
- displacements on this target. */ \
+ be aligned. */ \
|| (((MODE) == SFmode || (MODE) == DFmode) \
- && (TARGET_SOFT_FLOAT \
- || (TARGET_PA_20 \
- && !TARGET_ELF32 \
- && (INTVAL (index) \
- % GET_MODE_SIZE (MODE)) == 0))))) \
+ && INT14_OK_STRICT \
+ && (INTVAL (index) % GET_MODE_SIZE (MODE)) == 0))) \
|| INT_5_BITS (index))) \
goto ADDR; \
if (!TARGET_DISABLE_INDEXING \
@@ -1382,7 +1379,7 @@ do { \
rtx new, temp = NULL_RTX; \
\
mask = (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- ? (TARGET_PA_20 && !TARGET_ELF32 ? 0x3fff : 0x1f) : 0x3fff); \
+ ? (INT14_OK_STRICT ? 0x3fff : 0x1f) : 0x3fff); \
\
if (optimize && GET_CODE (AD) == PLUS) \
temp = simplify_binary_operation (PLUS, Pmode, \
@@ -1404,9 +1401,10 @@ do { \
newoffset = offset & ~mask; \
\
/* Ensure that long displacements are aligned. */ \
- if (!VAL_5_BITS_P (newoffset) \
- && GET_MODE_CLASS (MODE) == MODE_FLOAT) \
- newoffset &= ~(GET_MODE_SIZE (MODE) -1); \
+ if (mask == 0x3fff \
+ && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
+ || (TARGET_64BIT && (MODE) == DImode))) \
+ newoffset &= ~(GET_MODE_SIZE (MODE) - 1); \
\
if (newoffset != 0 && VAL_14_BITS_P (newoffset)) \
{ \
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index a515980..9487afa 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -3183,60 +3183,11 @@
(define_insn ""
[(set (match_operand:HI 0 "move_dest_operand"
- "=r,r,r,r,r,Q,!*q,!r,!*f,?r,?*f")
- (match_operand:HI 1 "move_src_operand"
- "r,J,N,K,RQ,rM,!rM,!*q,!*fM,*f,r"))]
- "(register_operand (operands[0], HImode)
- || reg_or_0_operand (operands[1], HImode))
- && !TARGET_SOFT_FLOAT
- && !TARGET_64BIT"
- "@
- copy %1,%0
- ldi %1,%0
- ldil L'%1,%0
- {zdepi|depwi,z} %Z1,%0
- ldh%M1 %1,%0
- sth%M0 %r1,%0
- mtsar %r1
- {mfctl|mfctl,w} %sar,%0
- fcpy,sgl %f1,%0
- {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
- {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
- [(set_attr "type" "move,move,move,shift,load,store,move,move,move,fpstore_load,store_fpload")
- (set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "move_dest_operand"
- "=r,r,r,r,r,Q,!*q,!r,!*f")
- (match_operand:HI 1 "move_src_operand"
- "r,J,N,K,RQ,rM,!rM,!*q,!*fM"))]
- "(register_operand (operands[0], HImode)
- || reg_or_0_operand (operands[1], HImode))
- && !TARGET_SOFT_FLOAT
- && TARGET_64BIT"
- "@
- copy %1,%0
- ldi %1,%0
- ldil L'%1,%0
- {zdepi|depwi,z} %Z1,%0
- 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,move")
- (set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4,4")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "move_dest_operand"
"=r,r,r,r,r,Q,!*q,!r")
(match_operand:HI 1 "move_src_operand"
"r,J,N,K,RQ,rM,!rM,!*q"))]
"(register_operand (operands[0], HImode)
- || reg_or_0_operand (operands[1], HImode))
- && TARGET_SOFT_FLOAT"
+ || reg_or_0_operand (operands[1], HImode))"
"@
copy %1,%0
ldi %1,%0
@@ -3356,60 +3307,11 @@
(define_insn ""
[(set (match_operand:QI 0 "move_dest_operand"
- "=r,r,r,r,r,Q,!*q,!r,!*f,?r,?*f")
- (match_operand:QI 1 "move_src_operand"
- "r,J,N,K,RQ,rM,!rM,!*q,!*fM,*f,r"))]
- "(register_operand (operands[0], QImode)
- || reg_or_0_operand (operands[1], QImode))
- && !TARGET_SOFT_FLOAT
- && !TARGET_64BIT"
- "@
- copy %1,%0
- ldi %1,%0
- ldil L'%1,%0
- {zdepi|depwi,z} %Z1,%0
- ldb%M1 %1,%0
- stb%M0 %r1,%0
- mtsar %r1
- {mfctl|mfctl,w} %%sar,%0
- fcpy,sgl %f1,%0
- {fstws|fstw} %1,-16(%%sp)\n\t{ldws|ldw} -16(%%sp),%0
- {stws|stw} %1,-16(%%sp)\n\t{fldws|fldw} -16(%%sp),%0"
- [(set_attr "type" "move,move,move,shift,load,store,move,move,move,fpstore_load,store_fpload")
- (set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8")])
-
-(define_insn ""
- [(set (match_operand:QI 0 "move_dest_operand"
- "=r,r,r,r,r,Q,!*q,!r,!*f")
- (match_operand:QI 1 "move_src_operand"
- "r,J,N,K,RQ,rM,!rM,!*q,!*fM"))]
- "(register_operand (operands[0], QImode)
- || reg_or_0_operand (operands[1], QImode))
- && !TARGET_SOFT_FLOAT
- && TARGET_64BIT"
- "@
- copy %1,%0
- ldi %1,%0
- ldil L'%1,%0
- {zdepi|depwi,z} %Z1,%0
- 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,move")
- (set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4,4")])
-
-(define_insn ""
- [(set (match_operand:QI 0 "move_dest_operand"
"=r,r,r,r,r,Q,!*q,!r")
(match_operand:QI 1 "move_src_operand"
"r,J,N,K,RQ,rM,!rM,!*q"))]
"(register_operand (operands[0], QImode)
- || reg_or_0_operand (operands[1], QImode))
- && TARGET_SOFT_FLOAT"
+ || reg_or_0_operand (operands[1], QImode))"
"@
copy %1,%0
ldi %1,%0
diff --git a/gcc/config/pa/pa32-regs.h b/gcc/config/pa/pa32-regs.h
index 782ad8d..89cbb9b 100644
--- a/gcc/config/pa/pa32-regs.h
+++ b/gcc/config/pa/pa32-regs.h
@@ -172,8 +172,7 @@
#define VALID_FP_MODE_P(MODE) \
((MODE) == SFmode || (MODE) == DFmode \
|| (MODE) == SCmode || (MODE) == DCmode \
- || (MODE) == QImode || (MODE) == HImode || (MODE) == SImode \
- || (TARGET_PA_11 && (MODE) == DImode))
+ || (MODE) == SImode || (TARGET_PA_11 && (MODE) == DImode))
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
@@ -288,6 +287,11 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
{0x00000000, 0x00000000, 0x01000000}, /* SHIFT_REGS */ \
{0xfffffffe, 0xffffffff, 0x01ffffff}} /* ALL_REGS */
+/* Defines invalid mode changes. */
+
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ pa_cannot_change_mode_class (FROM, TO, CLASS)
+
/* Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression
or could index an array. */
diff --git a/gcc/config/pa/pa64-regs.h b/gcc/config/pa/pa64-regs.h
index ddc1f06..828265f 100644
--- a/gcc/config/pa/pa64-regs.h
+++ b/gcc/config/pa/pa64-regs.h
@@ -156,8 +156,7 @@ along with GCC; see the file COPYING3. If not see
#define VALID_FP_MODE_P(MODE) \
((MODE) == SFmode || (MODE) == DFmode \
|| (MODE) == SCmode || (MODE) == DCmode \
- || (MODE) == QImode || (MODE) == HImode || (MODE) == SImode \
- || (MODE) == DImode)
+ || (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
@@ -242,17 +241,10 @@ enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS,
{0x00000000, 0x10000000}, /* SHIFT_REGS */ \
{0xfffffffe, 0x1fffffff}} /* ALL_REGS */
-/* Defines invalid mode changes.
+/* Defines invalid mode changes. */
- SImode loads to floating-point registers are not zero-extended.
- The definition for LOAD_EXTEND_OP specifies that integer loads
- narrower than BITS_PER_WORD will be zero-extended. As a result,
- we inhibit changes from SImode unless they are to a mode that is
- identical in size. */
-
-#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
- ((FROM) == SImode && GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
- ? reg_classes_intersect_p (CLASS, FP_REGS) : 0)
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
+ pa_cannot_change_mode_class (FROM, TO, CLASS)
/* Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression