pa.c (pa_init_machine_status): Initialize pic_offset_table_save_rtx to NULL_RTX.
authorJohn David Anglin <dave@hiauly1.hia.nrc.ca>
Tue, 30 Jan 2001 17:25:29 +0000 (17:25 +0000)
committerJeff Law <law@gcc.gnu.org>
Tue, 30 Jan 2001 17:25:29 +0000 (10:25 -0700)
        * pa.c (pa_init_machine_status): Initialize pic_offset_table_save_rtx
        to NULL_RTX.
        (hppa_expand_prologue): Delete code to save pic offset table register
        in the function prologue.
        * pa.h (PIC_OFFSET_TABLE_SAVE_RTX): Correct type in comment.
        * pa.md (call, call_value, sibcall, sibcall_value): Save the pic offset
        table register at the beginning of the function after the prologue.

From-SVN: r39351

gcc/ChangeLog
gcc/config/pa/pa.c
gcc/config/pa/pa.h
gcc/config/pa/pa.md

index 158b5c17b1f79b99df73d729e3c62a52ef049813..8f5a437bbcc173b3c381c5a5b84dcdc220bae558 100644 (file)
@@ -1,3 +1,13 @@
+2001-01-30  John David Anglin  <dave@hiauly1.hia.nrc.ca>
+
+       * pa.c (pa_init_machine_status): Initialize pic_offset_table_save_rtx
+       to NULL_RTX.
+       (hppa_expand_prologue): Delete code to save pic offset table register
+       in the function prologue.
+       * pa.h (PIC_OFFSET_TABLE_SAVE_RTX): Correct type in comment.
+       * pa.md (call, call_value, sibcall, sibcall_value): Save the pic offset
+       table register at the beginning of the function after the prologue.
+
 2001-01-29  lars brinkhoff  <lars@nocrew.org>
 
         * tm.texi (PUSH_ROUNDING): Remove duplicate lines.
index 06e96654d89109db297d764972213bf5f605e428..aad9345ed3591335f17f49f7b7ab82f30387f53a 100644 (file)
@@ -206,7 +206,7 @@ pa_init_machine_status (p)
 {
   p->machine = (machine_function *) xmalloc (sizeof (machine_function));
 
-  p->machine->pic_offset_table_save_rtx = gen_reg_rtx (Pmode);
+  p->machine->pic_offset_table_save_rtx = NULL_RTX;
 }
 
 static void
@@ -3186,25 +3186,6 @@ hppa_expand_prologue()
            }
        }
     }
-
-  /* When generating PIC code it is necessary to save/restore the
-     PIC register around each function call.  We used to do this
-     in the call patterns themselves, but that implementation
-     made incorrect assumptions about using global variables to hold
-     per-function rtl code generated in the backend.
-
-     So instead, we copy the PIC register into a callee saved register
-     in the prologue.  Then after each call we reload the PIC register
-     from the callee saved register.
-
-     Avoid doing this if the register isn't used (eg. leaf functions)
-     as it's an error to delete an instruction from the prologue.  */
-
-  if (flag_pic
-      && (GET_CODE (PIC_OFFSET_TABLE_SAVE_RTX) != REG
-         || HARD_REGISTER_P (PIC_OFFSET_TABLE_SAVE_RTX)))
-    emit_move_insn (PIC_OFFSET_TABLE_SAVE_RTX,
-                   gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM));
 }
 
 
index bbd3f7ae9d5b610156ab35cad06bcafe5a705bc2..898008e7305c87c5621df2d102dd1554dcc8932c 100644 (file)
@@ -500,7 +500,7 @@ extern int target_flags;
 #define PIC_OFFSET_TABLE_REGNUM (TARGET_64BIT ? 27 : 19)
 #define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED 1
 
-/* Register into which we save the PIC_OFFEST_TABLE_REGNUM so that it
+/* Register into which we save the PIC_OFFSET_TABLE_REGNUM so that it
    can be restored across function calls.  */
 #define PIC_OFFSET_TABLE_SAVE_RTX (cfun->machine->pic_offset_table_save_rtx)
 
index 76857f4eff4242157563a5fa78e40bca88fc6292..41dc77c0703c1202bafde05d03d81dc658360d19 100644 (file)
                    gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
                                  GEN_INT (64)));
 
+  if (flag_pic && PIC_OFFSET_TABLE_SAVE_RTX == NULL_RTX)
+    {
+      rtx insn;
+
+      PIC_OFFSET_TABLE_SAVE_RTX = gen_reg_rtx (Pmode);
+      insn = gen_rtx_SET (VOIDmode, PIC_OFFSET_TABLE_SAVE_RTX,
+                         gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM));
+
+      /* Emit the insn at the beginning of the function after the prologue.  */
+      push_topmost_sequence ();
+      emit_insn_after (insn, get_insns ());
+      pop_topmost_sequence ();
+    }
+
   /* Use two different patterns for calls to explicitly named functions
      and calls through function pointers.  This is necessary as these two
      types of calls use different calling conventions, and CSE might try
                    gen_rtx_PLUS (word_mode, virtual_outgoing_args_rtx,
                                  GEN_INT (64)));
 
+  if (flag_pic && PIC_OFFSET_TABLE_SAVE_RTX == NULL_RTX)
+    {
+      rtx insn;
+
+      PIC_OFFSET_TABLE_SAVE_RTX = gen_reg_rtx (Pmode);
+      insn = gen_rtx_SET (VOIDmode, PIC_OFFSET_TABLE_SAVE_RTX,
+                         gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM));
+
+      /* Emit the insn at the beginning of the function after the prologue.  */
+      push_topmost_sequence ();
+      emit_insn_after (insn, get_insns ());
+      pop_topmost_sequence ();
+    }
+
   /* Use two different patterns for calls to explicitly named functions
      and calls through function pointers.  This is necessary as these two
      types of calls use different calling conventions, and CSE might try
 
   op = XEXP (operands[0], 0);
 
+  if (flag_pic && PIC_OFFSET_TABLE_SAVE_RTX == NULL_RTX)
+    {
+      rtx insn;
+
+      PIC_OFFSET_TABLE_SAVE_RTX = gen_reg_rtx (Pmode);
+      insn = gen_rtx_SET (VOIDmode, PIC_OFFSET_TABLE_SAVE_RTX,
+                         gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM));
+
+      /* Emit the insn at the beginning of the function after the prologue.  */
+      push_topmost_sequence ();
+      emit_insn_after (insn, get_insns ());
+      pop_topmost_sequence ();
+    }
+
   /* We do not allow indirect sibling calls.  */
   call_insn = emit_call_insn (gen_sibcall_internal_symref (op, operands[1]));
 
 
   op = XEXP (operands[1], 0);
 
+  if (flag_pic && PIC_OFFSET_TABLE_SAVE_RTX == NULL_RTX)
+    {
+      rtx insn;
+
+      PIC_OFFSET_TABLE_SAVE_RTX = gen_reg_rtx (Pmode);
+      insn = gen_rtx_SET (VOIDmode, PIC_OFFSET_TABLE_SAVE_RTX,
+                         gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM));
+
+      /* Emit the insn at the beginning of the function after the prologue.  */
+      push_topmost_sequence ();
+      emit_insn_after (insn, get_insns ());
+      pop_topmost_sequence ();
+    }
+
   /* We do not allow indirect sibling calls.  */
   call_insn = emit_call_insn (gen_sibcall_value_internal_symref (operands[0],
                                                                 op,