mips.c (mips16_build_call_stub): Add CFI information to stubs with non-sibling calls.
authorRichard Sandiford <rdsandiford@googlemail.com>
Sun, 19 Feb 2012 16:44:54 +0000 (16:44 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sun, 19 Feb 2012 16:44:54 +0000 (16:44 +0000)
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
gcc/config/mips/mips.c
libgcc/ChangeLog
libgcc/config/mips/mips16.S

index 4292690c0f70871e8fa8048670772da94a54dac9..e052b4e38ec8849c5264e40fba2113711c3d0c04 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 56863fa88eaf180de8b9dc78c059697f75bdf08a..2dfbb4bdbb97ac5d2eb725760002444ab72d5451 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 01a3ac230a6d2d05e0e809b7043e2fb9e764320b..15d9b08824e8fee316e75b6d841b68655eb8657c 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 c82a55da6aa67629559908626b69d879fc7d7fa2..1899ab2ede9aec36f418a469e8ec43da5276f89d 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.  */