* procinlinenode removed

* aktexit2label removed, fast exit removed
  + tcallnode.inlined_pass_2 added
This commit is contained in:
peter 2003-05-26 21:17:17 +00:00
parent 75394a788e
commit 047a066711
16 changed files with 800 additions and 955 deletions

View File

@ -188,9 +188,6 @@ unit cgbase;
{ label to leave the sub routine }
aktexitlabel : tasmlabel;
{ also an exit label, only used we need to clear only the stack }
aktexit2label : tasmlabel;
{# true, if there was an error while code generation occurs }
codegenerror : boolean;
@ -582,7 +579,12 @@ implementation
end.
{
$Log$
Revision 1.51 2003-05-23 14:27:35 peter
Revision 1.52 2003-05-26 21:17:17 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.51 2003/05/23 14:27:35 peter
* remove some unit dependencies
* current_procinfo changes to store more info

View File

@ -1180,8 +1180,7 @@ implementation
if (m_delphi in aktmodeswitches) then
exclude(po_comp,po_varargs);
if ((po_comp * def1.procoptions)= (po_comp * def2.procoptions)) and
equal_defs(def1.rettype.def,def2.rettype.def) and
(def1.para_size(target_info.alignment.paraalign)=def2.para_size(target_info.alignment.paraalign)) then
equal_defs(def1.rettype.def,def2.rettype.def) then
begin
{ return equal type based on the parameters, but a proc->procvar
is never exact, so map an exact match of the parameters to
@ -1211,7 +1210,12 @@ implementation
end.
{
$Log$
Revision 1.25 2003-05-15 18:58:53 peter
Revision 1.26 2003-05-26 21:17:17 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.25 2003/05/15 18:58:53 peter
* removed selfpointer_offset, vmtpointer_offset
* tvarsym.adjusted_address
* address in localsymtable is now in the real direction

View File

@ -456,19 +456,19 @@ begin
funcResRegs := funcResRegs - [R_EAX,R_EBX,R_ECX,R_EDX,R_ESI];
funcResReg := reg.enum in funcResRegs;
hp1 := p;
while not(funcResReg and
{ while not(funcResReg and
(p.typ = ait_instruction) and
(Taicpu(p).opcode = A_JMP) and
(tasmlabel(Taicpu(p).oper[0].sym) = aktexit2label)) and
getLastInstruction(p, p) And
not(regInInstruction(reg.enum, p)) Do
hp1 := p;
hp1 := p; }
{ don't insert a dealloc for registers which contain the function result }
{ if they are followed by a jump to the exit label (for exit(...)) }
if not(funcResReg) or
{if not(funcResReg) or
not((hp1.typ = ait_instruction) and
(Taicpu(hp1).opcode = A_JMP) and
(tasmlabel(Taicpu(hp1).oper[0].sym) = aktexit2label)) then
(tasmlabel(Taicpu(hp1).oper[0].sym) = aktexit2label)) then }
begin
p := tai_regalloc.deAlloc(reg);
insertLLItem(AsmL, hp1.previous, hp1, p);
@ -2669,7 +2669,12 @@ End.
{
$Log$
Revision 1.49 2003-04-27 11:21:35 peter
Revision 1.50 2003-05-26 21:17:18 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.49 2003/04/27 11:21:35 peter
* aktprocdef renamed to current_procdef
* procinfo renamed to current_procinfo
* procinfo will now be stored in current_module so it can be

View File

@ -34,7 +34,7 @@ interface
type
ti386callnode = class(tcgcallnode)
protected
function align_parasize(parasize,para_alignment:longint):longint;override;
function align_parasize:longint;override;
procedure pop_parasize(pop_size:longint);override;
procedure extra_interrupt_code;override;
end;
@ -76,7 +76,7 @@ implementation
end;
function ti386callnode.align_parasize(parasize,para_alignment:longint):longint;
function ti386callnode.align_parasize:longint;
var
pop_size : longint;
{$ifdef OPTALIGN}
@ -87,12 +87,8 @@ implementation
rsp : tregister;
begin
pop_size:=0;
{ Old pushedsize aligned on 4 ? }
i:=parasize and 3;
if i>0 then
inc(pop_size,4-i);
{ This parasize aligned on 4 ? }
i:=procdefinition.para_size(para_alignment) and 3;
i:=procdefinition.parast.datasize and 3;
if i>0 then
inc(pop_size,4-i);
{ insert the opcode and update pushedparasize }
@ -114,7 +110,7 @@ implementation
if pop_allowed and (cs_align in aktglobalswitches) then
begin
pop_esp:=true;
push_size:=procdefinition.para_size(para_alignment);
push_size:=procdefinition.parast.datasize;
{ !!!! here we have to take care of return type, self
and nested procedures
}
@ -201,7 +197,12 @@ begin
end.
{
$Log$
Revision 1.91 2003-05-22 21:32:29 peter
Revision 1.92 2003-05-26 21:17:18 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.91 2003/05/22 21:32:29 peter
* removed some unit dependencies
Revision 1.90 2003/04/23 14:42:08 daniel

View File

@ -82,6 +82,8 @@ interface
{ function return node, this is used to pass the data for a
ret_in_param return value }
funcretnode : tnode;
{ inline function body }
inlinecode : tnode;
{ separately specified resulttype for some compilerprocs (e.g. }
{ you can't have a function with an "array of char" resulttype }
@ -158,30 +160,12 @@ interface
end;
tcallparanodeclass = class of tcallparanode;
tprocinlinenode = class(tnode)
inlinetree : tnode;
inlineprocdef : tprocdef;
retoffset,para_offset,para_size : longint;
constructor create(p:tprocdef);virtual;
destructor destroy;override;
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure derefimpl;override;
function getcopy : tnode;override;
function det_resulttype : tnode;override;
procedure insertintolist(l : tnodelist);override;
function pass_1 : tnode;override;
function docompare(p: tnode): boolean; override;
end;
tprocinlinenodeclass = class of tprocinlinenode;
function reverseparameters(p: tcallparanode): tcallparanode;
var
ccallnode : tcallnodeclass;
ccallparanode : tcallparanodeclass;
cprocinlinenode : tprocinlinenodeclass;
implementation
@ -888,6 +872,7 @@ type
procdefinition:=nil;
restypeset:=false;
funcretnode:=nil;
inlinecode:=nil;
paralength:=-1;
end;
@ -902,6 +887,7 @@ type
procdefinition:=def;
restypeset:=false;
funcretnode:=nil;
inlinecode:=nil;
paralength:=-1;
end;
@ -916,6 +902,7 @@ type
procdefinition:=nil;
restypeset:=false;
funcretnode:=nil;
inlinecode:=nil;
paralength:=-1;
end;
@ -974,6 +961,7 @@ type
begin
methodpointer.free;
funcretnode.free;
inlinecode.free;
inherited destroy;
end;
@ -990,6 +978,7 @@ type
restypeset:=boolean(ppufile.getbyte);
methodpointer:=ppuloadnode(ppufile);
funcretnode:=ppuloadnode(ppufile);
inlinecode:=ppuloadnode(ppufile);
end;
@ -1001,6 +990,7 @@ type
ppufile.putbyte(byte(restypeset));
ppuwritenode(ppufile,methodpointer);
ppuwritenode(ppufile,funcretnode);
ppuwritenode(ppufile,inlinecode);
end;
@ -1014,6 +1004,8 @@ type
methodpointer.derefimpl;
if assigned(funcretnode) then
funcretnode.derefimpl;
if assigned(inlinecode) then
inlinecode.derefimpl;
end;
@ -1035,6 +1027,10 @@ type
n.funcretnode:=funcretnode.getcopy
else
n.funcretnode:=nil;
if assigned(inlinecode) then
n.inlinecode:=inlinecode.getcopy
else
n.inlinecode:=nil;
result:=n;
end;
@ -2270,13 +2266,12 @@ type
function tcallnode.pass_1 : tnode;
var
inlinecode : tnode;
inlined : boolean;
{$ifdef m68k}
var
regi : tregister;
{$endif}
{$ifdef callparatemp}
var
callparatemps, newblock: tblocknode;
statement: tstatementnode;
paras, oldright, newcall: tnode;
@ -2285,8 +2280,6 @@ type
errorexit;
begin
result:=nil;
inlined:=false;
inlinecode := nil;
{ work trough all parameters to get the register requirements }
if assigned(left) then
@ -2300,15 +2293,6 @@ type
if assigned(funcretnode) then
firstpass(funcretnode);
if assigned(procdefinition) and
(procdefinition.proccalloption=pocall_inline) then
begin
inlinecode:=right;
if assigned(inlinecode) then
inlined:=true;
right:=nil;
end;
{ procedure variable ? }
if assigned(right) then
begin
@ -2329,22 +2313,20 @@ type
begin
if assigned(methodpointer) then
CGMessage(cg_e_unable_inline_object_methods);
if assigned(right) and (right.nodetype<>procinlinen) then
if assigned(right) then
CGMessage(cg_e_unable_inline_procvar);
if not assigned(inlinecode) then
if assigned(inlinecode) then
internalerror(200305261);
if assigned(tprocdef(procdefinition).code) then
inlinecode:=tprocdef(procdefinition).code.getcopy
else
CGMessage(cg_e_no_code_for_inline_stored);
if assigned(inlinecode) then
begin
if assigned(tprocdef(procdefinition).code) then
inlinecode:=cprocinlinenode.create(tprocdef(procdefinition))
else
CGMessage(cg_e_no_code_for_inline_stored);
if assigned(inlinecode) then
begin
{ consider it has not inlined if called
again inside the args }
procdefinition.proccalloption:=pocall_fpccall;
firstpass(inlinecode);
inlined:=true;
end;
{ consider it has not inlined if called
again inside the args }
procdefinition.proccalloption:=pocall_fpccall;
firstpass(inlinecode);
end;
end
else
@ -2356,7 +2338,6 @@ type
{ It doesn't hurt to calculate it already though :) (JM) }
rg.incrementintregisterpushed(tprocdef(procdefinition).usedintregisters);
rg.incrementotherregisterpushed(tprocdef(procdefinition).usedotherregisters);
end;
{ get a register for the return value }
@ -2458,8 +2439,16 @@ type
verifyabstractcalls;
end;
if inlined then
right:=inlinecode;
{ determine the registers of the procedure variable }
{ is this OK for inlined procs also ?? (PM) }
if assigned(inlinecode) then
begin
registersfpu:=max(inlinecode.registersfpu,registersfpu);
registers32:=max(inlinecode.registers32,registers32);
{$ifdef SUPPORT_MMX}
registersmmx:=max(inlinecode.registersmmx,registersmmx);
{$endif SUPPORT_MMX}
end;
{ determine the registers of the procedure variable }
{ is this OK for inlined procs also ?? (PM) }
if assigned(right) then
@ -2506,7 +2495,7 @@ type
end;
{$endif callparatemp}
errorexit:
if inlined then
if assigned(inlinecode) then
procdefinition.proccalloption:=pocall_inline;
{$ifdef callparatemp}
if assigned(callparatemps) then
@ -2574,168 +2563,18 @@ type
end;
{****************************************************************************
TPROCINLINENODE
****************************************************************************}
constructor tprocinlinenode.create(p:tprocdef);
begin
inherited create(procinlinen);
inlineprocdef:=p;
retoffset:=-POINTER_SIZE; { less dangerous as zero (PM) }
para_offset:=0;
para_size:=0;
{ copy inlinetree }
if assigned(p.code) then
inlinetree:=p.code.getcopy
else
inlinetree:=nil;
end;
destructor tprocinlinenode.destroy;
begin
if assigned(inlinetree) then
inlinetree.free;
inherited destroy;
end;
constructor tprocinlinenode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
begin
inherited ppuload(t,ppufile);
inlineprocdef:=tprocdef(ppufile.getderef);
inlinetree:=ppuloadnode(ppufile);
retoffset:=-POINTER_SIZE; { less dangerous as zero (PM) }
para_offset:=0;
para_size:=0;
end;
procedure tprocinlinenode.ppuwrite(ppufile:tcompilerppufile);
begin
inherited ppuwrite(ppufile);
ppufile.putderef(inlineprocdef);
ppuwritenode(ppufile,inlinetree);
end;
procedure tprocinlinenode.derefimpl;
begin
inherited derefimpl;
if assigned(inlinetree) then
inlinetree.derefimpl;
resolvedef(pointer(inlineprocdef));
end;
function tprocinlinenode.getcopy : tnode;
var
n : tprocinlinenode;
begin
n:=tprocinlinenode(inherited getcopy);
n.inlineprocdef:=inlineprocdef;
if assigned(inlinetree) then
n.inlinetree:=inlinetree.getcopy
else
n.inlinetree:=nil;
n.retoffset:=retoffset;
n.para_offset:=para_offset;
n.para_size:=para_size;
getcopy:=n;
end;
procedure tprocinlinenode.insertintolist(l : tnodelist);
begin
end;
function tprocinlinenode.det_resulttype : tnode;
var
storesymtablelevel : longint;
storeparasymtable,
storelocalsymtable : tsymtabletype;
oldprocdef : tprocdef;
oldprocinfo : tprocinfo;
oldinlining_procedure : boolean;
begin
result:=nil;
oldinlining_procedure:=inlining_procedure;
oldprocdef:=current_procdef;
oldprocinfo:=current_procinfo;
{ we're inlining a procedure }
inlining_procedure:=true;
{ create temp procinfo }
current_procinfo:=cprocinfo.create(nil);
current_procinfo.procdef:=inlineprocdef;
current_procinfo.return_offset:=retoffset;
current_procdef:=current_procinfo.procdef;
{ set it to the same lexical level }
storesymtablelevel:=current_procdef.localst.symtablelevel;
storelocalsymtable:=current_procdef.localst.symtabletype;
storeparasymtable:=current_procdef.parast.symtabletype;
current_procdef.localst.symtablelevel:=oldprocdef.localst.symtablelevel;
current_procdef.localst.symtabletype:=inlinelocalsymtable;
current_procdef.parast.symtabletype:=inlineparasymtable;
{ pass inlinetree }
resulttypepass(inlinetree);
resulttype:=inlineprocdef.rettype;
{ retrieve info from inlineprocdef }
retoffset:=-POINTER_SIZE; { less dangerous as zero (PM) }
para_offset:=0;
para_size:=inlineprocdef.para_size(target_info.alignment.paraalign);
if paramanager.ret_in_param(inlineprocdef.rettype.def,inlineprocdef.proccalloption) then
inc(para_size,POINTER_SIZE);
{ restore current_procinfo }
current_procinfo.free;
current_procinfo:=oldprocinfo;
{ restore symtable }
current_procdef.localst.symtablelevel:=storesymtablelevel;
current_procdef.localst.symtabletype:=storelocalsymtable;
current_procdef.parast.symtabletype:=storeparasymtable;
{ restore }
current_procdef:=oldprocdef;
inlining_procedure:=oldinlining_procedure;
end;
function tprocinlinenode.pass_1 : tnode;
begin
firstpass(inlinetree);
registers32:=inlinetree.registers32;
registersfpu:=inlinetree.registersfpu;
{$ifdef SUPPORT_MMX}
registersmmx:=inlinetree.registersmmx;
{$endif SUPPORT_MMX}
result:=nil;
end;
function tprocinlinenode.docompare(p: tnode): boolean;
begin
docompare :=
inherited docompare(p) and
inlinetree.isequal(tprocinlinenode(p).inlinetree) and
(inlineprocdef = tprocinlinenode(p).inlineprocdef);
end;
begin
ccallnode:=tcallnode;
ccallparanode:=tcallparanode;
cprocinlinenode:=tprocinlinenode;
end.
{
$Log$
Revision 1.161 2003-05-25 11:34:17 peter
Revision 1.162 2003-05-26 21:17:17 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.161 2003/05/25 11:34:17 peter
* methodpointer self pushing fixed
Revision 1.160 2003/05/25 08:59:16 peter

View File

@ -40,9 +40,13 @@ interface
end;
tcgcallnode = class(tcallnode)
private
procedure release_para_temps;
procedure normal_pass_2;
procedure inlined_pass_2;
protected
refcountedtemp : treference;
procedure handle_return_value(inlined:boolean);
procedure handle_return_value;
{# This routine is used to push the current frame pointer
on the stack. This is used in nested routines where the
value of the frame pointer is always pushed as an extra
@ -52,7 +56,7 @@ interface
most stack based machines, where the frame pointer is
the first invisible parameter.
}
function align_parasize(parasize,para_alignment:longint):longint;virtual;
function align_parasize:longint;virtual;
procedure pop_parasize(pop_size:longint);virtual;
procedure push_framepointer;virtual;
procedure extra_interrupt_code;virtual;
@ -60,10 +64,6 @@ interface
procedure pass_2;override;
end;
tcgprocinlinenode = class(tprocinlinenode)
procedure pass_2;override;
end;
implementation
@ -123,12 +123,8 @@ implementation
{ push from left to right if specified }
if push_from_left_to_right and assigned(right) then
begin
if (nf_varargs_para in flags) then
tcallparanode(right).secondcallparan(push_from_left_to_right,
calloption,para_alignment,para_offset)
else
tcallparanode(right).secondcallparan(push_from_left_to_right,
calloption,para_alignment,para_offset);
tcallparanode(right).secondcallparan(push_from_left_to_right,
calloption,para_alignment,para_offset);
end;
otlabel:=truelabel;
@ -347,10 +343,6 @@ implementation
{ push from right to left }
if not push_from_left_to_right and assigned(right) then
begin
if (nf_varargs_para in flags) then
tcallparanode(right).secondcallparan(push_from_left_to_right,
calloption,para_alignment,para_offset)
else
tcallparanode(right).secondcallparan(push_from_left_to_right,
calloption,para_alignment,para_offset);
end;
@ -366,7 +358,7 @@ implementation
end;
function tcgcallnode.align_parasize(parasize,para_alignment:longint):longint;
function tcgcallnode.align_parasize:longint;
begin
result:=0;
end;
@ -413,7 +405,7 @@ implementation
end;
procedure tcgcallnode.handle_return_value(inlined:boolean);
procedure tcgcallnode.handle_return_value;
var
cgsize : tcgsize;
r,hregister : tregister;
@ -465,8 +457,7 @@ implementation
cgsize:=def_cgsize(resulttype.def);
{ an object constructor is a function with pointer result }
if (inlined or (right=nil)) and
(procdefinition.proctypeoption=potype_constructor) then
if (procdefinition.proctypeoption=potype_constructor) then
cgsize:=OS_ADDR;
if cgsize<>OS_NO then
@ -541,7 +532,41 @@ implementation
end;
procedure tcgcallnode.pass_2;
procedure tcgcallnode.release_para_temps;
var
hp : tnode;
ppn : tcallparanode;
begin
{ Release temps from parameters }
ppn:=tcallparanode(left);
while assigned(ppn) do
begin
if assigned(ppn.left) then
begin
{ don't release the funcret temp }
if not(vo_is_funcret in tvarsym(ppn.paraitem.parasym).varoptions) then
location_freetemp(exprasmlist,ppn.left.location);
{ process also all nodes of an array of const }
if ppn.left.nodetype=arrayconstructorn then
begin
if assigned(tarrayconstructornode(ppn.left).left) then
begin
hp:=ppn.left;
while assigned(hp) do
begin
location_freetemp(exprasmlist,tarrayconstructornode(hp).left.location);
hp:=tarrayconstructornode(hp).right;
end;
end;
end;
end;
ppn:=tcallparanode(ppn.right);
end;
end;
procedure tcgcallnode.normal_pass_2;
var
regs_to_push_int : Tsupregset;
regs_to_push_other : tregisterset;
@ -553,23 +578,16 @@ implementation
iolabel : tasmlabel;
{ help reference pointer }
href : treference;
hp : tnode;
pp : tcallparanode;
inlined : boolean;
inlinecode : tprocinlinenode;
pushedregs : tmaybesave;
store_parast_fixup,
para_alignment,
para_offset : longint;
pop_size : longint;
returnref,
pararef : treference;
accreg : tregister;
oldaktcallnode : tcallnode;
begin
if not assigned(procdefinition) then
internalerror(200305264);
iolabel:=nil;
inlinecode:=nil;
inlined:=false;
rg.saveunusedstate(unusedstate);
{ if we allocate the temp. location for ansi- or widestrings }
@ -590,38 +608,8 @@ implementation
else
para_alignment:=aktalignment.paraalign;
if not assigned(procdefinition) then
exit;
if (procdefinition.proccalloption=pocall_inline) then
begin
inlined:=true;
inlinecode:=tprocinlinenode(right);
right:=nil;
{ set it to the same lexical level as the local symtable, becuase
the para's are stored there }
tprocdef(procdefinition).parast.symtablelevel:=current_procdef.localst.symtablelevel;
if assigned(left) then
begin
inlinecode.para_size:=tprocdef(procdefinition).para_size(para_alignment);
tg.GetTemp(exprasmlist,inlinecode.para_size,tt_persistent,pararef);
inlinecode.para_offset:=pararef.offset;
end;
store_parast_fixup:=tprocdef(procdefinition).parast.address_fixup;
tprocdef(procdefinition).parast.address_fixup:=inlinecode.para_offset;
{$ifdef extdebug}
Comment(V_debug,
'inlined parasymtable is at offset '
+tostr(tprocdef(procdefinition).parast.address_fixup));
exprasmList.concat(tai_comment.Create(
strpnew('inlined parasymtable is at offset '
+tostr(tprocdef(procdefinition).parast.address_fixup))));
{$endif extdebug}
end;
{ proc variables destroy all registers }
if (inlined or
(right=nil)) and
if (right=nil) and
{ virtual methods too }
not(po_virtualmethod in procdefinition.procoptions) then
begin
@ -669,11 +657,9 @@ implementation
{ Initialize for pushing the parameters }
oldpushedparasize:=pushedparasize;
pushedparasize:=0;
pop_size:=0;
{ Align stack if required }
if not inlined then
pop_size:=align_parasize(oldpushedparasize,para_alignment);
pop_size:=align_parasize;
{ Push parameters }
oldaktcallnode:=aktcallnode;
@ -683,31 +669,26 @@ implementation
{ destroy registers containing a parameter for the actual }
{ function call (e.g. if it's a function, its result will }
{ overwrite r3, which contains the first parameter) (JM) }
if not(inlined) and
assigned(right) then
if assigned(right) then
secondpass(right);
if inlined or
(right = nil) then
begin
if (po_virtualmethod in procdefinition.procoptions) and
assigned(methodpointer) then
begin
secondpass(methodpointer);
location_force_reg(exprasmlist,methodpointer.location,OS_ADDR,false);
if (po_virtualmethod in procdefinition.procoptions) and
assigned(methodpointer) then
begin
secondpass(methodpointer);
location_force_reg(exprasmlist,methodpointer.location,OS_ADDR,false);
{ virtual methods require an index }
if tprocdef(procdefinition).extnumber=-1 then
internalerror(200304021);
{ VMT should already be loaded in a register }
if methodpointer.location.register.number=NR_NO then
internalerror(200304022);
{ virtual methods require an index }
if tprocdef(procdefinition).extnumber=-1 then
internalerror(200304021);
{ VMT should already be loaded in a register }
if methodpointer.location.register.number=NR_NO then
internalerror(200304022);
{ test validity of VMT }
if not(is_interface(tprocdef(procdefinition)._class)) and
not(is_cppclass(tprocdef(procdefinition)._class)) then
cg.g_maybe_testvmt(exprasmlist,methodpointer.location.register,tprocdef(procdefinition)._class);
end;
{ test validity of VMT }
if not(is_interface(tprocdef(procdefinition)._class)) and
not(is_cppclass(tprocdef(procdefinition)._class)) then
cg.g_maybe_testvmt(exprasmlist,methodpointer.location.register,tprocdef(procdefinition)._class);
end;
if assigned(left) then
@ -720,21 +701,9 @@ implementation
maybe_save(exprasmlist,left.registers32,methodpointer.location,pushedregs);
{$endif}
{ be found elsewhere }
if inlined then
para_offset:=tprocdef(procdefinition).parast.address_fixup+
tprocdef(procdefinition).parast.datasize
else
para_offset:=0;
if not(inlined) and
assigned(right) then
tcallparanode(left).secondcallparan(
(po_leftright in procdefinition.procoptions),procdefinition.proccalloption,
para_alignment,para_offset)
else
tcallparanode(left).secondcallparan(
(po_leftright in procdefinition.procoptions),procdefinition.proccalloption,
para_alignment,para_offset);
tcallparanode(left).secondcallparan(
(po_leftright in procdefinition.procoptions),procdefinition.proccalloption,
para_alignment,0);
{$ifndef newra}
if assigned(right) then
maybe_restore(exprasmlist,right.location,pushedregs)
@ -745,27 +714,14 @@ implementation
end;
aktcallnode:=oldaktcallnode;
{ Allocate return value for inlined routines }
if inlined and
(resulttype.def.size>0) then
begin
tg.GetTemp(exprasmlist,Align(resulttype.def.size,aktalignment.paraalign),tt_persistent,returnref);
inlinecode.retoffset:=returnref.offset;
end;
{ procedure variable or normal function call ? }
if inlined or
(right=nil) then
if (right=nil) then
begin
{ push base pointer ?}
{ never when inlining, since if necessary, the base pointer }
{ can/will be gottten from the current procedure's symtable }
{ (JM) }
if not inlined then
if (current_procdef.parast.symtablelevel>=normal_function_level) and
assigned(tprocdef(procdefinition).parast) and
((tprocdef(procdefinition).parast.symtablelevel)>normal_function_level) then
push_framepointer;
if (current_procdef.parast.symtablelevel>=normal_function_level) and
assigned(tprocdef(procdefinition).parast) and
((tprocdef(procdefinition).parast.symtablelevel)>normal_function_level) then
push_framepointer;
rg.saveintregvars(exprasmlist,regs_to_push_int);
rg.saveotherregvars(exprasmlist,regs_to_push_other);
@ -778,28 +734,17 @@ implementation
tprocdef(procdefinition)._class.vmtmethodoffset(tprocdef(procdefinition).extnumber));
cg.a_call_ref(exprasmlist,href);
{ release self }
{ release vmt register }
rg.ungetaddressregister(exprasmlist,methodpointer.location.register);
end
else
begin
if not inlined then
begin
{ Calling interrupt from the same code requires some
extra code }
if (po_interrupt in procdefinition.procoptions) then
extra_interrupt_code;
{ Calling interrupt from the same code requires some
extra code }
if (po_interrupt in procdefinition.procoptions) then
extra_interrupt_code;
cg.a_call_name(exprasmlist,tprocdef(procdefinition).mangledname);
end
else { inlined proc }
begin
{ process the inlinecode }
secondpass(tnode(inlinecode));
{ free the args }
if tprocdef(procdefinition).parast.datasize>0 then
tg.UnGetTemp(exprasmlist,pararef);
end;
cg.a_call_name(exprasmlist,tprocdef(procdefinition).mangledname);
end;
end
else
@ -818,7 +763,7 @@ implementation
end;
{ Need to remove the parameters from the stack? }
if (not inlined) and (po_clearstack in procdefinition.procoptions) then
if (po_clearstack in procdefinition.procoptions) then
begin
{ the old pop_size was already included in pushedparasize }
pop_size:=pushedparasize;
@ -832,7 +777,6 @@ implementation
if pop_size>0 then
pop_parasize(pop_size);
{$ifdef powerpc}
{ this calculation must be done in pass_1 anyway, so don't worry }
if tppcprocinfo(current_procinfo).maxpushedparasize<pushedparasize then
@ -848,7 +792,7 @@ implementation
{ handle function results }
if (not is_void(resulttype.def)) then
handle_return_value(inlined)
handle_return_value
else
location_reset(location,LOC_VOID,OS_NO);
@ -864,44 +808,8 @@ implementation
rg.restoreusedotherregisters(exprasmlist,pushedother);
rg.restoreusedintregisters(exprasmlist,pushedint);
{ Release temps from parameters }
pp:=tcallparanode(left);
while assigned(pp) do
begin
if assigned(pp.left) then
begin
{ don't release the funcret temp }
if not(vo_is_funcret in tvarsym(pp.paraitem.parasym).varoptions) then
location_freetemp(exprasmlist,pp.left.location);
{ process also all nodes of an array of const }
if pp.left.nodetype=arrayconstructorn then
begin
if assigned(tarrayconstructornode(pp.left).left) then
begin
hp:=pp.left;
while assigned(hp) do
begin
location_freetemp(exprasmlist,tarrayconstructornode(hp).left.location);
hp:=tarrayconstructornode(hp).right;
end;
end;
end;
end;
pp:=tcallparanode(pp.right);
end;
if inlined then
begin
if (resulttype.def.size>0) then
tg.UnGetTemp(exprasmlist,returnref);
tprocdef(procdefinition).parast.address_fixup:=store_parast_fixup;
right:=inlinecode;
{ from now on the result can be freed normally }
if assigned(funcretnode) and
paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption) then
tg.ChangeTempType(exprasmlist,funcretnode.location.reference,tt_normal);
end;
{ release temps of paras }
release_para_temps;
{ if return value is not used }
if (not(nf_return_value_used in flags)) and (not is_void(resulttype.def)) then
@ -931,186 +839,387 @@ implementation
{*****************************************************************************
TCGPROCINLINENODE
*****************************************************************************}
procedure tcgprocinlinenode.pass_2;
var st : tsymtable;
oldprocdef : tprocdef;
ps, i : longint;
oldprocinfo : tprocinfo;
oldinlining_procedure,
nostackframe : boolean;
inlineentrycode,inlineexitcode : TAAsmoutput;
oldexitlabel,oldexit2label:tasmlabel;
oldregstate: pointer;
localsref : treference;
procedure tcgcallnode.inlined_pass_2;
var
regs_to_push_int : Tsupregset;
regs_to_push_other : tregisterset;
unusedstate: pointer;
pushedother : tpushedsavedother;
pushedint : tpushedsavedint;
oldpushedparasize : longint;
{ adress returned from an I/O-error }
iolabel : tasmlabel;
{ help reference pointer }
href : treference;
pushedregs : tmaybesave;
accreg : tregister;
oldaktcallnode : tcallnode;
oldprocdef : tprocdef;
i : longint;
oldprocinfo : tprocinfo;
oldinlining_procedure : boolean;
inlineentrycode,inlineexitcode : TAAsmoutput;
oldexitlabel:tasmlabel;
oldregstate: pointer;
old_local_fixup,
old_para_fixup : longint;
pararef,
localsref : treference;
{$ifdef GDB}
startlabel,endlabel : tasmlabel;
pp : pchar;
mangled_length : longint;
startlabel,endlabel : tasmlabel;
pp : pchar;
mangled_length : longint;
{$endif GDB}
begin
{ deallocate the registers used for the current procedure's regvars }
if assigned(current_procdef.regvarinfo) then
begin
with pregvarinfo(current_procdef.regvarinfo)^ do
for i := 1 to maxvarregs do
if assigned(regvars[i]) then
store_regvar(exprasmlist,regvars[i].reg);
rg.saveStateForInline(oldregstate);
{ make sure the register allocator knows what the regvars in the }
{ inlined code block are (JM) }
rg.resetusableregisters;
rg.clearregistercount;
{$ifndef newra}
rg.cleartempgen;
{$endif}
if assigned(inlineprocdef.regvarinfo) then
with pregvarinfo(inlineprocdef.regvarinfo)^ do
for i := 1 to maxvarregs do
if assigned(regvars[i]) then
begin
{Fix me!!}
{tmpreg:=rg.makeregsize(regvars[i].reg,OS_INT);
rg.makeregvar(tmpreg);}
internalerror(200301232);
end;
end;
oldinlining_procedure:=inlining_procedure;
oldexitlabel:=aktexitlabel;
oldexit2label:=aktexit2label;
oldprocdef:=current_procdef;
oldprocinfo:=current_procinfo;
objectlibrary.getlabel(aktexitlabel);
objectlibrary.getlabel(aktexit2label);
{ we're inlining a procedure }
inlining_procedure:=true;
begin
if not(assigned(procdefinition) and (procdefinition.deftype=procdef)) then
internalerror(200305262);
{ create temp procinfo }
current_procinfo:=cprocinfo.create(nil);
current_procinfo.procdef:=inlineprocdef;
current_procinfo.return_offset:=retoffset;
current_procdef:=current_procinfo.procdef;
oldinlining_procedure:=inlining_procedure;
oldexitlabel:=aktexitlabel;
oldprocdef:=current_procdef;
oldprocinfo:=current_procinfo;
objectlibrary.getlabel(aktexitlabel);
{ we're inlining a procedure }
inlining_procedure:=true;
{ arg space has been filled by the parent secondcall }
st:=current_procdef.localst;
{ set it to the same lexical level }
st.symtablelevel:=oldprocdef.localst.symtablelevel;
if st.datasize>0 then
begin
tg.GetTemp(exprasmlist,st.datasize,tt_persistent,localsref);
if tg.direction>0 then
st.address_fixup:=localsref.offset
else
st.address_fixup:=localsref.offset+st.datasize;
{ deallocate the registers used for the current procedure's regvars }
if assigned(current_procdef.regvarinfo) then
begin
with pregvarinfo(current_procdef.regvarinfo)^ do
for i := 1 to maxvarregs do
if assigned(regvars[i]) then
store_regvar(exprasmlist,regvars[i].reg);
rg.saveStateForInline(oldregstate);
{ make sure the register allocator knows what the regvars in the }
{ inlined code block are (JM) }
rg.resetusableregisters;
rg.clearregistercount;
{$ifndef newra}
rg.cleartempgen;
{$endif}
if assigned(tprocdef(procdefinition).regvarinfo) then
with pregvarinfo(tprocdef(procdefinition).regvarinfo)^ do
for i := 1 to maxvarregs do
if assigned(regvars[i]) then
begin
{Fix me!!}
{tmpreg:=rg.makeregsize(regvars[i].reg,OS_INT);
rg.makeregvar(tmpreg);}
internalerror(200301232);
end;
end;
{ create temp procinfo }
current_procinfo:=cprocinfo.create(nil);
current_procinfo.procdef:=tprocdef(procdefinition);
current_procdef:=current_procinfo.procdef;
{ Localsymtable }
current_procdef.localst.symtablelevel:=oldprocdef.localst.symtablelevel;
if current_procdef.localst.datasize>0 then
begin
old_local_fixup:=current_procdef.localst.address_fixup;
tg.GetTemp(exprasmlist,current_procdef.localst.datasize,tt_persistent,localsref);
if tg.direction>0 then
current_procdef.localst.address_fixup:=localsref.offset
else
current_procdef.localst.address_fixup:=localsref.offset+current_procdef.localst.datasize;
{$ifdef extdebug}
Comment(V_debug,'local symtable is at offset '+tostr(st.address_fixup));
exprasmList.concat(tai_comment.Create(strpnew(
'local symtable is at offset '+tostr(st.address_fixup))));
Comment(V_debug,'inlined local symtable ('+tostr(current_procdef.localst.datasize)+' bytes) is at offset '+tostr(current_procdef.localst.address_fixup));
exprasmList.concat(tai_comment.Create(strpnew(
'inlined local symtable ('+tostr(current_procdef.localst.datasize)+' bytes) is at offset '+tostr(current_procdef.localst.address_fixup))));
{$endif extdebug}
end;
exprasmList.concat(Tai_Marker.Create(InlineStart));
end;
{ Parasymtable }
current_procdef.parast.symtablelevel:=oldprocdef.localst.symtablelevel;
if current_procdef.parast.datasize>0 then
begin
old_para_fixup:=current_procdef.parast.address_fixup;
tg.GetTemp(exprasmlist,current_procdef.parast.datasize,tt_persistent,pararef);
current_procdef.parast.address_fixup:=pararef.offset;
{$ifdef extdebug}
exprasmList.concat(tai_comment.Create(strpnew('Start of inlined proc')));
Comment(V_debug,'inlined para symtable ('+tostr(current_procdef.parast.datasize)+' bytes) is at offset '+tostr(current_procdef.parast.address_fixup));
exprasmList.concat(tai_comment.Create(strpnew(
'inlined para symtable ('+tostr(current_procdef.parast.datasize)+' bytes) is at offset '+tostr(current_procdef.parast.address_fixup))));
{$endif extdebug}
end;
{ Calculate offsets }
current_procinfo.after_header;
exprasmList.concat(Tai_Marker.Create(InlineStart));
{$ifdef extdebug}
exprasmList.concat(tai_comment.Create(strpnew('Start of inlined proc')));
{$endif extdebug}
{$ifdef GDB}
if (cs_debuginfo in aktmoduleswitches) then
begin
objectlibrary.getaddrlabel(startlabel);
objectlibrary.getaddrlabel(endlabel);
cg.a_label(exprasmlist,startlabel);
inlineprocdef.localst.symtabletype:=inlinelocalsymtable;
inlineprocdef.parast.symtabletype:=inlineparasymtable;
if (cs_debuginfo in aktmoduleswitches) then
begin
objectlibrary.getaddrlabel(startlabel);
objectlibrary.getaddrlabel(endlabel);
cg.a_label(exprasmlist,startlabel);
tprocdef(procdefinition).localst.symtabletype:=inlinelocalsymtable;
procdefinition.parast.symtabletype:=inlineparasymtable;
{ Here we must include the para and local symtable info }
inlineprocdef.concatstabto(withdebuglist);
{ Here we must include the para and local symtable info }
procdefinition.concatstabto(withdebuglist);
{ set it back for safety }
inlineprocdef.localst.symtabletype:=localsymtable;
inlineprocdef.parast.symtabletype:=parasymtable;
{ set it back for safety }
tprocdef(procdefinition).localst.symtabletype:=localsymtable;
procdefinition.parast.symtabletype:=parasymtable;
mangled_length:=length(oldprocdef.mangledname);
getmem(pp,mangled_length+50);
strpcopy(pp,'192,0,0,'+startlabel.name);
if (target_info.use_function_relative_addresses) then
begin
strpcopy(strend(pp),'-');
strpcopy(strend(pp),oldprocdef.mangledname);
end;
withdebugList.concat(Tai_stabn.Create(strnew(pp)));
end;
{$endif GDB}
{ takes care of local data initialization }
inlineentrycode:=TAAsmoutput.Create;
inlineexitcode:=TAAsmoutput.Create;
ps:=para_size;
genentrycode(inlineentrycode,0,ps,nostackframe,true);
if po_assembler in current_procdef.procoptions then
inlineentrycode.insert(Tai_marker.Create(asmblockstart));
exprasmList.concatlist(inlineentrycode);
secondpass(inlinetree);
genexitcode(inlineexitcode,0,false,true);
if po_assembler in current_procdef.procoptions then
inlineexitcode.concat(Tai_marker.Create(asmblockend));
exprasmList.concatlist(inlineexitcode);
inlineentrycode.free;
inlineexitcode.free;
{$ifdef extdebug}
exprasmList.concat(tai_comment.Create(strpnew('End of inlined proc')));
{$endif extdebug}
exprasmList.concat(Tai_Marker.Create(InlineEnd));
{we can free the local data now, reset also the fixup address }
if st.datasize>0 then
begin
tg.UnGetTemp(exprasmlist,localsref);
st.address_fixup:=0;
end;
{ restore procinfo }
current_procinfo.free;
current_procinfo:=oldprocinfo;
{$ifdef GDB}
if (cs_debuginfo in aktmoduleswitches) then
begin
cg.a_label(exprasmlist,endlabel);
strpcopy(pp,'224,0,0,'+endlabel.name);
mangled_length:=length(oldprocdef.mangledname);
getmem(pp,mangled_length+50);
strpcopy(pp,'192,0,0,'+startlabel.name);
if (target_info.use_function_relative_addresses) then
begin
strpcopy(strend(pp),'-');
strpcopy(strend(pp),oldprocdef.mangledname);
end;
withdebugList.concat(Tai_stabn.Create(strnew(pp)));
freemem(pp,mangled_length+50);
end;
withdebugList.concat(Tai_stabn.Create(strnew(pp)));
end;
{$endif GDB}
{ restore }
current_procdef:=oldprocdef;
aktexitlabel:=oldexitlabel;
aktexit2label:=oldexit2label;
inlining_procedure:=oldinlining_procedure;
{ reallocate the registers used for the current procedure's regvars, }
{ since they may have been used and then deallocated in the inlined }
{ procedure (JM) }
if assigned(current_procdef.regvarinfo) then
begin
rg.restoreStateAfterInline(oldregstate);
end;
end;
iolabel:=nil;
rg.saveunusedstate(unusedstate);
{ if we allocate the temp. location for ansi- or widestrings }
{ already here, we avoid later a push/pop }
if is_widestring(resulttype.def) then
begin
tg.GetTemp(exprasmlist,pointer_size,tt_widestring,refcountedtemp);
cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp,false);
end
else if is_ansistring(resulttype.def) then
begin
tg.GetTemp(exprasmlist,pointer_size,tt_ansistring,refcountedtemp);
cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp,false);
end;
if (cs_check_io in aktlocalswitches) and
(po_iocheck in procdefinition.procoptions) and
not(po_iocheck in current_procdef.procoptions) then
begin
objectlibrary.getaddrlabel(iolabel);
cg.a_label(exprasmlist,iolabel);
end
else
iolabel:=nil;
{ save all used registers and possible registers
used for the return value }
regs_to_push_int := tprocdef(procdefinition).usedintregisters;
regs_to_push_other := tprocdef(procdefinition).usedotherregisters;
if (not is_void(resulttype.def)) and
(not paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption)) then
begin
include(regs_to_push_int,RS_ACCUMULATOR);
{$ifndef cpu64bit}
if resulttype.def.size>sizeof(aword) then
include(regs_to_push_int,RS_ACCUMULATORHIGH);
{$endif cpu64bit}
end;
rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
rg.saveusedotherregisters(exprasmlist,pushedother,regs_to_push_other);
{ give used registers through }
rg.usedintinproc:=rg.usedintinproc + tprocdef(procdefinition).usedintregisters;
rg.usedinproc:=rg.usedinproc + tprocdef(procdefinition).usedotherregisters;
{ Initialize for pushing the parameters }
oldpushedparasize:=pushedparasize;
pushedparasize:=0;
{ Push parameters }
oldaktcallnode:=aktcallnode;
aktcallnode:=self;
if assigned(left) then
begin
{$ifndef newra}
if assigned(right) then
maybe_save(exprasmlist,left.registers32,right.location,pushedregs)
else
if assigned(methodpointer) then
maybe_save(exprasmlist,left.registers32,methodpointer.location,pushedregs);
{$endif}
{ we push from right to left, so start with parameters at the end of
the parameter block }
tcallparanode(left).secondcallparan(
(po_leftright in procdefinition.procoptions),procdefinition.proccalloption,
0,procdefinition.parast.address_fixup+procdefinition.parast.datasize);
{$ifndef newra}
if assigned(right) then
maybe_restore(exprasmlist,right.location,pushedregs)
else
if assigned(methodpointer) then
maybe_restore(exprasmlist,methodpointer.location,pushedregs);
{$endif newra}
end;
aktcallnode:=oldaktcallnode;
rg.saveintregvars(exprasmlist,regs_to_push_int);
rg.saveotherregvars(exprasmlist,regs_to_push_other);
{ takes care of local data initialization }
inlineentrycode:=TAAsmoutput.Create;
inlineexitcode:=TAAsmoutput.Create;
geninlineentrycode(inlineentrycode,0);
if po_assembler in current_procdef.procoptions then
inlineentrycode.insert(Tai_marker.Create(asmblockstart));
exprasmList.concatlist(inlineentrycode);
{ process the inline code }
secondpass(inlinecode);
{$ifdef powerpc}
{ this calculation must be done in pass_1 anyway, so don't worry }
if tppcprocinfo(current_procinfo).maxpushedparasize<pushedparasize then
tppcprocinfo(current_procinfo).maxpushedparasize:=pushedparasize;
{$endif powerpc}
{ Restore }
pushedparasize:=oldpushedparasize;
rg.restoreunusedstate(unusedstate);
{$ifdef TEMPREGDEBUG}
testregisters32;
{$endif TEMPREGDEBUG}
geninlineexitcode(inlineexitcode,true);
if po_assembler in current_procdef.procoptions then
inlineexitcode.concat(Tai_marker.Create(asmblockend));
exprasmList.concatlist(inlineexitcode);
inlineentrycode.free;
inlineexitcode.free;
{$ifdef extdebug}
exprasmList.concat(tai_comment.Create(strpnew('End of inlined proc')));
{$endif extdebug}
exprasmList.concat(Tai_Marker.Create(InlineEnd));
{we can free the local data now, reset also the fixup address }
if current_procdef.localst.datasize>0 then
begin
tg.UnGetTemp(exprasmlist,localsref);
current_procdef.localst.address_fixup:=old_local_fixup;
end;
{we can free the para data now, reset also the fixup address }
if current_procdef.parast.datasize>0 then
begin
tg.UnGetTemp(exprasmlist,pararef);
current_procdef.parast.address_fixup:=old_para_fixup;
end;
{ free return reference }
if (resulttype.def.size>0) then
begin
{ from now on the result can be freed normally }
// if assigned(funcretnode) and
// paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption) then
// tg.ChangeTempType(exprasmlist,funcretnode.location.reference,tt_normal);
end;
{ handle function results }
if (not is_void(resulttype.def)) then
handle_return_value
else
location_reset(location,LOC_VOID,OS_NO);
{ perhaps i/o check ? }
if iolabel<>nil then
begin
reference_reset_symbol(href,iolabel,0);
cg.a_paramaddr_ref(exprasmlist,href,paramanager.getintparaloc(1));
cg.a_call_name(exprasmlist,'FPC_IOCHECK');
end;
{ restore registers }
rg.restoreusedotherregisters(exprasmlist,pushedother);
rg.restoreusedintregisters(exprasmlist,pushedint);
{ release temps of paras }
release_para_temps;
{ if return value is not used }
if (not is_void(resulttype.def)) and
(not(nf_return_value_used in flags)) then
begin
if location.loc in [LOC_CREFERENCE,LOC_REFERENCE] then
begin
{ data which must be finalized ? }
if (resulttype.def.needs_inittable) then
cg.g_finalize(exprasmlist,resulttype.def,location.reference,false);
{ release unused temp }
tg.ungetiftemp(exprasmlist,location.reference)
end
else if location.loc=LOC_FPUREGISTER then
begin
{$ifdef x86}
{ release FPU stack }
accreg.enum:=FPU_RESULT_REG;
emit_reg(A_FSTP,S_NO,accreg);
{
dec(trgcpu(rg).fpuvaroffset);
do NOT decrement as the increment before
is not called for unused results PM }
{$endif x86}
end;
end;
{ release procinfo }
current_procinfo.free;
current_procinfo:=oldprocinfo;
{$ifdef GDB}
if (cs_debuginfo in aktmoduleswitches) then
begin
cg.a_label(exprasmlist,endlabel);
strpcopy(pp,'224,0,0,'+endlabel.name);
if (target_info.use_function_relative_addresses) then
begin
strpcopy(strend(pp),'-');
strpcopy(strend(pp),oldprocdef.mangledname);
end;
withdebugList.concat(Tai_stabn.Create(strnew(pp)));
freemem(pp,mangled_length+50);
end;
{$endif GDB}
{ restore }
current_procdef:=oldprocdef;
aktexitlabel:=oldexitlabel;
inlining_procedure:=oldinlining_procedure;
{ reallocate the registers used for the current procedure's regvars, }
{ since they may have been used and then deallocated in the inlined }
{ procedure (JM) }
if assigned(current_procdef.regvarinfo) then
rg.restoreStateAfterInline(oldregstate);
end;
procedure tcgcallnode.pass_2;
begin
if assigned(inlinecode) then
inlined_pass_2
else
normal_pass_2;
end;
begin
ccallparanode:=tcgcallparanode;
ccallnode:=tcgcallnode;
cprocinlinenode:=tcgprocinlinenode;
end.
{
$Log$
Revision 1.74 2003-05-25 11:34:17 peter
Revision 1.75 2003-05-26 21:17:17 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.74 2003/05/25 11:34:17 peter
* methodpointer self pushing fixed
Revision 1.73 2003/05/25 08:59:16 peter

View File

@ -695,152 +695,14 @@ implementation
*****************************************************************************}
procedure tcgexitnode.pass_2;
var
otlabel,oflabel : tasmlabel;
cgsize : tcgsize;
r,hreg : tregister;
allocated_acc,
allocated_acchigh: boolean;
label
do_jmp;
begin
location_reset(location,LOC_VOID,OS_NO);
include(flowcontrol,fc_exit);
if assigned(left) then
begin
if onlyassign then
begin
{ just do a normal assignment followed by exit }
secondpass(left);
cg.a_jmp_always(exprasmlist,aktexitlabel);
end
else
begin
allocated_acc := false;
allocated_acchigh := false;
otlabel:=truelabel;
oflabel:=falselabel;
objectlibrary.getlabel(truelabel);
objectlibrary.getlabel(falselabel);
secondpass(left);
{ increment reference counter, this is
useless for string constants }
if (left.resulttype.def.needs_inittable) and
(left.nodetype<>stringconstn) then
cg.g_incrrefcount(exprasmlist,left.resulttype.def,left.location.reference,false);
{ the result of left is not needed anymore after this
node }
location_freetemp(exprasmlist,left.location);
location_release(exprasmlist,left.location);
case left.location.loc of
LOC_FPUREGISTER :
goto do_jmp;
{$ifdef cpuflags}
LOC_FLAGS :
begin
r.enum:=R_INTREGISTER;
r.number:=NR_ACCUMULATOR;
cg.a_reg_alloc(exprasmlist,r);
allocated_acc := true;
cg.g_flags2reg(exprasmlist,OS_INT,left.location.resflags,r);
goto do_jmp;
end;
{$endif cpuflags}
LOC_JUMP :
begin
r.enum:=R_INTREGISTER;
r.number:=(RS_ACCUMULATOR shl 8) or R_SUBL;
cg.a_reg_alloc(exprasmlist,r);
{ get an 8-bit register }
allocated_acc := true;
cg.a_label(exprasmlist,truelabel);
cg.a_load_const_reg(exprasmlist,OS_8,1,r);
cg.a_jmp_always(exprasmlist,aktexit2label);
cg.a_label(exprasmlist,falselabel);
cg.a_load_const_reg(exprasmlist,OS_8,0,r);
goto do_jmp;
end;
end;
case current_procdef.rettype.def.deftype of
pointerdef,
procvardef :
begin
r.enum:=R_INTREGISTER;
r.number:=NR_ACCUMULATOR;
cg.a_reg_alloc(exprasmlist,r);
allocated_acc := true;
cg.a_load_loc_reg(exprasmlist,left.location,r);
end;
floatdef :
begin
{$ifdef cpufpemu}
if cs_fp_emulation in aktmoduleswitches then
r.enum := accumulator
else
{$endif cpufpemu}
r.enum:=fpu_result_reg;
{$ifndef i386}
cg.a_reg_alloc(exprasmlist,r);
{$endif not i386}
cg.a_loadfpu_loc_reg(exprasmlist,left.location,r);
end;
else
begin
cgsize:=def_cgsize(current_procdef.rettype.def);
allocated_acc := true;
{$ifndef cpu64bit}
secondpass(left);
if cgsize in [OS_64,OS_S64] then
begin
r.enum:=R_INTREGISTER;
r.number:=NR_ACCUMULATOR;
hreg.enum:=R_INTREGISTER;
hreg.number:=NR_ACCUMULATORHIGH;
cg.a_reg_alloc(exprasmlist,r);
cg.a_reg_alloc(exprasmlist,hreg);
allocated_acchigh := true;
cg64.a_load64_loc_reg(exprasmlist,left.location,
joinreg64(r,hreg));
end
else
{$endif cpu64bit}
begin
r.enum:=R_INTREGISTER;
r.number:=(RS_ACCUMULATOR shl 8) or cgsize2subreg(cgsize);
cg.a_reg_alloc(exprasmlist,r);
cg.a_load_loc_reg(exprasmlist,left.location,r);
end;
end;
end;
do_jmp:
truelabel:=otlabel;
falselabel:=oflabel;
cg.a_jmp_always(exprasmlist,aktexit2label);
r.enum:=R_INTREGISTER;
r.number:=NR_ACCUMULATOR;
{$ifndef cpu64bit}
hreg.enum:=R_INTREGISTER;
hreg.number:=NR_ACCUMULATORHIGH;
{$endif cpu64bit}
if allocated_acc then
cg.a_reg_dealloc(exprasmlist,r);
{$ifndef cpu64bit}
if allocated_acchigh then
cg.a_reg_dealloc(exprasmlist,hreg);
{$endif cpu64bit}
{$ifndef i386}
r.enum:=fpu_result_reg;
if (current_procdef.rettype.def.deftype = floatdef) then
cg.a_reg_dealloc(exprasmlist,r);
{$endif not i386}
end;
end
else
cg.a_jmp_always(exprasmlist,aktexitlabel);
cg.a_jmp_always(exprasmlist,aktexitlabel);
end;
@ -1033,7 +895,6 @@ implementation
doobjectdestroy,
doobjectdestroyandreraise,
oldaktexitlabel,
oldaktexit2label,
oldaktcontinuelabel,
oldaktbreaklabel : tasmlabel;
oldflowcontrol,tryflowcontrol,
@ -1054,7 +915,6 @@ implementation
{ save the old labels for control flow statements }
oldaktexitlabel:=aktexitlabel;
oldaktexit2label:=aktexit2label;
if assigned(aktbreaklabel) then
begin
oldaktcontinuelabel:=aktcontinuelabel;
@ -1082,7 +942,6 @@ implementation
{ try block }
{ set control flow labels for the try block }
aktexitlabel:=exittrylabel;
aktexit2label:=exittrylabel;
if assigned(oldaktbreaklabel) then
begin
aktcontinuelabel:=continuetrylabel;
@ -1104,7 +963,6 @@ implementation
{ set control flow labels for the except block }
{ and the on statements }
aktexitlabel:=exitexceptlabel;
aktexit2label:=exitexceptlabel;
if assigned(oldaktbreaklabel) then
begin
aktcontinuelabel:=continueexceptlabel;
@ -1228,7 +1086,6 @@ implementation
{ restore the control flow labels }
aktexitlabel:=oldaktexitlabel;
aktexit2label:=oldaktexit2label;
if assigned(oldaktbreaklabel) then
begin
aktcontinuelabel:=oldaktcontinuelabel;
@ -1248,7 +1105,6 @@ implementation
continueonlabel,
breakonlabel,
oldaktexitlabel,
oldaktexit2label,
oldaktcontinuelabel,
doobjectdestroyandreraise,
doobjectdestroy,
@ -1295,10 +1151,8 @@ implementation
if assigned(right) then
begin
oldaktexitlabel:=aktexitlabel;
oldaktexit2label:=aktexit2label;
objectlibrary.getlabel(exitonlabel);
aktexitlabel:=exitonlabel;
aktexit2label:=exitonlabel;
if assigned(aktbreaklabel) then
begin
oldaktcontinuelabel:=aktcontinuelabel;
@ -1354,7 +1208,6 @@ implementation
end;
aktexitlabel:=oldaktexitlabel;
aktexit2label:=oldaktexit2label;
if assigned(oldaktbreaklabel) then
begin
aktcontinuelabel:=oldaktcontinuelabel;
@ -1387,7 +1240,6 @@ implementation
continuefinallylabel,
breakfinallylabel,
oldaktexitlabel,
oldaktexit2label,
oldaktcontinuelabel,
oldaktbreaklabel : tasmlabel;
oldflowcontrol,tryflowcontrol : tflowcontrol;
@ -1409,13 +1261,11 @@ implementation
{ the finally block must catch break, continue and exit }
{ statements }
oldaktexitlabel:=aktexitlabel;
oldaktexit2label:=aktexit2label;
if implicitframe then
exitfinallylabel:=finallylabel
else
objectlibrary.getlabel(exitfinallylabel);
aktexitlabel:=exitfinallylabel;
aktexit2label:=exitfinallylabel;
if assigned(aktbreaklabel) then
begin
oldaktcontinuelabel:=aktcontinuelabel;
@ -1528,7 +1378,6 @@ implementation
cg.a_label(exprasmlist,endfinallylabel);
aktexitlabel:=oldaktexitlabel;
aktexit2label:=oldaktexit2label;
if assigned(aktbreaklabel) then
begin
aktcontinuelabel:=oldaktcontinuelabel;
@ -1554,7 +1403,12 @@ begin
end.
{
$Log$
Revision 1.63 2003-05-23 14:27:35 peter
Revision 1.64 2003-05-26 21:17:17 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.63 2003/05/23 14:27:35 peter
* remove some unit dependencies
* current_procinfo changes to store more info

View File

@ -62,12 +62,11 @@ interface
para_offset:longint;alignment : longint;
const locpara : tparalocation);
procedure genentrycode(list : TAAsmoutput;
stackframe:longint;
var parasize:longint;
var nostackframe:boolean;
inlined : boolean);
procedure genexitcode(list : TAAsmoutput;parasize:longint;nostackframe:boolean;inlined:boolean);
procedure genentrycode(list : TAAsmoutput;stackframe:longint;inlined : boolean);
procedure genexitcode(list : TAAsmoutput;inlined:boolean);
procedure geninlineentrycode(list : TAAsmoutput;stackframe:longint);
procedure geninlineexitcode(list : TAAsmoutput;inlined:boolean);
{#
Allocate the buffers for exception management and setjmp environment.
@ -1185,8 +1184,57 @@ implementation
end;
procedure initretvalue(list:taasmoutput);
var
paraloc : tparalocation;
href : treference;
begin
if not is_void(current_procdef.rettype.def) then
begin
{ for now the pointer to the result can't be a register }
if paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) then
begin
{$ifdef powerpc}
{ no stack space is allocated in this case -> can't save the result reg on the stack }
if not(po_assembler in current_procdef.procoptions) then
{$endif powerpc}
begin
paraloc:=paramanager.getfuncretparaloc(current_procdef);
reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
case paraloc.loc of
LOC_CREGISTER,
LOC_REGISTER:
if not(paraloc.size in [OS_64,OS_S64]) then
cg.a_load_reg_ref(list,paraloc.size,paraloc.register,href)
else
cg64.a_load64_reg_ref(list,paraloc.register64,href);
LOC_CFPUREGISTER,
LOC_FPUREGISTER:
cg.a_load_reg_ref(list,paraloc.size,paraloc.register,href);
LOC_CMMREGISTER,
LOC_MMREGISTER:
cg.a_loadmm_reg_ref(list,paraloc.register,href);
end;
end;
end;
procedure handle_return_value(list:TAAsmoutput; inlined : boolean;var uses_acc,uses_acchi,uses_fpu : boolean);
{ initialize return value }
if (current_procdef.rettype.def.needs_inittable) then
begin
{$ifdef powerpc}
if (po_assembler in current_procdef.procoptions) then
internalerror(200304161);
{$endif powerpc}
if (cs_implicit_exceptions in aktmoduleswitches) then
include(current_procinfo.flags,pi_needs_implicit_finally);
reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
cg.g_initialize(list,current_procdef.rettype.def,href,paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption));
end;
end;
end;
procedure handle_return_value(list:TAAsmoutput; var uses_acc,uses_acchi,uses_fpu : boolean);
var
href : treference;
hreg,r,r2 : tregister;
@ -1267,65 +1315,12 @@ implementation
end;
procedure handle_fast_exit_return_value(list:TAAsmoutput);
var
href : treference;
hreg : tregister;
cgsize : TCGSize;
r,r2 : Tregister;
begin
if not is_void(current_procdef.rettype.def) then
begin
reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
cgsize:=def_cgsize(current_procdef.rettype.def);
case current_procdef.rettype.def.deftype of
orddef,
enumdef :
begin
{$ifndef cpu64bit}
r.enum:=accumulator;
r2.enum:=accumulatorhigh;
if cgsize in [OS_64,OS_S64] then
cg64.a_load64_reg_ref(list,joinreg64(r,r2),href)
else
{$endif cpu64bit}
begin
hreg:=rg.makeregsize(r,cgsize);
cg.a_load_reg_ref(list,cgsize,hreg,href);
end;
end;
floatdef :
begin
{$ifdef cpufpemu}
if cs_fp_emulation in aktmoduleswitches then
r.enum := accumulator
else
{$endif cpufpemu}
r.enum:=fpu_result_reg;
cg.a_loadfpu_reg_ref(list,cgsize,r,href);
end;
else
begin
r.enum:=accumulator;
if not paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) then
cg.a_load_reg_ref(list,cgsize,r,href);
end;
end;
end;
end;
procedure genentrycode(list : TAAsmoutput;
stackframe:longint;
var parasize:longint;
var nostackframe:boolean;
inlined : boolean);
procedure genentrycode(list : TAAsmoutput;stackframe:longint;inlined : boolean);
var
hs : string;
href : treference;
stackalloclist : taasmoutput;
hp : tparaitem;
paraloc : tparalocation;
rsp : tregister;
begin
if not inlined then
@ -1424,48 +1419,8 @@ implementation
cg.g_profilecode(list);
end;
if not is_void(current_procdef.rettype.def) then
begin
{ for now the pointer to the result can't be a register }
if paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) then
begin
{$ifdef powerpc}
{ no stack space is allocated in this case -> can't save the result reg on the stack }
if not(po_assembler in current_procdef.procoptions) then
{$endif powerpc}
begin
paraloc:=paramanager.getfuncretparaloc(current_procdef);
reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
case paraloc.loc of
LOC_CREGISTER,
LOC_REGISTER:
if not(paraloc.size in [OS_64,OS_S64]) then
cg.a_load_reg_ref(list,paraloc.size,paraloc.register,href)
else
cg64.a_load64_reg_ref(list,paraloc.register64,href);
LOC_CFPUREGISTER,
LOC_FPUREGISTER:
cg.a_load_reg_ref(list,paraloc.size,paraloc.register,href);
LOC_CMMREGISTER,
LOC_MMREGISTER:
cg.a_loadmm_reg_ref(list,paraloc.register,href);
end;
end;
end;
{ initialize return value }
if (current_procdef.rettype.def.needs_inittable) then
begin
{$ifdef powerpc}
if (po_assembler in current_procdef.procoptions) then
internalerror(200304161);
{$endif powerpc}
if (cs_implicit_exceptions in aktmoduleswitches) then
include(current_procinfo.flags,pi_needs_implicit_finally);
reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
cg.g_initialize(list,current_procdef.rettype.def,href,paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption));
end;
end;
{ initialize return value }
initretvalue(list);
{ initialize local data like ansistrings }
case current_procdef.proctypeoption of
@ -1508,9 +1463,9 @@ implementation
(cs_profile in aktmoduleswitches) then
begin
reference_reset_symbol(href,objectlibrary.newasmsymboldata('etext'),0);
cg.a_paramaddr_ref(list,href,paraloc);
cg.a_paramaddr_ref(list,href,paramanager.getintparaloc(2));
reference_reset_symbol(href,objectlibrary.newasmsymboldata('__image_base__'),0);
cg.a_paramaddr_ref(list,href,paraloc);
cg.a_paramaddr_ref(list,href,paramanager.getintparaloc(2));
cg.a_call_name(list,'_monstartup');
end;
@ -1577,23 +1532,12 @@ implementation
if (current_procinfo.framepointer.number=NR_STACK_POINTER_REG) then
begin
CGMessage(cg_d_stackframe_omited);
nostackframe:=true;
if (current_procdef.proctypeoption in [potype_unitinit,potype_proginit,potype_unitfinalize]) then
parasize:=0
else
parasize:=current_procdef.parast.datasize+current_procdef.parast.address_fixup-4;
if stackframe<>0 then
cg.g_stackpointer_alloc(stackalloclist,stackframe);
end
else
{$endif powerpc}
begin
nostackframe:=false;
if (current_procdef.proctypeoption in [potype_unitinit,potype_proginit,potype_unitfinalize]) then
parasize:=0
else
parasize:=current_procdef.parast.datasize+current_procdef.parast.address_fixup-target_info.first_parm_offset;
if (po_interrupt in current_procdef.procoptions) then
cg.g_interrupt_stackframe_entry(stackalloclist);
@ -1612,7 +1556,7 @@ implementation
end;
procedure genexitcode(list : TAAsmoutput;parasize:longint;nostackframe:boolean;inlined:boolean);
procedure genexitcode(list : TAAsmoutput;inlined:boolean);
var
{$ifdef GDB}
stabsendlabel : tasmlabel;
@ -1627,15 +1571,6 @@ implementation
usesfpu : boolean;
rsp,r : Tregister;
begin
if aktexit2label.is_used and
((pi_needs_implicit_finally in current_procinfo.flags) or
(pi_uses_exceptions in current_procinfo.flags)) then
begin
cg.a_jmp_always(list,aktexitlabel);
cg.a_label(list,aktexit2label);
handle_fast_exit_return_value(list);
end;
if aktexitlabel.is_used then
cg.a_label(list,aktexitlabel);
@ -1701,12 +1636,9 @@ implementation
usesacc:=true;
end
else
handle_return_value(list,inlined,usesacc,usesacchi,usesfpu)
handle_return_value(list,usesacc,usesacchi,usesfpu)
end;
if aktexit2label.is_used and not aktexit2label.is_set then
cg.a_label(list,aktexit2label);
{$ifdef GDB}
if ((cs_debuginfo in aktmoduleswitches) and not inlined) then
begin
@ -1739,14 +1671,13 @@ implementation
{ remove stackframe }
if not inlined then
begin
if (not nostackframe) then
cg.g_restore_frame_pointer(list)
if (current_procinfo.framepointer.number=NR_STACK_POINTER_REG) then
begin
if (tg.gettempsize<>0) then
cg.a_op_const_reg(list,OP_ADD,tg.gettempsize,current_procinfo.framepointer);
end
else
if (tg.gettempsize<>0) then
begin
r.enum:=stack_pointer_reg;
cg.a_op_const_reg(list,OP_ADD,tg.gettempsize,r);
end;
cg.g_restore_frame_pointer(list);
end;
{ at last, the return is generated }
@ -1755,16 +1686,7 @@ implementation
if (po_interrupt in current_procdef.procoptions) then
cg.g_interrupt_stackframe_exit(list,usesacc,usesacchi)
else
begin
{$ifndef i386}
{ give a warning if the limit of parameters allowed for
certain processors is reached.
}
if (parasize > maxparasize) then
Message(cg_w_parasize_too_big);
{$endif}
cg.g_return_from_proc(list,parasize);
end;
cg.g_return_from_proc(list,current_procdef.parast.datasize);
end;
if not inlined then
@ -1833,10 +1755,143 @@ implementation
cleanup_regvars(list);
end;
{****************************************************************************
Inlining
****************************************************************************}
procedure handle_inlined_return_value(list:TAAsmoutput);
var
href : treference;
r,r2 : tregister;
cgsize : TCGSize;
begin
if not is_void(current_procdef.rettype.def) then
begin
reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
cgsize:=def_cgsize(current_procdef.rettype.def);
{ Here, we return the function result. In most architectures, the value is
passed into the accumulator, but in a windowed architecure like sparc a
function returns in a register and the caller receives it in an other one }
case current_procdef.rettype.def.deftype of
orddef,
enumdef :
begin
{$ifndef cpu64bit}
if cgsize in [OS_64,OS_S64] then
begin
r:=rg.getregisterint(list,OS_INT);
r2:=rg.getregisterint(list,OS_INT);
cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
end
else
{$endif cpu64bit}
begin
r:=rg.getregisterint(list,cgsize);
cg.a_load_ref_reg(list,cgsize,href,r);
end;
end;
floatdef :
begin
{$ifdef cpufpemu}
if cs_fp_emulation in aktmoduleswitches then
r.enum := accumulator
else
{$endif cpufpemu}
r.enum:=fpu_result_reg;
cg.a_loadfpu_ref_reg(list,cgsize,href,r);
end;
else
begin
if not paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) then
begin
{$ifndef cpu64bit}
{ Win32 can return records in EAX:EDX }
if cgsize in [OS_64,OS_S64] then
begin
r:=rg.getregisterint(list,OS_INT);
r2:=rg.getregisterint(list,OS_INT);
cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
end
else
{$endif cpu64bit}
begin
r:=rg.getregisterint(list,cgsize);
cg.a_load_ref_reg(list,cgsize,href,r);
end;
end
end;
end;
end;
end;
procedure geninlineentrycode(list : TAAsmoutput;stackframe:longint);
begin
{ initialize return value }
initretvalue(list);
current_procdef.localst.foreach_static({$ifndef TP}@{$endif}initialize_data,list);
{ initialisizes temp. ansi/wide string data }
inittempvariables(list);
{ initialize ansi/widesstring para's }
if assigned(current_procdef.parast) then
current_procdef.parast.foreach_static({$ifndef TP}@{$endif}init_paras,list);
{ generate copies of call by value parameters }
if not(po_assembler in current_procdef.procoptions) then
current_procdef.parast.foreach_static({$ifndef TP}@{$endif}copyvalueparas,list);
load_regvars(list,nil);
end;
procedure geninlineexitcode(list : TAAsmoutput;inlined:boolean);
var
usesacc,
usesacchi,
usesfpu : boolean;
begin
if aktexitlabel.is_used then
cg.a_label(list,aktexitlabel);
cleanup_regvars(list);
{ finalize temporary data }
finalizetempvariables(list);
current_procdef.localst.foreach_static({$ifndef TP}@{$endif}finalize_data,list);
{ finalize paras data }
if assigned(current_procdef.parast) then
current_procdef.parast.foreach_static({$ifndef TP}@{$endif}final_paras,list);
{ handle return value, this is not done for assembler routines when
they didn't reference the result variable }
if not(po_assembler in current_procdef.procoptions) or
(assigned(current_procdef.funcretsym) and
(tvarsym(current_procdef.funcretsym).refcount>1)) then
begin
if (current_procdef.proctypeoption=potype_constructor) then
internalerror(200305263);
// handle_inlined_return_value(list);
handle_return_value(list,usesacc,usesacchi,usesfpu)
end;
cleanup_regvars(list);
end;
end.
{
$Log$
Revision 1.106 2003-05-24 11:59:42 jonas
Revision 1.107 2003-05-26 21:17:17 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.106 2003/05/24 11:59:42 jonas
* fixed integer typeconversion problems
Revision 1.105 2003/05/23 14:27:35 peter

View File

@ -93,7 +93,6 @@ interface
tfornodeclass = class of tfornode;
texitnode = class(tunarynode)
onlyassign : boolean;
constructor create(l:tnode);virtual;
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override;
@ -835,56 +834,34 @@ implementation
constructor texitnode.create(l:tnode);
begin
inherited create(exitn,l);
onlyassign:=false;
end;
constructor texitnode.ppuload(t:tnodetype;ppufile:tcompilerppufile);
begin
inherited ppuload(t,ppufile);
onlyassign:=boolean(ppufile.getbyte);
end;
procedure texitnode.ppuwrite(ppufile:tcompilerppufile);
begin
inherited ppuwrite(ppufile);
ppufile.putbyte(byte(onlyassign));
end;
function texitnode.det_resulttype:tnode;
begin
result:=nil;
{ Check the 2 types }
if not inlining_procedure then
begin
if assigned(left) then
begin
inserttypeconv(left,current_procdef.rettype);
if paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption) or
(current_procdef.proctypeoption=potype_constructor) or
(pi_needs_implicit_finally in current_procinfo.flags) or
(pi_uses_exceptions in current_procinfo.flags) then
begin
left:=cassignmentnode.create(
cloadnode.create(current_procdef.funcretsym,current_procdef.funcretsym.owner),
left);
onlyassign:=true;
end
else
begin
{ mark funcretsym as assigned }
inc(tvarsym(current_procdef.funcretsym).refs);
tvarsym(current_procdef.funcretsym).varstate:=vs_assigned;
end;
end;
end;
if assigned(left) then
begin
resulttypepass(left);
set_varstate(left,true);
end;
begin
{ add assignment to funcretsym }
inserttypeconv(left,current_procdef.rettype);
left:=cassignmentnode.create(
cloadnode.create(current_procdef.funcretsym,current_procdef.funcretsym.owner),
left);
resulttypepass(left);
set_varstate(left,true);
end;
resulttype:=voidtype;
end;
@ -1449,7 +1426,12 @@ begin
end.
{
$Log$
Revision 1.74 2003-05-13 19:14:41 peter
Revision 1.75 2003-05-26 21:17:17 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.74 2003/05/13 19:14:41 peter
* failn removed
* inherited result code check moven to pexpr

View File

@ -109,7 +109,6 @@ interface
asn, {Represents the as typecast}
caretn, {Represents the ^ operator}
starstarn, {Represents the ** operator exponentiation }
procinlinen, {Procedures that can be inlined }
arrayconstructorn, {Construction node for [...] parsing}
arrayconstructorrangen, {Range element to allow sets in array construction tree}
tempcreaten, { for temps in the result/firstpass }
@ -188,7 +187,6 @@ interface
'asn',
'caretn',
'starstarn',
'procinlinen',
'arrayconstructn',
'arrayconstructrangen',
'tempcreaten',
@ -984,7 +982,12 @@ implementation
end.
{
$Log$
Revision 1.61 2003-05-13 19:14:41 peter
Revision 1.62 2003-05-26 21:17:17 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.61 2003/05/13 19:14:41 peter
* failn removed
* inherited result code check moven to pexpr

View File

@ -84,9 +84,11 @@ implementation
end;
case n.nodetype of
calln:
result := foreachnode(tcallnode(n).methodpointer,f) or result;
procinlinen:
result := foreachnode(tprocinlinenode(n).inlinetree,f) or result;
begin
{ not in one statement, won't work because of b- }
result := foreachnode(tcallnode(n).methodpointer,f) or result;
result := foreachnode(tcallnode(n).inlinecode,f) or result;
end;
ifn, whilerepeatn, forn:
begin
{ not in one statement, won't work because of b- }
@ -129,9 +131,10 @@ implementation
end;
case n.nodetype of
calln:
result := foreachnodestatic(tcallnode(n).methodpointer,f) or result;
procinlinen:
result := foreachnodestatic(tprocinlinenode(n).inlinetree,f) or result;
begin
result := foreachnodestatic(tcallnode(n).methodpointer,f) or result;
result := foreachnodestatic(tcallnode(n).inlinecode,f) or result;
end;
ifn, whilerepeatn, forn:
begin
{ not in one statement, won't work because of b- }
@ -250,7 +253,12 @@ end.
{
$Log$
Revision 1.4 2003-05-16 14:33:31 peter
Revision 1.5 2003-05-26 21:17:17 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.4 2003/05/16 14:33:31 peter
* regvar fixes
Revision 1.3 2003/05/13 20:54:06 peter

View File

@ -134,7 +134,6 @@ implementation
'as', {asn}
'error-caret', {caretn}
'add-starstar', {starstarn}
'procinline', {procinlinen}
'arrayconstruc', {arrayconstructn}
'noth-arrcnstr', {arrayconstructrangen}
'tempcreaten',
@ -301,7 +300,12 @@ implementation
end.
{
$Log$
Revision 1.52 2003-05-15 18:58:53 peter
Revision 1.53 2003-05-26 21:17:17 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.52 2003/05/15 18:58:53 peter
* removed selfpointer_offset, vmtpointer_offset
* tvarsym.adjusted_address
* address in localsymtable is now in the real direction

View File

@ -768,11 +768,8 @@ implementation
procedure gen_implicit_initfinal(list:taasmoutput;flag:word;st:tsymtable);
var
parasize : longint;
nostackframe : boolean;
pd : tprocdef;
oldexitlabel,
oldexit2label : tasmlabel;
oldexitlabel : tasmlabel;
begin
{ update module flags }
current_module.flags:=current_module.flags or flag;
@ -793,20 +790,15 @@ implementation
end;
{ save labels }
oldexitlabel:=aktexitlabel;
oldexit2label:=aktexit2label;
{ generate a dummy function }
parasize:=0;
nostackframe:=false;
objectlibrary.getlabel(aktexitlabel);
objectlibrary.getlabel(aktexit2label);
include(current_procinfo.flags,pi_do_call);
genentrycode(list,0,parasize,nostackframe,false);
genexitcode(list,parasize,nostackframe,false);
genentrycode(list,0,false);
genexitcode(list,false);
list.convert_registers;
release_main_proc(pd);
{ restore }
aktexitlabel:=oldexitlabel;
aktexit2label:=oldexit2label;
end;
@ -1482,7 +1474,12 @@ So, all parameters are passerd into registers in sparc architecture.}
end.
{
$Log$
Revision 1.108 2003-05-25 10:27:12 peter
Revision 1.109 2003-05-26 21:17:17 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.108 2003/05/25 10:27:12 peter
* moved Comment calls to messge file
Revision 1.107 2003/05/22 21:31:35 peter

View File

@ -551,14 +551,9 @@ implementation
var
oldprocdef : tprocdef;
oldprocinfo : tprocinfo;
oldexitlabel,
oldexit2label : tasmlabel;
oldexitlabel : tasmlabel;
oldaktmaxfpuregisters : longint;
oldfilepos : tfileposinfo;
{ true when no stackframe is required }
nostackframe:boolean;
{ number of bytes which have to be cleared by RET }
parasize:longint;
begin
{ the initialization procedure can be empty, then we
don't need to generate anything. When it was an empty
@ -576,10 +571,8 @@ implementation
{ save old labels }
oldexitlabel:=aktexitlabel;
oldexit2label:=aktexit2label;
{ get new labels }
objectlibrary.getlabel(aktexitlabel);
objectlibrary.getlabel(aktexit2label);
aktbreaklabel:=nil;
aktcontinuelabel:=nil;
@ -599,12 +592,12 @@ implementation
{ first generate entry code with the correct position and switches }
aktfilepos:=current_procinfo.entrypos;
aktlocalswitches:=current_procinfo.entryswitches;
genentrycode(current_procinfo.aktentrycode,0,parasize,nostackframe,false);
genentrycode(current_procinfo.aktentrycode,0,false);
{ now generate exit code with the correct position and switches }
aktfilepos:=current_procinfo.exitpos;
aktlocalswitches:=current_procinfo.exitswitches;
genexitcode(current_procinfo.aktexitcode,parasize,nostackframe,false);
genexitcode(current_procinfo.aktexitcode,false);
{ now all the registers used are known }
current_procdef.usedintregisters:=rg.usedintinproc;
@ -666,7 +659,6 @@ implementation
{ restore labels }
aktexitlabel:=oldexitlabel;
aktexit2label:=oldexit2label;
{ restore }
aktmaxfpuregisters:=oldaktmaxfpuregisters;
@ -1216,7 +1208,12 @@ begin
end.
{
$Log$
Revision 1.117 2003-05-25 08:59:47 peter
Revision 1.118 2003-05-26 21:17:18 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.117 2003/05/25 08:59:47 peter
* do not generate code when there was an error
Revision 1.116 2003/05/23 18:49:55 jonas

View File

@ -423,7 +423,6 @@ implementation
nodeclass[asn]:=casnode;
nodeclass[caretn]:=caddnode;
nodeclass[starstarn]:=caddnode;
nodeclass[procinlinen]:=cprocinlinenode;
nodeclass[arrayconstructorn]:=carrayconstructornode;
nodeclass[arrayconstructorrangen]:=carrayconstructorrangenode;
nodeclass[tempcreaten]:=ctempcreatenode;
@ -494,7 +493,12 @@ implementation
end.
{
$Log$
Revision 1.51 2003-05-25 11:34:17 peter
Revision 1.52 2003-05-26 21:17:18 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.51 2003/05/25 11:34:17 peter
* methodpointer self pushing fixed
Revision 1.50 2003/05/13 19:14:41 peter

View File

@ -429,7 +429,6 @@ interface
function concatpara(afterpara:tparaitem;const tt:ttype;sym : tsym;defval:tsym;vhidden:boolean):tparaitem;
function insertpara(const tt:ttype;sym : tsym;defval:tsym;vhidden:boolean):tparaitem;
procedure removepara(currpara:tparaitem);
function para_size(alignsize:longint) : longint;
function typename_paras(showhidden:boolean): string;
procedure test_if_fpu_result;
function is_methodpointer:boolean;virtual;
@ -3278,29 +3277,6 @@ implementation
function tabstractprocdef.para_size(alignsize:longint) : longint;
var
pdc : TParaItem;
l : longint;
begin
l:=0;
pdc:=TParaItem(Para.first);
while assigned(pdc) do
begin
inc(l,paramanager.push_size(pdc.paratyp,pdc.paratype.def,proccalloption));
l:=align(l,alignsize);
if assigned(pdc.paratype.def) and
is_special_array(pdc.paratype.def) then
begin
inc(l,POINTER_SIZE);
l:=align(l,alignsize);
end;
pdc:=TParaItem(pdc.next);
end;
para_size:=l;
end;
function tabstractprocdef.typename_paras(showhidden:boolean) : string;
var
hs,s : string;
@ -5762,7 +5738,12 @@ implementation
end.
{
$Log$
Revision 1.145 2003-05-25 11:34:17 peter
Revision 1.146 2003-05-26 21:17:18 peter
* procinlinenode removed
* aktexit2label removed, fast exit removed
+ tcallnode.inlined_pass_2 added
Revision 1.145 2003/05/25 11:34:17 peter
* methodpointer self pushing fixed
Revision 1.144 2003/05/15 18:58:53 peter