72 lines · plain
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-exception6//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 used23// to return result, while Rtmp/R21/R22/R23 are clobbered.24//25//===----------------------------------------------------------------------===//26 27 .text28 .align 229 30#ifdef __AVR_TINY__31 .set __tmp_reg__, 1632 .set __zero_reg__, 1733#else34 .set __tmp_reg__, 035 .set __zero_reg__, 136#endif37 38 .globl __mulhi339 .type __mulhi3, @function40 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 r2148 cp r24, r2149 cpc r25, r2150 breq __mulhi3_end ; while (A != 0) {51 52 mov r21, r2453 andi r21, 154 breq __mulhi3_loop_a ; if (A & 1)55 add __tmp_reg__, r2256 adc __zero_reg__, r23 ; S += B;57 58__mulhi3_loop_a:59 lsr r2560 ror r24 ; A = ((unsigned int) A) >> 1;61 lsl r2262 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