[comp.lang.c] bit-field pointers / arrays

stuart@bms-at.UUCP (12/11/86)

It  has  been  said  that  bit-field  arrays  are   intrinsically
impossible in 'C' because there can be no pointers to bit-fields.

There is no special reason why there cannot be a type like:

        unsigned *bitptr:1

which would likely be bigger than a 'char *'.  Then we could also
declare:

        unsigned bitarr[5000]:1

or even:

        unsigned pixelarr[640]:4

for a line of EGA pixels.

Bitfield pointers would have wildly different  formats  depending
on the processor, of course.

For 68020, it might be 6 bytes.  An address  followed  by  offset
and  width in each of two bytes.  This would be loaded into three
registers for use with the bit field processor instructions.

Adding and subtracting integers, increment and decrement, all are
straightforward to define.

The problem comes with 'sizeof'.  What is the size of a bit?

1.   My  first  impulse  is  to  disallow  'sizeof'  applied   to
bitfields.  (It is not allowed now anyway.)

2.  Another alternative is to make sizeof char  ==  8,  but  this
would cause problems allocating huge arrays with malloc().

3.  A third approach is to define the size of a  bitfield  to  be
the minimum number of standard sizeof units required to store the
field.  This would allow code such as:

        pixptr = (unsigned *:4) malloc(sizeof (unsigned [640]:4));

"k - a ring of fire resistance (on right hand)"
-- 
Stuart D. Gathman	<..!seismo!dgis!bms-at!stuart>

ballou@brahms (Kenneth R. Ballou) (12/12/86)

In article <311@bms-at.UUCP> stuart@bms-at.UUCP (Stuart D. Gathman) writes:
>It  has  been  said  that  bit-field  arrays  are   intrinsically
>impossible in 'C' because there can be no pointers to bit-fields.
>
>There is no special reason why there cannot be a type like:
>
>        unsigned *bitptr:1
>
>which would likely be bigger than a 'char *'.  Then we could also
>declare:
>
>        unsigned bitarr[5000]:1
>
>or even:
>
>        unsigned pixelarr[640]:4
>
>for a line of EGA pixels.
>
>Bitfield pointers would have wildly different  formats  depending
>on the processor, of course.
>
>For 68020, it might be 6 bytes.  An address  followed  by  offset
>and  width in each of two bytes.  This would be loaded into three
>registers for use with the bit field processor instructions.

	Oh, please, here we go again with someone else who wants to redefine
C because he wants to take advantage of very specific features of his
machine/environment!  Big deal, so you can do this in a straightforward manner
on your 68020.  I'm just thrilled to pieces for you!  And what happens when
trying to implement C on a machine which doesn't have your spiffy handy-dandy
bitfield instructions?  Two possibilities come to mind:

	1) Implementors do somehow kludge this.  Besides screwing up pointer
format, this causes a lot of code to be generated to emulate your bitfield
instructions.

	2) Implementors do not kludge this.  Now you are stuck with a bunch
of non-portable code.

	Look, it's bad enough that there are those who claim C is just
symbolic PDP-11 assembly language.  Why are you trying to turn it into
symbolic 68020 assembly language?

	Please, please, *PLEASE* remember the philosophy of C is to provide
a small, low-level language which would nonetheless put a lot of power in
the hands of the programmer (and also the other side of the coin, a responsi-
bility to code in a halfway decent style to keep this power from making a
total mess).   As a result, C can be made to run on almost anything.  If you
want a fine example of language design by committee, look at ADA.  It is a
fine language, but also note how difficult it is to implement a compiler and
have it validated.
--------
Kenneth R. Ballou			ARPA:  ballou@brahms
Department of Mathematics		UUCP:  ...!ucbvax!brahms!ballou
University of California
Berkeley, California  94720

karl@haddock.UUCP (12/13/86)

In article <311@bms-at.UUCP> stuart@bms-at.UUCP (Stuart D. Gathman) writes:
>It has been said that bit-field arrays are intrinsically impossible in 'C'
>because there can be no pointers to bit-fields.  [Suggests adding syntax for
>bit pointers and bit arrays.]
>
>The problem comes with 'sizeof'.  What is the size of a bit?

How about 0.125e+0  :-)

>[Options reordered for rebuttal --kwzh]
>3. A third approach is to define the size of a bitfield to be the minimum
>number of standard sizeof units required to store the field.

This would violate the principles that p + n is "really" p + n * sizeof(*p)
and that sizeof(type [N]) == N * sizeof(type).

>2. Another alternative is to make sizeof char == 8, but this would cause
>problems allocating huge arrays with malloc().

Only if the number of addressible bits is greater than LONG_MAX.  Since, on
such an architecture, you already need a super-long datatype to hold a bit
pointer, you might as well also have arithmetic types of that size which
can then be typedef'd to "size_t" and "ptrdiff_t" (unsigned and signed).
(See X3J11 if you don't know what I'm talking about.)  Then the "only" problem
is dealing with the huge bulk of programs that assume sizeof(char)==1.

>1. My first impulse is to disallow 'sizeof' applied to bitfields. (It is not
>allowed now anyway.)

I think that this would be the best initial step.  It would be nice to phase
out the assumption that sizeof(char)==1, but I think that (for this version of
the standard) ANSI had better insist on it, though they may want to mark it as
deprecated.

But before they can remove this assumption, they have to go through all the
functions that mention (or suggest) "bytes" and decide whether they mean
"char" or "quantum of sizeof".  For example, malloc() should probably expect
a bit count (even though it rounds upward for alignment), but what about
fread()?  If it expects a bit count (which is what one would expect, given
that its arg type is "size_t"), what happens if you try to fread() one bit?

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

KJBSF%SLACVM.BITNET@wiscvm.wisc.edu (12/13/86)

Date: 12 December 1986, 13:16:05 PST
From: Kevin J. Burnett          x3330                <KJBSF@SLACVM>
To:   <INFO-C@BRL-SMOKE.ARPA>
Subject: re: bit-field pointers / arrays

<ballou@brahms.ARPA> writes:
>    Oh, please, here we go again with someone else who wants to redefine
>C because he wants to take advantage of very specific features of his
>machine/environment!  Big deal, so you can do this in a straightforward manner
>on your 68020.  I'm just thrilled to pieces for you!  And what happens when
>trying to implement C on a machine which doesn't have your spiffy handy-dandy

I must say that I have found all of your responses recently to be extremely
rude.  Can't you say anything CIVIL when you think that the other person is
obviously some lower form of life?  Your snide comments detract from whatever
arguments you might be making.
    I think you should think a bit more before posting such garbage to the net
again.  Just think about who's on the receiving end of your diatribes.

- Kevin Burnett
SLAC

garry@batcomputer.tn.cornell.edu (Garry Wiegand) (12/13/86)

[cross-posted to comp.lang.misc from comp.lang.c]

In a recent article ballou@brahms (Kenneth R. Ballou) wrote:
>...	Please, please, *PLEASE* remember the philosophy of C is to provide
>a small, low-level language which would nonetheless put a lot of power in
>the hands of the programmer (and also the other side of the coin, a responsi-
>bility to code in a halfway decent style to keep this power from making a
>total mess).   As a result, C can be made to run on almost anything. If you
>want a fine example of language design by committee, look at ADA...

I don't need a committee design, but I do need something better than C (or
"baby" Pascal). I love Simula, but Univacs to run it on are getting hard to 
come by, and a Snobol compiler I haven't seen for years. Lisp has some virtues,
but our version is a pig. C++ makes a good start on being a better language,
but I'm not able to transport it trivially (because the system interface
routines are written in C++) and it's not able to do much with basic things 
like bit arrays (because of the underlying C compiler).

So: what's wrong with wishing the world were a better place, and discussing
what one might want to have in such a place? And given such a discussion,
isn't it reasonable to argue for your pet idea by establishing that it's
at least *sometimes* rationally related to machine architecture? (After
all, isn't it from PDP-11 machine code that our beloved C originally 
acquired "*ptr++" ? :-)

garry wiegand   (garry%cadif-oak@cu-arpa.cs.cornell.edu)

PS - Having munged the primeval Unix C compiler once upon a time to make 
     it produce substantially better code (I got mad at it), I *know* 
     that compiler writers are an inherently lazy lot.

PPS - Wish I could get my hands on the source for the VMS C compiler -
      ach, some of the things it does! - oh, and the BSD one - yuck phooey!

brunner@sri-spam.istc.sri.com (Thomas Eric Brunner) (12/13/86)

In article <1802@batcomputer.tn.cornell.edu> garry%cadif-oak@cu-arpa.cs.cornell.edu writes:
>[cross-posted to comp.lang.misc from comp.lang.c]
>"baby" Pascal). I love Simula, but Univacs to run it on are getting hard to 
>come by, and a Snobol compiler I haven't seen for years. Lisp has some virtues,
>but

Yass! Univacs are getting hard to find. and snobol seems to have passed from 
the keen of some unix vendors. Too bad for their loosers, they've (macho++)
c and (head!) lisp to do their work in, and never the wiser re: simula or
snobol. You know garry, the trendiness of these language processors and their
zelots is awk-ward to grok. No snobol? One wonders why? Real processor readers
need not flame :-).

Oh well, flame me, why not?

-- 
Cheers!  o/
/teb    _0_
.if\\n()t .ds ]D OPEN UNIX CLUB DRAFT 1.0

stuart@bms-at.UUCP (Stuart D. Gathman) (12/14/86)

In article <534@cartan.Berkeley.EDU>, ballou@brahms (Kenneth R. Ballou) writes:

> In article <311@bms-at.UUCP> stuart@bms-at.UUCP (Stuart D. Gathman) writes:

	[ bitfield array proposal deleted, see parent article ]

> 	Oh, please, here we go again with someone else who wants to redefine
> C because he wants to take advantage of very specific features of his
> machine/environment!  Big deal, so you can do this in a straightforward manner
> on your 68020.  I'm just thrilled to pieces for you!  And what happens when
> trying to implement C on a machine which doesn't have your spiffy handy-dandy
> bitfield instructions?  Two possibilities come to mind:

	[ etc, etc ]

As a matter of fact, we do not even have a 68020 machine.  I  was
merely  giving  an  example  for  what  I  assumed  was a popular
processor to illustrate the feasability.  The NEC V20/V30 and the
VAX  are  other processors which I know for a fact have bit field
instructions.  Processors that don't have such nifty instructions
generate  lots  of  code; but ONLY when bitfields are used.  This
happens already now when  using  bitfield  in  structures!   Even
then,  the  compiler probably generates less code than if you did
it yourself using shifts and 'and's.  Furthermore,  the  bitfield
code  is  a  lot more portable than lots of shifts and logic with
the accompanying assumptions regarding byte size, etc.   The  EGA
application  was  just an EXAMPLE (and was labeled as such).  The
primary portable application would be bit arrays.

The operators  in  the  'C'  language  were  designed  to  relect
functions held in common across a wide range of processors.  Many
hardware extensions can be  handled  conveniently  via  functions
(e.g.  vector  processors).   Bit  manipulation is something that
most  modern  processors  can  do  efficiently  with   built   in
instructions,  and  that  any  machine can do just as efficiently
with compiler generated code as with programmer specified  shifts
and  masks.   It  cannot  however be handled well with functions.
Current 'C' *already* has bitfield support.  I am merely throwing
out  the  idea  of rounding  out that support to allow arrays and
pointers as well.
-- 
Stuart D. Gathman	<..!seismo!dgis!bms-at!stuart>

bzs@bu-cs.BU.EDU (Barry Shein) (12/15/86)

What is really being proposed here is a possible code-generation
methodology for bit-level addresses more than an extension of C,
although the proposer alludes to some of that.

Bit pointers etc (or, perhaps better put, variable size byte pointers
where bytes may be any number of bits from 1..wordsize) are well
defined for the PDP-10 architecture, very similar to this proposal (a
two word pointer/struct with offset, byte-size, word-pointer.)

Another approach which perhaps does a better job of showing how to
make arbitrary sized bitfields a full language object can be found in
PL/I where one could define the number of bits in an integer:

	declare foo,goo fixed binary (4);

declares foo and goo to be a 4-bit binary objects which will be
manipulated correctly by various operators (eg. foo+goo will be a
signed result with magnitude +- 7 [3 bits.], unsigned can be handled
as well.) Code will be automatically generated to use the architecture
to accomplish this (be it bit level instructions or lots of ands and
shifts, whatever, that's the compiler writer's problem.)

One could accomplish all this in C without much benefit from the
language or code generator by use of a set of macros or subroutines.

Making bitfields full-blown objects in C would probably be a major
headache for compiler implementors and, I would guess, a never-ending
source of compiler bugs and flames (eg. how do you interpret a one-bit
signed quantity? etc etc.) Before wishing for it, look at the code
generated by a PL/I compiler to manage this type of thing, you'll be
happier with what you have now (the only thing worse than not having
bitfields as full-blown types is having bitfields as full-blown types.)

So, PL/I and Simula come up as objects of nostalgia. Let's not try to
turn C into an object of nostalgia also. Certainly in the case of PL/1
it was precisely all these zillion (+- 10) "features" that caused the
ultimate demise of the language. It is nearly impossible (no, not
nearly, it is impossible...) to understand PL/1's semantics (lessee, I
add a fixed decimal (4,3) to a fixed binary (17) and then multiply by
an array of numeric char strings and suppress the on conversion...  hmm,
that should yield an intermediate result of, well, hmmm ...)

I think we'd be better off thinking about methods to better handle
abstract data types and overloaded operators (a la languages like
ADA and ALGOL68) and thus leave their interpretation in the hands
of the programmer (and his/her real needs) rather than just make a
list of data types which are sometimes useful and try to squeeze
them into C somehow. I believe extensibility is, in the long run,
more useful than specific extensions.

	-Barry Shein, Boston University

gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/15/86)

In article <194@haddock.UUCP> karl@haddock.ISC.COM.UUCP (Karl Heuer) writes:
-I think that this would be the best initial step.  It would be nice to phase
-out the assumption that sizeof(char)==1, but I think that (for this version of
-the standard) ANSI had better insist on it, though they may want to mark it as
-deprecated.
-
-But before they can remove this assumption, they have to go through all the
-functions that mention (or suggest) "bytes" and decide whether they mean
-"char" or "quantum of sizeof".  For example, malloc() should probably expect
-a bit count (even though it rounds upward for alignment), but what about
-fread()?  If it expects a bit count (which is what one would expect, given
-that its arg type is "size_t"), what happens if you try to fread() one bit?

This work has already been done, in document X3J11/86-136R,
although that document does not consider the bit in a bit-field
as the fundamental storage unit but rather proposes (short char),
which may or may not be a single bit as the implementor chooses.

A presentation of the whole multi-storage-unit character issue
is scheduled for the March 1987 X3J11 meeting.  If you have
points you want considered in this regard, please send them to
me (Gwyn@BRL.MIL), since I'll be making the presentation.

greg@utcsri.UUCP (Gregory Smith) (12/15/86)

In article <534@cartan.Berkeley.EDU> ballou@brahms (Kenneth R. Ballou) writes:
>In article <311@bms-at.UUCP> stuart@bms-at.UUCP (Stuart D. Gathman) writes:
>>It  has  been  said  that  bit-field  arrays  are   intrinsically
>>impossible in 'C' because there can be no pointers to bit-fields.
>>
>>There is no special reason why there cannot be a type like:
>>
>>        unsigned *bitptr:1
>>
>>which would likely be bigger than a 'char *'.  Then we could also
>>declare:
>>
>>        unsigned bitarr[5000]:1

>	Oh, please, here we go again with someone else who wants to redefine
>C because he wants to take advantage of very specific features of his
>machine/environment!  Big deal, so you can do this in a straightforward manner
>on your 68020.  I'm just thrilled to pieces for you!  And what happens when
>trying to implement C on a machine which doesn't have your spiffy handy-dandy
>bitfield instructions? 

Mr Ballou's point is well taken, but I have been thinking about this
same problem as it applies to the Texas Instruments 34010. This is a
graphics processor, and it is definitely powerful enough to run C.
However, it is crying out for bitfield addresses and arrays of bitfields;
in fact a 34010 pointer is a bit pointer; to make a char* point to
the next char, the code would add 8 to the bit pattern in the char *.
Furthermore, there are no alignment requirements, and data items of
any size may be read and written.

My question is this: how do you support this through extensions to C?
( I wouldn't expect to port code from a 34010 to anything else).
Writing assembler subtroutines to do the work is obviously a big lose.
There are two fundamental problems:

	(1) how do you declare, say, a 6-bit data type?
	(2) how does sizeof work?

(1) It must be possible to declare signed and unsigned int types,
and specify the number of bits. I'm not sure I like

	unsigned bitarray[10]:3;

since the :3 really should be part of the type-specifier, in order
to allow typedefs to work consistently.

I would suggest
	unsigned bits:3 bitarray[20];

Where the bits keyword is always followed by ': <constant>'. A series
of keywords bit1, bit2.. could be used, but then it would be harder
to parameterize the widths ( and besides you can always typedef bits:2 bit2
if you want that).

As for (2), I would redefine sizeof to return the number of bits in
an object. this gives sizeof(char==8), sacrificing a lot of portability
to Real C, but given the nature of the beast, I wouldn't expect to be
porting a lot of code to it..

Has somebody already implemented such a compiler? how were these problems
dealt with?

-- 
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg
Have vAX, will hack...

throopw@dg_rtp.UUCP (Wayne Throop) (12/16/86)

> stuart@bms-at.UUCP (Stuart D. Gathman)
> It  has  been  said  that  bit-field  arrays  are   intrinsically
> impossible in 'C' because there can be no pointers to bit-fields.

Waitaminut!  Who said that?  I (and the others I've seen) said that
bit-field arrays are impossible in C as C is currently defined, and
pointed out that there are several ways that this notion conflicts with
the current definition of C.  Naturally, if pointers to 1-bit-aligned
chunks of storage are allowed, or if the definition of array
subscripting in terms of pointer arithmetic is changed (and of course,
the syntax of general declarators changed also), then arrays of
bit-fields are possible.

I do wonder about Stuart's proposed syntax for declaring pointers to
bit-fields:

>         unsigned *bitptr:1

How does the bitsize qualifier fit into the general declarator syntax,
prescedence-wise?  If it behaves like the other suffix declarator, [],
then what we have here is a one-bit pointer to an unsigned and ought
really to be (*bitptr):1, whereas the next example:

>         unsigned bitarr[5000]:1

is more reasonable, an array of one-bit unsigned integers.

On the other hand, perhaps Stuart meant the :N to come at the end of the
declaration and refer to the integer type involved, however distant that
is to the :N syntactically and structurally.  I suppose that works, sort
of, and is analogous to how it happens in struct definitions.

I emphasize: I don't say that defining some C-like language with these
features is bad.  It is just far, far outside the scope of the current
X3J11 effort.

--
Like punning, programming is a play on words.
                                --- Alan J. Perlis
-- 
Wayne Throop      <the-known-world>!mcnc!rti-sel!dg_rtp!throopw

stuart@bms-at.UUCP (Stuart D. Gathman) (12/16/86)

In article <2937@bu-cs.BU.EDU>, bzs@bu-cs.BU.EDU (Barry Shein) writes:

	[ discussion of bit-fields in various languages deleted ]

> One could accomplish all this in C without much benefit from the
> language or code generator by use of a set of macros or subroutines.

	Unfortunately, a set of macros cannot use hardware bit-field
instructions.  Here is a list of processors which I know to have
bit-field instructions that I can't get at from 'C':

	NEC V20, V30
	M68000 & family
	PDP-11	(From previous posting)
	DEC-10, 20
	VAX
	???

Here are processors which do not:

	8088 & kin
	other 8-bits: 6502 8080 etc
	???

My point is that 'C' is efficient because is allows access to most
common processor features through the compiler.  'C' is flexible
because I/O and non-standard hardware features are handled through
libraries.  We are reaching the point where bit-fields are a 
common hardware feature.

> Making bitfields full-blown objects in C would probably be a major
> headache for compiler implementors and, I would guess, a never-ending

I didn't have any trouble creating the macros mentioned earlier.  Therefore
it could not be *that* difficult.  My complaint is that the macros do
not utilize the hardware bitfield instructions.  If your everyday optimizing
compiler can figure out when to use these from a mess of shifts and masks,
then I'll be satisfied.  I think that bitfield arrays might be the easier
approach, however.

A situation similar to this is signed division.  You would gag if you saw the
code required to accomplish an unsigned multiply or divide on our
Series/1 processor; the processor supports signed arithmetic only.  
Nevertheless, a 'C' compiler can code all that stuff for me so that
I don't have to worry about the hardware deficiencies.  I am glad that 'C'
supports unsigned arithmetic; many programs would be a mess of macros
otherwise!  Most processors support unsigned multiply and divide, that
is why 'unsigned' is part of 'C' (as opposed to a macro library).

'C' restricts itself to specifying lowlevel processor functions.  All
other tasks are left to data-types and libraries.  Bit-fields are a
low-level processor function.  Hardware vector units can be handled efficiently
via function calls.  Bit operations are too small for that; a macro
(with shifts and masks) would probably be faster!

	[ plug for overloaded operators deleted ]

I agree heartily!  I can hardly wait till I can code:

	complex a,b;
	. . .
	a += b;

And:

	float x;

	x ^= 5;		/* raise x to the 5'th power */

Plus, how about some APL like code using those vector libraries and
nice readable operators?
-- 
Stuart D. Gathman	<..!seismo!dgis!bms-at!stuart>

faustus@ucbcad.BERKELEY.EDU (Wayne A. Christopher) (12/16/86)

In article <321@bms-at.UUCP>, stuart@bms-at.UUCP (Stuart D. Gathman) writes:
> 	Unfortunately, a set of macros cannot use hardware bit-field
> instructions.

Yes they can: you can always write asm("...").

> Here is a list of processors which I know to have
> bit-field instructions that I can't get at from 'C':
> 
> 	NEC V20, V30
> 	M68000 & family
> 	PDP-11	(From previous posting)
> 	DEC-10, 20
> 	VAX
>
> Here are processors which do not:
> 
> 	8088 & kin
> 	other 8-bits: 6502 8080 etc

You should also include a lot of newer RISC machines in the second category.
These machines don't support unaligned word access or in some cases access to
individual bytes (you have to load the word and extract it).  These machines
certainly aren't going to have "set bit" instructions.  Also, they're
probably going to run faster than the machines with bit instructions, even
for code that uses bitfields.

	Wayne

mayer@rochester.ARPA (Jim Mayer) (12/17/86)

In article <3796@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes:
>My question is this: how do you support this through extensions to C?
>( I wouldn't expect to port code from a 34010 to anything else).
>Writing assembler subtroutines to do the work is obviously a big lose.

I wonder if the "pragma" construct could be used for this.  In particular,
(I don't remember the exact syntax):

	pragma compiler_function(_foo)

would inform the compiler that it was ok to assume a particular definition
for the function "_foo".  In particular, any invocation of "_foo" could
be replaced by inline code using special instructions, etc.   A implementation
of "_foo" is assumed to be part of a library.

If the pragma was not recognized it would be ignored.

The pragma would not apply if "_foo" is not known to the compler, or if
it is used in a context other than an invocation.

This kind of thing does not solve all of Greg's problems, but it does
address the problem of getting access to low level machine operations
without modifying the C language in non-standard ways.  I suspect that
between the use of a mechanism like the one above and the bitfield
constructs that are already in C one could get a lot of work done.
-- 
-- Jim Mayer					Computer Science Department
(arpa) mayer@Rochester.EDU			University of Rochester
(uucp) rochester!mayer				Rochester, New York 14627

henry@utzoo.UUCP (Henry Spencer) (12/19/86)

> Here is a list of processors which I know to have
> bit-field instructions that I can't get at from 'C':
> 
> ...
> 	PDP-11	(From previous posting)

Uh, really?  Funny how I've never noticed them in all my years of PDP-11
programming.  Please identify them by opcode.  A quick look doesn't find
any relevant previous posting.

The 11 does have instructions that one can't get to from C, mostly fairly
useless or ultra-specialized odds and ends, but bit-fields are absent.
The byte is the smallest unit that the 11 architecture is aware of.  (Even
the BCD arithmetic in the grotesque "commercial instruction set", available
as an add-on for a few of the later 11s, wants numbers to begin and end
on byte boundaries.)
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,decvax,pyramid}!utzoo!henry

greg@utcsri.UUCP (Gregory Smith) (12/19/86)

In article <321@bms-at.UUCP> stuart@bms-at.UUCP (Stuart D. Gathman) writes:
>	Unfortunately, a set of macros cannot use hardware bit-field
>instructions.  Here is a list of processors which I know to have
>bit-field instructions that I can't get at from 'C':
...
>	VAX
...
>it could not be *that* difficult.  My complaint is that the macros do
>not utilize the hardware bitfield instructions.  If your everyday optimizing
>compiler can figure out when to use these from a mess of shifts and masks,
>then I'll be satisfied.  I think that bitfield arrays might be the easier
>approach, however.

Let's see:

main(){
	int a,b,c,d;
	register int x,y;
	x = (a>>13) & 15;	/* extract 4 bits */
	b |= 1<<y;		/* set a bit at variable position */
	c &= ~4; c |= y<<2;	/* insert unknown bit at fixed posn */
	d &=~0xf80; d|= y<<7;	/* insert 5 bits at fixed posn */
}
...
extzv	$13,$4,-4(fp),r11	|x = (a>>13) & 15; can't complain
ashl	r10,$1,r0		| 1<<y
bisl2	r0,-8(fp)		| b |= 1<<y
bicl2	$4,-12(fp)		| c ~= ~4
ashl	$2,r10,r0		| y<<2
bisl2	r0,-12(fp)		| c |= y<<2
bicl2	$3968,-16(fp)		| c &= ~0xf80
ashl	$7,r10,r0		| y<<7
bisl2	r0,-16(fp)		| d|=y<<7;

The compiler used a bitfield op only in the first case. I guess the
problem is that the other operations are not easily detectable as
candidates for bitfield instructions, especially when written as
two statements (I tried writing the last as d=(d&~0xf8) | (y<<7)
but it didn't help).

Despite the difficulty, I would prefer that the compiler figures out
when to use these from the mess of shifts and masks, rather than
by adding new types to the language. For one thing, this method
will allow bitfield ops to be used for shifts & masks that were
not specifically intended to operate on bitfields.

If it is that difficult to determine when a bitfield op can be used,
we should be asking why microcode is being wasted on them. (I'm not
sure it is that difficult, and I don't think it is necessarily
wasted).

Note that this solution adds several pages of code to the code
generator only on machines with bitfield ops, while the other solution
adds zillions of semantics checks, and other extra stuff *throughout*
the compiler, to the compiler on *all* machines.

[ these viewpoints may seem contrary to my previous posting re the
  34010. That was a graphics processor, and I was talking about C
  extensions. Here I am talking about general-purpose programming
  where portability is important ]


-- 
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg
Have vAX, will hack...

chris@mimsy.UUCP (Chris Torek) (12/20/86)

In article <3811@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes:
[In response to the allegation that C compilers will not use bit
field instrucitons on Vaxen]

>	x = (a>>13) & 15;	/* extract 4 bits */

compiles to

>extzv	$13,$4,-4(fp),r11	|x = (a>>13) & 15; can't complain

but

>	b |= 1<<y;		/* set a bit at variable position */

becomes

>ashl	r10,$1,r0		| 1<<y
>bisl2	r0,-8(fp)		| b |= 1<<y

rather than `insv r10,$1,$1,-8(fp)' (if I got the argument order
right).

>The compiler used a bitfield op only in the first case. I guess the
>problem is that the other operations are not easily detectable as
>candidates for bitfield instructions, especially when written as
>two statements (I tried writing the last as d=(d&~0xf8) | (y<<7)
>but it didn't help).

The real problem is that insv `clears the condition codes'.  The
bitfield operands are all inserted by the peephole optimiser,
/lib/c2 (at least on a 4BSD Vax, which is what Greg appears to be
using).  There is a section of code in c21.c to use insv that is
commented out with a note to this effect.  c2 could still do the
job if it were a bit smarter, or if it had more help from the
compiler as to which expressions are done for condition codes.

C's existing bitfield support has been called `a botch and a blemish'
(if I recall correctly, this is from DMR himself).  Be that as it
may, any attempt to repair or replace the existing facility is
sufficent change that the language should not then be called `C'.
There are a number of problems with bitfields:  Are they signed?
Unsigned?  Can they span word boundaries?  Can they be larger than
a machine word?  (struct { int i:200; }; is illegal on all compilers
I have used.)  All of these questions must be answered, either with
`yes', `no', or `compiler dependent'; by the time you are done,
you have something that is either slow, insufficient, or unportable.
C opts for the last.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	seismo!mimsy!chris	ARPA/CSNet:	chris@mimsy.umd.edu

bright@dataio.Data-IO.COM (Walter Bright) (12/23/86)

In article <3811@utcsri.UUCP> greg@utcsri.UUCP (Gregory Smith) writes:
>Despite the difficulty, I would prefer that the compiler figures out
>when to use [bitfield opcodes] from the mess of shifts and masks, rather than
>by adding new types to the language. For one thing, this method
>will allow bitfield ops to be used for shifts & masks that were
>not specifically intended to operate on bitfields.
>
>Note that this solution adds several pages of code to the code
>generator only on machines with bitfield ops, while the other solution
>adds zillions of semantics checks, and other extra stuff *throughout*
>the compiler, to the compiler on *all* machines.

Hear, hear! (Actually, the compiler I wrote translates all bitfield
operations into the appropriate shifts and masks. If I ever build a code
generator for a CPU that has bitfield opcodes, I will use them by
recognizing trees of shifts and masks.)

The same argument applies to the register keyword. Tuning a function
with register declarations is non-portable (the code is still portable,
but the tuning is not). I think the compiler should stuff variables
into registers automagically using some reasonable heuristic (many
compilers already do this).

Perhaps the XJ311 committee could be persuaded to make the register
keyword an obscelescent feature?

stuart@bms-at.UUCP (Stuart D. Gathman) (12/24/86)

In article <1170@ucbcad.BERKELEY.EDU>, faustus@ucbcad.BERKELEY.EDU (Wayne A. Christopher) writes:

> In article <321@bms-at.UUCP>, stuart@bms-at.UUCP (Stuart D. Gathman) writes:

> > 	Unfortunately, a set of macros cannot use hardware bit-field
> > instructions.

> Yes they can: you can always write asm("...").

But then the code is no longer portable, unless the macros were defined
as part of the standard library a la longjmp().  I have no objection
to this, but I can't get started on such a package because none of
the 'C' compilers we have used have an 'asm()' directive!  This includes

	SCO & IBM XENIX
	Motorola 6350, 8000, 6600, 2000  (using 68010 & 68020)

Not only that, but I am not sure that such a package would be any
easier to develop or maintain than adding it to the compiler.

BTW, I noticed that 'compress' has asm directives for the VAX.

BTW, another hardware feature that I miss in 'C' is the "carry flag".
In this case, however, the things that it is good for (like multiprecision
arithmetic) are quite naturally defined as functions written in assembler.
There have been some cases however . . .
-- 
Stuart D. Gathman	<..!seismo!dgis!bms-at!stuart>