i386.md (UNSPEC_GOTNTPOFF, [...]): New.
authorJakub Jelinek <jakub@redhat.com>
Fri, 20 Sep 2002 22:08:34 +0000 (00:08 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 20 Sep 2002 22:08:34 +0000 (00:08 +0200)
* config/i386/i386.md (UNSPEC_GOTNTPOFF, UNSPEC_INDNTPOFF): New.
* config/i386/i386.c (legitimate_pic_address_disp_p): Handle
UNSPEC_GOTNTPOFF and UNSPEC_INDNTPOFF like UNSPEC_GOTTPOFF.
(legitimate_address_p): Likewise.
(legitimize_address): Use @gotntpoff and @indntpoff.
(output_pic_addr_const): Handle UNSPEC_GOTNTPOFF and UNSPEC_INDNTPOFF.
(output_addr_const_extra): Likewise.

From-SVN: r57373

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

index 103bc9468ba874f2e65d703c4af23953ea744061..9e4c8b1a0bba8438c0097a4931d796722a4c58b2 100644 (file)
@@ -1,3 +1,13 @@
+2002-09-20  Jakub Jelinek  <jakub@redhat.com>
+
+       * config/i386/i386.md (UNSPEC_GOTNTPOFF, UNSPEC_INDNTPOFF): New.
+       * config/i386/i386.c (legitimate_pic_address_disp_p): Handle
+       UNSPEC_GOTNTPOFF and UNSPEC_INDNTPOFF like UNSPEC_GOTTPOFF.
+       (legitimate_address_p): Likewise.
+       (legitimize_address): Use @gotntpoff and @indntpoff.
+       (output_pic_addr_const): Handle UNSPEC_GOTNTPOFF and UNSPEC_INDNTPOFF.
+       (output_addr_const_extra): Likewise.
+
 2002-09-20  Jim Wilson  <wilson@redhat.com>
 
        * combine.c (try_combine): When split an instruction pair, where the
index 0926ef62fc4819df90593435dfdb7139a4380c95..f36206c6ab21d927ec2bc234f1168003ff3d95a6 100644 (file)
@@ -5077,6 +5077,8 @@ legitimate_pic_address_disp_p (disp)
     case UNSPEC_GOTOFF:
       return local_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
     case UNSPEC_GOTTPOFF:
+    case UNSPEC_GOTNTPOFF:
+    case UNSPEC_INDNTPOFF:
       if (saw_plus)
        return false;
       return initial_exec_symbolic_operand (XVECEXP (disp, 0, 0), Pmode);
@@ -5258,6 +5260,8 @@ legitimate_address_p (mode, addr, strict)
            goto is_legitimate_pic;
 
          case UNSPEC_GOTTPOFF:
+         case UNSPEC_GOTNTPOFF:
+         case UNSPEC_INDNTPOFF:
          case UNSPEC_NTPOFF:
          case UNSPEC_DTPOFF:
            break;
@@ -5664,32 +5668,36 @@ legitimize_address (x, oldx, mode)
                regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
              pic = pic_offset_table_rtx;
            }
-         else
+         else if (!TARGET_GNU_TLS)
            {
              pic = gen_reg_rtx (Pmode);
              emit_insn (gen_set_got (pic));
            }
+         else
+           pic = NULL;
 
          base = get_thread_pointer ();
 
-         off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_GOTTPOFF);
+         off = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x),
+                               !TARGET_GNU_TLS
+                               ? UNSPEC_GOTTPOFF
+                               : flag_pic ? UNSPEC_GOTNTPOFF
+                                          : UNSPEC_INDNTPOFF);
          off = gen_rtx_CONST (Pmode, off);
-         off = gen_rtx_PLUS (Pmode, pic, off);
+         if (flag_pic || !TARGET_GNU_TLS)
+           off = gen_rtx_PLUS (Pmode, pic, off);
          off = gen_rtx_MEM (Pmode, off);
          RTX_UNCHANGING_P (off) = 1;
          set_mem_alias_set (off, ix86_GOT_alias_set ());
-
-         /* Damn Sun for specifing a set of dynamic relocations without
-            considering the two-operand nature of the architecture!
-            We'd be much better off with a "GOTNTPOFF" relocation that
-            already contained the negated constant.  */
-         /* ??? Using negl and reg+reg addressing appears to be a lose
-            size-wise.  The negl is two bytes, just like the extra movl
-            incurred by the two-operand subl, but reg+reg addressing
-            uses the two-byte modrm form, unlike plain reg.  */
-
          dest = gen_reg_rtx (Pmode);
-         emit_insn (gen_subsi3 (dest, base, off));
+
+         if (TARGET_GNU_TLS)
+           {
+             emit_move_insn (dest, off);
+             return gen_rtx_PLUS (Pmode, base, dest);
+           }
+         else
+           emit_insn (gen_subsi3 (dest, base, off));
          break;
 
         case TLS_MODEL_LOCAL_EXEC:
@@ -5970,6 +5978,7 @@ output_pic_addr_const (file, x, code)
          fputs ("@GOTPCREL(%rip)", file);
          break;
        case UNSPEC_GOTTPOFF:
+         /* FIXME: This might be @TPOFF in Sun ld too.  */
          fputs ("@GOTTPOFF", file);
          break;
        case UNSPEC_TPOFF:
@@ -5981,6 +5990,12 @@ output_pic_addr_const (file, x, code)
        case UNSPEC_DTPOFF:
          fputs ("@DTPOFF", file);
          break;
+       case UNSPEC_GOTNTPOFF:
+         fputs ("@GOTNTPOFF", file);
+         break;
+       case UNSPEC_INDNTPOFF:
+         fputs ("@INDNTPOFF", file);
+         break;
        default:
          output_operand_lossage ("invalid UNSPEC as operand");
          break;
@@ -6890,6 +6905,7 @@ output_addr_const_extra (file, x)
     {
     case UNSPEC_GOTTPOFF:
       output_addr_const (file, op);
+      /* FIXME: This might be @TPOFF in Sun ld.  */
       fputs ("@GOTTPOFF", file);
       break;
     case UNSPEC_TPOFF:
@@ -6904,6 +6920,14 @@ output_addr_const_extra (file, x)
       output_addr_const (file, op);
       fputs ("@DTPOFF", file);
       break;
+    case UNSPEC_GOTNTPOFF:
+      output_addr_const (file, op);
+      fputs ("@GOTNTPOFF", file);
+      break;
+    case UNSPEC_INDNTPOFF:
+      output_addr_const (file, op);
+      fputs ("@INDNTPOFF", file);
+      break;
 
     default:
       return false;
index eb74fb555854fa1bab818a4f5dd39e96099e090e..02e4ee8c0e39aa61c3a3900b632cffcb231616f5 100644 (file)
@@ -61,6 +61,8 @@
    (UNSPEC_TPOFF               4)
    (UNSPEC_NTPOFF              5)
    (UNSPEC_DTPOFF              6)
+   (UNSPEC_GOTNTPOFF           7)
+   (UNSPEC_INDNTPOFF           8)
 
    ; Prologue support
    (UNSPEC_STACK_PROBE         10)