I have the simplest code to average two 8bit signed numbers, but it is not working, temp1 and temp3 are declared as uin8_t:

temp1=(uint8_t)((temp1-0x80)>>1)+(((uint8_t)temp3-0x80)>>1); temp1=temp1-0x80;

which translates to:

369:temp1=(uint8_t)((temp1-0x80)>>1)+(((uint8_t)temp3-0x80)>>1); MOV R24,R7 Copy register LDI R25,0x00 Load immediate SUBI R24,0x80 Subtract immediate SBCI R25,0x00 Subtract immediate with carry ASR R25 Arithmetic shift right ROR R24 Rotate right through carry LDI R27,0x80 Load immediate MOV R7,R27 Copy register ADD R7,R24 Add without carry 370:temp1=temp1-0x80; MOVW R30,R12 Copy register pair LDD R24,Z+0 Load indirect with displacement LDI R25,0x00 Load immediate SUBI R24,0x80 Subtract immediate SBCI R25,0x00 Subtract immediate with carry ASR R25 Arithmetic shift right ROR R24 Rotate right through carry ADD R7,R24 Add without carry

But what I really want the compiler to do is this:

subi R24, 0x80 ; Transform [0x80, 0x7f] -> [0x00, 0xff] lsr R24 ; Divide by 2 subi R22, 0x80 ; Transform [0x80, 0x7f] -> [0x00, 0xff] lsr r22 ; Divide by 2 add R24, R22 ; Add subi R24, 0x80 ; Transform [0x00, 0xff] -> [0x80, 0x7f]

Besides generating inefficient code, the C code also gives bad results with certain values, like adding -1 and 0.

About the averaging method itself, I know I am discarding the LSB from both operands, but this is not important.