diff --git a/libc/startup/linux/CMakeLists.txt b/libc/startup/gpu/CMakeLists.txt copy from libc/startup/linux/CMakeLists.txt copy to libc/startup/gpu/CMakeLists.txt --- a/libc/startup/linux/CMakeLists.txt +++ b/libc/startup/gpu/CMakeLists.txt @@ -37,7 +37,6 @@ DEPENDS ${ADD_STARTUP_OBJECT_DEPENDS} COMPILE_OPTIONS ${ADD_STARTUP_OBJECT_COMPILE_OPTIONS} ) - set(objfile ${LIBC_BUILD_DIR}/lib/${name}.o) add_custom_command( OUTPUT ${objfile} @@ -58,39 +57,37 @@ ) endfunction() -if(NOT (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_ARCHITECTURE})) - message(STATUS "Skipping startup for target architecture ${LIBC_TARGET_ARCHITECTURE}") - return() -endif() - -add_subdirectory(${LIBC_TARGET_ARCHITECTURE}) - -add_startup_object( - crt1 - ALIAS - DEPENDS - .${LIBC_TARGET_ARCHITECTURE}.crt1 -) +if(LIBC_GPU_TARGET_ARCHITECTURE_IS_AMDGPU) + add_subdirectory(amdgpu) -add_startup_object( - crti - SRC - crti.cpp -) + add_startup_object( + crt1 + ALIAS + DEPENDS + libc.startup.gpu.amdgpu.crt1 + ) +elseif(LIBC_GPU_TARGET_ARCHITECTURE_IS_NVPTX) + add_subdirectory(nvptx) -add_startup_object( - crtn - SRC - crtn.cpp -) + add_startup_object( + crt1 + ALIAS + DEPENDS + .nvptx.crt1 + ) +else() + # Skip building the startup code if there are no supported GPUs. + message(STATUS "Skipping startup for gpu target, no GPUs were detected") + return() +endif() add_custom_target(libc-startup) -set(startup_components crt1 crti crtn) +set(startup_components crt1) foreach(target IN LISTS startup_components) - set(fq_target_name libc.startup.linux.${target}) + set(fq_target_name libc.startup.gpu.${target}) add_dependencies(libc-startup ${fq_target_name}) get_target_property(startup_object ${fq_target_name} STARTUP_OBJECT) install(FILES ${startup_object} DESTINATION ${CMAKE_INSTALL_LIBDIR} - COMPONENT libc) + COMPONENT ${LIBC_COMPONENT}) endforeach() diff --git a/libc/startup/gpu/amdgpu/CMakeLists.txt b/libc/startup/gpu/amdgpu/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/startup/gpu/amdgpu/CMakeLists.txt @@ -0,0 +1,14 @@ +add_startup_object( + crt1 + SRC + start.cpp + COMPILE_OPTIONS + -ffreestanding # To avoid compiler warnings about calling the main function. + -fno-builtin + -nogpulib # Do not include any GPU vendor libraries. + -nogpuinc + -nostdinc + -mcpu=${LIBC_GPU_TARGET_ARCHITECTURE} + -emit-llvm # AMDGPU's intermediate object file format is bitcode. + --target=${LIBC_GPU_TARGET_TRIPLE} +) diff --git a/libc/startup/gpu/amdgpu/start.cpp b/libc/startup/gpu/amdgpu/start.cpp new file mode 100644 --- /dev/null +++ b/libc/startup/gpu/amdgpu/start.cpp @@ -0,0 +1,14 @@ +//===-- Implementation of crt for amdgpu ----------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +extern "C" int main(int argc, char **argv); + +extern "C" [[gnu::visibility("protected"), clang::amdgpu_kernel]] void +_start(int argc, char **argv, int *ret) { + __atomic_fetch_or(ret, main(argc, argv), __ATOMIC_RELAXED); +} diff --git a/libc/startup/gpu/nvptx/CMakeLists.txt b/libc/startup/gpu/nvptx/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/libc/startup/gpu/nvptx/CMakeLists.txt @@ -0,0 +1,14 @@ +add_startup_object( + crt1 + SRC + start.cpp + COMPILE_OPTIONS + -ffreestanding # To avoid compiler warnings about calling the main function. + -fno-builtin + -nogpulib # Do not include any GPU vendor libraries. + -nogpuinc + -nostdinc + -x cuda # Use the CUDA toolchain to emit the `_start` kernel. + --offload-device-only + --offload-arch=${LIBC_GPU_TARGET_ARCHITECTURE} +) diff --git a/libc/startup/gpu/nvptx/start.cpp b/libc/startup/gpu/nvptx/start.cpp new file mode 100644 --- /dev/null +++ b/libc/startup/gpu/nvptx/start.cpp @@ -0,0 +1,15 @@ +//===-- Implementation of crt for amdgpu ----------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +extern "C" __attribute__((device)) int main(int argc, char **argv); + +// TODO: We shouldn't need to use the CUDA language to emit a kernel for NVPTX. +extern "C" [[gnu::visibility("protected")]] __attribute__((global)) void +_start(int argc, char **argv, int *ret) { + __atomic_fetch_or(ret, main(argc, argv), __ATOMIC_RELAXED); +} diff --git a/libc/startup/linux/CMakeLists.txt b/libc/startup/linux/CMakeLists.txt --- a/libc/startup/linux/CMakeLists.txt +++ b/libc/startup/linux/CMakeLists.txt @@ -37,7 +37,6 @@ DEPENDS ${ADD_STARTUP_OBJECT_DEPENDS} COMPILE_OPTIONS ${ADD_STARTUP_OBJECT_COMPILE_OPTIONS} ) - set(objfile ${LIBC_BUILD_DIR}/lib/${name}.o) add_custom_command( OUTPUT ${objfile}