mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-23 09:12:04 +02:00
+ Compiler support for pic on darwin/i386. The i386 rtl still needs
to be made pic-safe (mainly accesses to the global default8087cw) * At the same time also made the non-pic code abi-compliant (access external data via indirect symbol pointers etc) Darwin/i386 also puts the got into a virtual register (like Darwin/ppc), a.o. because the register allocator fails to colour a routine in aasmcpu.pas if we take away ebx from it. git-svn-id: trunk@8657 -
This commit is contained in:
parent
4492ee39c5
commit
3266f4e483
@ -1135,6 +1135,16 @@ implementation
|
|||||||
result := '.section __TEXT, .fpc, regular, no_dead_strip';
|
result := '.section __TEXT, .fpc, regular, no_dead_strip';
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
sec_code:
|
||||||
|
begin
|
||||||
|
if (aname='fpc_geteipasebx') or
|
||||||
|
(aname='fpc_geteipasecx') then
|
||||||
|
begin
|
||||||
|
result:='.section __TEXT,__textcoal_nt,coalesced,pure_instructions'#10'.weak_definition '+aname+
|
||||||
|
#10'.private_extern '+aname;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
result := inherited sectionname(atype,aname,aorder);
|
result := inherited sectionname(atype,aname,aorder);
|
||||||
end;
|
end;
|
||||||
|
@ -83,7 +83,8 @@ unit cgcpu;
|
|||||||
procedure tcg386.init_register_allocators;
|
procedure tcg386.init_register_allocators;
|
||||||
begin
|
begin
|
||||||
inherited init_register_allocators;
|
inherited init_register_allocators;
|
||||||
if cs_create_pic in current_settings.moduleswitches then
|
if (target_info.system<>system_i386_darwin) and
|
||||||
|
(cs_create_pic in current_settings.moduleswitches) then
|
||||||
rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP])
|
rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP])
|
||||||
else
|
else
|
||||||
rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_EBX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP]);
|
rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_EBX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP]);
|
||||||
@ -493,13 +494,27 @@ unit cgcpu;
|
|||||||
(tf_pic_uses_got in target_info.flags) and
|
(tf_pic_uses_got in target_info.flags) and
|
||||||
(pi_needs_got in current_procinfo.flags) and
|
(pi_needs_got in current_procinfo.flags) and
|
||||||
not(po_kylixlocal in current_procinfo.procdef.procoptions) then
|
not(po_kylixlocal in current_procinfo.procdef.procoptions) then
|
||||||
|
begin
|
||||||
|
if (target_info.system<>system_i386_darwin) then
|
||||||
begin
|
begin
|
||||||
current_module.requires_ebx_pic_helper:=true;
|
current_module.requires_ebx_pic_helper:=true;
|
||||||
cg.a_call_name_static(list,'fpc_geteipasebx');
|
cg.a_call_name_static(list,'fpc_geteipasebx');
|
||||||
list.concat(taicpu.op_sym_ofs_reg(A_ADD,S_L,current_asmdata.RefAsmSymbol('_GLOBAL_OFFSET_TABLE_'),0,NR_PIC_OFFSET_REG));
|
list.concat(taicpu.op_sym_ofs_reg(A_ADD,S_L,current_asmdata.RefAsmSymbol('_GLOBAL_OFFSET_TABLE_'),0,NR_PIC_OFFSET_REG));
|
||||||
list.concat(tai_regalloc.alloc(NR_PIC_OFFSET_REG,nil));
|
list.concat(tai_regalloc.alloc(NR_PIC_OFFSET_REG,nil));
|
||||||
{ ecx could be used in leave procedures }
|
{ ecx could be used in leaf procedures }
|
||||||
current_procinfo.got:=NR_EBX;
|
current_procinfo.got:=NR_EBX;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
{ can't use ecx, since that one may overwrite a parameter }
|
||||||
|
current_module.requires_ebx_pic_helper:=true;
|
||||||
|
cg.a_call_name_static(list,'fpc_geteipasebx');
|
||||||
|
list.concat(tai_regalloc.alloc(NR_EBX,nil));
|
||||||
|
a_label(list,current_procinfo.CurrGotLabel);
|
||||||
|
{ got is already set by ti386procinfo.allocate_got_register }
|
||||||
|
list.concat(tai_regalloc.dealloc(NR_EBX,nil));
|
||||||
|
a_load_reg_reg(list,OS_ADDR,OS_ADDR,NR_EBX,current_procinfo.got);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ unit cpupi;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
psub,procinfo;
|
psub,procinfo,aasmdata;
|
||||||
|
|
||||||
type
|
type
|
||||||
ti386procinfo = class(tcgprocinfo)
|
ti386procinfo = class(tcgprocinfo)
|
||||||
@ -36,6 +36,7 @@ unit cpupi;
|
|||||||
procedure set_first_temp_offset;override;
|
procedure set_first_temp_offset;override;
|
||||||
function calc_stackframe_size:longint;override;
|
function calc_stackframe_size:longint;override;
|
||||||
procedure generate_parameter_info;override;
|
procedure generate_parameter_info;override;
|
||||||
|
procedure allocate_got_register(list: tasmlist);override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -43,8 +44,8 @@ unit cpupi;
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
cutils,
|
cutils,
|
||||||
systems,globals,
|
systems,globals,globtype,
|
||||||
tgobj,
|
cgobj,tgobj,
|
||||||
cpubase,
|
cpubase,
|
||||||
cgutils,
|
cgutils,
|
||||||
symconst;
|
symconst;
|
||||||
@ -88,6 +89,14 @@ unit cpupi;
|
|||||||
para_stack_size := 0;
|
para_stack_size := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure ti386procinfo.allocate_got_register(list: tasmlist);
|
||||||
|
begin
|
||||||
|
if (target_info.system = system_i386_darwin) and
|
||||||
|
(cs_create_pic in current_settings.moduleswitches) then
|
||||||
|
begin
|
||||||
|
got := cg.getaddressregister(list);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
cprocinfo:=ti386procinfo;
|
cprocinfo:=ti386procinfo;
|
||||||
|
@ -460,7 +460,7 @@ unit i_bsd;
|
|||||||
system : system_i386_darwin;
|
system : system_i386_darwin;
|
||||||
name : 'Darwin for i386';
|
name : 'Darwin for i386';
|
||||||
shortname : 'Darwin';
|
shortname : 'Darwin';
|
||||||
flags : [tf_p_ext_support,tf_files_case_aware,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels];
|
flags : [tf_p_ext_support,tf_files_case_aware,tf_smartlink_sections,tf_dwarf_relative_addresses,tf_dwarf_only_local_labels,tf_pic_uses_got];
|
||||||
cpu : cpu_i386;
|
cpu : cpu_i386;
|
||||||
unit_env : 'BSDUNITS';
|
unit_env : 'BSDUNITS';
|
||||||
extradefines : 'UNIX;BSD;HASUNIX';
|
extradefines : 'UNIX;BSD;HASUNIX';
|
||||||
|
@ -113,6 +113,8 @@ interface
|
|||||||
owner.AsmWrite(gas_regname(segment)+':');
|
owner.AsmWrite(gas_regname(segment)+':');
|
||||||
if assigned(symbol) then
|
if assigned(symbol) then
|
||||||
owner.AsmWrite(symbol.name);
|
owner.AsmWrite(symbol.name);
|
||||||
|
if assigned(relsymbol) then
|
||||||
|
owner.AsmWrite('-'+relsymbol.name);
|
||||||
if ref.refaddr=addr_pic then
|
if ref.refaddr=addr_pic then
|
||||||
{$ifdef x86_64}
|
{$ifdef x86_64}
|
||||||
owner.AsmWrite('@GOTPCREL');
|
owner.AsmWrite('@GOTPCREL');
|
||||||
|
@ -347,6 +347,9 @@ unit cgx86;
|
|||||||
var
|
var
|
||||||
hreg : tregister;
|
hreg : tregister;
|
||||||
href : treference;
|
href : treference;
|
||||||
|
{$ifndef x86_64}
|
||||||
|
add_hreg: boolean;
|
||||||
|
{$endif not x86_64}
|
||||||
begin
|
begin
|
||||||
{$ifdef x86_64}
|
{$ifdef x86_64}
|
||||||
{ Only 32bit is allowed }
|
{ Only 32bit is allowed }
|
||||||
@ -403,18 +406,45 @@ unit cgx86;
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
{$else x86_64}
|
{$else x86_64}
|
||||||
if (cs_create_pic in current_settings.moduleswitches) and
|
add_hreg:=false;
|
||||||
assigned(ref.symbol) and not((ref.symbol.bind=AB_LOCAL) and (ref.symbol.typ in [AT_LABEL,AT_FUNCTION])) then
|
if (target_info.system=system_i386_darwin) then
|
||||||
|
begin
|
||||||
|
if assigned(ref.symbol) and
|
||||||
|
not(assigned(ref.relsymbol)) and
|
||||||
|
((ref.symbol.bind = AB_EXTERNAL) or
|
||||||
|
(cs_create_pic in current_settings.moduleswitches)) then
|
||||||
|
begin
|
||||||
|
if (ref.symbol.bind = AB_EXTERNAL) or
|
||||||
|
((cs_create_pic in current_settings.moduleswitches) and
|
||||||
|
(ref.symbol.bind in [AB_COMMON,AB_GLOBAL])) then
|
||||||
|
begin
|
||||||
|
hreg:=g_indirect_sym_load(list,ref.symbol.name);
|
||||||
|
ref.symbol:=nil;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
include(current_procinfo.flags,pi_needs_got);
|
||||||
|
hreg:=current_procinfo.got;
|
||||||
|
ref.relsymbol:=current_procinfo.CurrGOTLabel;
|
||||||
|
end;
|
||||||
|
add_hreg:=true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else 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
|
||||||
begin
|
begin
|
||||||
reference_reset_symbol(href,ref.symbol,0);
|
|
||||||
hreg:=getaddressregister(list);
|
|
||||||
href.refaddr:=addr_pic;
|
href.refaddr:=addr_pic;
|
||||||
href.base:=current_procinfo.got;
|
href.base:=current_procinfo.got;
|
||||||
include(current_procinfo.flags,pi_needs_got);
|
include(current_procinfo.flags,pi_needs_got);
|
||||||
list.concat(taicpu.op_ref_reg(A_MOV,S_L,href,hreg));
|
list.concat(taicpu.op_ref_reg(A_MOV,S_L,href,hreg));
|
||||||
|
|
||||||
ref.symbol:=nil;
|
ref.symbol:=nil;
|
||||||
|
add_hreg:=true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if add_hreg then
|
||||||
|
begin
|
||||||
if ref.base=NR_NO then
|
if ref.base=NR_NO then
|
||||||
ref.base:=hreg
|
ref.base:=hreg
|
||||||
else if ref.index=NR_NO then
|
else if ref.index=NR_NO then
|
||||||
@ -770,7 +800,29 @@ unit cgx86;
|
|||||||
begin
|
begin
|
||||||
if assigned(ref.symbol) then
|
if assigned(ref.symbol) then
|
||||||
begin
|
begin
|
||||||
if (cs_create_pic in current_settings.moduleswitches) then
|
if (target_info.system=system_i386_darwin) and
|
||||||
|
((ref.symbol.bind = AB_EXTERNAL) or
|
||||||
|
(cs_create_pic in current_settings.moduleswitches)) then
|
||||||
|
begin
|
||||||
|
if (ref.symbol.bind = AB_EXTERNAL) or
|
||||||
|
((cs_create_pic in current_settings.moduleswitches) and
|
||||||
|
(ref.symbol.bind in [AB_COMMON,AB_GLOBAL])) then
|
||||||
|
begin
|
||||||
|
reference_reset_base(tmpref,
|
||||||
|
g_indirect_sym_load(list,ref.symbol.name),
|
||||||
|
offset);
|
||||||
|
a_loadaddr_ref_reg(list,tmpref,r);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
include(current_procinfo.flags,pi_needs_got);
|
||||||
|
reference_reset_base(tmpref,current_procinfo.got,offset);
|
||||||
|
tmpref.symbol:=symbol;
|
||||||
|
tmpref.relsymbol:=current_procinfo.CurrGOTLabel;
|
||||||
|
list.concat(Taicpu.op_ref_reg(A_LEA,tcgsize2opsize[OS_ADDR],tmpref,r));
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else if (cs_create_pic in current_settings.moduleswitches) then
|
||||||
begin
|
begin
|
||||||
{$ifdef x86_64}
|
{$ifdef x86_64}
|
||||||
reference_reset_symbol(tmpref,ref.symbol,0);
|
reference_reset_symbol(tmpref,ref.symbol,0);
|
||||||
@ -1996,7 +2048,13 @@ unit cgx86;
|
|||||||
got loaded
|
got loaded
|
||||||
}
|
}
|
||||||
g_maybe_got_init(list);
|
g_maybe_got_init(list);
|
||||||
ref.refaddr:=addr_pic;
|
if (target_info.system<>system_i386_darwin) then
|
||||||
|
ref.refaddr:=addr_pic
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
ref.refaddr:=addr_no;
|
||||||
|
ref.relsymbol:=current_procinfo.CurrGOTLabel;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
ref.refaddr:=addr_full;
|
ref.refaddr:=addr_full;
|
||||||
|
Loading…
Reference in New Issue
Block a user