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 } { set if the stack frame of the procedure is estimated }
pi_estimatestacksize, pi_estimatestacksize,
{ the routine calls a C-style varargs function } { 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; tprocinfoflags=set of tprocinfoflag;

View File

@ -3685,6 +3685,7 @@ implementation
{ because some abis don't support dynamic stack allocation properly { because some abis don't support dynamic stack allocation properly
open array value parameters are copied onto the heap open array value parameters are copied onto the heap
} }
include(current_procinfo.flags, pi_has_open_array_parameter);
{ calculate necessary memory } { calculate necessary memory }

View File

@ -1818,6 +1818,24 @@ unit cgcpu;
var var
stacksize : longint; stacksize : longint;
ret_instr: TAsmOp; 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 begin
if is_proc_far(current_procinfo.procdef) then if is_proc_far(current_procinfo.procdef) then
ret_instr:=A_RETF ret_instr:=A_RETF
@ -1828,21 +1846,9 @@ unit cgcpu;
(rg[R_MMXREGISTER].uses_registers) then (rg[R_MMXREGISTER].uses_registers) then
list.concat(Taicpu.op_none(A_EMMS,S_NO)); list.concat(Taicpu.op_none(A_EMMS,S_NO));
sp_moved:=false;
{ remove stackframe } { remove stackframe }
if not nostackframe then if not nostackframe then
begin
if (po_exports in current_procinfo.procdef.procoptions) and
(target_info.system=system_i8086_win16) then
begin
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_DI));
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_SI));
end;
if ((current_settings.x86memorymodel=mm_huge) and
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));
if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
begin begin
stacksize:=current_procinfo.calc_stackframe_size; stacksize:=current_procinfo.calc_stackframe_size;
if (target_info.stackalign>4) and if (target_info.stackalign>4) and
@ -1852,6 +1858,23 @@ unit cgcpu;
{ if you (think you) know what you are doing } { if you (think you) know what you are doing }
(po_assembler in current_procinfo.procdef.procoptions)) then (po_assembler in current_procinfo.procdef.procoptions)) then
stacksize := align(stacksize+sizeof(aint),target_info.stackalign) - sizeof(aint); 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;
if ((current_settings.x86memorymodel=mm_huge) and
not (po_interrupt in current_procinfo.procdef.procoptions)) or
((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_DS));
end;
if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
begin
if (stacksize<>0) then if (stacksize<>0) then
cg.a_op_const_reg(list,OP_ADD,OS_ADDR,stacksize,current_procinfo.framepointer); cg.a_op_const_reg(list,OP_ADD,OS_ADDR,stacksize,current_procinfo.framepointer);
end end
@ -1922,6 +1945,8 @@ unit cgcpu;
list.concat(Taicpu.op_reg(A_INC,S_W,NR_DI)); list.concat(Taicpu.op_reg(A_INC,S_W,NR_DI));
{ Now DI contains (high+1). } { Now DI contains (high+1). }
include(current_procinfo.flags, pi_has_open_array_parameter);
{ special case handling for elesize=2: { special case handling for elesize=2:
set CX = (high+1) instead of CX = (high+1)*elesize. 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); procedure tcg8086.g_releasevaluepara_openarray(list : TAsmList;const l:tlocation);
begin begin
{ Nothing to release } { Nothing to do }
end; end;

View File

@ -1281,7 +1281,9 @@ const
(mask:pi_estimatestacksize; (mask:pi_estimatestacksize;
str:' stack size is estimated before subroutine is compiled '), str:' stack size is estimated before subroutine is compiled '),
(mask:pi_calls_c_varargs; (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 var
procinfooptions : tprocinfoflags; procinfooptions : tprocinfoflags;