summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1998-09-05 22:22:07 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>1998-09-05 22:22:07 +0000
commit5a96522597fa98fab47145a4d5ece43eb9aac238 (patch)
tree08f1b3bd01cc97bc3538c0c23730f536d7c2d692 /gcc
parent86b18255f2a5ce9abdce76591122f950a3acf4e9 (diff)
downloadgcc-5a96522597fa98fab47145a4d5ece43eb9aac238.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@22277 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/alpha/alpha.c151
-rw-r--r--gcc/config/alpha/alpha.h3
-rw-r--r--gcc/config/alpha/alpha.md10
-rw-r--r--gcc/config/alpha/crtbegin.asm89
-rw-r--r--gcc/config/alpha/crtend.asm3
-rw-r--r--gcc/config/alpha/elf.h16
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 <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.
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,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
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 ();