From: steve@digibd.com (Steve Wahl)
Subject: Re: Lack of libPW.a module
Organization: DigiBoard Incorporated, Eden Prairie, MN
Date: Wed, 02 Sep 1992 20:12:16 GMT
Keywords: libPW PW alloca xmalloc

I don't think anyone understands me yet.  First, some context.

In article <1992Aug29.052011.24352@colnet.cmhnet.org> res@colnet.cmhnet.org (Rob Stampfli) writes:
>In article <1992Aug27.213851.20578@digibd.com> steve@digibd.com (Steve Wahl) writes:
>[ alloca.s code deleted ]
>>
>>Rob's post mentions that you can't call this alloca() when there's
>>something on the stack.  But beware: I believe this aproach also fails
>>if you use register variables in your functions: think about how the
>>compiler saves and restores the registers.
>>
>
>Register variables are not saved prior to calling a function, but rather are
>saved and restored by the called function, and then only if the register is
>needed therein.

Yes, but the problem is in what is restored by the called function...

>  This is true of both the stock cc and gcc compilers for the
>3B1.  The alloca function I posted uses only those register variables that
>are defined to be scratch variables by the compilers, so there is no need
>for it to save %d0 or %a0.  (In fact, this function doesn't really set up a
>standard 'C' stack frame for itself -- since it is so simple and calls no
>one, it uses an efficient, but externally equivalent alternative.)

Ok, so consider this code:

f1()
{
	register int a;

	a = 5;
	a += f2();
	return(a);
}

f2()
{
	register int b;
	char *p;

	b = 7;
	p = alloca(10);
	return(b);
}

I don't have direct access to my 3b1 right at this moment, but I believe the
compiler will pick register d2 for both variables a and b.  So the
code for f1 would be something like:

     [ I don't have immediate access to my 3b1 , so this could be off ]

f1:
	link.l	%a6,0		# create stack frame
	mov.l	%d2,-(%sp)	# save register variable
	mov.l	&5,%d2		# set a to 5
	bsr	f2		# call f2
	add.l	%d0,%d2		# add result
	mov.l	%d2,%d0		# set return value
	mov.l	(%sp)+,%d2	# restore register variable
	unlk	%a6		# remove stack frame
	rts

f2:
	link.l	%a6,-4		# create stack frame
	mov.l	%d2,-(%sp)	# save regsiter variable
	mov.l	&7,%d2		# set b to 5
	pea.l	10		# parameter to alloca
	bsr	alloca		# call alloca
	add.w	&4,%sp		# pop argument to alloca
	mov.l	$d0,-4(%a6)	# store alloca return in p
	mov.l	%d2,%d0		# return value
	mov.l	(%sp)+,%d2	# restore register variable **************	
	unlk	%a6		# remove stack frame
	rts

The restore register variable step marked with "*******" is the
problem, because it restores garbage from within the alloca'd area
instead of the value pushed on the stack (alloca made the stack
pointer move, unknown to the compiler).  This could be a very hard
problem to figure out, since it doesn't affect variables in f2, only
in f1!  (BTW, I believe gcc may restore the register contents with
known offsets from the frame pointer %a6, rather than the stack
pointer - so GCC may not have the problem, but I'm quite sure the
stock cc has it.)

Anyone disagree with my analysis?

--> Steve
-- 
Steve Wahl               steve@digibd.com
Digi International, Inc.
Eden Prairie, MN         (612) 943-5387
Newsgroups: comp.sys.3b1