*BSD News Article 6293


Return to BSD News archive

Newsgroups: comp.unix.bsd
Path: sserve!manuel.anu.edu.au!munnari.oz.au!spool.mu.edu!umn.edu!math.fu-berlin.de!Sirius.dfn.de!tubsibr!ramz.ing.tu-bs.de!ruediger
From: ruediger@ramz.ing.tu-bs.de (Ruediger Helsch)
Subject: Rumors about floating point exceptions (80x87 FP stack)
Message-ID: <1992Oct9.165256.23145@ibr.cs.tu-bs.de>
Sender: postnntp@ibr.cs.tu-bs.de (nntp inews entry)
Organization: Mechanikzentrum, Technische Universitaet Braunschweig, Germany
Date: Fri, 9 Oct 1992 16:52:56 GMT
Lines: 49

This article is written to shed some light on the function of the 80x87
floating point processor (and the 80486) and to help explain the
occurrence of arbitrary floating point exceptions in code that works
fine on other processors. Summary: undeclared floating point functions,
even if the result is ignored, cause the 80x87 floating point stack to
overflow at possibly entirely unrelated places of the program.

Each few days somebody writes here about GCC optimization errors
resulting in floating point exceptions. Last time it was in the patch kit
at patch00036. As the reason was given: "The gist of this is that an
external double function that isn't declared has an implicit type of int.
Assigning a double variable the return value of this function causes a
floating point exception. Declaring the function fixes 'ps'".

Obviously this was a programming error in 'ps' and not an optimization
bug. The 80x86/80x87 is extremely sensitive against function
misdeclarations. An undeclared floating point function, EVEN IF THE
RESULT IS IGNORED, may cause a floating point exception at any
point much further in the program. These bugs are very difficult to
locate.

The reason is the following: the 80x87 contains eight floating point
registers organized as a FP stack. During floating point calculations
temporary values are pushed onto this stack and popped when they
are used. It is the responsibility of the compiler to make sure that not
more than eight values are pushed and that the stack is cleaned up
after the temporaries are no longer needed.
Floating point functions also push their result onto this stack before
they return. The caller can then pop the function result from the FP stack
when it is used, emptying the stack.

If a floating point function is not declared as such, the compiler has no
way to guess that the function has pushed a value onto the FP stack.
The value will not be popped but will remain there, reducing the free
space on the FP stack to seven registers. After four more calls to the
function the FP stack will be shrink to three registers. Then, at some
completely unrelated place in the program, where a complicated FP
expression is computed, the FP stack will overflow and cause the
floating point exception.

The best way to trace these bugs is to watch the floating point stack
using a debugger. I do not know if such a debugger is available for
386bsd, my experiences come from ISC Unix, where the debugger
allowed to watch the FP stack growth.

I hope this makes the problems clearer and helps people who observe
seemingly unexplicable floating point exceptions.

Ruediger Helsch <ruediger@ramz.ing.tu-bs.de>