summaryrefslogtreecommitdiffstats
path: root/gcc
diff options
context:
space:
mode:
authorjules <jules@138bc75d-0d04-0410-961f-82ee72b054a4>2005-04-26 16:30:37 +0000
committerjules <jules@138bc75d-0d04-0410-961f-82ee72b054a4>2005-04-26 16:30:37 +0000
commit46b5d8784dd14caa491b6ccbb8397c0e3cf489cb (patch)
treedd496ead09510fc6c073f86dd74831a32b92e7d6 /gcc
parent866da9a19f17f696324711437cf21734a1f92255 (diff)
downloadppe42-gcc-46b5d8784dd14caa491b6ccbb8397c0e3cf489cb.tar.gz
ppe42-gcc-46b5d8784dd14caa491b6ccbb8397c0e3cf489cb.zip
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@98774 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/arm/arm-protos.h2
-rw-r--r--gcc/config/arm/arm.c86
-rw-r--r--gcc/config/arm/arm.h18
4 files changed, 118 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2d441c43cab..07c96a5372f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 087b475a96b..0d20eb8fd44 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -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
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 8189909f2eb..cd529365c2f 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -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
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 5955a52ad85..61ff2133c5f 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -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.
OpenPOWER on IntegriCloud