OSDN Git Service

gcc/
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 19 Feb 2012 16:44:54 +0000 (16:44 +0000)
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 19 Feb 2012 16:44:54 +0000 (16:44 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@184379 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/mips/mips.c
libgcc/ChangeLog
libgcc/config/mips/mips16.S

index 4292690..e052b4e 100644 (file)
@@ -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.
index 56863fa..2dfbb4b 100644 (file)
@@ -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
index 01a3ac2..15d9b08 100644 (file)
@@ -1,3 +1,7 @@
+2012-02-19  Richard Sandiford  <rdsandiford@googlemail.com>
+
+       * config/mips/mips16.S (CALL_STUB_RET): Add CFI information.
+
 2012-02-15  Iain Sandoe  <iains@gcc.gnu.org>
 
        PR libitm/52220
index c82a55d..1899ab2 100644 (file)
@@ -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.  */