Floating-Point Exception Handling

Product Version(s): 4.00 4.01 4.10 | 4.10
Operating System:   MS-DOS         | OS/2
Flags: ENDUSER |  coprocessor 8087 80187 80287 80387
Last Modified: 30-SEP-1988    ArticleIdent: Q19807

Question:

How can I clear the status word? Can I set it to any value I want?
Page 359 of the "Microsoft FORTRAN User's Guide", Appendix D states
that the status word remains set until the user clears it.

Response:

The following is a routine named "clrstat", which will allow
you to clear the status word. Use this routine at your own
risk, i.e., we do not support this routine.

In both Versions 3.31 and 4.00, you cannot change the status word.
Once it is set to a value (perhaps by a divide-by-zero error), the
status remains at that value. Even by using assembly language, you
only are allowed to clear the status word; you cannot set it to a
specific value.

The math run time does not allow you to clear the status due to the
coupling of the invalid exception and NDP stack overflow conditions on
the chip; the same exception is raised for both conditions. The
clearing of the status word is prohibited because, due to the order in
which the evaluation is done, you can inadvertently clear an invalid
exception before the exception handler can access it.

The following is a short FORTRAN program that first generates a
divide-by-zero error, then does a valid calculation, followed by an
assembly-language subroutine that only clears the status word:

   integer*2 sswrqq
   call lcwrqq (4927)
   call val1 (x,y) 100 continue
   z = x/y
   irep = sswrqq()
   write (*,*) 'status=',irep
   if (irep .eq. 4) then
   write (*,*) 'divide by zero'
   call clrstat
   endif
   if (irep .eq. 0) stop
   call val2 (x,y)
   go to 100
   end
   subroutine val1 (x,y)
   x = 1.0
   y = 0.0
   end
   subroutine val2 (x,y)
   x = 5.0
   y = 2.0
   end

   TITLE clrstat

   .8087 CLRSTAT_TEXT SEGMENT BYTE PUBLIC 'CODE' CLRSTAT_TEXT ENDS
   ASSUME CS: CLRSTAT_TEXT EXTRN __acrtused:ABS CLRSTAT_TEXT SEGMENT
   PUBLIC CLRSTA CLRSTA PROC FAR
   push bp
   mov bp,sp
   fclex
   fwait
   pop bp
   ret CLRSTA ENDP CLRSTAT_TEXT ENDS END