🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

1 total messages Started by Brendan Lynch - Sun Boston Devel... Tue, 07 Apr 1992 17:32
Bug in gcc-2.1 (and 2.0): 'const' function calls.
#225
Author: Brendan Lynch - Sun Boston Devel...
Date: Tue, 07 Apr 1992 17:32
152 lines
3712 bytes
The gcc-2.1 compiler does not correctly handle deferred argument
poping in a routine in which calls to 'const' functions have been
removed during optimization.  This problem is not
architecture-specific, but should affect all machines for which
deferred argument popping is allowed.

The following example shows this:

The routine:
-------------------------
extern double const sqrt(double);

double a[8];

extern void func2();

void
init(void)
{
	a[0] = sqrt(1.5);
	a[1] = 2 * sqrt(3.25);
	a[2] = 2 * sqrt(3.25);
	a[3] = 2 * sqrt(3.65);
	a[4] = 3 * sqrt(3.25);
	func2(a);
}
-------------------------

generates the following code on a Sun386 (Sun syntax assembler):

-----------------------------
	.file	"trysc.c"
	.version	"GNU C 2.1"
	.optim
gcc2_compiled.:
	.text
	.align 4
.LC0:
	.double 3.0000000000000000000000e+00
	.align 4
.globl init
init:
	pushl %ebp
	movl %esp,%ebp
	subl $8,%esp
	pushl $1073217536
	pushl $0
	call sqrt
	fstpl a
	pushl $1074397184
	pushl $0
	call sqrt
	fstpl -8(%ebp)
	fldl -8(%ebp)
	fadd %st(0),%st
	fstl a+8
	fstpl a+16
	pushl $1074606899
	pushl $858993459
	call sqrt
	fadd %st(0),%st
	fstpl a+24
	fldl -8(%ebp)
	fmull .LC0
	fstpl a+32
	addl $40,%esp		<< error
	pushl $a
	call func2
	leave
	ret
	.align 4
.comm a,64
-----------------------------

The erroneous staement is that which pushes 40 bytes from the stack.
Although there were originally 5 calls to 'sqrt' (each pushing 8 bytes
of arguments), 2 of them have been optimized away, leaving only 24
bytes of arguments on the stack.  Popping 40 bytes causes the stack to
get messed up.

The expand_call routine, in "calls.c" at line 598, has code which
looks as if it were intended to avoid this problem:

  /* When calling a const function, we must pop the stack args right away,
     so that the pop is deleted or moved with the call.  */
  if (is_const)
    NO_DEFER_POP;

Unfortunately this only sets the 'inhibit_defer_pop' flag which is
reset to the value of 'old_inhibit_defer_pop' in 'emit_call_1'
*before* the check to see if the caller must pop the arguments
immediatley after the call.

The fix I have implemented is to set 'old_inhibit_defer_pop' at the
same time; this seems to generate correct code, but I am not sure if
it is the best fix for this problem.

With this fix in place, the following code is generated:

-----------------------------------------
	.file	"trysc.c"
	.version	"GNU C 2.1"
	.optim
gcc2_compiled.:
	.text
	.align 4
.LC0:
	.double 3.0000000000000000000000e+00
	.align 4
.globl init
init:
	pushl %ebp
	movl %esp,%ebp
	subl $8,%esp
	pushl $1073217536
	pushl $0
	call sqrt
	addl $8,%esp
	fstpl a
	pushl $1074397184
	pushl $0
	call sqrt
	addl $8,%esp
	fld %st(0)
	fadd %st,%st(1)
	fxch %st(1)
	fstl a+8
	fstpl a+16
	pushl $1074606899
	pushl $858993459
	fstpl -8(%ebp)
	call sqrt
	addl $8,%esp
	fadd %st(0),%st
	fstpl a+24
	fldl -8(%ebp)
	fmull .LC0
	fstpl a+32
	pushl $a
	call func2
	leave
	ret
	.align 4
.comm a,64
--------------------------------

- ---------------------------------------------

Brendan Lynch

EMail:	internal: blynch@East
	external: Brendan.Lynch@East.Sun.COM
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads