1*81ad6265SDimitry Andric//===------------ mulhi3.S - int8 multiplication --------------------------===// 2*81ad6265SDimitry Andric// 3*81ad6265SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*81ad6265SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 5*81ad6265SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*81ad6265SDimitry Andric// 7*81ad6265SDimitry Andric//===----------------------------------------------------------------------===// 8*81ad6265SDimitry Andric// 9*81ad6265SDimitry Andric// The corresponding C code is something like: 10*81ad6265SDimitry Andric// 11*81ad6265SDimitry Andric// char __mulqi3(char A, char B) { 12*81ad6265SDimitry Andric// int S = 0; 13*81ad6265SDimitry Andric// while (A != 0) { 14*81ad6265SDimitry Andric// if (A & 1) 15*81ad6265SDimitry Andric// S += B; 16*81ad6265SDimitry Andric// B <<= 1; 17*81ad6265SDimitry Andric// A = ((unsigned char) A) >> 1; 18*81ad6265SDimitry Andric// } 19*81ad6265SDimitry Andric// return S; 20*81ad6265SDimitry Andric// } 21*81ad6265SDimitry Andric// 22*81ad6265SDimitry Andric// __mulqi3 has special ABI, as the implementation of libgcc, the result is 23*81ad6265SDimitry Andric// returned via R24, while Rtmp and R22 are clobbered. 24*81ad6265SDimitry Andric// 25*81ad6265SDimitry Andric//===----------------------------------------------------------------------===// 26*81ad6265SDimitry Andric 27*81ad6265SDimitry Andric .text 28*81ad6265SDimitry Andric .align 2 29*81ad6265SDimitry Andric 30*81ad6265SDimitry Andric#ifdef __AVR_TINY__ 31*81ad6265SDimitry Andric .set __tmp_reg__, 16 32*81ad6265SDimitry Andric#else 33*81ad6265SDimitry Andric .set __tmp_reg__, 0 34*81ad6265SDimitry Andric#endif 35*81ad6265SDimitry Andric 36*81ad6265SDimitry Andric .globl __mulqi3 37*81ad6265SDimitry Andric .type __mulqi3, @function 38*81ad6265SDimitry Andric 39*81ad6265SDimitry Andric__mulqi3: 40*81ad6265SDimitry Andric clr __tmp_reg__ ; S = 0; 41*81ad6265SDimitry Andric 42*81ad6265SDimitry Andric__mulqi3_loop: 43*81ad6265SDimitry Andric cpi r24, 0 44*81ad6265SDimitry Andric breq __mulqi3_end ; while (A != 0) { 45*81ad6265SDimitry Andric sbrc r24, 0 ; if (A & 1) 46*81ad6265SDimitry Andric add __tmp_reg__, r22 ; S += B; 47*81ad6265SDimitry Andric add r22, r22 ; B <<= 1; 48*81ad6265SDimitry Andric lsr r24 ; A = ((unsigned char) A) >> 1; 49*81ad6265SDimitry Andric rjmp __mulqi3_loop ; } 50*81ad6265SDimitry Andric 51*81ad6265SDimitry Andric__mulqi3_end: 52*81ad6265SDimitry Andric mov r24, __tmp_reg__ 53*81ad6265SDimitry Andric ret ; return S; 54