* 8086: Do not destroy contents of the BX parameter when calling a procvar by ref with a base.

git-svn-id: trunk@46559 -
This commit is contained in:
yury 2020-08-22 23:06:55 +00:00
parent eee67af684
commit 5ec101d578
2 changed files with 25 additions and 24 deletions

View File

@ -37,8 +37,8 @@ interface
protected
procedure pop_parasize(pop_size:longint);override;
procedure extra_interrupt_code;override;
procedure extra_call_ref_code(var ref: treference);override;
function do_call_ref(ref: treference): tcgpara;override;
function can_call_ref(var ref: treference): boolean; override;
public
function pass_typecheck: tnode; override;
end;
@ -102,25 +102,6 @@ implementation
end;
procedure ti8086callnode.extra_call_ref_code(var ref: treference);
begin
if (ref.base<>NR_NO) and (ref.base<>NR_BP) then
begin
cg.getcpuregister(current_asmdata.CurrAsmList,NR_BX);
cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,ref.base,NR_BX);
ref.base:=NR_BX;
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_BX);
end;
if ref.index<>NR_NO then
begin
cg.getcpuregister(current_asmdata.CurrAsmList,NR_SI);
cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_16,OS_16,ref.index,NR_SI);
ref.index:=NR_SI;
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_SI);
end;
end;
function ti8086callnode.do_call_ref(ref: treference): tcgpara;
begin
if is_proc_far(procdefinition) then
@ -131,6 +112,28 @@ implementation
end;
function ti8086callnode.can_call_ref(var ref: treference): boolean;
var
reg,seg: tregister;
begin
tcgx86(cg).make_simple_ref(current_asmdata.CurrAsmList,ref);
if (procdefinition.proccalloption=pocall_register) and
(getsupreg(ref.base)>=first_int_imreg) and
(getsupreg(ref.index)>=first_int_imreg) then
begin
{ Precalculate the ref address in case both ref base and index are
imm registers and the register calling convention is used.
Otherwise register allocation will fail if BX is used for a parameter. }
reg:=cg.getaddressregister(current_asmdata.CurrAsmList);
current_asmdata.CurrAsmList.concat(taicpu.op_ref_reg(A_LEA,S_W,ref,reg));
seg:=ref.segment;
reference_reset_base(ref,reg,0,ref.temppos,ref.alignment,[]);
ref.segment:=seg;
end;
result:=true;
end;
function ti8086callnode.pass_typecheck: tnode;
begin
Result:=inherited pass_typecheck;

View File

@ -87,11 +87,9 @@ implementation
function tx86callnode.can_call_ref(var ref: treference): boolean;
const
{$if defined(i8086)}
save_all_regs=[pocall_pascal];
{$elseif defined(i386)}
{$if defined(i386)}
save_all_regs=[pocall_far16,pocall_oldfpccall];
{$elseif defined(x86_64)}
{$else}
save_all_regs=[];
{$endif}
begin