Re: Help with cross-endian bitfields?

2 messages, 2 authors, 2000-05-08 · open the first message on its own page

Re: Help with cross-endian bitfields?

From: D.J. Barrow <hidden>
Date: 2000-05-08 10:13:31

If you are using gcc using __attribute__(packed)
may help otherwise the compiler may optimise alignment
info gcc for more info.
struct blah
{
   uchar a : 3;
   uchar b : 3;
   uchar c : 2;
} __attribute__(packed);

to pack the array it also would be more correct to
use unsigned as opposed to uchar.

struct blah
{
   unsigned a : 3;
   unsigned b : 3;
   unsigned c : 2;
} __attribute__(packed);

I personally would be expecting to use ((*((u8
*)&blah[0]))&0x0e0)>>5 to get the info from blah.a on
both little & big endian machines.


--- Daniel Jacobowitz <drow@false.org> wrote:
On Fri, May 05, 2000 at 03:27:21PM -0400,
jlquinn@us.ibm.com wrote:
quoted
Hi, all.  I'm working on getting the Advansys
driver working and what
quoted
appears to be the final stumbling block is a
difference in the layout of
quoted
bitfields between little-endian and big-endian
systems.  In particular,
quoted
there are structs like the following:

struct blah {
  uchar a : 3;
  uchar b : 3;
  uchar c : 2;
}

On a little endian machine, this works like I
expect.  (blah & 0x07) ==
quoted
blah.a is true.  On linuxppc (and apparently MacOS
as well), this is NOT
quoted
true.  blah.a refers to the 3 most significant
bits.  The linuxppc behavior
quoted
seems counterintuitive to me because I expected
each successive member in a
quoted
struct to be the next physical piece of data I
encounter.
quoted
Can someone tell me what's going on here?  Am I
going to have to have
quoted
ifdef's on these structs, or resort to mask
macros, or is there a
quoted
reasonable solution here.
As Dan Malek said, there is no defined ordering.
The compiler is free
to do whatever it wishes.  You can't assume that.
(I think.)

Also, by your intuition, the obvious thing IS
happening.  Remember that
we are big-endian - the first thing in memory is
big-endian.  Thus, it
follows logically that a should be in the first
three (most
significant) bits.

Dan

/--------------------------------\
/--------------------------------\
|       Daniel Jacobowitz        |__|        SCS
Class of 2002       |
|   Debian GNU/Linux Developer    __    Carnegie
Mellon University   |
|         dan@debian.org         |  |
dmj+@andrew.cmu.edu      |
\--------------------------------/
\--------------------------------/
=====
D.J. Barrow Linux for S/390 kernel developer
eMail: djbarrow@de.ibm.com,barrow_dj@yahoo.com
Phone: +49-(0)7031-16-2583
IBM Germany Lab, Sch�naicherstr. 220, 71032 B�blingen


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

Re: Help with cross-endian bitfields?

From: Geert Uytterhoeven <geert@linux-m68k.org>
Date: 2000-05-08 14:19:59

On Mon, 8 May 2000, D.J. Barrow wrote:
struct blah
{
   unsigned a : 3;
   unsigned b : 3;
   unsigned c : 2;
} __attribute__(packed);

I personally would be expecting to use ((*((u8
*)&blah[0]))&0x0e0)>>5 to get the info from blah.a on
both little & big endian machines.
Which no longer works if a is longer than 8 bits and/or spans multiple bytes.
For PCI accesses, you can work around this by using {read,write}l(), which do
byte swapping on big-endian platforms as well.

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- Linux/{m68k~Amiga,PPC~CHRP} -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help