mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-13 18:30:59 +08:00
Basic ABI changes for passing structs by value in 64-bit Darwin.
* config/rs6000/rs6000.c (rs6000_darwin64_abi): New flag. (rs6000_override_options): Set it for 64-bit Darwin. (rs6000_parse_abi_options): Add testing options to change it. (rs6000_return_in_memory): Test whether the type is one that can be passed in registers. (darwin64_function_arg_advance): New. (function_arg_advance): Call it, plus add recursion depth argument and test when counting off arguments. (rs6000_darwin64_function_arg): New. (function_arg): Call it. (setup_incoming_varargs): Add argument to function_arg_advance. (rs6000_darwin64_function_value): New. (rs6000_function_value): Call it. * config/rs6000/rs6000.h (FUNCTION_ARG_ADVANCE): Pass depth arg. * config/rs6000/rs6000-protos.h: Update decl of function_arg_advance. From-SVN: r90629
This commit is contained in:
parent
1e1b864906
commit
594a51febe
@ -1,3 +1,23 @@
|
||||
2004-11-14 Stan Shebs <shebs@apple.com>
|
||||
|
||||
Basic ABI changes for passing structs by value in 64-bit Darwin.
|
||||
* config/rs6000/rs6000.c (rs6000_darwin64_abi): New flag.
|
||||
(rs6000_override_options): Set it for 64-bit Darwin.
|
||||
(rs6000_parse_abi_options): Add testing options to change it.
|
||||
(rs6000_return_in_memory): Test whether the type is one
|
||||
that can be passed in registers.
|
||||
(darwin64_function_arg_advance): New.
|
||||
(function_arg_advance): Call it, plus add recursion depth
|
||||
argument and test when counting off arguments.
|
||||
(rs6000_darwin64_function_arg): New.
|
||||
(function_arg): Call it.
|
||||
(setup_incoming_varargs): Add argument to function_arg_advance.
|
||||
(rs6000_darwin64_function_value): New.
|
||||
(rs6000_function_value): Call it.
|
||||
* config/rs6000/rs6000.h (FUNCTION_ARG_ADVANCE): Pass depth arg.
|
||||
* config/rs6000/rs6000-protos.h: Update decl of
|
||||
function_arg_advance.
|
||||
|
||||
2004-11-14 Andrew Pinski <pinskia@physics.uc.edu>
|
||||
|
||||
PR c/17279
|
||||
|
@ -156,7 +156,7 @@ extern rtx rs6000_machopic_legitimize_pic_address (rtx orig,
|
||||
#ifdef TREE_CODE
|
||||
extern unsigned int rs6000_special_round_type_align (tree, int, int);
|
||||
extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
|
||||
tree, int);
|
||||
tree, int, int);
|
||||
extern int function_arg_boundary (enum machine_mode, tree);
|
||||
extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int);
|
||||
|
@ -175,6 +175,9 @@ int rs6000_spe;
|
||||
/* Nonzero if floating point operations are done in the GPRs. */
|
||||
int rs6000_float_gprs = 0;
|
||||
|
||||
/* Nonzero if we want Darwin's struct-by-value-in-regs ABI. */
|
||||
int rs6000_darwin64_abi;
|
||||
|
||||
/* String from -mfloat-gprs=. */
|
||||
const char *rs6000_float_gprs_string;
|
||||
|
||||
@ -746,6 +749,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_darwin64_function_arg (CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int);
|
||||
static rtx rs6000_mixed_function_arg (enum machine_mode, tree, int);
|
||||
static void rs6000_move_block_from_reg (int regno, rtx x, int nregs);
|
||||
static void setup_incoming_varargs (CUMULATIVE_ARGS *,
|
||||
@ -1292,6 +1297,12 @@ rs6000_override_options (const char *default_cpu)
|
||||
rs6000_altivec_vrsave = 1;
|
||||
}
|
||||
|
||||
/* Set the Darwin64 ABI as default for 64-bit Darwin. */
|
||||
if (DEFAULT_ABI == ABI_DARWIN && TARGET_64BIT)
|
||||
{
|
||||
rs6000_darwin64_abi = 1;
|
||||
}
|
||||
|
||||
/* Handle -mabi= options. */
|
||||
rs6000_parse_abi_options ();
|
||||
|
||||
@ -1625,6 +1636,19 @@ rs6000_parse_abi_options (void)
|
||||
error ("not configured for ABI: '%s'", rs6000_abi_string);
|
||||
}
|
||||
|
||||
/* These are here for testing during development only, do not
|
||||
document in the manual please. */
|
||||
else if (! strcmp (rs6000_abi_string, "d64"))
|
||||
{
|
||||
rs6000_darwin64_abi = 1;
|
||||
warning ("Using darwin64 ABI");
|
||||
}
|
||||
else if (! strcmp (rs6000_abi_string, "d32"))
|
||||
{
|
||||
rs6000_darwin64_abi = 0;
|
||||
warning ("Using old darwin ABI");
|
||||
}
|
||||
|
||||
else if (! strcmp (rs6000_abi_string, "no-spe"))
|
||||
rs6000_spe_abi = 0;
|
||||
else
|
||||
@ -4603,6 +4627,15 @@ rs6000_emit_move (rtx dest, rtx source, enum machine_mode mode)
|
||||
static bool
|
||||
rs6000_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* In the darwin64 abi, try to use registers for larger structs
|
||||
if possible. */
|
||||
if (AGGREGATE_TYPE_P (type)
|
||||
&& rs6000_darwin64_abi
|
||||
&& TREE_CODE (type) == RECORD_TYPE
|
||||
&& ((unsigned HOST_WIDE_INT) int_size_in_bytes (type) <= 32)
|
||||
&& ((unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 0))
|
||||
return false;
|
||||
|
||||
if (AGGREGATE_TYPE_P (type)
|
||||
&& (TARGET_AIX_STRUCT_RET
|
||||
|| (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8))
|
||||
@ -4783,6 +4816,48 @@ rs6000_arg_size (enum machine_mode mode, tree type)
|
||||
return (size + 7) >> 3;
|
||||
}
|
||||
|
||||
/* The darwin64 ABI calls for us to recurse down through structs,
|
||||
applying the same rules to struct elements as if a reference to
|
||||
each were being passed directly. */
|
||||
|
||||
static void
|
||||
darwin64_function_arg_advance (CUMULATIVE_ARGS *cum, tree type,
|
||||
int named, int depth)
|
||||
{
|
||||
tree f, ftype;
|
||||
int i, tot;
|
||||
|
||||
switch (TREE_CODE (type))
|
||||
{
|
||||
case RECORD_TYPE:
|
||||
for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
|
||||
if (TREE_CODE (f) == FIELD_DECL)
|
||||
{
|
||||
ftype = TREE_TYPE (f);
|
||||
function_arg_advance (cum, TYPE_MODE (ftype), ftype,
|
||||
named, depth + 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case ARRAY_TYPE:
|
||||
tot = int_size_in_bytes (type);
|
||||
if (tot <= 0)
|
||||
return;
|
||||
ftype = TREE_TYPE (type);
|
||||
tot /= int_size_in_bytes (ftype);
|
||||
|
||||
for (i = 0; i < tot; ++i)
|
||||
{
|
||||
function_arg_advance (cum, TYPE_MODE (ftype), ftype,
|
||||
named, depth + 1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the data in CUM to advance over an argument
|
||||
of mode MODE and data type TYPE.
|
||||
(TYPE is null for libcalls where that information may not be available.)
|
||||
@ -4793,9 +4868,11 @@ rs6000_arg_size (enum machine_mode mode, tree type)
|
||||
|
||||
void
|
||||
function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, int named)
|
||||
tree type, int named, int depth)
|
||||
{
|
||||
cum->nargs_prototype--;
|
||||
/* Only tick off an argument if we're not recursing. */
|
||||
if (depth == 0)
|
||||
cum->nargs_prototype--;
|
||||
|
||||
if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
|
||||
{
|
||||
@ -4850,6 +4927,13 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
&& !cum->stdarg
|
||||
&& cum->sysv_gregno <= GP_ARG_MAX_REG)
|
||||
cum->sysv_gregno++;
|
||||
|
||||
else if (rs6000_darwin64_abi
|
||||
&& mode == BLKmode
|
||||
&& (TREE_CODE (type) == RECORD_TYPE
|
||||
|| TREE_CODE (type) == ARRAY_TYPE))
|
||||
darwin64_function_arg_advance (cum, type, named, depth);
|
||||
|
||||
else if (DEFAULT_ABI == ABI_V4)
|
||||
{
|
||||
if (TARGET_HARD_FLOAT && TARGET_FPRS
|
||||
@ -4925,7 +5009,8 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
cum->words, cum->fregno);
|
||||
fprintf (stderr, "nargs = %4d, proto = %d, mode = %4s, ",
|
||||
cum->nargs_prototype, cum->prototype, GET_MODE_NAME (mode));
|
||||
fprintf (stderr, "named = %d, align = %d\n", named, align);
|
||||
fprintf (stderr, "named = %d, align = %d, depth = %d\n",
|
||||
named, align, depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5003,6 +5088,123 @@ rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
}
|
||||
}
|
||||
|
||||
/* For the darwin64 ABI, we want to construct a PARALLEL consisting of
|
||||
the register(s) to be used for each field and subfield of a struct
|
||||
being passed by value, along with the offset of where the
|
||||
register's value may be found in the block. */
|
||||
|
||||
static rtx
|
||||
rs6000_darwin64_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
tree type, int named)
|
||||
{
|
||||
tree f, ftype, offset;
|
||||
rtx rvec[FIRST_PSEUDO_REGISTER], sub, suboff, roffset;
|
||||
int k = 0, i, j, bytepos, subbytepos, tot;
|
||||
CUMULATIVE_ARGS saved_cum = *cum;
|
||||
enum machine_mode submode;
|
||||
|
||||
switch (TREE_CODE (type))
|
||||
{
|
||||
case RECORD_TYPE:
|
||||
for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
|
||||
if (TREE_CODE (f) == FIELD_DECL)
|
||||
{
|
||||
ftype = TREE_TYPE (f);
|
||||
offset = DECL_FIELD_OFFSET (f);
|
||||
bytepos = int_bit_position (f) / BITS_PER_UNIT;
|
||||
/* Force substructs to be handled as BLKmode even if
|
||||
they're small enough to be recorded as DImode, so we
|
||||
drill through to non-record fields. */
|
||||
submode = TYPE_MODE (ftype);
|
||||
if (TREE_CODE (ftype) == RECORD_TYPE)
|
||||
submode = BLKmode;
|
||||
sub = function_arg (cum, submode, ftype, named);
|
||||
if (sub == NULL_RTX)
|
||||
return NULL_RTX;
|
||||
if (GET_CODE (sub) == PARALLEL)
|
||||
{
|
||||
for (i = 0; i < XVECLEN (sub, 0); i++)
|
||||
{
|
||||
rtx subsub = XVECEXP (sub, 0, i);
|
||||
suboff = XEXP (subsub, 1);
|
||||
subbytepos = INTVAL (suboff);
|
||||
subbytepos += bytepos;
|
||||
roffset = gen_rtx_CONST_INT (SImode, subbytepos);
|
||||
subsub = XEXP (subsub, 0);
|
||||
rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, subsub, roffset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
roffset = gen_rtx_CONST_INT (SImode, bytepos);
|
||||
rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, sub, roffset);
|
||||
}
|
||||
/* Now do an arg advance to get all the cumulative arg
|
||||
stuff set correctly for the next subfield. Note that it
|
||||
has no lasting effect, because it is being done on a
|
||||
temporary copy of the cumulative arg data. */
|
||||
function_arg_advance (cum, submode, ftype, named, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case ARRAY_TYPE:
|
||||
tot = int_size_in_bytes (type);
|
||||
if (tot <= 0)
|
||||
return NULL_RTX;
|
||||
ftype = TREE_TYPE (type);
|
||||
tot /= int_size_in_bytes (ftype);
|
||||
bytepos = 0;
|
||||
|
||||
for (j = 0; j < tot; ++j)
|
||||
{
|
||||
/* Force substructs to be handled as BLKmode even if
|
||||
they're small enough to be recorded as DImode, so we
|
||||
drill through to non-record fields. */
|
||||
submode = TYPE_MODE (ftype);
|
||||
if (TREE_CODE (ftype) == RECORD_TYPE)
|
||||
submode = BLKmode;
|
||||
sub = function_arg (cum, submode, ftype, named);
|
||||
if (sub == NULL_RTX)
|
||||
return NULL_RTX;
|
||||
if (GET_CODE (sub) == PARALLEL)
|
||||
{
|
||||
for (i = 0; i < XVECLEN (sub, 0); i++)
|
||||
{
|
||||
rtx subsub = XVECEXP (sub, 0, i);
|
||||
|
||||
suboff = XEXP (subsub, 1);
|
||||
subbytepos = INTVAL (suboff);
|
||||
subbytepos += bytepos;
|
||||
roffset = gen_rtx_CONST_INT (SImode, subbytepos);
|
||||
subsub = XEXP (subsub, 0);
|
||||
rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, subsub, roffset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
roffset = gen_rtx_CONST_INT (SImode, bytepos);
|
||||
rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, sub, roffset);
|
||||
}
|
||||
/* Now do an arg advance to get all the cumulative arg
|
||||
stuff set correctly for the next subfield. Note that it
|
||||
has no lasting effect, because it is being done on a
|
||||
temporary copy of the cumulative arg data. */
|
||||
function_arg_advance (cum, submode, ftype, named, 1);
|
||||
bytepos += int_size_in_bytes (ftype);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
*cum = saved_cum;
|
||||
if (k > 0)
|
||||
return gen_rtx_PARALLEL (mode, gen_rtvec_v (k, rvec));
|
||||
else
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
/* Determine where to place an argument in 64-bit mode with 32-bit ABI. */
|
||||
|
||||
static rtx
|
||||
@ -5180,6 +5382,13 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
&& (SPE_VECTOR_MODE (mode)
|
||||
|| (TARGET_E500_DOUBLE && mode == DFmode)))
|
||||
return rs6000_spe_function_arg (cum, mode, type);
|
||||
|
||||
else if (rs6000_darwin64_abi
|
||||
&& mode == BLKmode
|
||||
&& (TREE_CODE (type) == RECORD_TYPE
|
||||
|| TREE_CODE (type) == ARRAY_TYPE))
|
||||
return rs6000_darwin64_function_arg (cum, mode, type, named);
|
||||
|
||||
else if (abi == ABI_V4)
|
||||
{
|
||||
if (TARGET_HARD_FLOAT && TARGET_FPRS
|
||||
@ -5454,7 +5663,7 @@ setup_incoming_varargs (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
||||
|
||||
/* Skip the last named argument. */
|
||||
next_cum = *cum;
|
||||
function_arg_advance (&next_cum, mode, type, 1);
|
||||
function_arg_advance (&next_cum, mode, type, 1, 0);
|
||||
|
||||
if (DEFAULT_ABI == ABI_V4)
|
||||
{
|
||||
@ -18127,6 +18336,128 @@ rs6000_complex_function_value (enum machine_mode mode)
|
||||
return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
|
||||
}
|
||||
|
||||
/* Compose a PARALLEL for a darwin64 struct being returned by
|
||||
value. */
|
||||
|
||||
static rtx
|
||||
rs6000_darwin64_function_value (CUMULATIVE_ARGS *cum, tree valtype)
|
||||
{
|
||||
tree f, ftype;
|
||||
rtx rvec[FIRST_PSEUDO_REGISTER], sub, roffset, suboff;
|
||||
int k = 0, bytepos, tot, elt, i, subbytepos;
|
||||
enum machine_mode fmode;
|
||||
|
||||
switch (TREE_CODE (valtype))
|
||||
{
|
||||
case RECORD_TYPE:
|
||||
for (f = TYPE_FIELDS (valtype); f ; f = TREE_CHAIN (f))
|
||||
if (TREE_CODE (f) == FIELD_DECL)
|
||||
{
|
||||
ftype = TREE_TYPE (f);
|
||||
fmode = TYPE_MODE (ftype);
|
||||
bytepos = int_bit_position (f) / BITS_PER_UNIT;
|
||||
if (USE_FP_FOR_ARG_P (cum, fmode, ftype))
|
||||
{
|
||||
sub = gen_rtx_REG (fmode, cum->fregno++);
|
||||
cum->sysv_gregno++;
|
||||
}
|
||||
else if (USE_ALTIVEC_FOR_ARG_P (cum, fmode, ftype, 1))
|
||||
{
|
||||
sub = gen_rtx_REG (fmode, cum->vregno++);
|
||||
cum->sysv_gregno++;
|
||||
}
|
||||
else if (fmode == BLKmode
|
||||
&& (TREE_CODE (ftype) == RECORD_TYPE
|
||||
|| TREE_CODE (ftype) == ARRAY_TYPE))
|
||||
sub = rs6000_darwin64_function_value (cum, ftype);
|
||||
else
|
||||
sub = gen_rtx_REG (fmode, cum->sysv_gregno++);
|
||||
if (sub == NULL_RTX)
|
||||
return sub;
|
||||
else if (GET_CODE (sub) == PARALLEL)
|
||||
{
|
||||
for (i = 0; i < XVECLEN (sub, 0); i++)
|
||||
{
|
||||
rtx subsub = XVECEXP (sub, 0, i);
|
||||
|
||||
suboff = XEXP (subsub, 1);
|
||||
subbytepos = INTVAL (suboff);
|
||||
subbytepos += bytepos;
|
||||
roffset = gen_rtx_CONST_INT (SImode, subbytepos);
|
||||
subsub = XEXP (subsub, 0);
|
||||
rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, subsub, roffset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
roffset = gen_rtx_CONST_INT (SImode, bytepos);
|
||||
rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, sub, roffset);
|
||||
}
|
||||
}
|
||||
if (k > 0)
|
||||
return gen_rtx_PARALLEL (TYPE_MODE (valtype), gen_rtvec_v (k, rvec));
|
||||
else
|
||||
return NULL_RTX;
|
||||
|
||||
case ARRAY_TYPE:
|
||||
/* If passing by value won't work, give up. */
|
||||
if (int_size_in_bytes (valtype) <= 0)
|
||||
return NULL_RTX;
|
||||
ftype = TREE_TYPE (valtype);
|
||||
fmode = TYPE_MODE (ftype);
|
||||
tot = int_size_in_bytes (valtype) / int_size_in_bytes (ftype);
|
||||
bytepos = 0;
|
||||
for (elt = 0; elt < tot; ++elt)
|
||||
{
|
||||
if (USE_FP_FOR_ARG_P (cum, fmode, ftype))
|
||||
{
|
||||
sub = gen_rtx_REG (fmode, cum->fregno++);
|
||||
cum->sysv_gregno++;
|
||||
}
|
||||
else if (USE_ALTIVEC_FOR_ARG_P (cum, fmode, ftype, 1))
|
||||
{
|
||||
sub = gen_rtx_REG (fmode, cum->vregno++);
|
||||
cum->sysv_gregno++;
|
||||
}
|
||||
else if (fmode == BLKmode
|
||||
&& (TREE_CODE (ftype) == RECORD_TYPE
|
||||
|| TREE_CODE (ftype) == ARRAY_TYPE))
|
||||
sub = rs6000_darwin64_function_value (cum, ftype);
|
||||
else
|
||||
sub = gen_rtx_REG (fmode, cum->sysv_gregno++);
|
||||
if (sub == NULL_RTX)
|
||||
return sub;
|
||||
else if (GET_CODE (sub) == PARALLEL)
|
||||
{
|
||||
for (i = 0; i < XVECLEN (sub, 0); i++)
|
||||
{
|
||||
rtx subsub = XVECEXP (sub, 0, i);
|
||||
|
||||
suboff = XEXP (subsub, 1);
|
||||
subbytepos = INTVAL (suboff);
|
||||
subbytepos += bytepos;
|
||||
roffset = gen_rtx_CONST_INT (SImode, subbytepos);
|
||||
subsub = XEXP (subsub, 0);
|
||||
rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, subsub, roffset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
roffset = gen_rtx_CONST_INT (SImode, bytepos);
|
||||
rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, sub, roffset);
|
||||
}
|
||||
bytepos += int_size_in_bytes (ftype);
|
||||
}
|
||||
if (k > 0)
|
||||
return gen_rtx_PARALLEL (TYPE_MODE (valtype), gen_rtvec_v (k, rvec));
|
||||
else
|
||||
return NULL_RTX;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Define how to find the value returned by a function.
|
||||
VALTYPE is the data type of the value (as a tree).
|
||||
If the precise function being called is known, FUNC is its FUNCTION_DECL;
|
||||
@ -18143,6 +18474,24 @@ rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
|
||||
enum machine_mode mode;
|
||||
unsigned int regno;
|
||||
|
||||
/* Special handling for structs in darwin64. */
|
||||
if (rs6000_darwin64_abi
|
||||
&& TYPE_MODE (valtype) == BLKmode
|
||||
&& (TREE_CODE (valtype) == RECORD_TYPE
|
||||
|| TREE_CODE (valtype) == ARRAY_TYPE))
|
||||
{
|
||||
CUMULATIVE_ARGS valcum;
|
||||
rtx valret;
|
||||
|
||||
valcum.sysv_gregno = GP_ARG_RETURN;
|
||||
valcum.fregno = FP_ARG_MIN_REG;
|
||||
valcum.vregno = ALTIVEC_ARG_MIN_REG;
|
||||
valret = rs6000_darwin64_function_value (&valcum, valtype);
|
||||
if (valret)
|
||||
return valret;
|
||||
/* Otherwise fall through to standard ABI rules. */
|
||||
}
|
||||
|
||||
if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode)
|
||||
{
|
||||
/* Long long return value need be split in -mpowerpc64, 32bit ABI. */
|
||||
|
@ -1713,7 +1713,7 @@ typedef struct rs6000_args
|
||||
(TYPE is null for libcalls where that information may not be available.) */
|
||||
|
||||
#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg_advance (&CUM, MODE, TYPE, NAMED)
|
||||
function_arg_advance (&CUM, MODE, TYPE, NAMED, 0)
|
||||
|
||||
/* Determine where to put an argument to a function.
|
||||
Value is zero to push the argument on the stack,
|
||||
|
Loading…
x
Reference in New Issue
Block a user