Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/lib/builtins/avr/mulhi3.S
35290 views
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
73