From c65e094bbaba4271d96055a542839045c82f8ba8 Mon Sep 17 00:00:00 2001 From: florian Date: Sat, 20 Mar 2004 20:55:36 +0000 Subject: [PATCH] + implemented cdecl'd varargs on arm + -dCMEM supported by the compiler * label/goto asmsymbol type with -dextdebug fixed --- compiler/arm/cpupara.pas | 310 +++++++++++++++++++++++---------------- compiler/pdecl.pas | 16 +- compiler/pp.pas | 11 +- 3 files changed, 198 insertions(+), 139 deletions(-) diff --git a/compiler/arm/cpupara.pas b/compiler/arm/cpupara.pas index 2d7dd643b4..160fa10c89 100644 --- a/compiler/arm/cpupara.pas +++ b/compiler/arm/cpupara.pas @@ -30,7 +30,7 @@ unit cpupara; uses globtype, aasmtai, - cpubase,cgbase, + cpuinfo,cpubase,cgbase, symconst,symbase,symtype,symdef,paramgr; type @@ -39,16 +39,19 @@ unit cpupara; function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override; function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override; function getintparaloc(calloption : tproccalloption; nr : longint) : tparalocation;override; - // procedure freeintparaloc(list: taasmoutput; nr : longint); override; procedure alloctempparaloc(list: taasmoutput;calloption : tproccalloption;paraitem : tparaitem;var locpara:tparalocation);override; function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override; + function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint;override; + private + procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword); + function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; firstpara: tparaitem; + var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword):longint; end; implementation uses verbose,systems, - cpuinfo, rgobj, defutil,symsym; @@ -85,22 +88,6 @@ unit cpupara; result.size := OS_INT; end; -{ - procedure tarmparamanager.freeintparaloc(list: taasmoutput; nr : longint); - - var - r: tregister; - - begin - if nr<1 then - internalerror(2003060401) - else if nr<=4 then - begin - r:=newreg(R_INTREGISTER,RS_R0+nr,R_SUBWHOLE); - rg.ungetregisterint(list,r); - end; - end; -} function getparaloc(calloption : tproccalloption; p : tdef) : tcgloc; begin @@ -159,6 +146,7 @@ unit cpupara; end; end; + function tarmparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean; begin if varspez in [vs_var,vs_out] then @@ -186,47 +174,53 @@ unit cpupara; end; - function tarmparamanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint; + procedure tarmparamanager.init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword); + begin + curintreg:=RS_R0; + curfloatreg:=RS_F0; + curmmreg:=RS_D0; + cur_stack_offset:=0; + end; + + + function tarmparamanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; firstpara: tparaitem; + var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword):longint; var - nextintreg,nextfloatreg,nextmmreg : tsuperregister; - paradef : tdef; - paraloc : tparalocation; - stack_offset : aword; - hp : tparaitem; - loc : tcgloc; - is_64bit: boolean; + nextintreg,nextfloatreg,nextmmreg : tsuperregister; + paradef : tdef; + paraloc : tparalocation; + stack_offset : aword; + hp : tparaitem; + loc : tcgloc; + is_64bit: boolean; procedure assignintreg; - begin if nextintreg<=ord(NR_R3) then begin - paraloc.loc:=LOC_REGISTER; - paraloc.register:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE); - inc(nextintreg); + paraloc.loc:=LOC_REGISTER; + paraloc.register:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE); + inc(nextintreg); end else - begin - paraloc.loc:=LOC_REFERENCE; - paraloc.reference.index:=NR_STACK_POINTER_REG; - paraloc.reference.offset:=stack_offset; - inc(stack_offset,4); - end; + begin + paraloc.loc:=LOC_REFERENCE; + paraloc.reference.index:=NR_STACK_POINTER_REG; + paraloc.reference.offset:=stack_offset; + inc(stack_offset,4); + end; end; + begin result:=0; - { zero alignment bytes } - fillchar(nextintreg,sizeof(nextintreg),0); - fillchar(nextfloatreg,sizeof(nextfloatreg),0); - fillchar(nextmmreg,sizeof(nextmmreg),0); - nextintreg:=RS_R0; - nextfloatreg:=RS_F0; - nextmmreg:=RS_D0; - stack_offset:=0; + nextintreg:=curintreg; + nextfloatreg:=curfloatreg; + nextmmreg:=curmmreg; + stack_offset:=cur_stack_offset; - hp:=tparaitem(p.para.first); + hp:=firstpara; while assigned(hp) do begin if (hp.paratyp in [vs_var,vs_out]) then @@ -245,66 +239,66 @@ unit cpupara; case loc of LOC_REGISTER: begin - paraloc.size := def_cgsize(paradef); - { for things like formaldef } - if paraloc.size = OS_NO then - paraloc.size := OS_ADDR; - is_64bit := paraloc.size in [OS_64,OS_S64,OS_F64]; - { this is not abi compliant } - if nextintreg<=(RS_R3-ord(is_64bit)) then + paraloc.size := def_cgsize(paradef); + { for things like formaldef } + if paraloc.size = OS_NO then + paraloc.size := OS_ADDR; + is_64bit := paraloc.size in [OS_64,OS_S64,OS_F64]; + { this is not abi compliant } + if nextintreg<=(RS_R3-ord(is_64bit)) then + begin + paraloc.loc:=LOC_REGISTER; + paraloc.registerlow:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE); + inc(nextintreg); + if is_64bit then + begin + paraloc.lochigh:=LOC_REGISTER; + paraloc.registerhigh:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE); + inc(nextintreg); + end; + end + else begin - paraloc.loc:=LOC_REGISTER; - paraloc.registerlow:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE); - inc(nextintreg); - if is_64bit then - begin - paraloc.lochigh:=LOC_REGISTER; - paraloc.registerhigh:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE); - inc(nextintreg); - end; - end - else - begin - nextintreg:=RS_R4; - paraloc.loc:=LOC_REFERENCE; - paraloc.reference.index:=NR_STACK_POINTER_REG; - paraloc.reference.offset:=stack_offset; - if not is_64bit then - inc(stack_offset,4) - else - inc(stack_offset,8); - end; + nextintreg:=RS_R4; + paraloc.loc:=LOC_REFERENCE; + paraloc.reference.index:=NR_STACK_POINTER_REG; + paraloc.reference.offset:=stack_offset; + if not is_64bit then + inc(stack_offset,4) + else + inc(stack_offset,8); + end; end; LOC_FPUREGISTER: begin - paraloc.size:=def_cgsize(paradef); - if nextfloatreg<=RS_F3 then - begin - paraloc.loc:=LOC_FPUREGISTER; - paraloc.register:=newreg(R_FPUREGISTER,nextfloatreg,R_SUBWHOLE); - inc(nextfloatreg); - end - else - begin - {!!!!!!!} - paraloc.size:=def_cgsize(paradef); - internalerror(2002071004); - end; + paraloc.size:=def_cgsize(paradef); + if nextfloatreg<=RS_F3 then + begin + paraloc.loc:=LOC_FPUREGISTER; + paraloc.register:=newreg(R_FPUREGISTER,nextfloatreg,R_SUBWHOLE); + inc(nextfloatreg); + end + else + begin + {!!!!!!!} + paraloc.size:=def_cgsize(paradef); + internalerror(2002071004); + end; end; LOC_REFERENCE: begin - paraloc.size:=OS_ADDR; - if push_addr_param(hp.paratyp,paradef,p.proccalloption) or - is_open_array(paradef) or - is_array_of_const(paradef) then - assignintreg - else - begin - paraloc.loc:=LOC_REFERENCE; - paraloc.reference.index:=NR_STACK_POINTER_REG; - paraloc.reference.offset:=stack_offset; - inc(stack_offset,hp.paratype.def.size); - end; + paraloc.size:=OS_ADDR; + if push_addr_param(hp.paratyp,paradef,p.proccalloption) or + is_open_array(paradef) or + is_array_of_const(paradef) then + assignintreg + else + begin + paraloc.loc:=LOC_REFERENCE; + paraloc.reference.index:=NR_STACK_POINTER_REG; + paraloc.reference.offset:=stack_offset; + inc(stack_offset,hp.paratype.def.size); + end; end; else internalerror(2002071002); @@ -320,35 +314,53 @@ unit cpupara; hp.paraloc[side]:=paraloc; hp:=tparaitem(hp.next); end; - { Function return } - fillchar(paraloc,sizeof(tparalocation),0); - paraloc.lochigh:=LOC_INVALID; - paraloc.size:=def_cgsize(p.rettype.def); - { Return in FPU register? } - if p.rettype.def.deftype=floatdef then - begin - paraloc.loc:=LOC_FPUREGISTER; - paraloc.register:=NR_FPU_RESULT_REG; - end - else - { Return in register? } - if not ret_in_param(p.rettype.def,p.proccalloption) then - begin - paraloc.loc:=LOC_REGISTER; - if paraloc.size in [OS_64,OS_S64] then - begin - paraloc.lochigh:=LOC_REGISTER; - paraloc.register:=NR_FUNCTION_RETURN64_LOW_REG; - paraloc.registerhigh:=NR_FUNCTION_RETURN64_HIGH_REG; - end - else - paraloc.register:=NR_FUNCTION_RETURN_REG; - end - else - begin - paraloc.loc:=LOC_REFERENCE; - end; - p.funcret_paraloc[side]:=paraloc; + curintreg:=nextintreg; + curfloatreg:=nextfloatreg; + curmmreg:=nextmmreg; + cur_stack_offset:=stack_offset; + result:=cur_stack_offset; + end; + + + function tarmparamanager.create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint; + var + paraloc : tparalocation; + cur_stack_offset: aword; + curintreg, curfloatreg, curmmreg: tsuperregister; + begin + init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset); + + result:=create_paraloc_info_intern(p,side,tparaitem(p.para.first),curintreg,curfloatreg,curmmreg,cur_stack_offset); + + { Function return } + fillchar(paraloc,sizeof(tparalocation),0); + paraloc.lochigh:=LOC_INVALID; + paraloc.size:=def_cgsize(p.rettype.def); + { Return in FPU register? } + if p.rettype.def.deftype=floatdef then + begin + paraloc.loc:=LOC_FPUREGISTER; + paraloc.register:=NR_FPU_RESULT_REG; + end + else + { Return in register? } + if not ret_in_param(p.rettype.def,p.proccalloption) then + begin + paraloc.loc:=LOC_REGISTER; + if paraloc.size in [OS_64,OS_S64] then + begin + paraloc.lochigh:=LOC_REGISTER; + paraloc.register:=NR_FUNCTION_RETURN64_LOW_REG; + paraloc.registerhigh:=NR_FUNCTION_RETURN64_HIGH_REG; + end + else + paraloc.register:=NR_FUNCTION_RETURN_REG; + end + else + begin + paraloc.loc:=LOC_REFERENCE; + end; + p.funcret_paraloc[side]:=paraloc; end; @@ -372,12 +384,52 @@ unit cpupara; end; + function tarmparamanager.create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargspara):longint; + var + cur_stack_offset: aword; + parasize, l: longint; + curintreg, curfloatreg, curmmreg: tsuperregister; + hp: tparaitem; + paraloc: tparalocation; + begin + init_values(curintreg,curfloatreg,curmmreg,cur_stack_offset); + + result:=create_paraloc_info_intern(p,callerside,tparaitem(p.para.first),curintreg,curfloatreg,curmmreg,cur_stack_offset); + if (p.proccalloption in [pocall_cdecl,pocall_cppdecl]) then + { just continue loading the parameters in the registers } + result:=create_paraloc_info_intern(p,callerside,tparaitem(varargspara.first),curintreg,curfloatreg,curmmreg,cur_stack_offset) + else + begin + hp:=tparaitem(varargspara.first); + parasize:=cur_stack_offset; + while assigned(hp) do + begin + paraloc.size:=def_cgsize(hp.paratype.def); + paraloc.lochigh:=LOC_INVALID; + paraloc.loc:=LOC_REFERENCE; + paraloc.alignment:=4; + paraloc.reference.index:=NR_STACK_POINTER_REG; + l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption); + paraloc.reference.offset:=parasize; + parasize:=parasize+l; + hp.paraloc[callerside]:=paraloc; + hp:=tparaitem(hp.next); + end; + result := parasize; + end; + end; + begin paramanager:=tarmparamanager.create; end. { $Log$ - Revision 1.15 2004-03-07 00:16:59 florian + Revision 1.16 2004-03-20 20:55:36 florian + + implemented cdecl'd varargs on arm + + -dCMEM supported by the compiler + * label/goto asmsymbol type with -dextdebug fixed + + Revision 1.15 2004/03/07 00:16:59 florian * compilation of arm rtl fixed Revision 1.14 2004/02/09 22:48:45 florian diff --git a/compiler/pdecl.pas b/compiler/pdecl.pas index 9bfccb5e06..e4b61e98a2 100644 --- a/compiler/pdecl.pas +++ b/compiler/pdecl.pas @@ -258,14 +258,7 @@ implementation consume(_ID) else begin - if (cs_create_smart in aktmoduleswitches) then - begin - objectlibrary.getdatalabel(hl); - { we still want a warning if unused } - hl.decrefs; - end - else - objectlibrary.getlabel(hl); + objectlibrary.getlabel(hl); if token=_ID then symtablestack.insert(tlabelsym.create(orgpattern,hl)) else @@ -675,7 +668,12 @@ implementation end. { $Log$ - Revision 1.83 2004-03-08 22:07:47 peter + Revision 1.84 2004-03-20 20:55:36 florian + + implemented cdecl'd varargs on arm + + -dCMEM supported by the compiler + * label/goto asmsymbol type with -dextdebug fixed + + Revision 1.83 2004/03/08 22:07:47 peter * stabs updates to write stabs for def for all implictly used units diff --git a/compiler/pp.pas b/compiler/pp.pas index f498a61c18..57039f8b8b 100644 --- a/compiler/pp.pas +++ b/compiler/pp.pas @@ -26,6 +26,7 @@ program pp; possible compiler switches (* marks a currently required switch): ----------------------------------------------------------------- GDB* support of the GNU Debugger + CMEM use cmem unit for better memory debugging I386 generate a compiler for the Intel i386+ x86_64 generate a compiler for the AMD x86-64 architecture M68K generate a compiler for the M68000 @@ -129,6 +130,9 @@ program pp; {$endif} uses +{$ifdef cmem} + cmem, +{$endif cmem} {$ifdef FPC} {$ifdef profile} profile, @@ -203,7 +207,12 @@ begin end. { $Log$ - Revision 1.29 2004-01-26 17:39:12 florian + Revision 1.30 2004-03-20 20:55:36 florian + + implemented cdecl'd varargs on arm + + -dCMEM supported by the compiler + * label/goto asmsymbol type with -dextdebug fixed + + Revision 1.29 2004/01/26 17:39:12 florian * when compiled with -dnocatch, known rtes aren't translated anymore and a stack dump is written