re PR target/58067 (ICE in GFortran recog.c:2158)
authorJakub Jelinek <jakub@redhat.com>
Wed, 28 Aug 2013 16:31:41 +0000 (18:31 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 28 Aug 2013 16:31:41 +0000 (18:31 +0200)
PR target/58067
* config/i386/i386.md (*tls_global_dynamic_64_largepic): New insn.
(*tls_local_dynamic_base_64_largepic): Likewise.
(tls_global_dynamic_64_<mode>, tls_local_dynamic_base_64_<mode>):
Remove predicate from call operand.
* config/i386/i386.c (ix86_tls_get_addr): For -mcmodel=large -fpic
return sum of pic_offset_table_rtx and UNSPEC_PLTOFF of the symbol.

From-SVN: r202055

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.md

index 3d87dbbb8a0fcf2b5601c19cccb787cea21b2838..03577ecf93bfa7f83de38f1558f6ec96eb6fc6ac 100644 (file)
@@ -1,3 +1,13 @@
+2013-08-28  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/58067
+       * config/i386/i386.md (*tls_global_dynamic_64_largepic): New insn.
+       (*tls_local_dynamic_base_64_largepic): Likewise.
+       (tls_global_dynamic_64_<mode>, tls_local_dynamic_base_64_<mode>):
+       Remove predicate from call operand.
+       * config/i386/i386.c (ix86_tls_get_addr): For -mcmodel=large -fpic
+       return sum of pic_offset_table_rtx and UNSPEC_PLTOFF of the symbol.
+
 2013-08-28  Jeff Law  <law@redhat.com>
 
        * tree-ssa-threadedge.c (thread_around_empty_block): Remove
index d0818ad39acce2dd5e01ebf09c0c2aac8b66acf0..a8d70bc49b3dd00e769c7d590cfe6630b17871b0 100644 (file)
@@ -13048,6 +13048,14 @@ ix86_tls_get_addr (void)
       ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, sym);
     }
 
+  if (ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF)
+    {
+      rtx unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, ix86_tls_symbol),
+                                  UNSPEC_PLTOFF);
+      return gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
+                          gen_rtx_CONST (Pmode, unspec));
+    }
+
   return ix86_tls_symbol;
 }
 
index 3d7533a12f190466c778fe618ce3974054c8f075..3307b081aaa0ce6c83561776fbc453cc22a610e1 100644 (file)
    (set (attr "length")
        (symbol_ref "TARGET_X32 ? 15 : 16"))])
 
+(define_insn "*tls_global_dynamic_64_largepic"
+  [(set (match_operand:DI 0 "register_operand" "=a")
+       (call:DI
+        (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
+                         (match_operand:DI 3 "immediate_operand" "i")))
+        (match_operand 4)))
+   (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
+            UNSPEC_TLS_GD)]
+  "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
+   && GET_CODE (operands[3]) == CONST
+   && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
+   && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
+{
+  output_asm_insn
+    ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
+  output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
+  output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
+  return "call\t{*%%rax|rax}";
+}
+  [(set_attr "type" "multi")
+   (set_attr "length" "22")])
+
 (define_expand "tls_global_dynamic_64_<mode>"
   [(parallel
     [(set (match_operand:P 0 "register_operand")
          (call:P
-          (mem:QI (match_operand 2 "constant_call_address_operand"))
+          (mem:QI (match_operand 2))
           (const_int 0)))
      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
               UNSPEC_TLS_GD)])]
   [(set_attr "type" "multi")
    (set_attr "length" "12")])
 
+(define_insn "*tls_local_dynamic_base_64_largepic"
+  [(set (match_operand:DI 0 "register_operand" "=a")
+       (call:DI
+        (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
+                         (match_operand:DI 2 "immediate_operand" "i")))
+        (match_operand 3)))
+   (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
+  "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
+   && GET_CODE (operands[2]) == CONST
+   && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
+   && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
+{
+  output_asm_insn
+    ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
+  output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
+  output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
+  return "call\t{*%%rax|rax}";
+}
+  [(set_attr "type" "multi")
+   (set_attr "length" "22")])
+
 (define_expand "tls_local_dynamic_base_64_<mode>"
   [(parallel
      [(set (match_operand:P 0 "register_operand")
           (call:P
-           (mem:QI (match_operand 1 "constant_call_address_operand"))
+           (mem:QI (match_operand 1))
            (const_int 0)))
       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
   "TARGET_64BIT")