mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-30 19:40:08 +02:00
+ emit proper interrupt procedure entry/exit code on i8086
git-svn-id: trunk@24728 -
This commit is contained in:
parent
a11c113429
commit
c2e3fb5918
@ -97,6 +97,9 @@ interface
|
|||||||
,addr_lo8
|
,addr_lo8
|
||||||
,addr_hi8
|
,addr_hi8
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
{$IFDEF i8086}
|
||||||
|
,addr_dgroup // the data segment group
|
||||||
|
{$ENDIF}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -1244,45 +1244,17 @@ unit cgcpu;
|
|||||||
list.concat(tai_regalloc.dealloc(current_procinfo.framepointer,nil));
|
list.concat(tai_regalloc.dealloc(current_procinfo.framepointer,nil));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ return from proc }
|
{ return from interrupt }
|
||||||
if (po_interrupt in current_procinfo.procdef.procoptions) and
|
if po_interrupt in current_procinfo.procdef.procoptions then
|
||||||
{ this messes up stack alignment }
|
|
||||||
(target_info.stackalign=4) then
|
|
||||||
begin
|
begin
|
||||||
if assigned(current_procinfo.procdef.funcretloc[calleeside].location) and
|
list.concat(Taicpu.Op_reg(A_POP,S_L,NR_ES));
|
||||||
(current_procinfo.procdef.funcretloc[calleeside].location^.loc=LOC_REGISTER) then
|
list.concat(Taicpu.Op_reg(A_POP,S_L,NR_DS));
|
||||||
begin
|
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_DI));
|
||||||
if (getsupreg(current_procinfo.procdef.funcretloc[calleeside].location^.register)=RS_EAX) then
|
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_SI));
|
||||||
list.concat(Taicpu.Op_const_reg(A_ADD,S_L,4,NR_ESP))
|
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_DX));
|
||||||
else
|
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_CX));
|
||||||
internalerror(2010053001);
|
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_BX));
|
||||||
end
|
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_AX));
|
||||||
else
|
|
||||||
list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EAX));
|
|
||||||
list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EBX));
|
|
||||||
list.concat(Taicpu.Op_reg(A_POP,S_L,NR_ECX));
|
|
||||||
|
|
||||||
if (current_procinfo.procdef.funcretloc[calleeside].size in [OS_64,OS_S64]) and
|
|
||||||
assigned(current_procinfo.procdef.funcretloc[calleeside].location) and
|
|
||||||
assigned(current_procinfo.procdef.funcretloc[calleeside].location^.next) and
|
|
||||||
(current_procinfo.procdef.funcretloc[calleeside].location^.next^.loc=LOC_REGISTER) then
|
|
||||||
begin
|
|
||||||
if (getsupreg(current_procinfo.procdef.funcretloc[calleeside].location^.next^.register)=RS_EDX) then
|
|
||||||
list.concat(Taicpu.Op_const_reg(A_ADD,S_L,4,NR_ESP))
|
|
||||||
else
|
|
||||||
internalerror(2010053002);
|
|
||||||
end
|
|
||||||
else
|
|
||||||
list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EDX));
|
|
||||||
|
|
||||||
list.concat(Taicpu.Op_reg(A_POP,S_L,NR_ESI));
|
|
||||||
list.concat(Taicpu.Op_reg(A_POP,S_L,NR_EDI));
|
|
||||||
{ .... also the segment registers }
|
|
||||||
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_DS));
|
|
||||||
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_ES));
|
|
||||||
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_FS));
|
|
||||||
list.concat(Taicpu.Op_reg(A_POP,S_W,NR_GS));
|
|
||||||
{ this restores the flags }
|
|
||||||
list.concat(Taicpu.Op_none(A_IRET,S_NO));
|
list.concat(Taicpu.Op_none(A_IRET,S_NO));
|
||||||
end
|
end
|
||||||
{ Routines with the poclearstack flag set use only a ret }
|
{ Routines with the poclearstack flag set use only a ret }
|
||||||
|
@ -367,6 +367,12 @@ interface
|
|||||||
AsmWrite(sizestr(s,dest));
|
AsmWrite(sizestr(s,dest));
|
||||||
WriteReference(o.ref^);
|
WriteReference(o.ref^);
|
||||||
end
|
end
|
||||||
|
{$ifdef i8086}
|
||||||
|
else if o.ref^.refaddr=addr_dgroup then
|
||||||
|
begin
|
||||||
|
AsmWrite('dgroup');
|
||||||
|
end
|
||||||
|
{$endif i8086}
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
{$ifdef x86_64}
|
{$ifdef x86_64}
|
||||||
|
@ -2212,7 +2212,28 @@ unit cgx86;
|
|||||||
var
|
var
|
||||||
stackmisalignment: longint;
|
stackmisalignment: longint;
|
||||||
para: tparavarsym;
|
para: tparavarsym;
|
||||||
|
{$ifdef i8086}
|
||||||
|
dgroup: treference;
|
||||||
|
{$endif i8086}
|
||||||
begin
|
begin
|
||||||
|
{$ifdef i8086}
|
||||||
|
{ interrupt support for i8086 }
|
||||||
|
if po_interrupt in current_procinfo.procdef.procoptions then
|
||||||
|
begin
|
||||||
|
list.concat(Taicpu.Op_reg(A_PUSH,S_W,NR_AX));
|
||||||
|
list.concat(Taicpu.Op_reg(A_PUSH,S_W,NR_BX));
|
||||||
|
list.concat(Taicpu.Op_reg(A_PUSH,S_W,NR_CX));
|
||||||
|
list.concat(Taicpu.Op_reg(A_PUSH,S_W,NR_DX));
|
||||||
|
list.concat(Taicpu.Op_reg(A_PUSH,S_W,NR_SI));
|
||||||
|
list.concat(Taicpu.Op_reg(A_PUSH,S_W,NR_DI));
|
||||||
|
list.concat(Taicpu.Op_reg(A_PUSH,S_L,NR_DS));
|
||||||
|
list.concat(Taicpu.Op_reg(A_PUSH,S_L,NR_ES));
|
||||||
|
reference_reset(dgroup,0);
|
||||||
|
dgroup.refaddr:=addr_dgroup;
|
||||||
|
list.concat(Taicpu.Op_ref_reg(A_MOV,S_W,dgroup,NR_AX));
|
||||||
|
list.concat(Taicpu.Op_reg_reg(A_MOV,S_W,NR_AX,NR_DS));
|
||||||
|
end;
|
||||||
|
{$endif i8086}
|
||||||
{$ifdef i386}
|
{$ifdef i386}
|
||||||
{ interrupt support for i386 }
|
{ interrupt support for i386 }
|
||||||
if (po_interrupt in current_procinfo.procdef.procoptions) and
|
if (po_interrupt in current_procinfo.procdef.procoptions) and
|
||||||
|
Loading…
Reference in New Issue
Block a user