summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2015-11-25 12:14:05 -0800
committerH.J. Lu <hjl.tools@gmail.com>2016-04-16 07:47:40 -0700
commit45e9334d8ae95ab3724811c7d712a627dee5b5cd (patch)
treefd880d8ec475d9ca8c3c9155c594f3915d5b5a84
parent2ca55c0355be5423cbf253fe5c2b3d14afbebe81 (diff)
downloadgcc-45e9334d8ae95ab3724811c7d712a627dee5b5cd.tar.gz
Update TARGET_FUNCTION_INCOMING_ARG documentation
On x86, interrupt handlers are only called by processors which push interrupt data onto stack at the address where the normal return address is. Since interrupt handlers must access interrupt data via pointers so that they can update interrupt data, the pointer argument is passed as "argument pointer - word". TARGET_FUNCTION_INCOMING_ARG defines how callee sees its argument. Normally it returns REG, NULL, or CONST_INT. This patch adds arbitrary address computation based on hard register, which can be forced into a register, to the list. When copying an incoming argument onto stack, assign_parm_setup_stack has: if (argument in memory) copy argument in memory to stack else move argument to stack Since an arbitrary address computation may be passed as an argument, we change it to: if (argument in memory) copy argument in memory to stack else { if (argument isn't in register) force argument into a register move argument to stack } * function.c (assign_parm_setup_stack): Force source into a register if needed. * target.def (function_incoming_arg): Update documentation to allow arbitrary address computation based on hard register. * doc/tm.texi: Regenerated.
-rw-r--r--gcc/doc/tm.texi4
-rw-r--r--gcc/function.c6
-rw-r--r--gcc/target.def8
3 files changed, 15 insertions, 3 deletions
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index e32e77ea14a..b252d6d6a40 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -3941,6 +3941,10 @@ which the caller passes the value, and
fashion to tell the function being called where the arguments will
arrive.
+@code{TARGET_FUNCTION_INCOMING_ARG} can also return arbitrary address
+computation using hard register, which can be forced into a register,
+so that it can be used to pass special arguments.
+
If @code{TARGET_FUNCTION_INCOMING_ARG} is not defined,
@code{TARGET_FUNCTION_ARG} serves both purposes.
@end deftypefn
diff --git a/gcc/function.c b/gcc/function.c
index 5059cdf634b..7299936991a 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -3360,7 +3360,11 @@ assign_parm_setup_stack (struct assign_parm_data_all *all, tree parm,
BLOCK_OP_NORMAL);
}
else
- emit_move_insn (dest, src);
+ {
+ if (!REG_P (src))
+ src = force_reg (GET_MODE (src), src);
+ emit_move_insn (dest, src);
+ }
}
if (to_conversion)
diff --git a/gcc/target.def b/gcc/target.def
index a00181aa9bb..fff7409aca7 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -4359,8 +4359,8 @@ a register.",
bool named),
default_function_arg)
-/* Likewise, but for machines with register windows. Return the
- location where the argument will appear to the callee. */
+/* Likewise, but for machines with register windows or special arguments.
+ Return the location where the argument will appear to the callee. */
DEFHOOK
(function_incoming_arg,
"Define this hook if the target machine has ``register windows'', so\n\
@@ -4374,6 +4374,10 @@ which the caller passes the value, and\n\
fashion to tell the function being called where the arguments will\n\
arrive.\n\
\n\
+@code{TARGET_FUNCTION_INCOMING_ARG} can also return arbitrary address\n\
+computation using hard register, which can be forced into a register,\n\
+so that it can be used to pass special arguments.\n\
+\n\
If @code{TARGET_FUNCTION_INCOMING_ARG} is not defined,\n\
@code{TARGET_FUNCTION_ARG} serves both purposes.",
rtx, (cumulative_args_t ca, machine_mode mode, const_tree type,