From 5c255b57b25e4847b8e556c4b6450e6f559329ff Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 24 Sep 2010 14:20:51 -0700 Subject: [PATCH] ia64.c (ia64_dwarf_handle_frame_unspec): New. * config/ia64/ia64.c (ia64_dwarf_handle_frame_unspec): New. (TARGET_DWARF_HANDLE_FRAME_UNSPEC): New. (do_spill): Use REG_CFA_OFFSET. (ia64_expand_prologue): Use REG_CFA_ADJUST_CFA and REG_CFA_REGISTER as appropriate. (ia64_expand_epilogue): Likewise. (process_set): Split into ... (process_cfa_adjust_cfa): this, (process_cfa_register): this, (process_cfa_offset): and this new function. (ia64_asm_unwind_emit): Use them. Expect REG_CFA_* notes instead of REG_FRAME_RELATED_EXPR. From-SVN: r164609 --- gcc/ChangeLog | 15 ++ gcc/config/ia64/ia64.c | 555 ++++++++++++++++++++++------------------- 2 files changed, 319 insertions(+), 251 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ee1404f3be3..012757ebaa2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2010-09-24 Richard Henderson + + * config/ia64/ia64.c (ia64_dwarf_handle_frame_unspec): New. + (TARGET_DWARF_HANDLE_FRAME_UNSPEC): New. + (do_spill): Use REG_CFA_OFFSET. + (ia64_expand_prologue): Use REG_CFA_ADJUST_CFA and REG_CFA_REGISTER + as appropriate. + (ia64_expand_epilogue): Likewise. + (process_set): Split into ... + (process_cfa_adjust_cfa): this, + (process_cfa_register): this, + (process_cfa_offset): and this new function. + (ia64_asm_unwind_emit): Use them. Expect REG_CFA_* notes + instead of REG_FRAME_RELATED_EXPR. + 2010-09-24 Olivier Hainque * config/i386/vx-common.h (DBX_REGISTER_NUMBER): Reinstate. diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index d02d2b8fc3f..61be5a45bbe 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -230,7 +230,6 @@ static void emit_predicate_relation_info (void); static void ia64_reorg (void); static bool ia64_in_small_data_p (const_tree); static void process_epilogue (FILE *, rtx, bool, bool); -static int process_set (FILE *, rtx, rtx, bool, bool); static bool ia64_assemble_integer (rtx, unsigned int, int); static void ia64_output_function_prologue (FILE *, HOST_WIDE_INT); @@ -318,6 +317,8 @@ static enum machine_mode ia64_promote_function_mode (const_tree, int); static void ia64_trampoline_init (rtx, tree, rtx); static void ia64_override_options_after_change (void); + +static void ia64_dwarf_handle_frame_unspec (const char *, rtx, int); /* Table of valid machine attributes. */ static const struct attribute_spec ia64_attribute_table[] = @@ -527,6 +528,8 @@ static const struct attribute_spec ia64_attribute_table[] = #undef TARGET_GIMPLIFY_VA_ARG_EXPR #define TARGET_GIMPLIFY_VA_ARG_EXPR ia64_gimplify_va_arg +#undef TARGET_DWARF_HANDLE_FRAME_UNSPEC +#define TARGET_DWARF_HANDLE_FRAME_UNSPEC ia64_dwarf_handle_frame_unspec #undef TARGET_ASM_UNWIND_EMIT #define TARGET_ASM_UNWIND_EMIT ia64_asm_unwind_emit #undef TARGET_ASM_EMIT_EXCEPT_PERSONALITY @@ -3035,7 +3038,7 @@ do_spill (rtx (*move_fn) (rtx, rtx, rtx), rtx reg, HOST_WIDE_INT cfa_off, off = current_frame_info.total_size - cfa_off; } - add_reg_note (insn, REG_FRAME_RELATED_EXPR, + add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (VOIDmode, gen_rtx_MEM (GET_MODE (reg), plus_constant (base, off)), @@ -3219,6 +3222,10 @@ ia64_expand_prologue (void) { insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx); RTX_FRAME_RELATED_P (insn) = 1; + + /* Force the unwind info to recognize this as defining a new CFA, + rather than some temp register setup. */ + add_reg_note (insn, REG_CFA_ADJUST_CFA, NULL_RTX); } if (current_frame_info.total_size != 0) @@ -3241,13 +3248,12 @@ ia64_expand_prologue (void) if (! frame_pointer_needed) { RTX_FRAME_RELATED_P (insn) = 1; - if (GET_CODE (offset) != CONST_INT) - add_reg_note (insn, REG_FRAME_RELATED_EXPR, - gen_rtx_SET (VOIDmode, - stack_pointer_rtx, - gen_rtx_PLUS (DImode, - stack_pointer_rtx, - frame_size_rtx))); + add_reg_note (insn, REG_CFA_ADJUST_CFA, + gen_rtx_SET (VOIDmode, + stack_pointer_rtx, + gen_rtx_PLUS (DImode, + stack_pointer_rtx, + frame_size_rtx))); } /* ??? At this point we must generate a magic insn that appears to @@ -3275,7 +3281,11 @@ ia64_expand_prologue (void) reg = gen_rtx_REG (DImode, AR_UNAT_REGNUM); insn = emit_move_insn (ar_unat_save_reg, reg); - RTX_FRAME_RELATED_P (insn) = (current_frame_info.r[reg_save_ar_unat] != 0); + if (current_frame_info.r[reg_save_ar_unat]) + { + RTX_FRAME_RELATED_P (insn) = 1; + add_reg_note (insn, REG_CFA_REGISTER, NULL_RTX); + } /* Even if we're not going to generate an epilogue, we still need to save the register so that EH works. */ @@ -3314,8 +3324,7 @@ ia64_expand_prologue (void) /* ??? Denote pr spill/fill by a DImode move that modifies all 64 hard registers. */ RTX_FRAME_RELATED_P (insn) = 1; - add_reg_note (insn, REG_FRAME_RELATED_EXPR, - gen_rtx_SET (VOIDmode, alt_reg, reg)); + add_reg_note (insn, REG_CFA_REGISTER, NULL_RTX); /* Even if we're not going to generate an epilogue, we still need to save the register so that EH works. */ @@ -3361,6 +3370,7 @@ ia64_expand_prologue (void) reg_emitted (reg_save_ar_lc); insn = emit_move_insn (alt_reg, reg); RTX_FRAME_RELATED_P (insn) = 1; + add_reg_note (insn, REG_CFA_REGISTER, NULL_RTX); /* Even if we're not going to generate an epilogue, we still need to save the register so that EH works. */ @@ -3387,6 +3397,7 @@ ia64_expand_prologue (void) reg_emitted (reg_save_b0); insn = emit_move_insn (alt_reg, reg); RTX_FRAME_RELATED_P (insn) = 1; + add_reg_note (insn, REG_CFA_REGISTER, NULL_RTX); /* Even if we're not going to generate an epilogue, we still need to save the register so that EH works. */ @@ -3677,6 +3688,7 @@ ia64_expand_epilogue (int sibcall_p) { insn = emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx); RTX_FRAME_RELATED_P (insn) = 1; + add_reg_note (insn, REG_CFA_ADJUST_CFA, NULL); } else if (current_frame_info.total_size) { @@ -3696,13 +3708,12 @@ ia64_expand_epilogue (int sibcall_p) offset)); RTX_FRAME_RELATED_P (insn) = 1; - if (GET_CODE (offset) != CONST_INT) - add_reg_note (insn, REG_FRAME_RELATED_EXPR, - gen_rtx_SET (VOIDmode, - stack_pointer_rtx, - gen_rtx_PLUS (DImode, - stack_pointer_rtx, - frame_size_rtx))); + add_reg_note (insn, REG_CFA_ADJUST_CFA, + gen_rtx_SET (VOIDmode, + stack_pointer_rtx, + gen_rtx_PLUS (DImode, + stack_pointer_rtx, + frame_size_rtx))); } if (cfun->machine->ia64_eh_epilogue_bsp) @@ -3713,11 +3724,12 @@ ia64_expand_epilogue (int sibcall_p) else { int fp = GR_REG (2); - /* We need a throw away register here, r0 and r1 are reserved, so r2 is the - first available call clobbered register. If there was a frame_pointer - register, we may have swapped the names of r2 and HARD_FRAME_POINTER_REGNUM, - so we have to make sure we're using the string "r2" when emitting - the register name for the assembler. */ + /* We need a throw away register here, r0 and r1 are reserved, + so r2 is the first available call clobbered register. If + there was a frame_pointer register, we may have swapped the + names of r2 and HARD_FRAME_POINTER_REGNUM, so we have to make + sure we're using the string "r2" when emitting the register + name for the assembler. */ if (current_frame_info.r[reg_fp] && current_frame_info.r[reg_fp] == GR_REG (2)) fp = HARD_FRAME_POINTER_REGNUM; @@ -9590,6 +9602,17 @@ ia64_dwarf2out_def_steady_cfa (rtx insn, bool frame) + ARG_POINTER_CFA_OFFSET (current_function_decl)); } +/* All we need to do here is avoid a crash in the generic dwarf2 + processing. The real CFA definition is set up above. */ + +static void +ia64_dwarf_handle_frame_unspec (const char * ARG_UNUSED (label), + rtx ARG_UNUSED (pattern), + int index) +{ + gcc_assert (index == UNSPECV_ALLOC); +} + /* The generic dwarf2 frame debug info generator does not define a separate region for the very end of the epilogue, so refrain from doing so in the IA64-specific code as well. */ @@ -9619,53 +9642,19 @@ process_epilogue (FILE *asm_out_file, rtx insn, bool unwind, bool frame) STACK_POINTER_REGNUM, INCOMING_FRAME_SP_OFFSET); } -/* This function processes a SET pattern looking for specific patterns - which result in emitting an assembly directive required for unwinding. */ +/* This function processes a SET pattern for REG_CFA_ADJUST_CFA. */ -static int -process_set (FILE *asm_out_file, rtx pat, rtx insn, bool unwind, bool frame) +static void +process_cfa_adjust_cfa (FILE *asm_out_file, rtx pat, rtx insn, + bool unwind, bool frame) { - rtx src = SET_SRC (pat); rtx dest = SET_DEST (pat); - int src_regno, dest_regno; - - /* Look for the ALLOC insn. */ - if (GET_CODE (src) == UNSPEC_VOLATILE - && XINT (src, 1) == UNSPECV_ALLOC - && GET_CODE (dest) == REG) - { - dest_regno = REGNO (dest); - - /* If this is the final destination for ar.pfs, then this must - be the alloc in the prologue. */ - if (dest_regno == current_frame_info.r[reg_save_ar_pfs]) - { - if (unwind) - fprintf (asm_out_file, "\t.save ar.pfs, r%d\n", - ia64_dbx_register_number (dest_regno)); - } - else - { - /* This must be an alloc before a sibcall. We must drop the - old frame info. The easiest way to drop the old frame - info is to ensure we had a ".restore sp" directive - followed by a new prologue. If the procedure doesn't - have a memory-stack frame, we'll issue a dummy ".restore - sp" now. */ - if (current_frame_info.total_size == 0 && !frame_pointer_needed) - /* if haven't done process_epilogue() yet, do it now */ - process_epilogue (asm_out_file, insn, unwind, frame); - if (unwind) - fprintf (asm_out_file, "\t.prologue\n"); - } - return 1; - } + rtx src = SET_SRC (pat); - /* Look for SP = .... */ - if (GET_CODE (dest) == REG && REGNO (dest) == STACK_POINTER_REGNUM) + if (dest == stack_pointer_rtx) { if (GET_CODE (src) == PLUS) - { + { rtx op0 = XEXP (src, 0); rtx op1 = XEXP (src, 1); @@ -9675,7 +9664,8 @@ process_set (FILE *asm_out_file, rtx pat, rtx insn, bool unwind, bool frame) { gcc_assert (!frame_pointer_needed); if (unwind) - fprintf (asm_out_file, "\t.fframe "HOST_WIDE_INT_PRINT_DEC"\n", + fprintf (asm_out_file, + "\t.fframe "HOST_WIDE_INT_PRINT_DEC"\n", -INTVAL (op1)); ia64_dwarf2out_def_steady_cfa (insn, frame); } @@ -9684,240 +9674,303 @@ process_set (FILE *asm_out_file, rtx pat, rtx insn, bool unwind, bool frame) } else { - gcc_assert (GET_CODE (src) == REG - && REGNO (src) == HARD_FRAME_POINTER_REGNUM); + gcc_assert (src == hard_frame_pointer_rtx); process_epilogue (asm_out_file, insn, unwind, frame); } + } + else if (dest == hard_frame_pointer_rtx) + { + gcc_assert (src == stack_pointer_rtx); + gcc_assert (frame_pointer_needed); - return 1; + if (unwind) + fprintf (asm_out_file, "\t.vframe r%d\n", + ia64_dbx_register_number (REGNO (dest))); + ia64_dwarf2out_def_steady_cfa (insn, frame); } + else + gcc_unreachable (); +} - /* Register move we need to look at. */ - if (GET_CODE (dest) == REG && GET_CODE (src) == REG) - { - src_regno = REGNO (src); - dest_regno = REGNO (dest); +/* This function processes a SET pattern for REG_CFA_REGISTER. */ - switch (src_regno) - { - case BR_REG (0): - /* Saving return address pointer. */ - gcc_assert (dest_regno == current_frame_info.r[reg_save_b0]); - if (unwind) - fprintf (asm_out_file, "\t.save rp, r%d\n", - ia64_dbx_register_number (dest_regno)); - return 1; +static void +process_cfa_register (FILE *asm_out_file, rtx pat, bool unwind) +{ + rtx dest = SET_DEST (pat); + rtx src = SET_SRC (pat); - case PR_REG (0): - gcc_assert (dest_regno == current_frame_info.r[reg_save_pr]); - if (unwind) - fprintf (asm_out_file, "\t.save pr, r%d\n", - ia64_dbx_register_number (dest_regno)); - return 1; + int dest_regno = REGNO (dest); + int src_regno = REGNO (src); - case AR_UNAT_REGNUM: - gcc_assert (dest_regno == current_frame_info.r[reg_save_ar_unat]); - if (unwind) - fprintf (asm_out_file, "\t.save ar.unat, r%d\n", - ia64_dbx_register_number (dest_regno)); - return 1; + switch (src_regno) + { + case BR_REG (0): + /* Saving return address pointer. */ + gcc_assert (dest_regno == current_frame_info.r[reg_save_b0]); + if (unwind) + fprintf (asm_out_file, "\t.save rp, r%d\n", + ia64_dbx_register_number (dest_regno)); + break; - case AR_LC_REGNUM: - gcc_assert (dest_regno == current_frame_info.r[reg_save_ar_lc]); - if (unwind) - fprintf (asm_out_file, "\t.save ar.lc, r%d\n", - ia64_dbx_register_number (dest_regno)); - return 1; + case PR_REG (0): + gcc_assert (dest_regno == current_frame_info.r[reg_save_pr]); + if (unwind) + fprintf (asm_out_file, "\t.save pr, r%d\n", + ia64_dbx_register_number (dest_regno)); + break; - case STACK_POINTER_REGNUM: - gcc_assert (dest_regno == HARD_FRAME_POINTER_REGNUM - && frame_pointer_needed); - if (unwind) - fprintf (asm_out_file, "\t.vframe r%d\n", - ia64_dbx_register_number (dest_regno)); - ia64_dwarf2out_def_steady_cfa (insn, frame); - return 1; + case AR_UNAT_REGNUM: + gcc_assert (dest_regno == current_frame_info.r[reg_save_ar_unat]); + if (unwind) + fprintf (asm_out_file, "\t.save ar.unat, r%d\n", + ia64_dbx_register_number (dest_regno)); + break; - default: - /* Everything else should indicate being stored to memory. */ - gcc_unreachable (); - } + case AR_LC_REGNUM: + gcc_assert (dest_regno == current_frame_info.r[reg_save_ar_lc]); + if (unwind) + fprintf (asm_out_file, "\t.save ar.lc, r%d\n", + ia64_dbx_register_number (dest_regno)); + break; + + default: + /* Everything else should indicate being stored to memory. */ + gcc_unreachable (); } +} - /* Memory store we need to look at. */ - if (GET_CODE (dest) == MEM && GET_CODE (src) == REG) - { - long off; - rtx base; - const char *saveop; +/* This function processes a SET pattern for REG_CFA_OFFSET. */ - if (GET_CODE (XEXP (dest, 0)) == REG) - { - base = XEXP (dest, 0); - off = 0; - } - else - { - gcc_assert (GET_CODE (XEXP (dest, 0)) == PLUS - && GET_CODE (XEXP (XEXP (dest, 0), 1)) == CONST_INT); - base = XEXP (XEXP (dest, 0), 0); - off = INTVAL (XEXP (XEXP (dest, 0), 1)); - } +static void +process_cfa_offset (FILE *asm_out_file, rtx pat, bool unwind) +{ + rtx dest = SET_DEST (pat); + rtx src = SET_SRC (pat); + int src_regno = REGNO (src); + const char *saveop; + HOST_WIDE_INT off; + rtx base; - if (base == hard_frame_pointer_rtx) - { - saveop = ".savepsp"; - off = - off; - } - else - { - gcc_assert (base == stack_pointer_rtx); - saveop = ".savesp"; - } + gcc_assert (MEM_P (dest)); + if (GET_CODE (XEXP (dest, 0)) == REG) + { + base = XEXP (dest, 0); + off = 0; + } + else + { + gcc_assert (GET_CODE (XEXP (dest, 0)) == PLUS + && GET_CODE (XEXP (XEXP (dest, 0), 1)) == CONST_INT); + base = XEXP (XEXP (dest, 0), 0); + off = INTVAL (XEXP (XEXP (dest, 0), 1)); + } - src_regno = REGNO (src); - switch (src_regno) - { - case BR_REG (0): - gcc_assert (!current_frame_info.r[reg_save_b0]); - if (unwind) - fprintf (asm_out_file, "\t%s rp, %ld\n", saveop, off); - return 1; + if (base == hard_frame_pointer_rtx) + { + saveop = ".savepsp"; + off = - off; + } + else + { + gcc_assert (base == stack_pointer_rtx); + saveop = ".savesp"; + } - case PR_REG (0): - gcc_assert (!current_frame_info.r[reg_save_pr]); - if (unwind) - fprintf (asm_out_file, "\t%s pr, %ld\n", saveop, off); - return 1; + src_regno = REGNO (src); + switch (src_regno) + { + case BR_REG (0): + gcc_assert (!current_frame_info.r[reg_save_b0]); + if (unwind) + fprintf (asm_out_file, "\t%s rp, " HOST_WIDE_INT_PRINT_DEC "\n", + saveop, off); + break; - case AR_LC_REGNUM: - gcc_assert (!current_frame_info.r[reg_save_ar_lc]); - if (unwind) - fprintf (asm_out_file, "\t%s ar.lc, %ld\n", saveop, off); - return 1; + case PR_REG (0): + gcc_assert (!current_frame_info.r[reg_save_pr]); + if (unwind) + fprintf (asm_out_file, "\t%s pr, " HOST_WIDE_INT_PRINT_DEC "\n", + saveop, off); + break; - case AR_PFS_REGNUM: - gcc_assert (!current_frame_info.r[reg_save_ar_pfs]); - if (unwind) - fprintf (asm_out_file, "\t%s ar.pfs, %ld\n", saveop, off); - return 1; + case AR_LC_REGNUM: + gcc_assert (!current_frame_info.r[reg_save_ar_lc]); + if (unwind) + fprintf (asm_out_file, "\t%s ar.lc, " HOST_WIDE_INT_PRINT_DEC "\n", + saveop, off); + break; - case AR_UNAT_REGNUM: - gcc_assert (!current_frame_info.r[reg_save_ar_unat]); - if (unwind) - fprintf (asm_out_file, "\t%s ar.unat, %ld\n", saveop, off); - return 1; + case AR_PFS_REGNUM: + gcc_assert (!current_frame_info.r[reg_save_ar_pfs]); + if (unwind) + fprintf (asm_out_file, "\t%s ar.pfs, " HOST_WIDE_INT_PRINT_DEC "\n", + saveop, off); + break; - case GR_REG (4): - case GR_REG (5): - case GR_REG (6): - case GR_REG (7): - if (unwind) - fprintf (asm_out_file, "\t.save.g 0x%x\n", - 1 << (src_regno - GR_REG (4))); - return 1; + case AR_UNAT_REGNUM: + gcc_assert (!current_frame_info.r[reg_save_ar_unat]); + if (unwind) + fprintf (asm_out_file, "\t%s ar.unat, " HOST_WIDE_INT_PRINT_DEC "\n", + saveop, off); + break; - case BR_REG (1): - case BR_REG (2): - case BR_REG (3): - case BR_REG (4): - case BR_REG (5): - if (unwind) - fprintf (asm_out_file, "\t.save.b 0x%x\n", - 1 << (src_regno - BR_REG (1))); - return 1; + case GR_REG (4): + case GR_REG (5): + case GR_REG (6): + case GR_REG (7): + if (unwind) + fprintf (asm_out_file, "\t.save.g 0x%x\n", + 1 << (src_regno - GR_REG (4))); + break; - case FR_REG (2): - case FR_REG (3): - case FR_REG (4): - case FR_REG (5): - if (unwind) - fprintf (asm_out_file, "\t.save.f 0x%x\n", - 1 << (src_regno - FR_REG (2))); - return 1; + case BR_REG (1): + case BR_REG (2): + case BR_REG (3): + case BR_REG (4): + case BR_REG (5): + if (unwind) + fprintf (asm_out_file, "\t.save.b 0x%x\n", + 1 << (src_regno - BR_REG (1))); + break; - case FR_REG (16): case FR_REG (17): case FR_REG (18): case FR_REG (19): - case FR_REG (20): case FR_REG (21): case FR_REG (22): case FR_REG (23): - case FR_REG (24): case FR_REG (25): case FR_REG (26): case FR_REG (27): - case FR_REG (28): case FR_REG (29): case FR_REG (30): case FR_REG (31): - if (unwind) - fprintf (asm_out_file, "\t.save.gf 0x0, 0x%x\n", - 1 << (src_regno - FR_REG (12))); - return 1; + case FR_REG (2): + case FR_REG (3): + case FR_REG (4): + case FR_REG (5): + if (unwind) + fprintf (asm_out_file, "\t.save.f 0x%x\n", + 1 << (src_regno - FR_REG (2))); + break; - default: - return 0; - } - } + case FR_REG (16): case FR_REG (17): case FR_REG (18): case FR_REG (19): + case FR_REG (20): case FR_REG (21): case FR_REG (22): case FR_REG (23): + case FR_REG (24): case FR_REG (25): case FR_REG (26): case FR_REG (27): + case FR_REG (28): case FR_REG (29): case FR_REG (30): case FR_REG (31): + if (unwind) + fprintf (asm_out_file, "\t.save.gf 0x0, 0x%x\n", + 1 << (src_regno - FR_REG (12))); + break; - return 0; + default: + /* ??? For some reason we mark other general registers, even those + we can't represent in the unwind info. Ignore them. */ + break; + } } - /* This function looks at a single insn and emits any directives required to unwind this insn. */ + static void ia64_asm_unwind_emit (FILE *asm_out_file, rtx insn) { bool unwind = (flag_unwind_tables || (flag_exceptions && !USING_SJLJ_EXCEPTIONS)); bool frame = dwarf2out_do_frame (); + rtx note, pat; + bool handled_one; + + if (!unwind && !frame) + return; - if (unwind || frame) + if (NOTE_INSN_BASIC_BLOCK_P (insn)) { - rtx pat; + last_block = NOTE_BASIC_BLOCK (insn)->next_bb == EXIT_BLOCK_PTR; - if (NOTE_INSN_BASIC_BLOCK_P (insn)) + /* Restore unwind state from immediately before the epilogue. */ + if (need_copy_state) { - last_block = NOTE_BASIC_BLOCK (insn)->next_bb == EXIT_BLOCK_PTR; - - /* Restore unwind state from immediately before the epilogue. */ - if (need_copy_state) + if (unwind) { - if (unwind) - { - fprintf (asm_out_file, "\t.body\n"); - fprintf (asm_out_file, "\t.copy_state %d\n", - cfun->machine->state_num); - } - if (IA64_CHANGE_CFA_IN_EPILOGUE) - ia64_dwarf2out_def_steady_cfa (insn, frame); - need_copy_state = false; + fprintf (asm_out_file, "\t.body\n"); + fprintf (asm_out_file, "\t.copy_state %d\n", + cfun->machine->state_num); } + if (IA64_CHANGE_CFA_IN_EPILOGUE) + ia64_dwarf2out_def_steady_cfa (insn, frame); + need_copy_state = false; } + } - if (GET_CODE (insn) == NOTE || ! RTX_FRAME_RELATED_P (insn)) - return; + if (GET_CODE (insn) == NOTE || ! RTX_FRAME_RELATED_P (insn)) + return; + + /* Look for the ALLOC insn. */ + if (INSN_CODE (insn) == CODE_FOR_alloc) + { + rtx dest = SET_DEST (XVECEXP (PATTERN (insn), 0, 0)); + int dest_regno = REGNO (dest); - pat = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX); - if (pat) - pat = XEXP (pat, 0); + /* If this is the final destination for ar.pfs, then this must + be the alloc in the prologue. */ + if (dest_regno == current_frame_info.r[reg_save_ar_pfs]) + { + if (unwind) + fprintf (asm_out_file, "\t.save ar.pfs, r%d\n", + ia64_dbx_register_number (dest_regno)); + } else - pat = PATTERN (insn); + { + /* This must be an alloc before a sibcall. We must drop the + old frame info. The easiest way to drop the old frame + info is to ensure we had a ".restore sp" directive + followed by a new prologue. If the procedure doesn't + have a memory-stack frame, we'll issue a dummy ".restore + sp" now. */ + if (current_frame_info.total_size == 0 && !frame_pointer_needed) + /* if haven't done process_epilogue() yet, do it now */ + process_epilogue (asm_out_file, insn, unwind, frame); + if (unwind) + fprintf (asm_out_file, "\t.prologue\n"); + } + return; + } - switch (GET_CODE (pat)) - { - case SET: - process_set (asm_out_file, pat, insn, unwind, frame); - break; + handled_one = false; + for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) + switch (REG_NOTE_KIND (note)) + { + case REG_CFA_ADJUST_CFA: + pat = XEXP (note, 0); + if (pat == NULL) + pat = PATTERN (insn); + process_cfa_adjust_cfa (asm_out_file, pat, insn, unwind, frame); + handled_one = true; + break; - case PARALLEL: - { - int par_index; - int limit = XVECLEN (pat, 0); - for (par_index = 0; par_index < limit; par_index++) - { - rtx x = XVECEXP (pat, 0, par_index); - if (GET_CODE (x) == SET) - process_set (asm_out_file, x, insn, unwind, frame); - } - break; - } + case REG_CFA_OFFSET: + pat = XEXP (note, 0); + if (pat == NULL) + pat = PATTERN (insn); + process_cfa_offset (asm_out_file, pat, unwind); + handled_one = true; + break; - default: - gcc_unreachable (); - } - } + case REG_CFA_REGISTER: + pat = XEXP (note, 0); + if (pat == NULL) + pat = PATTERN (insn); + process_cfa_register (asm_out_file, pat, unwind); + handled_one = true; + break; + + case REG_FRAME_RELATED_EXPR: + case REG_CFA_DEF_CFA: + case REG_CFA_EXPRESSION: + case REG_CFA_RESTORE: + case REG_CFA_SET_VDRAP: + /* Not used in the ia64 port. */ + gcc_unreachable (); + + default: + /* Not a frame-related note. */ + break; + } + + /* All REG_FRAME_RELATED_P insns, besides ALLOC, are marked with the + explicit action to take. No guessing required. */ + gcc_assert (handled_one); } /* Implement TARGET_ASM_EMIT_EXCEPT_PERSONALITY. */ -- 2.30.2