Skip to content

Commit fb7a435

Browse files
committed
[compiler-rt][builtins] Add several helper functions for AVR
__mulqi3 : int8 multiplication __mulhi3 : int16 multiplication _exit : golobal terminator Reviewed By: MaskRay, aykevl Differential Revision: https://reviews.llvm.org/D123200
1 parent 1790e29 commit fb7a435

File tree

8 files changed

+124
-2
lines changed

8 files changed

+124
-2
lines changed

compiler-rt/cmake/Modules/CompilerRTUtils.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ endmacro()
153153

154154
macro(detect_target_arch)
155155
check_symbol_exists(__arm__ "" __ARM)
156+
check_symbol_exists(__AVR__ "" __AVR)
156157
check_symbol_exists(__aarch64__ "" __AARCH64)
157158
check_symbol_exists(__x86_64__ "" __X86_64)
158159
check_symbol_exists(__i386__ "" __I386)
@@ -170,6 +171,8 @@ macro(detect_target_arch)
170171
check_symbol_exists(__ve__ "" __VE)
171172
if(__ARM)
172173
add_default_target_arch(arm)
174+
elseif(__AVR)
175+
add_default_target_arch(avr)
173176
elseif(__AARCH64)
174177
add_default_target_arch(aarch64)
175178
elseif(__X86_64)

compiler-rt/cmake/base-config-ix.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,8 @@ macro(test_targets)
234234
test_target_arch(armhf "" "-march=armv7-a" "-mfloat-abi=hard")
235235
test_target_arch(armv6m "" "-march=armv6m" "-mfloat-abi=soft")
236236
endif()
237+
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "avr")
238+
test_target_arch(avr "__AVR__" "--target=avr")
237239
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch32")
238240
test_target_arch(aarch32 "" "-march=armv8-a")
239241
elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch64")

compiler-rt/cmake/builtin-config-ix.cmake

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ asm(\"cas w0, w1, [x2]\");
3838

3939
set(ARM64 aarch64)
4040
set(ARM32 arm armhf armv6m armv7m armv7em armv7 armv7s armv7k armv8m.main armv8.1m.main)
41+
set(AVR avr)
4142
set(HEXAGON hexagon)
4243
set(X86 i386)
4344
set(X86_64 x86_64)
@@ -60,7 +61,7 @@ if(APPLE)
6061
endif()
6162

6263
set(ALL_BUILTIN_SUPPORTED_ARCH
63-
${X86} ${X86_64} ${ARM32} ${ARM64}
64+
${X86} ${X86_64} ${ARM32} ${ARM64} ${AVR}
6465
${HEXAGON} ${MIPS32} ${MIPS64} ${PPC32} ${PPC64}
6566
${RISCV32} ${RISCV64} ${SPARC} ${SPARCV9}
6667
${WASM32} ${WASM64} ${VE})

compiler-rt/cmake/config-ix.cmake

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,10 @@ file(WRITE ${SIMPLE_SOURCE} "#include <stdlib.h>\n#include <stdio.h>\nint main()
203203

204204
# Detect whether the current target platform is 32-bit or 64-bit, and setup
205205
# the correct commandline flags needed to attempt to target 32-bit and 64-bit.
206+
# AVR and MSP430 are omitted since they have 16-bit pointers.
206207
if (NOT CMAKE_SIZEOF_VOID_P EQUAL 4 AND
207-
NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
208+
NOT CMAKE_SIZEOF_VOID_P EQUAL 8 AND
209+
NOT ${arch} MATCHES "avr|msp430")
208210
message(FATAL_ERROR "Please use architecture with 4 or 8 byte pointers.")
209211
endif()
210212

compiler-rt/lib/builtins/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,13 @@ set(armv7em_SOURCES ${arm_SOURCES})
567567
set(armv8m.main_SOURCES ${arm_SOURCES})
568568
set(armv8.1m.main_SOURCES ${arm_SOURCES})
569569

570+
# 8-bit AVR MCU
571+
set(avr_SOURCES
572+
avr/mulqi3.S
573+
avr/mulhi3.S
574+
avr/exit.S
575+
)
576+
570577
# hexagon arch
571578
set(hexagon_SOURCES
572579
hexagon/common_entry_exit_abi1.S

compiler-rt/lib/builtins/avr/exit.S

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//===------------ exit.S - global terminator for AVR ----------------------===//
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+
.text
10+
.align 2
11+
12+
.globl _exit
13+
.type _exit, @function
14+
15+
_exit:
16+
cli ; Disable all interrupts.
17+
__stop_program:
18+
rjmp __stop_program ; Fall into an infinite loop.

compiler-rt/lib/builtins/avr/mulhi3.S

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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+
//===----------------------------------------------------------------------===//
23+
24+
.text
25+
.align 2
26+
27+
.globl __mulhi3
28+
.type __mulhi3, @function
29+
30+
__mulhi3:
31+
eor r28, r28
32+
eor r20, r20
33+
eor r21, r21 ; Initialize the result to 0: `S = 0;`.
34+
35+
__mulhi3_loop:
36+
cp r24, r28
37+
cpc r25, r28 ; `while (A != 0) { ... }`
38+
breq __mulhi3_end ; End the loop if A is 0.
39+
40+
mov r29, r24
41+
andi r29, 1 ; `if (A & 1) { ... }`
42+
breq __mulhi3_loop_a ; Omit the accumulation (`S += B;`) if A's LSB is 0.
43+
44+
add r20, r22
45+
adc r21, r23 ; Do the accumulation: `S += B;`.
46+
47+
__mulhi3_loop_a:
48+
lsr r25
49+
ror r24 ; `A = ((unsigned int) A) >> 1;`.
50+
lsl r22
51+
rol r23 ; `B <<= 1;`
52+
53+
rjmp __mulhi3_loop
54+
55+
__mulhi3_end:
56+
mov r24, r20
57+
mov r25, r21
58+
ret

compiler-rt/lib/builtins/avr/mulqi3.S

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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+
// int __mulqi3(char A, char B) {
12+
// return __mulhi3((int) A, (int) B);
13+
// }
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
.text
18+
.align 2
19+
20+
.globl __mulqi3
21+
.type __mulqi3, @function
22+
23+
__mulqi3:
24+
mov r25, r24
25+
lsl r25
26+
sbc r25, r25 ; Promote A from char to int: `(int) A`.
27+
mov r23, r22
28+
lsl r23
29+
sbc r23, r23 ; Promote B from char to int: `(int) B`.
30+
rcall __mulhi3 ; `__mulhi3((int) A, (int) B);`.
31+
ret

0 commit comments

Comments
 (0)