473,397 Members | 2,099 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

Bitfields in a heterogenous environment

I am looking for opinions on a possible approach to coping with
bitfields in a heterogenous environment.

We've got a bunch of legacy code which maps to hardware using
bitfields. The code was developed for a PowerPC/VxWorks/Tornado
enviromant, with the bits packed in a big-endian manner: msb first. We
now have to develop an Intel/Windows/MSVC++ version (lsb assigned
first) which must maintain compatibility with the hardware interface
and use the same source for manipulating the related bitfields. So
discussion of better approaches than using bitfields is moot.

I am considering the following approach to minimize impact to the
legacy code. It uses nested macro calls to define the bitfields in
forward or reverse order according to the environment:

#ifdef BITFIELDS_LITTLE_ENDIAN
#define DEFINE_BITFIELDS_MSB_FIRST(A,B) B A
#else
#define DEFINE_BITFIELDS_MSB_FIRST(A,B) A B
#endif

struct bitfield_struct
{
DEFINE_BITFIELDS_MSB_FIRST( int bit31 : 1; ,
DEFINE_BITFIELDS_MSB_FIRST( int bit20_30 : 11; ,
DEFINE_BITFIELDS_MSB_FIRST( int bit10_19 : 10; ,
DEFINE_BITFIELDS_MSB_FIRST( int bit1_9 : 9; ,
int bit0 : 1;
))))
};

The preprocessor generates the following if BITFIELDS_LITTLE_ENDIAN is
defined:

struct bitfield_struct
{

int bit0 : 1; int bit1_9 : 9; int bit10_19 : 10; int bit20_30 : 11; int
bit31 : 1;
};

or otherwise,

struct bitfield_struct
{

int bit31 : 1; int bit20_30 : 11; int bit10_19 : 10; int bit1_9 : 9;
int bit0 : 1;
};

Of course, we will have to be careful to fill every bit position. We
will nest the calls to define exactly 32 bits worth at a time, so the
maximum nesting of the macro calls would be 32. We will also have to
put up with the collapse of multiple lines of code into a single line
for compiler error reporting and during debug.

If we are to avoid touching bitfield-processing code, the only other
option we have identified is to define the structures twice:

#ifdef BITFIELDS_LITTLE_ENDIAN
struct bitfield_struct
{
int bit0 : 1;
int bit1_9 : 9;
int bit10_19 : 10;
int bit20_30 : 11;
int bit31 : 1;
};
#else
struct bitfield_struct
{
int bit31 : 1;
int bit20_30 : 11;
int bit10_19 : 10;
int bit1_9 : 9;
int bit0 : 1;
};
#endif

I like the nested-macro approach because we only code the idea of the
hardware bit map once and inserting "DEFINE_BITFIELDS_MSB_FIRST(" in
front of the existing structures seems less error prone than trying to
manually invert the order of definition. I was surprised to not find
anything similar in previous discussions here and am wondering if it
has any drawbacks I have not considered. If it helps to focus the
discussion, we have no plans to go beyond the current 32-bit PowerPC
and Intel architectures, though we might migrate the Intel platform
from Windows/MSVC++ to Linux/gcc some day. We have 2000+ bitfield
definitions to cope with.

I look forward to your (constructive!) comments.

-Galen

Nov 14 '05 #1
6 2658
"GalenTX" <gb******@kannarr.tuffmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
I am looking for opinions on a possible approach to coping with
bitfields in a heterogenous environment.

We've got a bunch of legacy code which maps to hardware using
bitfields. The code was developed for a PowerPC/VxWorks/Tornado
enviromant, with the bits packed in a big-endian manner: msb first. We
now have to develop an Intel/Windows/MSVC++ version (lsb assigned
first) which must maintain compatibility with the hardware interface
and use the same source for manipulating the related bitfields. So
discussion of better approaches than using bitfields is moot.
Well then, you're stuck with poorly implemented legacy code.
You should've used bit masking at the byte level to have a chance
at portability to other hardware (at least where CHAR_BIT is
same).
I am considering the following approach to minimize impact to the
legacy code. It uses nested macro calls to define the bitfields in
forward or reverse order according to the environment:
Since you're planning on editing every header file to
insert the macros, maybe you should take the next step
and just convert the code to use masking. Masking is
easy to understand, easy to maintain.
#ifdef BITFIELDS_LITTLE_ENDIAN
#define DEFINE_BITFIELDS_MSB_FIRST(A,B) B A
#else
#define DEFINE_BITFIELDS_MSB_FIRST(A,B) A B
#endif

struct bitfield_struct
{
DEFINE_BITFIELDS_MSB_FIRST( int bit31 : 1; ,
DEFINE_BITFIELDS_MSB_FIRST( int bit20_30 : 11; ,
DEFINE_BITFIELDS_MSB_FIRST( int bit10_19 : 10; ,
DEFINE_BITFIELDS_MSB_FIRST( int bit1_9 : 9; ,
int bit0 : 1;
))))
};

The preprocessor generates the following if BITFIELDS_LITTLE_ENDIAN is
defined:

struct bitfield_struct
{

int bit0 : 1; int bit1_9 : 9; int bit10_19 : 10; int bit20_30 : 11; int
bit31 : 1;
};

or otherwise,

struct bitfield_struct
{

int bit31 : 1; int bit20_30 : 11; int bit10_19 : 10; int bit1_9 : 9;
int bit0 : 1;
};

Of course, we will have to be careful to fill every bit position. We
will nest the calls to define exactly 32 bits worth at a time, so the
maximum nesting of the macro calls would be 32. We will also have to
put up with the collapse of multiple lines of code into a single line
for compiler error reporting and during debug.
Yup, you're asking for even more headaches, than if you
had done it right the first time.
If we are to avoid touching bitfield-processing code, the only other
option we have identified is to define the structures twice:
Bite the bullet NOW. Fix the broken code.
#ifdef BITFIELDS_LITTLE_ENDIAN
struct bitfield_struct
{
int bit0 : 1;
int bit1_9 : 9;
int bit10_19 : 10;
int bit20_30 : 11;
int bit31 : 1;
};
#else
struct bitfield_struct
{
int bit31 : 1;
int bit20_30 : 11;
int bit10_19 : 10;
int bit1_9 : 9;
int bit0 : 1;
};
#endif
Hugely worse; a double-maintenance headache. Your junior
programmers will certainly screw this up.
I like the nested-macro approach because we only code the idea of the
hardware bit map once and inserting "DEFINE_BITFIELDS_MSB_FIRST(" in
front of the existing structures seems less error prone than trying to
manually invert the order of definition. I was surprised to not find
anything similar in previous discussions here and am wondering if it
has any drawbacks I have not considered. If it helps to focus the
discussion, we have no plans to go beyond the current 32-bit PowerPC
and Intel architectures, though we might migrate the Intel platform
from Windows/MSVC++ to Linux/gcc some day. We have 2000+ bitfield
definitions to cope with.

I look forward to your (constructive!) comments.


Good luck, you'll need it!
Nov 14 '05 #2


GalenTX wrote:
I am looking for opinions on a possible approach to coping with
bitfields in a heterogenous environment.

We've got a bunch of legacy code which maps to hardware using
bitfields. The code was developed for a PowerPC/VxWorks/Tornado
enviromant, with the bits packed in a big-endian manner: msb first. We
now have to develop an Intel/Windows/MSVC++ version (lsb assigned
first) which must maintain compatibility with the hardware interface
and use the same source for manipulating the related bitfields. So
discussion of better approaches than using bitfields is moot.

I am considering the following approach to minimize impact to the
legacy code. It uses nested macro calls to define the bitfields in
forward or reverse order according to the environment:

#ifdef BITFIELDS_LITTLE_ENDIAN
#define DEFINE_BITFIELDS_MSB_FIRST(A,B) B A
#else
#define DEFINE_BITFIELDS_MSB_FIRST(A,B) A B
#endif

struct bitfield_struct
{
DEFINE_BITFIELDS_MSB_FIRST( int bit31 : 1; ,
DEFINE_BITFIELDS_MSB_FIRST( int bit20_30 : 11; ,
DEFINE_BITFIELDS_MSB_FIRST( int bit10_19 : 10; ,
DEFINE_BITFIELDS_MSB_FIRST( int bit1_9 : 9; ,
int bit0 : 1;
))))
};
[...]


You seem to have taken care of arranging the bit fields
in the desired order, but what about the individual bits in
multi-bit fields like bit1_9? I'm using "order" rather
loosely here because the bits probably aren't addressable.
What I'm getting at is that if you do `foo.bit1_9 = 5', how
do you know which two bits of the 32-bit (probably) struct
are set?

There's no portable way to be sure of getting the layout
you want, so whatever solution you adopt will be compiler-
(or compilers-) dependent. If you're stuck with bit fields,
all I can suggest is to hack away and hope for the best; the
C language as such is of little help in your predicament.

It occurs to me that there might be a way out of the mess,
depending on how the code is structured. If (*if*) the bulk
of the code deals with bits already read from the hardware or
prepares batches of bits to be written to the hardware, but
the actual reading and writing takes place in relatively few
places, you could just let the structs line up any old way and
provide get() and put() functions that swizzled the bits as
needed, on the fly. That, in fact, is a pretty good model for
all such format-matching tasks: Put the format knowledge in a
few isolated functions and use a "CPU-friendly" representation
elsewhere. Whether your existing code base is organized so as
to make this approach attractive is something you'll need to
judge for yourself.

--
Er*********@sun.com

Nov 14 '05 #3
I don't think the bit-order within individually named bitfields is an
issue. Once accessed by name, they should be converted to an int with
the proper bit order. The issue just occurs with the way the names are
allocated within the comprising int.

We contemplated some bit-swizzling, as you say, but decided that was
going to be much more work and leaves places in your program where the
data in memory is not organized according to the structures you've
defined--always an opportunity for errors. The VxWorks system is an
embedded one, so the hardware interfaces permeate the code.

In defense of the original programmers, some of the code is 10 years
old and it was never envisioned that it would be used in any other
environment. Given the constraint of a static and well-understood
environment, bit-fields make for the clearest code at the point of use.
Bit masking and shifting is absolutely more portable, but even with
macros or functions to hide the complexity, it takes up more visual
space in the application code, which makes it harder to see the real
task at hand.

Nov 14 '05 #4


GalenTX wrote:
I don't think the bit-order within individually named bitfields is an
issue. Once accessed by name, they should be converted to an int with
the proper bit order. The issue just occurs with the way the names are
allocated within the comprising int.


You said the purpose was to match the fields to a
hardware device, which usually means that the order of
all the non-ignored bits is important. If you've got
a bit-order mismatch between the CPU and the device,
you might store 19 = 10011 in a five-bit field and find
that the device understood it as 11001 = 25 instead.
That's a good way to turn a READ SECTOR command into
LOW-LEVEL FORMAT ...

But then, perhaps you're not facing such issues.
If not, fine -- but you're still forced to rely on the
behaviors of the particular compilers you're using, and
not on anything guaranteed by the C language. Good luck!

--
Er*********@sun.com

Nov 14 '05 #5
You're absolutely right, the C language guarantees me nothing here.
But it would seem odd to assign an int to a bitfield and have the
compiler place the bits into the int structure containing the bitfield
in the opposite order that they appear in the int. That would require
bit reversal, which would seem expensive.

I'm not talking about the way the hardware is mapped on the processor
bus. But even there, the hardware guy who wires more significant bits
on the processor to less significant ones on the device is going to be
in trouble. I'm also not talking about byte order, either.
Fortunately, everything we are working with is a uniform byte width and
is read and written in one place in the code, so we have only one place
to verify that byte order is correct.

Again, I think it is a pretty safe bet that bit significance will be
preserved within a bitfield, regardless of the order in which multiple
bitfields are allocated space in an int. At least for the limited set
of compilers I am contemplating, I think I am okay.

Nov 14 '05 #6
Trying to pull the discussion back to the point of my original post, I
need to mention that we am constrained to edit header files only. So,
for better or worse, we're going to have bitfields, the only question
is how we go about defining the structure.

Does anybody see any problem with my preferred approach, the nested
macro calls? The alternative, to define the structures twice while
inverting the order manually, seems more error prone in initial
implementation seems to pose a higher maintenance cost.

By the way, can anyone suggest a better name for the macro? I'm not
entirely happy with DEFINE_BITFIELDS_MSB_FIRST.

-Galen

Nov 14 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Grumfish | last post by:
In order to familiarize my self with Flash files and their bytecode I've started to make an assembler. My first problem is writing the bitfields the format uses often. It is a series of fields,...
3
by: Jon Slaughter | last post by:
I'm using bit fields to compactly represent some data I need to manage and I've read that they are not portable. I don't understand why that is the case? As long as I don't "indirectly" mess with...
0
by: tmartsum | last post by:
I have a discussion in comp.std.c++ After a (bit stupid) suggestion on representing a fixed 'big' length int I moderated it to "Bitfields-ints should be allowed to have any fixed length" I...
8
by: Régis Troadec | last post by:
Hi all, I follow c.l.c. for only a short time and I would like to know why there isn't anything concerning bitfields among the FAQs. Is it because ... 1. of portability issues? 2. bitfields...
23
by: rohit | last post by:
Hi, In my couple of years of experience, I have never found a single instance where I needed to use unions and bitfields(though I have used structures).I was just imagining where would these find...
19
by: Mehta Shailendrakumar | last post by:
Hi, I would like to know why array of bitfields is not possible. Is there any relation with processor architecture for this? Thank you for your time. Regards, Shailendra
18
by: richard_l | last post by:
Hello All, I am writing an application which receives a word which is a bitmap. I have created a word typedef which contains a bitfield defining each bit. however, I was wondering however if it...
9
by: cman | last post by:
Who can explain to me what bitfields are and how to use them in practice? I would need a fairly detailed explaination, I would be a newbie to advanced C programming features. What are the...
10
by: lithiumcat | last post by:
Hi, This question seems to come up quite often, however I haven't managed to find an answer relevant to my case. I often use binary flags, and I have alaways used a "bitmask" technique, that...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.