[comp.unix.wizards] compiler predefines

seifert@doghouse.gwd.tek.com (Snoopy) (07/22/87)

Keywords:


[ comp.bugs.4bsd removed from newsgroups line.  This should probably
  move to one of the C groups. ]

In article <23741@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes:

>  There *should* either be a predicate built into the C
> preprocessor/compiler or a #define constant in some system include
> file;

YES! YES!  Anyone for "LITTLE_ENDIAN" and "BIG_ENDIAN" ?  And all the
predefines should be documented.

>is that 1) there's no guarantee that there will be a unique #define
>for a particular machine (consider "mc68000" vs. "m68k") and 2) it
>doesn't help when a new machine comes along.  (I don't even know what
>the magic predefine is for the NS32K series, or even if everybody
>uses the same one, so I didn't put it in up there;

Our compiler defines both ns16000 and ns32000.

"m68k" should mean 680x0, while "mc68000" should mean the 68000
specifically.

> I don't know if
> there *is* one for the WE32K series - AT&T seems to use stuff like
>
>	#if u3b20 || u3b2 || u3b5 || u3b15 || ...
>
> but enumerating all the 3Bs seems like a silly way of defining the
> set of machines using the WE32K

Last time I looked, the 3b20 didn't use the WE32K chip(s).  It predated
them, if I remember correctly.  Various boards had various micros (8085,
8086, 2911, etc).  Obviously they should define "3b" or similar.
(and probably we32k as well)

> (unless, of course, that set stops growing at some point,
> which is certainly possible).)

I read an article in one of the tabloids recently saying that sales
of the 3Bs were low, and they might be canceled (pending the result
of an internal battle).

But back to the main point, #ifdefs should reflect what you're
REALLY testing for.  Use #ifdef LITTLE_ENDIAN, or #ifdef MASSBUS,
not #ifdef vax, or worse, some internal codename for a machine.

Snoopy
tektronix!doghouse.gwd!snoopy
snoopy@doghouse.gwd.tek.com

"And it's a middle-endian machine with trinary logic."
"They would do that!"

Karl.Kleinpaste@cbstr1.att.com (07/22/87)

seifert@doghouse.gwd.tek.com writes:
> guy%gorodish@Sun.COM writes:
> > I don't know if
> > there *is* one for the WE32K series - AT&T seems to use stuff like
> >	#if u3b20 || u3b2 || u3b5 || u3b15 || ...
> > but enumerating all the 3Bs seems like a silly way of defining the
> > set of machines using the WE32K
> Last time I looked, the 3b20 didn't use the WE32K chip(s).  It predated
> them, if I remember correctly.  Various boards had various micros (8085,
> 8086, 2911, etc).  Obviously they should define "3b" or similar.
> (and probably we32k as well)

You are correct, the 3B20 is architecurally distinct from the
3B{2,5,15}.  The latter 3 can be considered identical for most any
application purpose.  The former is an older processor.

Also, the symbol defined on the -20 is just "u3b" (not "u3b20") which
it claims for historical reasons (i.e., it was there first), before
there was a useful distinction of one 3B from another.

For the most part the complicated "u3b2 || u3b5 || u3b15" is
significant only for certain pieces of the kernel, where such issues
actually matter.  Applications aren't supposed to care.  But a
distinction between the -20 and the rest is somewhat necessary at
other times.  As it happens, even large things like GNU Emacs can
avoid the issue entirely; the m-att3b.h file for GNU Emacs says, in
part:
	#define ATT3B
and then all the tests which are relevant to 3B's of any flavor just
work off of ATT3B.  A point of difference is in the data space
organization of the -20 versus 2/5/15, where the 2/5/15 have data
space starting with the high-order bit on, which plays hell with lisp
garbage collectors.  There is one 2||5||15 test in m-att3b.h which
defines special macros for accessing the necessary bit fields; other
than that, there's just one other 2||5||15 test to turn off the
optimizer because it happens to be just plain broken; the -20's
optimizer is fine.

(Chicken-and-egg problem: Compile -O, notice bug in resulting program
operation; recompile without -O in order to find apparent bug in your
program, bug goes away.  Mumble...I *hate* optimizer bugs...)

Karl

dhesi@bsu-cs.UUCP (Rahul Dhesi) (07/22/87)

#if 0    /* skip junk when compiling attached C program */
(I added comp.lang.c to the newsgroups and am directing followups there.)

In article <8888@tekecs.TEK.COM> snoopy@doghouse.gwd.tek.com (Snoopy) 
writes:
>In article <23741@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes:
>>  There *should* either be a predicate built into the C
>> preprocessor/compiler or a #define constant in some system include
>> file;
>YES! YES!  Anyone for "LITTLE_ENDIAN" and "BIG_ENDIAN" ?  And all the
>predefines should be documented.
[...]
>But back to the main point, #ifdefs should reflect what you're
>REALLY testing for.  Use #ifdef LITTLE_ENDIAN, or #ifdef MASSBUS,
>not #ifdef vax, or worse, some internal codename for a machine.

Yes, PLEASE do not use machine names except in ONE place, where you
select orthognoal attributes based on machine identity.  Use the
names of these attributes everywhere else.

I hope the problem of writing software that will adapt itself to
byte/word/int/long/short size and endianism and 1's vs 2's complement
will be solved by the following program.  The program can be compiled
and executed from a makefile, and generates a series of defines that
may then be included and tested by the remaining source files.

Sample output when executed on a VAX-11/785 under 4.3BSD (I manually
added the comments):

#define Mch_Csz 8       /* size of char */
#define Mch_Ssz 16      /* size of short */
#define Mch_Isz 32      /* size of int */
#define Mch_Lsz 32      /* size of long */
#define Mch_LE 1        /* little-endian */
#define Mch_sgc 1       /* char may be signed */

John Cowan, the author, is somewhat unclear about the copyright status
of this program.  I suspect he really wanted it to be public domain,
but wanted appropriate credit for it, so added the copyright notice.
#endif /* skip junk */

/* The contents of the following program are copyright 1987 by John Cowan.
It is hereby released to the public domain.

This program emits C #define statements to the standard output describing
the machine it is executing on.  The following #defines are generated:
        Mch_Csz -       size of a char, in bits
        Mch_Ssz -       size of a short int, in bits
        Mch_Isz -       size of a plain int, in bits
        Mch_Lsz -       size of a long int, in bits
        Mch_BE -        defined if the machine is big-endian; that is, if
                        the most significant byte in a number appears first.
        Mch_LE -        defined if the machine is little-endian; that is, if
                        the least significant byte in a number appears first.
        Mch_PDP -       defined if the machine uses PDP-11 byte ordering;
                        LE for bytes-in-a-word and BE for words-in-a-long.
        Mch_ONE -       defined if the machine uses one's complement arithmetic.
        Mch_sgc -       defined if characters can be signed.
*/

#include <stdio.h>

char bittest[6] = "\001\001\001\001\001";
char endtest[6] = "\001\002\003\004\005";
long be = 1;
long le = 1;
long pdp;
int byteoff;
int bytesize;
long longval;

main()
        {
        int i;

        byteoff = (*(int *) bittest & 2047) - 1;
        switch (byteoff) {
        case 256: bytesize = 8; break;
        case 512: bytesize = 9; break;
        case 1024: bytesize = 10; break;
        default: fprintf(stderr, "mch: bogus byte size\n"); exit(1);
                }
        printf("#define Mch_Csz %d\n", bytesize);
        printf("#define Mch_Ssz %d\n", sizeof(short) * bytesize);
        printf("#define Mch_Isz %d\n", sizeof(int) * bytesize);
        printf("#define Mch_Lsz %d\n", sizeof(long) * bytesize);
        longval = *(long *) endtest;
        for (i = 0; i < sizeof(long); i++) {
                be *= byteoff;
                be += endtest[i];
                }
        for (i = sizeof(long) - 1; i >= 0; i--) {
                le *= byteoff;
                le += endtest[i];
                }
        pdp = 0x02010403;
        if (longval == be)
                printf("#define Mch_BE 1\n");
        else if (longval == le)
                printf("#define Mch_LE 1\n");
        else if (longval == pdp)
                printf("#define Mch_PDP 1\n");
        else {
                fprintf(stderr, "mch: bogus endianism\n");
                exit(1);
                }
        if (~0 == 0)
                printf("#define Mch_ONE 1\n");
        if ('\377' < 0)       /* modified 1987/07/22 R. Dhesi */
                printf("#define Mch_sgc 1\n");
        }
/*
-- 
Rahul Dhesi         UUCP:  {ihnp4,seismo}!{iuvax,pur-ee}!bsu-cs!dhesi
*/

abh@pogo.cray.com (Andy Hastings) (07/27/87)

In article <865@bsu-cs.UUCP>, dhesi@bsu-cs.UUCP (Rahul Dhesi) writes:
> This program emits C #define statements to the standard output describing
> the machine it is executing on.  The following #defines are generated:
>         Mch_Csz -       size of a char, in bits
>         Mch_Ssz -       size of a short int, in bits
>         Mch_Isz -       size of a plain int, in bits
>         Mch_Lsz -       size of a long int, in bits
>         Mch_BE -        defined if the machine is big-endian; that is, if
>                         the most significant byte in a number appears first.
>         Mch_LE -        defined if the machine is little-endian; that is, if
>                         the least significant byte in a number appears first.
>         Mch_PDP -       defined if the machine uses PDP-11 byte ordering;
>                         LE for bytes-in-a-word and BE for words-in-a-long.
>         Mch_ONE -       defined if the machine uses one's complement arithmetic.
>         Mch_sgc -       defined if characters can be signed.

	Hmm.  The program said `mch: bogus byte size' when I ran it on my
CRAY X-MP.  I changed the definition of bittest to:
		char bittest[9] = "\001\001\001\001\001\001\001\001";
and then I got the correct results:
		#define Mch_Csz 8
		#define Mch_Ssz 64
		#define Mch_Isz 64
		#define Mch_Lsz 64
		#define Mch_BE 1
Much better.

-Andy Hastings			ihnp4!cray!hall!abh
 Cray Research, Inc.		sun!tundra!hall!abh

*CRAY X-MP is a trademark of Cray Research, Inc.