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
This commit is contained in:
John David Anglin 2007-12-09 18:02:08 +00:00 committed by John David Anglin
parent fad0afd7d7
commit 6982c5d4c8
8 changed files with 197 additions and 162 deletions

View File

@ -1,3 +1,31 @@
2007-12-09 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
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.
2007-12-09 Jakub Jelinek <jakub@redhat.com> 2007-12-09 Jakub Jelinek <jakub@redhat.com>
PR fortran/22244 PR fortran/22244

View File

@ -84,3 +84,17 @@ along with GCC; see the file COPYING3. If not see
want aggregates padded down. */ want aggregates padded down. */
#define PAD_VARARGS_DOWN (!AGGREGATE_TYPE_P (type)) #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))

View File

@ -172,6 +172,9 @@ extern void pa_asm_output_aligned_local (FILE *, const char *,
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
unsigned int); unsigned int);
extern void pa_hpux_asm_output_external (FILE *, tree, const char *); 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 const int magic_milli[];
extern int shadd_constant_p (int); extern int shadd_constant_p (int);

View File

@ -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) if (regno >= FIRST_PSEUDO_REGISTER || GET_CODE (x) == SUBREG)
regno = true_regnum (x); regno = true_regnum (x);
/* Handle out of range displacement for integer mode loads/stores of /* In order to allow 14-bit displacements in integer loads and stores,
FP registers. */ we need to prevent reload from generating out of range integer mode
if (((regno >= FIRST_PSEUDO_REGISTER || regno == -1) loads and stores to the floating point registers. Previously, we
&& GET_MODE_CLASS (mode) == MODE_INT used to call for a secondary reload and have emit_move_sequence()
&& FP_REG_CLASS_P (class)) fix the instruction sequence. However, reload occasionally wouldn't
|| (class == SHIFT_REGS && (regno <= 0 || regno >= 32))) 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]; sri->icode = in_p ? reload_in_optab[mode] : reload_out_optab[mode];
return NO_REGS; 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 /* A SAR<->FP register copy requires a secondary register (GPR) as
well as secondary memory. */ well as secondary memory. */
if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER
&& ((REGNO_REG_CLASS (regno) == SHIFT_REGS && FP_REG_CLASS_P (class)) && (REGNO_REG_CLASS (regno) == SHIFT_REGS
|| (class == SHIFT_REGS && FP_REG_CLASS_P (class)))
&& FP_REG_CLASS_P (REGNO_REG_CLASS (regno)))))
{ {
sri->icode = in_p ? reload_in_optab[mode] : reload_out_optab[mode]; sri->icode = in_p ? reload_in_optab[mode] : reload_out_optab[mode];
return NO_REGS; return NO_REGS;
} }
/* Secondary reloads of symbolic operands require %r1 as a scratch /* 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. */ readonly. */
if (GET_CODE (x) == HIGH) if (GET_CODE (x) == HIGH)
x = XEXP (x, 0); x = XEXP (x, 0);
@ -9570,4 +9606,62 @@ pa_hpux_file_end (void)
} }
#endif #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" #include "gt-pa.h"

View File

@ -349,7 +349,7 @@ typedef struct machine_function GTY(())
If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, 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. */ for any hard reg, then this must be 0 for correct output. */
#define MODES_TIEABLE_P(MODE1, MODE2) \ #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. /* Specify the registers used for certain standard purposes.
The values of these macros are register numbers. */ 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) \ #define MAYBE_FP_REG_CLASS_P(CLASS) \
reg_classes_intersect_p ((CLASS), FP_REGS) 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. */ /* Stack layout; function entry, exit and calling. */
@ -1116,6 +1105,24 @@ extern int may_call_alloca;
&& REG_OK_FOR_BASE_P (XEXP (OP, 0)) \ && REG_OK_FOR_BASE_P (XEXP (OP, 0)) \
&& GET_CODE (XEXP (OP, 1)) == UNSPEC) && 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 /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class. and check its validity for a certain class.
We have two alternate definitions for each of them. 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 /* Nonzero if X is a hard reg that can be used as an index
or if it is a pseudo reg. */ or if it is a pseudo reg. */
#define REG_OK_FOR_INDEX_P(X) \ #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 /* Nonzero if X is a hard reg that can be used as a base reg
or if it is a pseudo reg. */ or if it is a pseudo reg. */
#define REG_OK_FOR_BASE_P(X) \ #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 #else
/* Nonzero if X is a hard reg that can be used as an index. */ /* 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)) #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. */ /* 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)) #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 We treat a SYMBOL_REF as legitimate if it is part of the current
function's constant-pool, because such addresses can actually be function's constant-pool, because such addresses can actually be
output as REG+SMALLINT. 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. */
#define VAL_5_BITS_P(X) ((unsigned HOST_WIDE_INT)(X) + 0x10 < 0x20) #define VAL_5_BITS_P(X) ((unsigned HOST_WIDE_INT)(X) + 0x10 < 0x20)
#define INT_5_BITS(X) VAL_5_BITS_P (INTVAL (X)) #define INT_5_BITS(X) VAL_5_BITS_P (INTVAL (X))
@ -1227,7 +1232,8 @@ extern int may_call_alloca;
((TARGET_64BIT && (MODE) == DImode) \ ((TARGET_64BIT && (MODE) == DImode) \
|| (MODE) == SImode \ || (MODE) == SImode \
|| (MODE) == HImode \ || (MODE) == HImode \
|| (!TARGET_SOFT_FLOAT && ((MODE) == DFmode || (MODE) == SFmode))) || (MODE) == SFmode \
|| (MODE) == DFmode)
/* These are the modes that we allow for unscaled indexing. */ /* These are the modes that we allow for unscaled indexing. */
#define MODE_OK_FOR_UNSCALED_INDEXING_P(MODE) \ #define MODE_OK_FOR_UNSCALED_INDEXING_P(MODE) \
@ -1235,7 +1241,8 @@ extern int may_call_alloca;
|| (MODE) == SImode \ || (MODE) == SImode \
|| (MODE) == HImode \ || (MODE) == HImode \
|| (MODE) == QImode \ || (MODE) == QImode \
|| (!TARGET_SOFT_FLOAT && ((MODE) == DFmode || (MODE) == SFmode))) || (MODE) == SFmode \
|| (MODE) == DFmode)
#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
{ \ { \
@ -1269,20 +1276,10 @@ extern int may_call_alloca;
|| (INTVAL (index) % 8) == 0)) \ || (INTVAL (index) % 8) == 0)) \
/* Similarly, the base register for SFmode/DFmode \ /* Similarly, the base register for SFmode/DFmode \
loads and stores with long displacements must \ loads and stores with long displacements must \
be aligned. \ 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. */ \
|| (((MODE) == SFmode || (MODE) == DFmode) \ || (((MODE) == SFmode || (MODE) == DFmode) \
&& (TARGET_SOFT_FLOAT \ && INT14_OK_STRICT \
|| (TARGET_PA_20 \ && (INTVAL (index) % GET_MODE_SIZE (MODE)) == 0))) \
&& !TARGET_ELF32 \
&& (INTVAL (index) \
% GET_MODE_SIZE (MODE)) == 0))))) \
|| INT_5_BITS (index))) \ || INT_5_BITS (index))) \
goto ADDR; \ goto ADDR; \
if (!TARGET_DISABLE_INDEXING \ if (!TARGET_DISABLE_INDEXING \
@ -1382,7 +1379,7 @@ do { \
rtx new, temp = NULL_RTX; \ rtx new, temp = NULL_RTX; \
\ \
mask = (GET_MODE_CLASS (MODE) == MODE_FLOAT \ 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) \ if (optimize && GET_CODE (AD) == PLUS) \
temp = simplify_binary_operation (PLUS, Pmode, \ temp = simplify_binary_operation (PLUS, Pmode, \
@ -1404,9 +1401,10 @@ do { \
newoffset = offset & ~mask; \ newoffset = offset & ~mask; \
\ \
/* Ensure that long displacements are aligned. */ \ /* Ensure that long displacements are aligned. */ \
if (!VAL_5_BITS_P (newoffset) \ if (mask == 0x3fff \
&& GET_MODE_CLASS (MODE) == MODE_FLOAT) \ && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
newoffset &= ~(GET_MODE_SIZE (MODE) -1); \ || (TARGET_64BIT && (MODE) == DImode))) \
newoffset &= ~(GET_MODE_SIZE (MODE) - 1); \
\ \
if (newoffset != 0 && VAL_14_BITS_P (newoffset)) \ if (newoffset != 0 && VAL_14_BITS_P (newoffset)) \
{ \ { \

View File

@ -3181,62 +3181,13 @@
DONE; DONE;
}") }")
(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 "" (define_insn ""
[(set (match_operand:HI 0 "move_dest_operand" [(set (match_operand:HI 0 "move_dest_operand"
"=r,r,r,r,r,Q,!*q,!r") "=r,r,r,r,r,Q,!*q,!r")
(match_operand:HI 1 "move_src_operand" (match_operand:HI 1 "move_src_operand"
"r,J,N,K,RQ,rM,!rM,!*q"))] "r,J,N,K,RQ,rM,!rM,!*q"))]
"(register_operand (operands[0], HImode) "(register_operand (operands[0], HImode)
|| reg_or_0_operand (operands[1], HImode)) || reg_or_0_operand (operands[1], HImode))"
&& TARGET_SOFT_FLOAT"
"@ "@
copy %1,%0 copy %1,%0
ldi %1,%0 ldi %1,%0
@ -3354,62 +3305,13 @@
DONE; DONE;
}") }")
(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 "" (define_insn ""
[(set (match_operand:QI 0 "move_dest_operand" [(set (match_operand:QI 0 "move_dest_operand"
"=r,r,r,r,r,Q,!*q,!r") "=r,r,r,r,r,Q,!*q,!r")
(match_operand:QI 1 "move_src_operand" (match_operand:QI 1 "move_src_operand"
"r,J,N,K,RQ,rM,!rM,!*q"))] "r,J,N,K,RQ,rM,!rM,!*q"))]
"(register_operand (operands[0], QImode) "(register_operand (operands[0], QImode)
|| reg_or_0_operand (operands[1], QImode)) || reg_or_0_operand (operands[1], QImode))"
&& TARGET_SOFT_FLOAT"
"@ "@
copy %1,%0 copy %1,%0
ldi %1,%0 ldi %1,%0

View File

@ -172,8 +172,7 @@
#define VALID_FP_MODE_P(MODE) \ #define VALID_FP_MODE_P(MODE) \
((MODE) == SFmode || (MODE) == DFmode \ ((MODE) == SFmode || (MODE) == DFmode \
|| (MODE) == SCmode || (MODE) == DCmode \ || (MODE) == SCmode || (MODE) == DCmode \
|| (MODE) == QImode || (MODE) == HImode || (MODE) == SImode \ || (MODE) == SImode || (TARGET_PA_11 && (MODE) == DImode))
|| (TARGET_PA_11 && (MODE) == DImode))
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. /* 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 */ \ {0x00000000, 0x00000000, 0x01000000}, /* SHIFT_REGS */ \
{0xfffffffe, 0xffffffff, 0x01ffffff}} /* ALL_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 /* Return the class number of the smallest class containing
reg number REGNO. This could be a conditional expression reg number REGNO. This could be a conditional expression
or could index an array. */ or could index an array. */

View File

@ -156,8 +156,7 @@ along with GCC; see the file COPYING3. If not see
#define VALID_FP_MODE_P(MODE) \ #define VALID_FP_MODE_P(MODE) \
((MODE) == SFmode || (MODE) == DFmode \ ((MODE) == SFmode || (MODE) == DFmode \
|| (MODE) == SCmode || (MODE) == DCmode \ || (MODE) == SCmode || (MODE) == DCmode \
|| (MODE) == QImode || (MODE) == HImode || (MODE) == SImode \ || (MODE) == SImode || (MODE) == DImode)
|| (MODE) == DImode)
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. /* 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 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 */ \ {0x00000000, 0x10000000}, /* SHIFT_REGS */ \
{0xfffffffe, 0x1fffffff}} /* ALL_REGS */ {0xfffffffe, 0x1fffffff}} /* ALL_REGS */
/* Defines invalid mode changes. /* Defines invalid mode changes. */
SImode loads to floating-point registers are not zero-extended. #define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
The definition for LOAD_EXTEND_OP specifies that integer loads pa_cannot_change_mode_class (FROM, TO, CLASS)
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)
/* 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 reg number REGNO. This could be a conditional expression