Ralph Doncaster schrieb:
I wrote a small function to convert u8 to hex: // converts 4-bit nibble to ascii hex uint8_t nibbletohex(uint8_t value) { if ( value > 9 ) value += 'A' - '0'; return value + '0'; }// returns value as 2 ascii characters in a 16-bit int uint16_t u8tohex(uint8_t value) { uint16_t hexdigits; uint8_t hidigit = (value >> 4); hexdigits = (nibbletohex(hidigit) << 8); uint8_t lodigit = (value & 0x0F); hexdigits |= nibbletohex(lodigit); return hexdigits; } I compiled it with avr-gcc -Os using 4.8 and 5.1 and got the same code: 0000007a <u8tohex.1416>: 7a: 28 2f mov r18, r24 7c: 22 95 swap r18 7e: 2f 70 andi r18, 0x0F ; 15 80: 2a 30 cpi r18, 0x0A ; 10 82: 08 f0 brcs .+2 ; 0x86 <u8tohex.1416+0xc> 84: 2f 5e subi r18, 0xEF ; 239 86: 20 5d subi r18, 0xD0 ; 208 88: 30 e0 ldi r19, 0x00 ; 0 8a: 32 2f mov r19, r18 8c: 22 27 eor r18, r18 8e: 8f 70 andi r24, 0x0F ; 15 90: 8a 30 cpi r24, 0x0A ; 10 92: 08 f0 brcs .+2 ; 0x96 <u8tohex.1416+0x1c> 94: 8f 5e subi r24, 0xEF ; 239 96: 80 5d subi r24, 0xD0 ; 208 98: a9 01 movw r20, r18 9a: 48 2b or r20, r24 9c: ca 01 movw r24, r20 9e: 08 95 ret There's some completely pointless code there, like loading 0 to r19 and immediately overwriting it with the contents of r18 (88, 8a). Other register use is convoluted. The compiler should at least be able to generate the following code (5 fewer instructions): 28 2f mov r18, r24 22 95 swap r18 2f 70 andi r18, 0x0F ; 15 2a 30 cpi r18, 0x0A ; 10 08 f0 brcs .+2 ; 0x86 <u8tohex.1416+0xc> 2f 5e subi r18, 0xEF ; 239 20 5d subi r18, 0xD0 ; 208 32 2f mov r25, r18 8f 70 andi r24, 0x0F ; 15 8a 30 cpi r24, 0x0A ; 10 08 f0 brcs .+2 ; 0x96 <u8tohex.1416+0x1c> 8f 5e subi r24, 0xEF ; 239 80 5d subi r24, 0xD0 ; 208 08 95 ret
Looks like PR41076
