+2010-11-05 Kai Tietz <kai.tietz@onevision.com>
+
+ * 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 <jakub@redhat.com>
PR target/45670
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;
return false;
case UNSPEC_GOTPCREL:
+ case UNSPEC_PCREL:
gcc_assert (flag_pic);
goto is_legitimate_pic;
}
}
- 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);
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);
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);
|| 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);
|| 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;
}
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. */