diff --git a/compiler/arm/cpupara.pas b/compiler/arm/cpupara.pas index 2d6f2e5b9d..3b07404bbb 100644 --- a/compiler/arm/cpupara.pas +++ b/compiler/arm/cpupara.pas @@ -42,12 +42,11 @@ unit cpupara; procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override; function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override; function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override; - function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override; + function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override; private procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister); function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist; var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword; var sparesinglereg: tregister; isvariadic: boolean):longint; - procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); end; implementation @@ -576,23 +575,17 @@ unit cpupara; end; - procedure tarmparamanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); - begin - p.funcretloc[side]:=get_funcretloc(p,side,p.returndef); - end; - - - function tarmparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara; + function tarmparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara; var paraloc : pcgparalocation; retcgsize : tcgsize; begin - if set_common_funcretloc_info(p,def,retcgsize,result) then + if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then exit; paraloc:=result.add_location; { Return in FPU register? } - if def.typ=floatdef then + if result.def.typ=floatdef then begin if target_info.abi = abi_eabihf then begin diff --git a/compiler/avr/cpupara.pas b/compiler/avr/cpupara.pas index ae5c5a5996..763e7b3b7c 100644 --- a/compiler/avr/cpupara.pas +++ b/compiler/avr/cpupara.pas @@ -41,12 +41,11 @@ unit cpupara; procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override; function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override; function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override; - function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override; + function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override; private procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword); function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist; var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword):longint; - procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); end; implementation @@ -403,24 +402,18 @@ unit cpupara; end; - procedure tavrparamanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); - begin - p.funcretloc[side]:=get_funcretloc(p,side,p.returndef); - end; - - { TODO : fix tavrparamanager.get_funcretloc } - function tavrparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara; + function tavrparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara; var retcgsize : tcgsize; paraloc : pcgparalocation; begin - if set_common_funcretloc_info(p,def,retcgsize,result) then + if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then exit; paraloc:=result.add_location; { Return in FPU register? } - if def.typ=floatdef then + if result.def.typ=floatdef then begin if (p.proccalloption in [pocall_softfloat]) or (cs_fp_emulation in current_settings.moduleswitches) then begin diff --git a/compiler/hlcgobj.pas b/compiler/hlcgobj.pas index 7165fb974d..964ba6cae9 100644 --- a/compiler/hlcgobj.pas +++ b/compiler/hlcgobj.pas @@ -3310,6 +3310,7 @@ implementation cgpara3.done; cgpara2.done; cgpara1.done; + getmemres.resetiftemp; end; procedure thlcgobj.g_releasevaluepara_openarray(list: TAsmList; arrdef: tarraydef; const l: tlocation); diff --git a/compiler/i386/cpupara.pas b/compiler/i386/cpupara.pas index 6c904cf451..395d3b6c4a 100644 --- a/compiler/i386/cpupara.pas +++ b/compiler/i386/cpupara.pas @@ -49,9 +49,8 @@ unit cpupara; function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override; function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override; procedure createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);override; - function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): TCGPara;override; + function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): TCGPara;override; private - procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); procedure create_stdcall_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;var parasize:longint); procedure create_register_paraloc_info(p : tabstractprocdef; side: tcallercallee;paras:tparalist;var parareg,parasize:longint); end; @@ -310,29 +309,35 @@ unit cpupara; end; - procedure ti386paramanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); - begin - p.funcretloc[side]:=get_funcretloc(p,side,p.returndef); - end; - - - function ti386paramanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): TCGPara; + function ti386paramanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): TCGPara; var retcgsize : tcgsize; paraloc : pcgparalocation; sym: tfieldvarsym; + usedef: tdef; + handled: boolean; begin + if not assigned(forcetempdef) then + usedef:=p.returndef + else + usedef:=forcetempdef; { on darwin/i386, if a record has only one field and that field is a single or double, it has to be returned like a single/double } if (target_info.system in [system_i386_darwin,system_i386_iphonesim]) and - ((def.typ=recorddef) or - is_object(def)) and - tabstractrecordsymtable(tabstractrecorddef(def).symtable).has_single_field(sym) and + ((usedef.typ=recorddef) or + is_object(usedef)) and + tabstractrecordsymtable(tabstractrecorddef(usedef).symtable).has_single_field(sym) and (sym.vardef.typ=floatdef) and (tfloatdef(sym.vardef).floattype in [s32real,s64real]) then - def:=sym.vardef; + usedef:=sym.vardef; - if set_common_funcretloc_info(p,def,retcgsize,result) then + handled:=set_common_funcretloc_info(p,usedef,retcgsize,result); + { normally forcetempdef is passed straight through to + set_common_funcretloc_info and that one will correctly determine whether + the location is a temporary one, but that doesn't work here because we + sometimes have to change the type } + result.temporary:=assigned(forcetempdef); + if handled then exit; { darwin/x86 requires that results < sizeof(aint) are sign/zero @@ -349,7 +354,7 @@ unit cpupara; end; { Return in FPU register? } - if def.typ=floatdef then + if result.def.typ=floatdef then begin paraloc:=result.add_location; paraloc^.loc:=LOC_FPUREGISTER; diff --git a/compiler/jvm/cpupara.pas b/compiler/jvm/cpupara.pas index 761581f8f6..eccac2c474 100644 --- a/compiler/jvm/cpupara.pas +++ b/compiler/jvm/cpupara.pas @@ -45,12 +45,11 @@ interface procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override; function create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):longint;override; function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override; - function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override; + function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override; function param_use_paraloc(const cgpara: tcgpara): boolean; override; function ret_in_param(def: tdef; calloption: tproccalloption): boolean; override; function is_stack_paraloc(paraloc: pcgparalocation): boolean;override; private - procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist; var parasize:longint); end; @@ -111,23 +110,23 @@ implementation end; - procedure TJVMParaManager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); - begin - p.funcretloc[side]:=get_funcretloc(p,side,p.returndef); - end; - - - function TJVMParaManager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara; + function TJVMParaManager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara; var paraloc : pcgparalocation; retcgsize : tcgsize; begin - def:=get_para_push_size(def); result.init; result.alignment:=get_para_align(p.proccalloption); - result.def:=def; + if not assigned(forcetempdef) then + result.def:=p.returndef + else + begin + result.def:=forcetempdef; + result.temporary:=true; + end; + result.def:=get_para_push_size(result.def); { void has no location } - if is_void(def) then + if is_void(result.def) then begin paraloc:=result.add_location; result.size:=OS_NO; @@ -144,8 +143,8 @@ implementation end else begin - retcgsize:=def_cgsize(def); - result.intsize:=def.size; + retcgsize:=def_cgsize(result.def); + result.intsize:=result.def.size; end; result.size:=retcgsize; diff --git a/compiler/m68k/cpupara.pas b/compiler/m68k/cpupara.pas index 1ee1863d55..b1447b0493 100644 --- a/compiler/m68k/cpupara.pas +++ b/compiler/m68k/cpupara.pas @@ -44,9 +44,8 @@ unit cpupara; procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override; function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override; function push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override; - function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override; + function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override; procedure createtempparaloc(list: TAsmList;calloption : tproccalloption;parasym : tparavarsym;can_use_final_stack_loc : boolean;var cgpara:TCGPara);override; - procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override; function parseparaloc(p : tparavarsym;const s : string) : boolean;override; function parsefuncretloc(p : tabstractprocdef; const s : string) : boolean;override; @@ -187,23 +186,17 @@ unit cpupara; curfloatreg:=RS_FP0; end; - procedure tm68kparamanager.create_funcretloc_info(p: tabstractprocdef; side: tcallercallee); - begin - p.funcretloc[side]:=get_funcretloc(p,side,p.returndef); - end; - - - function tm68kparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara; + function tm68kparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara; var paraloc : pcgparalocation; retcgsize : tcgsize; begin - if set_common_funcretloc_info(p,def,retcgsize,result) then + if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then exit; paraloc:=result.add_location; { Return in FPU register? } - if not(cs_fp_emulation in current_settings.moduleswitches) and (p.returndef.typ=floatdef) then + if not(cs_fp_emulation in current_settings.moduleswitches) and (result.def.typ=floatdef) then begin paraloc^.loc:=LOC_FPUREGISTER; paraloc^.register:=NR_FPU_RESULT_REG; diff --git a/compiler/mips/cpupara.pas b/compiler/mips/cpupara.pas index d4c27e940e..aed3873bf9 100644 --- a/compiler/mips/cpupara.pas +++ b/compiler/mips/cpupara.pas @@ -79,11 +79,10 @@ interface procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override; function create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):longint;override; function create_varargs_paraloc_info(p : TAbstractProcDef; varargspara:tvarargsparalist):longint;override; - function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override; + function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override; private intparareg, intparasize : longint; - procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist); end; @@ -181,22 +180,16 @@ implementation end; - procedure TMIPSParaManager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); - begin - p.funcretloc[side]:=get_funcretloc(p,side,p.returndef); - end; - - - function TMIPSParaManager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara; + function TMIPSParaManager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara; var paraloc : pcgparalocation; retcgsize : tcgsize; begin - if set_common_funcretloc_info(p,def,retcgsize,result) then + if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then begin { Return is passed as var parameter, in this case we use the first register R4 for it } - if ret_in_param(def,p.proccalloption) then + if ret_in_param(result.def,p.proccalloption) then begin if intparareg=0 then inc(intparareg); @@ -222,14 +215,14 @@ implementation begin getIntParaLoc(p.proccalloption,1,result.def,result); end; - result.def:=getpointerdef(def); + result.def:=getpointerdef(result.def); end; exit; end; paraloc:=result.add_location; { Return in FPU register? } - if p.returndef.typ=floatdef then + if result.def.typ=floatdef then begin paraloc^.loc:=LOC_FPUREGISTER; paraloc^.register:=NR_FPU_RESULT_REG; diff --git a/compiler/ncgcal.pas b/compiler/ncgcal.pas index e759c2911d..e9d4f03806 100644 --- a/compiler/ncgcal.pas +++ b/compiler/ncgcal.pas @@ -872,9 +872,9 @@ implementation if cnf_inherited in callnodeflags then hlcg.a_call_name_inherited(current_asmdata.CurrAsmList,tprocdef(procdefinition),tprocdef(procdefinition).mangledname) else - hlcg.a_call_name(current_asmdata.CurrAsmList,tprocdef(procdefinition),tprocdef(procdefinition).mangledname,typedef,po_weakexternal in procdefinition.procoptions) + hlcg.a_call_name(current_asmdata.CurrAsmList,tprocdef(procdefinition),tprocdef(procdefinition).mangledname,typedef,po_weakexternal in procdefinition.procoptions).resetiftemp else - hlcg.a_call_name(current_asmdata.CurrAsmList,tprocdef(procdefinition),name_to_call,typedef,po_weakexternal in procdefinition.procoptions); + hlcg.a_call_name(current_asmdata.CurrAsmList,tprocdef(procdefinition),name_to_call,typedef,po_weakexternal in procdefinition.procoptions).resetiftemp; extra_post_call_code; end; end; @@ -1019,8 +1019,7 @@ implementation destructor tcgcallnode.destroy; begin - if assigned(typedef) then - retloc.done; + retloc.resetiftemp; inherited destroy; end; diff --git a/compiler/parabase.pas b/compiler/parabase.pas index b829301e8d..0ec2e7fbd5 100644 --- a/compiler/parabase.pas +++ b/compiler/parabase.pas @@ -73,18 +73,20 @@ unit parabase; end; TCGPara = object + Def : tdef; { Type of the parameter } Location : PCGParalocation; IntSize : tcgint; { size of the total location in bytes } + DefDeref : tderef; Alignment : ShortInt; Size : TCGSize; { Size of the parameter included in all locations } - Def : tdef; { Type of the parameter } - DefDeref : tderef; + Temporary : boolean; { created on the fly, no permanent references exist to this somewhere that will cause it to be disposed } {$ifdef powerpc} composite: boolean; { under the AIX abi, how certain parameters are passed depends on whether they are composite or not } {$endif powerpc} constructor init; destructor done; procedure reset; + procedure resetiftemp; { reset if Temporary } function getcopy:tcgpara; procedure check_simple_location; function add_location:pcgparalocation; @@ -132,6 +134,7 @@ implementation intsize:=0; location:=nil; def:=nil; + temporary:=false; {$ifdef powerpc} composite:=false; {$endif powerpc} @@ -162,6 +165,12 @@ implementation {$endif powerpc} end; + procedure TCGPara.resetiftemp; + begin + if temporary then + reset; + end; + function tcgpara.getcopy:tcgpara; var diff --git a/compiler/paramgr.pas b/compiler/paramgr.pas index 04cd690fc0..eb56b066db 100644 --- a/compiler/paramgr.pas +++ b/compiler/paramgr.pas @@ -114,7 +114,8 @@ unit paramgr; function result instead of its actual result. Used if the compiler forces the function result to something different than the real result. } - function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;virtual;abstract; + function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;virtual;abstract; + procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); { This is used to populate the location information on all parameters for the routine when it is being inlined. It returns @@ -143,7 +144,7 @@ unit paramgr; strict protected { common part of get_funcretloc; returns true if retloc is completely initialized afterwards } - function set_common_funcretloc_info(p : tabstractprocdef; def: tdef; out retcgsize: tcgsize; out retloc: tcgpara): boolean; + function set_common_funcretloc_info(p : tabstractprocdef; forcetempdef: tdef; out retcgsize: tcgsize; out retloc: tcgpara): boolean; end; @@ -453,6 +454,12 @@ implementation end; + procedure tparamanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); + begin + p.funcretloc[side]:=get_funcretloc(p,side,nil); + end; + + function tparamanager.create_inline_paraloc_info(p : tabstractprocdef):longint; begin { We need to return the size allocated } @@ -497,16 +504,22 @@ implementation end; - function tparamanager.set_common_funcretloc_info(p : tabstractprocdef; def: tdef; out retcgsize: tcgsize; out retloc: tcgpara): boolean; + function tparamanager.set_common_funcretloc_info(p : tabstractprocdef; forcetempdef: tdef; out retcgsize: tcgsize; out retloc: tcgpara): boolean; var paraloc : pcgparalocation; begin result:=true; retloc.init; - retloc.def:=def; + if not assigned(forcetempdef) then + retloc.def:=p.returndef + else + begin + retloc.def:=forcetempdef; + retloc.temporary:=true; + end; retloc.alignment:=get_para_align(p.proccalloption); { void has no location } - if is_void(def) then + if is_void(retloc.def) then begin paraloc:=retloc.add_location; retloc.size:=OS_NO; @@ -528,14 +541,14 @@ implementation end else begin - retcgsize:=def_cgsize(def); - retloc.intsize:=def.size; + retcgsize:=def_cgsize(retloc.def); + retloc.intsize:=retloc.def.size; end; retloc.size:=retcgsize; { Return is passed as var parameter } - if ret_in_param(def,p.proccalloption) then + if ret_in_param(retloc.def,p.proccalloption) then begin - retloc.def:=getpointerdef(def); + retloc.def:=getpointerdef(retloc.def); paraloc:=retloc.add_location; paraloc^.loc:=LOC_REFERENCE; paraloc^.size:=retcgsize; diff --git a/compiler/powerpc/cpupara.pas b/compiler/powerpc/cpupara.pas index 0f4970889f..eb372c2e2b 100644 --- a/compiler/powerpc/cpupara.pas +++ b/compiler/powerpc/cpupara.pas @@ -40,8 +40,7 @@ unit cpupara; procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override; function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override; function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override; - function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override; - procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); + function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override; private procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword); function create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras:tparalist; @@ -246,23 +245,17 @@ unit cpupara; end; - procedure tppcparamanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); - begin - p.funcretloc[side]:=get_funcretloc(p,side,p.returndef); - end; - - - function tppcparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara; + function tppcparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara; var paraloc : pcgparalocation; retcgsize : tcgsize; begin - if set_common_funcretloc_info(p,def,retcgsize,result) then + if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then exit; paraloc:=result.add_location; { Return in FPU register? } - if def.typ=floatdef then + if result.def.typ=floatdef then begin paraloc^.loc:=LOC_FPUREGISTER; paraloc^.register:=NR_FPU_RESULT_REG; diff --git a/compiler/powerpc64/cpupara.pas b/compiler/powerpc64/cpupara.pas index b17a4b7ae3..b387acdc3b 100644 --- a/compiler/powerpc64/cpupara.pas +++ b/compiler/powerpc64/cpupara.pas @@ -44,8 +44,7 @@ type function create_paraloc_info(p: tabstractprocdef; side: tcallercallee): longint; override; function create_varargs_paraloc_info(p: tabstractprocdef; varargspara: tvarargsparalist): longint; override; - function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override; - procedure create_funcretloc_info(p: tabstractprocdef; side: tcallercallee); + function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override; private procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; @@ -202,24 +201,18 @@ begin curmmreg := RS_M2; end; -procedure tppcparamanager.create_funcretloc_info(p: tabstractprocdef; side: - tcallercallee); -begin - p.funcretloc[side]:=get_funcretloc(p,side,p.returndef); -end; - function tppcparamanager.get_funcretloc(p : tabstractprocdef; side: - tcallercallee; def: tdef): tcgpara; + tcallercallee; forcetempdef: tdef): tcgpara; var paraloc : pcgparalocation; retcgsize : tcgsize; begin - if set_common_funcretloc_info(p,def,retcgsize,result) then + if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then exit; paraloc:=result.add_location; { Return in FPU register? } - if def.typ=floatdef then + if result.def.typ=floatdef then begin paraloc^.loc:=LOC_FPUREGISTER; paraloc^.register:=NR_FPU_RESULT_REG; diff --git a/compiler/sparc/cpupara.pas b/compiler/sparc/cpupara.pas index 30046ccc4f..8b9085397e 100644 --- a/compiler/sparc/cpupara.pas +++ b/compiler/sparc/cpupara.pas @@ -41,9 +41,8 @@ interface procedure getintparaloc(calloption : tproccalloption; nr : longint; def : tdef; var cgpara : tcgpara);override; function create_paraloc_info(p : TAbstractProcDef; side: tcallercallee):longint;override; function create_varargs_paraloc_info(p : TAbstractProcDef; varargspara:tvarargsparalist):longint;override; - function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override; + function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override; private - procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist; var intparareg,parasize:longint); end; @@ -140,23 +139,17 @@ implementation end; - procedure tsparcparamanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); - begin - p.funcretloc[side]:=get_funcretloc(p,side,p.returndef); - end; - - - function tsparcparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara; + function tsparcparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara; var paraloc : pcgparalocation; retcgsize : tcgsize; begin - if set_common_funcretloc_info(p,def,retcgsize,result) then + if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then exit; paraloc:=result.add_location; { Return in FPU register? } - if def.typ=floatdef then + if result.def.typ=floatdef then begin paraloc^.loc:=LOC_FPUREGISTER; paraloc^.register:=NR_FPU_RESULT_REG; diff --git a/compiler/x86/cgx86.pas b/compiler/x86/cgx86.pas index 4669cf800e..1ed895958a 100644 --- a/compiler/x86/cgx86.pas +++ b/compiler/x86/cgx86.pas @@ -515,9 +515,7 @@ unit cgx86; end end else if (cs_create_pic in current_settings.moduleswitches) and - assigned(ref.symbol) and - not((ref.symbol.bind=AB_LOCAL) and - (ref.symbol.typ in [AT_LABEL,AT_FUNCTION])) then + assigned(ref.symbol) then begin reference_reset_symbol(href,ref.symbol,0,sizeof(pint)); href.base:=current_procinfo.got; diff --git a/compiler/x86_64/cpupara.pas b/compiler/x86_64/cpupara.pas index db768ad422..a590b3ee2c 100644 --- a/compiler/x86_64/cpupara.pas +++ b/compiler/x86_64/cpupara.pas @@ -35,7 +35,6 @@ unit cpupara; type tx86_64paramanager = class(tparamanager) private - procedure create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); procedure create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee;paras:tparalist; var intparareg,mmparareg,parasize:longint;varargsparas: boolean); public @@ -48,7 +47,7 @@ unit cpupara; function get_volatile_registers_fpu(calloption : tproccalloption):tcpuregisterset;override; function create_paraloc_info(p : tabstractprocdef; side: tcallercallee):longint;override; function create_varargs_paraloc_info(p : tabstractprocdef; varargspara:tvarargsparalist):longint;override; - function get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;override; + function get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;override; end; implementation @@ -791,13 +790,7 @@ unit cpupara; end; - procedure tx86_64paramanager.create_funcretloc_info(p : tabstractprocdef; side: tcallercallee); - begin - p.funcretloc[side]:=get_funcretloc(p,side,p.returndef); - end; - - - function tx86_64paramanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara; + function tx86_64paramanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara; const intretregs: array[0..1] of tregister = (NR_FUNCTION_RETURN_REG,NR_FUNCTION_RETURN_REG_HIGH); mmretregs: array[0..1] of tregister = (NR_MM_RESULT_REG,NR_MM_RESULT_REG_HIGH); @@ -810,7 +803,7 @@ unit cpupara; retcgsize : tcgsize; paraloc : pcgparalocation; begin - if set_common_funcretloc_info(p,def,retcgsize,result) then + if set_common_funcretloc_info(p,forcetempdef,retcgsize,result) then exit; { integer sizes < 32 bit have to be sign/zero extended to 32 bit on @@ -827,10 +820,10 @@ unit cpupara; { Return in FPU register? -> don't use classify_argument(), because currency and comp need special treatment here (they are integer class when passing as parameter, but LOC_FPUREGISTER as function result) } - if def.typ=floatdef then + if result.def.typ=floatdef then begin paraloc:=result.add_location; - case tfloatdef(def).floattype of + case tfloatdef(result.def).floattype of s32real: begin paraloc^.loc:=LOC_MMREGISTER; @@ -861,7 +854,7 @@ unit cpupara; else { Return in register } begin - numclasses:=classify_argument(def,vs_value,def.size,classes,0); + numclasses:=classify_argument(result.def,vs_value,result.def.size,classes,0); { this would mean a memory return } if (numclasses=0) then internalerror(2010021502);