rs6000.c (rs6000_mixed_function_arg): New.
2003-10-31 Fariborz Jahanian <fjahanian@apple.com> David Edelsohn <edelsohn@gnu.org> * config/rs6000/rs6000.c (rs6000_mixed_function_arg): New. (function_arg): Call it. (rs6000_function_value): Widen integral return value to mode based on TARGET_32BIT, not word_mode. * config/rs6000/rs6000.h (PROMOTE_MODE): Likewise. Co-Authored-By: David Edelsohn <edelsohn@gnu.org> From-SVN: r73151
This commit is contained in:
parent
3dc5f34a79
commit
b78d48ddc2
3 changed files with 128 additions and 86 deletions
|
@ -1,3 +1,12 @@
|
|||
2003-10-31 Fariborz Jahanian <fjahanian@apple.com>
|
||||
David Edelsohn <edelsohn@gnu.org>
|
||||
|
||||
* config/rs6000/rs6000.c (rs6000_mixed_function_arg): New.
|
||||
(function_arg): Call it.
|
||||
(rs6000_function_value): Widen integral return value to mode based
|
||||
on TARGET_32BIT, not word_mode.
|
||||
* config/rs6000/rs6000.h (PROMOTE_MODE): Likewise.
|
||||
|
||||
2003-10-31 Gerald Pfeifer <gerald@pfeifer.com>
|
||||
|
||||
* .cvsignore: No longer ignore gengtype-lex.c, gengtype-yacc.c,
|
||||
|
|
|
@ -347,6 +347,8 @@ static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *);
|
|||
static rtx rs6000_complex_function_value (enum machine_mode);
|
||||
static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree);
|
||||
static rtx rs6000_mixed_function_arg (CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int);
|
||||
static void setup_incoming_varargs (CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree,
|
||||
int *, int);
|
||||
|
@ -3211,7 +3213,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2)
|
|||
|| (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
|
||||
{
|
||||
if (ud1 & 0x8000)
|
||||
emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
|
||||
emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
|
||||
else
|
||||
emit_move_insn (dest, GEN_INT (ud1));
|
||||
}
|
||||
|
@ -3894,6 +3896,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
}
|
||||
|
||||
/* Determine where to put a SIMD argument on the SPE. */
|
||||
|
||||
static rtx
|
||||
rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type)
|
||||
|
@ -3919,17 +3922,121 @@ rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
return NULL_RTX;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cum->sysv_gregno <= GP_ARG_MAX_REG)
|
||||
return gen_rtx_REG (mode, cum->sysv_gregno);
|
||||
else
|
||||
return NULL;
|
||||
return NULL_RTX;
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
|
||||
|
||||
static rtx
|
||||
rs6000_mixed_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, int align_words)
|
||||
{
|
||||
if (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)));
|
||||
}
|
||||
/* -mpowerpc64 with 32bit ABI splits up a DImode argument into one
|
||||
or two GPRs */
|
||||
else if (mode == DImode)
|
||||
{
|
||||
if (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 (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 (mode == BLKmode && align_words <= (GP_ARG_NUM_REG - 1))
|
||||
{
|
||||
int k;
|
||||
int size = int_size_in_bytes (type);
|
||||
int no_units = size / 4;
|
||||
int max_no_words = GP_ARG_NUM_REG - align_words;
|
||||
int rtlvec_len = no_units < max_no_words ? no_units : max_no_words;
|
||||
rtx *rtlvec = (rtx *) alloca (rtlvec_len * sizeof (rtx));
|
||||
|
||||
memset ((char *) rtlvec, 0, rtlvec_len * sizeof (rtx));
|
||||
|
||||
for (k=0; k < rtlvec_len; k++)
|
||||
rtlvec[k] = gen_rtx_EXPR_LIST (VOIDmode,
|
||||
gen_rtx_REG (SImode,
|
||||
GP_ARG_MIN_REG
|
||||
+ align_words + k),
|
||||
k == 0 ? const0_rtx : GEN_INT (k*4));
|
||||
|
||||
return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k, rtlvec));
|
||||
}
|
||||
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
/* Determine where to put an argument to a function.
|
||||
Value is zero to push the argument on the stack,
|
||||
or a hard register in which to store the argument.
|
||||
|
@ -4029,7 +4136,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
if (cum->fregno <= FP_ARG_V4_MAX_REG)
|
||||
return gen_rtx_REG (mode, cum->fregno);
|
||||
else
|
||||
return NULL;
|
||||
return NULL_RTX;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4051,7 +4158,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
|
||||
return gen_rtx_REG (mode, gregno);
|
||||
else
|
||||
return NULL;
|
||||
return NULL_RTX;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -4063,6 +4170,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
|
||||
return NULL_RTX;
|
||||
|
||||
if (TARGET_32BIT && TARGET_POWERPC64
|
||||
&& (mode == DFmode || mode == DImode || mode == BLKmode))
|
||||
return rs6000_mixed_function_arg (cum, mode, type, align_words);
|
||||
|
||||
if (USE_FP_FOR_ARG_P (*cum, mode, type))
|
||||
{
|
||||
if (! type
|
||||
|
@ -4075,53 +4186,6 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
|| (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,
|
||||
|
@ -4142,37 +4206,6 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
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
|
||||
|
@ -11365,7 +11398,7 @@ rs6000_emit_prologue (void)
|
|||
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;
|
||||
rtx cr_save_rtx = NULL;
|
||||
rtx cr_save_rtx = NULL_RTX;
|
||||
rtx insn;
|
||||
int saving_FPRs_inline;
|
||||
int using_store_multiple;
|
||||
|
@ -15456,7 +15489,7 @@ rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
|
|||
if ((INTEGRAL_TYPE_P (valtype)
|
||||
&& TYPE_PRECISION (valtype) < BITS_PER_WORD)
|
||||
|| POINTER_TYPE_P (valtype))
|
||||
mode = word_mode;
|
||||
mode = TARGET_32BIT ? SImode : DImode;
|
||||
else
|
||||
mode = TYPE_MODE (valtype);
|
||||
|
||||
|
|
|
@ -604,7 +604,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
|
|||
#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
|
||||
if (GET_MODE_CLASS (MODE) == MODE_INT \
|
||||
&& GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
|
||||
(MODE) = word_mode;
|
||||
(MODE) = TARGET_32BIT ? SImode : DImode;
|
||||
|
||||
/* Define this if most significant bit is lowest numbered
|
||||
in instructions that operate on numbered bit-fields. */
|
||||
|
|
Loading…
Add table
Reference in a new issue