aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2024-03-04 20:27:05 +0100
committerdeadprogram <[email protected]>2024-03-26 10:39:18 +0100
commit7c51594927d9605f16e44656aca0fd368191d548 (patch)
tree00a906fae573e4de6e14b75c4bce6b69d3be2c86
parentd628e3e2cb6f767dc5367bc43fb14751a509404a (diff)
downloadtinygo-7c51594927d9605f16e44656aca0fd368191d548.tar.gz
tinygo-7c51594927d9605f16e44656aca0fd368191d548.zip
wasm-unknown: add math and memory builtins that LLVM needs
This new library is needed for wasm targets that aren't WASI and don't need/want a libc, but still need some intrinsics that are generated by LLVM.
-rw-r--r--GNUmakefile14
-rw-r--r--builder/build.go7
-rw-r--r--builder/wasmbuiltins.go79
-rw-r--r--compileopts/config.go2
-rw-r--r--targets/wasm-unknown.json1
5 files changed, 101 insertions, 2 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 3e0549ec1..96d8e0deb 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -821,7 +821,9 @@ build/release: tinygo gen-device wasi-libc $(if $(filter 1,$(USE_SYSTEM_BINARYEN
@mkdir -p build/release/tinygo/lib/nrfx
@mkdir -p build/release/tinygo/lib/picolibc/newlib/libc
@mkdir -p build/release/tinygo/lib/picolibc/newlib/libm
- @mkdir -p build/release/tinygo/lib/wasi-libc
+ @mkdir -p build/release/tinygo/lib/wasi-libc/libc-bottom-half/headers
+ @mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
+ @mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@mkdir -p build/release/tinygo/pkg/thumbv6m-unknown-unknown-eabi-cortex-m0
@mkdir -p build/release/tinygo/pkg/thumbv6m-unknown-unknown-eabi-cortex-m0plus
@mkdir -p build/release/tinygo/pkg/thumbv7em-unknown-unknown-eabi-cortex-m4
@@ -872,7 +874,15 @@ endif
@cp -rp lib/picolibc/newlib/libm/common build/release/tinygo/lib/picolibc/newlib/libm
@cp -rp lib/picolibc/newlib/libm/math build/release/tinygo/lib/picolibc/newlib/libm
@cp -rp lib/picolibc-stdio.c build/release/tinygo/lib
- @cp -rp lib/wasi-libc/sysroot build/release/tinygo/lib/wasi-libc/sysroot
+ @cp -rp lib/wasi-libc/libc-bottom-half/headers/public build/release/tinygo/lib/wasi-libc/libc-bottom-half/headers
+ @cp -rp lib/wasi-libc/libc-top-half/musl/arch/generic build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
+ @cp -rp lib/wasi-libc/libc-top-half/musl/arch/wasm32 build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
+ @cp -rp lib/wasi-libc/libc-top-half/musl/src/include build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
+ @cp -rp lib/wasi-libc/libc-top-half/musl/src/internal build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
+ @cp -rp lib/wasi-libc/libc-top-half/musl/src/math build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
+ @cp -rp lib/wasi-libc/libc-top-half/musl/src/string build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
+ @cp -rp lib/wasi-libc/libc-top-half/musl/include build/release/tinygo/lib/wasi-libc/libc-top-half/musl
+ @cp -rp lib/wasi-libc/sysroot build/release/tinygo/lib/wasi-libc/sysroot
@cp -rp llvm-project/compiler-rt/lib/builtins build/release/tinygo/lib/compiler-rt-builtins
@cp -rp llvm-project/compiler-rt/LICENSE.TXT build/release/tinygo/lib/compiler-rt-builtins
@cp -rp src build/release/tinygo/src
diff --git a/builder/build.go b/builder/build.go
index 7b7cc4728..5a6683ae6 100644
--- a/builder/build.go
+++ b/builder/build.go
@@ -168,6 +168,13 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
return BuildResult{}, errors.New("could not find wasi-libc, perhaps you need to run `make wasi-libc`?")
}
libcDependencies = append(libcDependencies, dummyCompileJob(path))
+ case "wasmbuiltins":
+ libcJob, unlock, err := WasmBuiltins.load(config, tmpdir)
+ if err != nil {
+ return BuildResult{}, err
+ }
+ defer unlock()
+ libcDependencies = append(libcDependencies, libcJob)
case "mingw-w64":
_, unlock, err := MinGW.load(config, tmpdir)
if err != nil {
diff --git a/builder/wasmbuiltins.go b/builder/wasmbuiltins.go
new file mode 100644
index 000000000..06366bf95
--- /dev/null
+++ b/builder/wasmbuiltins.go
@@ -0,0 +1,79 @@
+package builder
+
+import (
+ "os"
+ "path/filepath"
+
+ "github.com/tinygo-org/tinygo/goenv"
+)
+
+var WasmBuiltins = Library{
+ name: "wasmbuiltins",
+ makeHeaders: func(target, includeDir string) error {
+ os.Mkdir(includeDir+"/bits", 0o777)
+ f, err := os.Create(includeDir + "/bits/alltypes.h")
+ if err != nil {
+ return err
+ }
+ if _, err := f.Write([]byte(wasmAllTypes)); err != nil {
+ return err
+ }
+ return f.Close()
+ },
+ cflags: func(target, headerPath string) []string {
+ libcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/wasi-libc")
+ return []string{
+ "-Werror",
+ "-Wall",
+ "-std=gnu11",
+ "-nostdlibinc",
+ "-isystem", libcDir + "/libc-top-half/musl/arch/wasm32",
+ "-isystem", libcDir + "/libc-top-half/musl/arch/generic",
+ "-isystem", libcDir + "/libc-top-half/musl/src/internal",
+ "-isystem", libcDir + "/libc-top-half/musl/src/include",
+ "-isystem", libcDir + "/libc-top-half/musl/include",
+ "-isystem", libcDir + "/libc-bottom-half/headers/public",
+ "-I" + headerPath,
+ }
+ },
+ sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/wasi-libc") },
+ librarySources: func(target string) ([]string, error) {
+ return []string{
+ // memory builtins needed for llvm.memcpy.*, llvm.memmove.*, and
+ // llvm.memset.* LLVM intrinsics.
+ "libc-top-half/musl/src/string/memcpy.c",
+ "libc-top-half/musl/src/string/memmove.c",
+ "libc-top-half/musl/src/string/memset.c",
+
+ // exp, exp2, and log are needed for LLVM math builtin functions
+ // like llvm.exp.*.
+ "libc-top-half/musl/src/math/__math_divzero.c",
+ "libc-top-half/musl/src/math/__math_invalid.c",
+ "libc-top-half/musl/src/math/__math_oflow.c",
+ "libc-top-half/musl/src/math/__math_uflow.c",
+ "libc-top-half/musl/src/math/__math_xflow.c",
+ "libc-top-half/musl/src/math/exp.c",
+ "libc-top-half/musl/src/math/exp_data.c",
+ "libc-top-half/musl/src/math/exp2.c",
+ "libc-top-half/musl/src/math/log.c",
+ "libc-top-half/musl/src/math/log_data.c",
+ }, nil
+ },
+}
+
+// alltypes.h for wasm-libc, using the types as defined inside Clang.
+const wasmAllTypes = `
+typedef __SIZE_TYPE__ size_t;
+typedef __INT8_TYPE__ int8_t;
+typedef __INT16_TYPE__ int16_t;
+typedef __INT32_TYPE__ int32_t;
+typedef __INT64_TYPE__ int64_t;
+typedef __UINT8_TYPE__ uint8_t;
+typedef __UINT16_TYPE__ uint16_t;
+typedef __UINT32_TYPE__ uint32_t;
+typedef __UINT64_TYPE__ uint64_t;
+typedef __UINTPTR_TYPE__ uintptr_t;
+
+// This type is used internally in wasi-libc.
+typedef double double_t;
+`
diff --git a/compileopts/config.go b/compileopts/config.go
index 9349738a4..24da4e280 100644
--- a/compileopts/config.go
+++ b/compileopts/config.go
@@ -311,6 +311,8 @@ func (c *Config) CFlags(libclang bool) []string {
case "wasi-libc":
root := goenv.Get("TINYGOROOT")
cflags = append(cflags, "--sysroot="+root+"/lib/wasi-libc/sysroot")
+ case "wasmbuiltins":
+ // nothing to add (library is purely for builtins)
case "mingw-w64":
root := goenv.Get("TINYGOROOT")
path, _ := c.LibcPath("mingw-w64")
diff --git a/targets/wasm-unknown.json b/targets/wasm-unknown.json
index 903afa49e..a3f6313c1 100644
--- a/targets/wasm-unknown.json
+++ b/targets/wasm-unknown.json
@@ -7,6 +7,7 @@
"goarch": "arm",
"linker": "wasm-ld",
"rtlib": "compiler-rt",
+ "libc": "wasmbuiltins",
"scheduler": "none",
"gc": "leaking",
"default-stack-size": 4096,