diff options
author | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-06-01 15:50:11 +0000 |
---|---|---|
committer | nickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-06-01 15:50:11 +0000 |
commit | 31b0e4bc6214e3c2f34df0ff3bc0da5dc8fd7d80 (patch) | |
tree | 38b3e11bbd3505ddadacf3813dfd06cc8c2fd896 /compiler | |
parent | 2b01a24670d6e461f34de33bca68648baaafbbfd (diff) | |
download | fpc-31b0e4bc6214e3c2f34df0ff3bc0da5dc8fd7d80.tar.gz |
+ emit proper interrupt procedure entry/exit code on i8086
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@24728 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/cgbase.pas | 3 | ||||
-rw-r--r-- | compiler/i8086/cgcpu.pas | 48 | ||||
-rw-r--r-- | compiler/x86/agx86nsm.pas | 6 | ||||
-rw-r--r-- | 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 |