@@ -1543,7 +1543,7 @@ setup_incoming_promotions (rtx_insn *first)
for (arg = DECL_ARGUMENTS (current_function_decl); arg;
arg = DECL_CHAIN (arg))
{
- rtx x, reg = DECL_INCOMING_RTL (arg);
+ rtx x, reg = get_decl_incoming_rtl (arg);
int uns1, uns3;
machine_mode mode1, mode2, mode3, mode4;
@@ -3953,6 +3953,14 @@ If @code{TARGET_FUNCTION_INCOMING_ARG} is not defined,
@code{TARGET_FUNCTION_ARG} serves both purposes.
@end deftypefn
+@deftypefn {Target Hook} rtx TARGET_FUNCTION_INCOMING_ARG_RTL (const_tree @var{parmdecl})
+Define this hook if the target machine has a special @code{DECL_INCOMING_RTL}
+which must be converted for the correct location.
+
+If @code{TARGET_FUNCTION_INCOMING_ARG_RTL} is not defined,
+@code{DECL_INCOMING_RTL} of the input @var{parmdecl} will be used.
+@end deftypefn
+
@deftypefn {Target Hook} bool TARGET_USE_PSEUDO_PIC_REG (void)
This hook should return 1 in case pseudo register should be created
for pic_offset_table_rtx during function expand.
@@ -3369,6 +3369,8 @@ the stack.
@hook TARGET_FUNCTION_INCOMING_ARG
+@hook TARGET_FUNCTION_INCOMING_ARG_RTL
+
@hook TARGET_USE_PSEUDO_PIC_REG
@hook TARGET_INIT_PIC_REG
@@ -5300,6 +5300,7 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
else
temp = *slot;
+ rtx incoming_rtl;
/* For PARM_DECLs try to keep around the original incoming value,
even if that means we'll emit a zero-range .debug_loc entry. */
if (temp->last
@@ -5307,10 +5308,10 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label)
&& TREE_CODE (decl) == PARM_DECL
&& NOTE_P (temp->first->loc)
&& NOTE_VAR_LOCATION_DECL (temp->first->loc) == decl
- && DECL_INCOMING_RTL (decl)
+ && (incoming_rtl = get_decl_incoming_rtl (decl))
&& NOTE_VAR_LOCATION_LOC (temp->first->loc)
&& GET_CODE (NOTE_VAR_LOCATION_LOC (temp->first->loc))
- == GET_CODE (DECL_INCOMING_RTL (decl))
+ == GET_CODE (incoming_rtl)
&& prev_real_insn (temp->first->loc) == NULL_RTX
&& (bitsize != -1
|| !rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->first->loc),
@@ -15972,13 +15973,15 @@ rtl_for_decl_location (tree decl)
}
else if (TREE_CODE (decl) == PARM_DECL)
{
+ rtx incoming_rtl = get_decl_incoming_rtl (decl);
+
if (rtl == NULL_RTX
|| is_pseudo_reg (rtl)
|| (MEM_P (rtl)
&& is_pseudo_reg (XEXP (rtl, 0))
- && DECL_INCOMING_RTL (decl)
- && MEM_P (DECL_INCOMING_RTL (decl))
- && GET_MODE (rtl) == GET_MODE (DECL_INCOMING_RTL (decl))))
+ && incoming_rtl
+ && MEM_P (incoming_rtl)
+ && GET_MODE (rtl) == GET_MODE (incoming_rtl)))
{
tree declared_type = TREE_TYPE (decl);
tree passed_type = DECL_ARG_TYPE (decl);
@@ -15989,13 +15992,13 @@ rtl_for_decl_location (tree decl)
Note that DECL_INCOMING_RTL may be NULL in here, but we handle
all cases where (rtl == NULL_RTX) just below. */
if (dmode == pmode)
- rtl = DECL_INCOMING_RTL (decl);
+ rtl = incoming_rtl;
else if ((rtl == NULL_RTX || is_pseudo_reg (rtl))
&& SCALAR_INT_MODE_P (dmode)
&& GET_MODE_SIZE (dmode) <= GET_MODE_SIZE (pmode)
- && DECL_INCOMING_RTL (decl))
+ && incoming_rtl)
{
- rtx inc = DECL_INCOMING_RTL (decl);
+ rtx inc = incoming_rtl;
if (REG_P (inc))
rtl = inc;
else if (MEM_P (inc))
@@ -16021,7 +16024,7 @@ rtl_for_decl_location (tree decl)
&& XEXP (rtl, 0) != const0_rtx
&& ! CONSTANT_P (XEXP (rtl, 0))
/* Not passed in memory. */
- && !MEM_P (DECL_INCOMING_RTL (decl))
+ && !MEM_P (incoming_rtl)
/* Not passed by invisible reference. */
&& (!REG_P (XEXP (rtl, 0))
|| REGNO (XEXP (rtl, 0)) == HARD_FRAME_POINTER_REGNUM
@@ -1290,6 +1290,14 @@ set_decl_incoming_rtl (tree t, rtx x, bool by_reference_p)
set_reg_attrs_for_decl_rtl (t, x);
}
+/* Return the location where the argument appears to the callee. */
+
+rtx
+get_decl_incoming_rtl (const_tree parmdecl)
+{
+ return targetm.calls.function_incoming_arg_rtl (parmdecl);
+}
+
/* Identify REG (which may be a CONCAT) as a user register. */
void
@@ -430,6 +430,7 @@ get_max_uid (void)
}
extern void set_decl_incoming_rtl (tree, rtx, bool);
+extern rtx get_decl_incoming_rtl (const_tree);
/* Return a memory reference like MEMREF, but with its mode changed
to MODE and its address changed to ADDR.
@@ -4493,6 +4493,18 @@ If @code{TARGET_FUNCTION_INCOMING_ARG} is not defined,\n\
bool named),
default_function_incoming_arg)
+/* Return the location where the argument will appear to the callee. */
+DEFHOOK
+(function_incoming_arg_rtl,
+ "Define this hook if the target machine has a special\
+ @code{DECL_INCOMING_RTL}\n\
+which must be converted for the correct location.\n\
+\n\
+If @code{TARGET_FUNCTION_INCOMING_ARG_RTL} is not defined,\n\
+@code{DECL_INCOMING_RTL} of the input @var{parmdecl} will be used.",
+ rtx, (const_tree parmdecl),
+ default_function_incoming_arg_rtl)
+
DEFHOOK
(function_arg_boundary,
"This hook returns the alignment boundary, in bits, of an argument\n\
@@ -661,6 +661,12 @@ default_function_incoming_arg (cumulative_args_t ca ATTRIBUTE_UNUSED,
gcc_unreachable ();
}
+rtx
+default_function_incoming_arg_rtl (const_tree parmdecl)
+{
+ return DECL_INCOMING_RTL (parmdecl);
+}
+
unsigned int
default_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED,
const_tree type ATTRIBUTE_UNUSED)
@@ -135,6 +135,7 @@ extern rtx default_function_arg
(cumulative_args_t, machine_mode, const_tree, bool);
extern rtx default_function_incoming_arg
(cumulative_args_t, machine_mode, const_tree, bool);
+extern rtx default_function_incoming_arg_rtl (const_tree);
extern unsigned int default_function_arg_boundary (machine_mode,
const_tree);
extern unsigned int default_function_arg_round_boundary (machine_mode,
@@ -5809,9 +5809,13 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
mode2 = mode;
+ rtx incoming_rtl = NULL;
+
if (REG_P (loc))
{
gcc_assert (loc != cfa_base_rtx);
+ if (REG_EXPR (loc) && TREE_CODE (REG_EXPR (loc)) == PARM_DECL)
+ incoming_rtl = get_decl_incoming_rtl (REG_EXPR (loc));
if ((GET_CODE (expr) == CLOBBER && type != MO_VAL_SET)
|| !(track_p = use_type (loc, NULL, &mode2) == MO_USE)
|| GET_CODE (expr) == CLOBBER)
@@ -5855,9 +5859,8 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
&& REG_EXPR (loc)
&& TREE_CODE (REG_EXPR (loc)) == PARM_DECL
&& DECL_MODE (REG_EXPR (loc)) != BLKmode
- && MEM_P (DECL_INCOMING_RTL (REG_EXPR (loc)))
- && XEXP (DECL_INCOMING_RTL (REG_EXPR (loc)), 0)
- != arg_pointer_rtx)
+ && MEM_P (incoming_rtl)
+ && XEXP (incoming_rtl, 0) != arg_pointer_rtx)
mo.type = MO_SET;
else
mo.type = MO_COPY;
@@ -5941,10 +5944,10 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
&& TREE_CODE (REG_EXPR (loc)) == PARM_DECL
&& DECL_MODE (REG_EXPR (loc)) != BLKmode
&& TREE_CODE (TREE_TYPE (REG_EXPR (loc))) != UNION_TYPE
- && ((MEM_P (DECL_INCOMING_RTL (REG_EXPR (loc)))
- && XEXP (DECL_INCOMING_RTL (REG_EXPR (loc)), 0) != arg_pointer_rtx)
- || (GET_CODE (DECL_INCOMING_RTL (REG_EXPR (loc))) == PARALLEL
- && XVECLEN (DECL_INCOMING_RTL (REG_EXPR (loc)), 0) > 1)))
+ && ((MEM_P (incoming_rtl)
+ && XEXP (incoming_rtl, 0) != arg_pointer_rtx)
+ || (GET_CODE (incoming_rtl) == PARALLEL
+ && XVECLEN (incoming_rtl, 0) > 1)))
{
/* Although we don't use the value here, it could be used later by the
mere virtue of its existence as the operand of the reverse operation
@@ -9506,7 +9509,7 @@ static void
vt_add_function_parameter (tree parm)
{
rtx decl_rtl = DECL_RTL_IF_SET (parm);
- rtx incoming = DECL_INCOMING_RTL (parm);
+ rtx incoming = get_decl_incoming_rtl (parm);
tree decl;
machine_mode mode;
HOST_WIDE_INT offset;