xref: /freebsd/contrib/llvm-project/compiler-rt/lib/builtins/avr/mulqi3.S (revision 2e3507c25e42292b45a5482e116d278f5515d04d)
1//===------------ mulhi3.S - int8 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// char __mulqi3(char A, char B) {
12//   int S = 0;
13//   while (A != 0) {
14//     if (A & 1)
15//       S += B;
16//     B <<= 1;
17//     A = ((unsigned char) A) >> 1;
18//   }
19//   return S;
20// }
21//
22// __mulqi3 has special ABI, as the implementation of libgcc, the result is
23// returned via R24, while Rtmp and R22 are clobbered.
24//
25//===----------------------------------------------------------------------===//
26
27	.text
28	.align 2
29
30#ifdef __AVR_TINY__
31	.set __tmp_reg__, 16
32#else
33	.set __tmp_reg__, 0
34#endif
35
36	.globl __mulqi3
37	.type  __mulqi3, @function
38
39__mulqi3:
40	clr   __tmp_reg__              ; S = 0;
41
42__mulqi3_loop:
43	cpi   r24, 0
44	breq  __mulqi3_end             ; while (A != 0) {
45	sbrc  r24, 0                   ;   if (A & 1)
46	add   __tmp_reg__, r22         ;     S += B;
47	add   r22, r22                 ;   B <<= 1;
48	lsr   r24                      ;   A = ((unsigned char) A) >> 1;
49	rjmp  __mulqi3_loop            ; }
50
51__mulqi3_end:
52	mov   r24, __tmp_reg__
53	ret                            ; return S;
54