aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@gcc.gnu.org>2001-06-11 09:27:26 -0700
committerRichard Henderson <rth@gcc.gnu.org>2001-06-11 09:27:26 -0700
commitccb83cbced4e6f83ae973d214075de743da4bed3 (patch)
tree90a3ac1b11fbae1eab80955a548f873066e130db
parentf90e86cd003cdc54584fdeb5cef84af0e12634cb (diff)
downloadgcc-ccb83cbced4e6f83ae973d214075de743da4bed3.zip
gcc-ccb83cbced4e6f83ae973d214075de743da4bed3.tar.gz
gcc-ccb83cbced4e6f83ae973d214075de743da4bed3.tar.bz2
osf5.h (TARGET_LD_BUGGY_LDGP): New.
* config/alpha/osf5.h (TARGET_LD_BUGGY_LDGP): New. * config/alpha/alpha.h (TARGET_LD_BUGGY_LDGP): Default. (struct machine_function): Add gp_save_rtx. * config/alpha/alpha.c (alpha_mark_machine_status): Mark it. (alpha_gp_save_rtx): New. * config/alpha/alpha-protos.h: Declare it. * config/alpha/alpha.md (exception_receiver): Make an expander. Use alpha_gp_save_rtx if TARGET_LD_BUGGY_LDGP. From-SVN: r43196
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/alpha/alpha-protos.h1
-rw-r--r--gcc/config/alpha/alpha.c24
-rw-r--r--gcc/config/alpha/alpha.h6
-rw-r--r--gcc/config/alpha/alpha.md27
-rw-r--r--gcc/config/alpha/osf5.h6
6 files changed, 74 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cac511c..6d8b7ab 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,16 @@
2001-06-11 Richard Henderson <rth@redhat.com>
+ * config/alpha/osf5.h (TARGET_LD_BUGGY_LDGP): New.
+ * config/alpha/alpha.h (TARGET_LD_BUGGY_LDGP): Default.
+ (struct machine_function): Add gp_save_rtx.
+ * config/alpha/alpha.c (alpha_mark_machine_status): Mark it.
+ (alpha_gp_save_rtx): New.
+ * config/alpha/alpha-protos.h: Declare it.
+ * config/alpha/alpha.md (exception_receiver): Make an expander.
+ Use alpha_gp_save_rtx if TARGET_LD_BUGGY_LDGP.
+
+2001-06-11 Richard Henderson <rth@redhat.com>
+
* config/alpha/osf.h (LINK_SPEC): Hide _GLOBAL_* symbols.
2001-06-11 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
@@ -42,7 +53,7 @@ Mon Jun 11 15:47:45 CEST 2001 Jan Hubicka <jh@suse.cz>
2001-06-11 Aldy Hernandez <aldyh@redhat.com>
- * loop.c (scan_loop): Do not combine asm statements.
+ * loop.c (scan_loop): Do not combine asm statements.
2001-06-11 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
diff --git a/gcc/config/alpha/alpha-protos.h b/gcc/config/alpha/alpha-protos.h
index c12b92d..06ecfa3 100644
--- a/gcc/config/alpha/alpha-protos.h
+++ b/gcc/config/alpha/alpha-protos.h
@@ -100,6 +100,7 @@ extern int alpha_expand_block_move PARAMS ((rtx []));
extern int alpha_expand_block_clear PARAMS ((rtx []));
extern int alpha_adjust_cost PARAMS ((rtx, rtx, rtx, int));
extern rtx alpha_return_addr PARAMS ((int, rtx));
+extern rtx alpha_gp_save_rtx PARAMS ((void));
extern void print_operand PARAMS ((FILE *, rtx, int));
extern void print_operand_address PARAMS ((FILE *, rtx));
extern void alpha_initialize_trampoline PARAMS ((rtx, rtx, rtx, int, int, int));
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index f9dc046..3e3de70 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -3678,6 +3678,7 @@ alpha_mark_machine_status (p)
if (machine)
{
ggc_mark_rtx (machine->ra_rtx);
+ ggc_mark_rtx (machine->gp_save_rtx);
}
}
@@ -3719,6 +3720,29 @@ alpha_return_addr (count, frame)
return reg;
}
+/* Return or create a pseudo containing the gp value for the current
+ function. Needed only if TARGET_LD_BUGGY_LDGP. */
+
+rtx
+alpha_gp_save_rtx ()
+{
+ rtx init, reg;
+
+ reg = cfun->machine->gp_save_rtx;
+ if (reg == NULL)
+ {
+ reg = gen_reg_rtx (DImode);
+ cfun->machine->gp_save_rtx = reg;
+ init = gen_rtx_SET (VOIDmode, reg, gen_rtx_REG (DImode, 29));
+
+ push_topmost_sequence ();
+ emit_insn_after (init, get_insns ());
+ pop_topmost_sequence ();
+ }
+
+ return reg;
+}
+
static int
alpha_ra_ever_killed ()
{
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 148a6cf..739a177 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -192,6 +192,9 @@ extern enum alpha_fp_trap_mode alpha_fptm;
#ifndef TARGET_PROFILING_NEEDS_GP
#define TARGET_PROFILING_NEEDS_GP 0
#endif
+#ifndef TARGET_LD_BUGGY_LDGP
+#define TARGET_LD_BUGGY_LDGP 0
+#endif
/* Macro to define tables used to set the flags.
This is a list in braces of pairs in braces,
@@ -1188,6 +1191,9 @@ struct machine_function
{
/* If non-null, this rtx holds the return address for the function. */
struct rtx_def *ra_rtx;
+
+ /* If non-null, this rtx holds a saved copy of the GP for the function. */
+ struct rtx_def *gp_save_rtx;
};
/* Make (or fake) .linkage entry for function call.
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index 0efba73..cafee44 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -5959,13 +5959,36 @@
[(set_attr "length" "12")
(set_attr "type" "multi")])
-(define_insn "exception_receiver"
- [(unspec_volatile [(const_int 0)] 7)]
+(define_expand "exception_receiver"
+ [(unspec_volatile [(match_dup 0)] 7)]
"! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
+ "
+{
+ if (TARGET_LD_BUGGY_LDGP)
+ operands[0] = alpha_gp_save_rtx ();
+ else
+ operands[0] = const0_rtx;
+}")
+
+(define_insn "*exception_receiver_1"
+ [(unspec_volatile [(const_int 0)] 7)]
+ "! TARGET_LD_BUGGY_LDGP"
"ldgp $29,0($26)"
[(set_attr "length" "8")
(set_attr "type" "multi")])
+;; ??? We don't represent the usage of $29 properly in address loads
+;; and function calls. This leads to the following move being deleted
+;; as dead code unless it is represented as a volatile unspec.
+
+(define_insn "*exception_receiver_2"
+ [(unspec_volatile [(match_operand:DI 0 "nonimmediate_operand" "r,m")] 7)]
+ "TARGET_LD_BUGGY_LDGP"
+ "@
+ mov %0,$29
+ ldq $29,%0"
+ [(set_attr "type" "ilog,ild")])
+
(define_expand "nonlocal_goto_receiver"
[(unspec_volatile [(const_int 0)] 1)
(set (reg:DI 27) (mem:DI (reg:DI 29)))
diff --git a/gcc/config/alpha/osf5.h b/gcc/config/alpha/osf5.h
index d9b70f8..9599d76 100644
--- a/gcc/config/alpha/osf5.h
+++ b/gcc/config/alpha/osf5.h
@@ -46,3 +46,9 @@
#undef ASM_OLDAS_SPEC
#define ASM_OLDAS_SPEC "-oldas -c"
+
+/* The linker appears to perform invalid code optimizations that result
+ in the ldgp emitted for the exception_receiver pattern being incorrctly
+ linked. */
+#undef TARGET_LD_BUGGY_LDGP
+#define TARGET_LD_BUGGY_LDGP 1