Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multilib #250

Merged
merged 1 commit into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 51 additions & 24 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE BOOL "" FORCE)
endif()

find_package(Python3 REQUIRED COMPONENTS Interpreter)

if(NOT CMAKE_C_COMPILER_LAUNCHER AND NOT CMAKE_CXX_COMPILER_LAUNCHER)
# If ccache is available then use it by default.
find_program(CCACHE_EXECUTABLE ccache)
Expand Down Expand Up @@ -457,7 +459,7 @@ function(add_picolibc directory variant target_triple flags qemu_params variant_
INSTALL_DIR "${LLVM_BINARY_DIR}/${directory}"
PREFIX picolibc/${variant}
DEPENDS clang lld llvm-ar llvm-config llvm-nm llvm-ranlib llvm-strip
CONFIGURE_COMMAND ${MESON_EXECUTABLE} -Dincludedir=include -Dlibdir=lib -Dspecsdir=none --prefix <INSTALL_DIR> --cross-file <BINARY_DIR>/meson-cross-build.txt ${picolibc_SOURCE_DIR}
CONFIGURE_COMMAND ${MESON_EXECUTABLE} -Dincludedir=include -Dlibdir=lib -Dspecsdir=none -Dmultilib=false --prefix <INSTALL_DIR> --cross-file <BINARY_DIR>/meson-cross-build.txt ${picolibc_SOURCE_DIR}
BUILD_COMMAND ninja
INSTALL_COMMAND ${MESON_EXECUTABLE} install ${MESON_INSTALL_QUIET}
USES_TERMINAL_CONFIGURE TRUE
Expand Down Expand Up @@ -831,7 +833,7 @@ function(make_config_cfg directory variant flags)
)
endfunction()

function(get_compiler_rt_target_triple target_arch)
function(get_compiler_rt_target_triple target_arch flags)
if(target_arch STREQUAL "aarch64")
set(target_triple "aarch64-none-elf")
else()
Expand Down Expand Up @@ -861,7 +863,7 @@ endfunction()
function(add_library_variants)
set(variant_args "${ARGN}")
while(variant_args)
list(POP_FRONT variant_args target_arch variant_suffix flags qemu_params)
list(POP_FRONT variant_args target_arch variant_suffix compile_flags multilib_flags qemu_params)

if(variant_suffix)
set(variant "${target_arch}_${variant_suffix}")
Expand All @@ -884,18 +886,18 @@ function(add_library_variants)
set(parent_dir_name arm-none-eabi)
endif()

get_compiler_rt_target_triple(${target_arch})
get_compiler_rt_target_triple("${target_arch}" "${compile_flags}")

set(directory "${TARGET_LIBRARIES_DIR}/${parent_dir_name}/${variant}")
set(flags "--target=${target_triple} ${flags}")
make_config_cfg("${directory}" "${variant}" "${flags}")
set(compile_flags "--target=${target_triple} ${compile_flags}")
make_config_cfg("${directory}" "${variant}" "${compile_flags}")
set(variant_options)
if(NOT PREBUILT_TARGET_LIBRARIES)
add_picolibc("${directory}" "${variant}" "${target_triple}" "${flags}" "${qemu_params}" variant_options)
add_compiler_rt("${directory}" "${variant}" "${target_triple}" "${flags}" "${qemu_params}" "picolibc_${variant}")
add_picolibc("${directory}" "${variant}" "${target_triple}" "${compile_flags}" "${qemu_params}" variant_options)
add_compiler_rt("${directory}" "${variant}" "${target_triple}" "${compile_flags}" "${qemu_params}" "picolibc_${variant}")
list(APPEND variant_options ${picolibc_specific_runtimes_options})
add_libcxx_libcxxabi_libunwind("${directory}" "${variant}" "${target_triple}" "${flags}" "picolibc_${variant}" "${variant_options}")
if(flags MATCHES "-march=armv8")
add_libcxx_libcxxabi_libunwind("${directory}" "${variant}" "${target_triple}" "${compile_flags}" "picolibc_${variant}" "${variant_options}")
if(compile_flags MATCHES "-march=armv8")
message("C++ runtime libraries tests disabled for ${variant}")
else()
add_custom_target(check-llvm-toolchain-runtimes-${variant})
Expand All @@ -905,30 +907,52 @@ function(add_library_variants)
endif()
endif()

string(APPEND multilib_yaml_content "- Dir: ${parent_dir_name}/${variant}\n")

string(APPEND multilib_yaml_content " Flags:\n")
string(REPLACE " " ";" multilib_flags_list ${multilib_flags})
foreach(flag ${multilib_flags_list})
string(APPEND multilib_yaml_content " - ${flag}\n")
endforeach()

install(
DIRECTORY "${LLVM_BINARY_DIR}/${directory}/"
DESTINATION "${directory}"
COMPONENT llvm-toolchain-libs
)
endwhile()
set(multilib_yaml_content "${multilib_yaml_content}" PARENT_SCOPE)
endfunction()

set(multilib_yaml_content "")

# Define which library variants to build and which flags to use.
# The order is <parent dir> <arch> <name suffix> <flags> <qemu params>
# The order is <arch> <name suffix> <compile flags> <multilib selection flags> <qemu params>
add_library_variants(
aarch64 "" "-march=armv8-a" "-M virt -cpu cortex-a57"
armv4t "" "-march=armv4t" "-M musicpal -cpu arm926"
armv5te "" "-march=armv5te" "-M musicpal -cpu arm926"
armv6m soft_nofp "-mfloat-abi=soft -march=armv6m" "-M mps2-an385"
armv7m soft_nofp "-mfloat-abi=soft -march=armv7m+nofp" "-M mps2-an385 -cpu cortex-m3"
armv7em soft_nofp "-mfloat-abi=soft -march=armv7em -mfpu=none" "-M mps2-an386 -cpu cortex-m4"
armv7em hard_fpv4_sp_d16 "-mfloat-abi=hard -march=armv7em -mfpu=fpv4-sp-d16" "-M mps2-an386 -cpu cortex-m4"
armv7em hard_fpv5_d16 "-mfloat-abi=hard -march=armv7em -mfpu=fpv5-d16" "-M mps2-an500 -cpu cortex-m7"
armv8m.main soft_nofp "-mfloat-abi=soft -march=armv8m.main+nofp" "-M mps2-an505 -cpu cortex-m33"
armv8m.main hard_fp "-mfloat-abi=hard -march=armv8m.main+fp" "-M mps2-an505 -cpu cortex-m33"
armv8.1m.main soft_nofp_nomve "-mfloat-abi=soft -march=armv8.1m.main+nofp+nomve" "-M mps3-an547 -cpu cortex-m55"
armv8.1m.main hard_fp "-mfloat-abi=hard -march=armv8.1m.main+fp" "-M mps3-an547 -cpu cortex-m55"
armv8.1m.main hard_nofp_mve "-mfloat-abi=hard -march=armv8.1m.main+nofp+mve" "-M mps3-an547 -cpu cortex-m55"
aarch64 "" "-march=armv8-a" "--target=aarch64-none-unknown-elf" "-M virt -cpu cortex-a57"
armv4t "" "-march=armv4t" "--target=armv4t-none-unknown-eabi -mfpu=none" "-M musicpal -cpu arm926"
armv5te "" "-march=armv5te" "--target=armv5e-none-unknown-eabi -mfpu=none" "-M musicpal -cpu arm926"
armv6m soft_nofp "-mfloat-abi=soft -march=armv6m" "--target=thumbv6m-none-unknown-eabi -mfpu=none" "-M mps2-an385"
armv7m soft_nofp "-mfloat-abi=soft -march=armv7m+nofp" "--target=thumbv7m-none-unknown-eabi -mfpu=none" "-M mps2-an385 -cpu cortex-m3"
armv7em soft_nofp "-mfloat-abi=soft -march=armv7em -mfpu=none" "--target=thumbv7em-none-unknown-eabi -mfpu=none" "-M mps2-an386 -cpu cortex-m4"
armv7em hard_fpv4_sp_d16 "-mfloat-abi=hard -march=armv7em -mfpu=fpv4-sp-d16" "--target=thumbv7em-none-unknown-eabihf -mfpu=fpv4-sp-d16" "-M mps2-an386 -cpu cortex-m4"
armv7em hard_fpv5_d16 "-mfloat-abi=hard -march=armv7em -mfpu=fpv5-d16" "--target=thumbv7em-none-unknown-eabihf -mfpu=fpv5-d16" "-M mps2-an500 -cpu cortex-m7"
armv8m.main soft_nofp "-mfloat-abi=soft -march=armv8m.main+nofp" "--target=thumbv8m.main-none-unknown-eabi -mfpu=none" "-M mps2-an505 -cpu cortex-m33"
armv8m.main hard_fp "-mfloat-abi=hard -march=armv8m.main+fp" "--target=thumbv8m.main-none-unknown-eabihf -mfpu=fpv5-d16" "-M mps2-an505 -cpu cortex-m33"
armv8.1m.main soft_nofp_nomve "-mfloat-abi=soft -march=armv8.1m.main+nofp+nomve" "--target=thumbv8.1m.main-none-unknown-eabi -mfpu=none" "-M mps3-an547 -cpu cortex-m55"
armv8.1m.main hard_fp "-mfloat-abi=hard -march=armv8.1m.main+fp" "--target=thumbv8.1m.main-none-unknown-eabihf -march=thumbv8.1m.main+fp16 -mfpu=fp-armv8-fullfp16-sp-d16" "-M mps3-an547 -cpu cortex-m55"
armv8.1m.main hard_nofp_mve "-mfloat-abi=hard -march=armv8.1m.main+nofp+mve" "--target=thumbv8.1m.main-none-unknown-eabihf -march=thumbv8.1m.main+dsp+mve -mfpu=none" "-M mps3-an547 -cpu cortex-m55"
)

configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/multilib.yaml.in
${CMAKE_CURRENT_BINARY_DIR}/llvm/${TARGET_LIBRARIES_DIR}/multilib.yaml
@ONLY
)
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/llvm/${TARGET_LIBRARIES_DIR}/multilib.yaml
DESTINATION ${TARGET_LIBRARIES_DIR}
COMPONENT llvm-toolchain-libs
)

install(
Expand Down Expand Up @@ -1075,12 +1099,15 @@ add_dependencies(



# TODO move this into tests/CMakeLists.txt
# Smoke tests

# Run tests on the built toolchain.
add_custom_target(check-llvm-toolchain)
add_dependencies(check-llvm-toolchain check-picolibc)
add_dependencies(check-llvm-toolchain check-compiler-rt)
add_subdirectory(tests)
add_dependencies(check-llvm-toolchain check-llvm-toolchain-lit)

# Run tests on the packaged and unpacked toolchain.
add_custom_target(check-package-llvm-toolchain)
Expand Down
140 changes: 140 additions & 0 deletions cmake/multilib.yaml.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#
# Copyright (c) 2023, Arm Limited and affiliates.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# If you're reading this file under the name 'multilib.yaml.in' in the
# LLVM-embedded-toolchain-for-Arm source tree, then it's not valid
# YAML in its own right: it's a template that CMakeLists.txt will
# expand into a real 'multilib.yaml' containing a list of library
# variants and the flags that will select them.
#
# If you're reading it under the name 'multilib.yaml' in the build or
# install directory, then that substitution has been done.
#
# Comments in this file mostly make more sense from the
# multilib.yaml.in point of view.

MultilibVersion: '1.0'

# The list of library variants is substituted in by CMakeLists.txt, so
# that it can respect the LLVM_TOOLCHAIN_LIBRARY_VARIANTS setting and
# only include the set of libraries actually included in this build.

Variants:
@multilib_yaml_content@

Mappings:

# Map higher architecture versions to subsets of them, so that a
# compatible library can be found even for architectures we don't have
# specific variants for.

# v8-M Baseline is a superset of v6-M
- Match: --target=thumbv8m\.base-none-unknown-eabi
Flags:
- --target=thumbv6m-none-unknown-eabi

# v8.2-M Mainline is a superset of v8.1-M Mainline, in both hard and
# soft float variants.
#
# Also, v8.1-M Mainline is also a superset of v8-M Mainline, which in
# turn is a superset of v7E-M, and then of plain v7-M. We have
# libraries for all those architecture versions, but not for every
# combination of them with FPUs, so in some cases it might be
# necessary to fall back to a lower architecture in order to provide
# the needed FPU support.
- Match: --target=thumbv8\.[2-9]m\.main-none-unknown-eabi
Flags:
- --target=thumbv8.1m.main-none-unknown-eabi
- --target=thumbv8m.main-none-unknown-eabi
- --target=thumbv7em-none-unknown-eabi
- --target=thumbv7m-none-unknown-eabi
- Match: --target=thumbv8\.[2-9]m\.main-none-unknown-eabihf
Flags:
- --target=thumbv8.1m.main-none-unknown-eabihf
- --target=thumbv8m.main-none-unknown-eabihf
- --target=thumbv7em-none-unknown-eabihf
- --target=thumbv7m-none-unknown-eabihf
- Match: --target=thumbv8\.1m\.main-none-unknown-eabi
Flags:
- --target=thumbv8m.main-none-unknown-eabi
- --target=thumbv7em-none-unknown-eabi
- --target=thumbv7m-none-unknown-eabi
- Match: --target=thumbv8\.1m\.main-none-unknown-eabihf
Flags:
- --target=thumbv8m.main-none-unknown-eabihf
- --target=thumbv7em-none-unknown-eabihf
- --target=thumbv7m-none-unknown-eabihf
- Match: --target=thumbv8m\.main-none-unknown-eabi
Flags:
- --target=thumbv7em-none-unknown-eabi
- --target=thumbv7m-none-unknown-eabi
- Match: --target=thumbv8m\.main-none-unknown-eabihf
Flags:
- --target=thumbv7em-none-unknown-eabihf
- --target=thumbv7m-none-unknown-eabihf
- Match: --target=thumbv7em-none-unknown-eabi
Flags:
- --target=thumbv7m-none-unknown-eabi
- Match: --target=thumbv7em-none-unknown-eabihf
Flags:
- --target=thumbv7m-none-unknown-eabihf

# Higher versions of v8-A, and v9-A, are all supersets of v8-A. (And
# of each other, in the obvious way, but we don't have any libraries
# for those at present, so there's no need to generate all their
# flags.)
- Match: --target=armv(8\.[1-9]|9|9\.[1-9])a-none-unknown-eabi
Flags:
- --target=armv8a-none-unknown-eabi

# -march extensions
- Match: -march=thumbv8\.[1-9]m\.main.*\+fp16.*
Flags:
- -march=thumbv8.1m.main+fp16
- Match: -march=thumbv8\.[1-9]m\.main.*\+dsp.*\+mve.*
Flags:
- -march=thumbv8.1m.main+dsp+mve
- Match: -march=thumbv8\.[1-9]m\.main.*\+fp16.*\+lob.*\+mve\.fp.*
Flags:
- -march=thumbv8.1m.main+fp16+lob+mve.fp

# Hierarchy among FPUs: fpvN-d16 is a superset of fpvN-sp-d16, and
# fpvN-d16 is a superset of fpv[N-1]-d16, for all N.
#
# We don't consider any hardware FP configuration to be compatible
# with -mfpu=none. It would work in most cases to cross-call between
# code compiled for an FPU or no FPU, if you were using the soft float
# ABI. But it wouldn't work in all cases: setjmp needs to know whether
# to save FP registers in the jmp_buf, so a non-FPU-aware setjmp would
# not behave correctly if linked into an otherwise FPU-using
# application. Similarly for exception unwinding. So we don't permit
# selecting an -mfpu=none library as a fallback for any hard-FP
# library.
- Match: -mfpu=fpv5-d16
Flags:
- -mfpu=fpv4-d16
- -mfpu=fpv5-sp-d16
- -mfpu=fpv4-sp-d16
- Match: -mfpu=fpv5-sp-d16
Flags:
- -mfpu=fpv4-sp-d16
- Match: -mfpu=fpv4-d16
Flags:
- -mfpu=fpv4-sp-d16
- Match: -mfpu=fp-armv8-fullfp16-d16
Flags:
- -mfpu=fp-armv8-fullfp16-sp-d16
30 changes: 30 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
if(LLVM_ENABLE_BACKTRACES)
set(ENABLE_BACKTRACES 1)
endif()
llvm_canonicalize_cmake_booleans(
ENABLE_BACKTRACES
)

configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in
${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py
MAIN_CONFIG
${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py
)

list(APPEND LLVM_TOOLCHAIN_TEST_DEPS
llvm-toolchain
FileCheck
count
not
)

add_lit_testsuite(check-llvm-toolchain-lit
"Running LLVM Embedded Toolchain for Arm regression tests"
${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${LLVM_TOOLCHAIN_TEST_DEPS}
)

add_lit_testsuites(llvm-toolchain-lit ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${LLVM_TOOLCHAIN_TEST_DEPS}
)
20 changes: 20 additions & 0 deletions tests/lit.cfg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- Python -*-

import os

import lit.formats

from lit.llvm import llvm_config

# Configuration file for the 'lit' test runner.

config.name = 'LLVM Embedded Toolchain for Arm'
config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
config.suffixes = ['.test']
config.excludes = ['CMakeLists.txt', 'Makefile.conf', 'ldscripts', 'smoketests']
config.test_source_root = os.path.dirname(__file__)

llvm_config.use_default_substitutions()
llvm_config.use_clang()

config.environment["CLANG_NO_DEFAULT_CONFIG"] = "1"
19 changes: 19 additions & 0 deletions tests/lit.site.cfg.py.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@LIT_SITE_CFG_IN_HEADER@

config.llvm_src_root = "@LLVM_SOURCE_DIR@"
config.llvm_obj_root = "@LLVM_BINARY_DIR@"
config.llvm_tools_dir = lit_config.substitute("@LLVM_BINARY_DIR@/bin")
config.llvm_libs_dir = lit_config.substitute("@LLVM_BINARY_DIR@/lib")
config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
config.enable_backtrace = @ENABLE_BACKTRACES@
config.errc_messages = "@LLVM_LIT_ERRC_MESSAGES@"
config.host_triple = "@LLVM_HOST_TRIPLE@"
config.target_triple = "@LLVM_DEFAULT_TARGET_TRIPLE@"
config.python_executable = "@Python3_EXECUTABLE@"
config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@"

import lit.llvm
lit.llvm.initialize(lit_config, config)

# Let the main config do the real work.
lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg.py")
2 changes: 2 additions & 0 deletions tests/multilib/aarch64.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# RUN: %clang -print-multi-directory --target=aarch64-none-elf | FileCheck %s
# CHECK: aarch64-none-elf/aarch64
2 changes: 2 additions & 0 deletions tests/multilib/armv4t.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# RUN: %clang -print-multi-directory --target=arm-none-eabi | FileCheck %s
# CHECK: arm-none-eabi/armv4t
2 changes: 2 additions & 0 deletions tests/multilib/armv5e.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# RUN: %clang -print-multi-directory --target=armv5e-none-eabi | FileCheck %s
# CHECK: arm-none-eabi/armv5te
2 changes: 2 additions & 0 deletions tests/multilib/armv6m.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# RUN: %clang -print-multi-directory --target=armv6m-none-eabi | FileCheck %s
# CHECK: arm-none-eabi/armv6m_soft_nofp
8 changes: 8 additions & 0 deletions tests/multilib/armv7em.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# RUN: %clang -print-multi-directory --target=armv7em-none-eabi -mfpu=none | FileCheck %s
# CHECK: arm-none-eabi/armv7em_soft_nofp

# RUN: %clang -print-multi-directory --target=armv7em-none-eabihf -mfpu=fpv4-sp-d16 | FileCheck --check-prefix=FPV4 %s
# FPV4: arm-none-eabi/armv7em_hard_fpv4_sp_d16

# RUN: %clang -print-multi-directory --target=armv7em-none-eabihf -mfpu=fpv5-d16 | FileCheck --check-prefix=FPV5 %s
# FPV5: arm-none-eabi/armv7em_hard_fpv5_d16
2 changes: 2 additions & 0 deletions tests/multilib/armv7m.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# RUN: %clang -print-multi-directory --target=armv7m-none-eabi | FileCheck %s
# CHECK: arm-none-eabi/armv7m_soft_nofp
11 changes: 11 additions & 0 deletions tests/multilib/armv8.1m.main.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# RUN: %clang -print-multi-directory --target=armv8.1m.main-none-eabi -mfpu=none | FileCheck %s
# CHECK: arm-none-eabi/armv8.1m.main_soft_nofp

# RUN: %clang -print-multi-directory --target=armv8.1m.main-none-eabihf -march=armv8.1m.main+fp | FileCheck --check-prefix=HARD %s
# HARD: arm-none-eabi/armv8.1m.main_hard_fp

# RUN: %clang -print-multi-directory --target=armv8.1m.main-none-eabihf -march=armv8.1m.main+nofp+mve | FileCheck --check-prefix=MVE %s
# MVE: arm-none-eabi/armv8.1m.main_hard_nofp_mve

# RUN: %clang -print-multi-flags-experimental --target=arm-none-eabihf -mcpu=cortex-m55 | FileCheck --check-prefix=CORTEXM55 %s
# CORTEXM55: -march=thumbv8.1m.main+fp16+lob+mve.fp
5 changes: 5 additions & 0 deletions tests/multilib/armv8m.main.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# RUN: %clang -print-multi-directory --target=armv8m.main-none-eabi -mfpu=none | FileCheck %s
# CHECK: arm-none-eabi/armv8m.main_soft_nofp

# RUN: %clang -print-multi-directory --target=armv8m.main-none-eabihf | FileCheck --check-prefix=HARD %s
# HARD: arm-none-eabi/armv8m.main_hard_fp