mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-22 02:09:29 +02:00
* Always use RIP relative symbol addressing for x86_64 Windows targets. Bug #13657.
* Support for simple form of RIP relative addressing by x86_64 assembler writer. Example: movl rax,SomeSymbol(%rip) git-svn-id: trunk@13135 -
This commit is contained in:
parent
4eef2b87a1
commit
92ad06f1e8
@ -1298,6 +1298,9 @@ implementation
|
|||||||
begin
|
begin
|
||||||
result:=(oper[opidx]^.typ=top_ref) and
|
result:=(oper[opidx]^.typ=top_ref) and
|
||||||
(oper[opidx]^.ref^.refaddr=addr_no) and
|
(oper[opidx]^.ref^.refaddr=addr_no) and
|
||||||
|
{$ifdef x86_64}
|
||||||
|
(oper[opidx]^.ref^.base<>NR_RIP) and
|
||||||
|
{$endif x86_64}
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
(oper[opidx]^.ref^.index<>NR_NO) and
|
(oper[opidx]^.ref^.index<>NR_NO) and
|
||||||
@ -2279,13 +2282,28 @@ implementation
|
|||||||
2,4 :
|
2,4 :
|
||||||
begin
|
begin
|
||||||
currsym:=objdata.symbolref(oper[opidx]^.ref^.symbol);
|
currsym:=objdata.symbolref(oper[opidx]^.ref^.symbol);
|
||||||
|
currval:=oper[opidx]^.ref^.offset;
|
||||||
{$ifdef x86_64}
|
{$ifdef x86_64}
|
||||||
if oper[opidx]^.ref^.refaddr=addr_pic then
|
if oper[opidx]^.ref^.refaddr=addr_pic then
|
||||||
currabsreloc:=RELOC_GOTPCREL
|
currabsreloc:=RELOC_GOTPCREL
|
||||||
else
|
else
|
||||||
|
if oper[opidx]^.ref^.base=NR_RIP then
|
||||||
|
begin
|
||||||
|
currabsreloc:=RELOC_RELATIVE;
|
||||||
|
{ Adjust reloc value depending of immediate operand size }
|
||||||
|
case Ord(codes^) of
|
||||||
|
12,13,14,16,17,18,20,21,22:
|
||||||
|
Dec(currval, 1);
|
||||||
|
24,25,26:
|
||||||
|
Dec(currval, 2);
|
||||||
|
32,33,34:
|
||||||
|
Dec(currval, 4);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
{$endif x86_64}
|
{$endif x86_64}
|
||||||
currabsreloc:=RELOC_ABSOLUTE32;
|
currabsreloc:=RELOC_ABSOLUTE32;
|
||||||
objdata.writereloc(oper[opidx]^.ref^.offset,ea_data.bytes,currsym,currabsreloc);
|
objdata.writereloc(currval,ea_data.bytes,currsym,currabsreloc);
|
||||||
inc(s,ea_data.bytes);
|
inc(s,ea_data.bytes);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -381,29 +381,62 @@ unit cgx86;
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if (cs_create_pic in current_settings.moduleswitches) and
|
|
||||||
assigned(ref.symbol) and not((ref.symbol.bind=AB_LOCAL) and (ref.symbol.typ in [AT_LABEL,AT_FUNCTION])) then
|
if assigned(ref.symbol) and not((ref.symbol.bind=AB_LOCAL) and (ref.symbol.typ in [AT_LABEL,AT_FUNCTION])) then
|
||||||
begin
|
begin
|
||||||
reference_reset_symbol(href,ref.symbol,0,sizeof(pint));
|
if cs_create_pic in current_settings.moduleswitches then
|
||||||
hreg:=getaddressregister(list);
|
|
||||||
href.refaddr:=addr_pic;
|
|
||||||
href.base:=NR_RIP;
|
|
||||||
list.concat(taicpu.op_ref_reg(A_MOV,S_Q,href,hreg));
|
|
||||||
|
|
||||||
ref.symbol:=nil;
|
|
||||||
|
|
||||||
if ref.base=NR_NO then
|
|
||||||
ref.base:=hreg
|
|
||||||
else if ref.index=NR_NO then
|
|
||||||
begin
|
begin
|
||||||
ref.index:=hreg;
|
reference_reset_symbol(href,ref.symbol,0,sizeof(pint));
|
||||||
ref.scalefactor:=1;
|
hreg:=getaddressregister(list);
|
||||||
|
href.refaddr:=addr_pic;
|
||||||
|
href.base:=NR_RIP;
|
||||||
|
list.concat(taicpu.op_ref_reg(A_MOV,S_Q,href,hreg));
|
||||||
|
|
||||||
|
ref.symbol:=nil;
|
||||||
|
|
||||||
|
if ref.base=NR_NO then
|
||||||
|
ref.base:=hreg
|
||||||
|
else if ref.index=NR_NO then
|
||||||
|
begin
|
||||||
|
ref.index:=hreg;
|
||||||
|
ref.scalefactor:=1;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
list.concat(taicpu.op_reg_reg(A_ADD,S_Q,ref.base,hreg));
|
||||||
|
ref.base:=hreg;
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
{ Always use RIP relative symbol addressing for Windows targets. }
|
||||||
list.concat(taicpu.op_reg_reg(A_ADD,S_Q,ref.base,hreg));
|
if (target_info.system in system_all_windows) and (ref.base<>NR_RIP) then
|
||||||
ref.base:=hreg;
|
begin
|
||||||
end;
|
if (ref.refaddr=addr_no) and (ref.base=NR_NO) and (ref.index=NR_NO) then
|
||||||
|
{ Set RIP relative addressing for simple symbol references }
|
||||||
|
ref.base:=NR_RIP
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
{ Use temp register to load calculated 64-bit symbol address for complex references }
|
||||||
|
reference_reset_symbol(href,ref.symbol,0,sizeof(pint));
|
||||||
|
href.base:=NR_RIP;
|
||||||
|
hreg:=GetAddressRegister(list);
|
||||||
|
list.concat(taicpu.op_ref_reg(A_LEA,S_Q,href,hreg));
|
||||||
|
ref.symbol:=nil;
|
||||||
|
if ref.base=NR_NO then
|
||||||
|
ref.base:=hreg
|
||||||
|
else if ref.index=NR_NO then
|
||||||
|
begin
|
||||||
|
ref.index:=hreg;
|
||||||
|
ref.scalefactor:=0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
list.concat(taicpu.op_reg_reg(A_ADD,S_Q,ref.base,hreg));
|
||||||
|
ref.base:=hreg;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
{$else x86_64}
|
{$else x86_64}
|
||||||
add_hreg:=false;
|
add_hreg:=false;
|
||||||
|
@ -235,6 +235,7 @@ implementation
|
|||||||
else
|
else
|
||||||
internalerror(200506081);
|
internalerror(200506081);
|
||||||
end;
|
end;
|
||||||
|
tcgx86(cg).make_simple_ref(current_asmdata.CurrAsmList, href);
|
||||||
current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(A_ANDPS,S_XMM,href,location.register))
|
current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(A_ANDPS,S_XMM,href,location.register))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user