From: Jan Beulich Date: Mon, 31 Jan 2005 09:46:15 +0000 (+0000) Subject: gas/ X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=75e0991382fb4617434490056616fab346359fc2;p=binutils-gdb.git gas/ 2005-01-31 Jan Beulich * config/tc-ia64.c (unwind): Remove proc_end (now an automatic variable in dot_endp). Add body and insn. Make prologue, prologue_mask, body, and insn bitfields. (fixup_unw_records): Remove spurious new-lines from end of diagnostic messages. (in_procedure, in_prologue, in_body): New. (dot_fframe, dot_vframe, dot_vframesp, dot_vframepsp, dot_save, dot_restore, dot_restorereg, dot_restorereg_p, dot_handlerdata, dot_unwentry, dot_altrp, dot_savemem, dot_saveg, dot_savef, dot_saveb, dot_savegf, dot_spill, dot_spillreg, dot_spillmem, dot_spillreg_p, dot_spillmem_p, dot_label_state, dot_copy_state, dot_unwabi, dot_personality): Use the appropriate one of the above. (dot_proc): Clear unwind.proc_start; set to current location only if none of the entry points were valid. Check for non-zero-length entry point names. Check that entry points aren't defined, yet. Clear unwind.prologue, unwind.body, and unwind.insn. (dot_body): Call in_procedure. Check that first directive in procedure had no insns emitted before. Set unwind.body. (dot_prologue): Call in_procedure. Check that not already in prologue. Check that first directive in procedure had no insns emitted before. Clear unwind.body. (dot_endp): Call in_procedure. Declare proc_end. Check for non-zero- length entry point names. Check that entry points became defined. (md_assemble): Set unwind.insn once unwind.proc_start is defined. gas/testsuite/ 2005-01-31 Jan Beulich * gas/ia64/proc.[ls]: New. * gas/ia64/unwind-err.[ls]: New. * gas/ia64/ia64.exp: Run new tests. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 73079cf2dde..0af5769087b 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,30 @@ +2005-01-31 Jan Beulich + + * config/tc-ia64.c (unwind): Remove proc_end (now an automatic + variable in dot_endp). Add body and insn. Make prologue, + prologue_mask, body, and insn bitfields. + (fixup_unw_records): Remove spurious new-lines from end of diagnostic + messages. + (in_procedure, in_prologue, in_body): New. + (dot_fframe, dot_vframe, dot_vframesp, dot_vframepsp, dot_save, + dot_restore, dot_restorereg, dot_restorereg_p, dot_handlerdata, + dot_unwentry, dot_altrp, dot_savemem, dot_saveg, dot_savef, dot_saveb, + dot_savegf, dot_spill, dot_spillreg, dot_spillmem, dot_spillreg_p, + dot_spillmem_p, dot_label_state, dot_copy_state, dot_unwabi, + dot_personality): Use the appropriate one of the above. + (dot_proc): Clear unwind.proc_start; set to current location only if + none of the entry points were valid. Check for non-zero-length entry + point names. Check that entry points aren't defined, yet. Clear + unwind.prologue, unwind.body, and unwind.insn. + (dot_body): Call in_procedure. Check that first directive in procedure + had no insns emitted before. Set unwind.body. + (dot_prologue): Call in_procedure. Check that not already in prologue. + Check that first directive in procedure had no insns emitted before. + Clear unwind.body. + (dot_endp): Call in_procedure. Declare proc_end. Check for non-zero- + length entry point names. Check that entry points became defined. + (md_assemble): Set unwind.insn once unwind.proc_start is defined. + 2005-01-31 Jan Beulich * config/tc-ia64.c (emit_one_bundle): Snapshot manual bundling state diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c index 51bf2ede0ff..7d87cc538b6 100644 --- a/gas/config/tc-ia64.c +++ b/gas/config/tc-ia64.c @@ -684,7 +684,6 @@ static struct /* These are used to create the unwind table entry for this function. */ symbolS *proc_start; - symbolS *proc_end; symbolS *info; /* pointer to unwind info */ symbolS *personality_routine; segT saved_text_seg; @@ -692,8 +691,10 @@ static struct unsigned int force_unwind_entry : 1; /* force generation of unwind entry? */ /* TRUE if processing unwind directives in a prologue region. */ - int prologue; - int prologue_mask; + unsigned int prologue : 1; + unsigned int prologue_mask : 4; + unsigned int body : 1; + unsigned int insn : 1; unsigned int prologue_count; /* number of .prologues seen so far */ /* Prologue counts at previous .label_state directives. */ struct label_prologue_count * saved_prologue_counts; @@ -2785,7 +2786,7 @@ fixup_unw_records (list, before_relax) case frgr_mem: if (!region) { - as_bad ("frgr_mem record before region record!\n"); + as_bad ("frgr_mem record before region record!"); return; } region->r.record.r.mask.fr_mem |= ptr->r.record.p.frmask; @@ -2796,7 +2797,7 @@ fixup_unw_records (list, before_relax) case fr_mem: if (!region) { - as_bad ("fr_mem record before region record!\n"); + as_bad ("fr_mem record before region record!"); return; } region->r.record.r.mask.fr_mem |= ptr->r.record.p.rmask; @@ -2805,7 +2806,7 @@ fixup_unw_records (list, before_relax) case gr_mem: if (!region) { - as_bad ("gr_mem record before region record!\n"); + as_bad ("gr_mem record before region record!"); return; } region->r.record.r.mask.gr_mem |= ptr->r.record.p.rmask; @@ -2814,7 +2815,7 @@ fixup_unw_records (list, before_relax) case br_mem: if (!region) { - as_bad ("br_mem record before region record!\n"); + as_bad ("br_mem record before region record!"); return; } region->r.record.r.mask.br_mem |= ptr->r.record.p.brmask; @@ -2824,7 +2825,7 @@ fixup_unw_records (list, before_relax) case gr_gr: if (!region) { - as_bad ("gr_gr record before region record!\n"); + as_bad ("gr_gr record before region record!"); return; } set_imask (region, ptr->r.record.p.grmask, t, 2); @@ -2832,7 +2833,7 @@ fixup_unw_records (list, before_relax) case br_gr: if (!region) { - as_bad ("br_gr record before region record!\n"); + as_bad ("br_gr record before region record!"); return; } set_imask (region, ptr->r.record.p.brmask, t, 3); @@ -3067,6 +3068,43 @@ dot_special_section (which) set_section ((char *) special_section_name[which]); } +static int +in_procedure (const char *directive) +{ + if (unwind.proc_start + && (!unwind.saved_text_seg || strcmp (directive, "endp") == 0)) + return 1; + as_bad (".%s outside of procedure", directive); + ignore_rest_of_line (); + return 0; +} + +static int +in_prologue (const char *directive) +{ + if (in_procedure (directive)) + { + if (unwind.prologue) + return 1; + as_bad (".%s outside of prologue", directive); + ignore_rest_of_line (); + } + return 0; +} + +static int +in_body (const char *directive) +{ + if (in_procedure (directive)) + { + if (unwind.body) + return 1; + as_bad (".%s outside of body region", directive); + ignore_rest_of_line (); + } + return 0; +} + static void add_unwind_entry (ptr) unw_rec_list *ptr; @@ -3088,6 +3126,9 @@ dot_fframe (dummy) { expressionS e; + if (!in_prologue ("fframe")) + return; + parse_operand (&e); if (e.X_op != O_constant) @@ -3103,6 +3144,9 @@ dot_vframe (dummy) expressionS e; unsigned reg; + if (!in_prologue ("vframe")) + return; + parse_operand (&e); reg = e.X_add_number - REG_GR; if (e.X_op == O_register && reg < 128) @@ -3121,6 +3165,9 @@ dot_vframesp (dummy) { expressionS e; + if (!in_prologue ("vframesp")) + return; + parse_operand (&e); if (e.X_op == O_constant) { @@ -3137,6 +3184,9 @@ dot_vframepsp (dummy) { expressionS e; + if (!in_prologue ("vframepsp")) + return; + parse_operand (&e); if (e.X_op == O_constant) { @@ -3155,6 +3205,9 @@ dot_save (dummy) int sep; int reg1, reg2; + if (!in_prologue ("save")) + return; + sep = parse_operand (&e1); if (sep != ',') as_bad ("No second operand to .save"); @@ -3232,6 +3285,9 @@ dot_restore (dummy) unsigned long ecount; /* # of _additional_ regions to pop */ int sep; + if (!in_body ("restore")) + return; + sep = parse_operand (&e1); if (e1.X_op != O_register || e1.X_add_number != REG_GR + 12) { @@ -3274,6 +3330,9 @@ dot_restorereg (dummy) unsigned int ab, reg; expressionS e; + if (!in_procedure ("restorereg")) + return; + parse_operand (&e); if (!convert_expr_to_ab_reg (&e, &ab, ®)) @@ -3292,6 +3351,9 @@ dot_restorereg_p (dummy) expressionS e1, e2; int sep; + if (!in_procedure ("restorereg.p")) + return; + sep = parse_operand (&e1); if (sep != ',') { @@ -3525,6 +3587,8 @@ static void dot_handlerdata (dummy) int dummy ATTRIBUTE_UNUSED; { + if (!in_procedure ("handlerdata")) + return; unwind.force_unwind_entry = 1; /* Remember which segment we're in so we can switch back after .endp */ @@ -3542,6 +3606,8 @@ static void dot_unwentry (dummy) int dummy ATTRIBUTE_UNUSED; { + if (!in_procedure ("unwentry")) + return; unwind.force_unwind_entry = 1; demand_empty_rest_of_line (); } @@ -3553,6 +3619,9 @@ dot_altrp (dummy) expressionS e; unsigned reg; + if (!in_prologue ("altrp")) + return; + parse_operand (&e); reg = e.X_add_number - REG_BR; if (e.X_op == O_register && reg < 8) @@ -3569,6 +3638,9 @@ dot_savemem (psprel) int sep; int reg1, val; + if (!in_prologue (psprel ? "savepsp" : "savesp")) + return; + sep = parse_operand (&e1); if (sep != ',') as_bad ("No second operand to .save%ssp", psprel ? "p" : ""); @@ -3661,6 +3733,10 @@ dot_saveg (dummy) { expressionS e1, e2; int sep; + + if (!in_prologue ("save.g")) + return; + sep = parse_operand (&e1); if (sep == ',') parse_operand (&e2); @@ -3689,6 +3765,10 @@ dot_savef (dummy) { expressionS e1; int sep; + + if (!in_prologue ("save.f")) + return; + sep = parse_operand (&e1); if (e1.X_op != O_constant) @@ -3706,6 +3786,9 @@ dot_saveb (dummy) unsigned char sep; int brmask; + if (!in_prologue ("save.b")) + return; + sep = parse_operand (&e1); if (e1.X_op != O_constant) { @@ -3738,6 +3821,10 @@ dot_savegf (dummy) { expressionS e1, e2; int sep; + + if (!in_prologue ("save.gf")) + return; + sep = parse_operand (&e1); if (sep == ',') parse_operand (&e2); @@ -3759,6 +3846,9 @@ dot_spill (dummy) expressionS e; unsigned char sep; + if (!in_prologue ("spill")) + return; + sep = parse_operand (&e); if (!is_end_of_line[sep] && !is_it_end_of_statement ()) demand_empty_rest_of_line (); @@ -3776,6 +3866,9 @@ dot_spillreg (dummy) int sep, ab, xy, reg, treg; expressionS e1, e2; + if (!in_procedure ("spillreg")) + return; + sep = parse_operand (&e1); if (sep != ',') { @@ -3807,6 +3900,9 @@ dot_spillmem (psprel) expressionS e1, e2; int sep, ab, reg; + if (!in_procedure ("spillmem")) + return; + sep = parse_operand (&e1); if (sep != ',') { @@ -3844,6 +3940,9 @@ dot_spillreg_p (dummy) expressionS e1, e2, e3; unsigned int qp; + if (!in_procedure ("spillreg.p")) + return; + sep = parse_operand (&e1); if (sep != ',') { @@ -3891,6 +3990,9 @@ dot_spillmem_p (psprel) int sep, ab, reg; unsigned int qp; + if (!in_procedure ("spillmem.p")) + return; + sep = parse_operand (&e1); if (sep != ',') { @@ -3996,6 +4098,9 @@ dot_label_state (dummy) { expressionS e; + if (!in_body ("label_state")) + return; + parse_operand (&e); if (e.X_op != O_constant) { @@ -4012,6 +4117,9 @@ dot_copy_state (dummy) { expressionS e; + if (!in_body ("copy_state")) + return; + parse_operand (&e); if (e.X_op != O_constant) { @@ -4029,6 +4137,9 @@ dot_unwabi (dummy) expressionS e1, e2; unsigned char sep; + if (!in_procedure ("unwabi")) + return; + sep = parse_operand (&e1); if (sep != ',') { @@ -4059,6 +4170,8 @@ dot_personality (dummy) int dummy ATTRIBUTE_UNUSED; { char *name, *p, c; + if (!in_procedure ("personality")) + return; SKIP_WHITESPACE (); name = input_line_pointer; c = get_symbol_end (); @@ -4077,7 +4190,7 @@ dot_proc (dummy) char *name, *p, c; symbolS *sym; - unwind.proc_start = expr_build_dot (); + unwind.proc_start = 0; /* Parse names of main and alternate entry points and mark them as function symbols: */ while (1) @@ -4086,22 +4199,34 @@ dot_proc (dummy) name = input_line_pointer; c = get_symbol_end (); p = input_line_pointer; - sym = symbol_find_or_make (name); - if (unwind.proc_start == 0) + if (!*name) + as_bad ("Empty argument of .proc"); + else { - unwind.proc_start = sym; + sym = symbol_find_or_make (name); + if (S_IS_DEFINED (sym)) + as_bad ("`%s' was already defined", name); + else if (unwind.proc_start == 0) + { + unwind.proc_start = sym; + } + symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION; } - symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION; *p = c; SKIP_WHITESPACE (); if (*input_line_pointer != ',') break; ++input_line_pointer; } + if (unwind.proc_start == 0) + unwind.proc_start = expr_build_dot (); demand_empty_rest_of_line (); ia64_do_align (16); + unwind.prologue = 0; unwind.prologue_count = 0; + unwind.body = 0; + unwind.insn = 0; unwind.list = unwind.tail = unwind.current_entry = NULL; unwind.personality_routine = 0; } @@ -4110,8 +4235,14 @@ static void dot_body (dummy) int dummy ATTRIBUTE_UNUSED; { + if (!in_procedure ("body")) + return; + if (!unwind.prologue && !unwind.body && unwind.insn) + as_warn ("Initial .body should precede any instructions"); + unwind.prologue = 0; unwind.prologue_mask = 0; + unwind.body = 1; add_unwind_entry (output_body ()); demand_empty_rest_of_line (); @@ -4124,6 +4255,17 @@ dot_prologue (dummy) unsigned char sep; int mask = 0, grsave = 0; + if (!in_procedure ("prologue")) + return; + if (unwind.prologue) + { + as_bad (".prologue within prologue"); + ignore_rest_of_line (); + return; + } + if (!unwind.body && unwind.insn) + as_warn ("Initial .prologue should precede any instructions"); + if (!is_it_end_of_statement ()) { expressionS e1, e2; @@ -4156,6 +4298,7 @@ dot_prologue (dummy) unwind.prologue = 1; unwind.prologue_mask = mask; + unwind.body = 0; ++unwind.prologue_count; } @@ -4172,6 +4315,9 @@ dot_endp (dummy) char *name, *p, c; symbolS *sym; + if (!in_procedure ("endp")) + return; + if (unwind.saved_text_seg) { saved_seg = unwind.saved_text_seg; @@ -4192,8 +4338,10 @@ dot_endp (dummy) if (unwind.info || unwind.force_unwind_entry) { + symbolS *proc_end; + subseg_set (md.last_text_seg, 0); - unwind.proc_end = expr_build_dot (); + proc_end = expr_build_dot (); start_unwind_section (saved_seg, SPECIAL_SECTION_UNWIND, 0); @@ -4217,7 +4365,7 @@ dot_endp (dummy) e.X_op = O_pseudo_fixup; e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym; e.X_add_number = 0; - e.X_add_symbol = unwind.proc_end; + e.X_add_symbol = proc_end; ia64_cons_fix_new (frag_now, where + bytes_per_address, bytes_per_address, &e); @@ -4247,32 +4395,39 @@ dot_endp (dummy) name = input_line_pointer; c = get_symbol_end (); p = input_line_pointer; - sym = symbol_find (name); - if (sym && unwind.proc_start - && (symbol_get_bfdsym (sym)->flags & BSF_FUNCTION) - && S_GET_SIZE (sym) == 0 && symbol_get_obj (sym)->size == NULL) - { - fragS *fr = symbol_get_frag (unwind.proc_start); - fragS *frag = symbol_get_frag (sym); - - /* Check whether the function label is at or beyond last - .proc directive. */ - while (fr && fr != frag) - fr = fr->fr_next; - if (fr) - { - if (frag == frag_now && SEG_NORMAL (now_seg)) - S_SET_SIZE (sym, frag_now_fix () - S_GET_VALUE (sym)); - else + if (!*name) + as_bad ("Empty argument of .endp"); + else + { + sym = symbol_find (name); + if (!sym || !S_IS_DEFINED (sym)) + as_bad ("`%s' was not defined within procedure", name); + else if (unwind.proc_start + && (symbol_get_bfdsym (sym)->flags & BSF_FUNCTION) + && S_GET_SIZE (sym) == 0 && symbol_get_obj (sym)->size == NULL) + { + fragS *fr = symbol_get_frag (unwind.proc_start); + fragS *frag = symbol_get_frag (sym); + + /* Check whether the function label is at or beyond last + .proc directive. */ + while (fr && fr != frag) + fr = fr->fr_next; + if (fr) { - symbol_get_obj (sym)->size = - (expressionS *) xmalloc (sizeof (expressionS)); - symbol_get_obj (sym)->size->X_op = O_subtract; - symbol_get_obj (sym)->size->X_add_symbol - = symbol_new (FAKE_LABEL_NAME, now_seg, - frag_now_fix (), frag_now); - symbol_get_obj (sym)->size->X_op_symbol = sym; - symbol_get_obj (sym)->size->X_add_number = 0; + if (frag == frag_now && SEG_NORMAL (now_seg)) + S_SET_SIZE (sym, frag_now_fix () - S_GET_VALUE (sym)); + else + { + symbol_get_obj (sym)->size = + (expressionS *) xmalloc (sizeof (expressionS)); + symbol_get_obj (sym)->size->X_op = O_subtract; + symbol_get_obj (sym)->size->X_add_symbol + = symbol_new (FAKE_LABEL_NAME, now_seg, + frag_now_fix (), frag_now); + symbol_get_obj (sym)->size->X_op_symbol = sym; + symbol_get_obj (sym)->size->X_add_number = 0; + } } } } @@ -4283,7 +4438,7 @@ dot_endp (dummy) ++input_line_pointer; } demand_empty_rest_of_line (); - unwind.proc_start = unwind.proc_end = unwind.info = 0; + unwind.proc_start = unwind.info = 0; } static void @@ -10213,6 +10368,8 @@ md_assemble (str) CURR_SLOT.unwind_record = unwind.current_entry; unwind.current_entry = NULL; } + if (unwind.proc_start && S_IS_DEFINED (unwind.proc_start)) + unwind.insn = 1; /* Check for dependency violations. */ if (md.detect_dv) diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index bfc1de6a83c..353e3ffa121 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2005-01-31 Jan Beulich + + * gas/ia64/proc.[ls]: New. + * gas/ia64/unwind-err.[ls]: New. + * gas/ia64/ia64.exp: Run new tests. + 2005-01-31 Jan Beulich * gas/ia64/bundling.[ds]: New. diff --git a/gas/testsuite/gas/ia64/ia64.exp b/gas/testsuite/gas/ia64/ia64.exp index 57cea895900..c5dc9e122f2 100644 --- a/gas/testsuite/gas/ia64/ia64.exp +++ b/gas/testsuite/gas/ia64/ia64.exp @@ -65,5 +65,7 @@ if [istarget "ia64-*"] then { run_dump_test "bundling" run_list_test "label" "" run_list_test "last" "" + run_list_test "proc" "" run_list_test "slot2" "" + run_list_test "unwind-err" "" } diff --git a/gas/testsuite/gas/ia64/proc.l b/gas/testsuite/gas/ia64/proc.l new file mode 100644 index 00000000000..8b3322879e5 --- /dev/null +++ b/gas/testsuite/gas/ia64/proc.l @@ -0,0 +1,5 @@ +.*: Assembler messages: +.*:4: Error: .* already defined.* +.*:7: Error: .* not defined.* +.*:12: Error: Empty argument of .proc +.*:13: Error: Empty argument of .endp diff --git a/gas/testsuite/gas/ia64/proc.s b/gas/testsuite/gas/ia64/proc.s new file mode 100644 index 00000000000..9225a0a01b5 --- /dev/null +++ b/gas/testsuite/gas/ia64/proc.s @@ -0,0 +1,13 @@ +func1:: + br.ret.sptk rp + +.proc func, func1, func2 +func:: + br.ret.sptk rp +.endp func, func1, func2 + +func2:: + br.ret.sptk rp + +.proc +.endp diff --git a/gas/testsuite/gas/ia64/unwind-err.l b/gas/testsuite/gas/ia64/unwind-err.l new file mode 100644 index 00000000000..7641df77424 --- /dev/null +++ b/gas/testsuite/gas/ia64/unwind-err.l @@ -0,0 +1,34 @@ +.*: Assembler messages: +.*:1: Error: .endp outside of procedure +.*:2: Error: .personality outside of procedure +.*:3: Error: .unwentry outside of procedure +.*:4: Error: .unwabi outside of procedure +.*:5: Error: .handlerdata outside of procedure +.*:6: Error: .prologue outside of procedure +.*:7: Error: .body outside of procedure +.*:8: Error: .spillreg outside of procedure +.*:9: Error: .spillreg.p outside of procedure +.*:10: Error: .spillmem outside of procedure +.*:11: Error: .spillmem.p outside of procedure +.*:12: Error: .spillmem outside of procedure +.*:13: Error: .spillmem.p outside of procedure +.*:14: Error: .restorereg outside of procedure +.*:15: Error: .restorereg.p outside of procedure +.*:24: Error: .label_state outside of body region +.*:25: Error: .copy_state outside of body region +.*:26: Error: .fframe outside of prologue +.*:27: Error: .vframe outside of prologue +.*:28: Error: .spill outside of prologue +.*:29: Error: .restore outside of body region +.*:30: Error: .save outside of prologue +.*:31: Error: .savesp outside of prologue +.*:32: Error: .savepsp outside of prologue +.*:33: Error: .save.g outside of prologue +.*:34: Error: .save.gf outside of prologue +.*:35: Error: .save.f outside of prologue +.*:36: Error: .save.b outside of prologue +.*:37: Error: .altrp outside of prologue +.*:42: Error: .prologue within prologue +.*:52: Error: .body outside of procedure +.*:59: Warning: Initial .prologue.* +.*:66: Warning: Initial .body.* diff --git a/gas/testsuite/gas/ia64/unwind-err.s b/gas/testsuite/gas/ia64/unwind-err.s new file mode 100644 index 00000000000..49cb6c92f7a --- /dev/null +++ b/gas/testsuite/gas/ia64/unwind-err.s @@ -0,0 +1,68 @@ +.endp xyz +.personality personality +.unwentry +.unwabi @svr4, 0 +.handlerdata +.prologue +.body +.spillreg r4, r8 +.spillreg.p p1, r4, r8 +.spillsp r5, 0 +.spillsp.p p2, r5, 0 +.spillpsp r6, 0 +.spillpsp.p p2, r6, 0 +.restorereg r4 +.restorereg.p p1, r4 + +.proc personality +personality: +.endp personality + +.proc start +start: + +.label_state 1 +.copy_state 1 +.fframe 0 +.vframe r0 +.spill 0 +.restore sp +.save rp, r0 +.savesp pr, 0 +.savepsp ar.fpsr, 0 +.save.g 2 +.save.gf 2,2 +.save.f 2 +.save.b 2 +.altrp b7 +.body + + + .prologue + .prologue + .save ar.lc, r31 + mov r31 = ar.lc + ;; + .body + .body + br.ret.sptk rp + ;; +.personality personality +.handlerdata +.body + +.endp start + +.proc late_prologue +late_prologue: + nop 0 + .prologue + nop 0 +.endp late_prologue + +.proc late_body +late_body: + nop 0 + .body + nop 0 +.endp late_body