From 5eef73c1ab06a28c556dcf4df1f131be2be417c0 Mon Sep 17 00:00:00 2001 From: florian Date: Tue, 17 Oct 2006 20:58:16 +0000 Subject: [PATCH] * fixed passing of registers on x86-64_linux, should fix #7613 git-svn-id: trunk@4951 - --- compiler/x86_64/cgcpu.pas | 35 +++++++++++++++++++++++++++++++++-- compiler/x86_64/cpupara.pas | 33 +++++++++++++++++++-------------- 2 files changed, 52 insertions(+), 16 deletions(-) diff --git a/compiler/x86_64/cgcpu.pas b/compiler/x86_64/cgcpu.pas index 2f330ddc2e..6d63c4cd60 100644 --- a/compiler/x86_64/cgcpu.pas +++ b/compiler/x86_64/cgcpu.pas @@ -26,7 +26,7 @@ unit cgcpu; interface uses - cgbase,cgobj,cgx86, + cgbase,cgutils,cgobj,cgx86, aasmbase,aasmtai,aasmdata,aasmcpu, cpubase,cpuinfo,cpupara,parabase, symdef, @@ -37,6 +37,8 @@ unit cgcpu; procedure init_register_allocators;override; procedure g_proc_exit(list : TAsmList;parasize:longint;nostackframe:boolean);override; procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override; + + procedure a_param_ref(list : TAsmList;size : tcgsize;const r : treference;const paraloc : TCGPara);override; end; @@ -44,7 +46,7 @@ unit cgcpu; uses globtype,globals,verbose,systems,cutils, - symsym,defutil,paramgr,fmodule,cgutils, + symsym,defutil,paramgr,fmodule, rgobj,tgobj,rgcpu; @@ -59,6 +61,35 @@ unit cgcpu; end; + procedure tcgx86_64.a_param_ref(list : TAsmList;size : tcgsize;const r : treference;const paraloc : TCGPara); + var + tmpref, ref: treference; + location: pcgparalocation; + sizeleft: aint; + begin + location := paraloc.location; + tmpref := r; + sizeleft := paraloc.intsize; + while assigned(location) do + begin + case location^.loc of + LOC_REGISTER,LOC_CREGISTER: + a_load_ref_reg(list,location^.size,location^.size,tmpref,location^.register); + LOC_REFERENCE: + begin + reference_reset_base(ref,location^.reference.index,location^.reference.offset); + g_concatcopy(list,tmpref,ref,sizeleft); + end; + else + internalerror(2002081103); + end; + inc(tmpref.offset,tcgsize2size[location^.size]); + dec(sizeleft,tcgsize2size[location^.size]); + location := location^.next; + end; + end; + + procedure tcgx86_64.g_proc_exit(list : TAsmList;parasize:longint;nostackframe:boolean); var stacksize : longint; diff --git a/compiler/x86_64/cpupara.pas b/compiler/x86_64/cpupara.pas index d438953c46..8d55ca68bb 100644 --- a/compiler/x86_64/cpupara.pas +++ b/compiler/x86_64/cpupara.pas @@ -96,14 +96,11 @@ unit cpupara; end; recorddef: begin - if p.size<=16 then - begin - if (target_info.system=system_x86_64_win64) and - (p.size<=8) then - loc1:=LOC_REGISTER - else - loc1:=LOC_REFERENCE; - end + { win64 abi } + if ((target_info.system=system_x86_64_win64) and (p.size<=8)) or + { linux abi } + ((target_info.system<>system_x86_64_win64) and (p.size<=16)) then + loc1:=LOC_REGISTER else loc1:=LOC_REFERENCE; end; @@ -111,8 +108,10 @@ unit cpupara; begin if is_object(p) then begin - if (target_info.system=system_x86_64_win64) and - (p.size<=8) then + { win64 abi } + if ((target_info.system=system_x86_64_win64) and (p.size<=8)) or + { linux abi } + ((target_info.system<>system_x86_64_win64) and (p.size<=16)) then loc1:=LOC_REGISTER else loc1:=LOC_REFERENCE; @@ -122,15 +121,21 @@ unit cpupara; end; arraydef: begin - if (target_info.system=system_x86_64_win64) and - not(is_special_array(p)) and - (p.size<=8) then + if not(is_special_array(p)) and + { win64 abi } + ((target_info.system=system_x86_64_win64) and (p.size<=8)) or + { linux abi } + ((target_info.system<>system_x86_64_win64) and (p.size<=16)) then loc1:=LOC_REGISTER else loc1:=LOC_REFERENCE; end; variantdef: - loc1:=LOC_REFERENCE; + { linux abi } + if target_info.system<>system_x86_64_win64 then + loc1:=LOC_REGISTER + else + loc1:=LOC_REFERENCE; stringdef: if is_shortstring(p) or is_longstring(p) then loc1:=LOC_REFERENCE