Browse Source

* changed handling of interrupt 0x75 :
the status word is saved into ___djgpp_fpu_state
and inserted in __sigmaks field of djgpp exception record
BUT fnclex is called after to avoid a second interrupt
generation on fn??? calls

pierre 25 years ago
parent
commit
f6da28673a
2 changed files with 36 additions and 8 deletions
  1. 26 6
      rtl/go32v2/dpmiexcp.pp
  2. 10 2
      rtl/go32v2/exceptn.as

+ 26 - 6
rtl/go32v2/dpmiexcp.pp

@@ -1367,13 +1367,15 @@ const
   FPU_Underflow = $10;
   FPU_StackUnderflow = $20;
   FPU_StackOverflow = $40;
+  FPU_ExceptionMask = $ff;
+  FPU_ControlWord : word = $1332;
 
 
 function HandleException(sig : longint) : longint;
 var
   truesig : longint;
   ErrorOfSig : longint;
-  FpuStatus : word;
+  FpuStatus,FPUControl : word;
   eip,ebp : longint;
 begin
   if assigned(djgpp_exception_state_ptr) then
@@ -1392,10 +1394,15 @@ begin
    16,SIGFPE,$75 : begin
          { This needs special handling }
          { to discriminate between 205,206 and 207 }
-         asm
-           fnstsw %ax
-           movw   %ax,fpustatus
-         end;
+
+         if truesig=$75 then
+           fpustatus:=djgpp_exception_state_ptr^.__sigmask and $ffff
+         else
+           asm
+             fnstsw %ax
+             fnclex
+             movw   %ax,fpustatus
+           end;
          if (FpuStatus and FPU_Invalid)<>0 then
            ErrorOfSig:=216
          else if (FpuStatus and FPU_Denormal)<>0 then
@@ -1408,6 +1415,12 @@ begin
            ErrorOfSig:=206
          else
            ErrorOfSig:=207;  {'Coprocessor Error'}
+         { if exceptions then Reset FPU and reload control word }
+         if (FPUStatus and FPU_ExceptionMask)<>0 then
+           asm
+             fninit
+             fldcw FPU_ControlWord
+           end;
         end;
    4 : ErrorOfSig:=215;    {'Overflow'}
    1,                      {'Debug'}
@@ -1453,7 +1466,14 @@ end;
 {$endif IN_SYSTEM}
 {
   $Log$
-  Revision 1.15  2000-03-30 13:40:57  pierre
+  Revision 1.16  2000-03-31 23:19:12  pierre
+    * changed handling of interrupt 0x75 :
+      the status word is saved into ___djgpp_fpu_state
+      and inserted in __sigmaks field of djgpp exception record
+      BUT fnclex is called after to avoid a second interrupt
+      generation on fn??? calls
+
+  Revision 1.15  2000/03/30 13:40:57  pierre
    * fix FPU and multiple exception problems
 
   Revision 1.14  2000/03/13 19:45:21  pierre

+ 10 - 2
rtl/go32v2/exceptn.as

@@ -85,7 +85,11 @@ exception_handler:
 	call	limitFix
    	.byte	0x2e				/* CS: */
 	movzbl	forced,%ebx
-	movl	%ebx,8(%esp)			/* replace EXCEPNO */
+        movl    %ebx,8(%esp)                    /* replace EXCEPNO */
+        cmpb    $0x75, %bl
+        jne     not_forced
+        movzwl    ___djgpp_fpu_state,%ebx
+        movl    %ebx,20(%esp)                   /* set ERRCODE to FPU state */
 not_forced:
 	movw	%cs:___djgpp_our_DS, %ds
 	movl	$0x10000, forced		/* its zero now, flag inuse */
@@ -292,9 +296,13 @@ exception_state:		.space	64
 	.global	___djgpp_ds_alias
 ___djgpp_ds_alias:		.word	0	/* used in dpmi/api/d0303.s (alloc rmcb) */
 
+        .global ___djgpp_fpu_state
+___djgpp_fpu_state:             .word   0
 	.balign 16,,7
 	.global	___djgpp_npx_hdlr
 ___djgpp_npx_hdlr:
+        fnstsw  ___djgpp_fpu_state
+        fnclex
 	pushl	%eax
 	xorl	%eax,%eax
 	outb	%al,$0x0f0
@@ -472,4 +480,4 @@ already_forced:
 
 	.global ___djgpp_hw_lock_end
 ___djgpp_hw_lock_end:
-        ret                                     /* LD does weird things */
+        ret                                     /* LD does weird things */