calls.c (initialize_argument_information): If an argument has no stack space associated with it...
* calls.c (initialize_argument_information): If an argument has no stack space associated with it, and BLOCK_REG_PADDING is defined, use it to decide at which end the argument should be padded. * function.c (assign_parms): Allocate BLKmode stack slots. * config/mips/mips-protos.h (mips_pad_arg_upward): Declare. (mips_pad_reg_upward): Declare. * config/mips/mips.h (PAD_VARARGS_DOWN): Use FUNCTION_ARG_PADDING. (CUMULATIVE_ARGS): Remove num_adjusts and adjusts. (FUNCTION_ARG_PADDING): Use mips_pad_arg_upward. (BLOCK_REG_PADDING): Use mips_pad_reg_upward. * config/mips/mips.c (struct mips_arg_info): Remove struct_p. (mips_expand_call): Remove code for generating structure shifts. (mips_arg_info): Don't set struct_p. Don't set fpr_p for non-float types unless using the EABI. (function_arg_advance): Don't generate shift instructions. (function_arg): Don't return them. Don't short-circuit the check for double structure chunks for DFmode arguments. (mips_pad_arg_upward, mips_pad_reg_upward): New functions. (mips_expand_prologue): Remove code to emit structure shifts. * config/mips/irix6-libc-compat.c: Remove workarounds for buggy structure passing (inet_ntoa, inet_lnaof, inet_netof). Update comments to say that only structure returns are a problem. From-SVN: r70843
This commit is contained in:
parent
0c7829a97b
commit
648bb15912
|
@ -1,3 +1,28 @@
|
|||
2003-08-27 Richard Sandiford <rsandifo@redhat.com>
|
||||
|
||||
* calls.c (initialize_argument_information): If an argument has no
|
||||
stack space associated with it, and BLOCK_REG_PADDING is defined,
|
||||
use it to decide at which end the argument should be padded.
|
||||
* function.c (assign_parms): Allocate BLKmode stack slots.
|
||||
* config/mips/mips-protos.h (mips_pad_arg_upward): Declare.
|
||||
(mips_pad_reg_upward): Declare.
|
||||
* config/mips/mips.h (PAD_VARARGS_DOWN): Use FUNCTION_ARG_PADDING.
|
||||
(CUMULATIVE_ARGS): Remove num_adjusts and adjusts.
|
||||
(FUNCTION_ARG_PADDING): Use mips_pad_arg_upward.
|
||||
(BLOCK_REG_PADDING): Use mips_pad_reg_upward.
|
||||
* config/mips/mips.c (struct mips_arg_info): Remove struct_p.
|
||||
(mips_expand_call): Remove code for generating structure shifts.
|
||||
(mips_arg_info): Don't set struct_p. Don't set fpr_p for non-float
|
||||
types unless using the EABI.
|
||||
(function_arg_advance): Don't generate shift instructions.
|
||||
(function_arg): Don't return them. Don't short-circuit the
|
||||
check for double structure chunks for DFmode arguments.
|
||||
(mips_pad_arg_upward, mips_pad_reg_upward): New functions.
|
||||
(mips_expand_prologue): Remove code to emit structure shifts.
|
||||
* config/mips/irix6-libc-compat.c: Remove workarounds for buggy
|
||||
structure passing (inet_ntoa, inet_lnaof, inet_netof). Update
|
||||
comments to say that only structure returns are a problem.
|
||||
|
||||
2003-08-26 Nathanael Nerode <neroden@gcc.gnu.org>
|
||||
|
||||
* fixinc/tests/base/string.h, fixinc/tests/base/sys/regset.h:
|
||||
|
|
|
@ -1238,6 +1238,14 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
|
|||
#endif
|
||||
args[i].pass_on_stack ? 0 : args[i].partial,
|
||||
fndecl, args_size, &args[i].locate);
|
||||
#ifdef BLOCK_REG_PADDING
|
||||
else
|
||||
/* The argument is passed entirely in registers. See at which
|
||||
end it should be padded. */
|
||||
args[i].locate.where_pad =
|
||||
BLOCK_REG_PADDING (mode, type,
|
||||
int_size_in_bytes (type) <= UNITS_PER_WORD);
|
||||
#endif
|
||||
|
||||
/* Update ARGS_SIZE, the total stack space for args so far. */
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Compensate for inconsistent structure passing conventions on IRIX 6. */
|
||||
/* Compensate for inconsistent structure return conventions on IRIX 6. */
|
||||
/* Compile this one with gcc. */
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
|
||||
|
@ -28,7 +28,7 @@ along with GNU CC; see the file COPYING. If not, write to
|
|||
the Free Software Foundation, 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* GCC doesn't correctly implement the structure and union passing and return
|
||||
/* GCC doesn't correctly implement the structure and union return
|
||||
conventions of the N32 and N64 ABIs on IRIX 6, as described in the
|
||||
MIPSpro N32 ABI Handbook, ch. 2, Calling Convention Implementations, p.7.
|
||||
The ABI requires that structures (or trailing parts of structures) smaller
|
||||
|
@ -38,17 +38,15 @@ Boston, MA 02111-1307, USA. */
|
|||
While GCC is internally consistent, calling routines compiled with a
|
||||
compiler that does implement the documented ABI (like SGIs MIPSpro C
|
||||
compiler) doesn't work. This is primarily an issue for system libraries
|
||||
like libc. Fortunately, there exist only very few routines that take
|
||||
structure value arguments or return structures by value, so until the
|
||||
underlying bug is fixed, it is possible to work around it by providing
|
||||
wrapper functions for the few affected routines that compensate for the
|
||||
inconsistent alignment.
|
||||
like libc. Fortunately, there exist only very few routines that return
|
||||
structures by value, so until the underlying bug is fixed, it is possible
|
||||
to work around it by providing wrappers for the few affected routines.
|
||||
|
||||
These wrappers rely on the fact that e.g. libc contains weak versions of
|
||||
those routines, and the real implementation is provided by _-prefixed
|
||||
variants. So we can provide our own versions, which will only be linked
|
||||
if the application uses any of the affected functions, calling the private
|
||||
variants after shifting the arguments or results as required.
|
||||
variants and then shifting the result as required.
|
||||
|
||||
This is a rewrite of code created by Andy Polyakov. */
|
||||
|
||||
|
@ -61,60 +59,15 @@ Boston, MA 02111-1307, USA. */
|
|||
|
||||
#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64
|
||||
|
||||
/* The affected arguments need to be shifted by
|
||||
/* The affected return values need to be shifted by
|
||||
|
||||
BITS_PER_WORD - (sizeof (arg) * BITS_PER_UNIT).
|
||||
BITS_PER_WORD - (sizeof (value) * BITS_PER_UNIT).
|
||||
|
||||
Since only 32-bit args and results are involved, the shift count is
|
||||
always 32. */
|
||||
Since only 32-bit results are involved, the shift count is always 32. */
|
||||
#define SHIFT_BITS 32
|
||||
|
||||
extern machreg_t inet_ntoa (machreg_t);
|
||||
extern machreg_t inet_lnaof (machreg_t);
|
||||
extern machreg_t inet_netof (machreg_t);
|
||||
extern machreg_t inet_makeaddr (machreg_t, machreg_t);
|
||||
|
||||
extern machreg_t _inet_ntoa (machreg_t);
|
||||
extern machreg_t _inet_lnaof (machreg_t);
|
||||
extern machreg_t _inet_netof (machreg_t);
|
||||
extern machreg_t _inet_makeaddr (machreg_t, machreg_t);
|
||||
|
||||
/* <arpa/inet.h> has
|
||||
|
||||
char *inet_ntoa (struct in_addr);
|
||||
|
||||
on both IRIX 6.2 and 6.5, with struct in_addr containing a 32-bit int. */
|
||||
|
||||
machreg_t
|
||||
inet_ntoa (machreg_t in)
|
||||
{
|
||||
return _inet_ntoa (in << SHIFT_BITS);
|
||||
}
|
||||
|
||||
/* <arpa/inet.h> has
|
||||
|
||||
unsigned long inet_lnaof (struct in_addr); (IRIX 6.2)
|
||||
in_addr_t inet_lnaof (struct in_addr); (IRIX 6.5)
|
||||
|
||||
in_addr_t is a 32-bit int. */
|
||||
|
||||
machreg_t
|
||||
inet_lnaof (machreg_t in)
|
||||
{
|
||||
return _inet_lnaof (in << SHIFT_BITS);
|
||||
}
|
||||
|
||||
/* <arpa/inet.h> has
|
||||
|
||||
unsigned long inet_netof (struct in_addr); (IRIX 6.2)
|
||||
in_addr_t inet_netof (struct in_addr); (IRIX 6.5) */
|
||||
|
||||
machreg_t
|
||||
inet_netof (machreg_t in)
|
||||
{
|
||||
return _inet_netof (in << SHIFT_BITS);
|
||||
}
|
||||
|
||||
/* <arpa/inet.h> has
|
||||
|
||||
struct in_addr inet_makeaddr (int, int); (IRIX 6.2)
|
||||
|
@ -126,23 +79,4 @@ inet_makeaddr (machreg_t net, machreg_t lna)
|
|||
return _inet_makeaddr (net, lna) >> SHIFT_BITS;
|
||||
}
|
||||
|
||||
#if _MIPS_SIM == _ABIN32
|
||||
extern machreg_t semctl (machreg_t, machreg_t, machreg_t, machreg_t);
|
||||
extern machreg_t _semctl (machreg_t, machreg_t, machreg_t, machreg_t);
|
||||
|
||||
/* <sys/sem.h> has
|
||||
|
||||
int semctl (int, int, int, ...);
|
||||
|
||||
where the variadic argument is union semun if used. union semun contains
|
||||
an int and two pointers, so the union is already 64 bits wide under the
|
||||
N64 ABI and alignment is not an issue. */
|
||||
|
||||
machreg_t
|
||||
semctl (machreg_t semid, machreg_t semnum, machreg_t cmd, machreg_t arg)
|
||||
{
|
||||
return _semctl(semid, semnum, cmd, arg << SHIFT_BITS);
|
||||
}
|
||||
#endif /* _ABIN32 */
|
||||
|
||||
#endif /* _ABIN32 || _ABI64 */
|
||||
|
|
|
@ -80,6 +80,8 @@ extern struct rtx_def *function_arg (const CUMULATIVE_ARGS *,
|
|||
enum machine_mode, tree, int);
|
||||
extern int function_arg_partial_nregs (const CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int);
|
||||
extern bool mips_pad_arg_upward (enum machine_mode, tree);
|
||||
extern bool mips_pad_reg_upward (enum machine_mode, tree);
|
||||
extern int mips_setup_incoming_varargs (const CUMULATIVE_ARGS *,
|
||||
enum machine_mode, tree, int);
|
||||
extern tree mips_build_va_list (void);
|
||||
|
|
|
@ -317,9 +317,6 @@ struct machine_function GTY(()) {
|
|||
/* Information about a single argument. */
|
||||
struct mips_arg_info
|
||||
{
|
||||
/* True if the argument is a record or union type. */
|
||||
bool struct_p;
|
||||
|
||||
/* True if the argument is passed in a floating-point register, or
|
||||
would have been if we hadn't run out of registers. */
|
||||
bool fpr_p;
|
||||
|
@ -3208,8 +3205,6 @@ mips_gen_conditional_trap (rtx *operands)
|
|||
void
|
||||
mips_expand_call (rtx result, rtx addr, rtx args_size, rtx aux, int sibcall_p)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!call_insn_operand (addr, VOIDmode))
|
||||
{
|
||||
/* When generating PIC, try to allow global functions to be
|
||||
|
@ -3226,16 +3221,6 @@ mips_expand_call (rtx result, rtx addr, rtx args_size, rtx aux, int sibcall_p)
|
|||
addr = force_reg (Pmode, addr);
|
||||
}
|
||||
|
||||
/* In order to pass small structures by value in registers
|
||||
compatibly with the MIPS compiler, we need to shift the value
|
||||
into the high part of the register. Function_arg has encoded
|
||||
a PARALLEL rtx, holding a vector of adjustments to be made
|
||||
as the next_arg_reg variable, so we split up the insns,
|
||||
and emit them separately. */
|
||||
if (aux != 0 && GET_CODE (aux) == PARALLEL)
|
||||
for (i = 0; i < XVECLEN (aux, 0); i++)
|
||||
emit_insn (XVECEXP (aux, 0, i));
|
||||
|
||||
if (TARGET_MIPS16
|
||||
&& mips16_hard_float
|
||||
&& build_mips16_call_stub (result, addr, args_size,
|
||||
|
@ -3557,34 +3542,27 @@ mips_arg_info (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
bool even_reg_p;
|
||||
unsigned int num_words, max_regs;
|
||||
|
||||
info->struct_p = (type != 0
|
||||
&& (TREE_CODE (type) == RECORD_TYPE
|
||||
|| TREE_CODE (type) == UNION_TYPE
|
||||
|| TREE_CODE (type) == QUAL_UNION_TYPE));
|
||||
|
||||
/* Decide whether this argument should go in a floating-point register,
|
||||
assuming one is free. Later code checks for availability. */
|
||||
|
||||
info->fpr_p = false;
|
||||
if (GET_MODE_CLASS (mode) == MODE_FLOAT
|
||||
&& GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE)
|
||||
{
|
||||
switch (mips_abi)
|
||||
{
|
||||
case ABI_32:
|
||||
case ABI_O64:
|
||||
info->fpr_p = (!cum->gp_reg_found && cum->arg_number < 2);
|
||||
break;
|
||||
info->fpr_p = (GET_MODE_CLASS (mode) == MODE_FLOAT
|
||||
&& GET_MODE_SIZE (mode) <= UNITS_PER_FPVALUE);
|
||||
|
||||
case ABI_EABI:
|
||||
info->fpr_p = true;
|
||||
break;
|
||||
if (info->fpr_p)
|
||||
switch (mips_abi)
|
||||
{
|
||||
case ABI_32:
|
||||
case ABI_O64:
|
||||
info->fpr_p = (!cum->gp_reg_found
|
||||
&& cum->arg_number < 2
|
||||
&& (type == 0 || FLOAT_TYPE_P (type)));
|
||||
break;
|
||||
|
||||
default:
|
||||
info->fpr_p = named;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case ABI_N32:
|
||||
case ABI_64:
|
||||
info->fpr_p = (named && (type == 0 || FLOAT_TYPE_P (type)));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Now decide whether the argument must go in an even-numbered register. */
|
||||
|
||||
|
@ -3648,36 +3626,6 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
|
||||
mips_arg_info (cum, mode, type, named, &info);
|
||||
|
||||
/* The following is a hack in order to pass 1 byte structures
|
||||
the same way that the MIPS compiler does (namely by passing
|
||||
the structure in the high byte or half word of the register).
|
||||
This also makes varargs work. If we have such a structure,
|
||||
we save the adjustment RTL, and the call define expands will
|
||||
emit them. For the VOIDmode argument (argument after the
|
||||
last real argument), pass back a parallel vector holding each
|
||||
of the adjustments. */
|
||||
|
||||
/* ??? This scheme requires everything smaller than the word size to
|
||||
shifted to the left, but when TARGET_64BIT and ! TARGET_INT64,
|
||||
that would mean every int needs to be shifted left, which is very
|
||||
inefficient. Let's not carry this compatibility to the 64 bit
|
||||
calling convention for now. */
|
||||
|
||||
if (info.struct_p
|
||||
&& info.reg_words == 1
|
||||
&& info.num_bytes < UNITS_PER_WORD
|
||||
&& !TARGET_64BIT
|
||||
&& mips_abi != ABI_EABI)
|
||||
{
|
||||
rtx amount = GEN_INT (BITS_PER_WORD - info.num_bytes * BITS_PER_UNIT);
|
||||
rtx reg = gen_rtx_REG (word_mode, GP_ARG_FIRST + info.reg_offset);
|
||||
|
||||
if (TARGET_64BIT)
|
||||
cum->adjust[cum->num_adjusts++] = PATTERN (gen_ashldi3 (reg, reg, amount));
|
||||
else
|
||||
cum->adjust[cum->num_adjusts++] = PATTERN (gen_ashlsi3 (reg, reg, amount));
|
||||
}
|
||||
|
||||
if (!info.fpr_p)
|
||||
cum->gp_reg_found = true;
|
||||
|
||||
|
@ -3708,18 +3656,11 @@ function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
|
||||
/* We will be called with a mode of VOIDmode after the last argument
|
||||
has been seen. Whatever we return will be passed to the call
|
||||
insn. If we need any shifts for small structures, return them in
|
||||
a PARALLEL; in that case, stuff the mips16 fp_code in as the
|
||||
mode. Otherwise, if we need a mips16 fp_code, return a REG
|
||||
with the code stored as the mode. */
|
||||
insn. If we need a mips16 fp_code, return a REG with the code
|
||||
stored as the mode. */
|
||||
if (mode == VOIDmode)
|
||||
{
|
||||
if (cum->num_adjusts > 0)
|
||||
return gen_rtx_PARALLEL ((enum machine_mode) cum->fp_code,
|
||||
gen_rtvec_v (cum->num_adjusts,
|
||||
(rtx *) cum->adjust));
|
||||
|
||||
else if (TARGET_MIPS16 && cum->fp_code != 0)
|
||||
if (TARGET_MIPS16 && cum->fp_code != 0)
|
||||
return gen_rtx_REG ((enum machine_mode) cum->fp_code, 0);
|
||||
|
||||
else
|
||||
|
@ -3737,8 +3678,7 @@ function_arg (const CUMULATIVE_ARGS *cum, enum machine_mode mode,
|
|||
&& (mips_abi == ABI_N32 || mips_abi == ABI_64)
|
||||
&& TYPE_SIZE_UNIT (type)
|
||||
&& host_integerp (TYPE_SIZE_UNIT (type), 1)
|
||||
&& named
|
||||
&& mode != DFmode)
|
||||
&& named)
|
||||
{
|
||||
/* The Irix 6 n32/n64 ABIs say that if any 64 bit chunk of the
|
||||
structure contains a double in its entirety, then that 64 bit
|
||||
|
@ -3815,6 +3755,55 @@ function_arg_partial_nregs (const CUMULATIVE_ARGS *cum,
|
|||
mips_arg_info (cum, mode, type, named, &info);
|
||||
return info.stack_words > 0 ? info.reg_words : 0;
|
||||
}
|
||||
|
||||
|
||||
/* Return true if FUNCTION_ARG_PADDING (MODE, TYPE) should return
|
||||
upward rather than downward. In other words, return true if the
|
||||
first byte of the stack slot has useful data, false if the last
|
||||
byte does. */
|
||||
|
||||
bool
|
||||
mips_pad_arg_upward (enum machine_mode mode, tree type)
|
||||
{
|
||||
/* On little-endian targets, the first byte of every stack argument
|
||||
is passed in the first byte of the stack slot. */
|
||||
if (!BYTES_BIG_ENDIAN)
|
||||
return true;
|
||||
|
||||
/* Otherwise, integral types are padded downward: the last byte of a
|
||||
stack argument is passed in the last byte of the stack slot. */
|
||||
if (type != 0
|
||||
? INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)
|
||||
: GET_MODE_CLASS (mode) == MODE_INT)
|
||||
return false;
|
||||
|
||||
/* Other types are padded upward for o32, o64, n32 and n64. */
|
||||
if (mips_abi != ABI_EABI)
|
||||
return true;
|
||||
|
||||
/* Arguments smaller than a stack slot are padded downward. */
|
||||
if (mode != BLKmode)
|
||||
return (GET_MODE_BITSIZE (mode) >= PARM_BOUNDARY);
|
||||
else
|
||||
return (int_size_in_bytes (type) >= (PARM_BOUNDARY / BITS_PER_UNIT));
|
||||
}
|
||||
|
||||
|
||||
/* Likewise BLOCK_REG_PADDING (MODE, TYPE, ...). Return !BYTES_BIG_ENDIAN
|
||||
if the least significant byte of the register has useful data. Return
|
||||
the opposite if the most significant byte does. */
|
||||
|
||||
bool
|
||||
mips_pad_reg_upward (enum machine_mode mode, tree type)
|
||||
{
|
||||
/* No shifting is required for floating-point arguments. */
|
||||
if (type != 0 ? FLOAT_TYPE_P (type) : GET_MODE_CLASS (mode) == MODE_FLOAT)
|
||||
return !BYTES_BIG_ENDIAN;
|
||||
|
||||
/* Otherwise, apply the same padding to register arguments as we do
|
||||
to stack arguments. */
|
||||
return mips_pad_arg_upward (mode, type);
|
||||
}
|
||||
|
||||
int
|
||||
mips_setup_incoming_varargs (const CUMULATIVE_ARGS *cum,
|
||||
|
@ -6716,8 +6705,6 @@ mips_expand_prologue (void)
|
|||
tree fndecl = current_function_decl;
|
||||
tree fntype = TREE_TYPE (fndecl);
|
||||
tree fnargs = DECL_ARGUMENTS (fndecl);
|
||||
rtx next_arg_reg;
|
||||
int i;
|
||||
tree cur_arg;
|
||||
CUMULATIVE_ARGS args_so_far;
|
||||
rtx reg_18_save = NULL_RTX;
|
||||
|
@ -6757,39 +6744,6 @@ mips_expand_prologue (void)
|
|||
FUNCTION_ARG_ADVANCE (args_so_far, passed_mode, passed_type, 1);
|
||||
}
|
||||
|
||||
/* In order to pass small structures by value in registers compatibly with
|
||||
the MIPS compiler, we need to shift the value into the high part of the
|
||||
register. Function_arg has encoded a PARALLEL rtx, holding a vector of
|
||||
adjustments to be made as the next_arg_reg variable, so we split up the
|
||||
insns, and emit them separately. */
|
||||
|
||||
next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
|
||||
if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL)
|
||||
{
|
||||
rtvec adjust = XVEC (next_arg_reg, 0);
|
||||
int num = GET_NUM_ELEM (adjust);
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
rtx insn, pattern;
|
||||
|
||||
pattern = RTVEC_ELT (adjust, i);
|
||||
if (GET_CODE (pattern) != SET
|
||||
|| GET_CODE (SET_SRC (pattern)) != ASHIFT)
|
||||
fatal_insn ("insn is not a shift", pattern);
|
||||
PUT_CODE (SET_SRC (pattern), ASHIFTRT);
|
||||
|
||||
insn = emit_insn (pattern);
|
||||
|
||||
/* Global life information isn't valid at this point, so we
|
||||
can't check whether these shifts are actually used. Mark
|
||||
them MAYBE_DEAD so that flow2 will remove them, and not
|
||||
complain about dead code in the prologue. */
|
||||
REG_NOTES(insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, NULL_RTX,
|
||||
REG_NOTES (insn));
|
||||
}
|
||||
}
|
||||
|
||||
tsize = compute_frame_size (get_frame_size ());
|
||||
|
||||
/* If we are using the entry pseudo instruction, it will
|
||||
|
|
|
@ -1399,9 +1399,8 @@ extern const struct mips_cpu_info *mips_tune_info;
|
|||
|| TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
|
||||
|
||||
|
||||
/* Force right-alignment for small varargs in 32 bit little_endian mode */
|
||||
|
||||
#define PAD_VARARGS_DOWN (TARGET_64BIT ? BYTES_BIG_ENDIAN : !BYTES_BIG_ENDIAN)
|
||||
#define PAD_VARARGS_DOWN \
|
||||
(FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
|
||||
|
||||
/* Arguments declared as 'char' or 'short' in a prototype should be
|
||||
passed as 'int's. */
|
||||
|
@ -2295,15 +2294,6 @@ typedef struct mips_args {
|
|||
|
||||
/* True if the function has a prototype. */
|
||||
int prototype;
|
||||
|
||||
/* When a structure does not take up a full register, the argument
|
||||
should sometimes be shifted left so that it occupies the high part
|
||||
of the register. These two fields describe an array of ashl
|
||||
patterns for doing this. See function_arg_advance, which creates
|
||||
the shift patterns, and function_arg, which returns them when given
|
||||
a VOIDmode argument. */
|
||||
unsigned int num_adjusts;
|
||||
rtx adjust[BIGGEST_MAX_ARGS_IN_REGISTERS];
|
||||
} CUMULATIVE_ARGS;
|
||||
|
||||
/* Initialize a variable CUM of type CUMULATIVE_ARGS
|
||||
|
@ -2361,18 +2351,11 @@ typedef struct mips_args {
|
|||
#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
|
||||
function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED)
|
||||
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
(! BYTES_BIG_ENDIAN \
|
||||
? upward \
|
||||
: (((MODE) == BLKmode \
|
||||
? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \
|
||||
&& int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT))\
|
||||
: (GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY \
|
||||
&& (mips_abi == ABI_32 \
|
||||
|| mips_abi == ABI_O64 \
|
||||
|| mips_abi == ABI_EABI \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_INT))) \
|
||||
? downward : upward))
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
(mips_pad_arg_upward (MODE, TYPE) ? upward : downward)
|
||||
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
(mips_pad_reg_upward (MODE, TYPE) ? upward : downward)
|
||||
|
||||
#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \
|
||||
(mips_abi == ABI_EABI && (NAMED) \
|
||||
|
|
|
@ -4674,9 +4674,8 @@ assign_parms (tree fndecl)
|
|||
|
||||
if (stack_parm == 0)
|
||||
{
|
||||
stack_parm
|
||||
= assign_stack_local (GET_MODE (entry_parm),
|
||||
size_stored, 0);
|
||||
stack_parm = assign_stack_local (BLKmode, size_stored, 0);
|
||||
PUT_MODE (stack_parm, GET_MODE (entry_parm));
|
||||
set_mem_attributes (stack_parm, parm, 1);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue