arm.c (arm_return_in_msb): New function.
* config/arm/arm.c (arm_return_in_msb): New function. (arm_must_pass_in_stack): New function. (TARGET_RETURN_IN_MSB): Define target hook. (TARGET_MUST_PASS_IN_STACK): Define target hook. (arm_function_value): Pad small aggregate return. (arm_pad_arg_upward): New function. (arm_pad_reg_upward): New function. * config/arm/arm.h (PROMOTE_FUNCTION_MODE): Include complex values. (FUNCTION_ARG_PADDING): Define macro. (BLOCK_REG_PADDING): Define macro. (PAD_VARARGS_DOWN): Correct padding for AAPCS. * config/arm/arm-protos.h (arm_pad_arg_upward): Declare function. (arm_pad_reg_upward): Declare function. From-SVN: r98774
This commit is contained in:
parent
747d0b9644
commit
866af8a909
@ -1,3 +1,19 @@
|
||||
2005-04-26 Julian Brown <julian@codesourcery.com>
|
||||
|
||||
* config/arm/arm.c (arm_return_in_msb): New function.
|
||||
(arm_must_pass_in_stack): New function.
|
||||
(TARGET_RETURN_IN_MSB): Define target hook.
|
||||
(TARGET_MUST_PASS_IN_STACK): Define target hook.
|
||||
(arm_function_value): Pad small aggregate return.
|
||||
(arm_pad_arg_upward): New function.
|
||||
(arm_pad_reg_upward): New function.
|
||||
* config/arm/arm.h (PROMOTE_FUNCTION_MODE): Include complex values.
|
||||
(FUNCTION_ARG_PADDING): Define macro.
|
||||
(BLOCK_REG_PADDING): Define macro.
|
||||
(PAD_VARARGS_DOWN): Correct padding for AAPCS.
|
||||
* config/arm/arm-protos.h (arm_pad_arg_upward): Declare function.
|
||||
(arm_pad_reg_upward): Declare function.
|
||||
|
||||
2005-04-26 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* basic-block.h (ei_cond): New.
|
||||
|
@ -121,6 +121,8 @@ extern int arm_eliminable_register (rtx);
|
||||
#if defined TREE_CODE
|
||||
extern rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
|
||||
extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
|
||||
extern bool arm_pad_arg_upward (enum machine_mode, tree);
|
||||
extern bool arm_pad_reg_upward (enum machine_mode, tree, int);
|
||||
extern bool arm_needs_doubleword_align (enum machine_mode, tree);
|
||||
extern rtx arm_function_value(tree, tree);
|
||||
#endif
|
||||
|
@ -165,6 +165,8 @@ static bool arm_pass_by_reference (CUMULATIVE_ARGS *,
|
||||
static bool arm_promote_prototypes (tree);
|
||||
static bool arm_default_short_enums (void);
|
||||
static bool arm_align_anon_bitfield (void);
|
||||
static bool arm_return_in_msb (tree);
|
||||
static bool arm_must_pass_in_stack (enum machine_mode, tree);
|
||||
|
||||
static tree arm_cxx_guard_type (void);
|
||||
static bool arm_cxx_guard_mask_bit (void);
|
||||
@ -319,6 +321,12 @@ static unsigned HOST_WIDE_INT arm_shift_truncation_mask (enum machine_mode);
|
||||
#undef TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT
|
||||
#define TARGET_CXX_CLASS_DATA_ALWAYS_COMDAT arm_cxx_class_data_always_comdat
|
||||
|
||||
#undef TARGET_RETURN_IN_MSB
|
||||
#define TARGET_RETURN_IN_MSB arm_return_in_msb
|
||||
|
||||
#undef TARGET_MUST_PASS_IN_STACK
|
||||
#define TARGET_MUST_PASS_IN_STACK arm_must_pass_in_stack
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
/* Obstack for minipool constant handling. */
|
||||
@ -2302,11 +2310,23 @@ arm_function_value(tree type, tree func ATTRIBUTE_UNUSED)
|
||||
int unsignedp ATTRIBUTE_UNUSED;
|
||||
rtx r ATTRIBUTE_UNUSED;
|
||||
|
||||
|
||||
mode = TYPE_MODE (type);
|
||||
/* Promote integer types. */
|
||||
if (INTEGRAL_TYPE_P (type))
|
||||
PROMOTE_FUNCTION_MODE (mode, unsignedp, type);
|
||||
|
||||
/* Promotes small structs returned in a register to full-word size
|
||||
for big-endian AAPCS. */
|
||||
if (arm_return_in_msb (type))
|
||||
{
|
||||
HOST_WIDE_INT size = int_size_in_bytes (type);
|
||||
if (size % UNITS_PER_WORD != 0)
|
||||
{
|
||||
size += UNITS_PER_WORD - size % UNITS_PER_WORD;
|
||||
mode = mode_for_size (size * BITS_PER_UNIT, MODE_INT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return LIBCALL_VALUE(mode);
|
||||
}
|
||||
|
||||
@ -4905,6 +4925,17 @@ vfp_secondary_reload_class (enum machine_mode mode, rtx x)
|
||||
return GENERAL_REGS;
|
||||
}
|
||||
|
||||
/* Values which must be returned in the most-significant end of the return
|
||||
register. */
|
||||
|
||||
static bool
|
||||
arm_return_in_msb (tree valtype)
|
||||
{
|
||||
return (TARGET_AAPCS_BASED
|
||||
&& BYTES_BIG_ENDIAN
|
||||
&& (AGGREGATE_TYPE_P (valtype)
|
||||
|| TREE_CODE (valtype) == COMPLEX_TYPE));
|
||||
}
|
||||
|
||||
/* Returns TRUE if INSN is an "LDR REG, ADDR" instruction.
|
||||
Use by the Cirrus Maverick code which has to workaround
|
||||
@ -6503,6 +6534,59 @@ arm_reload_out_hi (rtx *operands)
|
||||
gen_lowpart (QImode, scratch)));
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true if a type must be passed in memory. For AAPCS, small aggregates
|
||||
(padded to the size of a word) should be passed in a register. */
|
||||
|
||||
static bool
|
||||
arm_must_pass_in_stack (enum machine_mode mode, tree type)
|
||||
{
|
||||
if (TARGET_AAPCS_BASED)
|
||||
return must_pass_in_stack_var_size (mode, type);
|
||||
else
|
||||
return must_pass_in_stack_var_size_or_pad (mode, type);
|
||||
}
|
||||
|
||||
|
||||
/* For use by FUNCTION_ARG_PADDING (MODE, TYPE).
|
||||
Return true if an argument passed on the stack should be padded upwards,
|
||||
i.e. if the least-significant byte has useful data. */
|
||||
|
||||
bool
|
||||
arm_pad_arg_upward (enum machine_mode mode, tree type)
|
||||
{
|
||||
if (!TARGET_AAPCS_BASED)
|
||||
return DEFAULT_FUNCTION_ARG_PADDING(mode, type);
|
||||
|
||||
if (type && BYTES_BIG_ENDIAN && INTEGRAL_TYPE_P (type))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Similarly, for use by BLOCK_REG_PADDING (MODE, TYPE, FIRST).
|
||||
For non-AAPCS, return !BYTES_BIG_ENDIAN if the least significant
|
||||
byte of the register has useful data, and return the opposite if the
|
||||
most significant byte does.
|
||||
For AAPCS, small aggregates and small complex types are always padded
|
||||
upwards. */
|
||||
|
||||
bool
|
||||
arm_pad_reg_upward (enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||
tree type, int first ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (TARGET_AAPCS_BASED
|
||||
&& BYTES_BIG_ENDIAN
|
||||
&& (AGGREGATE_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE)
|
||||
&& int_size_in_bytes (type) <= 4)
|
||||
return true;
|
||||
|
||||
/* Otherwise, use default padding. */
|
||||
return !BYTES_BIG_ENDIAN;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Print a symbolic form of X to the debug file, F. */
|
||||
static void
|
||||
|
@ -607,9 +607,10 @@ extern int arm_cpp_interwork;
|
||||
}
|
||||
|
||||
#define PROMOTE_FUNCTION_MODE(MODE, UNSIGNEDP, TYPE) \
|
||||
if (GET_MODE_CLASS (MODE) == MODE_INT \
|
||||
&& GET_MODE_SIZE (MODE) < 4) \
|
||||
(MODE) = SImode; \
|
||||
if ((GET_MODE_CLASS (MODE) == MODE_INT \
|
||||
|| GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT) \
|
||||
&& GET_MODE_SIZE (MODE) < 4) \
|
||||
(MODE) = SImode; \
|
||||
|
||||
/* Define this if most significant bit is lowest numbered
|
||||
in instructions that operate on numbered bit-fields. */
|
||||
@ -1761,6 +1762,17 @@ typedef struct
|
||||
#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
|
||||
arm_function_arg (&(CUM), (MODE), (TYPE), (NAMED))
|
||||
|
||||
#define FUNCTION_ARG_PADDING(MODE, TYPE) \
|
||||
(arm_pad_arg_upward (MODE, TYPE) ? upward : downward)
|
||||
|
||||
#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
|
||||
(arm_pad_reg_upward (MODE, TYPE, FIRST) ? upward : downward)
|
||||
|
||||
/* For AAPCS, padding should never be below the argument. For other ABIs,
|
||||
* mimic the default. */
|
||||
#define PAD_VARARGS_DOWN \
|
||||
((TARGET_AAPCS_BASED) ? 0 : BYTES_BIG_ENDIAN)
|
||||
|
||||
/* Initialize a variable CUM of type CUMULATIVE_ARGS
|
||||
for a call to a function whose data type is FNTYPE.
|
||||
For a library call, FNTYPE is 0.
|
||||
|
Loading…
Reference in New Issue
Block a user