[unix-pc.general] alloca source needed

ditto@cbmvax.UUCP (Michael "Ford" Ditto) (01/25/89)

In article <642@shade.UUCP> steveb@shade.ann-arbor.mi.us (Steve Barber) writes:
>I need an alloca that will work in gcc-1.32 and I don't have a GNU emacs
>available to pull it out of.

# This is optimized for the Unix PC, it won't work on some other 68k systems.
# The "and.l &-4" could be changed to "and.l &-2" if you're only running the
# code on the Unix PC.  I use this same code when cross-compiling to a 68020
# system, thus the longword alignment.

	global	alloca
alloca:
	mov.l	(%sp)+,%a0	# pop return addr
	mov.l	(%sp),%d0	# get size argument
	and.l	&-4,%d0		# round size down to long word
	sub.l	%d0,%sp		# allocate by moving stack pointer
	mov.l	%sp,%d0		# return pointer in d0
	lea	-4(%sp),%sp	# allow caller to pop the arg
	jmp	(%a0)		# return

>If you could also document the theory behind what it does and how it
>works it would help a lot.

Alloca relies on the fact that the compiler-generated code in the calling
function exclusively uses the frame pointer (rather than the stack pointer)
for accessing stack-relative storage.  Basically, alloca(N) is equivalent
to (SP -= N), aside from adjusting N to prevent address errors, etc.  The
result is that the return value points to N bytes of new space on the stack,
%fp hasn't changed (still points to the local storage) and %sp is set up so
that future function calls will not touch the allocated area.  When the
calling function exits, it does an unlk %fp, pointing the stack pointer
back where it was when the function began, and making the alloca'd area
free for use again.

An important limitation of alloca is that it must never be called when the
compiler has something temporarily on the stack (such as arguments to an
outer function call, or intermediate results from an outer expression).
For example, you can't say:

	puts(strcpy(alloca(100), string));

you must do:

	char *tmp = alloca(100);
	puts(strcpy(tmp, string));

Generally, alloca must only be called with a simple argument (a constant
or a single variable) and the return value must be placed directly into a
variable.
-- 
					-=] Ford [=-

"The number of Unix installations	(In Real Life:  Mike Ditto)
has grown to 10, with more expected."	ford@kenobi.cts.com
- The Unix Programmer's Manual,		...!sdcsvax!crash!elgar!ford
  2nd Edition, June, 1972.		ditto@cbmvax.commodore.com