* 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:
yury 2009-05-13 10:07:44 +00:00
parent 4eef2b87a1
commit 92ad06f1e8
3 changed files with 73 additions and 21 deletions

View File

@ -1298,6 +1298,9 @@ implementation
begin
result:=(oper[opidx]^.typ=top_ref) 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
@ -2279,13 +2282,28 @@ implementation
2,4 :
begin
currsym:=objdata.symbolref(oper[opidx]^.ref^.symbol);
currval:=oper[opidx]^.ref^.offset;
{$ifdef x86_64}
if oper[opidx]^.ref^.refaddr=addr_pic then
currabsreloc:=RELOC_GOTPCREL
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}
currabsreloc:=RELOC_ABSOLUTE32;
objdata.writereloc(oper[opidx]^.ref^.offset,ea_data.bytes,currsym,currabsreloc);
currabsreloc:=RELOC_ABSOLUTE32;
objdata.writereloc(currval,ea_data.bytes,currsym,currabsreloc);
inc(s,ea_data.bytes);
end;
end;

View File

@ -381,29 +381,62 @@ unit cgx86;
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
reference_reset_symbol(href,ref.symbol,0,sizeof(pint));
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
if cs_create_pic in current_settings.moduleswitches then
begin
ref.index:=hreg;
ref.scalefactor:=1;
reference_reset_symbol(href,ref.symbol,0,sizeof(pint));
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
else
begin
list.concat(taicpu.op_reg_reg(A_ADD,S_Q,ref.base,hreg));
ref.base:=hreg;
end;
{ Always use RIP relative symbol addressing for Windows targets. }
if (target_info.system in system_all_windows) and (ref.base<>NR_RIP) then
begin
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;
{$else x86_64}
add_hreg:=false;

View File

@ -235,6 +235,7 @@ implementation
else
internalerror(200506081);
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))
end
else