[gnu.gcc.bug] More info on previous gcc bug report

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