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:
Julian Brown 2005-04-26 16:30:37 +00:00 committed by Julian Brown
parent 747d0b9644
commit 866af8a909
4 changed files with 118 additions and 4 deletions

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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.