diff --git a/compiler/aasmtai.pas b/compiler/aasmtai.pas index 4c1bdbeb9b..67304f502d 100644 --- a/compiler/aasmtai.pas +++ b/compiler/aasmtai.pas @@ -2061,13 +2061,15 @@ implementation begin case p.typ of ait_regalloc: - setsupreg(Tai_regalloc(p).reg,table[getsupreg(Tai_regalloc(p).reg)]); + if (getregtype(Tai_regalloc(p).reg)=R_INTREGISTER) then + setsupreg(Tai_regalloc(p).reg,table[getsupreg(Tai_regalloc(p).reg)]); ait_instruction: begin for i:=0 to Taicpu_abstract(p).ops-1 do case Taicpu_abstract(p).oper[i].typ of Top_reg: - setsupreg(Taicpu_abstract(p).oper[i].reg,table[getsupreg(Taicpu_abstract(p).oper[i].reg)]); + if (getregtype(Taicpu_abstract(p).oper[i].reg)=R_INTREGISTER) then + setsupreg(Taicpu_abstract(p).oper[i].reg,table[getsupreg(Taicpu_abstract(p).oper[i].reg)]); Top_ref: begin r:=Taicpu_abstract(p).oper[i].ref; @@ -2104,7 +2106,11 @@ implementation end. { $Log$ - Revision 1.38 2003-09-04 00:15:28 florian + Revision 1.39 2003-09-07 22:09:34 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.38 2003/09/04 00:15:28 florian * first bunch of adaptions of arm compiler for new register type Revision 1.37 2003/09/03 15:55:00 peter diff --git a/compiler/browcol.pas b/compiler/browcol.pas index f0fdaf5046..00c079a2b7 100644 --- a/compiler/browcol.pas +++ b/compiler/browcol.pas @@ -1453,7 +1453,7 @@ end; else MemInfo.Size:=getsize; { this is not completely correct... } - MemInfo.PushSize:=paramanager.push_size(varspez,vartype.def,pocall_none); + MemInfo.PushSize:=paramanager.push_size(varspez,vartype.def,pocall_default); Symbol^.SetMemInfo(MemInfo); end; constsym : @@ -2111,7 +2111,11 @@ begin end. { $Log$ - Revision 1.33 2003-04-26 00:29:17 peter + Revision 1.34 2003-09-07 22:09:34 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.33 2003/04/26 00:29:17 peter * adapted for removed funcretsym Revision 1.32 2002/12/29 14:57:50 peter diff --git a/compiler/cgbase.pas b/compiler/cgbase.pas index c9a37a1ddf..4de5e963b3 100644 --- a/compiler/cgbase.pas +++ b/compiler/cgbase.pas @@ -86,19 +86,10 @@ unit cgbase; } flags : tprocinfoflags; - {# register used as frame pointer } + { register used as frame pointer } framepointer : tregister; - {# Holds the reference used to store the original stackpointer - after all registers are saved - } - save_stackptr_ref :treference; - {# Holds the reference used to store alll saved registers. - - This is used on systems which do not have direct stack - operations (such as the PowerPC), it is unused on other - systems - } + { Holds the reference used to store alll saved registers. } save_regs_ref : treference; { label to leave the sub routine } @@ -324,7 +315,7 @@ implementation { asmlists } aktproccode:=Taasmoutput.Create; aktlocaldata:=Taasmoutput.Create; - reference_reset(save_stackptr_ref); + reference_reset(save_regs_ref); { labels } objectlibrary.getlabel(aktexitlabel); end; @@ -385,6 +376,8 @@ implementation current_procinfo.firsttemp_offset := tg.direction*symtablestack.datasize else current_procinfo.firsttemp_offset := 0; +(* + THe registers are also allocated when loading the result { include return value registers } if not is_void(procdef.rettype.def) then @@ -397,21 +390,22 @@ implementation LOC_CMMREGISTER : begin regidx:=findreg_by_number(paramloc.register); - include(rg.used_in_proc_other,regidx); + include(used_regs_fpu,regidx); end; LOC_REGISTER,LOC_CREGISTER : begin if ((paramloc.size in [OS_S64,OS_64]) and (sizeof(aword) < 8)) then begin - include(rg.used_in_proc_int,getsupreg(paramloc.registerhigh)); - include(rg.used_in_proc_int,getsupreg(paramloc.registerlow)); + include(used_regs_int,getsupreg(paramloc.registerhigh)); + include(used_regs_fpu,getsupreg(paramloc.registerlow)); end else - include(rg.used_in_proc_int,getsupreg(paramloc.register)); + include(used_regs_fpu,getsupreg(paramloc.register)); end; end; end; +*) end; @@ -582,7 +576,11 @@ implementation end. { $Log$ - Revision 1.61 2003-09-03 15:55:00 peter + Revision 1.62 2003-09-07 22:09:34 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.61 2003/09/03 15:55:00 peter * NEWRA branch merged Revision 1.60.2.1 2003/08/29 17:28:59 peter diff --git a/compiler/cgobj.pas b/compiler/cgobj.pas index 6ff7f07489..87206de928 100644 --- a/compiler/cgobj.pas +++ b/compiler/cgobj.pas @@ -1146,9 +1146,9 @@ unit cgobj; paramanager.freeintparaloc(list,3); paramanager.freeintparaloc(list,2); paramanager.freeintparaloc(list,1); - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); a_call_name(list,'FPC_SHORTSTR_ASSIGN'); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); end; @@ -1175,9 +1175,9 @@ unit cgobj; { these functions get the pointer by value } a_param_ref(list,OS_ADDR,ref,paramanager.getintparaloc(list,1)); paramanager.freeintparaloc(list,1); - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); a_call_name(list,incrfunc); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); end else begin @@ -1189,9 +1189,9 @@ unit cgobj; a_paramaddr_ref(list,ref,paramanager.getintparaloc(list,1)); paramanager.freeintparaloc(list,1); paramanager.freeintparaloc(list,2); - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); a_call_name(list,'FPC_ADDREF'); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); end; end; @@ -1229,9 +1229,9 @@ unit cgobj; else a_paramaddr_ref(list,ref,paramanager.getintparaloc(list,1)); paramanager.freeintparaloc(list,1); - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); a_call_name(list,decrfunc); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); if needrtti then paramanager.freeintparaloc(list,2); end @@ -1245,9 +1245,9 @@ unit cgobj; a_paramaddr_ref(list,ref,paramanager.getintparaloc(list,1)); paramanager.freeintparaloc(list,1); paramanager.freeintparaloc(list,2); - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); a_call_name(list,'FPC_DECREF'); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); end; end; @@ -1270,9 +1270,9 @@ unit cgobj; a_paramaddr_ref(list,ref,paramanager.getintparaloc(list,1)); paramanager.freeintparaloc(list,1); paramanager.freeintparaloc(list,2); - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); a_call_name(list,'FPC_INITIALIZE'); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); end; end; @@ -1295,9 +1295,9 @@ unit cgobj; a_paramaddr_ref(list,ref,paramanager.getintparaloc(list,1)); paramanager.freeintparaloc(list,1); paramanager.freeintparaloc(list,2); - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); a_call_name(list,'FPC_FINALIZE'); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); end; end; @@ -1461,18 +1461,18 @@ unit cgobj; a_param_reg(list,OS_ADDR,reg,paramanager.getintparaloc(list,1)); paramanager.freeintparaloc(list,2); paramanager.freeintparaloc(list,1); - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); a_call_name(list,'FPC_CHECK_OBJECT_EXT'); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); end else if (cs_check_range in aktlocalswitches) then begin a_param_reg(list,OS_ADDR,reg,paramanager.getintparaloc(list,1)); paramanager.freeintparaloc(list,1); - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); a_call_name(list,'FPC_CHECK_OBJECT'); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); end; end; @@ -1536,7 +1536,11 @@ finalization end. { $Log$ - Revision 1.118 2003-09-03 15:55:00 peter + Revision 1.119 2003-09-07 22:09:34 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.118 2003/09/03 15:55:00 peter * NEWRA branch merged Revision 1.117 2003/09/03 11:18:36 florian diff --git a/compiler/globals.pas b/compiler/globals.pas index 303dbf655f..5fac41d0f9 100644 --- a/compiler/globals.pas +++ b/compiler/globals.pas @@ -1660,7 +1660,7 @@ implementation initfputype:=fpu_fpa; {$endif arm} initinterfacetype:=it_interfacecom; - initdefproccall:=pocall_none; + initdefproccall:=pocall_default; initdefines:=TStringList.Create; { memory sizes, will be overriden by parameter or default for target @@ -1674,7 +1674,11 @@ implementation end. { $Log$ - Revision 1.96 2003-09-06 16:47:24 florian + Revision 1.97 2003-09-07 22:09:34 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.96 2003/09/06 16:47:24 florian + support of NaN and Inf in the compiler as values of real constants Revision 1.95 2003/09/05 17:41:12 florian diff --git a/compiler/globtype.pas b/compiler/globtype.pas index c387e9dc71..8397a49f0e 100644 --- a/compiler/globtype.pas +++ b/compiler/globtype.pas @@ -132,7 +132,7 @@ interface pocall_cppdecl, { C++ calling conventions } pocall_compilerproc, { Procedure is used for internal compiler calls } pocall_far16, { Far16 for OS/2 } - pocall_fpccall, { FPC default calling } + pocall_oldfpccall, { Old style FPC default calling } pocall_inline, { Procedure is an assembler macro } pocall_internproc, { Procedure has compiler magic} pocall_palmossyscall, { procedure is a PalmOS system call } @@ -143,13 +143,14 @@ interface ); tproccalloptions = set of tproccalloption; + const proccalloptionStr : array[tproccalloption] of string[14]=('', 'CDecl', 'CPPDecl', 'CompilerProc', 'Far16', - 'FPCCall', + 'OldFPCCall', 'Inline', 'InternProc', 'PalmOSSysCall', @@ -159,6 +160,9 @@ interface 'StdCall' ); + { Default calling convention } + pocall_default = pocall_oldfpccall; + type stringid = string[maxidlen]; @@ -206,7 +210,11 @@ implementation end. { $Log$ - Revision 1.41 2003-09-04 21:37:29 olle + Revision 1.42 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.41 2003/09/04 21:37:29 olle + added new lagnuage mode: MAC Revision 1.40 2003/09/03 15:55:00 peter diff --git a/compiler/i386/cpupara.pas b/compiler/i386/cpupara.pas index 2b6b6f1692..25cb2338e9 100644 --- a/compiler/i386/cpupara.pas +++ b/compiler/i386/cpupara.pas @@ -44,6 +44,8 @@ unit cpupara; ti386paramanager = class(tparamanager) function ret_in_param(def : tdef;calloption : tproccalloption) : boolean;override; function push_addr_param(def : tdef;calloption : tproccalloption) : boolean;override; + function get_volatile_registers_int(calloption : tproccalloption):tsuperregisterset;override; + function get_volatile_registers_fpu(calloption : tproccalloption):tsuperregisterset;override; function getintparaloc(list: taasmoutput; nr : longint) : tparalocation;override; procedure freeintparaloc(list: taasmoutput; nr : longint); override; function getparaloc(p : tdef) : tcgloc; @@ -60,6 +62,10 @@ unit cpupara; cgbase; +{**************************************************************************** + TI386PARAMANAGER +****************************************************************************} + function ti386paramanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean; begin case target_info.system of @@ -112,6 +118,35 @@ unit cpupara; end; + function ti386paramanager.get_volatile_registers_int(calloption : tproccalloption):tsuperregisterset; + begin + case calloption of + pocall_internproc : + result:=[]; + pocall_inline, + pocall_compilerproc, + pocall_register, + pocall_safecall, + pocall_stdcall, + pocall_cdecl, + pocall_cppdecl : + result:=[RS_EAX,RS_EDX,RS_ECX]; + pocall_far16, + pocall_pascal, + pocall_oldfpccall : + result:=[RS_EAX,RS_EDX,RS_ECX,RS_ESI,RS_EDI,RS_EBX]; + else + internalerror(200309071); + end; + end; + + + function ti386paramanager.get_volatile_registers_fpu(calloption : tproccalloption):tsuperregisterset; + begin + result:=[first_fpu_supreg..last_fpu_supreg];; + end; + + function ti386paramanager.getintparaloc(list: taasmoutput; nr : longint) : tparalocation; begin getintparaloc.loc:=LOC_REFERENCE; @@ -202,12 +237,17 @@ unit cpupara; getselflocation.reference.offset:=hsym.adjusted_address; end; + begin paramanager:=ti386paramanager.create; end. { $Log$ - Revision 1.23 2003-09-03 15:55:01 peter + Revision 1.24 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.23 2003/09/03 15:55:01 peter * NEWRA branch merged Revision 1.22.2.2 2003/08/28 18:35:08 peter diff --git a/compiler/i386/n386inl.pas b/compiler/i386/n386inl.pas index 89a5d59903..4f6891147f 100644 --- a/compiler/i386/n386inl.pas +++ b/compiler/i386/n386inl.pas @@ -300,8 +300,7 @@ implementation { need a cmp and jmp, but this should be done by the } { type cast code which does range checking if necessary (FK) } begin - hregister:=Tcallparanode(Tcallparanode(left).right).left.location.register; - setsubreg(hregister,R_SUBWHOLE); + hregister:=rg.makeregsize(Tcallparanode(Tcallparanode(left).right).left.location.register,OS_INT); end else begin @@ -323,7 +322,11 @@ begin end. { $Log$ - Revision 1.65 2003-09-03 15:55:01 peter + Revision 1.66 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.65 2003/09/03 15:55:01 peter * NEWRA branch merged Revision 1.64.2.2 2003/08/31 15:46:26 peter diff --git a/compiler/i386/n386obj.pas b/compiler/i386/n386obj.pas index 47f9b2e726..e92b1ce4e5 100644 --- a/compiler/i386/n386obj.pas +++ b/compiler/i386/n386obj.pas @@ -47,9 +47,9 @@ uses { possible calling conventions: - default stdcall cdecl pascal popstack register saveregisters -default(0): OK OK OK(1) OK OK(1) OK OK -virtual(2): OK OK OK(3) OK OK(3) OK OK(4) + default stdcall cdecl pascal register saveregisters +default(0): OK OK OK(1) OK OK OK +virtual(2): OK OK OK(3) OK OK OK(4) (0): set self parameter to correct value @@ -177,7 +177,7 @@ begin adjustselfvalue(procdef,ioffset); { case 1 or 2 } - if (po_clearstack in procdef.procoptions) then + if (procdef.proccalloption in clearstack_pocalls) then begin if po_virtualmethod in procdef.procoptions then begin { case 2 } @@ -228,7 +228,11 @@ initialization end. { $Log$ - Revision 1.21 2003-09-03 15:55:01 peter + Revision 1.22 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.21 2003/09/03 15:55:01 peter * NEWRA branch merged Revision 1.20.2.1 2003/08/29 17:29:00 peter diff --git a/compiler/i386/n386set.pas b/compiler/i386/n386set.pas index 880dd45a31..c040d9d81e 100644 --- a/compiler/i386/n386set.pas +++ b/compiler/i386/n386set.pas @@ -214,8 +214,7 @@ implementation { use the register as base in a reference (JM) } if ranges then begin - pleftreg:=left.location.register; - setsubreg(pleftreg,R_SUBWHOLE); + pleftreg:=rg.makeregsize(left.location.register,OS_INT); cg.a_load_reg_reg(exprasmlist,left.location.size,OS_INT,left.location.register,pleftreg); if opsize <> S_L then emit_const_reg(A_AND,S_L,255,pleftreg); @@ -225,8 +224,7 @@ implementation { otherwise simply use the lower 8 bits (no "and" } { necessary this way) (JM) } begin - pleftreg:=left.location.register; - setsubreg(pleftreg,R_SUBL); + pleftreg:=rg.makeregsize(left.location.register,OS_8); opsize := S_B; end; end @@ -494,10 +492,7 @@ implementation else begin if (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then - begin - pleftreg:=left.location.register; - setsubreg(pleftreg,R_SUBWHOLE); - end + pleftreg:=rg.makeregsize(left.location.register,OS_INT) else pleftreg:=rg.getregisterint(exprasmlist,OS_INT); cg.a_load_loc_reg(exprasmlist,OS_INT,left.location,pleftreg); @@ -689,7 +684,11 @@ begin end. { $Log$ - Revision 1.64 2003-09-05 11:21:39 marco + Revision 1.65 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.64 2003/09/05 11:21:39 marco * applied Peter's patch. Now cycles. Revision 1.63 2003/09/03 15:55:01 peter diff --git a/compiler/i386/rgcpu.pas b/compiler/i386/rgcpu.pas index 03cd01498a..714be86ce4 100644 --- a/compiler/i386/rgcpu.pas +++ b/compiler/i386/rgcpu.pas @@ -31,13 +31,15 @@ unit rgcpu; uses cpubase, cpuinfo, - aasmbase,aasmtai,aasmcpu, + aasmbase,aasmtai, cclasses,globtype,cgbase,cginfo,rgobj; type trgcpu = class(trgobj) fpuvaroffset : byte; + constructor create;override; + { to keep the same allocation order as with the old routines } procedure add_constraints(reg:Tregister);override; @@ -72,7 +74,6 @@ unit rgcpu; { corrects the fpu stack register by ofs } function correct_fpuregister(r : tregister;ofs : byte) : tregister; - end; @@ -80,13 +81,19 @@ unit rgcpu; uses systems, - globals,verbose, - tgobj; + globals,verbose; {************************************************************************} { trgcpu } {************************************************************************} + constructor Trgcpu.create; + begin + inherited create; + cpu_registers:=6; + end; + + procedure Trgcpu.add_constraints(reg:Tregister); var supreg : tsuperregister; @@ -230,22 +237,29 @@ unit rgcpu; function trgcpu.makeregsize(reg: tregister; size: tcgsize): tregister; + var + subreg : tsubregister; begin if getregtype(reg)<>R_INTREGISTER then internalerror(200306032); + subreg:=cgsize2subreg(size); result:=reg; - setsubreg(result,cgsize2subreg(size)); + setsubreg(result,subreg); + add_constraints(result); end; - initialization - rg := trgcpu.create(6); {We use 6 int registers on i386.} + crgobj:=trgcpu; end. { $Log$ - Revision 1.32 2003-09-03 15:55:01 peter + Revision 1.33 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.32 2003/09/03 15:55:01 peter * NEWRA branch merged Revision 1.31.2.3 2003/08/31 13:50:16 daniel diff --git a/compiler/nbas.pas b/compiler/nbas.pas index 78dd9426a9..bbb4ffb8fa 100644 --- a/compiler/nbas.pas +++ b/compiler/nbas.pas @@ -27,7 +27,7 @@ unit nbas; interface uses - cpubase, + cpubase,cginfo, aasmbase,aasmtai,aasmcpu, node, tgobj, @@ -53,6 +53,9 @@ interface p_asm : taasmoutput; currenttai : tai; getposition : boolean; + { Used registers in assembler block } + used_regs_int : tsuperregisterset; + used_regs_fpu : totherregisterset; constructor create(p : taasmoutput);virtual; constructor create_get_position; destructor destroy;override; @@ -180,7 +183,7 @@ implementation verbose,globals,globtype,systems, symconst,symdef,symsym,symutil,defutil,defcmp, pass_1, - nld,ncal,nflw,rgobj,cginfo,cgbase + nld,ncal,nflw,rgobj,cgbase ; @@ -483,6 +486,8 @@ implementation p_asm:=p; getposition:=false; currenttai:=nil; + used_regs_int:=[]; + used_regs_fpu:=[]; end; @@ -531,6 +536,7 @@ implementation begin inherited ppuwrite(ppufile); ppufile.putbyte(byte(getposition)); +{$warning FIXME Add saving of register sets} if not getposition then begin hp:=tai(p_asm.first); @@ -848,7 +854,11 @@ begin end. { $Log$ - Revision 1.60 2003-09-03 15:55:00 peter + Revision 1.61 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.60 2003/09/03 15:55:00 peter * NEWRA branch merged Revision 1.59.2.1 2003/08/27 20:23:55 peter diff --git a/compiler/ncal.pas b/compiler/ncal.pas index 9d5af64b3e..706efc02c1 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -2288,7 +2288,7 @@ type begin { consider it has not inlined if called again inside the args } - procdefinition.proccalloption:=pocall_fpccall; + procdefinition.proccalloption:=pocall_default; firstpass(inlinecode); end; end @@ -2514,7 +2514,11 @@ begin end. { $Log$ - Revision 1.178 2003-09-06 22:27:08 florian + Revision 1.179 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.178 2003/09/06 22:27:08 florian * fixed web bug 2669 * cosmetic fix in printnode * tobjectdef.gettypename implemented diff --git a/compiler/ncgbas.pas b/compiler/ncgbas.pas index 2f354bcf80..3b0b8bd3ee 100644 --- a/compiler/ncgbas.pas +++ b/compiler/ncgbas.pas @@ -138,6 +138,9 @@ interface exit; end; + { Allocate registers used in the assembler block } + rg.allocexplicitregistersint(exprasmlist,used_regs_int); + if inlining_procedure then begin objectlibrary.CreateUsedAsmSymbolList; @@ -220,6 +223,9 @@ interface else exprasmList.concatlist(p_asm); end; + + { Release register used in the assembler block } + rg.deallocexplicitregistersint(exprasmlist,used_regs_int); end; @@ -309,7 +315,11 @@ begin end. { $Log$ - Revision 1.38 2003-09-03 15:55:00 peter + Revision 1.39 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.38 2003/09/03 15:55:00 peter * NEWRA branch merged Revision 1.37.2.1 2003/08/27 20:23:55 peter diff --git a/compiler/ncgcal.pas b/compiler/ncgcal.pas index 515e4033cb..21bf138311 100644 --- a/compiler/ncgcal.pas +++ b/compiler/ncgcal.pas @@ -661,6 +661,7 @@ implementation else iolabel:=nil; +(* regs_to_alloc:=Tprocdef(procdefinition).usedintregisters; {$ifdef i386} @@ -675,24 +676,17 @@ implementation rg.used_in_proc_int:=rg.used_in_proc_int + tprocdef(procdefinition).usedintregisters; rg.used_in_proc_other:=rg.used_in_proc_other + tprocdef(procdefinition).usedotherregisters; {$endif i386} +*) end else begin - regs_to_alloc:=VOLATILE_INTREGISTERS; -{$ifdef i386} - regs_to_push_other := all_otherregisters; -{$else i386} - regs_to_push_other := VOLATILE_FPUREGISTERS; -{$endif i386} -{$ifdef i386} - rg.used_in_proc_int:=VOLATILE_INTREGISTERS; - rg.used_in_proc_other:=all_otherregisters; -{$endif i386} - { no IO check for methods and procedure variables } iolabel:=nil; end; + regs_to_alloc:=paramanager.get_volatile_registers_int(procdefinition.proccalloption); + regs_to_push_other:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption); + { Include Function result registers } if (not is_void(resulttype.def)) then begin @@ -758,7 +752,7 @@ implementation if assigned(left) then begin tcallparanode(left).secondcallparan( - (po_leftright in procdefinition.procoptions),procdefinition.proccalloption, + (procdefinition.proccalloption in pushleftright_pocalls),procdefinition.proccalloption, para_alignment,0); pushparas; @@ -875,7 +869,7 @@ implementation end; { Need to remove the parameters from the stack? } - if (po_clearstack in procdefinition.procoptions) then + if (procdefinition.proccalloption in clearstack_pocalls) then begin { the old pop_size was already included in pushedparasize } pop_size:=pushedparasize; @@ -933,9 +927,9 @@ implementation //reference_reset_symbol(href,iolabel,0); //cg.a_paramaddr_ref(exprasmlist,href,paramanager.getintparaloc(exprasmlist,1)); //paramanager.freeintparaloc(exprasmlist,1); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_IOCHECK'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); end; { restore registers } @@ -1133,8 +1127,12 @@ implementation { 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; +*) + regs_to_push_int:=paramanager.get_volatile_registers_int(procdefinition.proccalloption); + regs_to_push_other:=paramanager.get_volatile_registers_fpu(procdefinition.proccalloption); if (not is_void(resulttype.def)) then begin case procdefinition.funcret_paraloc[callerside].loc of @@ -1155,11 +1153,13 @@ implementation rg.saveusedotherregisters(exprasmlist,pushedother,regs_to_push_other); +(* {$ifdef i386} { give used registers through } rg.used_in_proc_int:=rg.used_in_proc_int + tprocdef(procdefinition).usedintregisters; rg.used_in_proc_other:=rg.used_in_proc_other + tprocdef(procdefinition).usedotherregisters; {$endif i386} +*) { Initialize for pushing the parameters } oldpushedparasize:=pushedparasize; @@ -1174,7 +1174,7 @@ implementation { 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, + (procdefinition.proccalloption in pushleftright_pocalls),procdefinition.proccalloption, 0,procdefinition.parast.address_fixup+procdefinition.parast.datasize); end; aktcallnode:=oldaktcallnode; @@ -1249,9 +1249,9 @@ implementation //reference_reset_symbol(href,iolabel,0); //cg.a_paramaddr_ref(exprasmlist,href,paramanager.getintparaloc(exprasmlist,1)); //paramanager.freeintparaloc(exprasmlist,1); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_IOCHECK'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); end; { restore registers } @@ -1331,7 +1331,11 @@ begin end. { $Log$ - Revision 1.110 2003-09-04 15:39:58 peter + Revision 1.111 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.110 2003/09/04 15:39:58 peter * released useparatemp Revision 1.109 2003/09/03 15:55:00 peter @@ -1403,7 +1407,7 @@ end. Revision 1.95 2003/06/17 16:34:44 jonas * lots of newra fixes (need getfuncretparaloc implementation for i386)! - * renamed all_intregisters to volatile_intregisters and made it + * renamed all_intregisters to paramanager.get_volatile_registers_int(pocall_default) and made it processor dependent Revision 1.94 2003/06/15 16:52:02 jonas diff --git a/compiler/ncgflw.pas b/compiler/ncgflw.pas index f31c19150c..7efe6fc791 100644 --- a/compiler/ncgflw.pas +++ b/compiler/ncgflw.pas @@ -816,16 +816,16 @@ implementation paramanager.freeintparaloc(exprasmlist,3); paramanager.freeintparaloc(exprasmlist,2); paramanager.freeintparaloc(exprasmlist,1); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_RAISEEXCEPTION'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); end else begin - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK'); cg.a_call_name(exprasmlist,'FPC_RERAISE'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); end; end; @@ -863,14 +863,14 @@ implementation procedure cleanupobjectstack; begin - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_param_reg(exprasmlist,OS_ADDR,NR_FUNCTION_RESULT_REG,paramanager.getintparaloc(exprasmlist,1)); paramanager.freeintparaloc(exprasmlist,1); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); end; @@ -975,9 +975,9 @@ implementation } cg.a_param_const(exprasmlist,OS_ADDR,aword(-1),paramanager.getintparaloc(exprasmlist,1)); paramanager.freeintparaloc(exprasmlist,1); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_CATCHES'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); { the destruction of the exception object must be also } { guarded by an exception frame } @@ -995,15 +995,15 @@ implementation try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,doobjectdestroy,false); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paramanager.getintparaloc(exprasmlist,1)); paramanager.freeintparaloc(exprasmlist,1); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); { we don't need to restore esi here because reraise never } { returns } cg.a_call_name(exprasmlist,'FPC_RERAISE'); @@ -1024,9 +1024,9 @@ implementation cg.a_label(exprasmlist,exitexceptlabel); { we must also destroy the address frame which guards } { exception object } - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.g_exception_reason_load(exprasmlist,href); cleanupobjectstack; cg.a_jmp_always(exprasmlist,oldaktexitlabel); @@ -1037,9 +1037,9 @@ implementation cg.a_label(exprasmlist,breakexceptlabel); { we must also destroy the address frame which guards } { exception object } - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.g_exception_reason_load(exprasmlist,href); cleanupobjectstack; cg.a_jmp_always(exprasmlist,oldaktbreaklabel); @@ -1050,9 +1050,9 @@ implementation cg.a_label(exprasmlist,continueexceptlabel); { we must also destroy the address frame which guards } { exception object } - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.g_exception_reason_load(exprasmlist,href); cleanupobjectstack; cg.a_jmp_always(exprasmlist,oldaktcontinuelabel); @@ -1062,9 +1062,9 @@ implementation begin { do some magic for exit in the try block } cg.a_label(exprasmlist,exittrylabel); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.g_exception_reason_load(exprasmlist,href); cg.a_jmp_always(exprasmlist,oldaktexitlabel); end; @@ -1072,9 +1072,9 @@ implementation if fc_break in tryflowcontrol then begin cg.a_label(exprasmlist,breaktrylabel); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.g_exception_reason_load(exprasmlist,href); cg.a_jmp_always(exprasmlist,oldaktbreaklabel); end; @@ -1082,9 +1082,9 @@ implementation if fc_continue in tryflowcontrol then begin cg.a_label(exprasmlist,continuetrylabel); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.g_exception_reason_load(exprasmlist,href); cg.a_jmp_always(exprasmlist,oldaktcontinuelabel); end; @@ -1136,9 +1136,9 @@ implementation reference_reset_symbol(href2,objectlibrary.newasmsymboldata(excepttype.vmt_mangledname),0); cg.a_paramaddr_ref(exprasmlist,href2,paramanager.getintparaloc(exprasmlist,1)); paramanager.freeintparaloc(exprasmlist,1); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_CATCHES'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); { is it this catch? No. go to next onlabel } cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,NR_FUNCTION_RESULT_REG,nextonlabel); @@ -1179,14 +1179,14 @@ implementation try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,doobjectdestroy,false); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_param_reg(exprasmlist, OS_ADDR, NR_FUNCTION_RESULT_REG, paramanager.getintparaloc(exprasmlist,1)); paramanager.freeintparaloc(exprasmlist,1); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); { we don't need to restore esi here because reraise never } { returns } cg.a_call_name(exprasmlist,'FPC_RERAISE'); @@ -1409,7 +1409,11 @@ begin end. { $Log$ - Revision 1.78 2003-09-03 15:55:00 peter + Revision 1.79 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.78 2003/09/03 15:55:00 peter * NEWRA branch merged Revision 1.77 2003/09/03 11:18:36 florian diff --git a/compiler/ncginl.pas b/compiler/ncginl.pas index c88897ce24..88ca99a0b5 100644 --- a/compiler/ncginl.pas +++ b/compiler/ncginl.pas @@ -208,9 +208,9 @@ implementation paramanager.freeintparaloc(exprasmlist,3); paramanager.freeintparaloc(exprasmlist,2); paramanager.freeintparaloc(exprasmlist,1); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_ASSERT'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_label(exprasmlist,truelabel); truelabel:=otlabel; falselabel:=oflabel; @@ -653,7 +653,11 @@ end. { $Log$ - Revision 1.40 2003-09-03 15:55:00 peter + Revision 1.41 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.40 2003/09/03 15:55:00 peter * NEWRA branch merged Revision 1.39.2.1 2003/08/29 17:28:59 peter diff --git a/compiler/ncgmem.pas b/compiler/ncgmem.pas index a6b0a80257..a9728d61d7 100644 --- a/compiler/ncgmem.pas +++ b/compiler/ncgmem.pas @@ -232,9 +232,9 @@ implementation begin cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paramanager.getintparaloc(exprasmlist,1)); paramanager.freeintparaloc(exprasmlist,1); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); end; end; @@ -282,9 +282,9 @@ implementation begin cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paramanager.getintparaloc(exprasmlist,1)); paramanager.freeintparaloc(exprasmlist,1); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER'); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); end; end else if is_interfacecom(left.resulttype.def) then @@ -298,9 +298,9 @@ implementation begin cg.a_param_reg(exprasmlist, OS_ADDR,location.reference.base,paramanager.getintparaloc(exprasmlist,1)); paramanager.freeintparaloc(exprasmlist,1); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_CHECKPOINTER'); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); end; end @@ -482,11 +482,11 @@ implementation begin cg.a_param_loc(exprasmlist,right.location,paramanager.getintparaloc(exprasmlist,2)); cg.a_param_loc(exprasmlist,left.location,paramanager.getintparaloc(exprasmlist,1)); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_DYNARRAY_RANGECHECK'); paramanager.freeintparaloc(exprasmlist,2); paramanager.freeintparaloc(exprasmlist,1); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); end else cg.g_rangecheck(exprasmlist,right.location,right.resulttype.def,left.resulttype.def); @@ -540,10 +540,10 @@ implementation if (cs_check_range in aktlocalswitches) then begin cg.a_param_reg(exprasmlist,OS_ADDR,location.reference.base,paramanager.getintparaloc(exprasmlist,1)); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_CHECKZERO'); paramanager.freeintparaloc(exprasmlist,1); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); end; { in ansistrings/widestrings S[1] is pchar(S)[0] !! } @@ -620,11 +620,11 @@ implementation href:=location.reference; dec(href.offset,7); cg.a_param_ref(exprasmlist,OS_INT,href,paramanager.getintparaloc(exprasmlist,1)); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK'); paramanager.freeintparaloc(exprasmlist,2); paramanager.freeintparaloc(exprasmlist,1); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); end; st_shortstring: @@ -750,11 +750,11 @@ implementation href:=location.reference; dec(href.offset,7); cg.a_param_ref(exprasmlist,OS_INT,href,paramanager.getintparaloc(exprasmlist,1)); - rg.allocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_RANGECHECK'); paramanager.freeintparaloc(exprasmlist,2); paramanager.freeintparaloc(exprasmlist,1); - rg.deallocexplicitregistersint(exprasmlist,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(exprasmlist,paramanager.get_volatile_registers_int(pocall_default)); end; st_shortstring: begin @@ -787,7 +787,11 @@ begin end. { $Log$ - Revision 1.70 2003-09-03 15:55:00 peter + Revision 1.71 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.70 2003/09/03 15:55:00 peter * NEWRA branch merged Revision 1.69.2.1 2003/08/29 17:28:59 peter @@ -817,7 +821,7 @@ end. Revision 1.63 2003/06/17 16:34:44 jonas * lots of newra fixes (need getfuncretparaloc implementation for i386)! - * renamed all_intregisters to volatile_intregisters and made it + * renamed all_intregisters to paramanager.get_volatile_registers_int(pocall_default) and made it processor dependent Revision 1.62 2003/06/13 21:19:30 peter diff --git a/compiler/ncgopt.pas b/compiler/ncgopt.pas index 9f4af38f7d..89b33615f2 100644 --- a/compiler/ncgopt.pas +++ b/compiler/ncgopt.pas @@ -185,7 +185,7 @@ begin end else cg.a_load_const_ref(exprasmlist,OS_8,tordconstnode(right).value,href2); - setsubreg(lengthreg,R_SUBL); + lengthreg:=rg.makeregsize(lengthreg,OS_8); { increase the string length } cg.a_op_const_reg(exprasmlist,OP_ADD,OS_8,1,lengthreg); cg.a_load_reg_ref(exprasmlist,OS_8,OS_8,lengthreg,left.location.reference); @@ -201,7 +201,11 @@ end. { $Log$ - Revision 1.7 2003-09-03 15:55:00 peter + Revision 1.8 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.7 2003/09/03 15:55:00 peter * NEWRA branch merged Revision 1.6.2.1 2003/08/29 17:28:59 peter diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas index 90d68af03d..72b0fb08af 100644 --- a/compiler/ncgutil.pas +++ b/compiler/ncgutil.pas @@ -60,8 +60,10 @@ interface procedure gen_proc_symbol(list:Taasmoutput); procedure gen_stackalloc_code(list:Taasmoutput); + procedure gen_save_used_regs(list : TAAsmoutput); + procedure gen_restore_used_regs(list : TAAsmoutput;usesacc,usesacchi,usesfpu:boolean); procedure gen_entry_code(list:TAAsmoutput;inlined:boolean); - procedure gen_exit_code(list : TAAsmoutput;inlined,usesacc,usesacchi,usesfpu:boolean); + procedure gen_exit_code(list:TAAsmoutput;inlined,usesacc,usesacchi:boolean); (* procedure geninlineentrycode(list : TAAsmoutput;stackframe:longint); @@ -263,15 +265,15 @@ implementation paramanager.freeintparaloc(list,3); paramanager.freeintparaloc(list,2); paramanager.freeintparaloc(list,1); - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(list,'FPC_PUSHEXCEPTADDR'); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); cg.a_param_reg(list,OS_ADDR,NR_FUNCTION_RESULT_REG,paramanager.getintparaloc(list,1)); paramanager.freeintparaloc(list,1); - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(list,'FPC_SETJMP'); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); cg.g_exception_reason_save(list, href); cg.a_cmp_const_reg_label(list,OS_S32,OC_NE,0,NR_FUNCTION_RESULT_REG,exceptlabel); @@ -282,9 +284,9 @@ implementation a : aword ; endexceptlabel : tasmlabel; onlyfree : boolean); begin - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(list,'FPC_POPADDRSTACK'); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); if not onlyfree then begin @@ -315,8 +317,7 @@ implementation { load a smaller size to OS_64 } if l.loc=LOC_REGISTER then begin - hregister:=l.registerlow; - setsubreg(hregister,R_SUBWHOLE); + hregister:=rg.makeregsize(l.registerlow,OS_32); cg.a_load_reg_reg(list,l.size,OS_32,l.registerlow,hregister); end else @@ -1039,9 +1040,9 @@ implementation reference_reset_base(href,current_procinfo.framepointer,hp^.pos); cg.a_paramaddr_ref(list,href,paramanager.getintparaloc(list,1)); paramanager.freeintparaloc(list,1); - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(list,'FPC_ANSISTR_DECR_REF'); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); end; tt_widestring, tt_freewidestring : @@ -1049,18 +1050,18 @@ implementation reference_reset_base(href,current_procinfo.framepointer,hp^.pos); cg.a_paramaddr_ref(list,href,paramanager.getintparaloc(list,1)); paramanager.freeintparaloc(list,1); - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(list,'FPC_WIDESTR_DECR_REF'); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); end; tt_interfacecom : begin reference_reset_base(href,current_procinfo.framepointer,hp^.pos); cg.a_paramaddr_ref(list,href,paramanager.getintparaloc(list,1)); paramanager.freeintparaloc(list,1); - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(list,'FPC_INTF_DECR_REF'); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); end; end; hp:=hp^.next; @@ -1068,6 +1069,10 @@ implementation end; +(* + Return value is in the localst/parast and will be initialized by the + foreach loop (PFV) + procedure initretvalue(list:taasmoutput); var href : treference; @@ -1091,6 +1096,7 @@ implementation end; end; end; +*) procedure gen_load_return_value(list:TAAsmoutput; var uses_acc,uses_acchi,uses_fpu : boolean); @@ -1230,8 +1236,10 @@ implementation cg.g_profilecode(list); end; +(* { initialize return value } initretvalue(list); +*) { initialize local data like ansistrings } case current_procinfo.procdef.proctypeoption of @@ -1278,15 +1286,15 @@ implementation cg.a_paramaddr_ref(list,href,paramanager.getintparaloc(list,1)); paramanager.freeintparaloc(list,2); paramanager.freeintparaloc(list,1); - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_cdecl)); cg.a_call_name(list,'_monstartup'); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_cdecl)); end; { initialize units } - rg.allocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.allocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); cg.a_call_name(list,'FPC_INITIALIZEUNITS'); - rg.deallocexplicitregistersint(list,VOLATILE_INTREGISTERS); + rg.deallocexplicitregistersint(list,paramanager.get_volatile_registers_int(pocall_default)); end; {$ifdef GDB} @@ -1417,6 +1425,62 @@ implementation end; + procedure gen_save_used_regs(list : TAAsmoutput); + begin + { Pure assembler routines need to save the registers themselves } + if (po_assembler in current_procinfo.procdef.procoptions) then + exit; + + { for the save all registers we can simply use a pusha,popa which + push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax } + if (po_saveregisters in current_procinfo.procdef.procoptions) then + cg.g_save_all_registers(list) + else + if current_procinfo.procdef.proccalloption in savestdregs_pocalls then + cg.g_save_standard_registers(list,rg.used_in_proc_int); + +(* + { Save stackpointer value } + if not inlined and + (current_procinfo.framepointer<>NR_STACK_POINTER_REG) and + ((po_savestdregs in current_procinfo.procdef.procoptions) or + (po_saveregisters in current_procinfo.procdef.procoptions)) then + begin + tg.GetTemp(list,POINTER_SIZE,tt_noreuse,current_procinfo.save_stackptr_ref); + cg.a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_STACK_POINTER_REG,current_procinfo.save_stackptr_ref); + end; +*) + end; + + + procedure gen_restore_used_regs(list : TAAsmoutput;usesacc,usesacchi,usesfpu:boolean); + begin + { Pure assembler routines need to save the registers themselves } + if (po_assembler in current_procinfo.procdef.procoptions) then + exit; + +(* + { Restore stackpointer if it was saved } + if not inlined and + (current_procinfo.framepointer<>NR_STACK_POINTER_REG) and + ((po_savestdregs in current_procinfo.procdef.procoptions) or + (po_saveregisters in current_procinfo.procdef.procoptions)) then + begin + cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,current_procinfo.save_stackptr_ref,NR_STACK_POINTER_REG); + tg.UngetTemp(list,current_procinfo.save_stackptr_ref); + end; +*) + + { for the save all registers we can simply use a pusha,popa which + push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax } + if (po_saveregisters in current_procinfo.procdef.procoptions) then + cg.g_restore_all_registers(list,usesacc,usesacchi) + else + if current_procinfo.procdef.proccalloption in savestdregs_pocalls then + cg.g_restore_standard_registers(list,rg.used_in_proc_int); + end; + + procedure gen_entry_code(list:TAAsmoutput;inlined:boolean); var href : treference; @@ -1470,29 +1534,10 @@ implementation end; end; end; - - { for the save all registers we can simply use a pusha,popa which - push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax } - if (po_saveregisters in current_procinfo.procdef.procoptions) then - cg.g_save_all_registers(list) - else - { should we save edi,esi,ebx like C ? } - if (po_savestdregs in current_procinfo.procdef.procoptions) then - cg.g_save_standard_registers(list,current_procinfo.procdef.usedintregisters); - - { Save stackpointer value } - if not inlined and - (current_procinfo.framepointer<>NR_STACK_POINTER_REG) and - ((po_savestdregs in current_procinfo.procdef.procoptions) or - (po_saveregisters in current_procinfo.procdef.procoptions)) then - begin - tg.GetTemp(list,POINTER_SIZE,tt_noreuse,current_procinfo.save_stackptr_ref); - cg.a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_STACK_POINTER_REG,current_procinfo.save_stackptr_ref); - end; end; - procedure gen_exit_code(list : TAAsmoutput;inlined,usesacc,usesacchi,usesfpu:boolean); + procedure gen_exit_code(list:TAAsmoutput;inlined,usesacc,usesacchi:boolean); var {$ifdef GDB} stabsendlabel : tasmlabel; @@ -1511,25 +1556,6 @@ implementation end; {$endif GDB} - { Restore stackpointer if it was saved } - if not inlined and - (current_procinfo.framepointer<>NR_STACK_POINTER_REG) and - ((po_savestdregs in current_procinfo.procdef.procoptions) or - (po_saveregisters in current_procinfo.procdef.procoptions)) then - begin - cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,current_procinfo.save_stackptr_ref,NR_STACK_POINTER_REG); - tg.UngetTemp(list,current_procinfo.save_stackptr_ref); - end; - - { for the save all registers we can simply use a pusha,popa which - push edi,esi,ebp,esp(ignored),ebx,edx,ecx,eax } - if (po_saveregisters in current_procinfo.procdef.procoptions) then - cg.g_restore_all_registers(list,usesacc,usesacchi) - else - { should we restore edi ? } - if (po_savestdregs in current_procinfo.procdef.procoptions) then - cg.g_restore_standard_registers(list,current_procinfo.procdef.usedintregisters); - {$ifndef powerpc} { remove stackframe } if not inlined then @@ -1552,7 +1578,7 @@ implementation cg.g_interrupt_stackframe_exit(list,usesacc,usesacchi) else begin - if (po_clearstack in current_procinfo.procdef.procoptions) then + if current_procinfo.procdef.proccalloption in clearstack_pocalls then begin retsize:=0; if paramanager.ret_in_param(current_procinfo.procdef.rettype.def,current_procinfo.procdef.proccalloption) then @@ -1779,7 +1805,11 @@ implementation end. { $Log$ - Revision 1.139 2003-09-03 15:55:01 peter + Revision 1.140 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.139 2003/09/03 15:55:01 peter * NEWRA branch merged Revision 1.138 2003/09/03 11:18:37 florian diff --git a/compiler/nld.pas b/compiler/nld.pas index be907c8ebe..83ecdcc129 100644 --- a/compiler/nld.pas +++ b/compiler/nld.pas @@ -488,7 +488,7 @@ implementation { we need a register for call by reference parameters } if (tvarsym(symtableentry).varspez in [vs_var,vs_out]) or ((tvarsym(symtableentry).varspez=vs_const) and - paramanager.push_addr_param(tvarsym(symtableentry).vartype.def,pocall_none)) or + paramanager.push_addr_param(tvarsym(symtableentry).vartype.def,pocall_default)) or { call by value open arrays are also indirect addressed } is_open_array(tvarsym(symtableentry).vartype.def) then registers32:=1; @@ -1287,7 +1287,11 @@ begin end. { $Log$ - Revision 1.103 2003-07-08 15:20:56 peter + Revision 1.104 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.103 2003/07/08 15:20:56 peter * don't allow add/assignments for formaldef * formaldef size changed to 0 diff --git a/compiler/nmat.pas b/compiler/nmat.pas index 8b179b33f5..e2471ec986 100644 --- a/compiler/nmat.pas +++ b/compiler/nmat.pas @@ -238,11 +238,10 @@ implementation function tmoddivnode.first_moddivint: tnode; +{$ifdef cpuneedsdiv32helper} var procname: string[31]; begin -{$ifdef cpuneedsdiv32helper} - begin result := nil; { otherwise create a call to a helper } @@ -264,9 +263,10 @@ implementation firstpass(result); end; {$else cpuneedsdiv32helper} + begin result:=nil; -{$endif cpuneedsdiv32helper} end; +{$endif cpuneedsdiv32helper} function tmoddivnode.first_moddiv64bitint: tnode; @@ -831,7 +831,11 @@ begin end. { $Log$ - Revision 1.50 2003-09-03 11:18:37 florian + Revision 1.51 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.50 2003/09/03 11:18:37 florian * fixed arm concatcopy + arm support in the common compiler sources added * moved some generic cg code around diff --git a/compiler/paramgr.pas b/compiler/paramgr.pas index 0fce019e13..2909b1df19 100644 --- a/compiler/paramgr.pas +++ b/compiler/paramgr.pas @@ -29,7 +29,7 @@ unit paramgr; interface uses - cpubase, + cpubase,cginfo, aasmtai, globtype, symconst,symtype,symdef; @@ -70,6 +70,8 @@ unit paramgr; @param(list Current assembler list) @param(nr Parameter number of routine, starting from 1) } + function get_volatile_registers_int(calloption : tproccalloption):tsuperregisterset;virtual; + function get_volatile_registers_fpu(calloption : tproccalloption):tsuperregisterset;virtual; function getintparaloc(list: taasmoutput; nr : longint) : tparalocation;virtual;abstract; {# frees a parameter location allocated with getintparaloc @@ -123,7 +125,7 @@ implementation cpuinfo,globals,systems, symbase,symsym, rgobj, - defutil,cgbase,cginfo,verbose; + defutil,cgbase,verbose; { true if uses a parameter as return value } function tparamanager.ret_in_param(def : tdef;calloption : tproccalloption) : boolean; @@ -244,6 +246,18 @@ implementation end; + function tparamanager.get_volatile_registers_int(calloption : tproccalloption):tsuperregisterset; + begin + result:=[]; + end; + + + function tparamanager.get_volatile_registers_fpu(calloption : tproccalloption):tsuperregisterset; + begin + result:=[]; + end; + + procedure tparamanager.allocparaloc(list: taasmoutput; const loc: tparalocation); begin case loc.loc of @@ -348,7 +362,11 @@ end. { $Log$ - Revision 1.52 2003-09-04 15:39:58 peter + Revision 1.53 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.52 2003/09/04 15:39:58 peter * released useparatemp Revision 1.51 2003/09/03 15:55:01 peter diff --git a/compiler/pdecsub.pas b/compiler/pdecsub.pas index 90afd354b0..b66d31bb04 100644 --- a/compiler/pdecsub.pas +++ b/compiler/pdecsub.pas @@ -273,7 +273,7 @@ implementation { Give a warning that cdecl routines does not include high() support } if (pd.proccalloption in [pocall_cdecl,pocall_cppdecl]) and - paramanager.push_high_param(currpara.paratype.def,pocall_fpccall) then + paramanager.push_high_param(currpara.paratype.def,pocall_default) then begin if is_open_string(currpara.paratype.def) then Message(parser_w_cdecl_no_openstring); @@ -965,7 +965,7 @@ begin begin Message1(parser_w_not_supported_for_inline,'array of const'); Message(parser_w_inlining_disabled); - pd.proccalloption:=pocall_fpccall; + pd.proccalloption:=pocall_default; end; end; hp:=tparaitem(hp.next); @@ -1185,7 +1185,7 @@ type end; const {Should contain the number of procedure directives we support.} - num_proc_directives=35; + num_proc_directives=34; proc_direcdata:array[1..num_proc_directives] of proc_dir_rec= ( ( @@ -1277,7 +1277,7 @@ const pooption : []; mutexclpocall : []; mutexclpotype : []; - mutexclpo : [po_external,po_leftright] + mutexclpo : [po_external] ),( idtok:_FORWARD; pd_flags : [pd_implemen,pd_notobject,pd_notobjintf]; @@ -1288,14 +1288,14 @@ const mutexclpotype : []; mutexclpo : [po_external] ),( - idtok:_FPCCALL; + idtok:_OLDFPCCALL; pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar]; handler : nil; - pocall : pocall_fpccall; + pocall : pocall_oldfpccall; pooption : []; mutexclpocall : []; mutexclpotype : []; - mutexclpo : [po_leftright] + mutexclpo : [] ),( idtok:_INLINE; pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobjintf]; @@ -1322,17 +1322,17 @@ const pooption : []; mutexclpocall : []; mutexclpotype : [potype_constructor,potype_destructor,potype_operator]; - mutexclpo : [po_exports,po_external,po_interrupt,po_assembler,po_iocheck,po_leftright] + mutexclpo : [po_exports,po_external,po_interrupt,po_assembler,po_iocheck] ),( idtok:_INTERRUPT; pd_flags : [pd_implemen,pd_body,pd_notobject,pd_notobjintf]; handler : {$ifdef FPCPROCVAR}@{$endif}pd_interrupt; pocall : pocall_none; pooption : [po_interrupt]; - mutexclpocall : [pocall_internproc,pocall_cdecl,pocall_cppdecl, - pocall_inline,pocall_pascal,pocall_far16,pocall_fpccall]; + mutexclpocall : [pocall_internproc,pocall_cdecl,pocall_cppdecl,pocall_stdcall, + pocall_inline,pocall_pascal,pocall_far16,pocall_oldfpccall]; mutexclpotype : [potype_constructor,potype_destructor,potype_operator]; - mutexclpo : [po_external,po_leftright,po_clearstack] + mutexclpo : [po_external] ),( idtok:_IOCHECK; pd_flags : [pd_implemen,pd_body,pd_notobjintf]; @@ -1387,15 +1387,6 @@ const mutexclpocall : []; mutexclpotype : [potype_constructor,potype_destructor]; mutexclpo : [po_external] - ),( - idtok:_POPSTACK; - pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar]; - handler : nil; - pocall : pocall_none; - pooption : [po_clearstack]; - mutexclpocall : [pocall_inline,pocall_internproc,pocall_stdcall]; - mutexclpotype : [potype_constructor,potype_destructor]; - mutexclpo : [po_assembler,po_external] ),( idtok:_PUBLIC; pd_flags : [pd_implemen,pd_body,pd_notobject,pd_notobjintf]; @@ -1482,7 +1473,7 @@ const pd_flags : [pd_interface,pd_implemen,pd_body,pd_procvar]; handler : nil; pocall : pocall_cppdecl; - pooption : [po_savestdregs]; + pooption : []; mutexclpocall : []; mutexclpotype : [potype_constructor,potype_destructor]; mutexclpo : [po_assembler,po_external,po_virtualmethod] @@ -1493,9 +1484,9 @@ const pocall : pocall_none; pooption : [po_varargs]; mutexclpocall : [pocall_internproc,pocall_stdcall,pocall_register, - pocall_inline,pocall_far16,pocall_fpccall]; + pocall_inline,pocall_far16,pocall_oldfpccall]; mutexclpotype : []; - mutexclpo : [po_assembler,po_interrupt,po_leftright] + mutexclpo : [po_assembler,po_interrupt] ),( idtok:_COMPILERPROC; pd_flags : [pd_interface,pd_implemen,pd_body,pd_notobjintf]; @@ -1656,9 +1647,6 @@ const case pd.proccalloption of pocall_cdecl : begin - { use popstack and save std registers } - include(pd.procoptions,po_clearstack); - include(pd.procoptions,po_savestdregs); { set mangledname } if (pd.deftype=procdef) then begin @@ -1677,9 +1665,6 @@ const end; pocall_cppdecl : begin - { use popstack and save std registers } - include(pd.procoptions,po_clearstack); - include(pd.procoptions,po_savestdregs); { set mangledname } if (pd.deftype=procdef) then begin @@ -1693,27 +1678,18 @@ const end; pocall_stdcall : begin - include(pd.procoptions,po_savestdregs); if (pd.deftype=procdef) then begin { Adjust alignment to match cdecl or stdcall } pd.parast.dataalignment:=std_param_align; end; end; - pocall_safecall : - begin - include(pd.procoptions,po_savestdregs); - end; pocall_compilerproc : begin if (pd.deftype<>procdef) then internalerror(200110232); tprocdef(pd).setmangledname(lower(tprocdef(pd).procsym.name)); end; - pocall_pascal : - begin - include(pd.procoptions,po_leftright); - end; pocall_register : begin Message1(parser_w_proc_directive_ignored,'REGISTER'); @@ -1725,9 +1701,6 @@ const end; pocall_palmossyscall : begin - { use popstack and save std registers } - include(pd.procoptions,po_clearstack); - include(pd.procoptions,po_savestdregs); if (pd.deftype=procdef) then begin { Adjust positions of args for cdecl or stdcall } @@ -1739,7 +1712,7 @@ const if not(cs_support_inline in aktmoduleswitches) then begin Message(parser_e_proc_inline_not_supported); - pd.proccalloption:=pocall_fpccall; + pd.proccalloption:=pocall_default; end; end; end; @@ -1795,7 +1768,7 @@ const { Calculate symtable addresses } st:=pd.parast; - if po_leftright in pd.procoptions then + if pd.proccalloption in pushleftright_pocalls then begin { pushed from left to right, so the in reverse order on the stack } @@ -2022,7 +1995,7 @@ const { Check procedure options, Delphi requires that class is repeated in the implementation for class methods } if (m_fpc in aktmodeswitches) then - po_comp:=[po_varargs,po_methodpointer,po_interrupt,po_clearstack] + po_comp:=[po_varargs,po_methodpointer,po_interrupt] else po_comp:=[po_classmethod,po_methodpointer]; @@ -2168,7 +2141,11 @@ const end. { $Log$ - Revision 1.130 2003-09-03 11:18:37 florian + Revision 1.131 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.130 2003/09/03 11:18:37 florian * fixed arm concatcopy + arm support in the common compiler sources added * moved some generic cg code around diff --git a/compiler/pmodules.pas b/compiler/pmodules.pas index 454d6fef25..6f3b14deec 100644 --- a/compiler/pmodules.pas +++ b/compiler/pmodules.pas @@ -40,7 +40,7 @@ implementation globals,verbose,fmodule,finput,fppu, symconst,symbase,symtype,symdef,symsym,symtable, aasmbase,aasmtai,aasmcpu, - cgbase,cpuinfo, + cgbase,cpuinfo,rgobj, ncgutil, link,assemble,import,export,gendef,ppu,comprsrc, cresstr,cpubase, @@ -725,6 +725,8 @@ implementation current_procinfo:=cprocinfo.create(nil); current_module.procinfo:=current_procinfo; current_procinfo.procdef:=pd; + { start register allocator } + rg:=crgobj.create; { return procdef } create_main_proc:=pd; end; @@ -737,6 +739,8 @@ implementation assigned(current_procinfo.parent) or not(current_procinfo.procdef=pd) then internalerror(200304276); + { remove register allocator } + rg.free; { remove procinfo } current_module.procinfo:=nil; current_procinfo.free; @@ -786,11 +790,15 @@ implementation usesfpu:=false; usesacchi:=false; gen_load_return_value(list,usesacc,usesacchi,usesfpu); + { Add save and restore of used registers } + gen_save_used_regs(templist); + list.insertlistafter(headertai,templist); + gen_restore_used_regs(list,usesacc,usesacchi,usesfpu); { Add stack allocation code after header } gen_stackalloc_code(templist); list.insertlistafter(headertai,templist); { Add exit code at the end } - gen_exit_code(list,false,usesacc,usesacchi,usesfpu); + gen_exit_code(list,false,usesacc,usesacchi); release_main_proc(pd); templist.free; end; @@ -1322,9 +1330,6 @@ implementation { Win32 startup code needs a single name } // if (target_info.system in [system_i386_win32,system_i386_wdosx]) then pd.aliasnames.insert('PASCALMAIN'); - { this code is called from C so we need to save some - registers } - include(pd.procoptions,po_savestdregs); end else begin @@ -1465,7 +1470,11 @@ implementation end. { $Log$ - Revision 1.121 2003-09-05 17:41:12 florian + Revision 1.122 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.121 2003/09/05 17:41:12 florian * merged Wiktor's Watcom patches in 1.1 Revision 1.120 2003/08/23 22:29:24 peter diff --git a/compiler/pstatmnt.pas b/compiler/pstatmnt.pas index 737ab76c9e..90cd37f455 100644 --- a/compiler/pstatmnt.pas +++ b/compiler/pstatmnt.pas @@ -800,7 +800,7 @@ implementation Begin Message1(parser_w_not_supported_for_inline,'direct asm'); Message(parser_w_inlining_disabled); - current_procinfo.procdef.proccalloption:=pocall_fpccall; + current_procinfo.procdef.proccalloption:=pocall_default; End; asmstat:=tasmnode(radirect.assemble); end; @@ -814,7 +814,7 @@ implementation { END is read, got a list of changed registers? } if try_to_consume(_LECKKLAMMER) then begin - rg.used_in_proc_other:=ALL_OTHERREGISTERS; + asmstat.used_regs_fpu:=ALL_OTHERREGISTERS; if token<>_RECKKLAMMER then begin repeat @@ -823,7 +823,7 @@ implementation if reg<>NR_NO then begin if getregtype(reg)=R_INTREGISTER then - include(rg.used_in_proc_int,getsupreg(reg)); + include(asmstat.used_regs_int,getsupreg(reg)); end else Message(asmr_e_invalid_register); @@ -836,8 +836,8 @@ implementation end else begin - rg.used_in_proc_int:=VOLATILE_INTREGISTERS; - rg.used_in_proc_other:=ALL_OTHERREGISTERS; + asmstat.used_regs_int:=paramanager.get_volatile_registers_int(current_procinfo.procdef.proccalloption); + asmstat.used_regs_fpu:=ALL_OTHERREGISTERS; end; { mark the start and the end of the assembler block @@ -1181,7 +1181,11 @@ implementation end. { $Log$ - Revision 1.107 2003-09-03 15:55:01 peter + Revision 1.108 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.107 2003/09/03 15:55:01 peter * NEWRA branch merged Revision 1.106.2.3 2003/08/31 15:46:26 peter @@ -1198,7 +1202,7 @@ end. Revision 1.105 2003/06/17 16:34:44 jonas * lots of newra fixes (need getfuncretparaloc implementation for i386)! - * renamed all_intregisters to volatile_intregisters and made it + * renamed all_intregisters to paramanager.get_volatile_registers_int(pocall_default) and made it processor dependent Revision 1.104 2003/06/13 21:19:31 peter diff --git a/compiler/psub.pas b/compiler/psub.pas index a9da67e302..7becc8efc8 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -574,6 +574,7 @@ implementation procedure tcgprocinfo.generate_code; var + oldrg : trgobj; oldprocinfo : tprocinfo; oldaktmaxfpuregisters : longint; oldfilepos : tfileposinfo; @@ -591,6 +592,7 @@ implementation exit; oldprocinfo:=current_procinfo; + oldrg:=rg; oldfilepos:=aktfilepos; oldaktmaxfpuregisters:=aktmaxfpuregisters; @@ -604,8 +606,11 @@ implementation { add parast/localst to symtablestack } add_to_symtablestack; - { reset the temporary memory } - rg.cleartempgen; + { set the start offset to the start of the temp area in the stack } + tg.setfirsttemp(firsttemp_offset); + + { Create register allocator } + rg:=crgobj.create; {$warning FIXME!!} { FIXME!! If a procedure contains assembler blocks (or is pure assembler), } @@ -615,21 +620,14 @@ implementation { assembler procedures... For non-i386, the changed registers are even } { always all volatile registers (JM) } {$ifdef i386} - if not(po_assembler in current_procinfo.procdef.procoptions) then + if (po_assembler in current_procinfo.procdef.procoptions) then begin - rg.used_in_proc_int:=[{RS_STACK_POINTER_REG}]; - rg.used_in_proc_other:=[]; - end - else -{$endif i386} - begin - rg.used_in_proc_int:={$ifdef i386}[]{$else}VOLATILE_INTREGISTERS{$endif}; - rg.used_in_proc_other:=VOLATILE_FPUREGISTERS; + rg.used_in_proc_int:=paramanager.get_volatile_registers_int(pocall_oldfpccall); + rg.used_in_proc_other:=paramanager.get_volatile_registers_int(pocall_oldfpccall); end; +{$endif i386} - { set the start offset to the start of the temp area in the stack } - tg.setfirsttemp(firsttemp_offset); - + { generate code for the body } generatecode(code); { first generate entry and initialize code with the correct @@ -682,21 +680,21 @@ implementation { The procedure body is finished, we can now allocate the registers } -{$ifdef ra_debug2} - rg.writegraph; -{$endif} if not(cs_no_regalloc in aktglobalswitches) then begin {Do register allocation.} spillingcounter:=0; repeat +{$ifdef EXTDEBUG} +// if aktfilepos.line=1207 then +// rg.writegraph(spillingcounter); +{$endif EXTDEBUG} rg.prepare_colouring; rg.colour_registers; rg.epilogue_colouring; if rg.spillednodes='' then break; - if not rg.spill_registers(aktproccode,rg.spillednodes) then - break; + rg.spill_registers(aktproccode,rg.spillednodes); inc(spillingcounter); if spillingcounter>maxspillingcounter then internalerror(200309041); @@ -713,17 +711,23 @@ implementation end; translate_regvars(aktproccode,rg.colour); + { Add save and restore of used registers } + gen_save_used_regs(templist); + aktproccode.insertlistafter(headertai,templist); + gen_restore_used_regs(aktproccode,usesacc,usesacchi,usesfpu); { Add stack allocation code after header } gen_stackalloc_code(templist); aktproccode.insertlistafter(headertai,templist); { Add exit code at the end } - gen_exit_code(templist,false,usesacc,usesacchi,usesfpu); + gen_exit_code(templist,false,usesacc,usesacchi); aktproccode.concatlist(templist); +(* { now all the registers used are known } { Remove all imaginary registers from the used list.} - procdef.usedintregisters:=rg.used_in_proc_int*VOLATILE_INTREGISTERS-rg.savedintbyproc; + procdef.usedintregisters:=rg.used_in_proc_int*paramanager.get_volatile_registers_int(pocall_default)-rg.preserved_by_proc_int; procdef.usedotherregisters:=rg.used_in_proc_other; +*) { save local data (casetable) also in the same file } if assigned(aktlocaldata) and @@ -745,8 +749,6 @@ implementation codesegment.concat(Tai_cut.Create); codesegment.concatlist(aktproccode); - { all registers can be used again } - rg.resetusableregisters; { only now we can remove the temps } tg.resettempgen; @@ -754,7 +756,9 @@ implementation remove_from_symtablestack; { restore } + rg.free; templist.free; + rg:=oldrg; aktmaxfpuregisters:=oldaktmaxfpuregisters; aktfilepos:=oldfilepos; current_procinfo:=oldprocinfo; @@ -873,11 +877,6 @@ implementation { constant symbols are inserted in this symboltable } constsymtable:=symtablestack; - { reset the temporary memory } - rg.cleartempgen; - rg.used_in_proc_int:=[]; - rg.used_in_proc_other:=[]; - { save entry info } entrypos:=aktfilepos; entryswitches:=aktlocalswitches; @@ -1216,7 +1215,7 @@ implementation Begin Message1(parser_w_not_supported_for_inline,tokenstring(t)); Message(parser_w_inlining_disabled); - current_procinfo.procdef.proccalloption:=pocall_fpccall; + current_procinfo.procdef.proccalloption:=pocall_default; End; end; @@ -1315,7 +1314,11 @@ begin end. { $Log$ - Revision 1.141 2003-09-04 14:46:12 peter + Revision 1.142 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.141 2003/09/04 14:46:12 peter * abort with IE when spilling requires > 20 loops Revision 1.140 2003/09/03 15:55:01 peter @@ -1371,7 +1374,7 @@ end. Revision 1.129 2003/06/17 16:34:44 jonas * lots of newra fixes (need getfuncretparaloc implementation for i386)! - * renamed all_intregisters to volatile_intregisters and made it + * renamed all_intregisters to paramanager.get_volatile_registers_int(pocall_default) and made it processor dependent Revision 1.128 2003/06/14 14:53:50 jonas diff --git a/compiler/regvars.pas b/compiler/regvars.pas index dfad0305f3..857f7da30b 100644 --- a/compiler/regvars.pas +++ b/compiler/regvars.pas @@ -554,7 +554,7 @@ implementation end else begin - setsubreg(reg,cgsize2subreg(OS_INT)); + reg:=rg.makeregsize(reg,OS_INT); regidx:=findreg_by_number(reg); if (rg.regvar_loaded_other[regidx]) then asml.concat(tai_regalloc.dealloc(reg)); @@ -610,7 +610,11 @@ end. { $Log$ - Revision 1.63 2003-09-03 15:55:01 peter + Revision 1.64 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.63 2003/09/03 15:55:01 peter * NEWRA branch merged Revision 1.62.2.2 2003/08/29 17:28:59 peter diff --git a/compiler/rgobj.pas b/compiler/rgobj.pas index 3b214cf817..67d26a0adc 100644 --- a/compiler/rgobj.pas +++ b/compiler/rgobj.pas @@ -178,9 +178,8 @@ unit rgobj; { Contains the registers which are really used by the proc itself. It doesn't take care of registers used by called procedures } - savedintbyproc, - used_in_proc_int, - usedaddrinproc : Tsuperregisterset; + preserved_by_proc_int, + used_in_proc_int : Tsuperregisterset; used_in_proc_other : totherregisterset; reg_pushes_other : regvarother_longintarray; @@ -194,7 +193,8 @@ unit rgobj; { tries to hold the amount of times which the current tree is processed } t_times: longint; - constructor create(Acpu_registers:byte); + constructor create;virtual; + destructor destroy;virtual; {# Allocate a general purpose register @@ -287,14 +287,6 @@ unit rgobj; } procedure ungetreference(list: taasmoutput; const ref : treference); virtual; - {# Reset the register allocator information (usable registers etc). - Please note that it is mortal sins to call cleartempgen during - graph colouring (that is between prepare_colouring and - epilogue_colouring). - } - - procedure cleartempgen;virtual; - {# Convert a register to a specified register size, and return that register size } function makeregsize(reg: tregister; size: tcgsize): tregister; virtual; @@ -338,9 +330,9 @@ unit rgobj; procedure saveUnusedState(var state: pointer);virtual; procedure restoreUnusedState(var state: pointer);virtual; -{$ifdef ra_debug2} - procedure writegraph; -{$endif ra_debug2} +{$ifdef EXTDEBUG} + procedure writegraph(loopidx:longint); +{$endif EXTDEBUG} procedure add_move_instruction(instr:Taicpu); procedure prepare_colouring; procedure epilogue_colouring; @@ -395,6 +387,8 @@ unit rgobj; procedure clear_interferences(u:Tsuperregister); end; + trgobjclass = class of trgobj; + const {# This value is used in tsaved. If the array value is equal to this, then this means that this register is not used. @@ -403,7 +397,8 @@ unit rgobj; var {# This is the class instance used to access the register allocator class } - rg: trgobj; + crgobj : trgobjclass; + rg : trgobj; { trerefence handling } @@ -462,11 +457,11 @@ unit rgobj; implementation uses - systems,{$ifdef ra_debug2}fmodule,{$endif} + systems,{$ifdef EXTDEBUG}fmodule,{$endif} globals,verbose, cgobj,tgobj,regvars; - constructor Trgobj.create(Acpu_registers:byte); + constructor Trgobj.create; begin used_in_proc_int := []; @@ -475,12 +470,17 @@ unit rgobj; resetusableregisters; lastintreg:=0; maxintreg:=first_int_imreg; - {What madman decided to change the code like this: (??) - cpu_registers:=last_int_supreg-first_int_supreg+1; - The amount of registers available for register allocation is - allmost allways smaller than the amount of registers that exists! - Therefore: } - cpu_registers:=Acpu_registers; + cpu_registers:=0; + unusedregsint:=[0..254]; { 255 (RS_INVALID) can't be used } + unusedregsfpu:=usableregsfpu; + unusedregsmm:=usableregsmm; + countunusedregsfpu:=countusableregsfpu; + countunusedregsmm:=countusableregsmm; +{$ifdef powerpc} + preserved_by_proc_int:=[RS_R13..RS_R31]; +{$else powerpc} + preserved_by_proc_int:=[]; +{$endif powerpc} fillchar(igraph,sizeof(igraph),0); fillchar(degree,sizeof(degree),0); {Precoloured nodes should have an infinite degree, which we can approach @@ -488,9 +488,26 @@ unit rgobj; fillchar(movelist,sizeof(movelist),0); worklist_moves:=Tlinkedlist.create; abtlist:=''; + fillchar(colour,sizeof(colour),RS_INVALID); end; + destructor Trgobj.destroy; + + var i:Tsuperregister; + + begin + for i:=low(Tsuperregister) to high(Tsuperregister) do + begin + if igraph.adjlist[i]<>nil then + dispose(igraph.adjlist[i]); + if movelist[i]<>nil then + dispose(movelist[i]); + end; + worklist_moves.free; + end; + + function trgobj.getregistergenother(list: taasmoutput; const lowreg, highreg: tsuperregister; var unusedregs: tsuperregisterset; var countunusedregs: byte): tregister; var @@ -541,6 +558,7 @@ unit rgobj; if i>maxintreg then maxintreg:=i; add_edges_used(i); + add_constraints(r); exit; end; until i=lastintreg; @@ -581,6 +599,7 @@ unit rgobj; include(unusedregs,supreg); list.concat(tai_regalloc.dealloc(r)); add_edges_used(supreg); + add_constraints(r); end; @@ -590,10 +609,11 @@ unit rgobj; begin subreg:=cgsize2subreg(size); + { Leave 2 imaginary registers free for spilling (PFV) } result:=getregistergenint(list, subreg, first_int_imreg, - last_int_imreg, + last_int_imreg-2, used_in_proc_int, unusedregsint); add_constraints(getregisterint); @@ -625,6 +645,7 @@ unit rgobj; include(used_in_proc_int,supreg); list.concat(tai_regalloc.alloc(r)); add_edges_used(supreg); + add_constraints(r); end else {$ifndef ALLOWDUPREG} @@ -772,42 +793,6 @@ unit rgobj; end; - procedure Trgobj.cleartempgen; - - var i:Tsuperregister; - - begin - countunusedregsfpu:=countusableregsfpu; - countunusedregsmm:=countusableregsmm; - lastintreg:=0; - maxintreg:=first_int_imreg; - unusedregsint:=[0..255]; - unusedregsfpu:=usableregsfpu; - unusedregsmm:=usableregsmm; -{$ifdef powerpc} - savedintbyproc:=[RS_R13..RS_R31]; -{$else powerpc} - savedintbyproc:=[]; -{$endif powerpc} - for i:=low(Tsuperregister) to high(Tsuperregister) do - begin - if igraph.adjlist[i]<>nil then - dispose(igraph.adjlist[i]); - if movelist[i]<>nil then - dispose(movelist[i]); - end; - fillchar(movelist,sizeof(movelist),0); - fillchar(igraph,sizeof(igraph),0); - fillchar(degree,sizeof(degree),0); - {Precoloured nodes should have an infinite degree, which we can approach - by 255.} - for i:=first_int_supreg to last_int_supreg do - degree[i]:=255; - worklist_moves.clear; - abtlist:=''; - end; - - procedure trgobj.ungetreference(list : taasmoutput; const ref : treference); begin @@ -1164,6 +1149,7 @@ unit rgobj; end; end; + procedure Trgobj.add_edges_used(u:Tsuperregister); var i:Tsuperregister; @@ -1174,8 +1160,8 @@ unit rgobj; add_edge(u,i); end; -{$ifdef ra_debug2} - procedure Trgobj.writegraph; +{$ifdef EXTDEBUG} + procedure Trgobj.writegraph(loopidx:longint); {This procedure writes out the current interference graph in the register allocator.} @@ -1185,7 +1171,7 @@ unit rgobj; i,j:Tsuperregister; begin - assign(f,'igraph.'+Lower(current_module.modulename^)); + assign(f,'igraph'+tostr(loopidx)); rewrite(f); writeln(f,'Interference graph'); writeln(f); @@ -1210,7 +1196,7 @@ unit rgobj; end; close(f); end; -{$endif ra_debug2} +{$endif EXTDEBUG} procedure Trgobj.add_to_movelist(u:Tsuperregister;data:Tlinkedlistitem); @@ -1750,11 +1736,10 @@ unit rgobj; freeze else if length(spillworklist)<>0 then select_spill; - until (length(simplifyworklist) or - byte(not(worklist_moves.empty)) or - length(freezeworklist) or - length(spillworklist) - )=0; + until (length(simplifyworklist)=0) and + worklist_moves.empty and + (length(freezeworklist)=0) and + (length(spillworklist)=0); assign_colours; end; @@ -1911,7 +1896,11 @@ unit rgobj; i:=first_int_imreg else inc(i); - if (i in unusedregsint) and (pos(char(i),abtlist)=0) then + if (i in unusedregsint) and + (pos(char(i),abtlist)=0) and + (pos(char(i),spillednodes)=0) and + ((rg.colour[i] in unusedregsint) or + (rg.colour[i]=RS_INVALID)) then begin exclude(unusedregsint,i); include(used_in_proc_int,i); @@ -1920,12 +1909,12 @@ unit rgobj; list.insert(Tai_regalloc.alloc(r)) else list.insertafter(Tai_regalloc.alloc(r),position); - result:=r; lastintreg:=i; if i>maxintreg then maxintreg:=i; add_edges_used(i); - add_constraints(result); + add_constraints(r); + result:=r; exit; end; until i=lastintreg; @@ -1958,6 +1947,7 @@ unit rgobj; var i:Tsuperregister; r:Tregister; + subreg:tsubregister; found:boolean; begin @@ -1986,19 +1976,20 @@ unit rgobj; begin exclude(unusedregsint,i); include(used_in_proc_int,i); - r:=newreg(R_INTREGISTER,i,cgsize2subreg(size)); + subreg:=cgsize2subreg(size); + r:=newreg(R_INTREGISTER,i,subreg); list.concat(Tai_regalloc.alloc(r)); getabtregisterint:=r; lastintreg:=i; if i>maxintreg then maxintreg:=i; add_edges_used(i); + add_constraints(r); if pos(char(i),abtlist)=0 then abtlist:=abtlist+char(i); end else internalerror(10); - add_constraints(getabtregisterint); end; procedure Trgobj.ungetregisterintinline(list:Taasmoutput;position:Tai;r:Tregister); @@ -2013,6 +2004,7 @@ unit rgobj; else list.insertafter(Tai_regalloc.dealloc(r),position); add_edges_used(supreg); + add_constraints(r); end; function Trgobj.spill_registers(list:Taasmoutput;const regs_to_spill:string):boolean; @@ -2203,14 +2195,19 @@ unit rgobj; initialization - ; -finalization - rg.free; + { This check is required because rgcpu is initialized before rgobj + when compiling with FPC 1.0.x (PFV) } + if not assigned(crgobj) then + crgobj:=trgobj; end. { $Log$ - Revision 1.70 2003-09-03 21:06:45 peter + Revision 1.71 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.70 2003/09/03 21:06:45 peter * fixes for FPU register allocation Revision 1.69 2003/09/03 15:55:01 peter diff --git a/compiler/symconst.pas b/compiler/symconst.pas index 5060971dc1..54acaf28a8 100644 --- a/compiler/symconst.pas +++ b/compiler/symconst.pas @@ -25,6 +25,9 @@ unit symconst; interface +uses + globtype; + const def_alignment = 4; @@ -193,12 +196,9 @@ type po_msgint, { method for int message handling } po_exports, { Procedure has export directive (needed for OS/2) } po_external, { Procedure is external (in other object or lib)} - po_savestdregs, { save std regs cdecl and stdcall need that ! } po_saveregisters, { save all registers } po_overload, { procedure is declared with overload directive } po_varargs, { printf like arguments } - po_leftright, { push arguments from left to right } - po_clearstack, { caller clears the stack } po_internconst, { procedure has constant evaluator intern } po_addressonly, { flag that only the address of a method is returned and not a full methodpointer } po_public { procedure is exported } @@ -333,7 +333,22 @@ const objectdef]; {$endif GDB} + const + savestdregs_pocalls = [ + pocall_cdecl,pocall_cppdecl,pocall_palmossyscall, + pocall_stdcall,pocall_safecall,pocall_compilerproc, + pocall_register + ]; + + clearstack_pocalls = [ + pocall_cdecl,pocall_cppdecl,pocall_palmossyscall + ]; + + pushleftright_pocalls = [ + pocall_pascal + ]; + SymTypeName : array[tsymtyp] of string[12] = ( 'abstractsym','variable','type','proc','unit', 'const','enum','typed const','errorsym','system sym', @@ -357,7 +372,11 @@ implementation end. { $Log$ - Revision 1.60 2003-08-11 21:18:20 peter + Revision 1.61 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.60 2003/08/11 21:18:20 peter * start of sparc support for newra Revision 1.59 2003/08/10 17:25:23 peter diff --git a/compiler/symdef.pas b/compiler/symdef.pas index 0ce8f505ff..1e2324132f 100644 --- a/compiler/symdef.pas +++ b/compiler/symdef.pas @@ -3419,7 +3419,7 @@ implementation end; lastref:=defref; { first, we assume that all registers are used } - usedintregisters:=VOLATILE_INTREGISTERS; + usedintregisters:=paramanager.get_volatile_registers_int(pocall_default); usedotherregisters:=ALL_OTHERREGISTERS; forwarddef:=true; interfacedef:=false; @@ -3561,7 +3561,7 @@ implementation { set all registers to used for simplified compilation PM } if simplify_ppu then begin - usedintregisters:=VOLATILE_INTREGISTERS; + usedintregisters:=paramanager.get_volatile_registers_int(pocall_default); usedotherregisters:=ALL_OTHERREGISTERS; end; @@ -4302,7 +4302,7 @@ implementation { write parameter info. The parameters must be written in reverse order if this method uses right to left parameter pushing! } - if (po_leftright in procoptions) then + if proccalloption in pushleftright_pocalls then pdc:=TParaItem(Para.first) else pdc:=TParaItem(Para.last); @@ -4322,7 +4322,7 @@ implementation { write name of type of current parameter } tstoreddef(pdc.paratype.def).write_rtti_name; - if (po_leftright in procoptions) then + if proccalloption in pushleftright_pocalls then pdc:=TParaItem(pdc.next) else pdc:=TParaItem(pdc.previous); @@ -5848,7 +5848,11 @@ implementation end. { $Log$ - Revision 1.161 2003-09-06 22:27:09 florian + Revision 1.162 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.161 2003/09/06 22:27:09 florian * fixed web bug 2669 * cosmetic fix in printnode * tobjectdef.gettypename implemented @@ -5893,7 +5897,7 @@ end. Revision 1.152 2003/06/17 16:34:44 jonas * lots of newra fixes (need getfuncretparaloc implementation for i386)! - * renamed all_intregisters to volatile_intregisters and made it + * renamed all_intregisters to paramanager.get_volatile_registers_int(pocall_default) and made it processor dependent Revision 1.151 2003/06/08 11:41:21 peter diff --git a/compiler/tokens.pas b/compiler/tokens.pas index f01bc314c2..566d3ca4f9 100644 --- a/compiler/tokens.pas +++ b/compiler/tokens.pas @@ -169,7 +169,6 @@ type _EXPORTS, _FINALLY, _FORWARD, - _FPCCALL, _IOCHECK, _LIBRARY, _MESSAGE, @@ -189,7 +188,6 @@ type _OVERLOAD, _OVERRIDE, _PLATFORM, - _POPSTACK, _PROPERTY, _REGISTER, _RESIDENT, @@ -208,6 +206,7 @@ type _DESTRUCTOR, _IMPLEMENTS, _INTERNPROC, + _OLDFPCCALL, _OPENSTRING, _CONSTRUCTOR, _INTERNCONST, @@ -392,7 +391,6 @@ const (str:'EXPORTS' ;special:false;keyword:m_all;op:NOTOKEN), (str:'FINALLY' ;special:false;keyword:m_class;op:NOTOKEN), (str:'FORWARD' ;special:false;keyword:m_none;op:NOTOKEN), - (str:'FPCCALL' ;special:false;keyword:m_none;op:NOTOKEN), (str:'IOCHECK' ;special:false;keyword:m_none;op:NOTOKEN), (str:'LIBRARY' ;special:false;keyword:m_all;op:NOTOKEN), (str:'MESSAGE' ;special:false;keyword:m_none;op:NOTOKEN), @@ -412,7 +410,6 @@ const (str:'OVERLOAD' ;special:false;keyword:m_none;op:NOTOKEN), (str:'OVERRIDE' ;special:false;keyword:m_none;op:NOTOKEN), (str:'PLATFORM' ;special:false;keyword:m_none;op:NOTOKEN), - (str:'POPSTACK' ;special:false;keyword:m_none;op:NOTOKEN), (str:'PROPERTY' ;special:false;keyword:m_class;op:NOTOKEN), (str:'REGISTER' ;special:false;keyword:m_none;op:NOTOKEN), (str:'RESIDENT' ;special:false;keyword:m_none;op:NOTOKEN), @@ -431,6 +428,7 @@ const (str:'DESTRUCTOR' ;special:false;keyword:m_all;op:NOTOKEN), (str:'IMPLEMENTS' ;special:false;keyword:m_none;op:NOTOKEN), (str:'INTERNPROC' ;special:false;keyword:m_none;op:NOTOKEN), + (str:'OLDFPCCALL' ;special:false;keyword:m_none;op:NOTOKEN), (str:'OPENSTRING' ;special:false;keyword:m_none;op:NOTOKEN), (str:'CONSTRUCTOR' ;special:false;keyword:m_all;op:NOTOKEN), (str:'INTERNCONST' ;special:false;keyword:m_none;op:NOTOKEN), @@ -504,7 +502,11 @@ end; end. { $Log$ - Revision 1.23 2003-09-04 21:58:16 olle + Revision 1.24 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.23 2003/09/04 21:58:16 olle + bugfix, put token UNIMPLEMENTED in right order Revision 1.22 2003/08/10 17:25:23 peter diff --git a/compiler/x86/aasmcpu.pas b/compiler/x86/aasmcpu.pas index bb91ebf2ba..9dd82cd1cb 100644 --- a/compiler/x86/aasmcpu.pas +++ b/compiler/x86/aasmcpu.pas @@ -1920,7 +1920,7 @@ implementation if oper[0].ref^.index=NR_NO then pos:=Tai(previous) else - pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].ref^.index),0,0,unusedregsint); + pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].ref^.index),RS_INVALID,RS_INVALID,unusedregsint); rgget(list,pos,subreg,helpreg); spill_registers:=true; helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[0].ref^.base),spilltemplist[supreg],helpreg); @@ -1946,7 +1946,7 @@ implementation if oper[0].ref^.base=NR_NO then pos:=Tai(previous) else - pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].ref^.base),0,0,unusedregsint); + pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].ref^.base),RS_INVALID,RS_INVALID,unusedregsint); rgget(list,pos,subreg,helpreg); spill_registers:=true; helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[0].ref^.index),spilltemplist[supreg],helpreg); @@ -1981,9 +1981,9 @@ implementation subreg:=getsubreg(oper[i].ref^.base); if i=1 then pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.index),getsupreg(oper[0].reg), - 0,unusedregsint) + RS_INVALID,unusedregsint) else - pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.index),0,0,unusedregsint); + pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.index),RS_INVALID,RS_INVALID,unusedregsint); rgget(list,pos,subreg,helpreg); spill_registers:=true; helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[i].ref^.base),spilltemplist[supreg],helpreg); @@ -2008,9 +2008,9 @@ implementation subreg:=getsubreg(oper[i].ref^.index); if i=1 then pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.base),getsupreg(oper[0].reg), - 0,unusedregsint) + RS_INVALID,unusedregsint) else - pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.base),0,0,unusedregsint); + pos:=get_insert_pos(Tai(previous),getsupreg(oper[i].ref^.base),RS_INVALID,RS_INVALID,unusedregsint); rgget(list,pos,subreg,helpreg); spill_registers:=true; helpins:=Taicpu.op_ref_reg(A_MOV,reg2opsize(oper[i].ref^.index),spilltemplist[supreg],helpreg); @@ -2082,7 +2082,7 @@ implementation mov r22d,[r21d] ; Use a help register add [ebp-12],r22d ; Replace register by helpregister } pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].ref^.base), - getsupreg(oper[0].ref^.index),0,unusedregsint); + getsupreg(oper[0].ref^.index),RS_INVALID,unusedregsint); rgget(list,pos,subreg,helpreg); spill_registers:=true; op:=A_MOV; @@ -2123,7 +2123,7 @@ implementation op:=opcode; opcode:=A_MOV; opsize:=reg2opsize(oper[1].reg); - pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].reg),0,0,unusedregsint); + pos:=get_insert_pos(Tai(previous),getsupreg(oper[0].reg),RS_INVALID,RS_INVALID,unusedregsint); rgget(list,pos,subreg,helpreg); helpins:=Taicpu.op_reg_reg(op,hopsize,oper[0].reg,helpreg); if pos=nil then @@ -2228,7 +2228,11 @@ implementation end. { $Log$ - Revision 1.17 2003-09-03 15:55:02 peter + Revision 1.18 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.17 2003/09/03 15:55:02 peter * NEWRA branch merged Revision 1.16.2.4 2003/08/31 15:46:26 peter diff --git a/compiler/x86/cgx86.pas b/compiler/x86/cgx86.pas index 47aee6df38..f1c04ed1c1 100644 --- a/compiler/x86/cgx86.pas +++ b/compiler/x86/cgx86.pas @@ -346,9 +346,9 @@ unit cgx86; OS_16,OS_S16: begin if target_info.alignment.paraalign = 2 then - setsubreg(r,R_SUBW) + r:=rg.makeregsize(r,OS_16) else - setsubreg(r,R_SUBD); + r:=rg.makeregsize(r,OS_32); list.concat(taicpu.op_reg(A_PUSH,S_L,r)); end; OS_32,OS_S32: @@ -1372,8 +1372,7 @@ unit cgx86; else begin objectlibrary.getlabel(again); - r:=NR_EDI; - rg.getexplicitregisterint(list,r); + r:=rg.getexplicitregisterint(list,NR_EDI); list.concat(Taicpu.op_const_reg(A_MOV,S_L,localsize div winstackpagesize,r)); a_label(list,again); list.concat(Taicpu.op_const_reg(A_SUB,S_L,winstackpagesize-4,NR_ESP)); @@ -1395,7 +1394,7 @@ unit cgx86; begin list.concat(tai_regalloc.alloc(NR_EBP)); - include(rg.savedintbyproc,RS_EBP); + include(rg.preserved_by_proc_int,RS_EBP); list.concat(Taicpu.op_reg(A_PUSH,S_L,NR_EBP)); list.concat(Taicpu.op_reg_reg(A_MOV,S_L,NR_ESP,NR_EBP)); if localsize>0 then @@ -1415,7 +1414,7 @@ unit cgx86; begin { Routines with the poclearstack flag set use only a ret } { also routines with parasize=0 } - if (po_clearstack in current_procinfo.procdef.procoptions) then + if current_procinfo.procdef.proccalloption in clearstack_pocalls then begin { complex return values are removed from stack in C code PM } if paramanager.ret_in_param(current_procinfo.procdef.rettype.def, @@ -1438,26 +1437,68 @@ unit cgx86; procedure tcgx86.g_save_standard_registers(list:Taasmoutput;usedinproc:Tsuperregisterset); - - begin - if (RS_EBX in usedinproc) then - list.concat(Taicpu.op_reg(A_PUSH,S_L,NR_EBX)); - list.concat(Taicpu.op_reg(A_PUSH,S_L,NR_ESI)); - list.concat(Taicpu.op_reg(A_PUSH,S_L,NR_EDI)); - include(rg.savedintbyproc,RS_EBX); - include(rg.savedintbyproc,RS_ESI); - include(rg.savedintbyproc,RS_EDI); - end; + var + href : treference; + size : longint; + begin + { Get temp } + size:=0; + if (RS_EBX in usedinproc) then + inc(size,POINTER_SIZE); + if (RS_ESI in usedinproc) then + inc(size,POINTER_SIZE); + if (RS_EDI in usedinproc) then + inc(size,POINTER_SIZE); + if size>0 then + begin + tg.GetTemp(list,size,tt_noreuse,current_procinfo.save_regs_ref); + { Copy registers to temp } + href:=current_procinfo.save_regs_ref; + if (RS_EBX in usedinproc) then + begin + cg.a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_EBX,href); + inc(href.offset,POINTER_SIZE); + end; + if (RS_ESI in usedinproc) then + begin + cg.a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_ESI,href); + inc(href.offset,POINTER_SIZE); + end; + if (RS_EDI in usedinproc) then + begin + cg.a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_EDI,href); + inc(href.offset,POINTER_SIZE); + end; + end; + include(rg.preserved_by_proc_int,RS_EBX); + include(rg.preserved_by_proc_int,RS_ESI); + include(rg.preserved_by_proc_int,RS_EDI); + end; procedure tcgx86.g_restore_standard_registers(list:Taasmoutput;usedinproc:Tsuperregisterset); - - begin - list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EDI)); - list.concat(Taicpu.Op_reg(A_POP,S_L,NR_ESI)); + var + href : treference; + begin + { Copy registers from temp } + href:=current_procinfo.save_regs_ref; if (RS_EBX in usedinproc) then - list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EBX)); - end; + begin + cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_EBX); + inc(href.offset,POINTER_SIZE); + end; + if (RS_ESI in usedinproc) then + begin + cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_ESI); + inc(href.offset,POINTER_SIZE); + end; + if (RS_EDI in usedinproc) then + begin + cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_EDI); + inc(href.offset,POINTER_SIZE); + end; + tg.UnGetTemp(list,current_procinfo.save_regs_ref); + end; procedure tcgx86.g_save_all_registers(list : taasmoutput); @@ -1516,7 +1557,11 @@ unit cgx86; end. { $Log$ - Revision 1.60 2003-09-05 17:41:13 florian + Revision 1.61 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.60 2003/09/05 17:41:13 florian * merged Wiktor's Watcom patches in 1.1 Revision 1.59 2003/09/03 15:55:02 peter diff --git a/compiler/x86/cpubase.pas b/compiler/x86/cpubase.pas index f5c9330463..6ab6631ddb 100644 --- a/compiler/x86/cpubase.pas +++ b/compiler/x86/cpubase.pas @@ -185,10 +185,6 @@ uses {$endif x86_64} ); - { registers which may be destroyed by calls } - VOLATILE_INTREGISTERS = [first_int_supreg..last_int_supreg]-[RS_EBP,RS_ESP]; - VOLATILE_FPUREGISTERS = [first_fpu_supreg..last_fpu_supreg]; - type totherregisterset = set of tregisterindex; @@ -563,7 +559,11 @@ implementation end. { $Log$ - Revision 1.16 2003-09-04 21:07:03 florian + Revision 1.17 2003-09-07 22:09:35 peter + * preparations for different default calling conventions + * various RA fixes + + Revision 1.16 2003/09/04 21:07:03 florian * ARM compiler compiles again Revision 1.15 2003/09/03 15:55:02 peter