From patchwork Fri Mar 22 09:27:00 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kai Tietz X-Patchwork-Id: 229933 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 25E5E2C00C3 for ; Fri, 22 Mar 2013 20:28:04 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:date:message-id:subject:from:to:cc:content-type; q=dns; s=default; b=BG1icIZvlZuqR4zvpuKAWOgCBsbqEmR825eIdvD22fP ONfQL/I0+L1uuKFlwXiELQYm1LNz5k8fuIq9zcB8/JKixdJhayRsv34vXokOliEp 3lBk5v5RX/ojTCJGsfz+eYOblNQFugzOnOxvgBFzbeueRdDxcTvt3/+0Kh/k3IKQ = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:date:message-id:subject:from:to:cc:content-type; s=default; bh=WkMrT5cnAiNuis2O+RN5cDIOOj8=; b=q2eAFWd3l9Tnco2Z3 1f9/VMGD0SVRxIeUc9WvxSWxxyigXfU2LPhy+130v4q5NXhZtC5kDfIeAb08Wygw 3faIMlj9t35RSoYZ2gM5BCwgvyyhAgVVzPUJARkbuFugcMjCV9k5fmYgvkeu61rL C4f/O/8EZpJhiN9ObW1p3jAevI= Received: (qmail 16397 invoked by alias); 22 Mar 2013 09:27:58 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 16324 invoked by uid 89); 22 Mar 2013 09:27:10 -0000 X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL, BAYES_00, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, KAM_STOCKGEN, RCVD_IN_DNSWL_LOW, TW_FP, T_FILL_THIS_FORM_SHORT autolearn=no version=3.3.1 Received: from mail-ia0-f175.google.com (HELO mail-ia0-f175.google.com) (209.85.210.175) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Fri, 22 Mar 2013 09:27:01 +0000 Received: by mail-ia0-f175.google.com with SMTP id y26so3275889iab.20 for ; Fri, 22 Mar 2013 02:27:00 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.50.7.242 with SMTP id m18mr4343173iga.53.1363944420129; Fri, 22 Mar 2013 02:27:00 -0700 (PDT) Received: by 10.64.14.129 with HTTP; Fri, 22 Mar 2013 02:27:00 -0700 (PDT) Date: Fri, 22 Mar 2013 10:27:00 +0100 Message-ID: Subject: [patch i386 windows]: Fix PR/52790 also required for workig upcoming cygwin x64 target From: Kai Tietz To: GCC Patches Cc: Richard Henderson Hi, this patch fixes PR/52790 and supports for x64 Windows targets the use of large and medium code-model. This feature is required for upcoming new cygwin x64 target, which uses full 48-bit available address-space of x64 Windows. The cygwin-target depends on pseudo-relocation-feature, which operates on instruction relocations. This can lead for x86_64 to issues, due instructions are in general signed-32bit-pc-relative relocated. So distances can become too wide for pseudo-relocation. Due for functions we generate anyway on pe-coff targets jump-stubs, we just need to make sure that variables are accessed via reference-pointer-variables. So we add for them in medium model .refptr-variables. In large model we using for external (therefore possibly pseudo-relocated) symbols also indirect-addressing via refptr-stubs. To avoid same issues as we noticed on cygwin64, I want to change code-model default to medium also for native-windows x64 target. ChangeLog 2013-03-22 Kai Tietz PR target/52790 * config/i386/cygming.h (SUB_TARGET_RECORD_STUB): New sub-target macro. * config/i386/i386-protos.h (i386_pe_record_stub): Add new prototype. * config/i386/i386.c (legitimize_pe_coff_extern_decl): New static function. (legitimize_pe_coff_symbol): Likewise. (is_imported_p): New helper-function. (ix86_option_override_internal): Make MEDIUM_PIC the default code-model for Windows x64 targets. (ix86_expand_prologue): Optimize for pe-coff targets. (ix86_expand_split_stack_prologue): Adjust for pe-coff targets. (legitimate_pic_address_disp_p): Adjust for x64 pe-coff to support medium/large code-model. (legitimize_pic_address): Likewise. (legitimize_tls_address): Likewise. (ix86_expand_call): Likewise. (x86_output_mi_thunk): Likewise. (get_dllimport_decl): Add new beimport argument. (construct_plt_address): Don't assert for x64 pe-coff targets. * config/i386/i386.h (PIC_OFFSET_TABLE_REGNUM): Adjust for x64 pe-coff targets. (SYMBOL_FLAG_STUBVAR): New macro. (SYMBOL_REF_STUBVAR_P): Likewise. * config/i386/winnt.c (stub_list): New structure. (stub_head): New local variable. (i386_pe_record_stub): New function. (i386_pe_file_end): Emit refptr-stubs. This patch is tested for x86_64-pc-cygwin, x86_64-w64-mingw32. Additional tested for x86_64-unknown-linux-gnu to see that no regression were introduced by this patch. Ok for apply? Regards, Kai Index: gcc/config/i386/cygming.h =================================================================== --- gcc/config/i386/cygming.h (Revision 196898) +++ gcc/config/i386/cygming.h (Arbeitskopie) @@ -474,5 +474,8 @@ do { \ #undef TARGET_ASM_ASSEMBLE_VISIBILITY #define TARGET_ASM_ASSEMBLE_VISIBILITY i386_pe_assemble_visibility +#undef SUB_TARGET_RECORD_STUB +#define SUB_TARGET_RECORD_STUB i386_pe_record_stub + /* Static stack checking is supported by means of probes. */ #define STACK_CHECK_STATIC_BUILTIN 1 Index: gcc/config/i386/i386-protos.h =================================================================== --- gcc/config/i386/i386-protos.h (Revision 196898) +++ gcc/config/i386/i386-protos.h (Arbeitskopie) @@ -260,6 +260,7 @@ extern void i386_pe_end_function (FILE *, const ch extern void i386_pe_assemble_visibility (tree, int); extern tree i386_pe_mangle_decl_assembler_name (tree, tree); extern tree i386_pe_mangle_assembler_name (const char *); +extern void i386_pe_record_stub (const char *); extern void i386_pe_seh_init (FILE *); extern void i386_pe_seh_end_prologue (FILE *); Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c (Revision 196898) +++ gcc/config/i386/i386.c (Arbeitskopie) @@ -64,6 +64,8 @@ along with GCC; see the file COPYING3. If not see #include "tree-flow.h" static rtx legitimize_dllimport_symbol (rtx, bool); +static rtx legitimize_pe_coff_extern_decl (rtx, bool); +static rtx legitimize_pe_coff_symbol (rtx, bool); #ifndef CHECK_STACK_LIMIT #define CHECK_STACK_LIMIT (-1) @@ -3233,9 +3235,7 @@ ix86_option_override_internal (bool main_args_p) use of rip-relative addressing. This eliminates fixups that would otherwise be needed if this object is to be placed in a DLL, and is essentially just as efficient as direct addressing. */ - if (TARGET_64BIT && DEFAULT_ABI == MS_ABI) - ix86_cmodel = CM_SMALL_PIC, flag_pic = 1; - else if (TARGET_64BIT && TARGET_RDOS) + if (TARGET_64BIT && (TARGET_RDOS || DEFAULT_ABI == MS_ABI)) ix86_cmodel = CM_MEDIUM_PIC, flag_pic = 1; else if (TARGET_64BIT) ix86_cmodel = flag_pic ? CM_SMALL_PIC : CM_SMALL; @@ -10575,7 +10575,9 @@ ix86_expand_prologue (void) ix86_emit_save_sse_regs_using_mov (frame.sse_reg_save_offset); pic_reg_used = false; + /* We don't use pic-register for pe-coff target. */ if (pic_offset_table_rtx + && DEFAULT_ABI != MS_ABI && (df_regs_ever_live_p (REAL_PIC_OFFSET_TABLE_REGNUM) || crtl->profile)) { @@ -11380,7 +11382,8 @@ ix86_expand_split_stack_prologue (void) use_reg (&call_fusage, rax); } - if (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC) + if ((ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC) + && DEFAULT_ABI != MS_ABI) { HOST_WIDE_INT argval; @@ -11998,7 +12001,20 @@ ix86_cannot_force_const_mem (enum machine_mode mod return !ix86_legitimate_constant_p (mode, x); } +/* Nonzero if the symbol is marked as dllimport, or as stub-variable, + otherwise zero. */ +static bool +is_imported_p (rtx x) +{ + if (!TARGET_DLLIMPORT_DECL_ATTRIBUTES + || GET_CODE (x) != SYMBOL_REF) + return false; + + return SYMBOL_REF_DLLIMPORT_P (x) || SYMBOL_REF_STUBVAR_P (x); +} + + /* Nonzero if the constant value X is a legitimate general operand when generating PIC code. It is given that flag_pic is on and that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ @@ -12086,11 +12102,39 @@ legitimate_pic_address_disp_p (rtx disp) /* FALLTHRU */ case SYMBOL_REF: - /* TLS references should always be enclosed in UNSPEC. */ - if (SYMBOL_REF_TLS_MODEL (op0)) + /* TLS references should always be enclosed in UNSPEC. + The dllimported symbol needs always to be resolved. */ + if (SYMBOL_REF_TLS_MODEL (op0) + || (TARGET_DLLIMPORT_DECL_ATTRIBUTES && SYMBOL_REF_DLLIMPORT_P (op0))) return false; - if (!SYMBOL_REF_FAR_ADDR_P (op0) && SYMBOL_REF_LOCAL_P (op0) - && ix86_cmodel != CM_LARGE_PIC) + + if (DEFAULT_ABI == MS_ABI) + { + if (is_imported_p (op0)) + return true; + + if (SYMBOL_REF_FAR_ADDR_P (op0) + || !SYMBOL_REF_LOCAL_P (op0)) + break; + + /* Function-symbols need to be resolved only for + large-model. + For the small-model we don't need to resolve anything + here. */ + if ((ix86_cmodel != CM_LARGE_PIC + && SYMBOL_REF_FUNCTION_P (op0)) + || ix86_cmodel == CM_SMALL_PIC) + return true; + /* Non-external symbols don't need to be resolved for + large, and medium-model. */ + if ((ix86_cmodel == CM_LARGE_PIC + || ix86_cmodel == CM_MEDIUM_PIC) + && !SYMBOL_REF_EXTERNAL_P (op0)) + return true; + } + else if (!SYMBOL_REF_FAR_ADDR_P (op0) + && SYMBOL_REF_LOCAL_P (op0) + && ix86_cmodel != CM_LARGE_PIC) return true; break; @@ -12151,7 +12195,7 @@ legitimate_pic_address_disp_p (rtx disp) if ((GET_CODE (XVECEXP (disp, 0, 0)) == SYMBOL_REF || GET_CODE (XVECEXP (disp, 0, 0)) == LABEL_REF) && !TARGET_64BIT) - return gotoff_operand (XVECEXP (disp, 0, 0), Pmode); + return DEFAULT_ABI != MS_ABI && gotoff_operand (XVECEXP (disp, 0, 0), Pmode); return false; case UNSPEC_GOTTPOFF: case UNSPEC_GOTNTPOFF: @@ -12486,11 +12530,17 @@ legitimize_pic_address (rtx orig, rtx reg) } #endif + if (TARGET_64BIT && TARGET_DLLIMPORT_DECL_ATTRIBUTES) + { + rtx tmp = legitimize_pe_coff_symbol (addr, true); + if (tmp) + return tmp; + } + if (TARGET_64BIT && legitimate_pic_address_disp_p (addr)) new_rtx = addr; - else if (TARGET_64BIT - && ix86_cmodel != CM_SMALL_PIC - && gotoff_operand (addr, Pmode)) + else if (TARGET_64BIT && DEFAULT_ABI != MS_ABI + && ix86_cmodel != CM_SMALL_PIC && gotoff_operand (addr, Pmode)) { rtx tmpreg; /* This symbol may be referenced via a displacement from the PIC @@ -12521,9 +12571,10 @@ legitimize_pic_address (rtx orig, rtx reg) tmpreg, 1, OPTAB_DIRECT); new_rtx = reg; } - else new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmpreg); + else + new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmpreg); } - else if (!TARGET_64BIT && gotoff_operand (addr, Pmode)) + else if (!TARGET_64BIT && DEFAULT_ABI != MS_ABI && gotoff_operand (addr, Pmode)) { /* This symbol may be referenced via a displacement from the PIC base address (@GOTOFF). */ @@ -12554,31 +12605,22 @@ legitimize_pic_address (rtx orig, rtx reg) see gotoff_operand. */ || (TARGET_VXWORKS_RTP && GET_CODE (addr) == LABEL_REF)) { - if (TARGET_DLLIMPORT_DECL_ATTRIBUTES) - { - if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (addr)) - return legitimize_dllimport_symbol (addr, true); - if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS - && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF - && SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (addr, 0), 0))) - { - rtx t = legitimize_dllimport_symbol (XEXP (XEXP (addr, 0), 0), true); - return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1)); - } - } + rtx tmp = legitimize_pe_coff_symbol (addr, true); + if (tmp) + return tmp; /* 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); + 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); @@ -12647,7 +12689,7 @@ legitimize_pic_address (rtx orig, rtx reg) /* Check first to see if this is a constant offset from a @GOTOFF symbol reference. */ - if (gotoff_operand (op0, Pmode) + if (DEFAULT_ABI != MS_ABI && gotoff_operand (op0, Pmode) && CONST_INT_P (op1)) { if (!TARGET_64BIT) @@ -12791,7 +12833,7 @@ legitimize_tls_address (rtx x, enum tls_model mode if (!TARGET_64BIT) { - if (flag_pic) + if (flag_pic && DEFAULT_ABI != MS_ABI) pic = pic_offset_table_rtx; else { @@ -13000,13 +13042,14 @@ legitimize_tls_address (rtx x, enum tls_model mode } /* Create or return the unique __imp_DECL dllimport symbol corresponding - to symbol DECL. */ + to symbol DECL if BEIMPORT is true. Otherwise create or return the + unique refptr-DECL symbol corresponding to symbol DECL. */ static GTY((if_marked ("tree_map_marked_p"), param_is (struct tree_map))) htab_t dllimport_map; static tree -get_dllimport_decl (tree decl) +get_dllimport_decl (tree decl, bool beimport) { struct tree_map *h, in; void **loc; @@ -13039,8 +13082,11 @@ static tree name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); name = targetm.strip_name_encoding (name); - prefix = name[0] == FASTCALL_PREFIX || user_label_prefix[0] == 0 - ? "*__imp_" : "*__imp__"; + if (beimport) + prefix = name[0] == FASTCALL_PREFIX || user_label_prefix[0] == 0 + ? "*__imp_" : "*__imp__"; + else + prefix = user_label_prefix[0] == 0 ? "*.refptr." : "*refptr."; namelen = strlen (name); prefixlen = strlen (prefix); imp_name = (char *) alloca (namelen + prefixlen + 1); @@ -13050,7 +13096,14 @@ static tree name = ggc_alloc_string (imp_name, namelen + prefixlen); rtl = gen_rtx_SYMBOL_REF (Pmode, name); SET_SYMBOL_REF_DECL (rtl, to); - SYMBOL_REF_FLAGS (rtl) = SYMBOL_FLAG_LOCAL; + SYMBOL_REF_FLAGS (rtl) = SYMBOL_FLAG_LOCAL | SYMBOL_FLAG_STUBVAR; + if (!beimport) + { + SYMBOL_REF_FLAGS (rtl) |= SYMBOL_FLAG_EXTERNAL; +#ifdef SUB_TARGET_RECORD_STUB + SUB_TARGET_RECORD_STUB (name); +#endif + } rtl = gen_const_mem (Pmode, rtl); set_mem_alias_set (rtl, ix86_GOT_alias_set ()); @@ -13061,6 +13114,24 @@ static tree return to; } +/* Expand SYMBOL into its corresponding far-addresse symbol. + WANT_REG is true if we require the result be a register. */ + +static rtx +legitimize_pe_coff_extern_decl (rtx symbol, bool want_reg) +{ + tree imp_decl; + rtx x; + + gcc_assert (SYMBOL_REF_DECL (symbol)); + imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), false); + + x = DECL_RTL (imp_decl); + if (want_reg) + x = force_reg (Pmode, x); + return x; +} + /* Expand SYMBOL into its corresponding dllimport symbol. WANT_REG is true if we require the result be a register. */ @@ -13071,7 +13142,7 @@ legitimize_dllimport_symbol (rtx symbol, bool want rtx x; gcc_assert (SYMBOL_REF_DECL (symbol)); - imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol)); + imp_decl = get_dllimport_decl (SYMBOL_REF_DECL (symbol), true); x = DECL_RTL (imp_decl); if (want_reg) @@ -13079,6 +13150,50 @@ legitimize_dllimport_symbol (rtx symbol, bool want return x; } +/* Expand SYMBOL into its corresponding dllimport or refptr symbol. WANT_REG + is true if we require the result be a register. */ + +static rtx +legitimize_pe_coff_symbol (rtx addr, bool inreg) +{ + if (DEFAULT_ABI != MS_ABI) + return NULL_RTX; + + if (TARGET_DLLIMPORT_DECL_ATTRIBUTES) + { + if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (addr)) + return legitimize_dllimport_symbol (addr, inreg); + if (GET_CODE (addr) == CONST + && GET_CODE (XEXP (addr, 0)) == PLUS + && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF + && SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (addr, 0), 0))) + { + rtx t = legitimize_dllimport_symbol (XEXP (XEXP (addr, 0), 0), inreg); + return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1)); + } + } + + if (ix86_cmodel != CM_LARGE_PIC && ix86_cmodel != CM_MEDIUM_PIC) + return NULL_RTX; + if (GET_CODE (addr) == SYMBOL_REF + && !is_imported_p (addr) + && SYMBOL_REF_EXTERNAL_P (addr) + && SYMBOL_REF_DECL (addr)) + return legitimize_pe_coff_extern_decl (addr, inreg); + + if (GET_CODE (addr) == CONST + && GET_CODE (XEXP (addr, 0)) == PLUS + && GET_CODE (XEXP (XEXP (addr, 0), 0)) == SYMBOL_REF + && !is_imported_p (XEXP (XEXP (addr, 0), 0)) + && SYMBOL_REF_EXTERNAL_P (XEXP (XEXP (addr, 0), 0)) + && SYMBOL_REF_DECL (XEXP (XEXP (addr, 0), 0))) + { + rtx t = legitimize_pe_coff_extern_decl (XEXP (XEXP (addr, 0), 0), inreg); + return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (addr, 0), 1)); + } + return NULL_RTX; +} + /* Try machine-dependent ways of modifying an illegitimate address to be legitimate. If we find one, return the new, valid address. This macro is used in only one place: `memory_address' in explow.c. @@ -13119,16 +13234,9 @@ ix86_legitimize_address (rtx x, rtx oldx ATTRIBUTE if (TARGET_DLLIMPORT_DECL_ATTRIBUTES) { - if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_DLLIMPORT_P (x)) - return legitimize_dllimport_symbol (x, true); - if (GET_CODE (x) == CONST - && GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF - && SYMBOL_REF_DLLIMPORT_P (XEXP (XEXP (x, 0), 0))) - { - rtx t = legitimize_dllimport_symbol (XEXP (XEXP (x, 0), 0), true); - return gen_rtx_PLUS (Pmode, t, XEXP (XEXP (x, 0), 1)); - } + rtx tmp = legitimize_pe_coff_symbol (x, true); + if (tmp) + return tmp; } if (flag_pic && SYMBOLIC_CONST (x)) @@ -15944,6 +16052,8 @@ ix86_expand_move (enum machine_mode mode, rtx oper if (GET_CODE (op1) == SYMBOL_REF) { + rtx tmp; + model = SYMBOL_REF_TLS_MODEL (op1); if (model) { @@ -15953,9 +16063,8 @@ ix86_expand_move (enum machine_mode mode, rtx oper return; op1 = convert_to_mode (mode, op1, 1); } - else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES - && SYMBOL_REF_DLLIMPORT_P (op1)) - op1 = legitimize_dllimport_symbol (op1, false); + else if ((tmp = legitimize_pe_coff_symbol (op1, false)) != NULL_RTX) + op1 = tmp; } else if (GET_CODE (op1) == CONST && GET_CODE (XEXP (op1, 0)) == PLUS @@ -15963,14 +16072,13 @@ ix86_expand_move (enum machine_mode mode, rtx oper { rtx addend = XEXP (XEXP (op1, 0), 1); rtx symbol = XEXP (XEXP (op1, 0), 0); - rtx tmp = NULL; + rtx tmp; model = SYMBOL_REF_TLS_MODEL (symbol); if (model) tmp = legitimize_tls_address (symbol, model, true); - else if (TARGET_DLLIMPORT_DECL_ATTRIBUTES - && SYMBOL_REF_DLLIMPORT_P (symbol)) - tmp = legitimize_dllimport_symbol (symbol, true); + else + tmp = legitimize_pe_coff_symbol (symbol, true); if (tmp) { @@ -23576,7 +23684,7 @@ construct_plt_address (rtx symbol) rtx tmp, unspec; gcc_assert (GET_CODE (symbol) == SYMBOL_REF); - gcc_assert (ix86_cmodel == CM_LARGE_PIC); + gcc_assert (ix86_cmodel == CM_LARGE_PIC && DEFAULT_ABI != MS_ABI); gcc_assert (Pmode == DImode); tmp = gen_reg_rtx (Pmode); @@ -23618,7 +23726,8 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx call else { /* Static functions and indirect calls don't need the pic register. */ - if (flag_pic && (!TARGET_64BIT || ix86_cmodel == CM_LARGE_PIC) + if (flag_pic && (!TARGET_64BIT + || (ix86_cmodel == CM_LARGE_PIC && DEFAULT_ABI != MS_ABI)) && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF && ! SYMBOL_REF_LOCAL_P (XEXP (fnaddr, 0))) use_reg (&use, pic_offset_table_rtx); @@ -23632,6 +23741,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx call } if (ix86_cmodel == CM_LARGE_PIC + && DEFAULT_ABI != MS_ABI && MEM_P (fnaddr) && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF && !local_symbolic_operand (XEXP (fnaddr, 0), VOIDmode)) @@ -34959,7 +35069,7 @@ x86_output_mi_thunk (FILE *file, if (TARGET_64BIT) { if (!flag_pic || targetm.binds_local_p (function) - || cfun->machine->call_abi == MS_ABI) + || DEFAULT_ABI == MS_ABI) ; else { Index: gcc/config/i386/i386.h =================================================================== --- gcc/config/i386/i386.h (Revision 196898) +++ gcc/config/i386/i386.h (Arbeitskopie) @@ -1179,7 +1179,8 @@ enum target_cpu_default #define REAL_PIC_OFFSET_TABLE_REGNUM BX_REG #define PIC_OFFSET_TABLE_REGNUM \ - ((TARGET_64BIT && ix86_cmodel == CM_SMALL_PIC) \ + ((TARGET_64BIT && (ix86_cmodel == CM_SMALL_PIC \ + || DEFAULT_ABI == MS_ABI)) \ || !flag_pic ? INVALID_REGNUM \ : reload_completed ? REGNO (pic_offset_table_rtx) \ : REAL_PIC_OFFSET_TABLE_REGNUM) @@ -2379,6 +2380,10 @@ struct GTY(()) machine_function { #define SYMBOL_REF_DLLEXPORT_P(X) \ ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_DLLEXPORT) != 0) +#define SYMBOL_FLAG_STUBVAR (SYMBOL_FLAG_MACH_DEP << 4) +#define SYMBOL_REF_STUBVAR_P(X) \ + ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_STUBVAR) != 0) + extern void debug_ready_dispatch (void); extern void debug_dispatch_window (int); Index: gcc/config/i386/winnt.c =================================================================== --- gcc/config/i386/winnt.c (Revision 196898) +++ gcc/config/i386/winnt.c (Arbeitskopie) @@ -554,6 +554,7 @@ i386_pe_asm_named_section (const char *name, unsig } } + /* Beware, DECL may be NULL if compile_file() is emitting the LTO marker. */ void @@ -646,8 +647,18 @@ struct GTY(()) export_list int is_data; /* used to type tag exported symbols. */ }; +/* Keep a list of stub symbols. */ + +struct GTY(()) stub_list +{ + struct stub_list *next; + const char *name; +}; + static GTY(()) struct export_list *export_head; +static GTY(()) struct stub_list *stub_head; + /* Assemble an export symbol entry. We need to keep a list of these, so that we can output the export list at the end of the assembly. We used to output these export symbols in each function, @@ -678,6 +689,30 @@ i386_pe_maybe_record_exported_symbol (tree decl, c export_head = p; } +void +i386_pe_record_stub (const char *name) +{ + struct stub_list *p; + + if (!name || *name == 0) + return; + + p = stub_head; + while (p != NULL) + { + if (p->name[0] == *name + && !strcmp (p->name, name)) + return; + p = p->next; + } + + p = ggc_alloc_stub_list (); + p->next = stub_head; + p->name = name; + stub_head = p; +} + + #ifdef CXX_WRAP_SPEC_LIST /* Hash table equality helper function. */ @@ -781,6 +819,30 @@ i386_pe_file_end (void) (q->is_data ? ",data" : "")); } } + + if (stub_head) + { + struct stub_list *q; + + for (q = stub_head; q != NULL; q = q->next) + { + const char *name = q->name; + const char *oname; + + if (name[0] == '*') + ++name; + oname = name; + if (name[0] == '.') + ++name; + if (strncmp (name, "refptr.", 7) != 0) + continue; + name += 7; + fprintf (asm_out_file, "\t.section\t.rdata$%s, \"dr\"\n" + "\t.globl\t%s\n" + "\t.linkonce\tdiscard\n", oname, oname); + fprintf (asm_out_file, "%s:\n\t.quad\t%s\n", oname, name); + } + } }