From dea7379019da21674e38abaa27917a8596c5780f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 21 Sep 2002 00:08:34 +0200 Subject: [PATCH] i386.md (UNSPEC_GOTNTPOFF, [...]): New. * 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 | 10 ++++++++ gcc/config/i386/i386.c | 52 ++++++++++++++++++++++++++++++----------- gcc/config/i386/i386.md | 2 ++ 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 103bc9468ba..9e4c8b1a0bb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2002-09-20 Jakub Jelinek + + * 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 * combine.c (try_combine): When split an instruction pair, where the diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 0926ef62fc4..f36206c6ab2 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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; diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index eb74fb55585..02e4ee8c0e3 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -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) -- 2.30.2