diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1e480c3d350..b3bb96efc08 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,31 @@ +2007-12-09 John David Anglin + + 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 PR fortran/22244 diff --git a/gcc/config/pa/pa-64.h b/gcc/config/pa/pa-64.h index e3adcf3ec28..67c8179c573 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 ff621a30733..7fc9dcad40f 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 58122f62118..b1f3a003653 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 8a7fb63eaca..f8cf9d2f4e9 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 a515980ea74..9487afac5d3 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -3181,62 +3181,13 @@ 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 "" [(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 @@ -3354,62 +3305,13 @@ 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 "" [(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 782ad8d5f5c..89cbb9b7552 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 ddc1f061ab2..828265f23b8 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