1//===------------ mulhi3.S - int16 multiplication -------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// The corresponding C code is something like: 10// 11// int __mulhi3(int A, int B) { 12// int S = 0; 13// while (A != 0) { 14// if (A & 1) 15// S += B; 16// A = ((unsigned int) A) >> 1; 17// B <<= 1; 18// } 19// return S; 20// } 21// 22// __mulhi3 has special ABI, as the implementation of libgcc, R25:R24 is used 23// to return result, while Rtmp/R21/R22/R23 are clobbered. 24// 25//===----------------------------------------------------------------------===// 26 27 .text 28 .align 2 29 30#ifdef __AVR_TINY__ 31 .set __tmp_reg__, 16 32 .set __zero_reg__, 17 33#else 34 .set __tmp_reg__, 0 35 .set __zero_reg__, 1 36#endif 37 38 .globl __mulhi3 39 .type __mulhi3, @function 40 41__mulhi3: 42 ; Use Rzero:Rtmp to store the result. 43 clr __tmp_reg__ 44 clr __zero_reg__ ; S = 0; 45 46__mulhi3_loop: 47 clr r21 48 cp r24, r21 49 cpc r25, r21 50 breq __mulhi3_end ; while (A != 0) { 51 52 mov r21, r24 53 andi r21, 1 54 breq __mulhi3_loop_a ; if (A & 1) 55 add __tmp_reg__, r22 56 adc __zero_reg__, r23 ; S += B; 57 58__mulhi3_loop_a: 59 lsr r25 60 ror r24 ; A = ((unsigned int) A) >> 1; 61 lsl r22 62 rol r23 ; B <<= 1; 63 rjmp __mulhi3_loop ; } 64 65__mulhi3_end: 66 ; Return the result via R25:R24. 67 mov r24, __tmp_reg__ 68 mov r25, __zero_reg__ 69 ; Restore __zero_reg__ to 0. 70 clr __zero_reg__ 71 ret ; return S; 72