[net.lang.c] register variables allocation in Pyramids

vijay@topaz.ARPA (P. Vijay) (07/05/85)

>> I have to admit to getting into the sloppy habit of stopping after
>> six register declarations.  But that's not why I'm writing this.
>> . . what I really want to do is make another point here, and that
>> is that you should declare register variables before ordinary
>> variables (in general), since some machines (Pyramids) ignore the
>> word ``register'' and just put the first N (12) variables in
>> registers.  (Such a machine must, of course, be able to take the
>> address of a register.)

>Sounds like the Pyramid compiler has a problem there, to the extent that
>it's not following the spirit of the `register' declaration.  Who ever said
>that "order of declaration" is a hint to the compiler on which variables
>are most frequently used?!
>
>Also, it's not generally possible to declare register variables before
>ordinary variables--parameters are effectively just initialized local
>variables, but the syntax requires that they all be declared before any of
>the locals.  The parameter-vs-local distinction is another reason that
>compilers ought not to do what the Pyramid compiler is described as doing.

	Pyramid C compiler seems to be taking an easy way out, when
it comes to allocating register variables. However, I would like to
point out that Pyramid architecture allows for a large number of
registers and every invocation of a function results in a new set of
registers (a la TI994, I think). Actually, there are 16 global
registers for each process. Besides this, for every invocation of a
function, three sets of 16 registers each are allocated. One of the
sets is specifically for storing local variables (if you have more
than 16 local vars, the rest can be placed on the data stack). Also,
the call instruction ensures that the third register set (Parameter
Register Set) before the call is the first register set (Temporary
Register Set), on entry into the function. Thus whatever arguments
you want to pass, you store in the parameter registers in some order,
and the function you are calling will see them in its temporary
registers.  Needless to say, the value(s) being RETurned is (are) put
in the temporary register set, so that on return the caller sees it
(them) in its parameter register. Actually, because one may have data
types that cannot be fit into the 32 bit registers, parameter passing
uses the data stack too, if necessary. BTW, the local variables can
be stored (where else) in the second register set (Local Register
Set), one of which is created for every invocation.

	Hope this clears up some of the astonishment expressed over
the *stupidity* of the Pyramid C compiler. Philosophy here is if you
can get the hardware to supply you with reasonable amount of
registers, without the hassle of saving them over calls, you don't
break your head over register allocation (*sort of*).

							--Vijay--

chris@umcp-cs.UUCP (Chris Torek) (07/06/85)

Close, but the temporary registers become the called procedure's
parameter registers, not vice versa.  I.e., after

_main:
	tr0 = 4		# put 4 in temp reg 0
	tr1 = 32
	call _foo

(I'm not going to use real Pyramid assembly) in foo, pr0 is 4 and
pr1 is 32.  foo's pr0 has the same address as main's tr0, of course,
so after foo does

	pr0 = 0
	ret

main has tr0 = 0.  This is how "return(expr);" works (if expr fits
in registers).  (There is also a bug in the compiler that is related
to this.)

Incidentally, although there are 16 of each type of register (global,
parameter, local, and temporary/transfer [transfer is my personal
name for 'em just before a call]), only 12 of each can be used,
since the others are "special".  (Or at least the compiler only
uses 12.  I don't know what the extra pr's, lr's, and tr's do; but
the gr's are stack & frame & so forth, I think.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

zben@umd5.UUCP (07/09/85)

In article <2496@topaz.ARPA> vijay@topaz.ARPA (P. Vijay) writes:
>	Pyramid C compiler seems to be taking an easy way out, when
>it comes to allocating register variables. However, I would like to
>point out that Pyramid architecture allows for a large number of
>registers and every invocation of a function results in a new set of
>registers (a la TI994, I think)...

Actually there are TWO subroutine call instructions, one for local
procedures and another for distant procedures, only the second one
gives you another registerset.

This can be done cheaply because the registers actually live in memory!
There is a Workspace Pointer register that points to the base of the
memory used for registers.  This is a BIG lose timewise because every
reference to a REGISTER requires a bus cycle.  Ick.

But there was sort of a win silicon-wise - they saved enough space by
not having registers on the chip to implement an integer multiply AND
integer divide operation!

From the proud owner of a Technico 9900 board with 1k bytes of RAM and
NO disk.  Assembler?  Who has room?  I program in HEX...  (ick)  Not too
bad - A is add, C is compare...   :-)

-- 
Ben Cranston  ...{seismo!umcp-cs,ihnp4!rlgvax}!cvl!umd5!zben  zben@umd2.ARPA