aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog33
-rw-r--r--gcc/config/i386/i386.c115
-rw-r--r--gcc/config/i386/i386.h1
-rw-r--r--gcc/config/i386/i386.md23
-rw-r--r--gcc/doc/tm.texi12
-rw-r--r--gcc/dwarf2out.c26
-rw-r--r--gcc/function.c53
-rw-r--r--gcc/target-def.h4
-rw-r--r--gcc/target.h4
-rw-r--r--gcc/targhooks.c16
-rw-r--r--gcc/targhooks.h2
-rw-r--r--gcc/tree.h4
12 files changed, 216 insertions, 77 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index afca62b..a2e518a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,36 @@
+2005-11-02 Richard Henderson <rth@redhat.com>
+
+ PR target/9350
+ PR target/24374
+ * dwarf2out.c (dwarf2out_reg_save_reg): New.
+ (dwarf2out_frame_debug_expr): Return after dwarf_handle_frame_unspec.
+ * function.c (assign_parms): Use calls.internal_arg_pointer.
+ (expand_main_function): Remove FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
+ code.
+ * target-def.h (TARGET_INTERNAL_ARG_POINTER): New.
+ (TARGET_CALLS): Add it.
+ * target.h (struct gcc_target): Add calls.internal_arg_pointer.
+ * targhooks.c (default_internal_arg_pointer): New.
+ * targhooks.h (default_internal_arg_pointer): Declare.
+ * tree.h (dwarf2out_reg_save_reg): Declare.
+ * doc/tm.texi (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN): Remove.
+ * config/i386/i386.c (dbx_register_map): Add return column.
+ (dbx64_register_map, svr4_dbx_register_map): Likewise.
+ (TARGET_INTERNAL_ARG_POINTER, ix86_internal_arg_pointer): New.
+ (TARGET_DWARF_HANDLE_FRAME_UNSPEC, ix86_dwarf_handle_frame_unspec): New.
+ (ix86_function_ok_for_sibcall): Disable if force_align_arg_pointer.
+ (ix86_save_reg): Save force_align_arg_pointer.
+ (ix86_emit_save_regs): Make regno unsigned.
+ (ix86_emit_save_regs_using_mov): Likewise.
+ (ix86_expand_prologue): Handle force_align_arg_pointer.
+ (ix86_expand_epilogue): Likewise.
+ * config/i386/i386.h: (dbx_register_map): Update.
+ (dbx64_register_map, svr4_dbx_register_map): Update.
+ (struct machine_function): Add force_align_arg_pointer.
+ * config/i386/i386.md (UNSPEC_REG_SAVE, UNSPEC_DEF_CFA): New.
+ (UNSPEC_TP, UNSPEC_TLS_GD, UNSPEC_TLS_LD_BASE): Renumber.
+ (TARGET_PUSH_MEMORY peepholes): Disable if RTX_FRAME_RELATED_P.
+
2005-11-02 Jan Hubicka <jh@suse.cz>
PR target/23303
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 7b3f888..26f0299 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -913,6 +913,8 @@ static void ix86_init_builtins (void);
static rtx ix86_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
static const char *ix86_mangle_fundamental_type (tree);
static tree ix86_stack_protect_fail (void);
+static rtx ix86_internal_arg_pointer (void);
+static void ix86_dwarf_handle_frame_unspec (const char *, rtx, int);
/* This function is only used on Solaris. */
static void i386_solaris_elf_named_section (const char *, unsigned int, tree)
@@ -1081,6 +1083,10 @@ static void x86_64_elf_select_section (tree decl, int reloc,
#define TARGET_MUST_PASS_IN_STACK ix86_must_pass_in_stack
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE ix86_pass_by_reference
+#undef TARGET_INTERNAL_ARG_POINTER
+#define TARGET_INTERNAL_ARG_POINTER ix86_internal_arg_pointer
+#undef TARGET_DWARF_HANDLE_FRAME_UNSPEC
+#define TARGET_DWARF_HANDLE_FRAME_UNSPEC ix86_dwarf_handle_frame_unspec
#undef TARGET_GIMPLIFY_VA_ARG_EXPR
#define TARGET_GIMPLIFY_VA_ARG_EXPR ix86_gimplify_va_arg
@@ -1987,6 +1993,11 @@ ix86_function_ok_for_sibcall (tree decl, tree exp)
return false;
#endif
+ /* If we forced aligned the stack, then sibcalling would unalign the
+ stack, which may break the called function. */
+ if (cfun->machine->force_align_arg_pointer)
+ return false;
+
/* Otherwise okay. That also includes certain types of indirect calls. */
return true;
}
@@ -4508,6 +4519,10 @@ ix86_save_reg (unsigned int regno, int maybe_eh_return)
}
}
+ if (cfun->machine->force_align_arg_pointer
+ && regno == REGNO (cfun->machine->force_align_arg_pointer))
+ return 1;
+
return (regs_ever_live[regno]
&& !call_used_regs[regno]
&& !fixed_regs[regno]
@@ -4719,10 +4734,10 @@ ix86_compute_frame_layout (struct ix86_frame *frame)
static void
ix86_emit_save_regs (void)
{
- int regno;
+ unsigned int regno;
rtx insn;
- for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
+ for (regno = FIRST_PSEUDO_REGISTER; regno-- > 0; )
if (ix86_save_reg (regno, true))
{
insn = emit_insn (gen_push (gen_rtx_REG (Pmode, regno)));
@@ -4735,7 +4750,7 @@ ix86_emit_save_regs (void)
static void
ix86_emit_save_regs_using_mov (rtx pointer, HOST_WIDE_INT offset)
{
- int regno;
+ unsigned int regno;
rtx insn;
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
@@ -4783,6 +4798,47 @@ pro_epilogue_adjust_stack (rtx dest, rtx src, rtx offset, int style)
RTX_FRAME_RELATED_P (insn) = 1;
}
+/* Handle the TARGET_INTERNAL_ARG_POINTER hook. */
+
+static rtx
+ix86_internal_arg_pointer (void)
+{
+ if (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
+ && DECL_NAME (current_function_decl)
+ && MAIN_NAME_P (DECL_NAME (current_function_decl))
+ && DECL_FILE_SCOPE_P (current_function_decl))
+ {
+ cfun->machine->force_align_arg_pointer = gen_rtx_REG (Pmode, 2);
+ return copy_to_reg (cfun->machine->force_align_arg_pointer);
+ }
+ else
+ return virtual_incoming_args_rtx;
+}
+
+/* Handle the TARGET_DWARF_HANDLE_FRAME_UNSPEC hook.
+ This is called from dwarf2out.c to emit call frame instructions
+ for frame-related insns containing UNSPECs and UNSPEC_VOLATILEs. */
+static void
+ix86_dwarf_handle_frame_unspec (const char *label, rtx pattern, int index)
+{
+ rtx unspec = SET_SRC (pattern);
+ gcc_assert (GET_CODE (unspec) == UNSPEC);
+
+ switch (index)
+ {
+ case UNSPEC_REG_SAVE:
+ dwarf2out_reg_save_reg (label, XVECEXP (unspec, 0, 0),
+ SET_DEST (pattern));
+ break;
+ case UNSPEC_DEF_CFA:
+ dwarf2out_def_cfa (label, REGNO (SET_DEST (pattern)),
+ INTVAL (XVECEXP (unspec, 0, 0)));
+ break;
+ default:
+ gcc_unreachable ();
+ }
+}
+
/* Expand the prologue into a bunch of separate insns. */
void
@@ -4795,6 +4851,52 @@ ix86_expand_prologue (void)
ix86_compute_frame_layout (&frame);
+ if (cfun->machine->force_align_arg_pointer)
+ {
+ rtx x, y;
+
+ /* Grab the argument pointer. */
+ x = plus_constant (stack_pointer_rtx, 4);
+ y = cfun->machine->force_align_arg_pointer;
+ insn = emit_insn (gen_rtx_SET (VOIDmode, y, x));
+ RTX_FRAME_RELATED_P (insn) = 1;
+
+ /* The unwind info consists of two parts: install the fafp as the cfa,
+ and record the fafp as the "save register" of the stack pointer.
+ The later is there in order that the unwinder can see where it
+ should restore the stack pointer across the and insn. */
+ x = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, const0_rtx), UNSPEC_DEF_CFA);
+ x = gen_rtx_SET (VOIDmode, y, x);
+ RTX_FRAME_RELATED_P (x) = 1;
+ y = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, stack_pointer_rtx),
+ UNSPEC_REG_SAVE);
+ y = gen_rtx_SET (VOIDmode, cfun->machine->force_align_arg_pointer, y);
+ RTX_FRAME_RELATED_P (y) = 1;
+ x = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, x, y));
+ x = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, x, NULL);
+ REG_NOTES (insn) = x;
+
+ /* Align the stack. */
+ emit_insn (gen_andsi3 (stack_pointer_rtx, stack_pointer_rtx,
+ GEN_INT (-16)));
+
+ /* And here we cheat like madmen with the unwind info. We force the
+ cfa register back to sp+4, which is exactly what it was at the
+ start of the function. Re-pushing the return address results in
+ the return at the same spot relative to the cfa, and thus is
+ correct wrt the unwind info. */
+ x = cfun->machine->force_align_arg_pointer;
+ x = gen_frame_mem (Pmode, plus_constant (x, -4));
+ insn = emit_insn (gen_push (x));
+ RTX_FRAME_RELATED_P (insn) = 1;
+
+ x = GEN_INT (4);
+ x = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, x), UNSPEC_DEF_CFA);
+ x = gen_rtx_SET (VOIDmode, stack_pointer_rtx, x);
+ x = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, x, NULL);
+ REG_NOTES (insn) = x;
+ }
+
/* Note: AT&T enter does NOT have reversed args. Enter is probably
slower on all targets. Also sdb doesn't like it. */
@@ -5072,6 +5174,13 @@ ix86_expand_epilogue (int style)
}
}
+ if (cfun->machine->force_align_arg_pointer)
+ {
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ cfun->machine->force_align_arg_pointer,
+ GEN_INT (-4)));
+ }
+
/* Sibcall epilogues don't want a return instruction. */
if (style == 0)
return;
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index a00e0e0..256c0e4 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2263,6 +2263,7 @@ struct machine_function GTY(())
{
struct stack_local_entry *stack_locals;
const char *some_ld_name;
+ rtx force_align_arg_pointer;
int save_varrargs_registers;
int accesses_prev_frame;
int optimize_mode_switching[MAX_386_ENTITIES];
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 19d874b..b739e50 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -66,11 +66,13 @@
(UNSPEC_STACK_ALLOC 11)
(UNSPEC_SET_GOT 12)
(UNSPEC_SSE_PROLOGUE_SAVE 13)
+ (UNSPEC_REG_SAVE 14)
+ (UNSPEC_DEF_CFA 15)
; TLS support
- (UNSPEC_TP 15)
- (UNSPEC_TLS_GD 16)
- (UNSPEC_TLS_LD_BASE 17)
+ (UNSPEC_TP 16)
+ (UNSPEC_TLS_GD 17)
+ (UNSPEC_TLS_LD_BASE 18)
; Other random patterns
(UNSPEC_SCAS 20)
@@ -18934,7 +18936,8 @@
[(set (match_operand:SI 0 "push_operand" "")
(match_operand:SI 1 "memory_operand" ""))
(match_scratch:SI 2 "r")]
- "! optimize_size && ! TARGET_PUSH_MEMORY"
+ "!optimize_size && !TARGET_PUSH_MEMORY
+ && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (match_dup 2))]
"")
@@ -18943,7 +18946,8 @@
[(set (match_operand:DI 0 "push_operand" "")
(match_operand:DI 1 "memory_operand" ""))
(match_scratch:DI 2 "r")]
- "! optimize_size && ! TARGET_PUSH_MEMORY"
+ "!optimize_size && !TARGET_PUSH_MEMORY
+ && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (match_dup 2))]
"")
@@ -18954,7 +18958,8 @@
[(set (match_operand:SF 0 "push_operand" "")
(match_operand:SF 1 "memory_operand" ""))
(match_scratch:SF 2 "r")]
- "! optimize_size && ! TARGET_PUSH_MEMORY"
+ "!optimize_size && !TARGET_PUSH_MEMORY
+ && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (match_dup 2))]
"")
@@ -18963,7 +18968,8 @@
[(set (match_operand:HI 0 "push_operand" "")
(match_operand:HI 1 "memory_operand" ""))
(match_scratch:HI 2 "r")]
- "! optimize_size && ! TARGET_PUSH_MEMORY"
+ "!optimize_size && !TARGET_PUSH_MEMORY
+ && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (match_dup 2))]
"")
@@ -18972,7 +18978,8 @@
[(set (match_operand:QI 0 "push_operand" "")
(match_operand:QI 1 "memory_operand" ""))
(match_scratch:QI 2 "q")]
- "! optimize_size && ! TARGET_PUSH_MEMORY"
+ "!optimize_size && !TARGET_PUSH_MEMORY
+ && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (match_dup 2))]
"")
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 46d24b6..b339c4c 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -1033,18 +1033,6 @@ macro must evaluate to a value equal to or larger than
@code{STACK_BOUNDARY}.
@end defmac
-@defmac FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
-A C expression that evaluates true if @code{PREFERRED_STACK_BOUNDARY} is
-not guaranteed by the runtime and we should emit code to align the stack
-at the beginning of @code{main}.
-
-@cindex @code{PUSH_ROUNDING}, interaction with @code{PREFERRED_STACK_BOUNDARY}
-If @code{PUSH_ROUNDING} is not defined, the stack will always be aligned
-to the specified boundary. If @code{PUSH_ROUNDING} is defined and specifies
-a less strict alignment than @code{PREFERRED_STACK_BOUNDARY}, the stack may
-be momentarily unaligned while pushing arguments.
-@end defmac
-
@defmac FUNCTION_BOUNDARY
Alignment required for a function entry point, in bits.
@end defmac
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index d780914..314652b 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -1271,6 +1271,30 @@ clobbers_queued_reg_save (rtx insn)
return false;
}
+/* Entry point for saving the first register into the second. */
+
+void
+dwarf2out_reg_save_reg (const char *label, rtx reg, rtx sreg)
+{
+ size_t i;
+ unsigned int regno, sregno;
+
+ for (i = 0; i < num_regs_saved_in_regs; i++)
+ if (REGNO (regs_saved_in_regs[i].orig_reg) == REGNO (reg))
+ break;
+ if (i == num_regs_saved_in_regs)
+ {
+ gcc_assert (i != ARRAY_SIZE (regs_saved_in_regs));
+ num_regs_saved_in_regs++;
+ }
+ regs_saved_in_regs[i].orig_reg = reg;
+ regs_saved_in_regs[i].saved_in_reg = sreg;
+
+ regno = DWARF_FRAME_REGNUM (REGNO (reg));
+ sregno = DWARF_FRAME_REGNUM (REGNO (sreg));
+ reg_save (label, regno, sregno, 0);
+}
+
/* What register, if any, is currently saved in REG? */
static rtx
@@ -1659,7 +1683,7 @@ dwarf2out_frame_debug_expr (rtx expr, const char *label)
case UNSPEC_VOLATILE:
gcc_assert (targetm.dwarf_handle_frame_unspec);
targetm.dwarf_handle_frame_unspec (label, expr, XINT (src, 1));
- break;
+ return;
default:
gcc_unreachable ();
diff --git a/gcc/function.c b/gcc/function.c
index 941021e..9e36af7 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -2894,22 +2894,9 @@ assign_parms (tree fndecl)
{
struct assign_parm_data_all all;
tree fnargs, parm;
- rtx internal_arg_pointer;
- /* If the reg that the virtual arg pointer will be translated into is
- not a fixed reg or is the stack pointer, make a copy of the virtual
- arg pointer, and address parms via the copy. The frame pointer is
- considered fixed even though it is not marked as such.
-
- The second time through, simply use ap to avoid generating rtx. */
-
- if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
- || ! (fixed_regs[ARG_POINTER_REGNUM]
- || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM)))
- internal_arg_pointer = copy_to_reg (virtual_incoming_args_rtx);
- else
- internal_arg_pointer = virtual_incoming_args_rtx;
- current_function_internal_arg_pointer = internal_arg_pointer;
+ current_function_internal_arg_pointer
+ = targetm.calls.internal_arg_pointer ();
assign_parms_initialize_all (&all);
fnargs = assign_parms_augmented_arg_list (&all);
@@ -3916,42 +3903,6 @@ struct tree_opt_pass pass_init_function =
void
expand_main_function (void)
{
-#ifdef FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN
- if (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN)
- {
- int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
- rtx tmp, seq;
-
- start_sequence ();
- /* Forcibly align the stack. */
-#ifdef STACK_GROWS_DOWNWARD
- tmp = expand_simple_binop (Pmode, AND, stack_pointer_rtx, GEN_INT(-align),
- stack_pointer_rtx, 1, OPTAB_WIDEN);
-#else
- tmp = expand_simple_binop (Pmode, PLUS, stack_pointer_rtx,
- GEN_INT (align - 1), NULL_RTX, 1, OPTAB_WIDEN);
- tmp = expand_simple_binop (Pmode, AND, tmp, GEN_INT (-align),
- stack_pointer_rtx, 1, OPTAB_WIDEN);
-#endif
- if (tmp != stack_pointer_rtx)
- emit_move_insn (stack_pointer_rtx, tmp);
-
- /* Enlist allocate_dynamic_stack_space to pick up the pieces. */
- tmp = force_reg (Pmode, const0_rtx);
- allocate_dynamic_stack_space (tmp, NULL_RTX, BIGGEST_ALIGNMENT);
- seq = get_insns ();
- end_sequence ();
-
- for (tmp = get_last_insn (); tmp; tmp = PREV_INSN (tmp))
- if (NOTE_P (tmp) && NOTE_LINE_NUMBER (tmp) == NOTE_INSN_FUNCTION_BEG)
- break;
- if (tmp)
- emit_insn_before (seq, tmp);
- else
- emit_insn (seq);
- }
-#endif
-
#if (defined(INVOKE__main) \
|| (!defined(HAS_INIT_SECTION) \
&& !defined(INIT_SECTION_ASM_OP) \
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 6dd121d..7e88374 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -445,6 +445,7 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define TARGET_ARG_PARTIAL_BYTES hook_int_CUMULATIVE_ARGS_mode_tree_bool_0
#define TARGET_FUNCTION_VALUE default_function_value
+#define TARGET_INTERNAL_ARG_POINTER default_internal_arg_pointer
#define TARGET_CALLS { \
TARGET_PROMOTE_FUNCTION_ARGS, \
@@ -463,7 +464,8 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
TARGET_CALLEE_COPIES, \
TARGET_ARG_PARTIAL_BYTES, \
TARGET_INVALID_ARG_FOR_UNPROTOTYPED_FN, \
- TARGET_FUNCTION_VALUE \
+ TARGET_FUNCTION_VALUE, \
+ TARGET_INTERNAL_ARG_POINTER \
}
#ifndef TARGET_UNWIND_TABLES_DEFAULT
diff --git a/gcc/target.h b/gcc/target.h
index cd850d1..0f775f1 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -613,6 +613,10 @@ struct gcc_target
specified by FN_DECL_OR_TYPE with a return type of RET_TYPE. */
rtx (*function_value) (tree ret_type, tree fn_decl_or_type,
bool outgoing);
+
+ /* Return an rtx for the argument pointer incoming to the
+ current function. */
+ rtx (*internal_arg_pointer) (void);
} calls;
/* Return the diagnostic message string if conversion from FROMTYPE
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index c0c4201..94469a7 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -62,6 +62,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "tm_p.h"
#include "target-def.h"
#include "ggc.h"
+#include "hard-reg-set.h"
void
@@ -439,4 +440,19 @@ default_function_value (tree ret_type ATTRIBUTE_UNUSED,
#endif
}
+rtx
+default_internal_arg_pointer (void)
+{
+ /* If the reg that the virtual arg pointer will be translated into is
+ not a fixed reg or is the stack pointer, make a copy of the virtual
+ arg pointer, and address parms via the copy. The frame pointer is
+ considered fixed even though it is not marked as such. */
+ if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM
+ || ! (fixed_regs[ARG_POINTER_REGNUM]
+ || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM)))
+ return copy_to_reg (virtual_incoming_args_rtx);
+ else
+ return virtual_incoming_args_rtx;
+}
+
#include "gt-targhooks.h"
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index a39d27d..24e3b6d 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -68,4 +68,4 @@ extern const char *hook_invalid_arg_for_unprototyped_fn
(tree, tree, tree);
extern bool hook_bool_rtx_commutative_p (rtx, int);
extern rtx default_function_value (tree, tree, bool);
-
+extern rtx default_internal_arg_pointer (void);
diff --git a/gcc/tree.h b/gcc/tree.h
index f54f6d3..4705bb1 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4119,6 +4119,10 @@ extern void dwarf2out_return_save (const char *, HOST_WIDE_INT);
extern void dwarf2out_return_reg (const char *, unsigned);
+/* Entry point for saving the first register into the second. */
+
+extern void dwarf2out_reg_save_reg (const char *, rtx, rtx);
+
/* In tree-inline.c */
/* The type of a set of already-visited pointers. Functions for creating