diff options
author | Ayke van Laethem <[email protected]> | 2024-03-04 20:27:05 +0100 |
---|---|---|
committer | deadprogram <[email protected]> | 2024-03-26 10:39:18 +0100 |
commit | 7c51594927d9605f16e44656aca0fd368191d548 (patch) | |
tree | 00a906fae573e4de6e14b75c4bce6b69d3be2c86 | |
parent | d628e3e2cb6f767dc5367bc43fb14751a509404a (diff) | |
download | tinygo-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-- | GNUmakefile | 14 | ||||
-rw-r--r-- | builder/build.go | 7 | ||||
-rw-r--r-- | builder/wasmbuiltins.go | 79 | ||||
-rw-r--r-- | compileopts/config.go | 2 | ||||
-rw-r--r-- | targets/wasm-unknown.json | 1 |
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, |