Subject: Re: Bitfields and kernel
To: None <>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-kern
Date: 09/30/1999 16:38:28
>>> reg_msr_t msr;
>>> msr.pow = 1;
>>> msr.ile = 0;

>> The biggest problem with this, aside from the nonportability various
>> people have commented on, is that it becomes impossible to
>> manipulate multiple bits at the same time.  This can be important
>> for setting and clearing bits and can be useful when testing bits.

> For setting multiple bits, using bitfields will work, and gcc
> optimizes it as tight as any hand-coded or (1<<30)|(1<<25) code

Not if the variable is volatile - or rather, if it does in that case
then it's broken.  (Granted, this matters comparatively seldom.)

Also, your claim is false on the SPARC, at least in a small test I just

	struct foo {
	  unsigned int a : 1;
	  unsigned int b : 1;
	  unsigned int c : 1;
	  } ;
	struct foo *fp;
	void setfoo(void);
	void setfoo(void)
	 fp->a = 1;
	 fp->b = 1;

Using -S -O99, I got assembly code the core of which was

        ld [%o0],%g2
        sethi %hi(-2147483648),%g3
        or %g2,%g3,%g2
        sethi %hi(1073741824),%g3
        or %g2,%g3,%g2
        st %g2,[%o0]

where there's no reason at all not to do a single sethi and or.  (This
was with gcc  "Modern" gcc, egcs-1.1.2 it calls itself, does
even worse, doing one ld-modify-st per source-code assignment even with
-O99 and no "volatile".)

>   For testing multiple bits, to me it is more clear to say
> if ((msr.pow == 1) && (msr.ile == 0))
> than
> if ((msr&POW_BIT) && !(msr&ILE_BIT))
> or
> if ((msr&POW_BIT == POW_BIT) && (msr&ILE_BIT == 0))

But what you should be comparing to is

	if ((msr & (POW_BIT|ILE_BIT)) == POW_BIT)

which reads msr only once (semantically significant if msr is volatile
and possibly worth paying attention to as an optimization if it's a
complicated expression).

> It looks like there's no clear consensus :),

Sure does look that way.  Especially since some important aspects vary,
it appears, from architecture to architecture.

					der Mouse

		     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B