[net.lang.c] Code Generation

cottrell@nbs-vms.arpa (COTTRELL, JAMES) (11/21/85)

/* Key: >> Ron Natalie, > Chris Torek
> > It doesn't ignore register short definitions, it mearly does not put them
> > in registers because registers can only be applied to types int and long
> > on VAX.
> 
> You can indeed apply
> registers to `short's and `char's and even `float's and `double's;
> it is merely much more difficult to get the code generation right.

Why is that? For the moment lets forget about the floating types.
From the way I read my manual, using the byte & word flavors of
instruxions makes the registers appear to be 8 & 16 bits wide.
So what's so difficult about that.

To put it another way, write a fragment of code using ints, run it
thru `cc -S'. Then change the `ints' to `shorts'. Now I claim I should
be able to get equivalent (more efficient tho) code merely by changing
the flavors of the instruxions from `long' to `word'. Prove me wrong.

	jim		cottrell@nbs
*/
------

chris@umcp-cs.UUCP (Chris Torek) (11/22/85)

In article <3457@brl-tgr.ARPA> cottrell@nbs-vms.arpa (COTTRELL, JAMES) writes:

> /* Key: >> Ron Natalie, > Chris Torek
> > You can indeed apply
> > registers to `short's and `char's and even `float's and `double's;
> > it is merely much more difficult to get the code generation right.

> Why is that? For the moment lets forget about the floating types.

PCC seems to want to convert all expressions of type `short' and
`char' before looking them up in its opcode tables.  You would have
to rip that out, which would require matching changes in all the
support routines.  That is an awful lot of changes....
-- 
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@mimsy.umd.edu

rcd@opus.UUCP (Dick Dunn) (11/22/85)

On the VAX C compiler ignoring "register" for char and short...
Key: >>> Natalie, >> Torek, > Cottrell
> > > It doesn't ignore register short definitions, it mearly does not put them
> > > in registers because registers can only be applied to types int and long
> > You can indeed apply
> > registers to `short's and `char's and even `float's and `double's;
> > it is merely much more difficult to get the code generation right.
> Why is that? For the moment lets forget about the floating types.
> From the way I read my manual, using the byte & word flavors of
> instruxions makes the registers appear to be 8 & 16 bits wide.

Honestly, the code generation difficulties are not great; neither are they
completely trivial.  Consider, for example, that the sum/difference/product
of two bytes is a word, so you need to be sure that you choose the right
operation but it's not much more difficult than that.  Keep some info with
register variables so that you know what types they are.

The nasty thing is that with the VAX working the way it does now, there is
a PENALTY for saying, e.g., `register short' instead of `register int'.  I
have been stung by this one more than once.  The situation arises because
I'm careful to declare `short' when I mean it--it makes a LOT of difference
on a 68000, where short*short is a single machine instruction but int*int
is a long procedure call.  Now I take this code, written carefully but not
particularly tuned to a particular machine, and move it to the VAX.  I
discover that I get better (==smaller&faster) code by LENGTHening the
operands?!  That's silly, also annoying, and should not be necessary.
-- 
Dick Dunn	{hao,ucbvax,allegra}!nbires!rcd		(303)444-5710 x3086
   ...If you get confused just listen to the music play...

peter@graffiti.UUCP (Peter da Silva) (11/23/85)

> > You can indeed apply
> > registers to `short's and `char's and even `float's and `double's;
> > it is merely much more difficult to get the code generation right.
> 
> Why is that? For the moment lets forget about the floating types.
> From the way I read my manual, using the byte & word flavors of
> instruxions makes the registers appear to be 8 & 16 bits wide.
> So what's so difficult about that.

The registers are not wide enough to hold a double. Also, you cannot
just change the flavors of the instructions. Consider a case where
{ register short i; register long j; short c; } are in registers. Perform
{ i=c; ... j=i; }. You have to do more than move the low word of the register.
You have to either explicitly clear the high word of i when you store
c in it, have explicitly cleared it when you entered the block, or clear
the high word of j after doing a 16-bit move from i to j.
-- 
Name: Peter da Silva
Graphic: `-_-'
UUCP: ...!shell!{graffiti,baylor}!peter
IAEF: ...!kitty!baylor!peter

meissner@rtp47.UUCP (Michael Meissner) (11/23/85)

In article <3457@brl-tgr.ARPA> cottrell@nbs-vms.arpa (COTTRELL, JAMES) writes:
>/* Key: >>> Ron Natalie, >> Chris Torek
>> > It doesn't ignore register short definitions, it mearly does not put them
>> > in registers because registers can only be applied to types int and long
>> > on VAX.
>> 
>> You can indeed apply
>> registers to `short's and `char's and even `float's and `double's;
>> it is merely much more difficult to get the code generation right.
>
>Why is that? For the moment lets forget about the floating types.
>From the way I read my manual, using the byte & word flavors of
>instruxions makes the registers appear to be 8 & 16 bits wide.
>So what's so difficult about that.
>

    I don't know much about the VAX pcc C compilers, but I would guess the
real problem is the semantics of C, which requires short/char items to be
converted to INT in any arithmetic expression.  Thus the 8 and 16 bit forms
of the instruction cannot be used (because they would truncate, etc.).  Also
such instructions assume that both operands are short/char.

	Michael Meissner, Data General

bilbo.niket@locus.ucla.edu (Niket K. Patwardhan) (11/25/85)

[on a 68000 where short*short is a single instruction, but int*int requires a
procedure call ]

Thats what you get for using a machine that calims to be 32-bit when it really
is 16-bit. Dont know how to help you with your gripe but "int" exists to
represent the natural size of the machine..... in my interpretation that
would be the size that works best, fastest etc.

chris@umcp-cs.UUCP (Chris Torek) (11/25/85)

In article <462@graffiti.UUCP> peter@graffiti.UUCP (Peter da Silva) writes:

[me]
> > > You can indeed apply
> > > registers to `short's and `char's and even `float's and `double's;
> > > it is merely much more difficult to get the code generation right.

[Jim Cottrell]
> > Why is that? ...

> The registers are not wide enough to hold a double.

No, but then they never were.  The double precision instructions
operate on register pairs (shades of the 370! :-) ), when they
operate on registers at all.

> Consider a case where { register short i; register long j; short c; }
> are in registers.  Perform { i=c; ... j=i; }.  You have to do more
> than move the low word of the register.  You have to either explicitly
> clear the high word of i when you store c in it, have explicitly cleared
> it when you entered the block, or clear the high word of j after doing
> a 16-bit move from i to j.

That is not really necessary.  All you need is `cvtwl rI,rJ'.

But all this just goes to demonstrate my original point.  The code
generation gets messier, and that makes it harder:  That is the main
reason no one has done it, except maybe Tartan Labs---and they are
not exactly giving it away....
-- 
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@mimsy.umd.edu

rcd@opus.UUCP (Dick Dunn) (11/26/85)

> [on a 68000 where short*short is a single instruction, but int*int requires a
> procedure call ]
> 
> Thats what you get for using a machine that calims to be 32-bit when it really
> is 16-bit. Dont know how to help you with your gripe but "int" exists to
> represent the natural size of the machine..... in my interpretation that
> would be the size that works best, fastest etc.

Did you escape from a marketing department, or what?  Go tighten up your
tie 'til your eyes bug out.

The 68000 and 68010 are described by Motorola as 16-bit microprocessors.
See, for example, the manual called "MC68010 16-BIT VIRTUAL MEMORY
MICROPROCESSOR" from Motorola.  Hint:  Even the title will (might?) give
you a clue.  They didn't start calling th 68000 family 32-bit processors
until the 68020, in spite of having 32-bit registers and 32-bit
add/subtract/logical instructions all along.

A choice of 16-bit ints for C for the 68000/68010 would be idiotic.  (Yes,
I know a few people have done it.  That makes it no less idiotic.)  Issues
are at least array indices and differences of pointers.

Really, there's a matter that some machines don't have a handy-dandy black
and white definition of what the natural size of integer for the machine
is.  32-bit ints make a lot of sense for the 680[01]0, but multiplies and
divides are expensive.  Implementor makes a choice and you do what you
can.  More modern languages ought to be able to cope with machines which
don't have a single obvious choice of length for all possible forms of
integer.
-- 
Dick Dunn	{hao,ucbvax,allegra}!nbires!rcd		(303)444-5710 x3086
   ...If you get confused just listen to the music play...

hammond@petrus.UUCP (Rich A. Hammond) (11/26/85)

> [on a 68000 where short*short is a single instruction, but int*int requires a
> procedure call ]
> 
> Thats what you get for using a machine that calims to be 32-bit when it really
> is 16-bit. Dont know how to help you with your gripe but "int" exists to
> represent the natural size of the machine..... in my interpretation that
> would be the size that works best, fastest etc.

The problem is really the brain damage among UNIX hackers that  assumes
sizeof(int) == sizeof (char *).  This is so painful to fix (for quick ports)
that although the 68000's int should be 16 bits (the size that works best,
fastest, ...) it is often made 32 bits.  While this avoids the pain for the
porter, it does lead to problems for the end user (i.e. using short vs int).

Rich Hammond    (ihnp4|allegra|decvax|ucbvax) !bellcore!hammond

mike@hpfcla.UUCP (11/27/85)

I suspect that one reason 16-bit int 68000 compilers appeared was that
they have an edge in simplistic benchmarking (marketing). 

Mike McNelly	hplabs!hpfcla!mike

garry@lasspvax.UUCP (Garry Wiegand) (11/27/85)

The definition of "int" I carry around in my head is "use whatever length
is natural and convenient on this machine; makes no difference to me."
There may be compilers that do not adhere to this (my 68000 compiler
requires a command-line switch), but I think that qualifies as a compiler
bug and a #define is in order.

As far as I've ever observed, word instructions execute at just about the
same speed as longword instructions on the vax -- ie, no penalty -- unless
you start mixing them.

garry wiegand

garry%geology@cu-arpa.cs.cornell.edu

laura@l5.uucp (Laura Creighton) (11/27/85)

In article <703@petrus.UUCP> hammond@petrus.UUCP (Rich A. Hammond) writes:
>
>The problem is really the brain damage among UNIX hackers that  assumes
>sizeof(int) == sizeof (char *).  This is so painful to fix (for quick ports)
>that although the 68000's int should be 16 bits (the size that works best,
>fastest, ...) it is often made 32 bits.  While this avoids the pain for the
>porter, it does lead to problems for the end user (i.e. using short vs int).
>
Unless you intend to do a lot of multiplying and dividing, I can't see what
you would gain in making ints 16 bits.  You *won't* get a significantly
faster port, because you have to go through all the code and check for
(at a minimum) dereferencing null pointers, and while you are at that you
can get those as well.

A harder problem is code that assumes sizeof(int *) == sizeof(char *) 
== sizeof(struct foo *). Use lint. realise that correct code is not just code
that happens to not dump core very often on your machine. Use lint.
-- 
Laura Creighton		
sun!l5!laura		(that is ell-five, not fifteen)
l5!laura@lll-crg.arpa

ps@celerity.UUCP (Pat Shanahan) (12/02/85)

In article <2327@umcp-cs.UUCP> chris@umcp-cs.UUCP (Chris Torek) writes:
...
>> > > You can indeed apply
>> > > registers to `short's and `char's and even `float's and `double's;
>> > > it is merely much more difficult to get the code generation right.
...
>But all this just goes to demonstrate my original point.  The code
>generation gets messier, and that makes it harder:  That is the main
>reason no one has done it, except maybe Tartan Labs---and they are
>not exactly giving it away....
>-- 
>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@mimsy.umd.edu

The Celerity C compiler supports long, short, char, float, and double in
registers. Both signed and unsigned are supported in registers for the
integer types. Of course, the fact that the target machine has 15 64-bit
floating point registers makes doubles easier to manage than on most
machines.

-- 
	ps
	(Pat Shanahan)
	uucp : {decvax!ucbvax || ihnp4 || philabs}!sdcsvax!celerity!ps
	arpa : sdcsvax!celerity!ps@nosc

bilbo.niket@locus.ucla.edu (Niket K. Patwardhan) (12/03/85)

Alright babes.... Motorola did start out by calling them things 32-bit, until
they ran into a lot of derisive comments. I still remember a flyer that
claimed this, AND the flak flyer.

Of course they have learned the error of their ways.... but
the damage has been done. And half-baked(!!!!!) implementations are not the
most beautiful of things to work with.

hdc@trsvax (12/05/85)

/* Written 12:02 am  Nov 26, 1985 by opus.UUCP!rcd in trsvax:net.lang.c */
/* ---------- "Re: Code Generation (register byte," ---------- */

They didn't start calling th 68000 family 32-bit processors
until the 68020, in spite of having 32-bit registers and 32-bit
add/subtract/logical instructions all along.

/* End of text from trsvax:net.lang.c */

   Actually I think Apple was guilty of promoting, vigorously, the idea
that the 68000 was/is a 32-bit processor.  In comparing the Mac to the
IBM PC, their literature has "32-bit" plastered all over it.  Personally
I like the title of one of Motorola's manuals, "M68000 16/32 Bit 
Microprocessor".

thomas@kuling.UUCP (Thomas H{meenaho) (12/05/85)

In article <462@graffiti.UUCP> peter@graffiti.UUCP (Peter da Silva) writes:

>The registers are not wide enough to hold a double. Also, you cannot
>just change the flavors of the instructions. Consider a case where
>{ register short i; register long j; short c; } are in registers. Perform
>{ i=c; ... j=i; }. You have to do more than move the low word of the register.
>You have to either explicitly clear the high word of i when you store
>c in it, have explicitly cleared it when you entered the block, or clear
>the high word of j after doing a 16-bit move from i to j.
>-- 

With that declaration of the register variables it is wrong to merely clear the
high bits.
Remember that they were implicitly declared as signed and you must therefore
sign extend them at some time. If that is done before the move or after doesn't
matter as long as it gets done.-- 
Thomas Hameenaho, Dept. of Computer Science, Uppsala University, Sweden
Phone: +46 18 138650
UUCP: thomas@kuling.UUCP (...!{seismo,mcvax}!enea!kuling!thomas)

skinner@saber.UUCP (Robert Skinner) (12/13/85)

> 
> /* Written 12:02 am  Nov 26, 1985 by opus.UUCP!rcd in trsvax:net.lang.c */
> /* ---------- "Re: Code Generation (register byte," ---------- */
> 
>    Actually I think Apple was guilty of promoting, vigorously, the idea
> that the 68000 was/is a 32-bit processor.  In comparing the Mac to the
> IBM PC, their literature has "32-bit" plastered all over it.  Personally
> I like the title of one of Motorola's manuals, "M68000 16/32 Bit 
> Microprocessor".

It's at least as honest as calling an 8088 a 16 bit processor.  Geez.


------------------------------------------------------------------------------
Name:	Robert Skinner
Snail:	Saber Technology, 2381 Bering Drive, San Jose, California 95131
AT&T:	(408) 945-0518, or 945-9600 (mesg. only)
UUCP:	...{decvax,ucbvax}!decwrl!saber!skinner
	...{amd,ihnp4,ittvax}!saber!skinner