[gnu.g++.bug] g++ 1.35.1-: A fix for Intel 386, and an unresolved bug

jw@sics.se (Johan Widen) (06/03/89)

g++ sometimes fails to pop arguments from the stack, on the 386. With the
following patch installed I am able to run all programs in libg++/tests
except:
	tRational, tRandom, tFix	they get a floating point exception
	tCurses runs but I have to terminate entered lines with ^J rather
	than ^M.
	No timing information is available, -1 is printed for all timing
	results.

The floating point exceptions are due to overflow on the i387 stack. This
is due to the instruction
	fstl
being output in some places where a
	fstpl
is required. Some of these bugs, but not all, disappear if -O is turned off.
It is thus possible to run tRandom to completion if libg++ is compiled without
-O. tRandom will still fail however.

My feeling is that this floating point problem is the last stumbling block
on the road to a working g++ on the 386 processor.


Now for the fix to the i386 stack pop bug. First a repeat by program:

struct s{int a; int b; int c;};

extern struct s h(int j);
extern int g(int, struct s, int);

f(int i, int j, int k)
{
  g(i, h(j), k);
}

Without the fix installed the following code is generated by g++:

	.file	"xx2.cc"
gcc_compiled.:
.text
	.align 2
.globl _f
_f:
	pushl %ebp
	movl %esp,%ebp
	subl $20,%esp
	movl 16(%ebp),%edx
	movl %edx,16(%esp)
	leal 4(%esp),%eax
	pushl 12(%ebp)
	pushl %eax
	call _h
	leal 4(%esp),%esp	<-- Bug, should be: leal 8(%esp),%esp
	movl 8(%ebp),%edx
	movl %edx,(%esp)
	call _g
	leal 20(%esp),%esp
L1:
	leave
	ret

Here is the fix:

*** expr.c.orig	Wed May 17 08:45:29 1989
--- expr.c	Thu Jun  1 23:00:16 1989
***************
*** 4122,4128
        INIT_CUMULATIVE_ARGS (args_so_far, funtype);
        tem = FUNCTION_ARG (args_so_far, Pmode,
  			  build_pointer_type (TREE_TYPE (funtype)), 1);
!       if (tem != 0 && GET_CODE (tem) == MEM)
  	{
  	  actparms = tree_cons (error_mark_node,
  				build (SAVE_EXPR,

--- 4122,4128 -----
        INIT_CUMULATIVE_ARGS (args_so_far, funtype);
        tem = FUNCTION_ARG (args_so_far, Pmode,
  			  build_pointer_type (TREE_TYPE (funtype)), 1);
!       if (tem == 0)
  	{
  	  actparms = tree_cons (error_mark_node,
  				build (SAVE_EXPR,
--
Johan Widen
SICS, PO Box 1263, S-164 28 KISTA, SWEDEN	Internet: jw@sics.se
Tel: +46 8 752 15 32	Ttx: 812 61 54 SICS S	Fax: +46 8 751 72 30