aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2012-02-19 16:44:54 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2012-02-19 16:44:54 +0000
commit5adeb246868dba536895e60100ef20162b6d1911 (patch)
treead8b1e20eb94789217582fe66f9f9acb4948492a /gcc
parent3e95c6caec8cdb2683a2b57d6b2bf68be15a1769 (diff)
downloadgcc-5adeb246868dba536895e60100ef20162b6d1911.zip
gcc-5adeb246868dba536895e60100ef20162b6d1911.tar.gz
gcc-5adeb246868dba536895e60100ef20162b6d1911.tar.bz2
mips.c (mips16_build_call_stub): Add CFI information to stubs with non-sibling calls.
gcc/ * config/mips/mips.c (mips16_build_call_stub): Add CFI information to stubs with non-sibling calls. libgcc/ * config/mips/mips16.S (CALL_STUB_RET): Add CFI information. From-SVN: r184379
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/mips/mips.c29
2 files changed, 27 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4292690..e052b4e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2012-02-19 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/mips/mips.c (mips16_build_call_stub): Add CFI information
+ to stubs with non-sibling calls.
+
2012-02-18 Sandra Loosemore <sandra@codesourcery.com>
* doc/invoke.texi (-fira-* options): Copy-edit.
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 56863fa..2dfbb4b 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -6387,7 +6387,20 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
assemble_start_function (stubdecl, stubname);
mips_start_function_definition (stubname, false);
- if (!fp_ret_p)
+ if (fp_ret_p)
+ {
+ fprintf (asm_out_file, "\t.cfi_startproc\n");
+
+ /* Create a fake CFA 4 bytes below the stack pointer.
+ This works around unwinders (like libgcc's) that expect
+ the CFA for non-signal frames to be unique. */
+ fprintf (asm_out_file, "\t.cfi_def_cfa 29,-4\n");
+
+ /* "Save" $sp in itself so we don't use the fake CFA.
+ This is: DW_CFA_val_expression r29, { DW_OP_reg29 }. */
+ fprintf (asm_out_file, "\t.cfi_escape 0x16,29,1,0x6d\n");
+ }
+ else
{
/* Load the address of the MIPS16 function into $25. Do this
first so that targets with coprocessor interlocks can use
@@ -6405,12 +6418,7 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
registers. */
mips_output_args_xfer (fp_code, 't');
- if (!fp_ret_p)
- {
- /* Jump to the previously-loaded address. */
- output_asm_insn ("jr\t%^", NULL);
- }
- else
+ if (fp_ret_p)
{
/* Save the return address in $18 and call the non-MIPS16 function.
The stub's caller knows that $18 might be clobbered, even though
@@ -6418,6 +6426,7 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
fprintf (asm_out_file, "\tmove\t%s,%s\n",
reg_names[GP_REG_FIRST + 18], reg_names[RETURN_ADDR_REGNUM]);
output_asm_insn (MIPS_CALL ("jal", &fn, 0, -1), &fn);
+ fprintf (asm_out_file, "\t.cfi_register 31,18\n");
/* Move the result from floating-point registers to
general registers. */
@@ -6470,6 +6479,12 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
gcc_unreachable ();
}
fprintf (asm_out_file, "\tjr\t%s\n", reg_names[GP_REG_FIRST + 18]);
+ fprintf (asm_out_file, "\t.cfi_endproc\n");
+ }
+ else
+ {
+ /* Jump to the previously-loaded address. */
+ output_asm_insn ("jr\t%^", NULL);
}
#ifdef ASM_DECLARE_FUNCTION_SIZE