From 5adeb246868dba536895e60100ef20162b6d1911 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sun, 19 Feb 2012 16:44:54 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 +++++ gcc/config/mips/mips.c | 29 ++++++++++++++++++++++------- libgcc/ChangeLog | 4 ++++ libgcc/config/mips/mips16.S | 26 +++++++++++++++++--------- 4 files changed, 48 insertions(+), 16 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4292690c0f7..e052b4e38ec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2012-02-19 Richard Sandiford + + * config/mips/mips.c (mips16_build_call_stub): Add CFI information + to stubs with non-sibling calls. + 2012-02-18 Sandra Loosemore * doc/invoke.texi (-fira-* options): Copy-edit. diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 56863fa88ea..2dfbb4bdbb9 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 diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 01a3ac230a6..15d9b08824e 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,7 @@ +2012-02-19 Richard Sandiford + + * config/mips/mips16.S (CALL_STUB_RET): Add CFI information. + 2012-02-15 Iain Sandoe PR libitm/52220 diff --git a/libgcc/config/mips/mips16.S b/libgcc/config/mips/mips16.S index c82a55da6aa..1899ab2ede9 100644 --- a/libgcc/config/mips/mips16.S +++ b/libgcc/config/mips/mips16.S @@ -566,15 +566,23 @@ CALL_STUB_NO_RET (__mips16_call_stub_10, 10) being called is 16 bits, in which case the copy is unnecessary; however, it's faster to always do the copy. */ -#define CALL_STUB_RET(NAME, CODE, MODE) \ -STARTFN (NAME); \ - move $18,$31; \ - STUB_ARGS_##CODE; \ - .set noreorder; \ - jalr $2; \ - move $25,$2; \ - .set reorder; \ - MOVE_##MODE##_RET (f, $18); \ +#define CALL_STUB_RET(NAME, CODE, MODE) \ +STARTFN (NAME); \ + .cfi_startproc; \ + /* Create a fake CFA 4 bytes below the stack pointer. */ \ + .cfi_def_cfa 29,-4; \ + /* "Save" $sp in itself so we don't use the fake CFA. \ + This is: DW_CFA_val_expression r29, { DW_OP_reg29 }. */ \ + .cfi_escape 0x16,29,1,0x6d; \ + move $18,$31; \ + .cfi_register 31,18; \ + STUB_ARGS_##CODE; \ + .set noreorder; \ + jalr $2; \ + move $25,$2; \ + .set reorder; \ + MOVE_##MODE##_RET (f, $18); \ + .cfi_endproc; \ ENDFN (NAME) /* First, instantiate the single-float set. */ -- 2.30.2