* 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;
paraloc1 : tcgpara;
begin
{ we don't know the size of all arrays }
newsize:=def_cgsize(resultdef);
location_reset(location,LOC_REFERENCE,newsize);
case symtableentry.typ of
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:
{ we don't know the size of all arrays }
newsize:=def_cgsize(resultdef);
location_reset(location,LOC_REFERENCE,newsize);
case symtableentry.typ of
absolutevarsym :
begin
if tconstsym(symtableentry).consttyp=constresourcestring then
begin
location_reset(location,LOC_CREFERENCE,OS_ADDR);
location.reference.symbol:=current_asmdata.RefAsmSymbol(make_mangledname('RESSTR',symtableentry.owner,symtableentry.name));
{ Resourcestring layout:
TResourceStringRecord = Packed Record
Name,
CurrentValue,
DefaultValue : AnsiString;
HashValue : LongWord;
end;
}
location.reference.offset:=sizeof(pint);
end
else
internalerror(22798);
{ 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;
staticvarsym :
begin
gvs:=tstaticvarsym(symtableentry);
if ([vo_is_dll_var,vo_is_external] * gvs.varoptions <> []) then
constsym:
begin
if tconstsym(symtableentry).consttyp=constresourcestring 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;
location_reset(location,LOC_CREFERENCE,OS_ADDR);
location.reference.symbol:=current_asmdata.RefAsmSymbol(make_mangledname('RESSTR',symtableentry.owner,symtableentry.name));
{ Resourcestring layout:
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;
if (vo_is_dll_var in gvs.varoptions) then
{ DLL variable }
{ 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
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);
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
{ Thread variable }
else if (vo_is_thread_var in gvs.varoptions) and
not(tf_section_threadvars in target_info.flags) then
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 (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
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}
{ 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
{
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);
{ load address of the function }
reference_reset_symbol(href,current_asmdata.RefAsmSymbol(procdef.mangledname),0);
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;
cg.a_load_reg_ref(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,hregister,location.reference);
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;
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;
{ 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;
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
{ 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;
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;