aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/config/spu/spu.c15
-rw-r--r--gcc/config/spu/spu.h7
-rw-r--r--gcc/doc/tm.texi14
-rw-r--r--gcc/doc/tm.texi.in8
-rw-r--r--gcc/function.c5
-rw-r--r--gcc/system.h2
-rw-r--r--gcc/target.def10
-rw-r--r--gcc/targhooks.c8
-rw-r--r--gcc/targhooks.h1
10 files changed, 62 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 498d6b3..509742a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,21 @@
2017-09-15 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
+ * target.def (function_arg_offset): New hook.
+ * targhooks.h (default_function_arg_offset): Declare.
+ * targhooks.c (default_function_arg_offset): New function.
+ * function.c (locate_and_pad_parm): Use
+ targetm.calls.function_arg_offset instead of FUNCTION_ARG_OFFSET.
+ * doc/tm.texi.in (FUNCTION_ARG_OFFSET): Replace with...
+ (TARGET_FUNCTION_ARG_OFFSET): ...this.
+ * doc/tm.texi: Regenerate.
+ * config/spu/spu.h (FUNCTION_ARG_OFFSET): Delete.
+ * config/spu/spu.c (spu_function_arg_offset): New function.
+ (TARGET_FUNCTION_ARG_OFFSET): Redefine.
+ * system.h (FUNCTION_ARG_OFFSET): Poison.
+
+2017-09-15 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayard <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c
index 4ce227b..a35f0b8 100644
--- a/gcc/config/spu/spu.c
+++ b/gcc/config/spu/spu.c
@@ -3881,6 +3881,18 @@ spu_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
: spu_hard_regno_nregs (FIRST_ARG_REGNUM, mode));
}
+/* Implement TARGET_FUNCTION_ARG_OFFSET. The SPU ABI wants 32/64-bit
+ types at offset 0 in the quad-word on the stack. 8/16-bit types
+ should be at offsets 3/2 respectively. */
+
+static HOST_WIDE_INT
+spu_function_arg_offset (machine_mode mode, const_tree type)
+{
+ if (type && INTEGRAL_TYPE_P (type) && GET_MODE_SIZE (mode) < 4)
+ return 4 - GET_MODE_SIZE (mode);
+ return 0;
+}
+
/* Implement TARGET_FUNCTION_ARG_PADDING. */
static pad_direction
@@ -7300,6 +7312,9 @@ static const struct attribute_spec spu_attribute_table[] =
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE spu_function_arg_advance
+#undef TARGET_FUNCTION_ARG_OFFSET
+#define TARGET_FUNCTION_ARG_OFFSET spu_function_arg_offset
+
#undef TARGET_FUNCTION_ARG_PADDING
#define TARGET_FUNCTION_ARG_PADDING spu_function_arg_padding
diff --git a/gcc/config/spu/spu.h b/gcc/config/spu/spu.h
index 3e60e19..4cf426b 100644
--- a/gcc/config/spu/spu.h
+++ b/gcc/config/spu/spu.h
@@ -309,13 +309,6 @@ targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \
#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,FNDECL,N_NAMED_ARGS) \
((CUM) = 0)
-/* The SPU ABI wants 32/64-bit types at offset 0 in the quad-word on the
- stack. 8/16-bit types should be at offsets 3/2 respectively. */
-#define FUNCTION_ARG_OFFSET(MODE, TYPE) \
-(((TYPE) && INTEGRAL_TYPE_P (TYPE) && GET_MODE_SIZE (MODE) < 4) \
- ? (4 - GET_MODE_SIZE (MODE)) \
- : 0)
-
#define PAD_VARARGS_DOWN 0
#define FUNCTION_ARG_REGNO_P(N) ((N) >= (FIRST_ARG_REGNUM) && (N) <= (LAST_ARG_REGNUM))
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 6277e88..ae65e4f 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -4079,13 +4079,13 @@ on the stack. The compiler knows how to track the amount of stack space
used for arguments without any special help.
@end deftypefn
-@defmac FUNCTION_ARG_OFFSET (@var{mode}, @var{type})
-If defined, a C expression that is the number of bytes to add to the
-offset of the argument passed in memory. This is needed for the SPU,
-which passes @code{char} and @code{short} arguments in the preferred
-slot that is in the middle of the quad word instead of starting at the
-top.
-@end defmac
+@deftypefn {Target Hook} HOST_WIDE_INT TARGET_FUNCTION_ARG_OFFSET (machine_mode @var{mode}, const_tree @var{type})
+This hook returns the number of bytes to add to the offset of an
+argument of type @var{type} and mode @var{mode} when passed in memory.
+This is needed for the SPU, which passes @code{char} and @code{short}
+arguments in the preferred slot that is in the middle of the quad word
+instead of starting at the top. The default implementation returns 0.
+@end deftypefn
@deftypefn {Target Hook} pad_direction TARGET_FUNCTION_ARG_PADDING (machine_mode @var{mode}, const_tree @var{type})
This hook determines whether, and in which direction, to pad out
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index c66f8ce..733466d 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3281,13 +3281,7 @@ argument @var{libname} exists for symmetry with
@hook TARGET_FUNCTION_ARG_ADVANCE
-@defmac FUNCTION_ARG_OFFSET (@var{mode}, @var{type})
-If defined, a C expression that is the number of bytes to add to the
-offset of the argument passed in memory. This is needed for the SPU,
-which passes @code{char} and @code{short} arguments in the preferred
-slot that is in the middle of the quad word instead of starting at the
-top.
-@end defmac
+@hook TARGET_FUNCTION_ARG_OFFSET
@hook TARGET_FUNCTION_ARG_PADDING
diff --git a/gcc/function.c b/gcc/function.c
index 41878a9..3ae5a3a 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -4249,9 +4249,8 @@ locate_and_pad_parm (machine_mode passed_mode, tree type, int in_regs,
locate->size.constant -= part_size_in_regs;
}
-#ifdef FUNCTION_ARG_OFFSET
- locate->offset.constant += FUNCTION_ARG_OFFSET (passed_mode, type);
-#endif
+ locate->offset.constant
+ += targetm.calls.function_arg_offset (passed_mode, type);
}
/* Round the stack offset in *OFFSET_PTR up to a multiple of BOUNDARY.
diff --git a/gcc/system.h b/gcc/system.h
index 974d85c..c514cd8 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -915,7 +915,7 @@ extern void fancy_abort (const char *, int, const char *)
MODES_TIEABLE_P FUNCTION_ARG_PADDING SLOW_UNALIGNED_ACCESS \
HARD_REGNO_NREGS SECONDARY_MEMORY_NEEDED_MODE \
SECONDARY_MEMORY_NEEDED CANNOT_CHANGE_MODE_CLASS \
- TRULY_NOOP_TRUNCATION
+ TRULY_NOOP_TRUNCATION FUNCTION_ARG_OFFSET
/* Target macros only used for code built for the target, that have
moved to libgcc-tm.h or have never been present elsewhere. */
diff --git a/gcc/target.def b/gcc/target.def
index 885973b..f4c3576 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -4573,6 +4573,16 @@ used for arguments without any special help.",
default_function_arg_advance)
DEFHOOK
+(function_arg_offset,
+ "This hook returns the number of bytes to add to the offset of an\n\
+argument of type @var{type} and mode @var{mode} when passed in memory.\n\
+This is needed for the SPU, which passes @code{char} and @code{short}\n\
+arguments in the preferred slot that is in the middle of the quad word\n\
+instead of starting at the top. The default implementation returns 0.",
+ HOST_WIDE_INT, (machine_mode mode, const_tree type),
+ default_function_arg_offset)
+
+DEFHOOK
(function_arg_padding,
"This hook determines whether, and in which direction, to pad out\n\
an argument of mode @var{mode} and type @var{type}. It returns\n\
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 98e553c..4bd4833 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -734,6 +734,14 @@ default_function_arg_advance (cumulative_args_t ca ATTRIBUTE_UNUSED,
gcc_unreachable ();
}
+/* Default implementation of TARGET_FUNCTION_ARG_OFFSET. */
+
+HOST_WIDE_INT
+default_function_arg_offset (machine_mode, const_tree)
+{
+ return 0;
+}
+
/* Default implementation of TARGET_FUNCTION_ARG_PADDING: usually pad
upward, but pad short args downward on big-endian machines. */
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 3d03215..6d78508 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -132,6 +132,7 @@ extern const char *hook_invalid_arg_for_unprototyped_fn
(const_tree, const_tree, const_tree);
extern void default_function_arg_advance
(cumulative_args_t, machine_mode, const_tree, bool);
+extern HOST_WIDE_INT default_function_arg_offset (machine_mode, const_tree);
extern pad_direction default_function_arg_padding (machine_mode, const_tree);
extern rtx default_function_arg
(cumulative_args_t, machine_mode, const_tree, bool);