Skip to contentSkip to conversation

set the precision of Intel's FPU.

Linux-ia64 David Mosberger 2 participants 3 messages Dec 3, 2002

lore
Share & tools
lore
#0 lore raw
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line · John Kern

John> The Intel processors (i.e., x86 and ia64) have 80-bit John> (extended) floating point registers. By default, floating John> point computations are done with extended precision on Intel.

On ia64, it _should_ default to regular precision for values of type "double". The initial value of the floating-point control register (ar.fpsr) is defined by the Itanium Software Conventions and Runtime Architecture manual
(http://www.intel.com/design/itanium/downloads/245358.htm) in Table 13-1. As you can see there, only sf1 has the "Widest-range Exponent" flag set and this status field is only used for special runtime routines (e.g., integer division).

For example gcc translates:

double add (double x, double y) { return x + y; }

into:

6: 80 48 20 02 48 80 fadd.d.s0 f8ø,f9

which will use "IEEE real double" precision (since the sf0.wre bit is cleared to zero by default).

John> I want to obtain bitwise identical results across platforms. John> Extended precision simply requires at least 15 addition John> bits. So, it various between platforms. For example, Solaris John> and HP use 128-bit extended precision. The IEEE spec says John> there must be a way to control precision. Setting the John> precision to double, fixes the problem.

What floating-point type are you using here? long double?

John> On 32-bit Linux I can achieve this by #include <fpu_control.h>

John> fpu_control_t oldcw, newcw;

  John>   _FPU_GETCW(oldcw); newcw = (oldcw & ~_FPU_EXTENDED) |
  John> _FPU_DOUBLE; _FPU_SETCW(newcw);

John> Unfortunately, this doesn't work with Linux/IA-64. I haven't John> been able to find a reference on this topic. Can someone shed John> some light on this?

This interface is x86-specific. AFAIK, the proper interface to use here is the one defined by <fenv.h>. Specifically, the fesetenv() routine can manipulate any bit in ar.fpsr.

	--david
#1 lore raw

Hola,

Thanks. That's exactly what I needed to know. My mistake was I assumed IA-64 had the same problems as the x86 processor.

Just thought I'd leave a few sentences of background info which may be helpful to others with a similar concern.

From a language prespective, I'd like to the data type to map to the appropriate ieee precision.

data type ieee precision
float single(32-bit)
double double (64-bit)
long double extended

Many platforms(Solaris, HP-UX, and Linux/IA-64) use float and double this way. Since I don't use extended, I can't comment on the portability of it.

Unfortunately(for those who want consistent cross platform results), x86 implements float with extended (80-bit) precision registers. So, the mapping effectively looks like:

data type ieee precision
float extended
double extended
long double extended

Quoted 3 lines

This interface is x86-specific. AFAIK, the proper interface to use here is the one defined by <fenv.h>. Specifically, the fesetenv() routine can manipulate any bit in ar.fpsr.

fenv.h implements the C99 standard for both rounding and exceptions, but it doesn't control precision. So, the x86 code can't be replace with this (although I'd love to replace it with a standard call) and I now understand it isn't needed on IA-64.

Thanks again.

Sincerely,

John

-----Original Message-----
From: David Mosberger [mailto:[email protected]]
Sent: Tuesday, December 03, 2002 12:01 PM
To: [email protected]
Cc: [email protected]
Subject: Re: set the precision of Intel's FPU.

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

On Tue, 3 Dec 2002 11:10:07 -0800, John Kern <[email protected]>

said:

John> The Intel processors (i.e., x86 and ia64) have 80-bit John> (extended) floating point registers. By default, floating John> point computations are done with extended precision on Intel.

On ia64, it _should_ default to regular precision for values of type "double". The initial value of the floating-point control register (ar.fpsr) is defined by the Itanium Software Conventions and Runtime Architecture manual
(http://www.intel.com/design/itanium/downloads/245358.htm) in Table 13-1. As you can see there, only sf1 has the "Widest-range Exponent" flag set and this status field is only used for special runtime routines (e.g., integer division).

For example gcc translates:

double add (double x, double y) { return x + y; }

into:

6: 80 48 20 02 48 80 fadd.d.s0 f8ø,f9

which will use "IEEE real double" precision (since the sf0.wre bit is cleared to zero by default).

John> I want to obtain bitwise identical results across platforms. John> Extended precision simply requires at least 15 addition John> bits. So, it various between platforms. For example, Solaris John> and HP use 128-bit extended precision. The IEEE spec says John> there must be a way to control precision. Setting the John> precision to double, fixes the problem.

What floating-point type are you using here? long double?

John> On 32-bit Linux I can achieve this by #include <fpu_control.h>

John> fpu_control_t oldcw, newcw;

  John>   _FPU_GETCW(oldcw); newcw = (oldcw & ~_FPU_EXTENDED) |
  John> _FPU_DOUBLE; _FPU_SETCW(newcw);

John> Unfortunately, this doesn't work with Linux/IA-64. I haven't John> been able to find a reference on this topic. Can someone shed John> some light on this?

This interface is x86-specific. AFAIK, the proper interface to use here is the one defined by <fenv.h>. Specifically, the fesetenv() routine can manipulate any bit in ar.fpsr.

	--david

_______________________________________________
ia64-list mailing list
[email protected]
https://listman.redhat.com/mailman/listinfo/ia64-list

#2 lore raw
In reply to David Mosberger

Hi John,

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line · John Kern

John> fenv.h implements the C99 standard for both rounding and John> exceptions, but it doesn't control precision. So, the x86 John> code can't be replace with this (although I'd love to replace John> it with a standard call) and I now understand it isn't needed John> on IA-64.

Yes, given your background info, there should be no need to call fesetenv() on ia64 linux.

Thanks,

	--david