Page 1 of 2

Bit fields and (very)short integers!

Posted: Tue Apr 20, 2010 12:11 am
by Fred
Why didn't someone tell me about these things?!?! I was reading someone elses firmware code last night (GPL) and saw this :

Code: Select all

	struct s_flags
	{
		unsigned inj_occurred	:1;
		unsigned cranking		:1;
		unsigned running		:1;
		unsigned asc			:1;
		unsigned roc_update		:1;
		unsigned iac_update		:1;
		unsigned iac_reset		:1;
		unsigned cts_update		:1;
	}
And when used they look like this :

Code: Select all

status.flags.inj_occurred = TRUE;
And this :

Code: Select all

if (status.flags.inj_occurred){//Do work}
I'm currently ashamed of and embarrassed by my code. I'll be converting it to use these in the nearish future...

It's night and day better...

THANK YOU cpuTorture!!!

Fred.

Re: Bit fields and (very)short integers!

Posted: Tue Apr 20, 2010 12:15 am
by Fred
Additionally, for shorter than one byte integers nested inside registers this is ideal. You can just use :2 instead and you've got yourself 0 - 3 or :3 for 0 - 7 etc!

Fred.

Re: Bit fields and (very)short integers!

Posted: Tue Apr 20, 2010 12:16 am
by SleepyKeys
Sorry, I do remember bit fields from K&R.

Re: Bit fields and (very)short integers!

Posted: Tue Apr 20, 2010 12:18 am
by SleepyKeys
I wonder if it's as fast though............... with bit fields inorder to "get" a bit from a byte it must do a bit-wise then use that value, not just use the value. What do you think ?

Re: Bit fields and (very)short integers!

Posted: Tue Apr 20, 2010 12:36 am
by Fred
I think it's just going to mask it off as we do manually at the moment.

Each and every time I set a bit, I have to use or or and and a mask. It'll just be doing this behind the scenes. We can write some test code to try it out and compare the binary/assembly, but it'll probably be the same or better. Even if it's worse, it's going to clean up the code no end!

The code above runs on a 2mhz cpu... this guy cares about speed a LOT. So I doubt it's slow for that reason too!

I did try to search for boolean types early on, but I failed to find this, mostly because its not a boolean type, really.

I'm excited about doing the change :-)

Fred.

Re: Bit fields and (very)short integers!

Posted: Tue Apr 20, 2010 2:21 am
by SleepyKeys
Sorry from your first post I thought you were using entire bytes for bits. I should have known better :)

Re: Bit fields and (very)short integers!

Posted: Tue Apr 20, 2010 2:38 am
by Fred
I considered that early on too, but it was a factor of 8 too wasteful LOL :-)

Fred.

Re: Bit fields and (very)short integers!

Posted: Tue Apr 20, 2010 4:07 am
by EssEss
thats the beauty of bitfield .. you lean on the compiler to do all the masking/shifting for you .. but I think each has their place.

'old-school' firmware folks that I know hate them with a passion .. because they 'can't trust the compiler'. When I point out all their masking/shifting screwups, they get even madder .. because they have never been able to point back and show me where the compiler has ever screwed up on me.

I make personal exceptions for clarity, here's an example from some code i just did a couple of days ago. it's for some dead simple pin setup code. this is just for a couple of simple single bit fields in a register (which has more fields) but I want to keep the example short:

#define OUTPUT_BUFFER_ENABLE ( 1 << 10 )
#define OUTPUT_MODE ( 1 << 10 )
#define INPUT_BUFFER_ENABLE ( 1 << 9 )
#define INPUT_MODE ( 1 << 9 )
#define READBACK_ENABLE ( 1 << 9 )

I can construct things like:
func( GPIO | OUTPUT_MODE | READBACK_ENABLE ); // 'descriptive'
vs
func( GPIO | OUTPUT_BUFFER_ENABLE | INPUT_BUFFER_ENABLE ); // 'dry'
which mean the same thing ...

as an alternative, using the bitstruct way, ponder this ... how would you handle r-m-w operations atomically on a register when you had to setup multiple fields (i can give an example of how I would do it) ? sometimes the code gets a bit longer than you anticipated .. but its safer since the compiler is working for you.

I also have some other things I do for multi-bit fields to get some asserts() and 'contract-like' programming into my code .. which all compiles out w/NDEBUG like all of the other asserts.

you MAY also run into ordering issues if you use different compilers within the same platform - its considered a highly unportable construct to be using .. so do you trade the danger of shifting/masking across platforms or do you just change the ordering of your struct ?? tradeoffs everywhere in C.


did I go way off track on this ? tell me where to expand if you're interested. I can throw in some 'non-sensitive' real world current examples.

Re: Bit fields and (very)short integers!

Posted: Sun May 30, 2010 8:43 pm
by Fred
Hmmmmmmmmmmmmmmmmm

Mask:

Code: Select all

.LSM189:
	ldd	coreStatusA
	anda	#2
	andb	#0
	tbeq	d,.L74
Bitfield:

Code: Select all

.LSM189:
	ldab	coreStatusA+1
	rolb
	ldab	#0
	rolb
	beq	.L74
I'm unsure about the number of bus cycles those intructions take, but assuming its 1 each or equal between the two, bitfields are slower and regardless they are definitely bigger :-/

Code: Select all

fred@roadeee [07:39:54]:src$ l masks/firmware/
total 900
-rwxr-xr-x 1 fred fred 150742 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-LT1-360-8.s19
-rwxr-xr-x 1 fred fred 150622 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-MiataNB.s19
-rwxr-xr-x 1 fred fred 151860 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-MissingTeeth.s19
-rwxr-xr-x 1 fred fred 153666 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-NipponDenso.s19
-rwxr-xr-x 1 fred fred 152220 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-Simple.s19
-rwxr-xr-x 1 fred fred 150622 2010-05-30 21:31 freeems-0.1.1-SNAPSHOT-Subaru-36-2-2-2.s19
fred@roadeee [07:39:55]:src$ l bitfield/firmware/
total 900
-rwxr-xr-x 1 fred fred 150768 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-LT1-360-8.s19
-rwxr-xr-x 1 fred fred 150634 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-MiataNB.s19
-rwxr-xr-x 1 fred fred 151872 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-MissingTeeth.s19
-rwxr-xr-x 1 fred fred 153754 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-NipponDenso.s19
-rwxr-xr-x 1 fred fred 152232 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-Simple.s19
-rwxr-xr-x 1 fred fred 150634 2010-05-30 21:09 freeems-0.1.1-SNAPSHOT-Subaru-36-2-2-2.s19
Granted, not much, but still...

A bit disappointing :-/

Fred.

Re: Bit fields and (very)short integers!

Posted: Sun May 30, 2010 8:53 pm
by EssEss
Every single platform I've written to it always comes out bigger ... except for one .. if was on 8051. Mostly, I think its an optimization issue and the '51 compiler devs probably put the extra effort in to ensure it was still efficient.
I bet if you targeted a platform like ia32 .. someone has put the effort into the gcc optimizer.