another bug
Ulrich Drepper
drepper@gnu.org
Sat Dec 13 22:36:00 GMT 1997
Hi,
I think I found another bug which was introduced in egcs by the gcc
2.8 merge. So this might also effect gcc 2.8. I sincerely hope that
none of my modifications to my local gcc repository caused this
problem.
I appended a preprocessed file which you must compile on ix86 using
gcc e_hypotf.i -c -O3 -g -momit-leaf-frame-pointer -fPIC
The problematic code is right at the start
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0: 83 ec 04 subl $0x4,%esp
3: 56 pushl %esi
4: 53 pushl %ebx
5: e8 00 00 00 00 call a <__ieee754_hypotf+0xa>
a: 5b popl %ebx
b: 81 c3 03 00 00 addl $0x3,%ebx
10: 00
float a,b,t1,t2,y1,y2,w;
int32_t j,k,ha,hb;
do { ieee_float_shape_type gf_u; gf_u.value = ( x ); ( ha ) =
gf_u.word; } while (0) ;
ha &= 0x7fffffff;
11: 8b 4c 24 0c movl 0xc(%esp,1),%ecx
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The load in the last line loads the word at offset 12 but the stack
layout is like this:
+--------------+
| param #2 |
+--------------+
| param #1 |
+--------------+
| return addr | <---- %esp + 12
+--------------+
| <not init.> | <---------------------- created by the subl $4
+--------------+
| old %esi |
+--------------+
| old %ebx | <---- %esp
+--------------+
By some optimization the subl $4 moved before the prologue and this
kills all the parameter loading.
-- Uli
---------------. drepper at gnu.org ,-. Rubensstrasse 5
Ulrich Drepper \ ,-------------------' \ 76149 Karlsruhe/Germany
Cygnus Solutions `--' drepper at cygnus.com `------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
extern __inline float __ieee754_sqrtf ( float ); extern __inline float __ieee754_sqrtf ( float __x) { register float __result; __asm __volatile__ ( "fsqrt" : "=t" (__result) : "0" (__x) ); return __result; }
typedef int int32_t __attribute__ ((__mode__ ( __SI__ ))) ;
typedef unsigned int u_int32_t __attribute__ ((__mode__ ( __SI__ ))) ;
typedef union
{
float value;
u_int32_t word;
} ieee_float_shape_type;
float __ieee754_hypotf(float x, float y)
{
float a,b,t1,t2,y1,y2,w;
int32_t j,k,ha,hb;
do { ieee_float_shape_type gf_u; gf_u.value = ( x ); ( ha ) = gf_u.word; } while (0) ;
ha &= 0x7fffffff;
do { ieee_float_shape_type gf_u; gf_u.value = ( y ); ( hb ) = gf_u.word; } while (0) ;
hb &= 0x7fffffff;
if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
do { ieee_float_shape_type sf_u; sf_u.word = ( ha ); ( a ) = sf_u.value; } while (0) ;
do { ieee_float_shape_type sf_u; sf_u.word = ( hb ); ( b ) = sf_u.value; } while (0) ;
if((ha-hb)>0xf000000) {return a+b;}
k=0;
if(ha > 0x58800000) {
if(ha >= 0x7f800000) {
w = a+b;
if(ha == 0x7f800000) w = a;
if(hb == 0x7f800000) w = b;
return w;
}
ha -= 0x5d800000; hb -= 0x5d800000; k += 60;
do { ieee_float_shape_type sf_u; sf_u.word = ( ha ); ( a ) = sf_u.value; } while (0) ;
do { ieee_float_shape_type sf_u; sf_u.word = ( hb ); ( b ) = sf_u.value; } while (0) ;
}
if(hb < 0x26800000) {
if(hb <= 0x007fffff) {
if(hb==0) return a;
do { ieee_float_shape_type sf_u; sf_u.word = ( 0x3f000000 ); ( t1 ) = sf_u.value; } while (0) ;
b *= t1;
a *= t1;
k -= 126;
} else {
ha += 0x5d800000;
hb += 0x5d800000;
k -= 60;
do { ieee_float_shape_type sf_u; sf_u.word = ( ha ); ( a ) = sf_u.value; } while (0) ;
do { ieee_float_shape_type sf_u; sf_u.word = ( hb ); ( b ) = sf_u.value; } while (0) ;
}
}
w = a-b;
if (w>b) {
do { ieee_float_shape_type sf_u; sf_u.word = ( ha&0xfffff000 ); ( t1 ) = sf_u.value; } while (0) ;
t2 = a-t1;
w = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1)));
} else {
a = a+a;
do { ieee_float_shape_type sf_u; sf_u.word = ( hb&0xfffff000 ); ( y1 ) = sf_u.value; } while (0) ;
y2 = b - y1;
do { ieee_float_shape_type sf_u; sf_u.word = ( ha+0x00800000 ); ( t1 ) = sf_u.value; } while (0) ;
t2 = a - t1;
w = __ieee754_sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b)));
}
if(k!=0) {
do { ieee_float_shape_type sf_u; sf_u.word = ( 0x3f800000+(k<<23) ); ( t1 ) = sf_u.value; } while (0) ;
return t1*w;
} else return w;
}
More information about the Gcc
mailing list