First, I am using 7.5 so it is an old compiler, but that is the way it is.
I have a number of bit variables that I am trying to pack into a byte. they are scattered all across the bit area
volatile bit var1; volatile bit var2; volatile bit var3;
char result;
The compiler won't let me do
result= (var1 <<1) | (var2 <<2) | (var3 <<4); the only way I have been able to get this to work is result= var1; result= ((((result << 1) | var2)<<1) | var3)<<1); This results in very inefficient code mov a,result mov r7,a mov c,v2 clr a rlc A orl A,R7; add A,ACC mov a,r7 mov c,var3 rlc A orl A,R7 add A,ACC mov a,r7 etc. as compared to: mov A,result mov c,v2 rlc a mov c,v3 rlc a would be much better. Does anyone know how this might be forced in C, without resorting to assembly? I'm wondering if because the ACC and PSW are evenly divisible by 8, whether or not you can use those and explicitly use the _crol_ intrinsic to accomplish this. I have not had any luck so far. In this case memory efficiency is more important than speed.
bdata unsigned char sample_result = 0; sbit var1 = sample_result ^ 0; sbit var2 = sample_result ^ 1; sbit var3 = sample_result ^ 2; main () { var1 = 0; var2 = 1; var3 = 1; sample_result = 0xFFu;
Generated code:
79: var1 = 0; C:0x070D C200 CLR var1(0x20.0) 80: var2 = 1; C:0x070F D201 SETB var2(0x20.1) 81: var3 = 1; 82: C:0x0711 D202 SETB var3(0x20.2) 83: sample_result = 0xFFu; 84: C:0x0713 7520FF MOV sample_result(0x20),#0xFF
bdata unsigned char sample_result = 0;
sbit var1 = sample_result ^ 0; sbit var2 = sample_result ^ 1; sbit var3 = sample_result ^ 2; volatile bit source_bit;
main () { var1 = 0; var2 = 1; var3 = 1;
sample_result=0xFF;
This is not what I am trying to accomplish.
The desired result is to PACK the 3 bits into positions in the result, which will be a bit mapped representation of the various bits scattered throughout bit (bdata) memory.
So if V1 =1; V2=0;v3=0 then result would be b00000100 or 0x04. so assigning sample_result = 0xFF would defeat the purpose.
I have about 17 bits free, so I tried it and it....
WORKS LIKE A BOSS! VERY nice. Thank you. generates a set of Var1=source_bit; mov c,source_bit mov (sample_result.0),c cut generated code down from x1B6 to x153 bytes. very significant savings.
"That's what bdata was invented for"
Yes, bdata is nice. But the question is if any C sequences will make the compiler itself make use of the concept with an intermediate variable, instead of forcing the developer to explicitly create a bdata tmp variable + 8 overlapping sbit variables.
Such as if any code sequence could get the compiler to make use of the accumulator, which just happens to be both bit and byte addressable - but which doesn't require the consumption of 8 dummy bits.
But maybe the Keil compiler has no such optimization rule, in which case it isn't possible to find any "magic" C sequence that will make the compiler in the background make a byte clear, multiple bit assigns and then store a byte to the final target address. Such an optimization rule would allow efficient bit packing to happen even for bytes that doesn't fit in bdata, without #define macros to hide all the sub-steps of the computation/assign.
By the way - it's rather brilliant how newer ARM Cortex chips emulates the bdata concept outside of the core in a language-neutral way.
cut generated code down from x1B6 to x153 bytes. very significant savings.
How much of that sentence would be appreciated by one of the multitude of C# fraternity?
Luv it :)
View all questions in Keil forum