From 037de943dc054e19f7387c56668fbb6375bee268 Mon Sep 17 00:00:00 2001 From: Kai Tietz Date: Fri, 5 Nov 2010 23:00:35 +0000 Subject: [PATCH] i386.c (legitimate_pic_address_disp_p): Handle UNSPEC_PCREL. 2010-11-05 Kai Tietz * config/i386/i386.c (legitimate_pic_address_disp_p): Handle UNSPEC_PCREL. (ix86_legitimate_address_p): Likewise. (legitimize_pic_address): Likewise. (output_pic_addr_const): Likewise. (ix86_delegitimize_address): Likewise. (ix86_find_base_term): Likewise. (memory_address_length): Likewise. (x86_output_mi_thunk): Handle special case x64 for non local binding. * config/i386/i386.md (UNSPEC_PCREL): New. * config/i386/winnt.c (i386_pe_binds_local_p): Allow weak symbol for x64 windows with non-local binding. From-SVN: r166382 --- gcc/ChangeLog | 16 ++++++++++++++++ gcc/config/i386/i386.c | 28 +++++++++++++++++++++++++--- gcc/config/i386/i386.md | 1 + gcc/config/i386/winnt.c | 5 +---- 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 80f2ee31a6c..1678d050b77 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2010-11-05 Kai Tietz + + * config/i386/i386.c (legitimate_pic_address_disp_p): + Handle UNSPEC_PCREL. + (ix86_legitimate_address_p): Likewise. + (legitimize_pic_address): Likewise. + (output_pic_addr_const): Likewise. + (ix86_delegitimize_address): Likewise. + (ix86_find_base_term): Likewise. + (memory_address_length): Likewise. + (x86_output_mi_thunk): Handle special case x64 + for non local binding. + * config/i386/i386.md (UNSPEC_PCREL): New. + * config/i386/winnt.c (i386_pe_binds_local_p): + Allow weak symbol for x64 windows with non-local binding. + 2010-11-05 Jakub Jelinek PR target/45670 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 00febba7c64..c50fcc23b28 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -11718,6 +11718,7 @@ legitimate_pic_address_disp_p (rtx disp) if (GET_CODE (disp) != UNSPEC || (XINT (disp, 1) != UNSPEC_GOTPCREL && XINT (disp, 1) != UNSPEC_GOTOFF + && XINT (disp, 1) != UNSPEC_PCREL && XINT (disp, 1) != UNSPEC_PLTOFF)) return false; @@ -11900,6 +11901,7 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, return false; case UNSPEC_GOTPCREL: + case UNSPEC_PCREL: gcc_assert (flag_pic); goto is_legitimate_pic; @@ -12127,7 +12129,19 @@ legitimize_pic_address (rtx orig, rtx reg) } } - if (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC) + /* For x64 PE-COFF there is no GOT table. So we use address + directly. */ + if (TARGET_64BIT && DEFAULT_ABI == MS_ABI) + { + new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_PCREL); + new_rtx = gen_rtx_CONST (Pmode, new_rtx); + + if (reg == 0) + reg = gen_reg_rtx (Pmode); + emit_move_insn (reg, new_rtx); + new_rtx = reg; + } + else if (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC) { new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTPCREL); new_rtx = gen_rtx_CONST (Pmode, new_rtx); @@ -12836,6 +12850,10 @@ output_pic_addr_const (FILE *file, rtx x, int code) case UNSPEC_PLTOFF: fputs ("@PLTOFF", file); break; + case UNSPEC_PCREL: + fputs (ASSEMBLER_DIALECT == ASM_ATT ? + "(%rip)" : "[rip]", file); + break; case UNSPEC_GOTPCREL: fputs (ASSEMBLER_DIALECT == ASM_ATT ? "@GOTPCREL(%rip)" : "@GOTPCREL[rip]", file); @@ -12995,6 +13013,7 @@ ix86_delegitimize_address (rtx x) if (GET_CODE (x) != CONST || GET_CODE (XEXP (x, 0)) != UNSPEC || XINT (XEXP (x, 0), 1) != UNSPEC_GOTPCREL + || XINT (XEXP (x, 0), 1) != UNSPEC_PCREL || !MEM_P (orig_x)) return ix86_delegitimize_tls_address (orig_x); x = XVECEXP (XEXP (x, 0), 0, 0); @@ -13091,7 +13110,8 @@ ix86_find_base_term (rtx x) || GET_CODE (XEXP (term, 1)) == CONST_DOUBLE)) term = XEXP (term, 0); if (GET_CODE (term) != UNSPEC - || XINT (term, 1) != UNSPEC_GOTPCREL) + || (XINT (term, 1) != UNSPEC_GOTPCREL + && XINT (term, 1) != UNSPEC_PCREL)) return x; return XVECEXP (term, 0, 0); @@ -21803,6 +21823,7 @@ memory_address_length (rtx addr) || SYMBOL_REF_TLS_MODEL (symbol) != 0) && (GET_CODE (symbol) != UNSPEC || (XINT (symbol, 1) != UNSPEC_GOTPCREL + && XINT (symbol, 1) != UNSPEC_PCREL && XINT (symbol, 1) != UNSPEC_GOTNTPOFF))) len += 1; } @@ -29112,7 +29133,8 @@ x86_output_mi_thunk (FILE *file, xops[0] = XEXP (DECL_RTL (function), 0); if (TARGET_64BIT) { - if (!flag_pic || targetm.binds_local_p (function)) + if (!flag_pic || targetm.binds_local_p (function) + || DEFAULT_ABI == MS_ABI) output_asm_insn ("jmp\t%P0", xops); /* All thunks should be in the same object as their target, and thus binds_local_p should be true. */ diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 79f4b68d53c..eff96a106d4 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -76,6 +76,7 @@ UNSPEC_INDNTPOFF UNSPEC_PLTOFF UNSPEC_MACHOPIC_OFFSET + UNSPEC_PCREL ;; Prologue support UNSPEC_STACK_ALLOC diff --git a/gcc/config/i386/winnt.c b/gcc/config/i386/winnt.c index 45a736ad60e..251bb5ae5bc 100644 --- a/gcc/config/i386/winnt.c +++ b/gcc/config/i386/winnt.c @@ -326,10 +326,7 @@ i386_pe_binds_local_p (const_tree exp) /* Or a weak one, now that they are supported. */ if ((TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == FUNCTION_DECL) && DECL_WEAK (exp)) - /* But x64 gets confused and attempts to use unsupported GOTPCREL - relocations if we tell it the truth, so we still return true in - that case until the deeper problem can be fixed. */ - return (TARGET_64BIT && DEFAULT_ABI == MS_ABI); + return false; return true; }