This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

tru64 ldgp linker bug workaround


Instead of using ldgp in the exception_receiver, save it away
in a pseudo at the beginning of the function and restore it in
the receiver.


r~


        * 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.

Index: alpha-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha-protos.h,v
retrieving revision 1.14
diff -c -p -d -r1.14 alpha-protos.h
*** alpha-protos.h	2000/11/22 00:59:11	1.14
--- alpha-protos.h	2001/06/11 16:04:39
*************** extern int alpha_expand_block_move PARAM
*** 100,105 ****
--- 100,106 ----
  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: alpha.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v
retrieving revision 1.155.4.4
diff -c -p -d -r1.155.4.4 alpha.c
*** alpha.c	2001/06/10 23:09:49	1.155.4.4
--- alpha.c	2001/06/11 16:04:39
*************** alpha_mark_machine_status (p)
*** 3678,3683 ****
--- 3678,3684 ----
    if (machine)
      {
        ggc_mark_rtx (machine->ra_rtx);
+       ggc_mark_rtx (machine->gp_save_rtx);
      }
  }
  
*************** alpha_return_addr (count, frame)
*** 3711,3716 ****
--- 3712,3740 ----
        init = gen_rtx_SET (VOIDmode, reg, gen_rtx_REG (Pmode, REG_RA));
  
        /* Emit the insn to the prologue with the other argument copies.  */
+       push_topmost_sequence ();
+       emit_insn_after (init, get_insns ());
+       pop_topmost_sequence ();
+     }
+ 
+   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 ();
Index: alpha.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.h,v
retrieving revision 1.113.4.3
diff -c -p -d -r1.113.4.3 alpha.h
*** alpha.h	2001/06/10 23:09:49	1.113.4.3
--- alpha.h	2001/06/11 16:04:39
*************** extern enum alpha_fp_trap_mode alpha_fpt
*** 186,191 ****
--- 186,194 ----
  #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,
*************** struct machine_function
*** 1199,1204 ****
--- 1202,1210 ----
  {
    /* 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: alpha.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.md,v
retrieving revision 1.136.4.4
diff -c -p -d -r1.136.4.4 alpha.md
*** alpha.md	2001/05/25 20:05:32	1.136.4.4
--- alpha.md	2001/06/11 16:04:39
***************
*** 5959,5970 ****
    [(set_attr "length" "12")
     (set_attr "type" "multi")])
  
! (define_insn "exception_receiver"
!   [(unspec_volatile [(const_int 0)] 7)]
    "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT"
    "ldgp $29,0($26)"
    [(set_attr "length" "8")
     (set_attr "type" "multi")])
  
  (define_expand "nonlocal_goto_receiver"
    [(unspec_volatile [(const_int 0)] 1)
--- 5959,5993 ----
    [(set_attr "length" "12")
     (set_attr "type" "multi")])
  
! (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)
Index: osf5.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/osf5.h,v
retrieving revision 1.1.12.2
diff -c -p -d -r1.1.12.2 osf5.h
*** osf5.h	2001/06/11 02:30:40	1.1.12.2
--- osf5.h	2001/06/11 16:04:39
***************
*** 46,48 ****
--- 46,54 ----
  
  #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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]