[PATCH] Support IA-32 TLS @gotntpoff and @indntpoff
Jakub Jelinek
jakub@redhat.com
Fri Sep 20 13:37:00 GMT 2002
Hi!
Bootstrapped on IA-32, no regressions. Ok to commit?
No direct %gs:foo access yet...
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.
--- gcc/config/i386/i386.md.jj 2002-09-20 12:14:40.000000000 +0200
+++ gcc/config/i386/i386.md 2002-09-20 18:24:00.000000000 +0200
@@ -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)
--- gcc/config/i386/i386.c.jj 2002-09-20 18:42:33.000000000 +0200
+++ gcc/config/i386/i386.c 2002-09-20 19:56:47.000000000 +0200
@@ -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;
@@ -5658,38 +5662,43 @@ legitimize_address (x, oldx, mode)
return gen_rtx_PLUS (Pmode, base, off);
case TLS_MODEL_INITIAL_EXEC:
- if (flag_pic)
+ if (flag_pic || !TARGET_GNU_TLS)
{
- if (reload_in_progress)
- regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
- pic = pic_offset_table_rtx;
- }
- else
- {
- pic = gen_reg_rtx (Pmode);
- emit_insn (gen_set_got (pic));
+ if (flag_pic)
+ {
+ if (reload_in_progress)
+ regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
+ pic = pic_offset_table_rtx;
+ }
+ else
+ {
+ pic = gen_reg_rtx (Pmode);
+ emit_insn (gen_set_got (pic));
+ }
}
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 +5979,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 +5991,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 +6906,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 +6921,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;
Jakub
More information about the Gcc-patches
mailing list