* formatting fix

git-svn-id: trunk@12435 -
This commit is contained in:
florian 2008-12-24 16:17:35 +00:00
parent 23bbb087bd
commit e512367dbd

View File

@ -223,299 +223,298 @@ implementation
norelocatelab : tasmlabel; norelocatelab : tasmlabel;
paraloc1 : tcgpara; paraloc1 : tcgpara;
begin begin
{ we don't know the size of all arrays }
{ we don't know the size of all arrays } newsize:=def_cgsize(resultdef);
newsize:=def_cgsize(resultdef); location_reset(location,LOC_REFERENCE,newsize);
location_reset(location,LOC_REFERENCE,newsize); case symtableentry.typ of
case symtableentry.typ of absolutevarsym :
absolutevarsym :
begin
{ this is only for toasm and toaddr }
case tabsolutevarsym(symtableentry).abstyp of
toaddr :
begin
{$ifdef i386}
if tabsolutevarsym(symtableentry).absseg then
location.reference.segment:=NR_FS;
{$endif i386}
location.reference.offset:=tabsolutevarsym(symtableentry).addroffset;
end;
toasm :
location.reference.symbol:=current_asmdata.RefAsmSymbol(tabsolutevarsym(symtableentry).mangledname);
else
internalerror(200310283);
end;
end;
constsym:
begin begin
if tconstsym(symtableentry).consttyp=constresourcestring then { this is only for toasm and toaddr }
begin case tabsolutevarsym(symtableentry).abstyp of
location_reset(location,LOC_CREFERENCE,OS_ADDR); toaddr :
location.reference.symbol:=current_asmdata.RefAsmSymbol(make_mangledname('RESSTR',symtableentry.owner,symtableentry.name)); begin
{ Resourcestring layout: {$ifdef i386}
TResourceStringRecord = Packed Record if tabsolutevarsym(symtableentry).absseg then
Name, location.reference.segment:=NR_FS;
CurrentValue, {$endif i386}
DefaultValue : AnsiString; location.reference.offset:=tabsolutevarsym(symtableentry).addroffset;
HashValue : LongWord; end;
end; toasm :
} location.reference.symbol:=current_asmdata.RefAsmSymbol(tabsolutevarsym(symtableentry).mangledname);
location.reference.offset:=sizeof(pint); else
end internalerror(200310283);
else end;
internalerror(22798);
end; end;
staticvarsym : constsym:
begin begin
gvs:=tstaticvarsym(symtableentry); if tconstsym(symtableentry).consttyp=constresourcestring then
if ([vo_is_dll_var,vo_is_external] * gvs.varoptions <> []) then
begin begin
location.reference.base := cg.g_indirect_sym_load(current_asmdata.CurrAsmList,tstaticvarsym(symtableentry).mangledname, location_reset(location,LOC_CREFERENCE,OS_ADDR);
vo_is_weak_external in gvs.varoptions); location.reference.symbol:=current_asmdata.RefAsmSymbol(make_mangledname('RESSTR',symtableentry.owner,symtableentry.name));
if (location.reference.base <> NR_NO) then { Resourcestring layout:
exit; TResourceStringRecord = Packed Record
Name,
CurrentValue,
DefaultValue : AnsiString;
HashValue : LongWord;
end;
}
location.reference.offset:=sizeof(pint);
end
else
internalerror(22798);
end;
staticvarsym :
begin
gvs:=tstaticvarsym(symtableentry);
if ([vo_is_dll_var,vo_is_external] * gvs.varoptions <> []) then
begin
location.reference.base := cg.g_indirect_sym_load(current_asmdata.CurrAsmList,tstaticvarsym(symtableentry).mangledname,
vo_is_weak_external in gvs.varoptions);
if (location.reference.base <> NR_NO) then
exit;
end;
if (vo_is_dll_var in gvs.varoptions) then
{ DLL variable }
begin
hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
if not(vo_is_weak_external in gvs.varoptions) then
location.reference.symbol:=current_asmdata.RefAsmSymbol(tstaticvarsym(symtableentry).mangledname)
else
location.reference.symbol:=current_asmdata.WeakRefAsmSymbol(tstaticvarsym(symtableentry).mangledname);
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,location.reference,hregister);
reference_reset_base(location.reference,hregister,0);
end
{ Thread variable }
else if (vo_is_thread_var in gvs.varoptions) and
not(tf_section_threadvars in target_info.flags) then
begin
if (tf_section_threadvars in target_info.flags) then
begin
if gvs.localloc.loc=LOC_INVALID then
if not(vo_is_weak_external in gvs.varoptions) then
reference_reset_symbol(location.reference,current_asmdata.RefAsmSymbol(gvs.mangledname),0)
else
reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0)
else
location:=gvs.localloc;
{$ifdef i386}
case target_info.system of
system_i386_linux:
location.reference.segment:=NR_GS;
system_i386_win32:
location.reference.segment:=NR_FS;
end;
{$endif i386}
end
else
begin
{
Thread var loading is optimized to first check if
a relocate function is available. When the function
is available it is called to retrieve the address.
Otherwise the address is loaded with the symbol
The code needs to be in the order to first handle the
call and then the address load to be sure that the
register that is used for returning is the same (PFV)
}
current_asmdata.getjumplabel(norelocatelab);
current_asmdata.getjumplabel(endrelocatelab);
{ make sure hregister can't allocate the register necessary for the parameter }
paraloc1.init;
paramanager.getintparaloc(pocall_default,1,paraloc1);
hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
reference_reset_symbol(href,current_asmdata.RefAsmSymbol('FPC_THREADVAR_RELOCATE'),0);
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,hregister);
cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,OS_ADDR,OC_EQ,0,hregister,norelocatelab);
{ don't save the allocated register else the result will be destroyed later }
if not(vo_is_weak_external in gvs.varoptions) then
reference_reset_symbol(href,current_asmdata.RefAsmSymbol(gvs.mangledname),0)
else
reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0);
paramanager.allocparaloc(current_asmdata.CurrAsmList,paraloc1);
cg.a_param_ref(current_asmdata.CurrAsmList,OS_32,href,paraloc1);
paramanager.freeparaloc(current_asmdata.CurrAsmList,paraloc1);
paraloc1.done;
cg.allocallcpuregisters(current_asmdata.CurrAsmList);
cg.a_call_reg(current_asmdata.CurrAsmList,hregister);
cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
cg.getcpuregister(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_ADDR,NR_FUNCTION_RESULT_REG,hregister);
cg.a_jmp_always(current_asmdata.CurrAsmList,endrelocatelab);
cg.a_label(current_asmdata.CurrAsmList,norelocatelab);
{ no relocation needed, load the address of the variable only, the
layout of a threadvar is (4 bytes pointer):
0 - Threadvar index
4 - Threadvar value in single threading }
if not(vo_is_weak_external in gvs.varoptions) then
reference_reset_symbol(href,current_asmdata.RefAsmSymbol(gvs.mangledname),sizeof(pint))
else
reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),sizeof(pint));
cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,href,hregister);
cg.a_label(current_asmdata.CurrAsmList,endrelocatelab);
location.reference.base:=hregister;
end;
end
{ Normal (or external) variable }
else
begin
if gvs.localloc.loc=LOC_INVALID then
if not(vo_is_weak_external in gvs.varoptions) then
reference_reset_symbol(location.reference,current_asmdata.RefAsmSymbol(gvs.mangledname),0)
else
reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0)
else
location:=gvs.localloc;
end; end;
if (vo_is_dll_var in gvs.varoptions) then { make const a LOC_CREFERENCE }
{ DLL variable } if (gvs.varspez=vs_const) and
(location.loc=LOC_REFERENCE) then
location.loc:=LOC_CREFERENCE;
location.reference.alignment:=gvs.vardef.alignment;
end;
paravarsym,
localvarsym :
begin
vs:=tabstractnormalvarsym(symtableentry);
{ Nested variable }
if assigned(left) then
begin begin
hregister:=cg.getaddressregister(current_asmdata.CurrAsmList); secondpass(left);
if not(vo_is_weak_external in gvs.varoptions) then if left.location.loc<>LOC_REGISTER then
location.reference.symbol:=current_asmdata.RefAsmSymbol(tstaticvarsym(symtableentry).mangledname) internalerror(200309286);
else if vs.localloc.loc<>LOC_REFERENCE then
location.reference.symbol:=current_asmdata.WeakRefAsmSymbol(tstaticvarsym(symtableentry).mangledname); internalerror(200409241);
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,location.reference,hregister); reference_reset_base(location.reference,left.location.register,vs.localloc.reference.offset);
reference_reset_base(location.reference,hregister,0);
end end
{ Thread variable } else
else if (vo_is_thread_var in gvs.varoptions) and location:=vs.localloc;
not(tf_section_threadvars in target_info.flags) then
{ handle call by reference variables when they are not
alreayd copied to local copies. Also ignore the reference
when we need to load the self pointer for objects }
if is_addr_param_load then
begin begin
if (tf_section_threadvars in target_info.flags) then if (location.loc in [LOC_CREGISTER,LOC_REGISTER]) then
hregister:=location.register
else
begin
hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
{ we need to load only an address }
location.size:=OS_ADDR;
cg.a_load_loc_reg(current_asmdata.CurrAsmList,location.size,location,hregister);
end;
location_reset(location,LOC_REFERENCE,newsize);
location.reference.base:=hregister;
end;
{ make const a LOC_CREFERENCE }
if (vs.varspez=vs_const) and
(location.loc=LOC_REFERENCE) then
location.loc:=LOC_CREFERENCE;
end;
procsym:
begin
if not assigned(procdef) then
internalerror(200312011);
if assigned(left) then
begin
{$if sizeof(pint) = 4}
location_reset(location,LOC_CREFERENCE,OS_64);
{$else} {$if sizeof(pint) = 8}
location_reset(location,LOC_CREFERENCE,OS_128);
{$else}
internalerror(20020520);
{$endif} {$endif}
tg.GetTemp(current_asmdata.CurrAsmList,2*sizeof(pint),sizeof(pint),tt_normal,location.reference);
secondpass(left);
{ load class instance/classrefdef address }
if left.location.loc=LOC_CONSTANT then
location_force_reg(current_asmdata.CurrAsmList,left.location,OS_ADDR,false);
case left.location.loc of
LOC_CREGISTER,
LOC_REGISTER:
begin
{ this is not possible for objects }
if is_object(left.resultdef) then
internalerror(200304234);
hregister:=left.location.register;
end;
LOC_CREFERENCE,
LOC_REFERENCE:
begin
hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
if not is_object(left.resultdef) then
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,left.location.reference,hregister)
else
cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.location.reference,hregister);
location_freetemp(current_asmdata.CurrAsmList,left.location);
end;
else
internalerror(200610311);
end;
{ store the class instance or classredef address }
href:=location.reference;
inc(href.offset,sizeof(pint));
cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,hregister,href);
{ virtual method ? }
if (po_virtualmethod in procdef.procoptions) and
not(nf_inherited in flags) then
begin begin
if gvs.localloc.loc=LOC_INVALID then { a classrefdef already points to the VMT }
if not(vo_is_weak_external in gvs.varoptions) then if (left.resultdef.typ<>classrefdef) then
reference_reset_symbol(location.reference,current_asmdata.RefAsmSymbol(gvs.mangledname),0) begin
else { load vmt pointer }
reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0) reference_reset_base(href,hregister,0);
else hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
location:=gvs.localloc; cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,hregister);
{$ifdef i386} end;
case target_info.system of { load method address }
system_i386_linux: reference_reset_base(href,hregister,procdef._class.vmtmethodoffset(procdef.extnumber));
location.reference.segment:=NR_GS; hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
system_i386_win32: cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,hregister);
location.reference.segment:=NR_FS; { ... and store it }
end; cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,hregister,location.reference);
{$endif i386}
end end
else else
begin begin
{ { load address of the function }
Thread var loading is optimized to first check if reference_reset_symbol(href,current_asmdata.RefAsmSymbol(procdef.mangledname),0);
a relocate function is available. When the function
is available it is called to retrieve the address.
Otherwise the address is loaded with the symbol
The code needs to be in the order to first handle the
call and then the address load to be sure that the
register that is used for returning is the same (PFV)
}
current_asmdata.getjumplabel(norelocatelab);
current_asmdata.getjumplabel(endrelocatelab);
{ make sure hregister can't allocate the register necessary for the parameter }
paraloc1.init;
paramanager.getintparaloc(pocall_default,1,paraloc1);
hregister:=cg.getaddressregister(current_asmdata.CurrAsmList); hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
reference_reset_symbol(href,current_asmdata.RefAsmSymbol('FPC_THREADVAR_RELOCATE'),0);
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,hregister);
cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,OS_ADDR,OC_EQ,0,hregister,norelocatelab);
{ don't save the allocated register else the result will be destroyed later }
if not(vo_is_weak_external in gvs.varoptions) then
reference_reset_symbol(href,current_asmdata.RefAsmSymbol(gvs.mangledname),0)
else
reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0);
paramanager.allocparaloc(current_asmdata.CurrAsmList,paraloc1);
cg.a_param_ref(current_asmdata.CurrAsmList,OS_32,href,paraloc1);
paramanager.freeparaloc(current_asmdata.CurrAsmList,paraloc1);
paraloc1.done;
cg.allocallcpuregisters(current_asmdata.CurrAsmList);
cg.a_call_reg(current_asmdata.CurrAsmList,hregister);
cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
cg.getcpuregister(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_ADDR,NR_FUNCTION_RESULT_REG,hregister);
cg.a_jmp_always(current_asmdata.CurrAsmList,endrelocatelab);
cg.a_label(current_asmdata.CurrAsmList,norelocatelab);
{ no relocation needed, load the address of the variable only, the
layout of a threadvar is (4 bytes pointer):
0 - Threadvar index
4 - Threadvar value in single threading }
if not(vo_is_weak_external in gvs.varoptions) then
reference_reset_symbol(href,current_asmdata.RefAsmSymbol(gvs.mangledname),sizeof(pint))
else
reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),sizeof(pint));
cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,href,hregister); cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,href,hregister);
cg.a_label(current_asmdata.CurrAsmList,endrelocatelab); cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,hregister,location.reference);
location.reference.base:=hregister;
end; end;
end end
{ Normal (or external) variable }
else else
begin begin
if gvs.localloc.loc=LOC_INVALID then pd:=tprocdef(tprocsym(symtableentry).ProcdefList[0]);
if not(vo_is_weak_external in gvs.varoptions) then if (po_external in pd.procoptions) then
reference_reset_symbol(location.reference,current_asmdata.RefAsmSymbol(gvs.mangledname),0) location.reference.base :=
else cg.g_indirect_sym_load(current_asmdata.CurrAsmList,pd.mangledname,
reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0) po_weakexternal in pd.procoptions);
else {!!!!! Be aware, work on virtual methods too }
location:=gvs.localloc; if (location.reference.base = NR_NO) then
if not(po_weakexternal in pd.procoptions) then
location.reference.symbol:=current_asmdata.RefAsmSymbol(procdef.mangledname)
else
location.reference.symbol:=current_asmdata.WeakRefAsmSymbol(procdef.mangledname);
end; end;
{ make const a LOC_CREFERENCE }
if (gvs.varspez=vs_const) and
(location.loc=LOC_REFERENCE) then
location.loc:=LOC_CREFERENCE;
location.reference.alignment:=gvs.vardef.alignment;
end;
paravarsym,
localvarsym :
begin
vs:=tabstractnormalvarsym(symtableentry);
{ Nested variable }
if assigned(left) then
begin
secondpass(left);
if left.location.loc<>LOC_REGISTER then
internalerror(200309286);
if vs.localloc.loc<>LOC_REFERENCE then
internalerror(200409241);
reference_reset_base(location.reference,left.location.register,vs.localloc.reference.offset);
end
else
location:=vs.localloc;
{ handle call by reference variables when they are not
alreayd copied to local copies. Also ignore the reference
when we need to load the self pointer for objects }
if is_addr_param_load then
begin
if (location.loc in [LOC_CREGISTER,LOC_REGISTER]) then
hregister:=location.register
else
begin
hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
{ we need to load only an address }
location.size:=OS_ADDR;
cg.a_load_loc_reg(current_asmdata.CurrAsmList,location.size,location,hregister);
end;
location_reset(location,LOC_REFERENCE,newsize);
location.reference.base:=hregister;
end;
{ make const a LOC_CREFERENCE }
if (vs.varspez=vs_const) and
(location.loc=LOC_REFERENCE) then
location.loc:=LOC_CREFERENCE;
end; end;
procsym: labelsym :
begin if assigned(tlabelsym(symtableentry).asmblocklabel) then
if not assigned(procdef) then location.reference.symbol:=tlabelsym(symtableentry).asmblocklabel
internalerror(200312011); else
if assigned(left) then location.reference.symbol:=tcglabelnode((tlabelsym(symtableentry).code)).getasmlabel;
begin else internalerror(200510032);
{$if sizeof(pint) = 4} end;
location_reset(location,LOC_CREFERENCE,OS_64);
{$else} {$if sizeof(pint) = 8}
location_reset(location,LOC_CREFERENCE,OS_128);
{$else}
internalerror(20020520);
{$endif} {$endif}
tg.GetTemp(current_asmdata.CurrAsmList,2*sizeof(pint),sizeof(pint),tt_normal,location.reference);
secondpass(left);
{ load class instance/classrefdef address }
if left.location.loc=LOC_CONSTANT then
location_force_reg(current_asmdata.CurrAsmList,left.location,OS_ADDR,false);
case left.location.loc of
LOC_CREGISTER,
LOC_REGISTER:
begin
{ this is not possible for objects }
if is_object(left.resultdef) then
internalerror(200304234);
hregister:=left.location.register;
end;
LOC_CREFERENCE,
LOC_REFERENCE:
begin
hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
if not is_object(left.resultdef) then
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,left.location.reference,hregister)
else
cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,left.location.reference,hregister);
location_freetemp(current_asmdata.CurrAsmList,left.location);
end;
else
internalerror(200610311);
end;
{ store the class instance or classredef address }
href:=location.reference;
inc(href.offset,sizeof(pint));
cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,hregister,href);
{ virtual method ? }
if (po_virtualmethod in procdef.procoptions) and
not(nf_inherited in flags) then
begin
{ a classrefdef already points to the VMT }
if (left.resultdef.typ<>classrefdef) then
begin
{ load vmt pointer }
reference_reset_base(href,hregister,0);
hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,hregister);
end;
{ load method address }
reference_reset_base(href,hregister,procdef._class.vmtmethodoffset(procdef.extnumber));
hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,hregister);
{ ... and store it }
cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,hregister,location.reference);
end
else
begin
{ load address of the function }
reference_reset_symbol(href,current_asmdata.RefAsmSymbol(procdef.mangledname),0);
hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
cg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,href,hregister);
cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,hregister,location.reference);
end;
end
else
begin
pd:=tprocdef(tprocsym(symtableentry).ProcdefList[0]);
if (po_external in pd.procoptions) then
location.reference.base :=
cg.g_indirect_sym_load(current_asmdata.CurrAsmList,pd.mangledname,
po_weakexternal in pd.procoptions);
{!!!!! Be aware, work on virtual methods too }
if (location.reference.base = NR_NO) then
if not(po_weakexternal in pd.procoptions) then
location.reference.symbol:=current_asmdata.RefAsmSymbol(procdef.mangledname)
else
location.reference.symbol:=current_asmdata.WeakRefAsmSymbol(procdef.mangledname);
end;
end;
labelsym :
if assigned(tlabelsym(symtableentry).asmblocklabel) then
location.reference.symbol:=tlabelsym(symtableentry).asmblocklabel
else
location.reference.symbol:=tcglabelnode((tlabelsym(symtableentry).code)).getasmlabel;
else internalerror(200510032);
end;
end; end;