llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-libc Author: Petr Hosek (petrhosek) <details> <summary>Changes</summary> This change expands the stdio support on baremetal to support opaque FILE*. This builds on top of the existing baremetal embedding API; we treat the standard FILE* streams as pointers that point to the cookie symbols which are a part of the embedding API. This also allows users to define their own FILE* streams, but we don't (yet) support the API that return FILE* such as fopen or fopencookie. --- Patch is 33.69 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/168931.diff 23 Files Affected: - (modified) clang/cmake/caches/Fuchsia-stage2.cmake (+4-2) - (modified) libc/config/baremetal/aarch64/entrypoints.txt (+8) - (modified) libc/config/baremetal/arm/entrypoints.txt (+8) - (modified) libc/config/baremetal/riscv/entrypoints.txt (+8) - (modified) libc/src/__support/OSUtil/baremetal/io.cpp (+4-38) - (modified) libc/src/__support/OSUtil/baremetal/io.h (+39) - (modified) libc/src/stdio/baremetal/CMakeLists.txt (+133-18) - (added) libc/src/stdio/baremetal/feof.cpp (+24) - (added) libc/src/stdio/baremetal/ferror.cpp (+23) - (added) libc/src/stdio/baremetal/fgetc.cpp () - (added) libc/src/stdio/baremetal/fgets.cpp () - (added) libc/src/stdio/baremetal/fprintf.cpp (+34) - (added) libc/src/stdio/baremetal/fputc.cpp (+22) - (added) libc/src/stdio/baremetal/fputc_internal.h (+29) - (added) libc/src/stdio/baremetal/fputs.cpp (+23) - (added) libc/src/stdio/baremetal/fputs_internal.h (+29) - (added) libc/src/stdio/baremetal/fwrite_internal.h (+27) - (modified) libc/src/stdio/baremetal/printf.cpp (+4-42) - (modified) libc/src/stdio/baremetal/putchar.cpp (+5-8) - (modified) libc/src/stdio/baremetal/puts.cpp (+3-9) - (added) libc/src/stdio/baremetal/vfprintf.cpp (+30) - (added) libc/src/stdio/baremetal/vfprintf_internal.h (+69) - (modified) libc/src/stdio/baremetal/vprintf.cpp (+4-43) ``````````diff diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake index be3d0cfa2e657..1e7b3e1b71373 100644 --- a/clang/cmake/caches/Fuchsia-stage2.cmake +++ b/clang/cmake/caches/Fuchsia-stage2.cmake @@ -341,7 +341,7 @@ foreach(target armv6m-none-eabi;armv7m-none-eabi;armv7em-none-eabi;armv8m.main-n foreach(lang C;CXX;ASM) # TODO: The preprocessor defines workaround various issues in libc and libc++ integration. # These should be addressed and removed over time. - set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "--target=${target} -Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" \"-Dfputs(string, stream)=puts(string)\" -D_LIBCPP_PRINT=1") + set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "--target=${target} -Wno-atomic-alignment") if(NOT ${target} STREQUAL "aarch64-none-elf") set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "${RUNTIMES_${target}_CMAKE_${lang}_local_flags} -mthumb") endif() @@ -372,6 +372,7 @@ foreach(target armv6m-none-eabi;armv7m-none-eabi;armv7em-none-eabi;armv8m.main-n set(RUNTIMES_${target}_LIBCXX_ENABLE_RTTI OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_THREADS OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "") + set(RUNTIMES_${target}_LIBCXX_HAS_TERMINAL_AVAILABLE OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") set(RUNTIMES_${target}_LLVM_INCLUDE_TESTS OFF CACHE BOOL "") set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS OFF CACHE BOOL "") @@ -406,7 +407,7 @@ foreach(target riscv32-unknown-elf) foreach(lang C;CXX;ASM) # TODO: The preprocessor defines workaround various issues in libc and libc++ integration. # These should be addressed and removed over time. - set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "--target=${target} -march=rv32imafc -mabi=ilp32f -Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" \"-Dfputs(string, stream)=puts(string)\" -D_LIBCPP_PRINT=1" CACHE STRING "") + set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "--target=${target} -march=rv32imafc -mabi=ilp32f -Wno-atomic-alignment" CACHE STRING "") endforeach() foreach(type SHARED;MODULE;EXE) set(RUNTIMES_${target}_CMAKE_${type}_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "") @@ -427,6 +428,7 @@ foreach(target riscv32-unknown-elf) set(RUNTIMES_${target}_LIBCXX_ENABLE_RTTI OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_THREADS OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "") + set(RUNTIMES_${target}_LIBCXX_HAS_TERMINAL_AVAILABLE OFF CACHE BOOL "") set(RUNTIMES_${target}_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") set(RUNTIMES_${target}_LLVM_INCLUDE_TESTS OFF CACHE BOOL "") set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS OFF CACHE BOOL "") diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt index c69ab3d0bb37c..4c6b6dfc4d669 100644 --- a/libc/config/baremetal/aarch64/entrypoints.txt +++ b/libc/config/baremetal/aarch64/entrypoints.txt @@ -124,8 +124,15 @@ set(TARGET_LIBC_ENTRYPOINTS # stdio.h entrypoints libc.src.stdio.asprintf + libc.src.stdio.feof + libc.src.stdio.ferror + libc.src.stdio.fprintf + libc.src.stdio.fputc + libc.src.stdio.fputs + libc.src.stdio.fwrite libc.src.stdio.getchar libc.src.stdio.printf + libc.src.stdio.putc libc.src.stdio.putchar libc.src.stdio.puts libc.src.stdio.remove @@ -134,6 +141,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.stdio.sprintf libc.src.stdio.sscanf libc.src.stdio.vasprintf + libc.src.stdio.vfprintf libc.src.stdio.vprintf libc.src.stdio.vscanf libc.src.stdio.vsnprintf diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt index c566f8ad08c8e..0847a0905a6f7 100644 --- a/libc/config/baremetal/arm/entrypoints.txt +++ b/libc/config/baremetal/arm/entrypoints.txt @@ -124,8 +124,15 @@ set(TARGET_LIBC_ENTRYPOINTS # stdio.h entrypoints libc.src.stdio.asprintf + libc.src.stdio.feof + libc.src.stdio.ferror + libc.src.stdio.fprintf + libc.src.stdio.fputc + libc.src.stdio.fputs + libc.src.stdio.fwrite libc.src.stdio.getchar libc.src.stdio.printf + libc.src.stdio.putc libc.src.stdio.putchar libc.src.stdio.puts libc.src.stdio.remove @@ -134,6 +141,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.stdio.sprintf libc.src.stdio.sscanf libc.src.stdio.vasprintf + libc.src.stdio.vfprintf libc.src.stdio.vprintf libc.src.stdio.vscanf libc.src.stdio.vsnprintf diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt index a6aef96e91698..9a5c73b81e87f 100644 --- a/libc/config/baremetal/riscv/entrypoints.txt +++ b/libc/config/baremetal/riscv/entrypoints.txt @@ -124,8 +124,15 @@ set(TARGET_LIBC_ENTRYPOINTS # stdio.h entrypoints libc.src.stdio.asprintf + libc.src.stdio.feof + libc.src.stdio.ferror + libc.src.stdio.fprintf + libc.src.stdio.fputc + libc.src.stdio.fputs + libc.src.stdio.fwrite libc.src.stdio.getchar libc.src.stdio.printf + libc.src.stdio.putc libc.src.stdio.putchar libc.src.stdio.puts libc.src.stdio.remove @@ -134,6 +141,7 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.stdio.sprintf libc.src.stdio.sscanf libc.src.stdio.vasprintf + libc.src.stdio.vfprintf libc.src.stdio.vprintf libc.src.stdio.vscanf libc.src.stdio.vsnprintf diff --git a/libc/src/__support/OSUtil/baremetal/io.cpp b/libc/src/__support/OSUtil/baremetal/io.cpp index 2a9ef6bfa6579..2978d701017a5 100644 --- a/libc/src/__support/OSUtil/baremetal/io.cpp +++ b/libc/src/__support/OSUtil/baremetal/io.cpp @@ -8,49 +8,15 @@ #include "io.h" +#include "hdr/types/FILE.h" #include "src/__support/CPP/string_view.h" #include "src/__support/macros/config.h" namespace LIBC_NAMESPACE_DECL { -// These are intended to be provided by the vendor. -// -// The signature of these types and functions intentionally match `fopencookie` -// which allows the following: -// -// ``` -// struct __llvm_libc_stdio_cookie { ... }; -// ... -// struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie; -// cookie_io_functions_t stdin_func = { .read = __llvm_libc_stdio_read }; -// FILE *stdin = fopencookie(&__llvm_libc_stdin_cookie, "r", stdin_func); -// ... -// struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie; -// cookie_io_functions_t stdout_func = { .write = __llvm_libc_stdio_write }; -// FILE *stdout = fopencookie(&__llvm_libc_stdout_cookie, "w", stdout_func); -// ... -// struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie; -// cookie_io_functions_t stderr_func = { .write = __llvm_libc_stdio_write }; -// FILE *stderr = fopencookie(&__llvm_libc_stderr_cookie, "w", stderr_func); -// ``` -// -// At the same time, implementation of functions like `printf` and `scanf` can -// use `__llvm_libc_stdio_read` and `__llvm_libc_stdio_write` directly to avoid -// the extra indirection. -// -// All three symbols `__llvm_libc_stdin_cookie`, `__llvm_libc_stdout_cookie`, -// and `__llvm_libc_stderr_cookie` must be provided, even if they don't point -// at anything. - -struct __llvm_libc_stdio_cookie; - -extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie; -extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie; -extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie; - -extern "C" ssize_t __llvm_libc_stdio_read(void *cookie, char *buf, size_t size); -extern "C" ssize_t __llvm_libc_stdio_write(void *cookie, const char *buf, - size_t size); +extern "C" FILE *stdin = reinterpret_cast<FILE *>(&__llvm_libc_stdin_cookie); +extern "C" FILE *stdout = reinterpret_cast<FILE *>(&__llvm_libc_stdout_cookie); +extern "C" FILE *stderr = reinterpret_cast<FILE *>(&__llvm_libc_stderr_cookie); ssize_t read_from_stdin(char *buf, size_t size) { return __llvm_libc_stdio_read(static_cast<void *>(&__llvm_libc_stdin_cookie), diff --git a/libc/src/__support/OSUtil/baremetal/io.h b/libc/src/__support/OSUtil/baremetal/io.h index aed34ec7e62e3..2605fd45776b9 100644 --- a/libc/src/__support/OSUtil/baremetal/io.h +++ b/libc/src/__support/OSUtil/baremetal/io.h @@ -16,6 +16,45 @@ namespace LIBC_NAMESPACE_DECL { +// These are intended to be provided by the vendor. +// +// The signature of these types and functions intentionally match `fopencookie` +// which allows the following: +// +// ``` +// struct __llvm_libc_stdio_cookie { ... }; +// ... +// struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie; +// cookie_io_functions_t stdin_func = { .read = __llvm_libc_stdio_read }; +// FILE *stdin = fopencookie(&__llvm_libc_stdin_cookie, "r", stdin_func); +// ... +// struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie; +// cookie_io_functions_t stdout_func = { .write = __llvm_libc_stdio_write }; +// FILE *stdout = fopencookie(&__llvm_libc_stdout_cookie, "w", stdout_func); +// ... +// struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie; +// cookie_io_functions_t stderr_func = { .write = __llvm_libc_stdio_write }; +// FILE *stderr = fopencookie(&__llvm_libc_stderr_cookie, "w", stderr_func); +// ``` +// +// At the same time, implementation of functions like `printf` and `scanf` can +// use `__llvm_libc_stdio_read` and `__llvm_libc_stdio_write` directly to avoid +// the extra indirection. +// +// All three symbols `__llvm_libc_stdin_cookie`, `__llvm_libc_stdout_cookie`, +// and `__llvm_libc_stderr_cookie` must be provided, even if they don't point +// at anything. + +struct __llvm_libc_stdio_cookie; + +extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie; +extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie; +extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie; + +extern "C" ssize_t __llvm_libc_stdio_read(void *cookie, char *buf, size_t size); +extern "C" ssize_t __llvm_libc_stdio_write(void *cookie, const char *buf, + size_t size); + ssize_t read_from_stdin(char *buf, size_t size); void write_to_stderr(cpp::string_view msg); void write_to_stdout(cpp::string_view msg); diff --git a/libc/src/stdio/baremetal/CMakeLists.txt b/libc/src/stdio/baremetal/CMakeLists.txt index bfeff0e2b5880..e920b4a1a30f4 100644 --- a/libc/src/stdio/baremetal/CMakeLists.txt +++ b/libc/src/stdio/baremetal/CMakeLists.txt @@ -1,3 +1,111 @@ +add_header_library( + fputc_internal + HDRS + fputc_internal.h + DEPENDS + libc.hdr.types.FILE + libc.src.__support.CPP.string_view + libc.src.__support.OSUtil.osutil +) + +add_header_library( + fputs_internal + HDRS + fputs_internal.h + DEPENDS + libc.hdr.types.FILE + libc.src.__support.CPP.string_view + libc.src.__support.OSUtil.osutil +) + +add_header_library( + fwrite_internal + HDRS + fwrite_internal.h + DEPENDS + libc.hdr.types.FILE + libc.src.__support.OSUtil.osutil +) + +add_header_library( + vfprintf_internal + HDRS + vfprintf_internal.h + DEPENDS + libc.hdr.types.FILE + libc.hdr.stdio_macros + libc.src.__support.arg_list + libc.src.__support.CPP.limits + libc.src.__support.CPP.string_view + libc.src.__support.libc_errno + libc.src.__support.OSUtil.osutil + libc.src.stdio.printf_core.printf_main + libc.src.stdio.printf_core.writer + libc.src.stdio.printf_core.error_mapper + libc.src.stdio.printf_core.core_structs +) + +add_entrypoint_object( + feof + SRCS + feof.cpp + HDRS + ../feof.h + DEPENDS + libc.hdr.types.FILE +) + +add_entrypoint_object( + ferror + SRCS + ferror.cpp + HDRS + ../ferror.h + DEPENDS + libc.hdr.types.FILE +) + +add_entrypoint_object( + fprintf + SRCS + fprintf.cpp + HDRS + ../fprintf.h + DEPENDS + .vfprintf_internal + libc.src.__support.arg_list +) + +add_entrypoint_object( + fputc + SRCS + fputc.cpp + HDRS + ../fputc.h + DEPENDS + .fputc_internal +) + +add_entrypoint_object( + fputs + SRCS + fputs.cpp + HDRS + ../fputc.h + DEPENDS + .fputs_internal +) + +add_entrypoint_object( + fwrite + SRCS + fwrite.cpp + HDRS + ../fwrite.h + DEPENDS + .fwrite_internal +) + add_entrypoint_object( getchar SRCS @@ -27,14 +135,8 @@ add_entrypoint_object( HDRS ../printf.h DEPENDS - libc.src.stdio.printf_core.printf_main - libc.src.stdio.printf_core.writer - libc.src.stdio.printf_core.error_mapper - libc.src.stdio.printf_core.core_structs + .vfprintf_internal libc.src.__support.arg_list - libc.src.__support.OSUtil.osutil - libc.src.__support.libc_errno - libc.src.__support.CPP.limits ) add_entrypoint_object( @@ -44,8 +146,17 @@ add_entrypoint_object( HDRS ../putchar.h DEPENDS - libc.src.__support.OSUtil.osutil - libc.src.__support.CPP.string_view + .fputc_internal +) + +add_entrypoint_object( + putc + SRCS + putc.cpp + HDRS + ../putc.h + DEPENDS + .fputc_internal ) add_entrypoint_object( @@ -55,8 +166,7 @@ add_entrypoint_object( HDRS ../puts.h DEPENDS - libc.src.__support.OSUtil.osutil - libc.src.__support.CPP.string_view + .fputs_internal ) add_header_library( @@ -82,6 +192,17 @@ add_entrypoint_object( libc.src.__support.OSUtil.osutil ) +add_entrypoint_object( + vfprintf + SRCS + vfprintf.cpp + HDRS + ../vfprintf.h + DEPENDS + .vfprintf_internal + libc.src.__support.arg_list +) + add_entrypoint_object( vprintf SRCS @@ -89,14 +210,8 @@ add_entrypoint_object( HDRS ../vprintf.h DEPENDS - libc.src.stdio.printf_core.printf_main - libc.src.stdio.printf_core.writer - libc.src.stdio.printf_core.error_mapper - libc.src.stdio.printf_core.core_structs + .vfprintf_internal libc.src.__support.arg_list - libc.src.__support.OSUtil.osutil - libc.src.__support.libc_errno - libc.src.__support.CPP.limits ) add_entrypoint_object( diff --git a/libc/src/stdio/baremetal/feof.cpp b/libc/src/stdio/baremetal/feof.cpp new file mode 100644 index 0000000000000..3c241edeb47f6 --- /dev/null +++ b/libc/src/stdio/baremetal/feof.cpp @@ -0,0 +1,24 @@ +//===-- Implementation of feof for baremetal --------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/feof.h" + +#include "hdr/types/FILE.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, feof, (::FILE * stream)) { + (void)stream; + // TODO: Shall we have an embeddeding API for feof? + return 0; +} + +} // namespace LIBC_NAMESPACE_DECL + diff --git a/libc/src/stdio/baremetal/ferror.cpp b/libc/src/stdio/baremetal/ferror.cpp new file mode 100644 index 0000000000000..5af5a1efdcd9a --- /dev/null +++ b/libc/src/stdio/baremetal/ferror.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of ferror for baremetal ------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/ferror.h" + +#include "hdr/types/FILE.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, ferror, (::FILE * stream)) { + (void)stream; + // TODO: Shall we have an embeddeding API for ferror? + return 0; +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdio/baremetal/fgetc.cpp b/libc/src/stdio/baremetal/fgetc.cpp new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/libc/src/stdio/baremetal/fgets.cpp b/libc/src/stdio/baremetal/fgets.cpp new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/libc/src/stdio/baremetal/fprintf.cpp b/libc/src/stdio/baremetal/fprintf.cpp new file mode 100644 index 0000000000000..fc96c56ec77ed --- /dev/null +++ b/libc/src/stdio/baremetal/fprintf.cpp @@ -0,0 +1,34 @@ +//===-- Implementation of fprintf for baremetal -----------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/fprintf.h" + +#include "hdr/types/FILE.h" +#include "src/__support/arg_list.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" +#include "src/stdio/baremetal/vfprintf_internal.h" + +#include <stdarg.h> + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, fprintf, + (::FILE *__restrict stream, const char *__restrict format, + ...)) { + va_list vlist; + va_start(vlist, format); + internal::ArgList args(vlist); // This holder class allows for easier copying + // and pointer semantics, as well as handling + // destruction automatically. + va_end(vlist); + + return vfprintf_internal(stream, format, args); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdio/baremetal/fputc.cpp b/libc/src/stdio/baremetal/fputc.cpp new file mode 100644 index 0000000000000..1b4086466ee7b --- /dev/null +++ b/libc/src/stdio/baremetal/fputc.cpp @@ -0,0 +1,22 @@ +//===-- Implementation of fputc for baremetal -------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/fputc.h" + +#include "hdr/types/FILE.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" +#include "src/stdio/baremetal/fputc_internal.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(int, fputc, (int c, ::FILE *stream)) { + return fputc_internal(c, stream); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdio/baremetal/fputc_internal.h b/libc/src/stdio/baremetal/fputc_internal.h new file mode 100644 index 0000000000000..e578d6584bcfe --- /dev/null +++ b/libc/src/stdio/baremetal/fputc_internal.h @@ -0,0 +1,29 @@ +//===-- Baremetal implementation header of fputc ----------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIBC_SRC_STDIO_BAREMETAL_FPUTC_INTERNAL_H +#define LLVM_LIBC_SRC_STDIO_BAREMETAL_FPUTC_INTERNAL_H + +#include "hdr/types/FILE.h" +#include "src/__support/CPP/string_view.h" +#include "src/__support/OSUtil/io.h" +#include "src/__support/common.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +LIBC_INLINE int fputc_internal(int c, ::FILE *stream) { + char ch = static_cast<char>(c); + cpp::string_view str_view(&ch, 1); + __llvm_libc_stdio_write(stream, str_view.data(), str_view.size()); + return 0; +} + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_STDIO_BAREMETAL_FPUTC_INTERNAL_H diff --git a/libc/src/stdio/baremetal/fputs.cpp b/libc/src/stdio/baremetal/fputs.cpp new file mode 100644 index 0000000000000..daed53182686e --- /dev/null +++ b/libc/src/stdio/baremetal/fputs.cpp @@ -0,0 +1,23 @@ +//===-- Implementation of fputs for baremetal -------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for li... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/168931 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
