[net.micro.68k] nargs

mem@sii.UUCP (Mark Mallett) (12/27/83)

b
To the nargs() routine submitted by fortune!shah, I'd suggest recognizing
an LEA stack adjustment instruction, i.e.,

	LEA	n*4(SP),SP

While I know of no 68000 C compilers that generate this sort of fixup,
it is the sort of thing that assembler language programmers would think
of first (me, anyway); and it seems worth anticipating of future compilers.

I'd also like to opine that looking at the instruction after the call
instruction to determine the number of arguments is not a 100% accurate
way to get the number of arguments passed, for these reasons:

    - It doesn't take into account different argument types (e.g.
      doubles).

    - I can imagine compilers generating stack-fixup instructions in
      dealing with variables bound to local scopes.  Can't you?

    - The Whitesmith's compiler seems to keep a free location on the
      top of the stack to deal with calls to routines where only one
      value is passed.  At least this is what it appears to do; I'm
      easily fooled.  This is something that can't be detected by the
      subroutine, and is an optimization I'd easily expect of compiler
      writers.

But I can't think of any other way to do it.

Mark E. Mallett
decvax!sii!mem

shah@fortune.UUCP (12/28/83)

#R:sii:-36300:fortune:6600006:000:1044
fortune!shah    Dec 27 22:21:00 1983

*
    I agree with Mark Mallet (sii!mem); nargs should be used with
caution.  It is a simple hack that works well if your compiler is
not too tricky smart and if it is used in a well understood context.
That is, the caller of nargs() should *know* what kind of values may
be passed to it.

    The version you saw was written for a co-routine package.  We
wanted to create co-routines out of any routine (with ANY number of
arguments).  As an example, you can create a co-routine out of
routine "foo" with 3 arguments by saying

    fooProcess = createProc(stackAddress, stackSize, deathHandler,
			    foo, arg1, arg2, arg3);

Later on when you "resume(fooProcess)" it is as if you *called* foo
with arg1, arg2, arg3.  Our nargs() is used by routine createProc in
copying arguments arg1, arg2, etc. to the co-routine stack.

    Ofcourse, nargs() *has* to stay in tune with the compiler.  If
that is not possible you have to resort to really messy hacks (as
opposed to clean hacks) in such applications.
						     -- Bakul
						fortune!shah

tjt@kobold.UUCP (T.J.Teixeira) (12/30/83)

Another stack adjustment instruction is:

	ADDW	#n*4,SP

Remember, the 68000 will sign extend any operand applied to an address
register.

This has the same time/space performance as the

	LEA	n*4(SP),SP

instruction mentioned by sii!mem (Mark Mallet), and *is* actually
generated by the Masscomp C compiler.

Of course, all the other caveats apply, leading to the unfortunate
result of if you *really* want it done right, you have to do it
yourself.  Of course, since it is easy to miscount arguments, and the C
language (and most runtime systems) won't provide it for you, you could
try a special "end-of-argument-list" value (e.g. 0 in execv and
variants).

-- 
	Tom Teixeira,  Massachusetts Computer Corporation.  Westford MA
	...!{ihnp4,harpo,decvax,ucbcad,tektronix}!masscomp!tjt   (617) 692-6200

minow@decvax.UUCP (Martin Minow) (12/30/83)

fortune!shah suggests using an nargs() function when creating
processes in an operating system.  For example (changing his
slightly)

	procid = create_process(main_function, priority, stacksize,
		arg0, arg1, ... argn);

Then, when the process starts, it is called as

	main_function(arg0, arg1, ... argn);

A simpler solution, (which does require that you can access arguments
in sequence) would be as follows:

	procid = create_process(main_function, priority, stacksize,
		argc, arg0, arg1, ... argn);

The main_function would be called as

	main_function(argc, argv)
	int		argc;
	char		*argv[];

The implementation is quite straight-forward.

Martin Minow
decvax!minow

shah@fortune.UUCP (01/02/84)

#R:sii:-36300:fortune:6600009:000:2099
fortune!shah    Jan  1 18:50:00 1984

    `nargs' name is misleading as it really returns the size
of argument block (in units of sizeof (long)).  This is so
because you can have structs as arguments.  You can compute
the size of argument block without nargs but it is painful.
AND you, the user, has to know about how the compiler pushes
arguments on the stack.  A call to a version of createProc
that does not use nargs would look something like

    process = createProc(stackArea, stackSize, deathHandler,
			SIZE(arg1) + SIZE(arg2) + .. + SIZE(argn),
			foo, arg1, arg2, .. , argn);

	where SIZE(x) is
		(((sizeof(x)+LONGSIZE-1) / LONGSIZE)) * LONGSIZE)

	    where LONGSIZE is sizeof(long)

    Ughh!  OR you can restrict the argument types to be non-
structs!  OR you can always restrict total argument size to be
less than 2^N bytes -- wasteful and not easy to check.  OR you
can use a special value as the last argument to createProc and
restrict other arguments to not use this special value!  OR
you can use the printf idea of specifying argument type (and
hence size) in a string -- but how do you specify the size of
a structure?

    We did consider some of these ideas before choosing nargs
in favor of making the interface simpler and without any
restrictions on the number of arguments or their types.  It is
really unfortunate that nargs is not portable.

    I like nargs because it is an easy to use tool and with it
I can build easy to use tools.  On top of the co-routine
package we built a simulation kernel much like the one in
Concurrent Euclid.  Using this kernel we built a simple
simulator for the Fortune 32:16 bus to find out worst case DMA
latency etc.  Each level presented a simple interface to the
next one.  I think that was one of the major reasons for being
able to get our results in a short time.

    Ease of use is a very important attribute for software at
every level.  It does require you, the implementer, to look at
your program from its users' point of view.  By way of nargs
and the couple examples I wanted to draw your attention to this
belief.

					 -- Bakul Shah
					   fortune!shah