diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake --- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake +++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake @@ -153,6 +153,7 @@ macro(detect_target_arch) check_symbol_exists(__arm__ "" __ARM) + check_symbol_exists(__AVR__ "" __AVR) check_symbol_exists(__aarch64__ "" __AARCH64) check_symbol_exists(__x86_64__ "" __X86_64) check_symbol_exists(__i386__ "" __I386) @@ -170,6 +171,8 @@ check_symbol_exists(__ve__ "" __VE) if(__ARM) add_default_target_arch(arm) + elseif(__AVR) + add_default_target_arch(avr) elseif(__AARCH64) add_default_target_arch(aarch64) elseif(__X86_64) diff --git a/compiler-rt/cmake/base-config-ix.cmake b/compiler-rt/cmake/base-config-ix.cmake --- a/compiler-rt/cmake/base-config-ix.cmake +++ b/compiler-rt/cmake/base-config-ix.cmake @@ -234,6 +234,8 @@ test_target_arch(armhf "" "-march=armv7-a" "-mfloat-abi=hard") test_target_arch(armv6m "" "-march=armv6m" "-mfloat-abi=soft") endif() + elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "avr") + test_target_arch(avr "__AVR__" "--target=avr") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch32") test_target_arch(aarch32 "" "-march=armv8-a") elseif("${COMPILER_RT_DEFAULT_TARGET_ARCH}" MATCHES "aarch64") diff --git a/compiler-rt/cmake/builtin-config-ix.cmake b/compiler-rt/cmake/builtin-config-ix.cmake --- a/compiler-rt/cmake/builtin-config-ix.cmake +++ b/compiler-rt/cmake/builtin-config-ix.cmake @@ -38,6 +38,7 @@ set(ARM64 aarch64) set(ARM32 arm armhf armv6m armv7m armv7em armv7 armv7s armv7k armv8m.main armv8.1m.main) +set(AVR avr) set(HEXAGON hexagon) set(X86 i386) set(X86_64 x86_64) @@ -60,7 +61,7 @@ endif() set(ALL_BUILTIN_SUPPORTED_ARCH - ${X86} ${X86_64} ${ARM32} ${ARM64} + ${X86} ${X86_64} ${ARM32} ${ARM64} ${AVR} ${HEXAGON} ${MIPS32} ${MIPS64} ${PPC32} ${PPC64} ${RISCV32} ${RISCV64} ${SPARC} ${SPARCV9} ${WASM32} ${WASM64} ${VE}) diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -203,8 +203,10 @@ # Detect whether the current target platform is 32-bit or 64-bit, and setup # the correct commandline flags needed to attempt to target 32-bit and 64-bit. +# AVR and MSP430 are omitted since they have 16-bit pointers. if (NOT CMAKE_SIZEOF_VOID_P EQUAL 4 AND - NOT CMAKE_SIZEOF_VOID_P EQUAL 8) + NOT CMAKE_SIZEOF_VOID_P EQUAL 8 AND + NOT ${arch} MATCHES "avr|msp430") message(FATAL_ERROR "Please use architecture with 4 or 8 byte pointers.") endif() diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -567,6 +567,13 @@ set(armv8m.main_SOURCES ${arm_SOURCES}) set(armv8.1m.main_SOURCES ${arm_SOURCES}) +# 8-bit AVR MCU +set(avr_SOURCES + avr/mulqi3.S + avr/mulhi3.S + avr/exit.S +) + # hexagon arch set(hexagon_SOURCES hexagon/common_entry_exit_abi1.S diff --git a/compiler-rt/lib/builtins/avr/exit.S b/compiler-rt/lib/builtins/avr/exit.S new file mode 100644 --- /dev/null +++ b/compiler-rt/lib/builtins/avr/exit.S @@ -0,0 +1,18 @@ +//===------------ exit.S - global terminator for AVR ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + + .text + .align 2 + + .globl _exit + .type _exit, @function + +_exit: + cli ; Disable all interrupts. +__stop_program: + rjmp __stop_program ; Fall into an infinite loop. diff --git a/compiler-rt/lib/builtins/avr/mulhi3.S b/compiler-rt/lib/builtins/avr/mulhi3.S new file mode 100644 --- /dev/null +++ b/compiler-rt/lib/builtins/avr/mulhi3.S @@ -0,0 +1,58 @@ +//===------------ mulhi3.S - int16 multiplication -------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// The corresponding C code is something like: +// +// int __mulhi3(int A, int B) { +// int S = 0; +// while (A != 0) { +// if (A & 1) +// S += B; +// A = ((unsigned int) A) >> 1; +// B <<= 1; +// } +// return S; +// } +// +//===----------------------------------------------------------------------===// + + .text + .align 2 + + .globl __mulhi3 + .type __mulhi3, @function + +__mulhi3: + eor r28, r28 + eor r20, r20 + eor r21, r21 ; Initialize the result to 0: `S = 0;`. + +__mulhi3_loop: + cp r24, r28 + cpc r25, r28 ; `while (A != 0) { ... }` + breq __mulhi3_end ; End the loop if A is 0. + + mov r29, r24 + andi r29, 1 ; `if (A & 1) { ... }` + breq __mulhi3_loop_a ; Omit the accumulation (`S += B;`) if A's LSB is 0. + + add r20, r22 + adc r21, r23 ; Do the accumulation: `S += B;`. + +__mulhi3_loop_a: + lsr r25 + ror r24 ; `A = ((unsigned int) A) >> 1;`. + lsl r22 + rol r23 ; `B <<= 1;` + + rjmp __mulhi3_loop + +__mulhi3_end: + mov r24, r20 + mov r25, r21 + ret diff --git a/compiler-rt/lib/builtins/avr/mulqi3.S b/compiler-rt/lib/builtins/avr/mulqi3.S new file mode 100644 --- /dev/null +++ b/compiler-rt/lib/builtins/avr/mulqi3.S @@ -0,0 +1,31 @@ +//===------------ mulhi3.S - int8 multiplication --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// The corresponding C code is something like: +// +// int __mulqi3(char A, char B) { +// return __mulhi3((int) A, (int) B); +// } +// +//===----------------------------------------------------------------------===// + + .text + .align 2 + + .globl __mulqi3 + .type __mulqi3, @function + +__mulqi3: + mov r25, r24 + lsl r25 + sbc r25, r25 ; Promote A from char to int: `(int) A`. + mov r23, r22 + lsl r23 + sbc r23, r23 ; Promote B from char to int: `(int) B`. + rcall __mulhi3 ; `__mulhi3((int) A, (int) B);`. + ret