* config/i386/i386.c (get_pic_label_name): New.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 23 May 2002 07:43:13 +0000 (07:43 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 23 May 2002 07:43:13 +0000 (07:43 +0000)
        (load_pic_register): Remove.
        (output_set_got): New.
        (ix86_expand_prologue): Use gen_set_got; mark insn REG_MAYBE_DEAD.
        * config/i386/i386.md (UNSPEC_SET_GOT): New.
        (UNSPECV_PROLOGUE_SET_GOT, UNSPECV_PROLOGUE_GET_PC): Remove.
        (prologue_set_got, prologue_get_pc): Remove.
        (set_got, set_got_nopic, set_got_deep, set_got_nodeep): New.
        (builtin_setjmp_receiver): Use gen_set_got.
        * config/i386/i386-protos.h: Update.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@53773 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.md

index 67381fd..cb83350 100644 (file)
@@ -1,3 +1,16 @@
+2002-05-23  Richard Henderson  <rth@redhat.com>
+
+       * config/i386/i386.c (get_pic_label_name): New.
+       (load_pic_register): Remove.
+       (output_set_got): New.
+       (ix86_expand_prologue): Use gen_set_got; mark insn REG_MAYBE_DEAD.
+       * config/i386/i386.md (UNSPEC_SET_GOT): New.
+       (UNSPECV_PROLOGUE_SET_GOT, UNSPECV_PROLOGUE_GET_PC): Remove.
+       (prologue_set_got, prologue_get_pc): Remove.
+       (set_got, set_got_nopic, set_got_deep, set_got_nodeep): New.
+       (builtin_setjmp_receiver): Use gen_set_got.
+       * config/i386/i386-protos.h: Update.
+
 Thu May 23 09:22:23 CEST 2002  Jan Hubicka  <jh@suse.cz>
 
        * gcse.c (hash_expr): Do not use alias set for hashing.
index c02e2e3..21babe9 100644 (file)
@@ -28,7 +28,6 @@ extern int ix86_frame_pointer_required PARAMS ((void));
 extern void ix86_setup_frame_addresses PARAMS ((void));
 
 extern void ix86_asm_file_end PARAMS ((FILE *));
-extern void load_pic_register PARAMS ((void));
 extern HOST_WIDE_INT ix86_initial_elimination_offset PARAMS((int, int));
 extern void ix86_expand_prologue PARAMS ((void));
 extern void ix86_expand_epilogue PARAMS ((int));
@@ -96,6 +95,7 @@ extern void print_operand_address PARAMS ((FILE*, rtx));
 extern void split_di PARAMS ((rtx[], int, rtx[], rtx[]));
 extern void split_ti PARAMS ((rtx[], int, rtx[], rtx[]));
 
+extern const char *output_set_got PARAMS ((rtx));
 extern const char *output_387_binary_op PARAMS ((rtx, rtx*));
 extern const char *output_fix_trunc PARAMS ((rtx, rtx*));
 extern const char *output_fp_compare PARAMS ((rtx, rtx*, int, int));
index 6505131..96d0916 100644 (file)
@@ -647,6 +647,7 @@ static char internal_label_prefix[16];
 static int internal_label_prefix_len;
 \f
 static int local_symbolic_operand PARAMS ((rtx, enum machine_mode));
+static const char *get_pic_label_name PARAMS ((void));
 static void output_pic_addr_const PARAMS ((FILE *, rtx, int));
 static void put_condition_code PARAMS ((enum rtx_code, enum machine_mode,
                                       int, int, FILE *));
@@ -3795,6 +3796,14 @@ ix86_setup_frame_addresses ()
 \f
 static char pic_label_name[32];
 
+static const char *
+get_pic_label_name ()
+{
+  if (! pic_label_name[0])
+    ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", 0);
+  return pic_label_name;
+}
+
 /* This function generates code for -fpic that loads %ebx with
    the return address of the caller and then returns.  */
 
@@ -3847,33 +3856,45 @@ ix86_asm_file_end (file)
   output_asm_insn ("ret", xops);
 }
 
-void
-load_pic_register ()
-{
-  rtx gotsym, pclab;
+/* Emit code for the SET_GOT patterns.  */
 
-  if (TARGET_64BIT)
-    abort ();
+const char *
+output_set_got (dest)
+     rtx dest;
+{
+  rtx xops[3];
 
-  gotsym = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
+  xops[0] = dest;
+  xops[1] = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
 
-  if (TARGET_DEEP_BRANCH_PREDICTION)
+  if (! TARGET_DEEP_BRANCH_PREDICTION || !flag_pic)
     {
-      if (! pic_label_name[0])
-       ASM_GENERATE_INTERNAL_LABEL (pic_label_name, "LPR", 0);
-      pclab = gen_rtx_MEM (QImode, gen_rtx_SYMBOL_REF (Pmode, pic_label_name));
+      xops[2] = gen_rtx_LABEL_REF (Pmode, gen_label_rtx ());
+
+      if (!flag_pic)
+       output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops);
+      else
+       output_asm_insn ("call\t%a2", xops);
+
+      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
+                                CODE_LABEL_NUMBER (XEXP (xops[2], 0)));
+
+      if (flag_pic)
+       output_asm_insn ("pop{l}\t%0", xops);
     }
   else
     {
-      pclab = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
+      xops[2] = gen_rtx_SYMBOL_REF (Pmode, get_pic_label_name ());
+      xops[2] = gen_rtx_MEM (QImode, xops[2]);
+      output_asm_insn ("call\t%X2", xops);
     }
 
-  emit_insn (gen_prologue_get_pc (pic_offset_table_rtx, pclab));
-
-  if (! TARGET_DEEP_BRANCH_PREDICTION)
-    emit_insn (gen_popsi1 (pic_offset_table_rtx));
+  if (!flag_pic || TARGET_DEEP_BRANCH_PREDICTION)
+    output_asm_insn ("add{l}\t{%1, %0|%0, %1}", xops);
+  else
+    output_asm_insn ("add{l}\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}", xops);
 
-  emit_insn (gen_prologue_set_got (pic_offset_table_rtx, gotsym, pclab));
+  return "";
 }
 
 /* Generate an "push" pattern for input ARG.  */
@@ -4197,7 +4218,15 @@ ix86_expand_prologue ()
 #endif
 
   if (pic_reg_used)
-    load_pic_register ();
+    {
+      insn = emit_insn (gen_set_got (pic_offset_table_rtx));
+
+      /* ??? The current_function_uses_pic_offset_table flag is woefully
+        inaccurate, as it isn't updated as code gets deleted.  Allow the
+        thing to be removed.  A better solution would be to actually get
+        proper liveness for ebx, as then we won't save/restore it too.  */
+      REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_MAYBE_DEAD, const0_rtx, NULL);
+    }
 
   /* If we are profiling, make sure no instructions are scheduled before
      the call to mcount.  However, if -fpic, the above call will have
index cdd99fc..a385ead 100644 (file)
@@ -69,6 +69,7 @@
    (UNSPEC_SSE_PROLOGUE_SAVE   13)
    (UNSPEC_FLDCW               14)
    (UNSPEC_GOTPCREL            15)
+   (UNSPEC_SET_GOT             16)
 
    ; For SSE/MMX support:
    (UNSPEC_FIX                 30)
@@ -97,8 +98,6 @@
 
 (define_constants
   [(UNSPECV_BLOCKAGE           0)
-   (UNSPECV_PROLOGUE_SET_GOT   1)
-   (UNSPECV_PROLOGUE_GET_PC    2)
    (UNSPECV_EH_RETURN          13)
    (UNSPECV_EMMS               31)
    (UNSPECV_LDMXCSR            37)
   ""
   "ix86_expand_prologue (); DONE;")
 
-(define_insn "prologue_set_got"
+(define_expand "set_got"
+  [(parallel [(set (match_operand:SI 0 "register_operand" "")
+                  (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
+             (clobber (reg:CC 17))])]
+  "!TARGET_64BIT"
+  "")
+
+(define_insn "*set_got_nopic"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (unspec_volatile:SI
-        [(plus:SI (match_dup 0)
-                  (plus:SI (match_operand:SI 1 "symbolic_operand" "")
-                           (minus:SI (pc) (match_operand 2 "" ""))))]
-        UNSPECV_PROLOGUE_SET_GOT))
+       (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
    (clobber (reg:CC 17))]
-  "!TARGET_64BIT"
-{
-  if (GET_CODE (operands[2]) == LABEL_REF)
-     operands[2] = XEXP (operands[2], 0);
-  if (TARGET_DEEP_BRANCH_PREDICTION) 
-    return "add{l}\t{%1, %0|%0, %1}";
-  else  
-    return "add{l}\t{%1+[.-%X2], %0|%0, %a1+(.-%X2)}";
-}
-  [(set_attr "type" "alu")
-   ; Since this insn may have two constant operands, we must set the
-   ; length manually.
-   (set_attr "length_immediate" "4")
-   (set_attr "mode" "SI")])
+  "!TARGET_64BIT && !flag_pic"
+  { return output_set_got (operands[0]); }
+  [(set_attr "type" "multi")
+   (set_attr "length" "11")])
 
-(define_insn "prologue_get_pc"
+(define_insn "*set_got_deep"
+  [(set (match_operand:SI 0 "register_operand" "=b")
+       (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
+   (clobber (reg:CC 17))]
+  "!TARGET_64BIT && TARGET_DEEP_BRANCH_PREDICTION"
+  { return output_set_got (operands[0]); }
+  [(set_attr "type" "multi")
+   (set_attr "length" "11")])
+
+(define_insn "*set_got_nodeep"
   [(set (match_operand:SI 0 "register_operand" "=r")
-    (unspec_volatile:SI [(plus:SI (pc) (match_operand 1 "" ""))]
-                       UNSPECV_PROLOGUE_GET_PC))]
+       (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
+   (clobber (reg:CC 17))]
   "!TARGET_64BIT"
-{
-  if (GET_CODE (operands[1]) == LABEL_REF)
-    operands[1] = XEXP (operands[1], 0);
-  output_asm_insn ("call\t%X1", operands);
-  if (! TARGET_DEEP_BRANCH_PREDICTION)
-    {
-      ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
-                                CODE_LABEL_NUMBER (operands[1]));
-    }
-  RET;
-}
-  [(set_attr "type" "multi")])
+  { return output_set_got (operands[0]); }
+  [(set_attr "type" "multi")
+   (set_attr "length" "12")])
 
 (define_expand "epilogue"
   [(const_int 1)]
   [(label_ref (match_operand 0 "" ""))]
   "!TARGET_64BIT && flag_pic"
 {
-  load_pic_register ();
+  emit_insn (gen_set_got (pic_offset_table_rtx));
   DONE;
 })
 \f