summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authornickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2>2013-06-01 15:50:11 +0000
committernickysn <nickysn@3ad0048d-3df7-0310-abae-a5850022a9f2>2013-06-01 15:50:11 +0000
commit31b0e4bc6214e3c2f34df0ff3bc0da5dc8fd7d80 (patch)
tree38b3e11bbd3505ddadacf3813dfd06cc8c2fd896 /compiler
parent2b01a24670d6e461f34de33bca68648baaafbbfd (diff)
downloadfpc-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.pas3
-rw-r--r--compiler/i8086/cgcpu.pas48
-rw-r--r--compiler/x86/agx86nsm.pas6
-rw-r--r--compiler/x86/cgx86.pas21
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