Index: winnt.c =================================================================== --- winnt.c (revision 166301) +++ winnt.c (working copy) @@ -326,10 +326,7 @@ /* 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; } Index: i386.c =================================================================== --- i386.c (revision 166301) +++ i386.c (working copy) @@ -12127,7 +12127,19 @@ } } - 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_GOTPCREL); + 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); @@ -12837,8 +12849,12 @@ fputs ("@PLTOFF", file); break; case UNSPEC_GOTPCREL: - fputs (ASSEMBLER_DIALECT == ASM_ATT ? - "@GOTPCREL(%rip)" : "@GOTPCREL[rip]", file); + if (DEFAULT_ABI != MS_ABI) + fputs (ASSEMBLER_DIALECT == ASM_ATT ? + "@GOTPCREL(%rip)" : "@GOTPCREL[rip]", file); + else + fputs (ASSEMBLER_DIALECT == ASM_ATT ? + "(%rip)" : "[rip]", file); break; case UNSPEC_GOTTPOFF: /* FIXME: This might be @TPOFF in Sun ld too. */ @@ -29106,7 +29122,8 @@ 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. */