arduino / Arduino

Arduino IDE 1.x
https://www.arduino.cc/en/software
Other
14.18k stars 7.01k forks source link

>> operator expands 8bit value to 16bit by padding zero in the high byte before shifting on 8bit AVR #11965

Closed PeterW-avr closed 4 months ago

PeterW-avr commented 4 months ago

IDE 1.8.19 avr-gcc 7.3.0, Flags: -Os -mmcu:atmega328p -std:gnu11++

(uint8_t)~PIND >>4 or ((uint8_t)~PIND) >>4 will result in following assembly code: A single byte is read from the I/O port, then padded with zero to 16 bit value, finally shift-rotated right in loop of 4 cycle.

608: 89 b1 in r24, 0x09 ; 9 60a: 80 95 com r24 60c: 90 e0 ldi r25, 0x00 ; 0 ----> unnecessay 60e: 24 e0 ldi r18, 0x04 ; 4 610: 95 95 asr r25 --------------> unnecessary 612: 87 95 ror r24 --------------> should be: asr r24 614: 2a 95 dec r18 616: e1 f7 brne .-8 ; 0x610

PeterW-avr commented 4 months ago

Better optimization in avr-gcc 10 and higher: Shift respects the type.

    in r24,0x10
    com r24
    swap r24
    andi r24,lo8(15)
PeterW-avr commented 4 months ago

This optimization can still be accomplished in avr-gcc 7.3.0 by utilizing XOR and division:

(PIND^0xFF)/16

    com r24
    swap r24
    andi r24,lo8(15)