* 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 -
This commit is contained in:
Jonas Maebe 2014-11-04 21:16:27 +00:00
parent 6712954607
commit d8c898742a
2 changed files with 39 additions and 0 deletions

View File

@ -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

View File

@ -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 }