mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-10 15:45:57 +02:00
* In preparation for fixing Mantis #24791: Copy related code from tcgx86.g_proc_entry to tcgx86_64.g_proc_entry, and remove win64-specific stuff from tcgx86 version.
git-svn-id: trunk@25218 -
This commit is contained in:
parent
ea65e272dd
commit
1f72143eef
@ -2513,41 +2513,11 @@ unit cgx86;
|
||||
inc(stackmisalignment,sizeof(pint));
|
||||
include(rg[R_INTREGISTER].preserved_by_proc,RS_FRAME_POINTER_REG);
|
||||
list.concat(Taicpu.op_reg(A_PUSH,tcgsize2opsize[OS_ADDR],NR_FRAME_POINTER_REG));
|
||||
if (target_info.system=system_x86_64_win64) then
|
||||
begin
|
||||
list.concat(cai_seh_directive.create_reg(ash_pushreg,NR_FRAME_POINTER_REG));
|
||||
include(current_procinfo.flags,pi_has_unwind_info);
|
||||
end;
|
||||
{ Return address and FP are both on stack }
|
||||
current_asmdata.asmcfi.cfa_def_cfa_offset(list,2*sizeof(pint));
|
||||
current_asmdata.asmcfi.cfa_offset(list,NR_FRAME_POINTER_REG,-(2*sizeof(pint)));
|
||||
if current_procinfo.procdef.proctypeoption<>potype_exceptfilter then
|
||||
list.concat(Taicpu.op_reg_reg(A_MOV,tcgsize2opsize[OS_ADDR],NR_STACK_POINTER_REG,NR_FRAME_POINTER_REG))
|
||||
else
|
||||
begin
|
||||
{ load framepointer from hidden $parentfp parameter }
|
||||
para:=tparavarsym(current_procinfo.procdef.paras[0]);
|
||||
if not (vo_is_parentfp in para.varoptions) then
|
||||
InternalError(201201142);
|
||||
if (para.paraloc[calleeside].location^.loc<>LOC_REGISTER) or
|
||||
(para.paraloc[calleeside].location^.next<>nil) then
|
||||
InternalError(201201143);
|
||||
list.concat(Taicpu.op_reg_reg(A_MOV,tcgsize2opsize[OS_ADDR],
|
||||
para.paraloc[calleeside].location^.register,NR_FRAME_POINTER_REG));
|
||||
{ Need only as much stack space as necessary to do the calls.
|
||||
Exception filters don't have own local vars, and temps are 'mapped'
|
||||
to the parent procedure.
|
||||
maxpushedparasize is already aligned at least on x86_64. }
|
||||
localsize:=current_procinfo.maxpushedparasize;
|
||||
end;
|
||||
list.concat(Taicpu.op_reg_reg(A_MOV,tcgsize2opsize[OS_ADDR],NR_STACK_POINTER_REG,NR_FRAME_POINTER_REG));
|
||||
current_asmdata.asmcfi.cfa_def_cfa_register(list,NR_FRAME_POINTER_REG);
|
||||
{
|
||||
TODO: current framepointer handling is not compatible with Win64 at all:
|
||||
Win64 expects FP to point to the top or into the middle of local area.
|
||||
In FPC it points to the bottom, making it impossible to generate
|
||||
UWOP_SET_FPREG unwind code if local area is > 240 bytes.
|
||||
So for now pretend we never have a framepointer.
|
||||
}
|
||||
end;
|
||||
|
||||
{ allocate stackframe space }
|
||||
@ -2563,12 +2533,6 @@ unit cgx86;
|
||||
if current_procinfo.framepointer=NR_STACK_POINTER_REG then
|
||||
current_asmdata.asmcfi.cfa_def_cfa_offset(list,localsize+sizeof(pint));
|
||||
current_procinfo.final_localsize:=localsize;
|
||||
if (target_info.system=system_x86_64_win64) then
|
||||
begin
|
||||
if localsize<>0 then
|
||||
list.concat(cai_seh_directive.create_offset(ash_stackalloc,localsize));
|
||||
include(current_procinfo.flags,pi_has_unwind_info);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -36,7 +36,7 @@ unit cgcpu;
|
||||
tcgx86_64 = class(tcgx86)
|
||||
procedure init_register_allocators;override;
|
||||
|
||||
procedure g_proc_entry(list : TAsmList; parasize:longint; nostackframe:boolean);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;
|
||||
procedure g_local_unwind(list: TAsmList; l: TAsmLabel);override;
|
||||
@ -109,7 +109,7 @@ unit cgcpu;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgx86_64.g_proc_entry(list : TAsmList;parasize:longint;nostackframe:boolean);
|
||||
procedure tcgx86_64.g_proc_entry(list : TAsmList;localsize:longint;nostackframe:boolean);
|
||||
var
|
||||
hitem: tlinkedlistitem;
|
||||
r: integer;
|
||||
@ -117,13 +117,86 @@ unit cgcpu;
|
||||
templist: TAsmList;
|
||||
frame_offset: longint;
|
||||
suppress_endprologue: boolean;
|
||||
stackmisalignment: longint;
|
||||
para: tparavarsym;
|
||||
begin
|
||||
hitem:=list.last;
|
||||
{ pi_has_unwind_info may already be set at this point if there are
|
||||
SEH directives in assembler body. In this case, .seh_endprologue
|
||||
is expected to be one of those directives, and not generated here. }
|
||||
suppress_endprologue:=(pi_has_unwind_info in current_procinfo.flags);
|
||||
inherited g_proc_entry(list,parasize,nostackframe);
|
||||
|
||||
{ save old framepointer }
|
||||
if not nostackframe then
|
||||
begin
|
||||
{ return address }
|
||||
stackmisalignment := sizeof(pint);
|
||||
list.concat(tai_regalloc.alloc(current_procinfo.framepointer,nil));
|
||||
if current_procinfo.framepointer=NR_STACK_POINTER_REG then
|
||||
CGmessage(cg_d_stackframe_omited)
|
||||
else
|
||||
begin
|
||||
{ push <frame_pointer> }
|
||||
inc(stackmisalignment,sizeof(pint));
|
||||
list.concat(Taicpu.op_reg(A_PUSH,tcgsize2opsize[OS_ADDR],NR_FRAME_POINTER_REG));
|
||||
if (target_info.system=system_x86_64_win64) then
|
||||
begin
|
||||
list.concat(cai_seh_directive.create_reg(ash_pushreg,NR_FRAME_POINTER_REG));
|
||||
include(current_procinfo.flags,pi_has_unwind_info);
|
||||
end;
|
||||
{ Return address and FP are both on stack }
|
||||
current_asmdata.asmcfi.cfa_def_cfa_offset(list,2*sizeof(pint));
|
||||
current_asmdata.asmcfi.cfa_offset(list,NR_FRAME_POINTER_REG,-(2*sizeof(pint)));
|
||||
if current_procinfo.procdef.proctypeoption<>potype_exceptfilter then
|
||||
list.concat(Taicpu.op_reg_reg(A_MOV,tcgsize2opsize[OS_ADDR],NR_STACK_POINTER_REG,NR_FRAME_POINTER_REG))
|
||||
else
|
||||
begin
|
||||
{ load framepointer from hidden $parentfp parameter }
|
||||
para:=tparavarsym(current_procinfo.procdef.paras[0]);
|
||||
if not (vo_is_parentfp in para.varoptions) then
|
||||
InternalError(201201142);
|
||||
if (para.paraloc[calleeside].location^.loc<>LOC_REGISTER) or
|
||||
(para.paraloc[calleeside].location^.next<>nil) then
|
||||
InternalError(201201143);
|
||||
list.concat(Taicpu.op_reg_reg(A_MOV,tcgsize2opsize[OS_ADDR],
|
||||
para.paraloc[calleeside].location^.register,NR_FRAME_POINTER_REG));
|
||||
{ Need only as much stack space as necessary to do the calls.
|
||||
Exception filters don't have own local vars, and temps are 'mapped'
|
||||
to the parent procedure.
|
||||
maxpushedparasize is already aligned at least on x86_64. }
|
||||
localsize:=current_procinfo.maxpushedparasize;
|
||||
end;
|
||||
current_asmdata.asmcfi.cfa_def_cfa_register(list,NR_FRAME_POINTER_REG);
|
||||
{
|
||||
TODO: current framepointer handling is not compatible with Win64 at all:
|
||||
Win64 expects FP to point to the top or into the middle of local area.
|
||||
In FPC it points to the bottom, making it impossible to generate
|
||||
UWOP_SET_FPREG unwind code if local area is > 240 bytes.
|
||||
So for now pretend we never have a framepointer.
|
||||
}
|
||||
end;
|
||||
|
||||
{ allocate stackframe space }
|
||||
if (localsize<>0) or
|
||||
((target_info.stackalign>sizeof(pint)) and
|
||||
(stackmisalignment <> 0) and
|
||||
((pi_do_call in current_procinfo.flags) or
|
||||
(po_assembler in current_procinfo.procdef.procoptions))) then
|
||||
begin
|
||||
if target_info.stackalign>sizeof(pint) then
|
||||
localsize := align(localsize+stackmisalignment,target_info.stackalign)-stackmisalignment;
|
||||
cg.g_stackpointer_alloc(list,localsize);
|
||||
if current_procinfo.framepointer=NR_STACK_POINTER_REG then
|
||||
current_asmdata.asmcfi.cfa_def_cfa_offset(list,localsize+sizeof(pint));
|
||||
current_procinfo.final_localsize:=localsize;
|
||||
if (target_info.system=system_x86_64_win64) then
|
||||
begin
|
||||
if localsize<>0 then
|
||||
list.concat(cai_seh_directive.create_offset(ash_stackalloc,localsize));
|
||||
include(current_procinfo.flags,pi_has_unwind_info);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if not (pi_has_unwind_info in current_procinfo.flags) then
|
||||
exit;
|
||||
|
Loading…
Reference in New Issue
Block a user