diff --git a/rtl/go32v2/dpmiexcp.pp b/rtl/go32v2/dpmiexcp.pp index 8b5484082d..785e3510f1 100644 --- a/rtl/go32v2/dpmiexcp.pp +++ b/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 diff --git a/rtl/go32v2/exceptn.as b/rtl/go32v2/exceptn.as index ebf60180fe..8ec770222b 100644 --- a/rtl/go32v2/exceptn.as +++ b/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 */ \ No newline at end of file