[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Controlling the FPU under Linux



   Date: Mon, 13 Oct 1997 16:28:12 +0200
   From: Thomas SCHIEX <tschiex@tlse.toulouse.inra.fr>

   I'd like to know if anybody has experience in finely controlling the FPU
   under Linux (I'm under Debian 1.3.1). I need to control the rounding mode of
   the FPU (rounding up or down instead of "to nearest").

Here is a program to set the FPU modes (assuming you are using an
Intel machine).

/*

Code to initialize the ix87 FP coprocessor control word.
This code must be run once before starting a computation.

Bit(s)	Description
------	-----------
0	invalid operation (FP stack overflow or IEEE invalid arithmetic op)
1	denormalized operand
2	zero divide
3	overflow
4	underflow
5	precision (indicates that precision was lost; happens frequently)

	The first 6 bits control how the chip responds to various
	exceptions.  If a given mask bit is 0, then that exception
	will generate a processor trap.  If the mask bit is 1, then
	that exception will not trap but is handled by a "default
	action", usually substituting an infinity or NaN.

	Default is all masks set to 1.

8/9	precision control

	00 IEEE single precision
	01 (reserved)
	10 IEEE double precision
	11 non-IEEE extended precision

	Default is non-IEEE extended precision.

10/11	rounding control

	00 round to nearest or even
	01 round toward negative infinity
	10 round toward positive infinity
	11 truncate toward zero

	Default is round to nearest or even.

This code (0x0220) sets these bits as follows:

1. Precision mask 1, all others 0.
2. Precision control: IEEE double precision.
3. Rounding control: round to nearest or even.

*/

#ifdef __GNUC__
#if #cpu (i386)

void
initialize_387_to_ieee (void)
{
  unsigned short control_word;
  asm ("fclex" : : );
  asm ("fnstcw %0" : "=m" (control_word) : );
  asm ("andw %2,%0" : "=m" (control_word) : "0" (control_word), "n" (0xf0e0));
  asm ("orw %2,%0" : "=m" (control_word) : "0" (control_word), "n" (0x0220));
  asm ("fldcw %0" : : "m" (control_word));
}

#endif /* #cpu (i386) */
#endif /* __GNUC__ */


--
TO UNSUBSCRIBE FROM THIS MAILING LIST: e-mail the word "unsubscribe" to
debian-user-request@lists.debian.org . 
Trouble?  e-mail to templin@bucknell.edu .


Reply to: