Matthew Woehlke wrote: > Andrew Haley wrote: >> Matthew Woehlke wrote: >>> Using gcc-4.3.2-7.x86_64 (Fedora 10). >>> >>> I have these functions: >>> >>> void my_ntoh_float(float *f) >>> { >>> int p = (int*)f; >>> *p = ntohl(*p); >>> } >>> [snip snip] >>> >>> Is the bug in the code, or in gcc? In either case, is there a way >>> (besides dropping optimizations) to fix this that doesn't involve >>> non-portable code? >> >> It's in your code. You're accessing an object (p) as an incompatible >> type. >> See C99, Section 6.3.2.3 for all the details. > > That's what I suspected. > >> Do this: >> >> float my_ntoh_float(float f) >> { > > That should be 'float * f'. > >> union >> { >> int i; >> float f; >> } u; > > D'oh, should have thought of that. Brain must not be working :-). > > Anyway, I saw Brian's reply first, and already got it working with a > variant of this (i.e. not changing the signature of my_ntoh_float, which > I can't do for compatibility reasons!!). Thanks both for the quick replies! > >> Which generates this: >> >> my_get_float: >> pushl %ebp >> movl %esp, %ebp >> subl $4, %esp >> movl 8(%ebp), %eax >> movl (%eax), %eax >> bswap %eax >> movl %eax, -4(%ebp) >> flds -4(%ebp) >> leave >> ret > > Hmm, I still get this: > > ror $0x8,%ax > ror $0x10,%eax > ror $0x8,%ax > > ...which is interesting. Are you building 32-bit code? Looks like I > maybe need to see if there is a -march that we aren't using that might > help our performance (not just here, but in general). > > (I do get bswap with 64-bit code.) It's this macro in byteswap.h: # if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__ \ || defined __pentiumpro__ || defined __pentium4__ \ || defined __k8__ || defined __athlon__ \ || defined __k6__ || defined __nocona__ \ || defined __core2__ || defined __geode__ \ || defined __amdfam10__) /* To swap the bytes in a word the i486 processors and up provide the `bswap' opcode. On i386 we have to use three instructions. */ # define __bswap_32(x) \ (__extension__ \ ({ register unsigned int __v, __x = (x); \ if (__builtin_constant_p (__x)) \ __v = __bswap_constant_32 (__x); \ else \ __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \ __v; })) # else # define __bswap_32(x) \ (__extension__ \ ({ register unsigned int __v, __x = (x); \ if (__builtin_constant_p (__x)) \ __v = __bswap_constant_32 (__x); \ else \ __asm__ ("rorw $8, %w0;" \ "rorl $16, %0;" \ "rorw $8, %w0" \ : "=r" (__v) \ : "0" (__x) \ : "cc"); \ __v; })) # endif Andrew.