On sdcc version: 3.4.0 #8981 (May 19 2014) (Linux)
(given by sdcc --version)
Compilation command:
~~~~~~ :::bash
sdcc -mpic14 -p16f684 --std-sdcc99 --opt-code-size --use-non-free -c <file.c></file.c>
Code:
~~~~~~ :::c
#define __16F684
#include <pic16f684.h>
int main() {
unsigned z = PORTC;
PORTA = 2 * z;
while(1);
}
We obtain this asm code:
~~~~~~ :::asm
main ;Function start
; 2 exit points
; .line 6; "test.c" unsigned z = PORTC;
BANKSEL _PORTC
MOVF _PORTC,W
BANKSEL r0x1002
MOVWF r0x1002
;;1 MOVWF r0x1000
;;1 CLRF r0x1001
;;99 MOVF r0x1000,W
; .line 7; "test.c" PORTA = 2 * z;
MOVLW 0x02
MOVWF STK00
MOVF r0x1002,W
PAGESEL __mulchar
CALL __mulchar
PAGESEL $
BANKSEL _PORTA
MOVWF _PORTA
_00106_DS
; .line 8; "test.c" while(1);
GOTO 00106_DS
RETURN
~~~~~~
The call to __mulchar should be replaced by a shift. This would be faster and the code size would be smaller.
Such a replacement is expected in all conditions and for all targets.
Can still be observed in 4.3.6 [r14534].
Related
Commit: [r14534]
Looks like this only happens for pic: trying this for stm8 and z80, I see the left shift.
Looks like this is intentional: see src/SDCCicode.c, line 2233:
While the line was last changed by @maartenbrock, in [r8049], the exclusion of pic ports was there before. There is also this comment
though I don't know if that applies to pic.
I however do know that in some cases multiplication is indeed quite efficient, and some backends actually generate multiplication instructions for some shifts. But I don't think that could happen for a port where the multiplication require a support function call.