We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I have to count modified bits in a volatile 32 bit data word.Example:Initial counter32[32] := 0; olddata := 0x00000010; newdata := 0x0000000001;So we have moddata := newdata xor olddata => moddata := 00000011.So bit0 and bit1 have changed.Now I would have counter[1]++ and counter[0]++;How this can be done on a Cortex-M0+ fastes way?Best regards Juergen
int popcount32(uint32_t x) { x -= ((x >> 1) & 0x55555555); x = (x & 0x33333333) + ((x >> 2) & 0x33333333); x = (x + (x >> 4)) & 0x0F0F0F0F; x += (x >> 8); x += (x >> 16); return x & 0x0000003F; } printf("%d\n", popcount32(x ^ y));
I think this is a workable CM0 assembler version
pop32 PROC EXPORT pop32 ldr r1, =0x55555555 lsrs r2, r0, #1 ands r1, r2 subs r0, r1 ldr r1, =0x33333333 lsrs r2, r0, #2 ands r0, r1 ands r2, r1 adds r0, r2 lsrs r1, r0, #4 ldr r2, =0x0F0F0F0F adds r0, r1 ands r0, r2 lsrs r1, r0, #8 adds r0, r1 lsrs r1, r0, #16 adds r0, r1 movs r1, #0x3f ands r0, r1 bx lr ENDP
Sorry for not (yet) understanding your solution.What is x? What is y?Have to count changed bits.So I have an array of 32 counters (uint32_t counter32 [32];).In my example bit0 and bit1 have changed, so counter32[0] and counter32[1] should be incremented.the result of your popcount32() is something between 0 and 63...Best regardsJuergen
The problem here was that your task description was insufficiently clear. "Pier"'s reply counts bits the way most people would take "count the bits" to mean. You mean something quite different.
So bit0 and bit1 have changed.Now I would have counter[1]++ and counter[0]++;Sorry for that, ok, I try again…I have to count bit changes in a 32bit data word, separated for each bit.Therefore I have 32 distinct counters in an array named counter32[32].
counter32[0] counts bit changes of bit0, counter32[1] counts bit changes of bit1, and so on.Every time a bit changes, its counter should be incremented.olddata := 0x00000002; newdata := 0x00000001;olddata ^ newdata gives 0x00000011, so two bits changed.Here two bits have changed, bit0 and bit1, so counter32[0]++ and counter32[1]++
Best regardsJuergen
I think something like this.But this is tooo slow for our needs and I have no knowledge of ARM Assembler...MCU is a STM32G0 with Cortex-M0+.
uint32_t counter32[32]; olddata = 0x00000001U; newdata = 0x00000002U; void CountBits(uint32_t old, uint32_t new) { uint32_t x; uint32_t mask = 0x00000001U; int i; x = old ^ new; // x == 0x00000003 for (i = 0; i < 32; i++) { if (x & mask) counter[i]++; mask <<= 1; } } void main (void) { CountBits (olddata, newdata); }