I'm looking to optimize this function:
// Add signed to unsigned using saturation, return unsigned uint8_t addwsat(uint8_t a, int8_t b) { if(b>=0) { if(a>255-b) return 255; } else { if(a<(-b)) return 0; } return a+b; }
which the compilers converts to:
uint8_t addwsat(uint8_t a, int8_t b) { MOV R23,R24 Copy register MOV R20,R24 Copy register LDI R21,0x00 Load immediate MOV R18,R22 Copy register CLR R19 Clear Register SBRC R18,7 Skip if bit in register cleared LAT R19 Load and Toggle if(b>=0) { SBRC R22,7 Skip if bit in register cleared RJMP PC+0x000A Relative jump if(a>255-b) return 255; SER R24 Set Register LDI R25,0x00 Load immediate SUB R24,R18 Subtract without carry SBC R25,R19 Subtract with carry CP R24,R20 Compare CPC R25,R21 Compare with carry BRGE PC+0x0C Branch if greater or equal, signed SER R24 Set Register RET Subroutine return if(a<(-b)) return 0; CLR R24 Clear Register CLR R25 Clear Register SUB R24,R18 Subtract without carry SBC R25,R19 Subtract with carry CP R20,R24 Compare CPC R21,R25 Compare with carry BRGE PC+0x03 Branch if greater or equal, signed LDI R24,0x00 Load immediate RET Subroutine return return a+b; MOV R24,R22 Copy register ADD R24,R23 Add without carry } RET Subroutine return
I'm convinced that there is a more optimum way to achieve the same result. Any suggestions?