Exception handling on the Blackfin was broken by the dataflow merge. Inspecting the differences in the generated code, it appears that when compiling functions like _Unwind_Resume in unwind-dw2.c, the dse pass deletes necessary instructions.
Before: (insn 56 55 57 7 (set (reg/v:SI 56 [ offset ]) (reg:SI 0 R0)) 14 {*movsi_insn} (expr_list:REG_DEAD (reg:SI 0 R0) (nil))) (insn 57 56 67 7 (set (reg/v/f:SI 55 [ handler ]) (mem/s/f/c:SI (plus:SI (reg/f:SI 15 FP) (const_int -376 [0xfffffe88])) [12 cur_context.ra+0 S4 A32])) 14 {*movsi_insn} (nil)) (insn 67 57 68 7 (set (reg:SI 10 P2 [ offset ]) (reg/v:SI 56 [ offset ])) 14 {*movsi_insn} (expr_list:REG_DEAD (reg/v:SI 56 [ offset ]) (nil))) (insn 68 67 69 7 (set (mem:SI (plus:SI (reg/f:SI 15 FP) (const_int 4 [0x4])) [0 S4 A32]) (reg/v/f:SI 55 [ handler ])) 14 {*movsi_insn} (expr_list:REG_DEAD (reg/v/f:SI 55 [ handler ]) (nil))) (jump_insn 69 68 0 7 (set (pc) (unspec_volatile [ (reg:SI 10 P2) ] 0)) 126 {eh_return_internal} (expr_list:REG_DEAD (reg:SI 10 P2) (expr_list:REG_EQUAL (unspec_volatile [ (reg:SI 10 P2) ] 0) (nil)))) After: (insn 56 55 67 7 (set (reg/v:SI 56 [ offset ]) (reg:SI 0 R0)) 14 {*movsi_insn} (expr_list:REG_DEAD (reg:SI 0 R0) (nil))) (insn 67 56 69 7 (set (reg:SI 10 P2 [ offset ]) (reg/v:SI 56 [ offset ])) 14 {*movsi_insn} (expr_list:REG_DEAD (reg/v:SI 56 [ offset ]) (nil))) (jump_insn 69 67 0 7 (set (pc) (unspec_volatile [ (reg:SI 10 P2) ] 0)) 126 {eh_return_internal} (expr_list:REG_DEAD (reg:SI 10 P2) (expr_list:REG_EQUAL (unspec_volatile [ (reg:SI 10 P2) ] 0) (nil)))) [FP + 4] is part of the register save area. Insn 68, which stores a value into it, gets deleted. There is a reference to current_function_uses_eh_return in dse.c, but it's not clear to me what it's trying to achieve. Anyway, turning the store into an unspec_volatile solves the problem. I've committed the following. Bernd -- This footer brought to you by insane German lawmakers. Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 40368 Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif
Index: ChangeLog =================================================================== --- ChangeLog (revision 125680) +++ ChangeLog (working copy) @@ -1,3 +1,10 @@ +2007-06-13 Bernd Schmidt <[EMAIL PROTECTED]> + + * config/bfin/bfin.h (EH_RETURN_HANDLER_RTX): Use gen_frame_mem. + * config/bfin/bfin.md (UNSPEC_VOLATILE_STORE_EH_HANDLER): New constant. + (eh_store_handler): New pattern. + (eh_return): Emit it instead of a plain move. + 2007-06-13 Uros Bizjak <[EMAIL PROTECTED]> * config/i386/i386.c (ix86_init_mmx_sse_builtins) Index: config/bfin/bfin.h =================================================================== --- config/bfin/bfin.h (revision 125641) +++ config/bfin/bfin.h (working copy) @@ -813,7 +813,7 @@ typedef struct { #define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) : INVALID_REGNUM) #define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, REG_P2) #define EH_RETURN_HANDLER_RTX \ - gen_rtx_MEM (Pmode, plus_constant (frame_pointer_rtx, UNITS_PER_WORD)) + gen_frame_mem (Pmode, plus_constant (frame_pointer_rtx, UNITS_PER_WORD)) /* Addressing Modes */ Index: config/bfin/bfin.md =================================================================== --- config/bfin/bfin.md (revision 125648) +++ config/bfin/bfin.md (working copy) @@ -144,7 +144,8 @@ (define_constants [(UNSPEC_VOLATILE_EH_RETURN 0) (UNSPEC_VOLATILE_CSYNC 1) (UNSPEC_VOLATILE_SSYNC 2) - (UNSPEC_VOLATILE_LOAD_FUNCDESC 3)]) + (UNSPEC_VOLATILE_LOAD_FUNCDESC 3) + (UNSPEC_VOLATILE_STORE_EH_HANDLER 4)]) (define_constants [(MACFLAG_NONE 0) @@ -2687,12 +2688,20 @@ (define_expand "eh_return" UNSPEC_VOLATILE_EH_RETURN)] "" { - emit_move_insn (EH_RETURN_HANDLER_RTX, operands[0]); + emit_insn (gen_eh_store_handler (EH_RETURN_HANDLER_RTX, operands[0])); emit_jump_insn (gen_eh_return_internal ()); emit_barrier (); DONE; }) +(define_insn "eh_store_handler" + [(unspec_volatile [(match_operand:SI 1 "register_operand" "da")] + UNSPEC_VOLATILE_STORE_EH_HANDLER) + (clobber (match_operand:SI 0 "memory_operand" "=m"))] + "" + "%0 = %1%!" + [(set_attr "type" "mcst")]) + (define_insn_and_split "eh_return_internal" [(set (pc) (unspec_volatile [(reg:SI REG_P2)] UNSPEC_VOLATILE_EH_RETURN))]