osf5.h (TARGET_LD_BUGGY_LDGP): New.
authorRichard Henderson <rth@gcc.gnu.org>
Mon, 11 Jun 2001 16:27:26 +0000 (09:27 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 11 Jun 2001 16:27:26 +0000 (09:27 -0700)
        * 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

gcc/ChangeLog
gcc/config/alpha/alpha-protos.h
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/alpha/alpha.md
gcc/config/alpha/osf5.h

index cac511c..6d8b7ab 100644 (file)
@@ -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>
 
index c12b92d..06ecfa3 100644 (file)
@@ -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));
index f9dc046..3e3de70 100644 (file)
@@ -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 ()
 {
index 148a6cf..739a177 100644 (file)
@@ -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.
index 0efba73..cafee44 100644 (file)
   [(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)))
index d9b70f8..9599d76 100644 (file)
@@ -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