From d8c898742a814c245d2cf3fd8c2d386cef2a65f4 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Tue, 4 Nov 2014 21:16:27 +0000 Subject: [PATCH] * handle the fact that records containing a single extended value are returned on the x87 fpu stack on x86-64 o also handle the fact that this means that we'll generated float loads/stores with OS_128/OS_F128 in case the surrounding record is padded to a multiple of its alignment git-svn-id: trunk@28985 - --- compiler/x86_64/cgcpu.pas | 27 +++++++++++++++++++++++++++ compiler/x86_64/cpupara.pas | 12 ++++++++++++ 2 files changed, 39 insertions(+) diff --git a/compiler/x86_64/cgcpu.pas b/compiler/x86_64/cgcpu.pas index 6755f82787..d702844f4f 100644 --- a/compiler/x86_64/cgcpu.pas +++ b/compiler/x86_64/cgcpu.pas @@ -36,6 +36,9 @@ unit cgcpu; tcgx86_64 = class(tcgx86) procedure init_register_allocators;override; + procedure a_loadfpu_ref_cgpara(list: TAsmList; size: tcgsize; const ref: treference; const cgpara: TCGPara); override; + procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); override; + procedure g_proc_entry(list : TAsmList;localsize:longint; nostackframe:boolean);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; @@ -116,6 +119,30 @@ unit cgcpu; end; + procedure tcgx86_64.a_loadfpu_ref_cgpara(list: TAsmList; size: tcgsize; const ref: treference; const cgpara: TCGPara); + begin + { a record containing an extended value is returned on the x87 stack + -> size will be OS_F128 (if not packed), while cgpara.paraloc^.size + contains the proper size + + In the future we should probably always use cgpara.location^.size, but + that should only be tested/done after 2.8 is branched } + if size in [OS_128,OS_F128] then + size:=cgpara.location^.size; + inherited; + end; + + + procedure tcgx86_64.a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); + begin + { same as with a_loadfpu_ref_cgpara() above, but on the callee side + when the value is moved from the fpu register into a memory location } + if tosize in [OS_128,OS_F128] then + tosize:=OS_F80; + inherited; + end; + + function tcgx86_64.use_push: boolean; begin result:=(current_procinfo.framepointer=NR_STACK_POINTER_REG) or diff --git a/compiler/x86_64/cpupara.pas b/compiler/x86_64/cpupara.pas index 06c28efbae..c61712b10b 100644 --- a/compiler/x86_64/cpupara.pas +++ b/compiler/x86_64/cpupara.pas @@ -1036,6 +1036,18 @@ unit cpupara; end; inc(mmretregidx); end; + X86_64_X87_CLASS: + begin + { must be followed by X86_64_X87UP_CLASS and that must be + the last class } + if (i<>(numclasses-2)) or + (classes[i+1].typ<>X86_64_X87UP_CLASS) then + internalerror(2014110401); + paraloc^.loc:=LOC_FPUREGISTER; + paraloc^.register:=NR_FPU_RESULT_REG; + paraloc^.size:=OS_F80; + break; + end; X86_64_NO_CLASS: begin { empty record/array }