aboutsummaryrefslogtreecommitdiff
path: root/libc/src/stdio
diff options
context:
space:
mode:
Diffstat (limited to 'libc/src/stdio')
-rw-r--r--libc/src/stdio/CMakeLists.txt37
-rw-r--r--libc/src/stdio/gpu/CMakeLists.txt61
-rw-r--r--libc/src/stdio/gpu/file.h89
-rw-r--r--libc/src/stdio/gpu/fputs.cpp27
-rw-r--r--libc/src/stdio/gpu/puts.cpp29
-rw-r--r--libc/src/stdio/gpu/stderr.cpp16
-rw-r--r--libc/src/stdio/gpu/stdin.cpp16
-rw-r--r--libc/src/stdio/gpu/stdout.cpp16
8 files changed, 286 insertions, 5 deletions
diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index 6cd4f2c..9d25326 100644
--- a/libc/src/stdio/CMakeLists.txt
+++ b/libc/src/stdio/CMakeLists.txt
@@ -1,3 +1,23 @@
+# Helper function that creates an alias if a target specific implementation
+# exists, otherwise it uses a generic one.
+function(add_stdio_entrypoint_object name)
+ if(TARGET libc.src.stdio.${LIBC_TARGET_OS}.${name})
+ add_entrypoint_object(
+ ${name}
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.${name}
+ )
+ elseif(TARGET libc.src.stdio.generic_${name})
+ add_entrypoint_object(
+ ${name}
+ ALIAS
+ DEPENDS
+ .${LIBC_TARGET_OS}.${name}
+ )
+ endif()
+endfunction(add_stdio_entrypoint_object)
+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
endif()
@@ -322,7 +342,7 @@ add_entrypoint_object(
)
add_entrypoint_object(
- fputs
+ generic_fputs
SRCS
fputs.cpp
HDRS
@@ -336,7 +356,7 @@ add_entrypoint_object(
add_entrypoint_object(
- puts
+ generic_puts
SRCS
puts.cpp
HDRS
@@ -386,7 +406,7 @@ add_entrypoint_object(
)
add_entrypoint_object(
- stdin
+ generic_stdin
SRCS
stdin.cpp
HDRS
@@ -398,7 +418,7 @@ add_entrypoint_object(
)
add_entrypoint_object(
- stdout
+ generic_stdout
SRCS
stdout.cpp
HDRS
@@ -410,7 +430,7 @@ add_entrypoint_object(
)
add_entrypoint_object(
- stderr
+ generic_stderr
SRCS
stderr.cpp
HDRS
@@ -608,3 +628,10 @@ add_entrypoint_object(
DEPENDS
.${LIBC_TARGET_OS}.remove
)
+
+# These entrypoints have multiple potential implementations.
+add_stdio_entrypoint_object(puts)
+add_stdio_entrypoint_object(fputs)
+add_stdio_entrypoint_object(stdin)
+add_stdio_entrypoint_object(stdout)
+add_stdio_entrypoint_object(stderr)
diff --git a/libc/src/stdio/gpu/CMakeLists.txt b/libc/src/stdio/gpu/CMakeLists.txt
new file mode 100644
index 0000000..f679557
--- /dev/null
+++ b/libc/src/stdio/gpu/CMakeLists.txt
@@ -0,0 +1,61 @@
+add_header_library(
+ gpu_file
+ HDRS
+ file.h
+ DEPENDS
+ libc.src.__support.common
+ libc.src.__support.CPP.string_view
+ libc.src.__support.RPC.rpc_client
+)
+
+add_entrypoint_object(
+ puts
+ SRCS
+ puts.cpp
+ HDRS
+ ../puts.h
+ DEPENDS
+ libc.include.stdio
+ .gpu_file
+)
+
+add_entrypoint_object(
+ fputs
+ SRCS
+ fputs.cpp
+ HDRS
+ ../fputs.h
+ DEPENDS
+ libc.include.stdio
+ .gpu_file
+)
+
+add_entrypoint_object(
+ stdin
+ SRCS
+ stdin.cpp
+ HDRS
+ ../stdin.h
+ DEPENDS
+ libc.include.stdio
+)
+
+add_entrypoint_object(
+ stdout
+ SRCS
+ stdout.cpp
+ HDRS
+ ../stdout.h
+ DEPENDS
+ libc.include.stdio
+)
+
+add_entrypoint_object(
+ stderr
+ SRCS
+ stderr.cpp
+ HDRS
+ ../stderr.h
+ DEPENDS
+ libc.include.stdio
+)
diff --git a/libc/src/stdio/gpu/file.h b/libc/src/stdio/gpu/file.h
new file mode 100644
index 0000000..c7b2559
--- /dev/null
+++ b/libc/src/stdio/gpu/file.h
@@ -0,0 +1,89 @@
+//===--- GPU helper functions--------------------===//
+//
+// 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/__support/RPC/rpc_client.h"
+#include "src/string/string_utils.h"
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+namespace file {
+
+LIBC_INLINE uint64_t write_to_stdout(const void *data, size_t size) {
+ uint64_t ret = 0;
+ rpc::Client::Port port = rpc::client.open<RPC_WRITE_TO_STDOUT>();
+ port.send_n(data, size);
+ port.recv([&](rpc::Buffer *buffer) {
+ ret = reinterpret_cast<uint64_t *>(buffer->data)[0];
+ });
+ port.close();
+ return ret;
+}
+
+LIBC_INLINE uint64_t write_to_stderr(const void *data, size_t size) {
+ uint64_t ret = 0;
+ rpc::Client::Port port = rpc::client.open<RPC_WRITE_TO_STDERR>();
+ port.send_n(data, size);
+ port.recv([&](rpc::Buffer *buffer) {
+ ret = reinterpret_cast<uint64_t *>(buffer->data)[0];
+ });
+ port.close();
+ return ret;
+}
+
+LIBC_INLINE uint64_t write_to_stream(uintptr_t file, const void *data,
+ size_t size) {
+ uint64_t ret = 0;
+ rpc::Client::Port port = rpc::client.open<RPC_WRITE_TO_STREAM>();
+ port.send([&](rpc::Buffer *buffer) {
+ reinterpret_cast<uintptr_t *>(buffer->data)[0] = file;
+ });
+ port.send_n(data, size);
+ port.recv([&](rpc::Buffer *buffer) {
+ ret = reinterpret_cast<uint64_t *>(buffer->data)[0];
+ });
+ port.close();
+ return ret;
+}
+
+LIBC_INLINE uint64_t write(FILE *f, const void *data, size_t size) {
+ if (f == stdout)
+ return write_to_stdout(data, size);
+ else if (f == stderr)
+ return write_to_stderr(data, size);
+ else
+ return write_to_stream(reinterpret_cast<uintptr_t>(f), data, size);
+}
+
+LIBC_INLINE uint64_t read_from_stdin(void *buf, size_t size) {
+ uint64_t ret = 0;
+ uint64_t recv_size;
+ rpc::Client::Port port = rpc::client.open<RPC_READ_FROM_STDIN>();
+ port.send([=](rpc::Buffer *buffer) { buffer->data[0] = size; });
+ port.recv_n(&buf, &recv_size, [&](uint64_t) { return buf; });
+ port.recv([&](rpc::Buffer *buffer) { ret = buffer->data[0]; });
+ port.close();
+ return ret;
+}
+
+LIBC_INLINE uint64_t read_from_stream(uintptr_t file, void *buf, size_t size) {
+ uint64_t ret = 0;
+ uint64_t recv_size;
+ rpc::Client::Port port = rpc::client.open<RPC_READ_FROM_STREAM>();
+ port.send([=](rpc::Buffer *buffer) {
+ buffer->data[0] = size;
+ buffer->data[1] = file;
+ });
+ port.recv_n(&buf, &recv_size, [&](uint64_t) { return buf; });
+ port.recv([&](rpc::Buffer *buffer) { ret = buffer->data[0]; });
+ port.close();
+ return ret;
+}
+
+} // namespace file
+} // namespace __llvm_libc
diff --git a/libc/src/stdio/gpu/fputs.cpp b/libc/src/stdio/gpu/fputs.cpp
new file mode 100644
index 0000000..c5919e8
--- /dev/null
+++ b/libc/src/stdio/gpu/fputs.cpp
@@ -0,0 +1,27 @@
+//===-- GPU Implementation of fputs ---------------------------------------===//
+//
+// 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/fputs.h"
+#include "src/__support/CPP/string_view.h"
+#include "src/errno/libc_errno.h"
+#include "src/stdio/gpu/file.h"
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, fputs,
+ (const char *__restrict str, ::FILE *__restrict stream)) {
+ cpp::string_view str_view(str);
+ auto written = file::write(stream, str, str_view.size());
+ if (written != str_view.size())
+ return EOF;
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/stdio/gpu/puts.cpp b/libc/src/stdio/gpu/puts.cpp
new file mode 100644
index 0000000..58a3534
--- /dev/null
+++ b/libc/src/stdio/gpu/puts.cpp
@@ -0,0 +1,29 @@
+//===-- GPU Implementation of puts ----------------------------------------===//
+//
+// 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/puts.h"
+#include "src/__support/CPP/string_view.h"
+#include "src/errno/libc_errno.h"
+#include "src/stdio/gpu/file.h"
+
+#include <stdio.h>
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, puts, (const char *__restrict str)) {
+ cpp::string_view str_view(str);
+ auto written = file::write(stdout, str, str_view.size());
+ if (written != str_view.size())
+ return EOF;
+ written = file::write(stdout, "\n", 1);
+ if (written != 1)
+ return EOF;
+ return 0;
+}
+
+} // namespace __llvm_libc
diff --git a/libc/src/stdio/gpu/stderr.cpp b/libc/src/stdio/gpu/stderr.cpp
new file mode 100644
index 0000000..5e7b79e
--- /dev/null
+++ b/libc/src/stdio/gpu/stderr.cpp
@@ -0,0 +1,16 @@
+//===-- Definition of the global stderr object ----------------------------===//
+//
+// 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 <stdio.h>
+
+namespace __llvm_libc {
+static struct {
+} stub;
+FILE *stderr = reinterpret_cast<FILE *>(&stub);
+} // namespace __llvm_libc
+extern "C" FILE *stderr = reinterpret_cast<FILE *>(&__llvm_libc::stub);
diff --git a/libc/src/stdio/gpu/stdin.cpp b/libc/src/stdio/gpu/stdin.cpp
new file mode 100644
index 0000000..408852b
--- /dev/null
+++ b/libc/src/stdio/gpu/stdin.cpp
@@ -0,0 +1,16 @@
+//===-- Definition of the global stdin object -----------------------------===//
+//
+// 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 <stdio.h>
+
+namespace __llvm_libc {
+static struct {
+} stub;
+FILE *stdin = reinterpret_cast<FILE *>(&stub);
+} // namespace __llvm_libc
+extern "C" FILE *stdin = reinterpret_cast<FILE *>(&__llvm_libc::stub);
diff --git a/libc/src/stdio/gpu/stdout.cpp b/libc/src/stdio/gpu/stdout.cpp
new file mode 100644
index 0000000..02425d3
--- /dev/null
+++ b/libc/src/stdio/gpu/stdout.cpp
@@ -0,0 +1,16 @@
+//===-- Definition of the global stdout object ----------------------------===//
+//
+// 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 <stdio.h>
+
+namespace __llvm_libc {
+static struct {
+} stub;
+FILE *stdout = reinterpret_cast<FILE *>(&stub);
+} // namespace __llvm_libc
+extern "C" FILE *stdout = reinterpret_cast<FILE *>(&__llvm_libc::stub);