Pārlūkot izejas kodu

+ emit proper interrupt procedure entry/exit code on i8086

git-svn-id: trunk@24728 -
nickysn 12 gadi atpakaļ
vecāks
revīzija
c2e3fb5918
4 mainītis faili ar 40 papildinājumiem un 38 dzēšanām
  1. 3 0
      compiler/cgbase.pas
  2. 10 38
      compiler/i8086/cgcpu.pas
  3. 6 0
      compiler/x86/agx86nsm.pas
  4. 21 0
      compiler/x86/cgx86.pas

+ 3 - 0
compiler/cgbase.pas

@@ -97,6 +97,9 @@ interface
          ,addr_lo8
          ,addr_hi8
          {$ENDIF}
+         {$IFDEF i8086}
+         ,addr_dgroup      // the data segment group
+         {$ENDIF}
          );
 
 

+ 10 - 38
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 }

+ 6 - 0
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}

+ 21 - 0
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