Commit 6abc6f40 by Richard Henderson Committed by Richard Henderson

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
parent 07ebc930
Sat Sep 5 22:05:25 1998 Richard Henderson <rth@cygnus.com>
* 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.
......
......@@ -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)));
}
}
......
......@@ -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. */
......
......@@ -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")])
......
......@@ -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,18 +69,33 @@ __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.
#
.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
......@@ -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
......
......@@ -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 ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment