Index: compiler-rt/lib/builtins/avr/mulqi3.S =================================================================== --- compiler-rt/lib/builtins/avr/mulqi3.S +++ compiler-rt/lib/builtins/avr/mulqi3.S @@ -8,24 +8,46 @@ // // The corresponding C code is something like: // -// int __mulqi3(char A, char B) { -// return __mulhi3((int) A, (int) B); +// char __mulqi3(char A, char B) { +// int S = 0; +// while (A != 0) { +// if (A & 1) +// S += B; +// B <<= 1; +// A = ((unsigned char) A) >> 1; +// } +// return S; // } // +// __mulqi3 has special ABI, as the implementation of libgcc, the result is +// returned via R24, while Rtmp and R22 are clobbered. +// //===----------------------------------------------------------------------===// .text .align 2 +#ifdef __AVR_TINY__ + .set __tmp_reg__, 16 +#else + .set __tmp_reg__, 0 +#endif + .globl __mulqi3 .type __mulqi3, @function __mulqi3: - mov r25, r24 - lsl r25 - sbc r25, r25 ; Promote A from char to int: `(int) A`. - mov r23, r22 - lsl r23 - sbc r23, r23 ; Promote B from char to int: `(int) B`. - rcall __mulhi3 ; `__mulhi3((int) A, (int) B);`. - ret + eor __tmp_reg__, __tmp_reg__ ; S = 0; + +__mulqi3_loop: + cpi r24, 0 + breq __mulqi3_end ; while (A != 0) { + sbrc r24, 0 ; if (A & 1) + add __tmp_reg__, r22 ; S += B; + add r22, r22 ; B <<= 1; + lsr r24 ; A = ((unsigned char) A) >> 1; + rjmp __mulqi3_loop ; } + +__mulqi3_end: + mov r24, __tmp_reg__ + ret ; return S;