From c2e3fb5918287da5604d75f98227f994b910f4f4 Mon Sep 17 00:00:00 2001 From: nickysn Date: Sat, 1 Jun 2013 15:50:11 +0000 Subject: [PATCH] + emit proper interrupt procedure entry/exit code on i8086 git-svn-id: trunk@24728 - --- compiler/cgbase.pas | 3 +++ compiler/i8086/cgcpu.pas | 48 ++++++++------------------------------- compiler/x86/agx86nsm.pas | 6 +++++ compiler/x86/cgx86.pas | 21 +++++++++++++++++ 4 files changed, 40 insertions(+), 38 deletions(-) diff --git a/compiler/cgbase.pas b/compiler/cgbase.pas index 816e05a9c8..dcaf96c12e 100644 --- a/compiler/cgbase.pas +++ b/compiler/cgbase.pas @@ -97,6 +97,9 @@ interface ,addr_lo8 ,addr_hi8 {$ENDIF} + {$IFDEF i8086} + ,addr_dgroup // the data segment group + {$ENDIF} ); diff --git a/compiler/i8086/cgcpu.pas b/compiler/i8086/cgcpu.pas index f35f932728..1b398beaed 100644 --- a/compiler/i8086/cgcpu.pas +++ b/compiler/i8086/cgcpu.pas @@ -1244,45 +1244,17 @@ unit cgcpu; list.concat(tai_regalloc.dealloc(current_procinfo.framepointer,nil)); end; - { return from proc } - if (po_interrupt in current_procinfo.procdef.procoptions) and - { this messes up stack alignment } - (target_info.stackalign=4) then + { return from interrupt } + if po_interrupt in current_procinfo.procdef.procoptions then begin - if assigned(current_procinfo.procdef.funcretloc[calleeside].location) and - (current_procinfo.procdef.funcretloc[calleeside].location^.loc=LOC_REGISTER) then - begin - if (getsupreg(current_procinfo.procdef.funcretloc[calleeside].location^.register)=RS_EAX) then - list.concat(Taicpu.Op_const_reg(A_ADD,S_L,4,NR_ESP)) - else - internalerror(2010053001); - end - 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_reg(A_POP,S_L,NR_ES)); + list.concat(Taicpu.Op_reg(A_POP,S_L,NR_DS)); + list.concat(Taicpu.Op_reg(A_POP,S_W,NR_DI)); + list.concat(Taicpu.Op_reg(A_POP,S_W,NR_SI)); + list.concat(Taicpu.Op_reg(A_POP,S_W,NR_DX)); + list.concat(Taicpu.Op_reg(A_POP,S_W,NR_CX)); + list.concat(Taicpu.Op_reg(A_POP,S_W,NR_BX)); + list.concat(Taicpu.Op_reg(A_POP,S_W,NR_AX)); list.concat(Taicpu.Op_none(A_IRET,S_NO)); end { Routines with the poclearstack flag set use only a ret } diff --git a/compiler/x86/agx86nsm.pas b/compiler/x86/agx86nsm.pas index f663865144..e70ca884de 100644 --- a/compiler/x86/agx86nsm.pas +++ b/compiler/x86/agx86nsm.pas @@ -367,6 +367,12 @@ interface AsmWrite(sizestr(s,dest)); WriteReference(o.ref^); end +{$ifdef i8086} + else if o.ref^.refaddr=addr_dgroup then + begin + AsmWrite('dgroup'); + end +{$endif i8086} else begin {$ifdef x86_64} diff --git a/compiler/x86/cgx86.pas b/compiler/x86/cgx86.pas index 4571b2d0b7..3bb13dc526 100644 --- a/compiler/x86/cgx86.pas +++ b/compiler/x86/cgx86.pas @@ -2212,7 +2212,28 @@ unit cgx86; var stackmisalignment: longint; para: tparavarsym; +{$ifdef i8086} + dgroup: treference; +{$endif i8086} 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} { interrupt support for i386 } if (po_interrupt in current_procinfo.procdef.procoptions) and