Fix ia64-linux kernel miscompile, bad unwind info when reorder epilogue block.
* final.c (final_scan_insn, case NOTE_INSN_BASIC_BLOCK): Call IA64_UNWIND_EMIT. * config/ia64/ia64.c (block_num, need_copy_state): New static vars. (process_epilogue): New static function. (process_set): Call process_epilogue instead of emitting .restore directly. (process_for_unwind_directive): Handle NOTE_INSN_BASIC_BLOCK. From-SVN: r40885
This commit is contained in:
parent
911e61070f
commit
ad0fc69878
@ -7,6 +7,14 @@
|
||||
|
||||
2001-03-27 Jim Wilson <wilson@redhat.com>
|
||||
|
||||
* final.c (final_scan_insn, case NOTE_INSN_BASIC_BLOCK): Call
|
||||
IA64_UNWIND_EMIT.
|
||||
* config/ia64/ia64.c (block_num, need_copy_state): New static vars.
|
||||
(process_epilogue): New static function.
|
||||
(process_set): Call process_epilogue instead of emitting .restore
|
||||
directly.
|
||||
(process_for_unwind_directive): Handle NOTE_INSN_BASIC_BLOCK.
|
||||
|
||||
* flow.c (struct reg_cond_life_info): New fields orig_condition
|
||||
and stores.
|
||||
(init_propagate_block_info): Set new fields.
|
||||
|
@ -6335,7 +6335,32 @@ ia64_encode_section_info (decl)
|
||||
}
|
||||
}
|
||||
|
||||
/* Output assmebly directives for prologue regions. */
|
||||
/* Output assembly directives for prologue regions. */
|
||||
|
||||
/* The current basic block number. */
|
||||
|
||||
static int block_num;
|
||||
|
||||
/* True if we need a copy_state command at the start of the next block. */
|
||||
|
||||
static int need_copy_state;
|
||||
|
||||
/* The function emits unwind directives for the start of an epilogue. */
|
||||
|
||||
static void
|
||||
process_epilogue ()
|
||||
{
|
||||
/* If this isn't the last block of the function, then we need to label the
|
||||
current state, and copy it back in at the start of the next block. */
|
||||
|
||||
if (block_num != n_basic_blocks - 1)
|
||||
{
|
||||
fprintf (asm_out_file, "\t.label_state 1\n");
|
||||
need_copy_state = 1;
|
||||
}
|
||||
|
||||
fprintf (asm_out_file, "\t.restore sp\n");
|
||||
}
|
||||
|
||||
/* This function processes a SET pattern looking for specific patterns
|
||||
which result in emitting an assembly directive required for unwinding. */
|
||||
@ -6383,14 +6408,14 @@ process_set (asm_out_file, pat)
|
||||
fputc ('\n', asm_out_file);
|
||||
}
|
||||
else
|
||||
fprintf (asm_out_file, "\t.restore sp\n");
|
||||
process_epilogue ();
|
||||
}
|
||||
else
|
||||
abort ();
|
||||
}
|
||||
else if (GET_CODE (src) == REG
|
||||
&& REGNO (src) == HARD_FRAME_POINTER_REGNUM)
|
||||
fprintf (asm_out_file, "\t.restore sp\n");
|
||||
process_epilogue ();
|
||||
else
|
||||
abort ();
|
||||
|
||||
@ -6561,12 +6586,28 @@ process_for_unwind_directive (asm_out_file, insn)
|
||||
FILE *asm_out_file;
|
||||
rtx insn;
|
||||
{
|
||||
if ((flag_unwind_tables
|
||||
|| (flag_exceptions && !exceptions_via_longjmp))
|
||||
&& RTX_FRAME_RELATED_P (insn))
|
||||
if (flag_unwind_tables
|
||||
|| (flag_exceptions && !exceptions_via_longjmp))
|
||||
{
|
||||
rtx pat;
|
||||
|
||||
if (GET_CODE (insn) == NOTE
|
||||
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_BASIC_BLOCK)
|
||||
{
|
||||
block_num = NOTE_BASIC_BLOCK (insn)->index;
|
||||
|
||||
/* Restore unwind state from immediately before the epilogue. */
|
||||
if (need_copy_state)
|
||||
{
|
||||
fprintf (asm_out_file, "\t.body\n");
|
||||
fprintf (asm_out_file, "\t.copy_state 1\n");
|
||||
need_copy_state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (! RTX_FRAME_RELATED_P (insn))
|
||||
return;
|
||||
|
||||
pat = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
|
||||
if (pat)
|
||||
pat = XEXP (pat, 0);
|
||||
|
@ -2117,6 +2117,9 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
|
||||
break;
|
||||
|
||||
case NOTE_INSN_BASIC_BLOCK:
|
||||
#ifdef IA64_UNWIND_INFO
|
||||
IA64_UNWIND_EMIT (asm_out_file, insn);
|
||||
#endif
|
||||
if (flag_debug_asm)
|
||||
fprintf (asm_out_file, "\t%s basic block %d\n",
|
||||
ASM_COMMENT_START, NOTE_BASIC_BLOCK (insn)->index);
|
||||
|
Loading…
x
Reference in New Issue
Block a user