diff --git a/compiler/ncgbas.pas b/compiler/ncgbas.pas index 0f61722e31..cdcae4feb6 100644 --- a/compiler/ncgbas.pas +++ b/compiler/ncgbas.pas @@ -26,6 +26,8 @@ unit ncgbas; interface uses + globtype, + aasmtai,aasmdata, cpubase,cgutils, node,nbas; @@ -35,6 +37,9 @@ interface end; tcgasmnode = class(tasmnode) + protected + procedure ResolveRef(const filepos: tfileposinfo; var op:toper); virtual; + public procedure pass_generate_code;override; end; @@ -66,9 +71,9 @@ interface implementation uses - globtype,globals,systems, + globals,systems, cutils,verbose, - aasmbase,aasmtai,aasmdata,aasmcpu, + aasmbase,aasmcpu, symsym,symconst,symdef,defutil, nflw,pass_2,ncgutil, cgbase,cgobj,hlcgobj, @@ -117,6 +122,117 @@ interface TASMNODE *****************************************************************************} + + procedure tcgasmnode.ResolveRef(const filepos: tfileposinfo; var op:toper); + var + sym : tabstractnormalvarsym; +{$ifdef x86} + scale : byte; +{$endif x86} + forceref, + getoffset : boolean; + indexreg : tregister; + sofs : longint; + begin + if (op.typ=top_local) then + begin + sofs:=op.localoper^.localsymofs; + indexreg:=op.localoper^.localindexreg; +{$ifdef x86} + scale:=op.localoper^.localscale; +{$endif x86} + getoffset:=op.localoper^.localgetoffset; + forceref:=op.localoper^.localforceref; + sym:=tabstractnormalvarsym(pointer(op.localoper^.localsym)); + dispose(op.localoper); + case sym.localloc.loc of + LOC_REFERENCE : + begin + if getoffset then + begin + if indexreg=NR_NO then + begin + op.typ:=top_const; + op.val:=sym.localloc.reference.offset+sofs; + end + else + begin + op.typ:=top_ref; + new(op.ref); + reference_reset_base(op.ref^,indexreg,sym.localloc.reference.offset+sofs, + newalignment(sym.localloc.reference.alignment,sofs)); + end; + end + else + begin + op.typ:=top_ref; + new(op.ref); + reference_reset_base(op.ref^,sym.localloc.reference.base,sym.localloc.reference.offset+sofs, + newalignment(sym.localloc.reference.alignment,sofs)); + op.ref^.index:=indexreg; +{$ifdef x86} + op.ref^.scalefactor:=scale; +{$endif x86} + end; + end; + LOC_REGISTER : + begin + if getoffset then + MessagePos(filepos,asmr_e_invalid_reference_syntax); + { Subscribed access } + if forceref or + (sofs<>0) then + begin + op.typ:=top_ref; + new(op.ref); + { no idea about the actual alignment } + reference_reset_base(op.ref^,sym.localloc.register,sofs,1); + op.ref^.index:=indexreg; +{$ifdef x86} + op.ref^.scalefactor:=scale; +{$endif x86} + end + else + begin + op.typ:=top_reg; + op.reg:=sym.localloc.register; + end; + end; + LOC_FPUREGISTER, + LOC_MMXREGISTER, + LOC_MMREGISTER : + begin + op.typ:=top_reg; + op.reg:=NR_NO; + if getoffset then + MessagePos(filepos,asmr_e_invalid_reference_syntax); + { Using an MM/FPU register in a reference is not possible } + if forceref or (sofs<>0) then + MessagePos1(filepos,asmr_e_invalid_ref_register,std_regname(sym.localloc.register)) + else + op.reg:=sym.localloc.register; + end; + LOC_INVALID : + begin + { in "assembler; nostackframe;" routines, the + funcret loc is set to LOC_INVALID in case the + result is returned via a complex location + (more than one register, ...) } + if (vo_is_funcret in tabstractvarsym(sym).varoptions) then + MessagePos(filepos,asmr_e_complex_function_result_location) + else + internalerror(2012082101); + { recover } + op.typ:=top_reg; + op.reg:=NR_FUNCTION_RETURN_REG; + end; + else + internalerror(201001031); + end; + end; + end; + + procedure tcgasmnode.pass_generate_code; procedure ReLabel(var p:tasmsymbol); @@ -132,115 +248,6 @@ interface end; end; - procedure ResolveRef(const filepos: tfileposinfo; var op:toper); - var - sym : tabstractnormalvarsym; -{$ifdef x86} - scale : byte; -{$endif x86} - forceref, - getoffset : boolean; - indexreg : tregister; - sofs : longint; - begin - if (op.typ=top_local) then - begin - sofs:=op.localoper^.localsymofs; - indexreg:=op.localoper^.localindexreg; -{$ifdef x86} - scale:=op.localoper^.localscale; -{$endif x86} - getoffset:=op.localoper^.localgetoffset; - forceref:=op.localoper^.localforceref; - sym:=tabstractnormalvarsym(pointer(op.localoper^.localsym)); - dispose(op.localoper); - case sym.localloc.loc of - LOC_REFERENCE : - begin - if getoffset then - begin - if indexreg=NR_NO then - begin - op.typ:=top_const; - op.val:=sym.localloc.reference.offset+sofs; - end - else - begin - op.typ:=top_ref; - new(op.ref); - reference_reset_base(op.ref^,indexreg,sym.localloc.reference.offset+sofs, - newalignment(sym.localloc.reference.alignment,sofs)); - end; - end - else - begin - op.typ:=top_ref; - new(op.ref); - reference_reset_base(op.ref^,sym.localloc.reference.base,sym.localloc.reference.offset+sofs, - newalignment(sym.localloc.reference.alignment,sofs)); - op.ref^.index:=indexreg; -{$ifdef x86} - op.ref^.scalefactor:=scale; -{$endif x86} - end; - end; - LOC_REGISTER : - begin - if getoffset then - MessagePos(filepos,asmr_e_invalid_reference_syntax); - { Subscribed access } - if forceref or - (sofs<>0) then - begin - op.typ:=top_ref; - new(op.ref); - { no idea about the actual alignment } - reference_reset_base(op.ref^,sym.localloc.register,sofs,1); - op.ref^.index:=indexreg; -{$ifdef x86} - op.ref^.scalefactor:=scale; -{$endif x86} - end - else - begin - op.typ:=top_reg; - op.reg:=sym.localloc.register; - end; - end; - LOC_FPUREGISTER, - LOC_MMXREGISTER, - LOC_MMREGISTER : - begin - op.typ:=top_reg; - op.reg:=NR_NO; - if getoffset then - MessagePos(filepos,asmr_e_invalid_reference_syntax); - { Using an MM/FPU register in a reference is not possible } - if forceref or (sofs<>0) then - MessagePos1(filepos,asmr_e_invalid_ref_register,std_regname(sym.localloc.register)) - else - op.reg:=sym.localloc.register; - end; - LOC_INVALID : - begin - { in "assembler; nostackframe;" routines, the - funcret loc is set to LOC_INVALID in case the - result is returned via a complex location - (more than one register, ...) } - if (vo_is_funcret in tabstractvarsym(sym).varoptions) then - MessagePos(filepos,asmr_e_complex_function_result_location) - else - internalerror(2012082101); - { recover } - op.typ:=top_reg; - op.reg:=NR_FUNCTION_RETURN_REG; - end; - else - internalerror(201001031); - end; - end; - end; - var hp,hp2 : tai; i : longint;