builtins and fwait

David Wohlferd dw@LimeGreenSocks.com
Wed Dec 2 06:36:00 GMT 2015


As part of my review of inline asm in gcc, I came across this code (from 
libatomic/config/x86/fenv.c, among other places):

       asm volatile ("fnstenv\t%0" : "=m" (temp));
       temp.__status_word |= FE_DENORM;
       asm volatile ("fldenv\t%0" : : "m" (temp));
       asm("fwait");

I was wondering if this could be replaced by using builtins rather than 
inline asm.  Poking around, I found both __builtin_ia32_fnstenv and 
__builtin_ia32_fldenv.  But I found no __builtin_ia32_fwait (nor 
anything similar).

I briefly considered whether __builtin_ia32_fldenv implies (or should 
imply) an fwait, but it doesn't look like it does one.  And it seems 
plausible (to a floating point neophyte like me) that you could want to 
use fldenv, but know that you won't cause an exception, so don't want to 
waste cycles on the fwait.

So without __builtin_ia32_fwait, this is as close as I can get.  Can 
someone get me closer?

#define FE_DENORM    0x02

struct fenv
{
   unsigned short int __control_word;
   unsigned short int __unused1;
   unsigned short int __status_word;
   unsigned short int __unused2;
   unsigned short int __tags;
   unsigned short int __unused3;
   unsigned int __eip;
   unsigned short int __cs_selector;
   unsigned int __opcode:11;
   unsigned int __unused4:5;
   unsigned int __data_offset;
   unsigned short int __data_selector;
   unsigned short int __unused5;
};

int main()
{
    struct fenv temp;

    __builtin_ia32_fnstenv(&temp);
    temp.__status_word |= FE_DENORM;
    __builtin_ia32_fldenv(&temp);
    asm("fwait" :::);
}

dw

PS Should the fwait include "cc"?  fwait changes flags, just not the eflags.



More information about the Gcc-help mailing list