Skip to content

Commit 7c54652

Browse files
aykevldeadprogram
authored andcommitted
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.
1 parent d628e3e commit 7c54652

File tree

5 files changed

+101
-2
lines changed

5 files changed

+101
-2
lines changed

GNUmakefile

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,9 @@ build/release: tinygo gen-device wasi-libc $(if $(filter 1,$(USE_SYSTEM_BINARYEN
821821
@mkdir -p build/release/tinygo/lib/nrfx
822822
@mkdir -p build/release/tinygo/lib/picolibc/newlib/libc
823823
@mkdir -p build/release/tinygo/lib/picolibc/newlib/libm
824-
@mkdir -p build/release/tinygo/lib/wasi-libc
824+
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-bottom-half/headers
825+
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
826+
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
825827
@mkdir -p build/release/tinygo/pkg/thumbv6m-unknown-unknown-eabi-cortex-m0
826828
@mkdir -p build/release/tinygo/pkg/thumbv6m-unknown-unknown-eabi-cortex-m0plus
827829
@mkdir -p build/release/tinygo/pkg/thumbv7em-unknown-unknown-eabi-cortex-m4
@@ -872,7 +874,15 @@ endif
872874
@cp -rp lib/picolibc/newlib/libm/common build/release/tinygo/lib/picolibc/newlib/libm
873875
@cp -rp lib/picolibc/newlib/libm/math build/release/tinygo/lib/picolibc/newlib/libm
874876
@cp -rp lib/picolibc-stdio.c build/release/tinygo/lib
875-
@cp -rp lib/wasi-libc/sysroot build/release/tinygo/lib/wasi-libc/sysroot
877+
@cp -rp lib/wasi-libc/libc-bottom-half/headers/public build/release/tinygo/lib/wasi-libc/libc-bottom-half/headers
878+
@cp -rp lib/wasi-libc/libc-top-half/musl/arch/generic build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
879+
@cp -rp lib/wasi-libc/libc-top-half/musl/arch/wasm32 build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
880+
@cp -rp lib/wasi-libc/libc-top-half/musl/src/include build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
881+
@cp -rp lib/wasi-libc/libc-top-half/musl/src/internal build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
882+
@cp -rp lib/wasi-libc/libc-top-half/musl/src/math build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
883+
@cp -rp lib/wasi-libc/libc-top-half/musl/src/string build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
884+
@cp -rp lib/wasi-libc/libc-top-half/musl/include build/release/tinygo/lib/wasi-libc/libc-top-half/musl
885+
@cp -rp lib/wasi-libc/sysroot build/release/tinygo/lib/wasi-libc/sysroot
876886
@cp -rp llvm-project/compiler-rt/lib/builtins build/release/tinygo/lib/compiler-rt-builtins
877887
@cp -rp llvm-project/compiler-rt/LICENSE.TXT build/release/tinygo/lib/compiler-rt-builtins
878888
@cp -rp src build/release/tinygo/src

builder/build.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,13 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
168168
return BuildResult{}, errors.New("could not find wasi-libc, perhaps you need to run `make wasi-libc`?")
169169
}
170170
libcDependencies = append(libcDependencies, dummyCompileJob(path))
171+
case "wasmbuiltins":
172+
libcJob, unlock, err := WasmBuiltins.load(config, tmpdir)
173+
if err != nil {
174+
return BuildResult{}, err
175+
}
176+
defer unlock()
177+
libcDependencies = append(libcDependencies, libcJob)
171178
case "mingw-w64":
172179
_, unlock, err := MinGW.load(config, tmpdir)
173180
if err != nil {

builder/wasmbuiltins.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package builder
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
7+
"github.com/tinygo-org/tinygo/goenv"
8+
)
9+
10+
var WasmBuiltins = Library{
11+
name: "wasmbuiltins",
12+
makeHeaders: func(target, includeDir string) error {
13+
os.Mkdir(includeDir+"/bits", 0o777)
14+
f, err := os.Create(includeDir + "/bits/alltypes.h")
15+
if err != nil {
16+
return err
17+
}
18+
if _, err := f.Write([]byte(wasmAllTypes)); err != nil {
19+
return err
20+
}
21+
return f.Close()
22+
},
23+
cflags: func(target, headerPath string) []string {
24+
libcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/wasi-libc")
25+
return []string{
26+
"-Werror",
27+
"-Wall",
28+
"-std=gnu11",
29+
"-nostdlibinc",
30+
"-isystem", libcDir + "/libc-top-half/musl/arch/wasm32",
31+
"-isystem", libcDir + "/libc-top-half/musl/arch/generic",
32+
"-isystem", libcDir + "/libc-top-half/musl/src/internal",
33+
"-isystem", libcDir + "/libc-top-half/musl/src/include",
34+
"-isystem", libcDir + "/libc-top-half/musl/include",
35+
"-isystem", libcDir + "/libc-bottom-half/headers/public",
36+
"-I" + headerPath,
37+
}
38+
},
39+
sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/wasi-libc") },
40+
librarySources: func(target string) ([]string, error) {
41+
return []string{
42+
// memory builtins needed for llvm.memcpy.*, llvm.memmove.*, and
43+
// llvm.memset.* LLVM intrinsics.
44+
"libc-top-half/musl/src/string/memcpy.c",
45+
"libc-top-half/musl/src/string/memmove.c",
46+
"libc-top-half/musl/src/string/memset.c",
47+
48+
// exp, exp2, and log are needed for LLVM math builtin functions
49+
// like llvm.exp.*.
50+
"libc-top-half/musl/src/math/__math_divzero.c",
51+
"libc-top-half/musl/src/math/__math_invalid.c",
52+
"libc-top-half/musl/src/math/__math_oflow.c",
53+
"libc-top-half/musl/src/math/__math_uflow.c",
54+
"libc-top-half/musl/src/math/__math_xflow.c",
55+
"libc-top-half/musl/src/math/exp.c",
56+
"libc-top-half/musl/src/math/exp_data.c",
57+
"libc-top-half/musl/src/math/exp2.c",
58+
"libc-top-half/musl/src/math/log.c",
59+
"libc-top-half/musl/src/math/log_data.c",
60+
}, nil
61+
},
62+
}
63+
64+
// alltypes.h for wasm-libc, using the types as defined inside Clang.
65+
const wasmAllTypes = `
66+
typedef __SIZE_TYPE__ size_t;
67+
typedef __INT8_TYPE__ int8_t;
68+
typedef __INT16_TYPE__ int16_t;
69+
typedef __INT32_TYPE__ int32_t;
70+
typedef __INT64_TYPE__ int64_t;
71+
typedef __UINT8_TYPE__ uint8_t;
72+
typedef __UINT16_TYPE__ uint16_t;
73+
typedef __UINT32_TYPE__ uint32_t;
74+
typedef __UINT64_TYPE__ uint64_t;
75+
typedef __UINTPTR_TYPE__ uintptr_t;
76+
77+
// This type is used internally in wasi-libc.
78+
typedef double double_t;
79+
`

compileopts/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,8 @@ func (c *Config) CFlags(libclang bool) []string {
311311
case "wasi-libc":
312312
root := goenv.Get("TINYGOROOT")
313313
cflags = append(cflags, "--sysroot="+root+"/lib/wasi-libc/sysroot")
314+
case "wasmbuiltins":
315+
// nothing to add (library is purely for builtins)
314316
case "mingw-w64":
315317
root := goenv.Get("TINYGOROOT")
316318
path, _ := c.LibcPath("mingw-w64")

targets/wasm-unknown.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"goarch": "arm",
88
"linker": "wasm-ld",
99
"rtlib": "compiler-rt",
10+
"libc": "wasmbuiltins",
1011
"scheduler": "none",
1112
"gc": "leaking",
1213
"default-stack-size": 4096,

0 commit comments

Comments
 (0)