mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-14 13:59:28 +02:00
Add pi_has_open_array_parameter to proc_info.flags as this requires special handling for i8086 huge memory model to restore DS register correctly
git-svn-id: trunk@32922 -
This commit is contained in:
parent
741a3eedf9
commit
40193ea1db
@ -644,7 +644,12 @@ interface
|
||||
{ set if the stack frame of the procedure is estimated }
|
||||
pi_estimatestacksize,
|
||||
{ the routine calls a C-style varargs function }
|
||||
pi_calls_c_varargs
|
||||
pi_calls_c_varargs,
|
||||
{ the routine has an open array parameter,
|
||||
for i8086 cpu huge memory model,
|
||||
as this changes SP register it requires special handling
|
||||
to restore DS segment register }
|
||||
pi_has_open_array_parameter
|
||||
);
|
||||
tprocinfoflags=set of tprocinfoflag;
|
||||
|
||||
|
@ -3685,6 +3685,7 @@ implementation
|
||||
{ because some abis don't support dynamic stack allocation properly
|
||||
open array value parameters are copied onto the heap
|
||||
}
|
||||
include(current_procinfo.flags, pi_has_open_array_parameter);
|
||||
|
||||
{ calculate necessary memory }
|
||||
|
||||
|
@ -1818,6 +1818,24 @@ unit cgcpu;
|
||||
var
|
||||
stacksize : longint;
|
||||
ret_instr: TAsmOp;
|
||||
sp_moved : boolean;
|
||||
|
||||
procedure maybe_move_sp;
|
||||
var
|
||||
ref : treference;
|
||||
begin
|
||||
if sp_moved then
|
||||
exit;
|
||||
if not(pi_has_open_array_parameter in current_procinfo.flags) then
|
||||
exit;
|
||||
{ Restore SP position before SP change }
|
||||
if current_settings.x86memorymodel=mm_huge then
|
||||
stacksize:=stacksize + 2;
|
||||
reference_reset_base(ref,NR_BP,-stacksize,2);
|
||||
list.concat(Taicpu.op_ref_reg(A_LEA,S_W,ref,NR_SP));
|
||||
sp_moved:=true;
|
||||
end;
|
||||
|
||||
begin
|
||||
if is_proc_far(current_procinfo.procdef) then
|
||||
ret_instr:=A_RETF
|
||||
@ -1828,12 +1846,22 @@ unit cgcpu;
|
||||
(rg[R_MMXREGISTER].uses_registers) then
|
||||
list.concat(Taicpu.op_none(A_EMMS,S_NO));
|
||||
|
||||
sp_moved:=false;
|
||||
{ remove stackframe }
|
||||
if not nostackframe then
|
||||
begin
|
||||
stacksize:=current_procinfo.calc_stackframe_size;
|
||||
if (target_info.stackalign>4) and
|
||||
((stacksize <> 0) or
|
||||
(pi_do_call in current_procinfo.flags) or
|
||||
{ can't detect if a call in this case -> use nostackframe }
|
||||
{ if you (think you) know what you are doing }
|
||||
(po_assembler in current_procinfo.procdef.procoptions)) then
|
||||
stacksize := align(stacksize+sizeof(aint),target_info.stackalign) - sizeof(aint);
|
||||
if (po_exports in current_procinfo.procdef.procoptions) and
|
||||
(target_info.system=system_i8086_win16) then
|
||||
begin
|
||||
maybe_move_sp;
|
||||
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_DI));
|
||||
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_SI));
|
||||
end;
|
||||
@ -1841,17 +1869,12 @@ unit cgcpu;
|
||||
not (po_interrupt in current_procinfo.procdef.procoptions)) or
|
||||
((po_exports in current_procinfo.procdef.procoptions) and
|
||||
(target_info.system=system_i8086_win16)) then
|
||||
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_DS));
|
||||
begin
|
||||
maybe_move_sp;
|
||||
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_DS));
|
||||
end;
|
||||
if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
|
||||
begin
|
||||
stacksize:=current_procinfo.calc_stackframe_size;
|
||||
if (target_info.stackalign>4) and
|
||||
((stacksize <> 0) or
|
||||
(pi_do_call in current_procinfo.flags) or
|
||||
{ can't detect if a call in this case -> use nostackframe }
|
||||
{ if you (think you) know what you are doing }
|
||||
(po_assembler in current_procinfo.procdef.procoptions)) then
|
||||
stacksize := align(stacksize+sizeof(aint),target_info.stackalign) - sizeof(aint);
|
||||
if (stacksize<>0) then
|
||||
cg.a_op_const_reg(list,OP_ADD,OS_ADDR,stacksize,current_procinfo.framepointer);
|
||||
end
|
||||
@ -1921,6 +1944,8 @@ unit cgcpu;
|
||||
a_load_loc_reg(list,OS_INT,lenloc,NR_DI);
|
||||
list.concat(Taicpu.op_reg(A_INC,S_W,NR_DI));
|
||||
{ Now DI contains (high+1). }
|
||||
|
||||
include(current_procinfo.flags, pi_has_open_array_parameter);
|
||||
|
||||
{ special case handling for elesize=2:
|
||||
set CX = (high+1) instead of CX = (high+1)*elesize.
|
||||
@ -2034,7 +2059,7 @@ unit cgcpu;
|
||||
|
||||
procedure tcg8086.g_releasevaluepara_openarray(list : TAsmList;const l:tlocation);
|
||||
begin
|
||||
{ Nothing to release }
|
||||
{ Nothing to do }
|
||||
end;
|
||||
|
||||
|
||||
|
@ -1281,7 +1281,9 @@ const
|
||||
(mask:pi_estimatestacksize;
|
||||
str:' stack size is estimated before subroutine is compiled '),
|
||||
(mask:pi_calls_c_varargs;
|
||||
str:' calls function with C-style varargs ')
|
||||
str:' calls function with C-style varargs '),
|
||||
(mask:pi_has_open_array_parameter;
|
||||
str:' has open array parameter ')
|
||||
);
|
||||
var
|
||||
procinfooptions : tprocinfoflags;
|
||||
|
Loading…
Reference in New Issue
Block a user