i386.c (legitimize_tls_address): Call gen_tls_dynamic_gnu2_{32,64} expanders directly...
authorUros Bizjak <uros@gcc.gnu.org>
Wed, 11 May 2011 15:30:52 +0000 (17:30 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Wed, 11 May 2011 15:30:52 +0000 (17:30 +0200)
* config/i386/i386.c (legitimize_tls_address)
<TLS_MODEL_GLOBAL_DYNAMIC>: Call gen_tls_dynamic_gnu2_{32,64}
expanders directly for TARGET_GNU2_TLS.  Determine pic and
__tls_get_addr symbol reference here.  Update call to
gen_tls_global_dynamic_{32,64} for added arguments.
<TLS_MODEL_LOCAL_DYNAMIC>: Call gen_tls_dynamic_gnu2_{32,64}
expanders directly for TARGET_GNU2_TLS.  Determine
__tls_get_addr symbol reference here.  Update call to
gen_tls_local_dynamic_base_{32,64} for added arguments.  Attach
unique UNSPEC REG_EQUIV to libcall block.
(ix86_tls_get_addr): Declare static.
* config/i386/i386-protos.h (ix86_tls_get_addr): Remove declaration.
* config/i386/i386.md (tls_global_dynamic_32): Add operand 2 and 3.
Do not determine pic and __tls_get_addr symbol reference here. Do not
call gen_tls_dynamic_gnu2_32 for TARGET_GNU2_TLS.
(tls_local_dynamic_base_32): Ditto for operands 1 and 2.
(tls_global_dynamic_64): Add operand 2.  Do not determine
__tls_get_addr symbol reference here.  Do not call
gen_tls_dynamic_gnu2_64 for TARGET_GNU2_TLS here.
(tls_local_dynamic_base64): Ditto for operand 1.

From-SVN: r173662

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

index 6db1f29e8ae8d54363abf81fa454e7a98d1e41b6..8c799370220b553a8d12aa30da8e6d16173b2bcf 100644 (file)
@@ -1,3 +1,26 @@
+2011-05-11  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.c (legitimize_tls_address)
+       <TLS_MODEL_GLOBAL_DYNAMIC>: Call gen_tls_dynamic_gnu2_{32,64}
+       expanders directly for TARGET_GNU2_TLS.  Determine pic and
+       __tls_get_addr symbol reference here.  Update call to
+       gen_tls_global_dynamic_{32,64} for added arguments.
+       <TLS_MODEL_LOCAL_DYNAMIC>: Call gen_tls_dynamic_gnu2_{32,64}
+       expanders directly for TARGET_GNU2_TLS.  Determine
+       __tls_get_addr symbol reference here.  Update call to
+       gen_tls_local_dynamic_base_{32,64} for added arguments.  Attach
+       unique UNSPEC REG_EQUIV to libcall block.
+       (ix86_tls_get_addr): Declare static.
+       * config/i386/i386-protos.h (ix86_tls_get_addr): Remove declaration.
+       * config/i386/i386.md (tls_global_dynamic_32): Add operand 2 and 3.
+       Do not determine pic and __tls_get_addr symbol reference here. Do not
+       call gen_tls_dynamic_gnu2_32 for TARGET_GNU2_TLS.
+       (tls_local_dynamic_base_32): Ditto for operands 1 and 2.
+       (tls_global_dynamic_64): Add operand 2.  Do not determine
+       __tls_get_addr symbol reference here.  Do not call
+       gen_tls_dynamic_gnu2_64 for TARGET_GNU2_TLS here.
+       (tls_local_dynamic_base64): Ditto for operand 1.
+
 2011-05-11  Eric Botcazou  <ebotcazou@adacore.com>
 
        * function.c (expand_function_start): Initialize stack_check_probe_note
@@ -13,8 +36,7 @@
 
 2011-05-11  Nathan Froyd  <froydnj@codesourcery.com>
 
-       * ggc-page.c (extra_order_size_table): Use struct
-       tree_type_non_common.
+       * ggc-page.c (extra_order_size_table): Use struct tree_type_non_common.
        * lto-streamer-in.c (unpack_ts_type_value_fields): Rename to...
        (unpack_ts_type_common_value_fields): ...this.  Update comment.
        (unpack_value_fields): Adjust for renaming.
 
 2011-05-11  Joseph Myers  <joseph@codesourcery.com>
 
-       * opts.c (finish_options): Move warning settings from
-       process_options.
-       * toplev.c (process_options): Move warning settings to
-       finish_options.
+       * opts.c (finish_options): Move warning settings from process_options.
+       * toplev.c (process_options): Move warning settings to finish_options.
 
 2011-05-11  Richard Guenther  <rguenther@suse.de>
 
 
 2011-05-10  Joseph Myers  <joseph@codesourcery.com>
 
-       * config/rs6000/genopt.sh, config/rs6000/rs6000-cpus.def: New
-       files.
+       * config/rs6000/genopt.sh, config/rs6000/rs6000-cpus.def: New files.
        * config/rs6000/rs6000-tables.opt: New file (generated).
        * config.gcc (powerpc*-*-*, rs6000*-*-*): Add
        rs6000/rs6000-tables.opt to extra_options.
 
        * config.gcc (libgcc_tm_file): Define instead of including files
        from ../../libgcc/config/ in tm_file.
-       * configure.ac (libgcc_tm_file_list, libgcc_tm_include_list):
-       Define.
+       * configure.ac (libgcc_tm_file_list, libgcc_tm_include_list): Define.
        * configure: Regenerate.
        * Makefile.in (libgcc_tm_file_list, libgcc_tm_include_list,
        libgcc_tm.h, cs-libgcc_tm.h): New.
index ccba8484bdc3db3f4f7399971afa52d00570fe9f..a58c964475b0caf2e89fb2e5cfd1d0ecab2a8155 100644 (file)
@@ -193,7 +193,6 @@ extern unsigned int ix86_get_callcvt (const_tree);
 
 #endif
 
-extern rtx ix86_tls_get_addr (void);
 extern rtx ix86_tls_module_base (void);
 
 extern void ix86_expand_vector_init (bool, rtx, rtx);
index afba1a7049dc4d1f083bad91d0e92d44896f7caa..1cf8933e4dfeef0f5b8a36e16f176e55253c588f 100644 (file)
@@ -12657,7 +12657,7 @@ legitimize_pic_address (rtx orig, rtx reg)
 /* Load the thread pointer.  If TO_REG is true, force it into a register.  */
 
 static rtx
-get_thread_pointer (int to_reg)
+get_thread_pointer (bool to_reg)
 {
   rtx tp, reg, insn;
 
@@ -12672,76 +12672,154 @@ get_thread_pointer (int to_reg)
   return reg;
 }
 
+/* Construct the SYMBOL_REF for the tls_get_addr function.  */
+
+static GTY(()) rtx ix86_tls_symbol;
+
+static rtx
+ix86_tls_get_addr (void)
+{
+  if (!ix86_tls_symbol)
+    {
+      const char *sym
+       = ((TARGET_ANY_GNU_TLS && !TARGET_64BIT)
+          ? "___tls_get_addr" : "__tls_get_addr");
+
+      ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, sym);
+    }
+
+  return ix86_tls_symbol;
+}
+
+/* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol.  */
+
+static GTY(()) rtx ix86_tls_module_base_symbol;
+
+rtx
+ix86_tls_module_base (void)
+{
+  if (!ix86_tls_module_base_symbol)
+    {
+      ix86_tls_module_base_symbol
+       = gen_rtx_SYMBOL_REF (Pmode, "_TLS_MODULE_BASE_");
+
+      SYMBOL_REF_FLAGS (ix86_tls_module_base_symbol)
+       |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
+    }
+
+  return ix86_tls_module_base_symbol;
+}
+
 /* A subroutine of ix86_legitimize_address and ix86_expand_move.  FOR_MOV is
    false if we expect this to be used for a memory address and true if
    we expect to load the address into a register.  */
 
 static rtx
-legitimize_tls_address (rtx x, enum tls_model model, int for_mov)
+legitimize_tls_address (rtx x, enum tls_model model, bool for_mov)
 {
-  rtx dest, base, off, pic, tp;
+  rtx dest, base, off;
+  rtx pic = NULL_RTX, tp = NULL_RTX;
   int type;
 
   switch (model)
     {
     case TLS_MODEL_GLOBAL_DYNAMIC:
       dest = gen_reg_rtx (Pmode);
-      tp = TARGET_GNU2_TLS ? get_thread_pointer (1) : 0;
 
-      if (TARGET_64BIT && ! TARGET_GNU2_TLS)
+      if (!TARGET_64BIT)
        {
-         rtx rax = gen_rtx_REG (Pmode, AX_REG), insns;
-
-         start_sequence ();
-         emit_call_insn (gen_tls_global_dynamic_64 (rax, x));
-         insns = get_insns ();
-         end_sequence ();
-
-         RTL_CONST_CALL_P (insns) = 1;
-         emit_libcall_block (insns, dest, rax, x);
+         if (flag_pic)
+           pic = pic_offset_table_rtx;
+         else
+           {
+             pic = gen_reg_rtx (Pmode);
+             emit_insn (gen_set_got (pic));
+           }
        }
-      else if (TARGET_64BIT && TARGET_GNU2_TLS)
-       emit_insn (gen_tls_global_dynamic_64 (dest, x));
-      else
-       emit_insn (gen_tls_global_dynamic_32 (dest, x));
 
       if (TARGET_GNU2_TLS)
        {
+         if (TARGET_64BIT)
+           emit_insn (gen_tls_dynamic_gnu2_64 (dest, x));
+         else
+           emit_insn (gen_tls_dynamic_gnu2_32 (dest, x, pic));
+
+         tp = get_thread_pointer (true);
          dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, tp, dest));
 
          set_unique_reg_note (get_last_insn (), REG_EQUIV, x);
        }
+      else
+       {
+         rtx caddr = ix86_tls_get_addr ();
+
+         if (TARGET_64BIT)
+           {
+             rtx rax = gen_rtx_REG (Pmode, AX_REG), insns;
+
+             start_sequence ();
+             emit_call_insn (gen_tls_global_dynamic_64 (rax, x, caddr));
+             insns = get_insns ();
+             end_sequence ();
+
+             RTL_CONST_CALL_P (insns) = 1;
+             emit_libcall_block (insns, dest, rax, x);
+           }
+         else
+           emit_insn (gen_tls_global_dynamic_32 (dest, x, pic, caddr));
+       }
       break;
 
     case TLS_MODEL_LOCAL_DYNAMIC:
       base = gen_reg_rtx (Pmode);
-      tp = TARGET_GNU2_TLS ? get_thread_pointer (1) : 0;
 
-      if (TARGET_64BIT && ! TARGET_GNU2_TLS)
+      if (!TARGET_64BIT)
        {
-         rtx rax = gen_rtx_REG (Pmode, AX_REG), insns, note;
-
-         start_sequence ();
-         emit_call_insn (gen_tls_local_dynamic_base_64 (rax));
-         insns = get_insns ();
-         end_sequence ();
-
-         note = gen_rtx_EXPR_LIST (VOIDmode, const0_rtx, NULL);
-         note = gen_rtx_EXPR_LIST (VOIDmode, ix86_tls_get_addr (), note);
-         RTL_CONST_CALL_P (insns) = 1;
-         emit_libcall_block (insns, base, rax, note);
+         if (flag_pic)
+           pic = pic_offset_table_rtx;
+         else
+           {
+             pic = gen_reg_rtx (Pmode);
+             emit_insn (gen_set_got (pic));
+           }
        }
-      else if (TARGET_64BIT && TARGET_GNU2_TLS)
-       emit_insn (gen_tls_local_dynamic_base_64 (base));
-      else
-       emit_insn (gen_tls_local_dynamic_base_32 (base));
 
       if (TARGET_GNU2_TLS)
        {
-         rtx x = ix86_tls_module_base ();
+         rtx tmp = ix86_tls_module_base ();
 
+         if (TARGET_64BIT)
+           emit_insn (gen_tls_dynamic_gnu2_64 (base, tmp));
+         else
+           emit_insn (gen_tls_dynamic_gnu2_32 (base, tmp, pic));
+
+         tp = get_thread_pointer (true);
          set_unique_reg_note (get_last_insn (), REG_EQUIV,
-                              gen_rtx_MINUS (Pmode, x, tp));
+                              gen_rtx_MINUS (Pmode, tmp, tp));
+       }
+      else
+       {
+         rtx caddr = ix86_tls_get_addr ();
+
+         if (TARGET_64BIT)
+           {
+             rtx rax = gen_rtx_REG (Pmode, AX_REG), insns, eqv;
+
+             start_sequence ();
+             emit_call_insn (gen_tls_local_dynamic_base_64 (rax, caddr));
+             insns = get_insns ();
+             end_sequence ();
+
+             /* Attach a unique REG_EQUIV, to allow the RTL optimizers to
+                share the LD_BASE result with other LD model accesses.  */
+             eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
+                                   UNSPEC_TLS_LD_BASE);
+
+             RTL_CONST_CALL_P (insns) = 1;
+             emit_libcall_block (insns, base, rax, eqv);
+           }
+         else
+           emit_insn (gen_tls_local_dynamic_base_32 (base, pic, caddr));
        }
 
       off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_DTPOFF);
@@ -12755,7 +12833,6 @@ legitimize_tls_address (rtx x, enum tls_model model, int for_mov)
 
          set_unique_reg_note (get_last_insn (), REG_EQUIV, x);
        }
-
       break;
 
     case TLS_MODEL_INITIAL_EXEC:
@@ -22166,43 +22243,6 @@ assign_386_stack_local (enum machine_mode mode, enum ix86_stack_slot n)
   ix86_stack_locals = s;
   return s->rtl;
 }
-
-/* Construct the SYMBOL_REF for the tls_get_addr function.  */
-
-static GTY(()) rtx ix86_tls_symbol;
-rtx
-ix86_tls_get_addr (void)
-{
-
-  if (!ix86_tls_symbol)
-    {
-      ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode,
-                                           (TARGET_ANY_GNU_TLS
-                                            && !TARGET_64BIT)
-                                           ? "___tls_get_addr"
-                                           : "__tls_get_addr");
-    }
-
-  return ix86_tls_symbol;
-}
-
-/* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol.  */
-
-static GTY(()) rtx ix86_tls_module_base_symbol;
-rtx
-ix86_tls_module_base (void)
-{
-
-  if (!ix86_tls_module_base_symbol)
-    {
-      ix86_tls_module_base_symbol = gen_rtx_SYMBOL_REF (Pmode,
-                                                       "_TLS_MODULE_BASE_");
-      SYMBOL_REF_FLAGS (ix86_tls_module_base_symbol)
-       |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
-    }
-
-  return ix86_tls_module_base_symbol;
-}
 \f
 /* Calculate the length of the memory address in the instruction
    encoding.  Does not include the one-byte modrm, opcode, or prefix.  */
index b1fc57314a2ff5cc7b333d6245d034a87a9c9e7c..028eafd3ee1219b87a102401bdedc4bbc645cad3 100644 (file)
 (define_expand "tls_global_dynamic_32"
   [(parallel [(set (match_operand:SI 0 "register_operand" "")
                   (unspec:SI
-                   [(match_dup 2)
+                   [(match_operand:SI 2 "register_operand" "")
                     (match_operand:SI 1 "tls_symbolic_operand" "")
-                    (match_dup 3)]
+                    (match_operand:SI 3 "call_insn_operand" "")]
                    UNSPEC_TLS_GD))
              (clobber (match_scratch:SI 4 ""))
              (clobber (match_scratch:SI 5 ""))
-             (clobber (reg:CC FLAGS_REG))])]
-  ""
-{
-  if (flag_pic)
-    operands[2] = pic_offset_table_rtx;
-  else
-    {
-      operands[2] = gen_reg_rtx (Pmode);
-      emit_insn (gen_set_got (operands[2]));
-    }
-  if (TARGET_GNU2_TLS)
-    {
-       emit_insn (gen_tls_dynamic_gnu2_32
-                 (operands[0], operands[1], operands[2]));
-       DONE;
-    }
-  operands[3] = ix86_tls_get_addr ();
-})
+             (clobber (reg:CC FLAGS_REG))])])
 
 (define_insn "*tls_global_dynamic_64"
   [(set (match_operand:DI 0 "register_operand" "=a")
 
 (define_expand "tls_global_dynamic_64"
   [(parallel [(set (match_operand:DI 0 "register_operand" "")
-                  (call:DI (mem:QI (match_dup 2)) (const_int 0)))
+                  (call:DI
+                    (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
+                    (const_int 0)))
              (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
-                        UNSPEC_TLS_GD)])]
-  ""
-{
-  if (TARGET_GNU2_TLS)
-    {
-       emit_insn (gen_tls_dynamic_gnu2_64
-                 (operands[0], operands[1]));
-       DONE;
-    }
-  operands[2] = ix86_tls_get_addr ();
-})
+                        UNSPEC_TLS_GD)])])
 
 (define_insn "*tls_local_dynamic_base_32_gnu"
   [(set (match_operand:SI 0 "register_operand" "=a")
 
 (define_expand "tls_local_dynamic_base_32"
   [(parallel [(set (match_operand:SI 0 "register_operand" "")
-                  (unspec:SI [(match_dup 1) (match_dup 2)]
+                  (unspec:SI [(match_operand:SI 1 "register_operand" "")
+                              (match_operand:SI 2 "call_insn_operand" "")]
                              UNSPEC_TLS_LD_BASE))
              (clobber (match_scratch:SI 3 ""))
              (clobber (match_scratch:SI 4 ""))
-             (clobber (reg:CC FLAGS_REG))])]
-  ""
-{
-  if (flag_pic)
-    operands[1] = pic_offset_table_rtx;
-  else
-    {
-      operands[1] = gen_reg_rtx (Pmode);
-      emit_insn (gen_set_got (operands[1]));
-    }
-  if (TARGET_GNU2_TLS)
-    {
-       emit_insn (gen_tls_dynamic_gnu2_32
-                 (operands[0], ix86_tls_module_base (), operands[1]));
-       DONE;
-    }
-  operands[2] = ix86_tls_get_addr ();
-})
+             (clobber (reg:CC FLAGS_REG))])])
 
 (define_insn "*tls_local_dynamic_base_64"
   [(set (match_operand:DI 0 "register_operand" "=a")
 
 (define_expand "tls_local_dynamic_base_64"
   [(parallel [(set (match_operand:DI 0 "register_operand" "")
-                  (call:DI (mem:QI (match_dup 1)) (const_int 0)))
-             (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
-  ""
-{
-  if (TARGET_GNU2_TLS)
-    {
-       emit_insn (gen_tls_dynamic_gnu2_64
-                 (operands[0], ix86_tls_module_base ()));
-       DONE;
-    }
-  operands[1] = ix86_tls_get_addr ();
-})
+                  (call:DI
+                    (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
+                    (const_int 0)))
+             (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
 
 ;; Local dynamic of a single variable is a lose.  Show combine how
 ;; to convert that back to global dynamic.