From 6abc6f40efa309ed9d84f6b1d778b6cbefe1aaf3 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 5 Sep 1998 15:22:07 -0700 Subject: [PATCH] alpha.c (alpha_ra_ever_killed): Inspect the topmost sequence, not whatever we're generating now. * alpha.c (alpha_ra_ever_killed): Inspect the topmost sequence, not whatever we're generating now. * alpha.c (set_frame_related_p, FRP): New. (alpha_expand_prologue): Mark frame related insns. (alpha_expand_epilogue): Likewise, but with a null FRP. * alpha.h (INCOMING_RETURN_ADDR_RTX): New. * alpha.md (exception_receiver): New. * alpha/crtbegin.asm (.eh_frame): New beginning. (__do_frame_setup, __do_frame_takedown): New. * alpha/crtend.asm (.eh_frame): New ending. * alpha/elf.h (DWARF2_DEBUGGING_INFO): Define. (ASM_SPEC): Don't emit both dwarf2 and mdebug. (ASM_FILE_START): Don't emit .file for dwarf2. From-SVN: r22277 --- gcc/ChangeLog | 15 ++++ gcc/config/alpha/alpha.c | 151 +++++++++++++++++++++++----------- gcc/config/alpha/alpha.h | 3 + gcc/config/alpha/alpha.md | 10 ++- gcc/config/alpha/crtbegin.asm | 89 +++++++++++++++++++- gcc/config/alpha/crtend.asm | 3 + gcc/config/alpha/elf.h | 16 ++-- 7 files changed, 226 insertions(+), 61 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dd5d66499dd..0f3b52e0c58 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,20 @@ Sat Sep 5 22:05:25 1998 Richard Henderson + * alpha.c (alpha_ra_ever_killed): Inspect the topmost sequence, + not whatever we're generating now. + + * alpha.c (set_frame_related_p, FRP): New. + (alpha_expand_prologue): Mark frame related insns. + (alpha_expand_epilogue): Likewise, but with a null FRP. + * alpha.h (INCOMING_RETURN_ADDR_RTX): New. + * alpha.md (exception_receiver): New. + * alpha/crtbegin.asm (.eh_frame): New beginning. + (__do_frame_setup, __do_frame_takedown): New. + * alpha/crtend.asm (.eh_frame): New ending. + * alpha/elf.h (DWARF2_DEBUGGING_INFO): Define. + (ASM_SPEC): Don't emit both dwarf2 and mdebug. + (ASM_FILE_START): Don't emit .file for dwarf2. + * rtl.h (enum reg_note): Add REG_FRAME_RELATED_EXPR. * rtl.c (reg_note_name): Likewise. * rtl.texi (REG_NOTES): Likewise. diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index 17cab88d8d5..e19ddab0fd8 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -2468,6 +2468,8 @@ alpha_return_addr (count, frame) static int alpha_ra_ever_killed () { + rtx top; + #ifdef ASM_OUTPUT_MI_THUNK if (current_function_is_thunk) return 0; @@ -2475,8 +2477,11 @@ alpha_ra_ever_killed () if (!alpha_return_addr_rtx) return regs_ever_live[REG_RA]; - return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), - get_insns(), NULL_RTX); + push_topmost_sequence (); + top = get_insns (); + pop_topmost_sequence (); + + return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX); } @@ -3192,6 +3197,32 @@ alpha_write_verstamp (file) #endif } +/* Helper function to set RTX_FRAME_RELATED_P on instructions, including + sequences. */ + +static rtx +set_frame_related_p () +{ + rtx seq = gen_sequence (); + end_sequence (); + + if (GET_CODE (seq) == SEQUENCE) + { + int i = XVECLEN (seq, 0); + while (--i >= 0) + RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1; + return emit_insn (seq); + } + else + { + seq = emit_insn (seq); + RTX_FRAME_RELATED_P (seq) = 1; + return seq; + } +} + +#define FRP(exp) (start_sequence (), exp, set_frame_related_p ()) + /* Write function prologue. */ /* On vms we have two kinds of functions: @@ -3271,8 +3302,8 @@ alpha_expand_prologue () if (frame_size != 0) { - emit_move_insn (stack_pointer_rtx, - plus_constant (stack_pointer_rtx, -frame_size)); + FRP (emit_move_insn (stack_pointer_rtx, + plus_constant (stack_pointer_rtx, -frame_size))); } } else @@ -3302,7 +3333,18 @@ alpha_expand_prologue () emit_move_insn (last, const0_rtx); } - emit_move_insn (stack_pointer_rtx, plus_constant (ptr, -leftover)); + ptr = emit_move_insn (stack_pointer_rtx, plus_constant (ptr, -leftover)); + + /* This alternative is special, because the DWARF code cannot possibly + intuit through the loop above. So we invent this note it looks at + instead. */ + RTX_FRAME_RELATED_P (ptr) = 1; + REG_NOTES (ptr) + = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, + gen_rtx_SET (VOIDmode, stack_pointer_rtx, + gen_rtx_PLUS (Pmode, stack_pointer_rtx, + GEN_INT (-frame_size))), + REG_NOTES (ptr)); } /* Cope with very large offsets to the register save area. */ @@ -3318,21 +3360,22 @@ alpha_expand_prologue () bias = reg_offset, reg_offset = 0; sa_reg = gen_rtx_REG (DImode, 24); - emit_move_insn (sa_reg, plus_constant (stack_pointer_rtx, bias)); + FRP (emit_move_insn (sa_reg, plus_constant (stack_pointer_rtx, bias))); } /* Save regs in stack order. Beginning with VMS PV. */ if (TARGET_OPEN_VMS && vms_is_stack_procedure) { - emit_move_insn (gen_rtx_MEM (DImode, stack_pointer_rtx), - gen_rtx_REG (DImode, REG_PV)); + FRP (emit_move_insn (gen_rtx_MEM (DImode, stack_pointer_rtx), + gen_rtx_REG (DImode, REG_PV))); } /* Save register RA next. */ if (imask & (1L << REG_RA)) { - emit_move_insn (gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset)), - gen_rtx_REG (DImode, REG_RA)); + FRP (emit_move_insn (gen_rtx_MEM (DImode, + plus_constant (sa_reg, reg_offset)), + gen_rtx_REG (DImode, REG_RA))); imask &= ~(1L << REG_RA); reg_offset += 8; } @@ -3341,18 +3384,18 @@ alpha_expand_prologue () for (i = 0; i < 32; i++) if (imask & (1L << i)) { - emit_move_insn (gen_rtx_MEM (DImode, - plus_constant (sa_reg, reg_offset)), - gen_rtx_REG (DImode, i)); + FRP (emit_move_insn (gen_rtx_MEM (DImode, + plus_constant (sa_reg, reg_offset)), + gen_rtx_REG (DImode, i))); reg_offset += 8; } for (i = 0; i < 32; i++) if (fmask & (1L << i)) { - emit_move_insn (gen_rtx_MEM (DFmode, - plus_constant (sa_reg, reg_offset)), - gen_rtx_REG (DFmode, i+32)); + FRP (emit_move_insn (gen_rtx_MEM (DFmode, + plus_constant (sa_reg, reg_offset)), + gen_rtx_REG (DFmode, i+32))); reg_offset += 8; } @@ -3361,25 +3404,25 @@ alpha_expand_prologue () if (!vms_is_stack_procedure) { /* Register frame procedures fave the fp. */ - emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno), - hard_frame_pointer_rtx); + FRP (emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno), + hard_frame_pointer_rtx)); } if (vms_base_regno != REG_PV) - emit_move_insn (gen_rtx_REG (DImode, vms_base_regno), - gen_rtx_REG (DImode, REG_PV)); + FRP (emit_move_insn (gen_rtx_REG (DImode, vms_base_regno), + gen_rtx_REG (DImode, REG_PV))); if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM) { - emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx); + FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx)); } /* If we have to allocate space for outgoing args, do it now. */ if (current_function_outgoing_args_size != 0) { - emit_move_insn (stack_pointer_rtx, - plus_constant (hard_frame_pointer_rtx, - - ALPHA_ROUND (current_function_outgoing_args_size))); + FRP (emit_move_insn (stack_pointer_rtx, + plus_constant (hard_frame_pointer_rtx, + - ALPHA_ROUND (current_function_outgoing_args_size)))); } } else @@ -3388,13 +3431,13 @@ alpha_expand_prologue () if (frame_pointer_needed) { if (TARGET_CAN_FAULT_IN_PROLOGUE) - emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx); + FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx)); else { /* This must always be the last instruction in the prologue, thus we emit a special move + clobber. */ - emit_insn (gen_init_fp (hard_frame_pointer_rtx, - stack_pointer_rtx, sa_reg)); + FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx, + stack_pointer_rtx, sa_reg))); } } } @@ -3611,6 +3654,12 @@ output_end_prologue (file) /* Write function epilogue. */ +/* ??? At some point we will want to support full unwind, and so will + need to mark the epilogue as well. At the moment, we just confuse + dwarf2out. */ +#undef FRP +#define FRP(exp) exp + void alpha_expand_epilogue () { @@ -3659,7 +3708,7 @@ alpha_expand_epilogue () && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM) || (!TARGET_OPEN_VMS && frame_pointer_needed)) { - emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx); + FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx)); } /* Cope with very large offsets to the register save area. */ @@ -3677,13 +3726,14 @@ alpha_expand_epilogue () sa_reg = gen_rtx_REG (DImode, 22); sa_reg_exp = plus_constant (stack_pointer_rtx, bias); - emit_move_insn (sa_reg, sa_reg_exp); + FRP (emit_move_insn (sa_reg, sa_reg_exp)); } /* Restore registers in order, excepting a true frame pointer. */ - emit_move_insn (gen_rtx_REG (DImode, REG_RA), - gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset))); + FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), + gen_rtx_MEM (DImode, plus_constant(sa_reg, + reg_offset)))); reg_offset += 8; imask &= ~(1L << REG_RA); @@ -3694,10 +3744,10 @@ alpha_expand_epilogue () fp_offset = reg_offset; else { - emit_move_insn (gen_rtx_REG (DImode, i), - gen_rtx_MEM (DImode, - plus_constant(sa_reg, - reg_offset))); + FRP (emit_move_insn (gen_rtx_REG (DImode, i), + gen_rtx_MEM (DImode, + plus_constant(sa_reg, + reg_offset)))); } reg_offset += 8; } @@ -3705,9 +3755,10 @@ alpha_expand_epilogue () for (i = 0; i < 32; ++i) if (fmask & (1L << i)) { - emit_move_insn (gen_rtx_REG (DFmode, i+32), - gen_rtx_MEM (DFmode, - plus_constant(sa_reg, reg_offset))); + FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), + gen_rtx_MEM (DFmode, + plus_constant(sa_reg, + reg_offset)))); reg_offset += 8; } } @@ -3732,20 +3783,20 @@ alpha_expand_epilogue () else { sp_adj1 = gen_rtx_REG (DImode, 23); - emit_move_insn (sp_adj1, sp_adj2); + FRP (emit_move_insn (sp_adj1, sp_adj2)); } sp_adj2 = GEN_INT (low); } else { sp_adj2 = gen_rtx_REG (DImode, 23); - sp_adj1 = alpha_emit_set_const (sp_adj2, DImode, frame_size, 3); + FRP (sp_adj1 = alpha_emit_set_const (sp_adj2, DImode, frame_size, 3)); if (!sp_adj1) { /* We can't drop new things to memory this late, afaik, so build it up by pieces. */ #if HOST_BITS_PER_WIDE_INT == 64 - sp_adj1 = alpha_emit_set_long_const (sp_adj2, frame_size); + FRP (sp_adj1 = alpha_emit_set_long_const (sp_adj2, frame_size)); if (!sp_adj1) abort (); #else @@ -3761,29 +3812,29 @@ alpha_expand_epilogue () if (fp_is_frame_pointer) { emit_insn (gen_blockage ()); - emit_move_insn (hard_frame_pointer_rtx, - gen_rtx_MEM (DImode, - plus_constant(sa_reg, fp_offset))); + FRP (emit_move_insn (hard_frame_pointer_rtx, + gen_rtx_MEM (DImode, + plus_constant(sa_reg, fp_offset)))); } else if (TARGET_OPEN_VMS) { emit_insn (gen_blockage ()); - emit_move_insn (hard_frame_pointer_rtx, - gen_rtx_REG (DImode, vms_save_fp_regno)); + FRP (emit_move_insn (hard_frame_pointer_rtx, + gen_rtx_REG (DImode, vms_save_fp_regno))); } /* Restore the stack pointer. */ emit_insn (gen_blockage ()); - emit_move_insn (stack_pointer_rtx, - gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)); + FRP (emit_move_insn (stack_pointer_rtx, + gen_rtx_PLUS (DImode, sp_adj1, sp_adj2))); } else { if (TARGET_OPEN_VMS && !vms_is_stack_procedure) { emit_insn (gen_blockage ()); - emit_move_insn (hard_frame_pointer_rtx, - gen_rtx_REG (DImode, vms_save_fp_regno)); + FRP (emit_move_insn (hard_frame_pointer_rtx, + gen_rtx_REG (DImode, vms_save_fp_regno))); } } diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index b77f3b9e855..9aacab5d833 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -1301,6 +1301,9 @@ extern void alpha_initialize_trampoline (); #define RETURN_ADDR_RTX alpha_return_addr extern struct rtx_def *alpha_return_addr (); +/* Before the prologue, RA lives in $26. */ +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, 26) + /* Initialize data used by insn expanders. This is called from insn_emit, once for every function before code is generated. */ diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 89184bf25b3..232fb01def1 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -39,6 +39,7 @@ ;; 4 trapb ;; 5 prologue_stack_probe_loop ;; 6 realign +;; 7 exception_receiver ;; Processor type -- this attribute must exactly match the processor_type ;; enumeration in alpha.h. @@ -5177,7 +5178,14 @@ (define_insn "" [(unspec_volatile [(match_operand 0 "" "")] 2)] "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT" - "br $27,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($27)" + "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)" + [(set_attr "length" "12") + (set_attr "type" "multi")]) + +(define_insn "exception_receiver" + [(unspec_volatile [(const_int 0)] 7)] + "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT" + "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)" [(set_attr "length" "12") (set_attr "type" "multi")]) diff --git a/gcc/config/alpha/crtbegin.asm b/gcc/config/alpha/crtbegin.asm index c28440d8a24..f954f1ab0d3 100644 --- a/gcc/config/alpha/crtbegin.asm +++ b/gcc/config/alpha/crtbegin.asm @@ -50,6 +50,8 @@ __CTOR_LIST__: __DTOR_LIST__: .quad -1 +.section .eh_frame,"aw" +__EH_FRAME_BEGIN__: # # Fragment of the ELF _fini routine that invokes our dtor cleanup. @@ -67,10 +69,25 @@ __DTOR_LIST__: 1: ldgp $29,0($29) jsr $26,__do_global_dtors_aux + # Ideally this call would go in crtend.o, except that we can't + # get hold of __EH_FRAME_BEGIN__ there. + + jsr $26,__do_frame_takedown + # Must match the alignment we got from crti.o else we get # zero-filled holes in our _fini function and then SIGILL. .align 3 + # + # Fragment of the ELF _init routine that sets up the frame info. + # + +.section .init,"ax" + br $29,1f +1: ldgp $29,0($29) + jsr $26,__do_frame_setup + .align 3 + # # Invoke our destructors in order. # @@ -78,7 +95,7 @@ __DTOR_LIST__: .data # Support recursive calls to exit. -9: .quad __DTOR_LIST__ +$ptr: .quad __DTOR_LIST__ .text @@ -86,15 +103,14 @@ __DTOR_LIST__: .ent __do_global_dtors_aux __do_global_dtors_aux: - ldgp $29,0($27) lda $30,-16($30) .frame $30,16,$26,0 stq $9,8($30) stq $26,0($30) .mask 0x4000200,-16 - .prologue 1 + .prologue 0 - lda $9,9b + lda $9,$ptr br 1f 0: stq $1,0($9) jsr $26,($27) @@ -109,3 +125,68 @@ __do_global_dtors_aux: ret .end __do_global_dtors_aux + + # + # Install our frame info. + # + + # ??? How can we rationally keep this size correct? + +.section .bss + .type $object,@object + .align 3 +$object: + .zero 48 + .size $object, 48 + +.text + + .align 3 + .ent __do_frame_setup + +__do_frame_setup: + ldgp $29,0($27) + lda $30,-16($30) + .frame $30,16,$26,0 + stq $26,0($30) + .mask 0x4000000,-16 + .prologue 1 + + lda $1,__register_frame_info + beq $1,0f + lda $16,__EH_FRAME_BEGIN__ + lda $17,$object + jsr $26,__register_frame_info + ldq $26,0($30) +0: lda $30,16($30) + ret + + .end __do_frame_setup + + # + # Remove our frame info. + # + + .align 3 + .ent __do_frame_takedown + +__do_frame_takedown: + ldgp $29,0($27) + lda $30,-16($30) + .frame $30,16,$26,0 + stq $26,0($30) + .mask 0x4000000,-16 + .prologue 1 + + lda $1,__deregister_frame_info + beq $1,0f + lda $16,__EH_FRAME_BEGIN__ + jsr $26,__deregister_frame_info + ldq $26,0($30) +0: lda $30,16($30) + ret + + .end __do_frame_takedown + +.weak __register_frame_info +.weak __deregister_frame_info diff --git a/gcc/config/alpha/crtend.asm b/gcc/config/alpha/crtend.asm index 36f11b9723a..4a0cc5e9f61 100644 --- a/gcc/config/alpha/crtend.asm +++ b/gcc/config/alpha/crtend.asm @@ -50,6 +50,9 @@ __CTOR_END__: __DTOR_END__: .quad 0 +.section .eh_frame,"aw" +__FRAME_END__: + .quad 0 # # Fragment of the ELF _init routine that invokes our ctor startup diff --git a/gcc/config/alpha/elf.h b/gcc/config/alpha/elf.h index 4f4703c14ef..89eda748c06 100644 --- a/gcc/config/alpha/elf.h +++ b/gcc/config/alpha/elf.h @@ -24,6 +24,7 @@ Boston, MA 02111-1307, USA. */ #define OBJECT_FORMAT_ELF #define DBX_DEBUGGING_INFO +#define DWARF2_DEBUGGING_INFO #undef PREFERRED_DEBUGGING_TYPE #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG @@ -34,7 +35,7 @@ Boston, MA 02111-1307, USA. */ #define CC1_SPEC "%{G*}" #undef ASM_SPEC -#define ASM_SPEC "%{G*} %{relax:-relax}" +#define ASM_SPEC "%{G*} %{relax:-relax} %{gdwarf*:-no-mdebug}" #undef LINK_SPEC #define LINK_SPEC "-m elf64alpha %{G*} %{relax:-relax} \ @@ -49,18 +50,21 @@ Boston, MA 02111-1307, USA. */ /* Output at beginning of assembler file. */ #undef ASM_FILE_START #define ASM_FILE_START(FILE) \ -{ \ - alpha_write_verstamp (FILE); \ - output_file_directive (FILE, main_input_filename); \ +do { \ + if (write_symbols != DWARF2_DEBUG) \ + { \ + alpha_write_verstamp (FILE); \ + output_file_directive (FILE, main_input_filename); \ + } \ fprintf (FILE, "\t.set noat\n"); \ - fprintf (FILE, "\t.set noreorder\n"); \ + fprintf (FILE, "\t.set noreorder\n"); \ if (TARGET_BWX | TARGET_MAX | TARGET_CIX) \ { \ fprintf (FILE, "\t.arch %s\n", \ (alpha_cpu == PROCESSOR_EV6 ? "ev6" \ : TARGET_MAX ? "pca56" : "ev56")); \ } \ -} +} while (0) extern void output_file_directive (); -- 2.30.2