From: fmccva!bms88!stuart@uunet.UU.NET (Stuart D. Gathman)
Subject: 88open OCS
Summary: is 88open OCS braindamaged?
Keywords: code, 88000, registers
Reply-To: fmccva!bms88!stuart@uunet.UU.NET (Stuart D. Gathman)
Organization: Business Management Systems, Inc.
Date: Wed, 15 Apr 1992 02:10:28 GMT

I think that the 88open OCS is braindamaged with respect to argument
passing.  But maybe someone on the net can enlighten me.

The simple past
---------------

We have been using GNUC 1.40 on the 88k for some time now.  My port used
the simple argument passing scheme supported by GNUC 1.40:

	pass the first 8 words in registers.  
	pass the remainder on the stack.

In functions using varargs.h or stdarg.h, the compiler would flush
anonymous argument registers to the stack.  All anonymous args where then
adjacent in memory and properly aligned.  This meant that va_list was a
char * and that standard varargs and stdarg headers could be used.  The
only restriction was that varargs functions had to remember to use "..."
or "va_alist".

The system compiler (Greenhills) was quite buggy compared to GNU, (and we
never used it once GNU was installed) but its most aggravating feature was
the argument passing convention:

	pass the first 8 words in registers,
		except, certain types were always passed on the stack.
	always reserve stack space, even when passing in registers,
		unless, nothing was passed on the stack.

With this convention, a varargs function doesn't know the stack offset of
arguments until it knows how many, and what type of arguments were passed.
The system varargs header was a nightmare, using a struct for va_list with
pointers to register and stack args and a count of how many had been
analyzed so far.  There were half a dozen compiler hooks to decide whether
a given argument could be passed in registers or not.

Naturally, I thought my approach was much better and I added a few stubs
to gnulib to interface to the vprintf functions in libc.

Then, along came GNUC 2.0 with C++ and OCS
------------------------------------------

This compiled right up and worked great, including C++.  Unfortunately,
the official GNU 88k port uses the same (to me) braindamaged argument
convention as Greenhills, explaining that they are merely following the
88open OCS standard.

I tried to think of some reasons why someone would want to use
the OCS convention:

	1) passing C++ objects with constructors is tricky with my method.  
	The obvious solution of constructing on the stack, then reloading
	into registers is inefficient.  Transparently passing a reference 
	to a temporary is better.  I favor (tranparently) reordering
	arguments.
	(Implying that anonymous args can't have constructors.  Big deal.)

That's all I could think of.  Is there a good reason?  Or this another
bureaucratic blunder?

We have to decided to use the OCS convention for now with C++, since
varargs are hardly ever (never?) needed in C++.  This also means I don't
have to mess with the GNU 88k port.

P.S.
	My 1.40 88k port did insn scheduling in the assembler.  Doing it
in the compiler can better schedule across basic blocks, but the assembler
pass was almost as good and resulted in a much smaller and faster
compiler.  Any opinions on this?  I can post my (small and simple) asopt
pass if anyone is interested.
-- 
Stuart D. Gathman	<stuart@bms88.uucp>
			<..!fmccva!bms88!stuart>
-- 
Send compilers articles to compilers@iecc.cambridge.ma.us or
{ima | spdcc | world}!iecc!compilers.  Meta-mail to compilers-request.
Xref: sparky comp.compilers:791 comp.lang.c:7702 gnu.gcc.help:1101