this C code line {(((Cyg_libm_ieee_double_shape_type *)&x)->parts.msw) = (hx&0x800fffff)|(k<<20); return x;} causes this assembler code to be generated:
bic r3, ip, #2130706432 bic r3, r3, #15728640 ldmia sp, {r0-r1} orr r3, r3, r2, asl #20 str r3, [r5, #0] b .L6 The ldmia instruction loads the value to be returned from memory before the calculation is finished and the result is stored there. Rearranging the instructions by hand in the resulting binary makes the program work. gcc output: Using built-in specs. Target: arm-elf Configured with: /usr/local/src/gcc-4.2.0/configure --target=arm-elf --prefix=/usr/local --with-gnu-as --with-gnu-ld --disable-hosted-libstdcxx --disable-__cxa_atexit --enable-languages=c,c++ Thread model: single gcc version 4.2.0 /usr/local/libexec/gcc/arm-elf/4.2.0/cc1 -E -quiet -v -I/tmp/ecos/whz2292_install/include -I/usr/local/share/ecos/packages/language/c/libm/current -I/usr/local/share/ecos/packages/language/c/libm/current/src -I/usr/local/share/ecos/packages/language/c/libm/current/tests -I. -I/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/ -D__USES_INITFINI__ -MD src/double/portable-api/s_scalbn.tmp /usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/s_scalbn.c -mcpu=arm7tdmi -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -finline-limit=7000 -ffunction-sections -fdata-sections -fno-exceptions -fworking-directory -O2 -fpch-preprocess -o s_scalbn.i ignoring nonexistent directory "/usr/local/lib/gcc/arm-elf/4.2.0/../../../../arm-elf/sys-include" #include "..." search starts here: #include <...> search starts here: /tmp/ecos/whz2292_install/include /usr/local/share/ecos/packages/language/c/libm/current /usr/local/share/ecos/packages/language/c/libm/current/src /usr/local/share/ecos/packages/language/c/libm/current/tests . /usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/ /usr/local/lib/gcc/arm-elf/4.2.0/include /usr/local/lib/gcc/arm-elf/4.2.0/../../../../arm-elf/include End of search list. /usr/local/libexec/gcc/arm-elf/4.2.0/cc1 -fpreprocessed s_scalbn.i -quiet -dumpbase s_scalbn.c -mcpu=arm7tdmi -auxbase-strip src/double/portable-api/language_c_libm_s_scalbn.o -g -O2 -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -version -finline-limit=7000 -ffunction-sections -fdata-sections -fno-exceptions -o s_scalbn.s GNU C version 4.2.0 (arm-elf) compiled by GNU C version 4.1.2 20061021 prerelease (NetBSD nb3 20061125). GGC heuristics: --param ggc-min-expand=64 --param ggc-min-heapsize=65415 Compiler executable checksum: f21aa8a15d6feeb6af69912bd33e6003 /usr/local/lib/gcc/arm-elf/4.2.0/../../../../arm-elf/bin/as -mcpu=arm7tdmi -o src/double/portable-api/language_c_libm_s_scalbn.o s_scalbn.s source file: # 1 "/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/s_scalbn.c" # 1 "/tmp/ecos/whz2292_build/language/c/libm/current//" # 1 "<built-in>" # 1 "<command-line>" # 1 "/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/s_scalbn.c" # 56 "/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/s_scalbn.c" # 1 "/tmp/ecos/whz2292_install/include/pkgconf/libm.h" 1 # 12 "/tmp/ecos/whz2292_install/include/pkgconf/libm.h" # 1 "/tmp/ecos/whz2292_install/include/pkgconf/system.h" 1 # 13 "/tmp/ecos/whz2292_install/include/pkgconf/libm.h" 2 typedef enum { CYGNUM_LIBM_COMPAT_UNINIT= 0, CYGNUM_LIBM_COMPAT_POSIX = 1, CYGNUM_LIBM_COMPAT_IEEE = 2, CYGNUM_LIBM_COMPAT_XOPEN = 3, CYGNUM_LIBM_COMPAT_SVID = 4 } Cyg_libm_compat_t; # 57 "/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/s_scalbn.c" 2 # 83 "/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/s_scalbn.c" # 1 "/usr/local/share/ecos/packages/language/c/libm/current/src/mathincl/fdlibm.h" 1 # 66 "/usr/local/share/ecos/packages/language/c/libm/current/src/mathincl/fdlibm.h" # 1 "/tmp/ecos/whz2292_install/include/cyg/infra/cyg_type.h" 1 # 58 "/tmp/ecos/whz2292_install/include/cyg/infra/cyg_type.h" # 1 "/tmp/ecos/whz2292_install/include/stddef.h" 1 # 64 "/tmp/ecos/whz2292_install/include/stddef.h" # 1 "/usr/local/lib/gcc/arm-elf/4.2.0/include/stddef.h" 1 3 4 # 152 "/usr/local/lib/gcc/arm-elf/4.2.0/include/stddef.h" 3 4 typedef long int ptrdiff_t; # 214 "/usr/local/lib/gcc/arm-elf/4.2.0/include/stddef.h" 3 4 typedef long unsigned int size_t; # 326 "/usr/local/lib/gcc/arm-elf/4.2.0/include/stddef.h" 3 4 typedef int wchar_t; # 65 "/tmp/ecos/whz2292_install/include/stddef.h" 2 # 59 "/tmp/ecos/whz2292_install/include/cyg/infra/cyg_type.h" 2 # 83 "/tmp/ecos/whz2292_install/include/cyg/infra/cyg_type.h" # 1 "/tmp/ecos/whz2292_install/include/cyg/hal/basetype.h" 1 # 84 "/tmp/ecos/whz2292_install/include/cyg/infra/cyg_type.h" 2 # 160 "/tmp/ecos/whz2292_install/include/cyg/infra/cyg_type.h" typedef int bool; # 202 "/tmp/ecos/whz2292_install/include/cyg/infra/cyg_type.h" typedef unsigned char cyg_uint8 ; typedef signed char cyg_int8 ; typedef unsigned short cyg_uint16 ; typedef signed short cyg_int16 ; typedef unsigned int cyg_uint32 ; typedef signed int cyg_int32 ; typedef unsigned long long cyg_uint64 ; typedef signed long long cyg_int64 ; typedef int cyg_bool ; typedef unsigned int cyg_ucount8 ; typedef signed int cyg_count8 ; typedef unsigned int cyg_ucount16 ; typedef signed int cyg_count16 ; typedef unsigned int cyg_ucount32 ; typedef signed int cyg_count32 ; typedef unsigned long long cyg_ucount64 ; typedef signed long long cyg_count64 ; typedef volatile unsigned char cyg_atomic; typedef volatile unsigned char CYG_ATOMIC; typedef cyg_uint32 CYG_WORD; typedef cyg_uint8 CYG_BYTE; typedef cyg_uint16 CYG_WORD16; typedef cyg_uint32 CYG_WORD32; typedef cyg_uint64 CYG_WORD64; typedef cyg_uint32 CYG_ADDRESS; typedef cyg_uint32 CYG_ADDRWORD; # 67 "/usr/local/share/ecos/packages/language/c/libm/current/src/mathincl/fdlibm.h" 2 # 1 "/tmp/ecos/whz2292_install/include/math.h" 1 # 69 "/tmp/ecos/whz2292_install/include/math.h" # 1 "/tmp/ecos/whz2292_install/include/float.h" 1 # 65 "/tmp/ecos/whz2292_install/include/float.h" # 1 "/usr/local/lib/gcc/arm-elf/4.2.0/include/float.h" 1 3 4 # 66 "/tmp/ecos/whz2292_install/include/float.h" 2 # 70 "/tmp/ecos/whz2292_install/include/math.h" 2 # 1 "/tmp/ecos/whz2292_install/include/sys/ieeefp.h" 1 # 141 "/tmp/ecos/whz2292_install/include/sys/ieeefp.h" typedef union { cyg_int32 asi32[2]; cyg_int64 asi64; double value; struct { unsigned int fraction1:16; unsigned int fraction0: 4; unsigned int exponent :11; unsigned int sign : 1; unsigned int fraction3:16; unsigned int fraction2:16; # 166 "/tmp/ecos/whz2292_install/include/sys/ieeefp.h" } number; struct { unsigned int function1:16; unsigned int function0:3; unsigned int quiet:1; unsigned int exponent: 11; unsigned int sign : 1; unsigned int function3:16; unsigned int function2:16; # 187 "/tmp/ecos/whz2292_install/include/sys/ieeefp.h" } nan; struct { cyg_uint32 msw; cyg_uint32 lsw; } parts; } Cyg_libm_ieee_double_shape_type; typedef union { cyg_int32 asi32; float value; struct { unsigned int fraction0: 7; unsigned int fraction1: 16; unsigned int exponent: 8; unsigned int sign : 1; } number; struct { unsigned int function1:16; unsigned int function0:6; unsigned int quiet:1; unsigned int exponent:8; unsigned int sign:1; } nan; } Cyg_libm_ieee_float_shape_type; # 72 "/tmp/ecos/whz2292_install/include/math.h" 2 # 102 "/tmp/ecos/whz2292_install/include/math.h" struct exception { int type; char *name; double arg1; double arg2; double retval; }; extern const Cyg_libm_ieee_double_shape_type cyg_libm_infinity; # 135 "/tmp/ecos/whz2292_install/include/math.h" extern Cyg_libm_compat_t cygvar_libm_compat_mode; static inline Cyg_libm_compat_t cyg_libm_get_compat_mode( void ) { return cygvar_libm_compat_mode; } static inline Cyg_libm_compat_t cyg_libm_set_compat_mode( Cyg_libm_compat_t math_compat_mode) { Cyg_libm_compat_t oldmode; oldmode = cygvar_libm_compat_mode; cygvar_libm_compat_mode = math_compat_mode; return oldmode; } # 173 "/tmp/ecos/whz2292_install/include/math.h" extern int signgam; # 182 "/tmp/ecos/whz2292_install/include/math.h" extern double acos( double ); extern double asin( double ); extern double atan( double ); extern double atan2( double, double ); extern double cos( double ); extern double sin( double ); extern double tan( double ); extern double cosh( double ); extern double sinh( double ); extern double tanh( double ); extern double exp( double ); extern double frexp( double, int * ); extern double ldexp( double, int ); extern double log( double ); extern double log10( double ); extern double modf( double, double * ); extern double pow( double, double ); extern double sqrt( double ); extern double ceil( double ); extern double fabs( double ); extern double floor( double ); extern double fmod( double, double ); extern int matherr( struct exception * ); extern double acosh( double ); extern double asinh( double ); extern double atanh( double ); extern double erf( double ); extern double erfc( double ); extern double lgamma( double ); extern double lgamma_r( double, int * ); extern double gamma( double ); # 312 "/tmp/ecos/whz2292_install/include/math.h" extern double gamma_r( double, int * ); extern double j0( double ); extern double j1( double ); extern double jn( int, double ); extern double y0( double ); extern double y1( double ); extern double yn( int, double ); extern double scalbn( double, int ); extern double scalb( double, double ); # 358 "/tmp/ecos/whz2292_install/include/math.h" extern double cbrt( double ); extern double hypot( double, double ); extern int isnan( double ); extern int finite( double ); extern double logb( double ); extern int ilogb( double ); extern double nextafter( double, double ); extern double remainder( double, double ); extern double significand( double ); extern double copysign ( double, double ); extern double rint( double ); extern double expm1( double ); extern double log1p( double ); # 68 "/usr/local/share/ecos/packages/language/c/libm/current/src/mathincl/fdlibm.h" 2 # 1 "/tmp/ecos/whz2292_install/include/float.h" 1 # 69 "/usr/local/share/ecos/packages/language/c/libm/current/src/mathincl/fdlibm.h" 2 # 85 "/usr/local/share/ecos/packages/language/c/libm/current/src/mathincl/fdlibm.h" typedef cyg_int32 __int32_t; typedef cyg_uint32 __uint32_t; typedef Cyg_libm_ieee_double_shape_type ieee_double_shape_type; # 190 "/usr/local/share/ecos/packages/language/c/libm/current/src/mathincl/fdlibm.h" extern double __ieee754_sqrt( double ); extern double __ieee754_acos( double ); extern double __ieee754_acosh( double ); extern double __ieee754_log( double ); extern double __ieee754_atanh( double ); extern double __ieee754_asin( double ); extern double __ieee754_atan2( double, double ); extern double __ieee754_exp( double ); extern double __ieee754_cosh( double ); extern double __ieee754_fmod( double, double ); extern double __ieee754_pow( double, double ); extern double __ieee754_lgamma_r( double, int * ); extern double __ieee754_gamma_r( double, int * ); extern double __ieee754_lgamma( double ); extern double __ieee754_gamma( double ); extern double __ieee754_log10( double ); extern double __ieee754_sinh( double ); extern double __ieee754_hypot( double, double ); extern double __ieee754_j0( double ); extern double __ieee754_j1( double ); extern double __ieee754_y0( double ); extern double __ieee754_y1( double ); extern double __ieee754_jn( int, double ); extern double __ieee754_yn( int, double ); extern double __ieee754_remainder( double, double ); extern int __ieee754_rem_pio2( double, double * ); extern double __ieee754_scalb( double, double ); extern double __kernel_standard( double, double, int ); extern double __kernel_sin( double, double, int ); extern double __kernel_cos( double, double ); extern double __kernel_tan( double, double, int ); extern int __kernel_rem_pio2( double *, double *, int, int, int, const int * ); # 84 "/usr/local/share/ecos/packages/language/c/libm/current/src/double/portable-api/s_scalbn.c" 2 static const double two54 = 1.80143985094819840000e+16, twom54 = 5.55111512312578270212e-17, huge = 1.0e+300, tiny = 1.0e-300; double scalbn (double x, int n) { int k,hx,lx; hx = (((Cyg_libm_ieee_double_shape_type *)&x)->parts.msw); lx = (((Cyg_libm_ieee_double_shape_type *)&x)->parts.lsw); k = (hx&0x7ff00000)>>20; if (k==0) { if ((lx|(hx&0x7fffffff))==0) return x; x *= two54; hx = (((Cyg_libm_ieee_double_shape_type *)&x)->parts.msw); k = ((hx&0x7ff00000)>>20) - 54; if (n< -50000) return tiny*x; } if (k==0x7ff) return x+x; k = k+n; if (k > 0x7fe) return huge*copysign(huge,x); if (k > 0) {(((Cyg_libm_ieee_double_shape_type *)&x)->parts.msw) = (hx&0x800fffff)|(k<<20); return x;} if (k <= -54) { if (n > 50000) return huge*copysign(huge,x); else return tiny*copysign(tiny,x); } k += 54; (((Cyg_libm_ieee_double_shape_type *)&x)->parts.msw) = (hx&0x800fffff)|(k<<20); return x*twom54; } -- Summary: wrong instruction order generated Product: gcc Version: 4.2.0 Status: UNCONFIRMED Severity: major Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: rosenfeld at grumpf dot hope-2000 dot org GCC build triplet: i386-unknown-netbsdelf4.0. GCC host triplet: i386-unknown-netbsdelf4.0. GCC target triplet: arm-elf http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32397