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:
pierre 2016-01-11 15:02:10 +00:00
parent 741a3eedf9
commit 40193ea1db
4 changed files with 45 additions and 12 deletions

View File

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

View File

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

View File

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

View File

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