phil@DECWRL.DEC.COM (Phil Hochstetler) (07/18/89)
Here is some more info on a bug reported previously:
Version of GNU CC: gcc version 1.35
Input file:
#include <stdio.h>
main()
{
double d;
unsigned bogus = 1;
d = ((double) bogus);
printf("hex = %x,%x\n", ((int *)&d)[1], ((int *)&d)[0]); fflush(stdout);
printf("%%e = %e\n", d); fflush(stdout);
exit(0);
}
Compiled via: gcc -g -o foo foo.c
tm.h and md file: md -> config/i386.md
tm.h -> config/tm-seq386.h
type of machine: Sequent SYMMETRY
OS name and version: DYNIX(R) V3.0.15
Bad behavior: Running compiled program gets a
floating point exception in printf.
Should print:
hex = 3ff00000,0
%e = 1.000000e+00
Instead, prints:
hex = 0,0
Floating exception (core dumped)
MORE INFO:
The compiler is generating bad code and is trying to pop the floating
point stack too many times causing a "invalid operation" floating
exception. The next floating point operation (in this case printf)
will detect the error and dump core. This delayed detection is because
of the async nature of the 386/387 interface.
Output of "gcc -g -S foo.c":
.file "foo.c"
gcc_compiled.:
.stabs "foo.c",100,0,0,Ltext
Ltext:
.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
.stabs "char:t2=r2;0;127;",128,0,0,0
.stabs "long int:t3=r1;-2147483648;2147483647;",128,0,0,0
.stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
.stabs "long unsigned int:t5=r1;0;-1;",128,0,0,0
.stabs "short int:t6=r1;-32768;32767;",128,0,0,0
.stabs "long long int:t7=r1;0;-1;",128,0,0,0
.stabs "short unsigned int:t8=r1;0;65535;",128,0,0,0
.stabs "long long unsigned int:t9=r1;0;-1;",128,0,0,0
.stabs "signed char:t10=r1;-128;127;",128,0,0,0
.stabs "unsigned char:t11=r1;0;255;",128,0,0,0
.stabs "float:t12=r1;4;0;",128,0,0,0
.stabs "double:t13=r1;8;0;",128,0,0,0
.stabs "long double:t14=r1;8;0;",128,0,0,0
.stabs "void:t15=15",128,0,0,0
.text
LC0:
.ascii "hex = %x,%x\12\0"
LC1:
.ascii "%%e = %e\12\0"
.align 2
LC2:
.double 0d4.29496729600000000000e+09
.align 2
.globl _main
_main:
.stabd 68,0,8
pushl %ebp
movl %esp,%ebp
subl $12,%esp
LBB2:
.stabd 68,0,10
movl $1,-12(%ebp)
.stabd 68,0,12
fildl -12(%ebp) # push 1.0 on float stack
ftst # test against 0.0
fstp %st(0) # pop stack (stack now empty)
# NOTE: deleting this line makes the code work.
fnstsw %ax # store status in %ax register
sahf # store %ax into eflags
jae L2 # jmp if above or equal
faddl LC2 # else adjust TOS (ERROR, TOS is empty!)
L2:
fstpl -8(%ebp) # store TOS to memory (ERROR, TOS is empty!)
.stabd 68,0,13
pushl -8(%ebp)
pushl -4(%ebp)
pushl $LC0
call _printf
movl $__iob,%eax
addl $20,%eax
pushl %eax
call _fflush
.stabd 68,0,14
pushl -4(%ebp)
pushl -8(%ebp)
pushl $LC1
call _printf
movl $__iob,%eax
addl $20,%eax
pushl %eax
call _fflush
.stabd 68,0,15
leal 32(%esp),%esp
pushl $0
call _exit
LBE2:
.stabd 68,0,16
L1:
leave
ret
.stabs "_iobuf:T16=s20_cnt:1,0,32;_ptr:17=*2,32,32;_base:17,64,32;_bufsiz:1,96,32;_flag:6,128,16;_file:2,144,8;;",128,0,0,0
.stabs "main:F1",36,0,0,_main
.stabs "d:13",128,0,0,-8
.stabs "bogus:4",128,0,0,-12
.stabn 192,0,0,LBB2
.stabn 224,0,0,LBE2