[libc-commits] [libc] [llvm] [libc] Add bare-metal Hexagon port (PR #217528)

Brian Cain via libc-commits libc-commits at lists.llvm.org
Mon Sep 28 07:53:05 PDT 2026


================
@@ -0,0 +1,120 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// This file contains test utilities for bare-metal Hexagon hermetic tests.
+///
+/// llvm-libc's bare-metal port defers all OS interaction to a small set of
+/// "vendor-provided" hook symbols (see
+/// libc/src/__support/OSUtil/baremetal/io.h and the bare-metal time sources).
+/// This file implements those hooks for the Hexagon simulator using Angel-style
+/// semihosting, i.e. a `trap0(#0)` with:
+///   R0 = system call code (also the return value)
+///   R1 = pointer to an argument block (also errno on failure)
+///   R2 = exit status (for SYS_EXIT only)
+/// The read/write calls return the number of bytes NOT transferred.
+///
+/// It is compiled into HermeticTestUtils so hermetic tests can run under
+/// the simulator. It is purely test-support code and is not intended for use as
+/// general-purpose semihosting support.
+//===----------------------------------------------------------------------===//
+
+#include "hdr/stdint_proxy.h"
+#include "hdr/types/size_t.h"
+#include "hdr/types/ssize_t.h"
+#include "hdr/types/struct_timespec.h"
+
+namespace {
+
+enum HexagonSyscall {
+  SYS_WRITE = 5,
+  SYS_READ = 6,
+  SYS_TIME = 0x11,
+  SYS_EXIT = 24,
+};
+
+// Software interrupt used to enter the simulator monitor.
+#define HEXAGON_SWI "trap0(#0)"
+
+// Issue a semihosting call: R0 = code, R1 = pointer to argument block.
+// Returns the value the simulator places in R0.
+int hexagon_semihost(int code, size_t *args) {
+  register uintptr_t r0 __asm__("r0") = static_cast<uintptr_t>(code);
+  register uintptr_t r1 __asm__("r1") = reinterpret_cast<uintptr_t>(args);
+  __asm__ __volatile__(HEXAGON_SWI : "=r"(r0), "=r"(r1) : "r"(r0), "r"(r1));
+  return static_cast<int>(r0);
+}
+
+} // namespace
+
+extern "C" {
+
+// The cookie type/objects only need to exist; their contents encode the file
+// descriptor used by the simulator-backed implementation.
+struct __llvm_libc_stdio_cookie {
+  int fd;
+};
+
+__llvm_libc_stdio_cookie __llvm_libc_stdin_cookie = {0};
+__llvm_libc_stdio_cookie __llvm_libc_stdout_cookie = {1};
+__llvm_libc_stdio_cookie __llvm_libc_stderr_cookie = {2};
+
+ssize_t __llvm_libc_stdio_write(void *cookie, const char *buf, size_t size) {
+  int fd = cookie ? static_cast<__llvm_libc_stdio_cookie *>(cookie)->fd : 1;
+  size_t args[] = {
+      static_cast<size_t>(fd),
+      reinterpret_cast<size_t>(buf),
+      size,
+  };
+  int not_written = hexagon_semihost(SYS_WRITE, args);
+  if (not_written < 0)
+    return -1;
+  // The simulator returns the number of bytes NOT written.
----------------
androm3da wrote:

> simulator returns the number of bytes NOT written.

Are you sure that's the behavior?  If that's true then perhaps the spec is incorrect/incomplete?

https://docs.qualcomm.com/doc/80-N2040-101/topic/semihosting-specification.html#sys_write-0x5

https://github.com/llvm/llvm-project/pull/217528


More information about the libc-commits mailing list