Hello All,
I'm using msp430-gcc 3.2.2, which upto now worked fine, but is giving me
strange behaviour now. The following code (which when compiled identically for
the PC works perfectly), produces incorrect results when compiled by msp430-gcc
-O2:
#define GETBIT(d,n) (((d)>>(n))&1)
// calculates 4 parity bits for (8,12) hamming
unsigned char hamming_parity(unsigned char d)
{
unsigned char HP1,HP2,HP3,HP4;
// calculate parity bits
HP1 = GETBIT(d,0) ^ GETBIT(d,1) ^ GETBIT(d,3) ^ GETBIT(d,4) ^ GETBIT(d,6);
HP2 = GETBIT(d,0) ^ GETBIT(d,2) ^ GETBIT(d,3) ^ GETBIT(d,5) ^ GETBIT(d,6);
HP3 = GETBIT(d,1) ^ GETBIT(d,2) ^ GETBIT(d,3) ^ GETBIT(d,7);
HP4 = GETBIT(d,4) ^ GETBIT(d,5) ^ GETBIT(d,6) ^ GETBIT(d,7);
// combine into parity nibble
return (HP4<<3)|(HP3<<2)|(HP2<<1)|HP1;
}
For example, for an input of d=0x05 it should produce parity bits 0x05, but
instead it produces 0x09. When I look at the disassembly it says this:
00003072 <hamming_parity>:
*/
// calculates 4 parity bits for (8,12) hamming
unsigned char hamming_parity(unsigned char d)
{
3072: 0b 12 push r11 ;
3074: 0a 12 push r10 ;
3076: 09 12 push r9 ;
3078: 08 12 push r8 ;
307a: 07 12 push r7 ;
unsigned char HP1,HP2,HP3,HP4;
// calculate parity bits
HP1 = GETBIT(d,0) ^ GETBIT(d,1) ^ GETBIT(d,3) ^ GETBIT(d,4) ^
GETBIT(d,6);
307c: 4c 4f mov.b r15, r12 ;
307e: 5c f3 and.b #1, r12 ;subst r3 with
As==01
3080: 5f b3 bit.b #1, r15 ;subst r3 with
As==01
3082: 4d 43 clr.b r13 ;
3084: 4d 63 adc.b r13 ;
3086: 48 4c mov.b r12, r8 ;
3088: 48 ed xor.b r13, r8 ;
308a: 7f b0 03 00 bit.b #3, r15 ;#0x0003
308e: 4b 43 clr.b r11 ;
3090: 4b 63 adc.b r11 ;
3092: 48 eb xor.b r11, r8 ;
3094: 6f b2 bit.b #4, r15 ;subst r2 with
As==10
3096: 4e 43 clr.b r14 ;
3098: 4e 63 adc.b r14 ;
309a: 48 ee xor.b r14, r8 ;
309c: 7f b0 06 00 bit.b #6, r15 ;#0x0006
30a0: 4a 43 clr.b r10 ;
30a2: 4a 63 adc.b r10 ;
30a4: 48 ea xor.b r10, r8 ;
HP2 = GETBIT(d,0) ^ GETBIT(d,2) ^ GETBIT(d,3) ^ GETBIT(d,5) ^
GETBIT(d,6);
30a6: 6f b3 bit.b #2, r15 ;subst r3 with
As==10
30a8: 49 43 clr.b r9 ;
30aa: 49 63 adc.b r9 ;
30ac: 4c e9 xor.b r9, r12 ;
30ae: 4c eb xor.b r11, r12 ;
30b0: 7f b0 05 00 bit.b #5, r15 ;#0x0005
30b4: 47 43 clr.b r7 ;
30b6: 47 63 adc.b r7 ;
30b8: 4c e7 xor.b r7, r12 ;
30ba: 4c ea xor.b r10, r12 ;
HP3 = GETBIT(d,1) ^ GETBIT(d,2) ^ GETBIT(d,3) ^ GETBIT(d,7);
30bc: 4d e9 xor.b r9, r13 ;
30be: 4d eb xor.b r11, r13 ;
30c0: 4f 5f rla.b r15 ;
30c2: 4f 43 clr.b r15 ;
30c4: 4f 6f rlc.b r15 ;
30c6: 4d ef xor.b r15, r13 ;
HP4 = GETBIT(d,4) ^ GETBIT(d,5) ^ GETBIT(d,6) ^ GETBIT(d,7);
30c8: 4e e7 xor.b r7, r14 ;
30ca: 4e ea xor.b r10, r14 ;
30cc: 4e ef xor.b r15, r14 ;
// combine into parity nibble
return (HP4<<3)|(HP3<<2)|(HP2<<1)|HP1;
30ce: 7e f3 and.b #-1, r14 ;subst r3 with
As==11
30d0: 0e 5e rla r14 ;
30d2: 0e 5e rla r14 ;
30d4: 0e 5e rla r14 ;
30d6: 4f 4d mov.b r13, r15 ;
30d8: 0f 5f rla r15 ;
30da: 0f 5f rla r15 ;
30dc: 4e df bis.b r15, r14 ;
30de: 4f 4c mov.b r12, r15 ;
30e0: 0f 5f rla r15 ;
30e2: 4e df bis.b r15, r14 ;
30e4: 4e d8 bis.b r8, r14 ;
30e6: 4f 4e mov.b r14, r15 ;
}
30e8: 37 41 pop r7 ;
30ea: 38 41 pop r8 ;
30ec: 39 41 pop r9 ;
30ee: 3a 41 pop r10 ;
30f0: 3b 41 pop r11 ;
30f2: 30 41 ret
Maybe I'm missing something, but those bit.b instructions look messed up to
me... e.g. to get bit #3 in the carry flag shouldn't it be
bit.b #8, r15
instead of:
bit.b #3, r15
???
greetings,
Tom