+2003-10-23 Fariborz Jahanian <fjahanian@apple.com>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.h (UNITS_PER_WORD): Use TARGET_32BIT, not
+ TARGET_POWREPC64.
+ (UNITS_PER_GPR_WORD): Define.
+ (HARD_REGNO_NREGS): Use UNITS_PER_GPR_WORD.
+ (HARD_REGNO_CALL_PART_CLOBBERED): Define.
+ (HARD_REGNO_MODE_OK): Use UNITS_PER_GPR_WORD.
+ (CLASS_MAX_NREGS): Use UNITS_PER_GPR_WORD.
+ * config/rs6000/rs6000.c (function_arg): Generate PARALLEL for
+ DFmode and DImode in 32-bit ABI / 64-bit computation mode.
+ (rs6000_emit_prologue): Select reg_mode and reg_size using
+ TARGET_32BIT, not TARGET_POWERPC64.
+ (rs6000_function_value): Generate PARALLEL for DImode in 32-bit
+ ABI / 64-bit computation mode
+
2003-10-22 Andrew Haley <aph@redhat.com>
* toplev.c (output_file_directive): Allow for null input_name.
|| (align_words < GP_ARG_NUM_REG))))
return gen_rtx_REG (mode, cum->fregno);
+ if (TARGET_32BIT && TARGET_POWERPC64 && mode == DFmode)
+ {
+ /* -mpowerpc64 with 32bit ABI splits up a DFmode argument
+ in vararg list into zero, one or two GPRs */
+ if (align_words >= GP_ARG_NUM_REG)
+ return gen_rtx_PARALLEL (DFmode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ NULL_RTX, const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode,
+ cum->fregno),
+ const0_rtx)));
+ else if (align_words + RS6000_ARG_SIZE (mode, type)
+ > GP_ARG_NUM_REG)
+ /* If this is partially on the stack, then we only
+ include the portion actually in registers here. */
+ return gen_rtx_PARALLEL (DFmode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words),
+ const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode,
+ cum->fregno),
+ const0_rtx)));
+
+ /* split a DFmode arg into two GPRs */
+ return gen_rtx_PARALLEL (DFmode,
+ gen_rtvec (3,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words),
+ const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words + 1),
+ GEN_INT (4)),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (mode, cum->fregno),
+ const0_rtx)));
+ }
+
return gen_rtx_PARALLEL (mode,
gen_rtvec (2,
gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (mode, cum->fregno),
const0_rtx)));
}
+ /* -mpowerpc64 with 32bit ABI splits up a DImode argument into one
+ or two GPRs */
+ else if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode
+ && align_words < GP_ARG_NUM_REG - 1)
+ {
+ return gen_rtx_PARALLEL (DImode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words),
+ const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words + 1),
+ GEN_INT (4))));
+ }
+ else if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode
+ && align_words == GP_ARG_NUM_REG - 1)
+ {
+ return gen_rtx_PARALLEL (DImode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ NULL_RTX, const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_MIN_REG
+ + align_words),
+ const0_rtx)));
+ }
else if (align_words < GP_ARG_NUM_REG)
return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words);
else
rs6000_emit_prologue (void)
{
rs6000_stack_t *info = rs6000_stack_info ();
- enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
- int reg_size = TARGET_POWERPC64 ? 8 : 4;
+ enum machine_mode reg_mode = Pmode;
+ int reg_size = UNITS_PER_WORD;
rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
rtx frame_reg_rtx = sp_reg_rtx;
int sp_offset = 0;
rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
rtx frame_reg_rtx = sp_reg_rtx;
- enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode;
- int reg_size = TARGET_POWERPC64 ? 8 : 4;
+ enum machine_mode reg_mode = Pmode;
+ int reg_size = UNITS_PER_WORD;
int i;
info = rs6000_stack_info ();
enum machine_mode mode;
unsigned int regno;
+ if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
+ {
+ /* Long long return value need be split in -mpowerpc64, 32bit ABI. */
+ return gen_rtx_PARALLEL (DImode,
+ gen_rtvec (2,
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode, GP_ARG_RETURN),
+ const0_rtx),
+ gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_REG (SImode,
+ GP_ARG_RETURN + 1),
+ GEN_INT (4))));
+ }
+
if ((INTEGRAL_TYPE_P (valtype)
&& TYPE_PRECISION (valtype) < BITS_PER_WORD)
|| POINTER_TYPE_P (valtype))
#define MAX_BITS_PER_WORD 64
/* Width of a word, in units (bytes). */
-#define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8)
+#define UNITS_PER_WORD (TARGET_32BIT ? 4 : 8)
#ifdef IN_LIBGCC2
#define MIN_UNITS_PER_WORD UNITS_PER_WORD
#else
POWER and PowerPC GPRs hold 32 bits worth;
PowerPC64 GPRs and FPRs point register holds 64 bits worth. */
+#define UNITS_PER_GPR_WORD (! TARGET_POWERPC64 ? 4 : 8)
+
#define HARD_REGNO_NREGS(REGNO, MODE) \
(FP_REGNO_P (REGNO) \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD) \
: ALTIVEC_REGNO_P (REGNO) \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \
- : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+ : ((GET_MODE_SIZE (MODE) + UNITS_PER_GPR_WORD - 1) / UNITS_PER_GPR_WORD))
+
+#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
+ ((TARGET_32BIT && TARGET_POWERPC64 \
+ && (MODE == DImode || MODE == DFmode) \
+ && INT_REGNO_P (REGNO)) ? 1 : 0)
#define ALTIVEC_VECTOR_MODE(MODE) \
((MODE) == V16QImode \
: SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE) ? 1 \
: CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC \
: XER_REGNO_P (REGNO) ? (MODE) == PSImode \
- : GET_MODE_SIZE (MODE) <= UNITS_PER_WORD)
+ : GET_MODE_SIZE (MODE) <= UNITS_PER_GPR_WORD)
/* Value is 1 if it is a good idea to tie two pseudo registers
when one has mode MODE1 and one has mode MODE2.
#define CLASS_MAX_NREGS(CLASS, MODE) \
(((CLASS) == FLOAT_REGS) \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
- : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
+ : ((GET_MODE_SIZE (MODE) + UNITS_PER_GPR_WORD - 1) / UNITS_PER_GPR_WORD))
/* Return a class of registers that cannot change FROM mode to TO mode. */