From 03e3a66ed77460fad2ac3376056c8f4482510a2b Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Jan 11 2022 08:37:51 +0000 Subject: Backport support for LLVM 13 --- diff --git a/0001-Skip-WASI-tests.patch b/0001-Skip-WASI-tests.patch index 2d236fe..9c6641f 100644 --- a/0001-Skip-WASI-tests.patch +++ b/0001-Skip-WASI-tests.patch @@ -1,7 +1,7 @@ From 9b9f5ddc40d838c0141a81f718bb57e546dbc742 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Tue, 15 Dec 2020 05:06:04 -0500 -Subject: [PATCH 1/7] Skip WASI tests. +Subject: [PATCH 1/9] Skip WASI tests. We do not have wasmtime available. diff --git a/0002-Add-canThrow-argument-to-llvm.InlineAsm-calls.patch b/0002-Add-canThrow-argument-to-llvm.InlineAsm-calls.patch deleted file mode 100644 index bf348e5..0000000 --- a/0002-Add-canThrow-argument-to-llvm.InlineAsm-calls.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 2b069365b3d57dc0be1dfc32db62847ff4ae744c Mon Sep 17 00:00:00 2001 -From: Elliott Sales de Andrade -Date: Mon, 6 Sep 2021 05:01:19 -0400 -Subject: [PATCH 2/7] Add canThrow argument to llvm.InlineAsm calls - -This is new in LLVM 13, and uses the default `false` which matches the -default in the LLVM-internal `InlineAsm::get`, but I don't know if -that's the right thing here because docs are difficult to find. - -Signed-off-by: Elliott Sales de Andrade ---- - compiler/inlineasm.go | 16 ++++++++-------- - compiler/syscall.go | 8 ++++---- - 2 files changed, 12 insertions(+), 12 deletions(-) - -diff --git a/compiler/inlineasm.go b/compiler/inlineasm.go -index e32a4f39..635aed98 100644 ---- a/compiler/inlineasm.go -+++ b/compiler/inlineasm.go -@@ -24,7 +24,7 @@ func (b *builder) createInlineAsm(args []ssa.Value) (llvm.Value, error) { - // Magic function: insert inline assembly instead of calling it. - fnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{}, false) - asm := constant.StringVal(args[0].(*ssa.Const).Value) -- target := llvm.InlineAsm(fnType, asm, "", true, false, 0) -+ target := llvm.InlineAsm(fnType, asm, "", true, false, 0, false) - return b.CreateCall(target, nil, ""), nil - } - -@@ -116,7 +116,7 @@ func (b *builder) createInlineAsmFull(instr *ssa.CallCommon) (llvm.Value, error) - outputType = b.ctx.VoidType() - } - fnType := llvm.FunctionType(outputType, argTypes, false) -- target := llvm.InlineAsm(fnType, asmString, strings.Join(constraints, ","), true, false, 0) -+ target := llvm.InlineAsm(fnType, asmString, strings.Join(constraints, ","), true, false, 0, false) - result := b.CreateCall(target, args, "") - if hasOutput { - return result, nil -@@ -159,7 +159,7 @@ func (b *builder) emitSVCall(args []ssa.Value) (llvm.Value, error) { - // marked as clobbered. - constraints += ",~{r1},~{r2},~{r3}" - fnType := llvm.FunctionType(b.uintptrType, argTypes, false) -- target := llvm.InlineAsm(fnType, asm, constraints, true, false, 0) -+ target := llvm.InlineAsm(fnType, asm, constraints, true, false, 0, false) - return b.CreateCall(target, llvmArgs, ""), nil - } - -@@ -197,7 +197,7 @@ func (b *builder) emitSV64Call(args []ssa.Value) (llvm.Value, error) { - // marked as clobbered. - constraints += ",~{x1},~{x2},~{x3},~{x4},~{x5},~{x6},~{x7}" - fnType := llvm.FunctionType(b.uintptrType, argTypes, false) -- target := llvm.InlineAsm(fnType, asm, constraints, true, false, 0) -+ target := llvm.InlineAsm(fnType, asm, constraints, true, false, 0, false) - return b.CreateCall(target, llvmArgs, ""), nil - } - -@@ -222,24 +222,24 @@ func (b *builder) emitCSROperation(call *ssa.CallCommon) (llvm.Value, error) { - // marked as such. - fnType := llvm.FunctionType(b.uintptrType, nil, false) - asm := fmt.Sprintf("csrr $0, %d", csr) -- target := llvm.InlineAsm(fnType, asm, "=r", true, false, 0) -+ target := llvm.InlineAsm(fnType, asm, "=r", true, false, 0, false) - return b.CreateCall(target, nil, ""), nil - case "Set": - fnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{b.uintptrType}, false) - asm := fmt.Sprintf("csrw %d, $0", csr) -- target := llvm.InlineAsm(fnType, asm, "r", true, false, 0) -+ target := llvm.InlineAsm(fnType, asm, "r", true, false, 0, false) - return b.CreateCall(target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil - case "SetBits": - // Note: it may be possible to optimize this to csrrsi in many cases. - fnType := llvm.FunctionType(b.uintptrType, []llvm.Type{b.uintptrType}, false) - asm := fmt.Sprintf("csrrs $0, %d, $1", csr) -- target := llvm.InlineAsm(fnType, asm, "=r,r", true, false, 0) -+ target := llvm.InlineAsm(fnType, asm, "=r,r", true, false, 0, false) - return b.CreateCall(target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil - case "ClearBits": - // Note: it may be possible to optimize this to csrrci in many cases. - fnType := llvm.FunctionType(b.uintptrType, []llvm.Type{b.uintptrType}, false) - asm := fmt.Sprintf("csrrc $0, %d, $1", csr) -- target := llvm.InlineAsm(fnType, asm, "=r,r", true, false, 0) -+ target := llvm.InlineAsm(fnType, asm, "=r,r", true, false, 0, false) - return b.CreateCall(target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil - default: - return llvm.Value{}, b.makeError(call.Pos(), "unknown CSR operation: "+name) -diff --git a/compiler/syscall.go b/compiler/syscall.go -index db379d52..37330684 100644 ---- a/compiler/syscall.go -+++ b/compiler/syscall.go -@@ -56,7 +56,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) { - } - constraints += ",~{rcx},~{r11}" - fnType := llvm.FunctionType(b.uintptrType, argTypes, false) -- target := llvm.InlineAsm(fnType, "syscall", constraints, true, false, llvm.InlineAsmDialectIntel) -+ target := llvm.InlineAsm(fnType, "syscall", constraints, true, false, llvm.InlineAsmDialectIntel, false) - return b.CreateCall(target, args, ""), nil - case b.GOARCH == "386" && b.GOOS == "linux": - // Sources: -@@ -82,7 +82,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) { - argTypes = append(argTypes, llvmValue.Type()) - } - fnType := llvm.FunctionType(b.uintptrType, argTypes, false) -- target := llvm.InlineAsm(fnType, "int 0x80", constraints, true, false, llvm.InlineAsmDialectIntel) -+ target := llvm.InlineAsm(fnType, "int 0x80", constraints, true, false, llvm.InlineAsmDialectIntel, false) - return b.CreateCall(target, args, ""), nil - case b.GOARCH == "arm" && b.GOOS == "linux": - // Implement the EABI system call convention for Linux. -@@ -114,7 +114,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) { - constraints += ",~{r" + strconv.Itoa(i) + "}" - } - fnType := llvm.FunctionType(b.uintptrType, argTypes, false) -- target := llvm.InlineAsm(fnType, "svc #0", constraints, true, false, 0) -+ target := llvm.InlineAsm(fnType, "svc #0", constraints, true, false, 0, false) - return b.CreateCall(target, args, ""), nil - case b.GOARCH == "arm64" && b.GOOS == "linux": - // Source: syscall(2) man page. -@@ -146,7 +146,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) { - } - constraints += ",~{x16},~{x17}" // scratch registers - fnType := llvm.FunctionType(b.uintptrType, argTypes, false) -- target := llvm.InlineAsm(fnType, "svc #0", constraints, true, false, 0) -+ target := llvm.InlineAsm(fnType, "svc #0", constraints, true, false, 0, false) - return b.CreateCall(target, args, ""), nil - default: - return llvm.Value{}, b.makeError(call.Pos(), "unknown GOOS/GOARCH for syscall: "+b.GOOS+"/"+b.GOARCH) --- -2.31.1 - diff --git a/0002-Use-system-mingw64-headers-and-crt.patch b/0002-Use-system-mingw64-headers-and-crt.patch new file mode 100644 index 0000000..71b83cd --- /dev/null +++ b/0002-Use-system-mingw64-headers-and-crt.patch @@ -0,0 +1,121 @@ +From e981e11100f9cb9c79bfd62a7e57df60929cda7b Mon Sep 17 00:00:00 2001 +From: Elliott Sales de Andrade +Date: Sun, 2 Jan 2022 05:47:18 -0500 +Subject: [PATCH 2/9] Use system mingw64 headers and crt + +Signed-off-by: Elliott Sales de Andrade +--- + builder/mingw-w64.go | 66 +++---------------------------------------- + compileopts/config.go | 7 ++--- + 2 files changed, 6 insertions(+), 67 deletions(-) + +diff --git a/builder/mingw-w64.go b/builder/mingw-w64.go +index bdab730f..07ce05c8 100644 +--- a/builder/mingw-w64.go ++++ b/builder/mingw-w64.go +@@ -1,31 +1,11 @@ + package builder + + import ( +- "io" +- "os" +- "path/filepath" +- "strings" +- +- "github.com/tinygo-org/tinygo/goenv" ++ "fmt" + ) + + var MinGW = Library{ + name: "mingw-w64", +- makeHeaders: func(target, includeDir string) error { +- // copy _mingw.h +- srcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib", "mingw-w64") +- outf, err := os.Create(includeDir + "/_mingw.h") +- if err != nil { +- return err +- } +- defer outf.Close() +- inf, err := os.Open(srcDir + "/mingw-w64-headers/crt/_mingw.h.in") +- if err != nil { +- return err +- } +- _, err = io.Copy(outf, inf) +- return err +- }, + cflags: func(target, headerPath string) []string { + // No flags necessary because there are no files to compile. + return nil +@@ -44,47 +24,9 @@ var MinGW = Library{ + // compile these files. + func makeMinGWExtraLibs(tmpdir string) []*compileJob { + var jobs []*compileJob +- root := goenv.Get("TINYGOROOT") +- // Normally all the api-ms-win-crt-*.def files are all compiled to a single +- // .lib file. But to simplify things, we're going to leave them as separate +- // files. +- for _, name := range []string{ +- "kernel32.def.in", +- "api-ms-win-crt-conio-l1-1-0.def", +- "api-ms-win-crt-convert-l1-1-0.def", +- "api-ms-win-crt-environment-l1-1-0.def", +- "api-ms-win-crt-filesystem-l1-1-0.def", +- "api-ms-win-crt-heap-l1-1-0.def", +- "api-ms-win-crt-locale-l1-1-0.def", +- "api-ms-win-crt-math-l1-1-0.def.in", +- "api-ms-win-crt-multibyte-l1-1-0.def", +- "api-ms-win-crt-private-l1-1-0.def.in", +- "api-ms-win-crt-process-l1-1-0.def", +- "api-ms-win-crt-runtime-l1-1-0.def.in", +- "api-ms-win-crt-stdio-l1-1-0.def", +- "api-ms-win-crt-string-l1-1-0.def", +- "api-ms-win-crt-time-l1-1-0.def", +- "api-ms-win-crt-utility-l1-1-0.def", +- } { +- outpath := filepath.Join(tmpdir, filepath.Base(name)+".lib") +- inpath := filepath.Join(root, "lib/mingw-w64/mingw-w64-crt/lib-common/"+name) +- job := &compileJob{ +- description: "create lib file " + inpath, +- result: outpath, +- run: func(job *compileJob) error { +- defpath := inpath +- if strings.HasSuffix(inpath, ".in") { +- // .in files need to be preprocessed by a preprocessor (-E) +- // first. +- defpath = outpath + ".def" +- err := runCCompiler("-E", "-x", "c", "-Wp,-w", "-P", "-DDEF_X64", "-o", defpath, inpath, "-I"+goenv.Get("TINYGOROOT")+"/lib/mingw-w64/mingw-w64-crt/def-include/") +- if err != nil { +- return err +- } +- } +- return link("ld.lld", "-m", "i386pep", "-o", outpath, defpath) +- }, +- } ++ for _, name := range []string{"kernel32", "ucrt"} { ++ outpath := fmt.Sprintf("/usr/x86_64-w64-mingw32/sys-root/mingw/lib/lib%s.a", name) ++ job := dummyCompileJob(outpath) + jobs = append(jobs, job) + } + return jobs +diff --git a/compileopts/config.go b/compileopts/config.go +index 22cb676e..1f54e157 100644 +--- a/compileopts/config.go ++++ b/compileopts/config.go +@@ -273,12 +273,9 @@ func (c *Config) CFlags() []string { + root := goenv.Get("TINYGOROOT") + cflags = append(cflags, "--sysroot="+root+"/lib/wasi-libc/sysroot") + case "mingw-w64": +- root := goenv.Get("TINYGOROOT") +- path, _ := c.LibcPath("mingw-w64") + cflags = append(cflags, +- "--sysroot="+path, +- "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "crt"), +- "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "defaults", "include"), ++ "--sysroot=/usr/x86_64-w64-mingw32/sys-root", ++ "-Xclang", "-internal-isystem", "-Xclang", "/usr/x86_64-w64-mingw32/sys-root/mingw/include", + "-D_UCRT", + ) + case "": +-- +2.31.1 + diff --git a/0003-Use-system-mingw64-headers-and-crt.patch b/0003-Use-system-mingw64-headers-and-crt.patch deleted file mode 100644 index 524e404..0000000 --- a/0003-Use-system-mingw64-headers-and-crt.patch +++ /dev/null @@ -1,121 +0,0 @@ -From e26581e0d413b241195b7eee63d6499aa9fca3d5 Mon Sep 17 00:00:00 2001 -From: Elliott Sales de Andrade -Date: Sun, 2 Jan 2022 05:47:18 -0500 -Subject: [PATCH 3/7] Use system mingw64 headers and crt - -Signed-off-by: Elliott Sales de Andrade ---- - builder/mingw-w64.go | 66 +++---------------------------------------- - compileopts/config.go | 7 ++--- - 2 files changed, 6 insertions(+), 67 deletions(-) - -diff --git a/builder/mingw-w64.go b/builder/mingw-w64.go -index bdab730f..07ce05c8 100644 ---- a/builder/mingw-w64.go -+++ b/builder/mingw-w64.go -@@ -1,31 +1,11 @@ - package builder - - import ( -- "io" -- "os" -- "path/filepath" -- "strings" -- -- "github.com/tinygo-org/tinygo/goenv" -+ "fmt" - ) - - var MinGW = Library{ - name: "mingw-w64", -- makeHeaders: func(target, includeDir string) error { -- // copy _mingw.h -- srcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib", "mingw-w64") -- outf, err := os.Create(includeDir + "/_mingw.h") -- if err != nil { -- return err -- } -- defer outf.Close() -- inf, err := os.Open(srcDir + "/mingw-w64-headers/crt/_mingw.h.in") -- if err != nil { -- return err -- } -- _, err = io.Copy(outf, inf) -- return err -- }, - cflags: func(target, headerPath string) []string { - // No flags necessary because there are no files to compile. - return nil -@@ -44,47 +24,9 @@ var MinGW = Library{ - // compile these files. - func makeMinGWExtraLibs(tmpdir string) []*compileJob { - var jobs []*compileJob -- root := goenv.Get("TINYGOROOT") -- // Normally all the api-ms-win-crt-*.def files are all compiled to a single -- // .lib file. But to simplify things, we're going to leave them as separate -- // files. -- for _, name := range []string{ -- "kernel32.def.in", -- "api-ms-win-crt-conio-l1-1-0.def", -- "api-ms-win-crt-convert-l1-1-0.def", -- "api-ms-win-crt-environment-l1-1-0.def", -- "api-ms-win-crt-filesystem-l1-1-0.def", -- "api-ms-win-crt-heap-l1-1-0.def", -- "api-ms-win-crt-locale-l1-1-0.def", -- "api-ms-win-crt-math-l1-1-0.def.in", -- "api-ms-win-crt-multibyte-l1-1-0.def", -- "api-ms-win-crt-private-l1-1-0.def.in", -- "api-ms-win-crt-process-l1-1-0.def", -- "api-ms-win-crt-runtime-l1-1-0.def.in", -- "api-ms-win-crt-stdio-l1-1-0.def", -- "api-ms-win-crt-string-l1-1-0.def", -- "api-ms-win-crt-time-l1-1-0.def", -- "api-ms-win-crt-utility-l1-1-0.def", -- } { -- outpath := filepath.Join(tmpdir, filepath.Base(name)+".lib") -- inpath := filepath.Join(root, "lib/mingw-w64/mingw-w64-crt/lib-common/"+name) -- job := &compileJob{ -- description: "create lib file " + inpath, -- result: outpath, -- run: func(job *compileJob) error { -- defpath := inpath -- if strings.HasSuffix(inpath, ".in") { -- // .in files need to be preprocessed by a preprocessor (-E) -- // first. -- defpath = outpath + ".def" -- err := runCCompiler("-E", "-x", "c", "-Wp,-w", "-P", "-DDEF_X64", "-o", defpath, inpath, "-I"+goenv.Get("TINYGOROOT")+"/lib/mingw-w64/mingw-w64-crt/def-include/") -- if err != nil { -- return err -- } -- } -- return link("ld.lld", "-m", "i386pep", "-o", outpath, defpath) -- }, -- } -+ for _, name := range []string{"kernel32", "ucrt"} { -+ outpath := fmt.Sprintf("/usr/x86_64-w64-mingw32/sys-root/mingw/lib/lib%s.a", name) -+ job := dummyCompileJob(outpath) - jobs = append(jobs, job) - } - return jobs -diff --git a/compileopts/config.go b/compileopts/config.go -index 22cb676e..1f54e157 100644 ---- a/compileopts/config.go -+++ b/compileopts/config.go -@@ -273,12 +273,9 @@ func (c *Config) CFlags() []string { - root := goenv.Get("TINYGOROOT") - cflags = append(cflags, "--sysroot="+root+"/lib/wasi-libc/sysroot") - case "mingw-w64": -- root := goenv.Get("TINYGOROOT") -- path, _ := c.LibcPath("mingw-w64") - cflags = append(cflags, -- "--sysroot="+path, -- "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "crt"), -- "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(root, "lib", "mingw-w64", "mingw-w64-headers", "defaults", "include"), -+ "--sysroot=/usr/x86_64-w64-mingw32/sys-root", -+ "-Xclang", "-internal-isystem", "-Xclang", "/usr/x86_64-w64-mingw32/sys-root/mingw/include", - "-D_UCRT", - ) - case "": --- -2.31.1 - diff --git a/0003-arm-Explicitly-disable-unwind-tables.patch b/0003-arm-Explicitly-disable-unwind-tables.patch new file mode 100644 index 0000000..53bc377 --- /dev/null +++ b/0003-arm-Explicitly-disable-unwind-tables.patch @@ -0,0 +1,43 @@ +From 599bfa2b29c7d50d0871010e282414d94acaf68f Mon Sep 17 00:00:00 2001 +From: Elliott Sales de Andrade +Date: Mon, 3 Jan 2022 18:40:21 -0500 +Subject: [PATCH 3/9] arm: Explicitly disable unwind tables + +Some clang builds (e.g., Fedora's) enable unwind tables by default. As +tinygo does not need nor support them, that leads to undefined symbols +when linking. + +Signed-off-by: Elliott Sales de Andrade +--- + builder/library.go | 2 +- + compileopts/target.go | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/builder/library.go b/builder/library.go +index 73079785..012e4053 100644 +--- a/builder/library.go ++++ b/builder/library.go +@@ -120,7 +120,7 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ + } + } + if strings.HasPrefix(target, "arm") || strings.HasPrefix(target, "thumb") { +- args = append(args, "-fshort-enums", "-fomit-frame-pointer", "-mfloat-abi=soft") ++ args = append(args, "-fshort-enums", "-fomit-frame-pointer", "-mfloat-abi=soft", "-fno-unwind-tables") + } + if strings.HasPrefix(target, "riscv32-") { + args = append(args, "-march=rv32imac", "-mabi=ilp32", "-fforce-enable-int128") +diff --git a/compileopts/target.go b/compileopts/target.go +index 2e5f5487..829b481e 100644 +--- a/compileopts/target.go ++++ b/compileopts/target.go +@@ -256,6 +256,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { + spec.Features = "+cx8,+fxsr,+mmx,+sse,+sse2,+x87" + case "arm": + spec.CPU = "generic" ++ spec.CFlags = append(spec.CFlags, "-fno-unwind-tables") + switch strings.Split(triple, "-")[0] { + case "armv5": + spec.Features = "+armv5t,+strict-align,-thumb-mode" +-- +2.31.1 + diff --git a/0004-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch b/0004-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch new file mode 100644 index 0000000..804f479 --- /dev/null +++ b/0004-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch @@ -0,0 +1,43 @@ +From 6506b2a0081f5bb6a23f2262365fafaed1fa52a6 Mon Sep 17 00:00:00 2001 +From: Elliott Sales de Andrade +Date: Mon, 3 Jan 2022 22:39:31 -0500 +Subject: [PATCH 4/9] Skip some cross Linux tests where qemu is broken + +The upstream issues will hopefully be fixed soon: + +- https://gitlab.com/qemu-project/qemu/-/issues/447 +- https://gitlab.com/qemu-project/qemu/-/issues/690 + +Signed-off-by: Elliott Sales de Andrade +--- + main_test.go | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/main_test.go b/main_test.go +index d74e0d67..8850ef5f 100644 +--- a/main_test.go ++++ b/main_test.go +@@ -297,6 +297,20 @@ func runTestWithConfig(name string, t *testing.T, options compileopts.Options, c + return + } + ++ // Skip running the test executable due to bugs in qemu. ++ // https://gitlab.com/qemu-project/qemu/-/issues/447 ++ // https://gitlab.com/qemu-project/qemu/-/issues/690 ++ switch runtime.GOARCH { ++ case "arm64": ++ if options.GOARCH == "386" || options.GOARCH == "arm" { ++ return ++ } ++ case "386": ++ if options.GOARCH == "arm" { ++ return ++ } ++ } ++ + // Create the test command, taking care of emulators etc. + var cmd *exec.Cmd + if len(spec.Emulator) == 0 { +-- +2.31.1 + diff --git a/0004-arm-Explicitly-disable-unwind-tables.patch b/0004-arm-Explicitly-disable-unwind-tables.patch deleted file mode 100644 index bbd695a..0000000 --- a/0004-arm-Explicitly-disable-unwind-tables.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 4f3e80094626a2b67075efdb6b899f2ab806725c Mon Sep 17 00:00:00 2001 -From: Elliott Sales de Andrade -Date: Mon, 3 Jan 2022 18:40:21 -0500 -Subject: [PATCH 4/7] arm: Explicitly disable unwind tables - -Some clang builds (e.g., Fedora's) enable unwind tables by default. As -tinygo does not need nor support them, that leads to undefined symbols -when linking. - -Signed-off-by: Elliott Sales de Andrade ---- - builder/library.go | 2 +- - compileopts/target.go | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/builder/library.go b/builder/library.go -index 73079785..012e4053 100644 ---- a/builder/library.go -+++ b/builder/library.go -@@ -120,7 +120,7 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ - } - } - if strings.HasPrefix(target, "arm") || strings.HasPrefix(target, "thumb") { -- args = append(args, "-fshort-enums", "-fomit-frame-pointer", "-mfloat-abi=soft") -+ args = append(args, "-fshort-enums", "-fomit-frame-pointer", "-mfloat-abi=soft", "-fno-unwind-tables") - } - if strings.HasPrefix(target, "riscv32-") { - args = append(args, "-march=rv32imac", "-mabi=ilp32", "-fforce-enable-int128") -diff --git a/compileopts/target.go b/compileopts/target.go -index 2e5f5487..829b481e 100644 ---- a/compileopts/target.go -+++ b/compileopts/target.go -@@ -256,6 +256,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { - spec.Features = "+cx8,+fxsr,+mmx,+sse,+sse2,+x87" - case "arm": - spec.CPU = "generic" -+ spec.CFlags = append(spec.CFlags, "-fno-unwind-tables") - switch strings.Split(triple, "-")[0] { - case "armv5": - spec.Features = "+armv5t,+strict-align,-thumb-mode" --- -2.31.1 - diff --git a/0005-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch b/0005-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch deleted file mode 100644 index 6213390..0000000 --- a/0005-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 4681ad345b38e1fa9627614adf3348886fa4a71c Mon Sep 17 00:00:00 2001 -From: Elliott Sales de Andrade -Date: Mon, 3 Jan 2022 22:39:31 -0500 -Subject: [PATCH 5/7] Skip some cross Linux tests where qemu is broken - -The upstream issues will hopefully be fixed soon: - -- https://gitlab.com/qemu-project/qemu/-/issues/447 -- https://gitlab.com/qemu-project/qemu/-/issues/690 - -Signed-off-by: Elliott Sales de Andrade ---- - main_test.go | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/main_test.go b/main_test.go -index d74e0d67..8850ef5f 100644 ---- a/main_test.go -+++ b/main_test.go -@@ -297,6 +297,20 @@ func runTestWithConfig(name string, t *testing.T, options compileopts.Options, c - return - } - -+ // Skip running the test executable due to bugs in qemu. -+ // https://gitlab.com/qemu-project/qemu/-/issues/447 -+ // https://gitlab.com/qemu-project/qemu/-/issues/690 -+ switch runtime.GOARCH { -+ case "arm64": -+ if options.GOARCH == "386" || options.GOARCH == "arm" { -+ return -+ } -+ case "386": -+ if options.GOARCH == "arm" { -+ return -+ } -+ } -+ - // Create the test command, taking care of emulators etc. - var cmd *exec.Cmd - if len(spec.Emulator) == 0 { --- -2.31.1 - diff --git a/0005-targets-change-LLVM-features-to-match-vanilla-Clang.patch b/0005-targets-change-LLVM-features-to-match-vanilla-Clang.patch new file mode 100644 index 0000000..345d0e5 --- /dev/null +++ b/0005-targets-change-LLVM-features-to-match-vanilla-Clang.patch @@ -0,0 +1,129 @@ +From 1ab38efdc2f633ee27785f1cd8424fc133097a9e Mon Sep 17 00:00:00 2001 +From: Ayke van Laethem +Date: Fri, 19 Nov 2021 14:47:55 +0100 +Subject: [PATCH 5/9] targets: change LLVM features to match vanilla Clang + +I mistakenly believed the difference was in LLVM version 11.0.0 vs LLVM +11.1.0. However, the difference is in whether we use the Debian version +of Clang. + +The Debian version has had lots of patches. I'm not sure which is to +blame, but it could be this one: +https://salsa.debian.org/pkg-llvm-team/llvm-toolchain/-/blob/snapshot/debian/patches/clang-arm-default-vfp3-on-armv7a.patch + +Signed-off-by: Elliott Sales de Andrade +--- + builder/builder_test.go | 19 ++++++++++++------- + compileopts/target.go | 2 +- + targets/cortex-m0.json | 2 +- + targets/cortex-m0plus.json | 2 +- + targets/cortex-m3.json | 2 +- + targets/gameboy-advance.json | 2 +- + 6 files changed, 17 insertions(+), 12 deletions(-) + +diff --git a/builder/builder_test.go b/builder/builder_test.go +index cff43db8..c38d360a 100644 +--- a/builder/builder_test.go ++++ b/builder/builder_test.go +@@ -5,6 +5,7 @@ import ( + "io/ioutil" + "os" + "path/filepath" ++ "runtime" + "testing" + + "github.com/tinygo-org/tinygo/compileopts" +@@ -60,7 +61,11 @@ func TestClangAttributes(t *testing.T) { + {GOOS: "darwin", GOARCH: "arm64"}, + {GOOS: "windows", GOARCH: "amd64"}, + } { +- t.Run("GOOS="+options.GOOS+",GOARCH="+options.GOARCH, func(t *testing.T) { ++ name := "GOOS=" + options.GOOS + ",GOARCH=" + options.GOARCH ++ if options.GOARCH == "arm" { ++ name += ",GOARM=" + options.GOARM ++ } ++ t.Run(name, func(t *testing.T) { + testClangAttributes(t, options) + }) + } +@@ -131,12 +136,12 @@ func testClangAttributes(t *testing.T, options *compileopts.Options) { + t.Errorf("target has CPU %#v but Clang makes it CPU %#v", config.CPU(), cpu) + } + if features != config.Features() { +- if llvm.Version != "11.0.0" { +- // This needs to be removed once we switch to LLVM 12. +- // LLVM 11.0.0 uses a different "target-features" string than LLVM +- // 11.1.0 for Thumb targets. The Xtensa fork is still based on LLVM +- // 11.0.0, so we need to skip this check on that version. +- t.Errorf("target has LLVM features %#v but Clang makes it %#v", config.Features(), features) ++ if hasBuiltinTools || runtime.GOOS != "linux" { ++ // Skip this step when using an external Clang invocation on Linux. ++ // The reason is that Debian has patched Clang in a way that ++ // modifies the LLVM features string, changing lots of FPU/float ++ // related flags. We want to test vanilla Clang, not Debian Clang. ++ t.Errorf("target has LLVM features\n\t%#v\nbut Clang makes it\n\t%#v", config.Features(), features) + } + } + } +diff --git a/compileopts/target.go b/compileopts/target.go +index 829b481e..bdd77613 100644 +--- a/compileopts/target.go ++++ b/compileopts/target.go +@@ -263,7 +263,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { + case "armv6": + spec.Features = "+armv6,+dsp,+fp64,+strict-align,+vfp2,+vfp2sp,-thumb-mode" + case "armv7": +- spec.Features = "+armv7-a,+dsp,+fp64,+vfp2,+vfp2sp,+vfp3d16,+vfp3d16sp,-thumb-mode" ++ spec.Features = "+armv7-a,+d32,+dsp,+fp64,+neon,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,-thumb-mode" + } + case "arm64": + spec.CPU = "generic" +diff --git a/targets/cortex-m0.json b/targets/cortex-m0.json +index fe356805..315d6658 100644 +--- a/targets/cortex-m0.json ++++ b/targets/cortex-m0.json +@@ -2,5 +2,5 @@ + "inherits": ["cortex-m"], + "llvm-target": "thumbv6m-unknown-unknown-eabi", + "cpu": "cortex-m0", +- "features": "+armv6-m,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" ++ "features": "+armv6-m,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2" + } +diff --git a/targets/cortex-m0plus.json b/targets/cortex-m0plus.json +index a21d06ca..6ac9b531 100644 +--- a/targets/cortex-m0plus.json ++++ b/targets/cortex-m0plus.json +@@ -2,5 +2,5 @@ + "inherits": ["cortex-m"], + "llvm-target": "thumbv6m-unknown-unknown-eabi", + "cpu": "cortex-m0plus", +- "features": "+armv6-m,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" ++ "features": "+armv6-m,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2" + } +diff --git a/targets/cortex-m3.json b/targets/cortex-m3.json +index 7b878d52..07d88dfe 100644 +--- a/targets/cortex-m3.json ++++ b/targets/cortex-m3.json +@@ -2,5 +2,5 @@ + "inherits": ["cortex-m"], + "llvm-target": "thumbv7m-unknown-unknown-eabi", + "cpu": "cortex-m3", +- "features": "+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" ++ "features": "+armv7-m,+hwdiv,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2" + } +diff --git a/targets/gameboy-advance.json b/targets/gameboy-advance.json +index 24e16cda..2467b4b9 100644 +--- a/targets/gameboy-advance.json ++++ b/targets/gameboy-advance.json +@@ -1,7 +1,7 @@ + { + "llvm-target": "armv4t-unknown-unknown-eabi", + "cpu": "arm7tdmi", +- "features": "+armv4t,+soft-float,+strict-align,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp", ++ "features": "+armv4t,+strict-align,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2,-thumb-mode", + "build-tags": ["gameboyadvance", "arm7tdmi", "baremetal", "linux", "arm"], + "goos": "linux", + "goarch": "arm", +-- +2.31.1 + diff --git a/0006-all-add-LLVM-12-support.patch b/0006-all-add-LLVM-12-support.patch new file mode 100644 index 0000000..26e2ddb --- /dev/null +++ b/0006-all-add-LLVM-12-support.patch @@ -0,0 +1,469 @@ +From cff70b542db4a8b99e4445c555f70dad32337e5c Mon Sep 17 00:00:00 2001 +From: Ayke van Laethem +Date: Sun, 28 Mar 2021 19:56:03 -0400 +Subject: [PATCH 6/9] all: add LLVM 12 support + +Originally based on a PR by @QuLogic, but extended a lot to get all +tests to pass. + +Signed-off-by: Elliott Sales de Andrade +--- + .circleci/config.yml | 18 +++++++++--------- + .github/workflows/windows.yml | 4 ++-- + Makefile | 14 ++++++-------- + cgo/libclang_config.go | 1 + + cgo/libclang_config_llvm12.go | 14 ++++++++++++++ + compileopts/target.go | 14 ++++++++++++++ + compiler/compiler_test.go | 27 ++++++++++++++++++++++----- + compiler/testdata/channel.ll | 6 +++--- + compiler/testdata/intrinsics-wasm.ll | 6 +++--- + go.mod | 4 ++-- + go.sum | 10 ++++------ + interp/interp_test.go | 1 + + transform/maps_test.go | 1 + + transform/testdata/coroutines.out.ll | 6 +++--- + transform/transform_test.go | 3 ++- + 15 files changed, 87 insertions(+), 42 deletions(-) + create mode 100644 cgo/libclang_config_llvm12.go + +diff --git a/.circleci/config.yml b/.circleci/config.yml +index 61c7e287..50bdd087 100644 +--- a/.circleci/config.yml ++++ b/.circleci/config.yml +@@ -52,12 +52,12 @@ commands: + steps: + - restore_cache: + keys: +- - llvm-source-11-v2 ++ - llvm-source-12-v1 + - run: + name: "Fetch LLVM source" + command: make llvm-source + - save_cache: +- key: llvm-source-11-v2 ++ key: llvm-source-12-v1 + paths: + - llvm-project/clang/lib/Headers + - llvm-project/clang/include +@@ -332,12 +332,12 @@ commands: + - go-cache-macos-v3-{{ checksum "go.mod" }} + - restore_cache: + keys: +- - llvm-source-11-macos-v3 ++ - llvm-source-12-macos-v1 + - run: + name: "Fetch LLVM source" + command: make llvm-source + - save_cache: +- key: llvm-source-11-macos-v3 ++ key: llvm-source-12-macos-v1 + paths: + - llvm-project/clang/lib/Headers + - llvm-project/clang/include +@@ -345,7 +345,7 @@ commands: + - llvm-project/llvm/include + - restore_cache: + keys: +- - llvm-build-11-macos-v5 ++ - llvm-build-12-macos-v1 + - run: + name: "Build LLVM" + command: | +@@ -359,7 +359,7 @@ commands: + find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \; + fi + - save_cache: +- key: llvm-build-11-macos-v5 ++ key: llvm-build-12-macos-v1 + paths: + llvm-build + - restore_cache: +@@ -418,12 +418,12 @@ jobs: + steps: + - test-linux: + llvm: "11" +- test-llvm11-go116: ++ test-llvm12-go116: + docker: + - image: circleci/golang:1.16-buster + steps: + - test-linux: +- llvm: "11" ++ llvm: "12" + assert-test-linux: + docker: + - image: circleci/golang:1.17-buster +@@ -451,7 +451,7 @@ workflows: + test-all: + jobs: + - test-llvm11-go115 +- - test-llvm11-go116 ++ - test-llvm12-go116 + - build-linux + - test-linux-build: + requires: +diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml +index 4bc07d59..8649f635 100644 +--- a/.github/workflows/windows.yml ++++ b/.github/workflows/windows.yml +@@ -27,7 +27,7 @@ jobs: + uses: actions/cache@v2 + id: cache-llvm-source + with: +- key: llvm-source-11-windows-v1 ++ key: llvm-source-12-windows-v1 + path: | + llvm-project/clang/lib/Headers + llvm-project/clang/include +@@ -40,7 +40,7 @@ jobs: + uses: actions/cache@v2 + id: cache-llvm-build + with: +- key: llvm-build-11-windows-v2 ++ key: llvm-build-12-windows-v1 + path: llvm-build + - name: Build LLVM + if: steps.cache-llvm-build.outputs.cache-hit != 'true' +diff --git a/Makefile b/Makefile +index 5de97014..0ebfcd82 100644 +--- a/Makefile ++++ b/Makefile +@@ -59,18 +59,13 @@ ifeq ($(OS),Windows_NT) + + BINARYEN_OPTION += -DCMAKE_EXE_LINKER_FLAGS='-static-libgcc -static-libstdc++' + +- LIBCLANG_NAME = libclang +- + else ifeq ($(shell uname -s),Darwin) + MD5SUM = md5 +- LIBCLANG_NAME = clang + else ifeq ($(shell uname -s),FreeBSD) + MD5SUM = md5 +- LIBCLANG_NAME = clang + START_GROUP = -Wl,--start-group + END_GROUP = -Wl,--end-group + else +- LIBCLANG_NAME = clang + START_GROUP = -Wl,--start-group + END_GROUP = -Wl,--end-group + endif +@@ -86,19 +81,22 @@ LLD_LIBS = $(START_GROUP) $(addprefix -l,$(LLD_LIB_NAMES)) $(END_GROUP) + # Other libraries that are needed to link TinyGo. + EXTRA_LIB_NAMES = LLVMInterpreter + ++# All libraries to be built and linked with the tinygo binary (lib/lib*.a). ++LIB_NAMES = clang $(CLANG_LIB_NAMES) $(LLD_LIB_NAMES) $(EXTRA_LIB_NAMES) ++ + # These build targets appear to be the only ones necessary to build all TinyGo + # dependencies. Only building a subset significantly speeds up rebuilding LLVM. + # The Makefile rules convert a name like lldELF to lib/liblldELF.a to match the + # library path (for ninja). + # This list also includes a few tools that are necessary as part of the full + # TinyGo build. +-NINJA_BUILD_TARGETS = clang llvm-config llvm-ar llvm-nm $(addprefix lib/lib,$(addsuffix .a,$(LIBCLANG_NAME) $(CLANG_LIB_NAMES) $(LLD_LIB_NAMES) $(EXTRA_LIB_NAMES))) ++NINJA_BUILD_TARGETS = clang llvm-config llvm-ar llvm-nm $(addprefix lib/lib,$(addsuffix .a,$(LIB_NAMES))) + + # For static linking. + ifneq ("$(wildcard $(LLVM_BUILDDIR)/bin/llvm-config*)","") + CGO_CPPFLAGS+=$(shell $(LLVM_BUILDDIR)/bin/llvm-config --cppflags) -I$(abspath $(LLVM_BUILDDIR))/tools/clang/include -I$(abspath $(CLANG_SRC))/include -I$(abspath $(LLD_SRC))/include + CGO_CXXFLAGS=-std=c++14 +- CGO_LDFLAGS+=$(abspath $(LLVM_BUILDDIR))/lib/lib$(LIBCLANG_NAME).a -L$(abspath $(LLVM_BUILDDIR)/lib) $(CLANG_LIBS) $(LLD_LIBS) $(shell $(LLVM_BUILDDIR)/bin/llvm-config --ldflags --libs --system-libs $(LLVM_COMPONENTS)) -lstdc++ $(CGO_LDFLAGS_EXTRA) ++ CGO_LDFLAGS+=-L$(abspath $(LLVM_BUILDDIR)/lib) -lclang $(CLANG_LIBS) $(LLD_LIBS) $(shell $(LLVM_BUILDDIR)/bin/llvm-config --ldflags --libs --system-libs $(LLVM_COMPONENTS)) -lstdc++ $(CGO_LDFLAGS_EXTRA) + endif + + +@@ -162,7 +160,7 @@ gen-device-rp: build/gen-device-svd + + # Get LLVM sources. + $(LLVM_PROJECTDIR)/llvm: +- git clone -b xtensa_release_11.0.0 --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR) ++ git clone -b xtensa_release_12.0.1 --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR) + llvm-source: $(LLVM_PROJECTDIR)/llvm + + # Configure LLVM. +diff --git a/cgo/libclang_config.go b/cgo/libclang_config.go +index 4b4ce2db..9f7cdc1c 100644 +--- a/cgo/libclang_config.go ++++ b/cgo/libclang_config.go +@@ -1,4 +1,5 @@ + // +build !byollvm ++// +build !llvm12 + + package cgo + +diff --git a/cgo/libclang_config_llvm12.go b/cgo/libclang_config_llvm12.go +new file mode 100644 +index 00000000..1837cc15 +--- /dev/null ++++ b/cgo/libclang_config_llvm12.go +@@ -0,0 +1,14 @@ ++// +build !byollvm ++// +build llvm12 ++ ++package cgo ++ ++/* ++#cgo linux CFLAGS: -I/usr/lib/llvm-12/include ++#cgo darwin CFLAGS: -I/usr/local/opt/llvm@12/include ++#cgo freebsd CFLAGS: -I/usr/local/llvm12/include ++#cgo linux LDFLAGS: -L/usr/lib/llvm-12/lib -lclang ++#cgo darwin LDFLAGS: -L/usr/local/opt/llvm@12/lib -lclang -lffi ++#cgo freebsd LDFLAGS: -L/usr/local/llvm12/lib -lclang ++*/ ++import "C" +diff --git a/compileopts/target.go b/compileopts/target.go +index bdd77613..57b5bd84 100644 +--- a/compileopts/target.go ++++ b/compileopts/target.go +@@ -12,9 +12,11 @@ import ( + "path/filepath" + "reflect" + "runtime" ++ "strconv" + "strings" + + "github.com/tinygo-org/tinygo/goenv" ++ "tinygo.org/x/go-llvm" + ) + + // Target specification for a given target. Used for bare metal targets. +@@ -280,6 +282,12 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { + } else if goos == "windows" { + spec.Linker = "ld.lld" + spec.Libc = "mingw-w64" ++ // Note: using a medium code model, low image base and no ASLR ++ // because Go doesn't really need those features. ASLR patches ++ // around issues for unsafe languages like C/C++ that are not ++ // normally present in Go (without explicitly opting in). ++ // For more discussion: ++ // https://groups.google.com/g/Golang-nuts/c/Jd9tlNc6jUE/m/Zo-7zIP_m3MJ?pli=1 + spec.LDFlags = append(spec.LDFlags, + "-m", "i386pep", + "-Bdynamic", +@@ -287,6 +295,12 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { + "--gc-sections", + "--no-insert-timestamp", + ) ++ llvmMajor, _ := strconv.Atoi(strings.Split(llvm.Version, ".")[0]) ++ if llvmMajor >= 12 { ++ // This flag was added in LLVM 12. At the same time, LLVM 12 ++ // switched the default from --dynamicbase to --no-dynamicbase. ++ spec.LDFlags = append(spec.LDFlags, "--no-dynamicbase") ++ } + } else { + spec.LDFlags = append(spec.LDFlags, "-no-pie", "-Wl,--gc-sections") // WARNING: clang < 5.0 requires -nopie + } +diff --git a/compiler/compiler_test.go b/compiler/compiler_test.go +index cbf89fe2..3c978274 100644 +--- a/compiler/compiler_test.go ++++ b/compiler/compiler_test.go +@@ -41,6 +41,13 @@ func TestCompiler(t *testing.T) { + t.Skip("compiler tests require LLVM 11 or above, got LLVM ", llvm.Version) + } + ++ // Determine Go minor version (e.g. 16 in go1.16.3). ++ _, goMinor, err := goenv.GetGorootVersion(goenv.Get("GOROOT")) ++ if err != nil { ++ t.Fatal("could not read Go version:", err) ++ } ++ ++ // Determine which tests to run, depending on the Go and LLVM versions. + tests := []testCase{ + {"basic.go", "", ""}, + {"pointer.go", "", ""}, +@@ -58,12 +65,11 @@ func TestCompiler(t *testing.T) { + {"intrinsics.go", "wasm", ""}, + {"gc.go", "", ""}, + } +- +- _, minor, err := goenv.GetGorootVersion(goenv.Get("GOROOT")) +- if err != nil { +- t.Fatal("could not read Go version:", err) ++ if llvmMajor >= 12 { ++ tests = append(tests, testCase{"intrinsics.go", "cortex-m-qemu", ""}) ++ tests = append(tests, testCase{"intrinsics.go", "wasm", ""}) + } +- if minor >= 17 { ++ if goMinor >= 17 { + tests = append(tests, testCase{"go1.17.go", "", ""}) + } + +@@ -201,6 +207,12 @@ func fuzzyEqualIR(s1, s2 string) bool { + // stripped out. + func filterIrrelevantIRLines(lines []string) []string { + var out []string ++ llvmVersion, err := strconv.Atoi(strings.Split(llvm.Version, ".")[0]) ++ if err != nil { ++ // Note: this should never happen and if it does, it will always happen ++ // for a particular build because llvm.Version is a constant. ++ panic(err) ++ } + for _, line := range lines { + line = strings.Split(line, ";")[0] // strip out comments/info + line = strings.TrimRight(line, "\r ") // drop '\r' on Windows and remove trailing spaces from comments +@@ -210,6 +222,11 @@ func filterIrrelevantIRLines(lines []string) []string { + if strings.HasPrefix(line, "source_filename = ") { + continue + } ++ if llvmVersion < 12 && strings.HasPrefix(line, "attributes ") { ++ // Ignore attribute groups. These may change between LLVM versions. ++ // Right now test outputs are for LLVM 12. ++ continue ++ } + out = append(out, line) + } + return out +diff --git a/compiler/testdata/channel.ll b/compiler/testdata/channel.ll +index 04bfa4af..36d7fd96 100644 +--- a/compiler/testdata/channel.ll ++++ b/compiler/testdata/channel.ll +@@ -34,12 +34,12 @@ entry: + ret void + } + +-; Function Attrs: argmemonly nounwind willreturn ++; Function Attrs: argmemonly nofree nosync nounwind willreturn + declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 + + declare void @runtime.chanSend(%runtime.channel* dereferenceable_or_null(32), i8*, %runtime.channelBlockedList* dereferenceable_or_null(24), i8*, i8*) + +-; Function Attrs: argmemonly nounwind willreturn ++; Function Attrs: argmemonly nofree nosync nounwind willreturn + declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 + + ; Function Attrs: nounwind +@@ -119,4 +119,4 @@ select.body: ; preds = %select.next + declare { i32, i1 } @runtime.tryChanSelect(i8*, %runtime.chanSelectState*, i32, i32, i8*, i8*) + + attributes #0 = { nounwind } +-attributes #1 = { argmemonly nounwind willreturn } ++attributes #1 = { argmemonly nofree nosync nounwind willreturn } +diff --git a/compiler/testdata/intrinsics-wasm.ll b/compiler/testdata/intrinsics-wasm.ll +index bebadb08..9e6687d5 100644 +--- a/compiler/testdata/intrinsics-wasm.ll ++++ b/compiler/testdata/intrinsics-wasm.ll +@@ -18,7 +18,7 @@ entry: + ret double %0 + } + +-; Function Attrs: nounwind readnone speculatable willreturn ++; Function Attrs: nofree nosync nounwind readnone speculatable willreturn + declare double @llvm.sqrt.f64(double) #1 + + ; Function Attrs: nounwind +@@ -28,8 +28,8 @@ entry: + ret double %0 + } + +-; Function Attrs: nounwind readnone speculatable willreturn ++; Function Attrs: nofree nosync nounwind readnone speculatable willreturn + declare double @llvm.trunc.f64(double) #1 + + attributes #0 = { nounwind } +-attributes #1 = { nounwind readnone speculatable willreturn } ++attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } +diff --git a/go.mod b/go.mod +index 26a4b027..52dd71c3 100644 +--- a/go.mod ++++ b/go.mod +@@ -3,7 +3,7 @@ module github.com/tinygo-org/tinygo + go 1.15 + + require ( +- github.com/aykevl/go-wasm v0.0.2-0.20211030161413-11881cb9032d // indirect ++ github.com/aykevl/go-wasm v0.0.2-0.20211119014117-0761b1ddcd1a // indirect + github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2 + github.com/chromedp/cdproto v0.0.0-20210113043257-dabd2f2e7693 + github.com/chromedp/chromedp v0.6.4 +@@ -13,5 +13,5 @@ require ( + go.bug.st/serial v1.1.3 + golang.org/x/sys v0.0.0-20210510120138-977fb7262007 + golang.org/x/tools v0.1.6-0.20210813165731-45389f592fe9 +- tinygo.org/x/go-llvm v0.0.0-20210325115028-e7b85195e81c ++ tinygo.org/x/go-llvm v0.0.0-20210907125547-fd2d62ea06be + ) +diff --git a/go.sum b/go.sum +index 1daa9388..73697653 100644 +--- a/go.sum ++++ b/go.sum +@@ -1,5 +1,5 @@ +-github.com/aykevl/go-wasm v0.0.2-0.20211030161413-11881cb9032d h1:JeuI5/546naK5hpOIX+Lq5xE8rvt7uwiTp6iL+pLQgk= +-github.com/aykevl/go-wasm v0.0.2-0.20211030161413-11881cb9032d/go.mod h1:7sXyiaA0WtSogCu67R2252fQpVmJMh9JWJ9ddtGkpWw= ++github.com/aykevl/go-wasm v0.0.2-0.20211119014117-0761b1ddcd1a h1:QPU7APo6y/6VkCDq6HU3WWIUzER8iywSac23+1UQv60= ++github.com/aykevl/go-wasm v0.0.2-0.20211119014117-0761b1ddcd1a/go.mod h1:7sXyiaA0WtSogCu67R2252fQpVmJMh9JWJ9ddtGkpWw= + github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2 h1:oMCHnXa6CCCafdPDbMh/lWRhRByN0VFLvv+g+ayx1SI= + github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= + github.com/chromedp/cdproto v0.0.0-20210113043257-dabd2f2e7693 h1:11eq/RkpaotwdF6b1TRMcdgQUPNmyFEJOB7zLvh0O/Y= +@@ -68,7 +68,5 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= + gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +-tinygo.org/x/go-llvm v0.0.0-20210308112806-9ef958b6bed4 h1:CMUHxVTb+UuUePuMf8vkWjZ3gTp9BBK91KrgOCwoNHs= +-tinygo.org/x/go-llvm v0.0.0-20210308112806-9ef958b6bed4/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE= +-tinygo.org/x/go-llvm v0.0.0-20210325115028-e7b85195e81c h1:vn9IPshzYmzZis10UEVrsIBRv9FpykADw6M3/tHHROg= +-tinygo.org/x/go-llvm v0.0.0-20210325115028-e7b85195e81c/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE= ++tinygo.org/x/go-llvm v0.0.0-20210907125547-fd2d62ea06be h1:syIpWbi/yESuoyijF2nhRdgX4422sNfmij+o73B3+vU= ++tinygo.org/x/go-llvm v0.0.0-20210907125547-fd2d62ea06be/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE= +diff --git a/interp/interp_test.go b/interp/interp_test.go +index 516fdd11..ae2635af 100644 +--- a/interp/interp_test.go ++++ b/interp/interp_test.go +@@ -71,6 +71,7 @@ func runTest(t *testing.T, pathPrefix string) { + defer pm.Dispose() + pm.AddGlobalOptimizerPass() + pm.AddDeadStoreEliminationPass() ++ pm.AddAggressiveDCEPass() + pm.Run(mod) + + // Read the expected output IR. +diff --git a/transform/maps_test.go b/transform/maps_test.go +index 1f821d4b..e8b11133 100644 +--- a/transform/maps_test.go ++++ b/transform/maps_test.go +@@ -18,6 +18,7 @@ func TestOptimizeMaps(t *testing.T) { + pm := llvm.NewPassManager() + defer pm.Dispose() + pm.AddDeadStoreEliminationPass() ++ pm.AddAggressiveDCEPass() + pm.Run(mod) + }) + } +diff --git a/transform/testdata/coroutines.out.ll b/transform/testdata/coroutines.out.ll +index d4a49a5e..de902884 100644 +--- a/transform/testdata/coroutines.out.ll ++++ b/transform/testdata/coroutines.out.ll +@@ -301,13 +301,13 @@ declare i8* @llvm.coro.free(token, i8* nocapture readonly) #0 + ; Function Attrs: nounwind + declare token @llvm.coro.save(i8*) #2 + +-; Function Attrs: argmemonly nounwind willreturn ++; Function Attrs: argmemonly nofree nosync nounwind willreturn + declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #3 + +-; Function Attrs: argmemonly nounwind willreturn ++; Function Attrs: argmemonly nofree nosync nounwind willreturn + declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #3 + + attributes #0 = { argmemonly nounwind readonly } + attributes #1 = { nounwind readnone } + attributes #2 = { nounwind } +-attributes #3 = { argmemonly nounwind willreturn } ++attributes #3 = { argmemonly nofree nosync nounwind willreturn } +diff --git a/transform/transform_test.go b/transform/transform_test.go +index ae531eeb..935d660b 100644 +--- a/transform/transform_test.go ++++ b/transform/transform_test.go +@@ -116,8 +116,9 @@ func filterIrrelevantIRLines(lines []string) []string { + if strings.HasPrefix(line, "source_filename = ") { + continue + } +- if llvmVersion < 11 && strings.HasPrefix(line, "attributes ") { ++ if llvmVersion < 12 && strings.HasPrefix(line, "attributes ") { + // Ignore attribute groups. These may change between LLVM versions. ++ // Right now test outputs are for LLVM 12. + continue + } + out = append(out, line) +-- +2.31.1 + diff --git a/0006-targets-change-LLVM-features-to-match-vanilla-Clang.patch b/0006-targets-change-LLVM-features-to-match-vanilla-Clang.patch deleted file mode 100644 index d0e418a..0000000 --- a/0006-targets-change-LLVM-features-to-match-vanilla-Clang.patch +++ /dev/null @@ -1,129 +0,0 @@ -From a0ebf57f6164d5f795b7022fa26ac8bb66bee9e8 Mon Sep 17 00:00:00 2001 -From: Ayke van Laethem -Date: Fri, 19 Nov 2021 14:47:55 +0100 -Subject: [PATCH 6/7] targets: change LLVM features to match vanilla Clang - -I mistakenly believed the difference was in LLVM version 11.0.0 vs LLVM -11.1.0. However, the difference is in whether we use the Debian version -of Clang. - -The Debian version has had lots of patches. I'm not sure which is to -blame, but it could be this one: -https://salsa.debian.org/pkg-llvm-team/llvm-toolchain/-/blob/snapshot/debian/patches/clang-arm-default-vfp3-on-armv7a.patch - -Signed-off-by: Elliott Sales de Andrade ---- - builder/builder_test.go | 19 ++++++++++++------- - compileopts/target.go | 2 +- - targets/cortex-m0.json | 2 +- - targets/cortex-m0plus.json | 2 +- - targets/cortex-m3.json | 2 +- - targets/gameboy-advance.json | 2 +- - 6 files changed, 17 insertions(+), 12 deletions(-) - -diff --git a/builder/builder_test.go b/builder/builder_test.go -index cff43db8..c38d360a 100644 ---- a/builder/builder_test.go -+++ b/builder/builder_test.go -@@ -5,6 +5,7 @@ import ( - "io/ioutil" - "os" - "path/filepath" -+ "runtime" - "testing" - - "github.com/tinygo-org/tinygo/compileopts" -@@ -60,7 +61,11 @@ func TestClangAttributes(t *testing.T) { - {GOOS: "darwin", GOARCH: "arm64"}, - {GOOS: "windows", GOARCH: "amd64"}, - } { -- t.Run("GOOS="+options.GOOS+",GOARCH="+options.GOARCH, func(t *testing.T) { -+ name := "GOOS=" + options.GOOS + ",GOARCH=" + options.GOARCH -+ if options.GOARCH == "arm" { -+ name += ",GOARM=" + options.GOARM -+ } -+ t.Run(name, func(t *testing.T) { - testClangAttributes(t, options) - }) - } -@@ -131,12 +136,12 @@ func testClangAttributes(t *testing.T, options *compileopts.Options) { - t.Errorf("target has CPU %#v but Clang makes it CPU %#v", config.CPU(), cpu) - } - if features != config.Features() { -- if llvm.Version != "11.0.0" { -- // This needs to be removed once we switch to LLVM 12. -- // LLVM 11.0.0 uses a different "target-features" string than LLVM -- // 11.1.0 for Thumb targets. The Xtensa fork is still based on LLVM -- // 11.0.0, so we need to skip this check on that version. -- t.Errorf("target has LLVM features %#v but Clang makes it %#v", config.Features(), features) -+ if hasBuiltinTools || runtime.GOOS != "linux" { -+ // Skip this step when using an external Clang invocation on Linux. -+ // The reason is that Debian has patched Clang in a way that -+ // modifies the LLVM features string, changing lots of FPU/float -+ // related flags. We want to test vanilla Clang, not Debian Clang. -+ t.Errorf("target has LLVM features\n\t%#v\nbut Clang makes it\n\t%#v", config.Features(), features) - } - } - } -diff --git a/compileopts/target.go b/compileopts/target.go -index 829b481e..bdd77613 100644 ---- a/compileopts/target.go -+++ b/compileopts/target.go -@@ -263,7 +263,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { - case "armv6": - spec.Features = "+armv6,+dsp,+fp64,+strict-align,+vfp2,+vfp2sp,-thumb-mode" - case "armv7": -- spec.Features = "+armv7-a,+dsp,+fp64,+vfp2,+vfp2sp,+vfp3d16,+vfp3d16sp,-thumb-mode" -+ spec.Features = "+armv7-a,+d32,+dsp,+fp64,+neon,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,-thumb-mode" - } - case "arm64": - spec.CPU = "generic" -diff --git a/targets/cortex-m0.json b/targets/cortex-m0.json -index fe356805..315d6658 100644 ---- a/targets/cortex-m0.json -+++ b/targets/cortex-m0.json -@@ -2,5 +2,5 @@ - "inherits": ["cortex-m"], - "llvm-target": "thumbv6m-unknown-unknown-eabi", - "cpu": "cortex-m0", -- "features": "+armv6-m,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" -+ "features": "+armv6-m,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2" - } -diff --git a/targets/cortex-m0plus.json b/targets/cortex-m0plus.json -index a21d06ca..6ac9b531 100644 ---- a/targets/cortex-m0plus.json -+++ b/targets/cortex-m0plus.json -@@ -2,5 +2,5 @@ - "inherits": ["cortex-m"], - "llvm-target": "thumbv6m-unknown-unknown-eabi", - "cpu": "cortex-m0plus", -- "features": "+armv6-m,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" -+ "features": "+armv6-m,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2" - } -diff --git a/targets/cortex-m3.json b/targets/cortex-m3.json -index 7b878d52..07d88dfe 100644 ---- a/targets/cortex-m3.json -+++ b/targets/cortex-m3.json -@@ -2,5 +2,5 @@ - "inherits": ["cortex-m"], - "llvm-target": "thumbv7m-unknown-unknown-eabi", - "cpu": "cortex-m3", -- "features": "+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" -+ "features": "+armv7-m,+hwdiv,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2" - } -diff --git a/targets/gameboy-advance.json b/targets/gameboy-advance.json -index 24e16cda..2467b4b9 100644 ---- a/targets/gameboy-advance.json -+++ b/targets/gameboy-advance.json -@@ -1,7 +1,7 @@ - { - "llvm-target": "armv4t-unknown-unknown-eabi", - "cpu": "arm7tdmi", -- "features": "+armv4t,+soft-float,+strict-align,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp", -+ "features": "+armv4t,+strict-align,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2,-thumb-mode", - "build-tags": ["gameboyadvance", "arm7tdmi", "baremetal", "linux", "arm"], - "goos": "linux", - "goarch": "arm", --- -2.31.1 - diff --git a/0007-all-add-LLVM-12-support.patch b/0007-all-add-LLVM-12-support.patch deleted file mode 100644 index ff708c7..0000000 --- a/0007-all-add-LLVM-12-support.patch +++ /dev/null @@ -1,469 +0,0 @@ -From aefb7735476f11cbe3b7cb2a026afd34ab74d771 Mon Sep 17 00:00:00 2001 -From: Ayke van Laethem -Date: Sun, 28 Mar 2021 19:56:03 -0400 -Subject: [PATCH 7/7] all: add LLVM 12 support - -Originally based on a PR by @QuLogic, but extended a lot to get all -tests to pass. - -Signed-off-by: Elliott Sales de Andrade ---- - .circleci/config.yml | 18 +++++++++--------- - .github/workflows/windows.yml | 4 ++-- - Makefile | 14 ++++++-------- - cgo/libclang_config.go | 1 + - cgo/libclang_config_llvm12.go | 14 ++++++++++++++ - compileopts/target.go | 14 ++++++++++++++ - compiler/compiler_test.go | 27 ++++++++++++++++++++++----- - compiler/testdata/channel.ll | 6 +++--- - compiler/testdata/intrinsics-wasm.ll | 6 +++--- - go.mod | 4 ++-- - go.sum | 10 ++++------ - interp/interp_test.go | 1 + - transform/maps_test.go | 1 + - transform/testdata/coroutines.out.ll | 6 +++--- - transform/transform_test.go | 3 ++- - 15 files changed, 87 insertions(+), 42 deletions(-) - create mode 100644 cgo/libclang_config_llvm12.go - -diff --git a/.circleci/config.yml b/.circleci/config.yml -index 61c7e287..50bdd087 100644 ---- a/.circleci/config.yml -+++ b/.circleci/config.yml -@@ -52,12 +52,12 @@ commands: - steps: - - restore_cache: - keys: -- - llvm-source-11-v2 -+ - llvm-source-12-v1 - - run: - name: "Fetch LLVM source" - command: make llvm-source - - save_cache: -- key: llvm-source-11-v2 -+ key: llvm-source-12-v1 - paths: - - llvm-project/clang/lib/Headers - - llvm-project/clang/include -@@ -332,12 +332,12 @@ commands: - - go-cache-macos-v3-{{ checksum "go.mod" }} - - restore_cache: - keys: -- - llvm-source-11-macos-v3 -+ - llvm-source-12-macos-v1 - - run: - name: "Fetch LLVM source" - command: make llvm-source - - save_cache: -- key: llvm-source-11-macos-v3 -+ key: llvm-source-12-macos-v1 - paths: - - llvm-project/clang/lib/Headers - - llvm-project/clang/include -@@ -345,7 +345,7 @@ commands: - - llvm-project/llvm/include - - restore_cache: - keys: -- - llvm-build-11-macos-v5 -+ - llvm-build-12-macos-v1 - - run: - name: "Build LLVM" - command: | -@@ -359,7 +359,7 @@ commands: - find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \; - fi - - save_cache: -- key: llvm-build-11-macos-v5 -+ key: llvm-build-12-macos-v1 - paths: - llvm-build - - restore_cache: -@@ -418,12 +418,12 @@ jobs: - steps: - - test-linux: - llvm: "11" -- test-llvm11-go116: -+ test-llvm12-go116: - docker: - - image: circleci/golang:1.16-buster - steps: - - test-linux: -- llvm: "11" -+ llvm: "12" - assert-test-linux: - docker: - - image: circleci/golang:1.17-buster -@@ -451,7 +451,7 @@ workflows: - test-all: - jobs: - - test-llvm11-go115 -- - test-llvm11-go116 -+ - test-llvm12-go116 - - build-linux - - test-linux-build: - requires: -diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml -index 4bc07d59..8649f635 100644 ---- a/.github/workflows/windows.yml -+++ b/.github/workflows/windows.yml -@@ -27,7 +27,7 @@ jobs: - uses: actions/cache@v2 - id: cache-llvm-source - with: -- key: llvm-source-11-windows-v1 -+ key: llvm-source-12-windows-v1 - path: | - llvm-project/clang/lib/Headers - llvm-project/clang/include -@@ -40,7 +40,7 @@ jobs: - uses: actions/cache@v2 - id: cache-llvm-build - with: -- key: llvm-build-11-windows-v2 -+ key: llvm-build-12-windows-v1 - path: llvm-build - - name: Build LLVM - if: steps.cache-llvm-build.outputs.cache-hit != 'true' -diff --git a/Makefile b/Makefile -index 5de97014..0ebfcd82 100644 ---- a/Makefile -+++ b/Makefile -@@ -59,18 +59,13 @@ ifeq ($(OS),Windows_NT) - - BINARYEN_OPTION += -DCMAKE_EXE_LINKER_FLAGS='-static-libgcc -static-libstdc++' - -- LIBCLANG_NAME = libclang -- - else ifeq ($(shell uname -s),Darwin) - MD5SUM = md5 -- LIBCLANG_NAME = clang - else ifeq ($(shell uname -s),FreeBSD) - MD5SUM = md5 -- LIBCLANG_NAME = clang - START_GROUP = -Wl,--start-group - END_GROUP = -Wl,--end-group - else -- LIBCLANG_NAME = clang - START_GROUP = -Wl,--start-group - END_GROUP = -Wl,--end-group - endif -@@ -86,19 +81,22 @@ LLD_LIBS = $(START_GROUP) $(addprefix -l,$(LLD_LIB_NAMES)) $(END_GROUP) - # Other libraries that are needed to link TinyGo. - EXTRA_LIB_NAMES = LLVMInterpreter - -+# All libraries to be built and linked with the tinygo binary (lib/lib*.a). -+LIB_NAMES = clang $(CLANG_LIB_NAMES) $(LLD_LIB_NAMES) $(EXTRA_LIB_NAMES) -+ - # These build targets appear to be the only ones necessary to build all TinyGo - # dependencies. Only building a subset significantly speeds up rebuilding LLVM. - # The Makefile rules convert a name like lldELF to lib/liblldELF.a to match the - # library path (for ninja). - # This list also includes a few tools that are necessary as part of the full - # TinyGo build. --NINJA_BUILD_TARGETS = clang llvm-config llvm-ar llvm-nm $(addprefix lib/lib,$(addsuffix .a,$(LIBCLANG_NAME) $(CLANG_LIB_NAMES) $(LLD_LIB_NAMES) $(EXTRA_LIB_NAMES))) -+NINJA_BUILD_TARGETS = clang llvm-config llvm-ar llvm-nm $(addprefix lib/lib,$(addsuffix .a,$(LIB_NAMES))) - - # For static linking. - ifneq ("$(wildcard $(LLVM_BUILDDIR)/bin/llvm-config*)","") - CGO_CPPFLAGS+=$(shell $(LLVM_BUILDDIR)/bin/llvm-config --cppflags) -I$(abspath $(LLVM_BUILDDIR))/tools/clang/include -I$(abspath $(CLANG_SRC))/include -I$(abspath $(LLD_SRC))/include - CGO_CXXFLAGS=-std=c++14 -- CGO_LDFLAGS+=$(abspath $(LLVM_BUILDDIR))/lib/lib$(LIBCLANG_NAME).a -L$(abspath $(LLVM_BUILDDIR)/lib) $(CLANG_LIBS) $(LLD_LIBS) $(shell $(LLVM_BUILDDIR)/bin/llvm-config --ldflags --libs --system-libs $(LLVM_COMPONENTS)) -lstdc++ $(CGO_LDFLAGS_EXTRA) -+ CGO_LDFLAGS+=-L$(abspath $(LLVM_BUILDDIR)/lib) -lclang $(CLANG_LIBS) $(LLD_LIBS) $(shell $(LLVM_BUILDDIR)/bin/llvm-config --ldflags --libs --system-libs $(LLVM_COMPONENTS)) -lstdc++ $(CGO_LDFLAGS_EXTRA) - endif - - -@@ -162,7 +160,7 @@ gen-device-rp: build/gen-device-svd - - # Get LLVM sources. - $(LLVM_PROJECTDIR)/llvm: -- git clone -b xtensa_release_11.0.0 --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR) -+ git clone -b xtensa_release_12.0.1 --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR) - llvm-source: $(LLVM_PROJECTDIR)/llvm - - # Configure LLVM. -diff --git a/cgo/libclang_config.go b/cgo/libclang_config.go -index 4b4ce2db..9f7cdc1c 100644 ---- a/cgo/libclang_config.go -+++ b/cgo/libclang_config.go -@@ -1,4 +1,5 @@ - // +build !byollvm -+// +build !llvm12 - - package cgo - -diff --git a/cgo/libclang_config_llvm12.go b/cgo/libclang_config_llvm12.go -new file mode 100644 -index 00000000..1837cc15 ---- /dev/null -+++ b/cgo/libclang_config_llvm12.go -@@ -0,0 +1,14 @@ -+// +build !byollvm -+// +build llvm12 -+ -+package cgo -+ -+/* -+#cgo linux CFLAGS: -I/usr/lib/llvm-12/include -+#cgo darwin CFLAGS: -I/usr/local/opt/llvm@12/include -+#cgo freebsd CFLAGS: -I/usr/local/llvm12/include -+#cgo linux LDFLAGS: -L/usr/lib/llvm-12/lib -lclang -+#cgo darwin LDFLAGS: -L/usr/local/opt/llvm@12/lib -lclang -lffi -+#cgo freebsd LDFLAGS: -L/usr/local/llvm12/lib -lclang -+*/ -+import "C" -diff --git a/compileopts/target.go b/compileopts/target.go -index bdd77613..57b5bd84 100644 ---- a/compileopts/target.go -+++ b/compileopts/target.go -@@ -12,9 +12,11 @@ import ( - "path/filepath" - "reflect" - "runtime" -+ "strconv" - "strings" - - "github.com/tinygo-org/tinygo/goenv" -+ "tinygo.org/x/go-llvm" - ) - - // Target specification for a given target. Used for bare metal targets. -@@ -280,6 +282,12 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { - } else if goos == "windows" { - spec.Linker = "ld.lld" - spec.Libc = "mingw-w64" -+ // Note: using a medium code model, low image base and no ASLR -+ // because Go doesn't really need those features. ASLR patches -+ // around issues for unsafe languages like C/C++ that are not -+ // normally present in Go (without explicitly opting in). -+ // For more discussion: -+ // https://groups.google.com/g/Golang-nuts/c/Jd9tlNc6jUE/m/Zo-7zIP_m3MJ?pli=1 - spec.LDFlags = append(spec.LDFlags, - "-m", "i386pep", - "-Bdynamic", -@@ -287,6 +295,12 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { - "--gc-sections", - "--no-insert-timestamp", - ) -+ llvmMajor, _ := strconv.Atoi(strings.Split(llvm.Version, ".")[0]) -+ if llvmMajor >= 12 { -+ // This flag was added in LLVM 12. At the same time, LLVM 12 -+ // switched the default from --dynamicbase to --no-dynamicbase. -+ spec.LDFlags = append(spec.LDFlags, "--no-dynamicbase") -+ } - } else { - spec.LDFlags = append(spec.LDFlags, "-no-pie", "-Wl,--gc-sections") // WARNING: clang < 5.0 requires -nopie - } -diff --git a/compiler/compiler_test.go b/compiler/compiler_test.go -index cbf89fe2..3c978274 100644 ---- a/compiler/compiler_test.go -+++ b/compiler/compiler_test.go -@@ -41,6 +41,13 @@ func TestCompiler(t *testing.T) { - t.Skip("compiler tests require LLVM 11 or above, got LLVM ", llvm.Version) - } - -+ // Determine Go minor version (e.g. 16 in go1.16.3). -+ _, goMinor, err := goenv.GetGorootVersion(goenv.Get("GOROOT")) -+ if err != nil { -+ t.Fatal("could not read Go version:", err) -+ } -+ -+ // Determine which tests to run, depending on the Go and LLVM versions. - tests := []testCase{ - {"basic.go", "", ""}, - {"pointer.go", "", ""}, -@@ -58,12 +65,11 @@ func TestCompiler(t *testing.T) { - {"intrinsics.go", "wasm", ""}, - {"gc.go", "", ""}, - } -- -- _, minor, err := goenv.GetGorootVersion(goenv.Get("GOROOT")) -- if err != nil { -- t.Fatal("could not read Go version:", err) -+ if llvmMajor >= 12 { -+ tests = append(tests, testCase{"intrinsics.go", "cortex-m-qemu", ""}) -+ tests = append(tests, testCase{"intrinsics.go", "wasm", ""}) - } -- if minor >= 17 { -+ if goMinor >= 17 { - tests = append(tests, testCase{"go1.17.go", "", ""}) - } - -@@ -201,6 +207,12 @@ func fuzzyEqualIR(s1, s2 string) bool { - // stripped out. - func filterIrrelevantIRLines(lines []string) []string { - var out []string -+ llvmVersion, err := strconv.Atoi(strings.Split(llvm.Version, ".")[0]) -+ if err != nil { -+ // Note: this should never happen and if it does, it will always happen -+ // for a particular build because llvm.Version is a constant. -+ panic(err) -+ } - for _, line := range lines { - line = strings.Split(line, ";")[0] // strip out comments/info - line = strings.TrimRight(line, "\r ") // drop '\r' on Windows and remove trailing spaces from comments -@@ -210,6 +222,11 @@ func filterIrrelevantIRLines(lines []string) []string { - if strings.HasPrefix(line, "source_filename = ") { - continue - } -+ if llvmVersion < 12 && strings.HasPrefix(line, "attributes ") { -+ // Ignore attribute groups. These may change between LLVM versions. -+ // Right now test outputs are for LLVM 12. -+ continue -+ } - out = append(out, line) - } - return out -diff --git a/compiler/testdata/channel.ll b/compiler/testdata/channel.ll -index 04bfa4af..36d7fd96 100644 ---- a/compiler/testdata/channel.ll -+++ b/compiler/testdata/channel.ll -@@ -34,12 +34,12 @@ entry: - ret void - } - --; Function Attrs: argmemonly nounwind willreturn -+; Function Attrs: argmemonly nofree nosync nounwind willreturn - declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #1 - - declare void @runtime.chanSend(%runtime.channel* dereferenceable_or_null(32), i8*, %runtime.channelBlockedList* dereferenceable_or_null(24), i8*, i8*) - --; Function Attrs: argmemonly nounwind willreturn -+; Function Attrs: argmemonly nofree nosync nounwind willreturn - declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #1 - - ; Function Attrs: nounwind -@@ -119,4 +119,4 @@ select.body: ; preds = %select.next - declare { i32, i1 } @runtime.tryChanSelect(i8*, %runtime.chanSelectState*, i32, i32, i8*, i8*) - - attributes #0 = { nounwind } --attributes #1 = { argmemonly nounwind willreturn } -+attributes #1 = { argmemonly nofree nosync nounwind willreturn } -diff --git a/compiler/testdata/intrinsics-wasm.ll b/compiler/testdata/intrinsics-wasm.ll -index bebadb08..9e6687d5 100644 ---- a/compiler/testdata/intrinsics-wasm.ll -+++ b/compiler/testdata/intrinsics-wasm.ll -@@ -18,7 +18,7 @@ entry: - ret double %0 - } - --; Function Attrs: nounwind readnone speculatable willreturn -+; Function Attrs: nofree nosync nounwind readnone speculatable willreturn - declare double @llvm.sqrt.f64(double) #1 - - ; Function Attrs: nounwind -@@ -28,8 +28,8 @@ entry: - ret double %0 - } - --; Function Attrs: nounwind readnone speculatable willreturn -+; Function Attrs: nofree nosync nounwind readnone speculatable willreturn - declare double @llvm.trunc.f64(double) #1 - - attributes #0 = { nounwind } --attributes #1 = { nounwind readnone speculatable willreturn } -+attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } -diff --git a/go.mod b/go.mod -index 26a4b027..52dd71c3 100644 ---- a/go.mod -+++ b/go.mod -@@ -3,7 +3,7 @@ module github.com/tinygo-org/tinygo - go 1.15 - - require ( -- github.com/aykevl/go-wasm v0.0.2-0.20211030161413-11881cb9032d // indirect -+ github.com/aykevl/go-wasm v0.0.2-0.20211119014117-0761b1ddcd1a // indirect - github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2 - github.com/chromedp/cdproto v0.0.0-20210113043257-dabd2f2e7693 - github.com/chromedp/chromedp v0.6.4 -@@ -13,5 +13,5 @@ require ( - go.bug.st/serial v1.1.3 - golang.org/x/sys v0.0.0-20210510120138-977fb7262007 - golang.org/x/tools v0.1.6-0.20210813165731-45389f592fe9 -- tinygo.org/x/go-llvm v0.0.0-20210325115028-e7b85195e81c -+ tinygo.org/x/go-llvm v0.0.0-20210907125547-fd2d62ea06be - ) -diff --git a/go.sum b/go.sum -index 1daa9388..73697653 100644 ---- a/go.sum -+++ b/go.sum -@@ -1,5 +1,5 @@ --github.com/aykevl/go-wasm v0.0.2-0.20211030161413-11881cb9032d h1:JeuI5/546naK5hpOIX+Lq5xE8rvt7uwiTp6iL+pLQgk= --github.com/aykevl/go-wasm v0.0.2-0.20211030161413-11881cb9032d/go.mod h1:7sXyiaA0WtSogCu67R2252fQpVmJMh9JWJ9ddtGkpWw= -+github.com/aykevl/go-wasm v0.0.2-0.20211119014117-0761b1ddcd1a h1:QPU7APo6y/6VkCDq6HU3WWIUzER8iywSac23+1UQv60= -+github.com/aykevl/go-wasm v0.0.2-0.20211119014117-0761b1ddcd1a/go.mod h1:7sXyiaA0WtSogCu67R2252fQpVmJMh9JWJ9ddtGkpWw= - github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2 h1:oMCHnXa6CCCafdPDbMh/lWRhRByN0VFLvv+g+ayx1SI= - github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= - github.com/chromedp/cdproto v0.0.0-20210113043257-dabd2f2e7693 h1:11eq/RkpaotwdF6b1TRMcdgQUPNmyFEJOB7zLvh0O/Y= -@@ -68,7 +68,5 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= - gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= - gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= --tinygo.org/x/go-llvm v0.0.0-20210308112806-9ef958b6bed4 h1:CMUHxVTb+UuUePuMf8vkWjZ3gTp9BBK91KrgOCwoNHs= --tinygo.org/x/go-llvm v0.0.0-20210308112806-9ef958b6bed4/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE= --tinygo.org/x/go-llvm v0.0.0-20210325115028-e7b85195e81c h1:vn9IPshzYmzZis10UEVrsIBRv9FpykADw6M3/tHHROg= --tinygo.org/x/go-llvm v0.0.0-20210325115028-e7b85195e81c/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE= -+tinygo.org/x/go-llvm v0.0.0-20210907125547-fd2d62ea06be h1:syIpWbi/yESuoyijF2nhRdgX4422sNfmij+o73B3+vU= -+tinygo.org/x/go-llvm v0.0.0-20210907125547-fd2d62ea06be/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE= -diff --git a/interp/interp_test.go b/interp/interp_test.go -index 516fdd11..ae2635af 100644 ---- a/interp/interp_test.go -+++ b/interp/interp_test.go -@@ -71,6 +71,7 @@ func runTest(t *testing.T, pathPrefix string) { - defer pm.Dispose() - pm.AddGlobalOptimizerPass() - pm.AddDeadStoreEliminationPass() -+ pm.AddAggressiveDCEPass() - pm.Run(mod) - - // Read the expected output IR. -diff --git a/transform/maps_test.go b/transform/maps_test.go -index 1f821d4b..e8b11133 100644 ---- a/transform/maps_test.go -+++ b/transform/maps_test.go -@@ -18,6 +18,7 @@ func TestOptimizeMaps(t *testing.T) { - pm := llvm.NewPassManager() - defer pm.Dispose() - pm.AddDeadStoreEliminationPass() -+ pm.AddAggressiveDCEPass() - pm.Run(mod) - }) - } -diff --git a/transform/testdata/coroutines.out.ll b/transform/testdata/coroutines.out.ll -index d4a49a5e..de902884 100644 ---- a/transform/testdata/coroutines.out.ll -+++ b/transform/testdata/coroutines.out.ll -@@ -301,13 +301,13 @@ declare i8* @llvm.coro.free(token, i8* nocapture readonly) #0 - ; Function Attrs: nounwind - declare token @llvm.coro.save(i8*) #2 - --; Function Attrs: argmemonly nounwind willreturn -+; Function Attrs: argmemonly nofree nosync nounwind willreturn - declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) #3 - --; Function Attrs: argmemonly nounwind willreturn -+; Function Attrs: argmemonly nofree nosync nounwind willreturn - declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) #3 - - attributes #0 = { argmemonly nounwind readonly } - attributes #1 = { nounwind readnone } - attributes #2 = { nounwind } --attributes #3 = { argmemonly nounwind willreturn } -+attributes #3 = { argmemonly nofree nosync nounwind willreturn } -diff --git a/transform/transform_test.go b/transform/transform_test.go -index ae531eeb..935d660b 100644 ---- a/transform/transform_test.go -+++ b/transform/transform_test.go -@@ -116,8 +116,9 @@ func filterIrrelevantIRLines(lines []string) []string { - if strings.HasPrefix(line, "source_filename = ") { - continue - } -- if llvmVersion < 11 && strings.HasPrefix(line, "attributes ") { -+ if llvmVersion < 12 && strings.HasPrefix(line, "attributes ") { - // Ignore attribute groups. These may change between LLVM versions. -+ // Right now test outputs are for LLVM 12. - continue - } - out = append(out, line) --- -2.31.1 - diff --git a/0007-tests-improve-wasm-tests-slightly.patch b/0007-tests-improve-wasm-tests-slightly.patch new file mode 100644 index 0000000..cbac6ae --- /dev/null +++ b/0007-tests-improve-wasm-tests-slightly.patch @@ -0,0 +1,262 @@ +From f5ece39b3353ae389ab3da90163b6a49dda1d4aa Mon Sep 17 00:00:00 2001 +From: Ayke van Laethem +Date: Sat, 20 Nov 2021 01:06:02 +0100 +Subject: [PATCH 7/9] tests: improve wasm tests slightly + +These wasm tests weren't passing in GitHub Actions and also weren't +passing on my laptop. I'm not sure why, I think there are a few race +conditions that are going on. + +This commit attempts to fix this at least to a degree: + + - The context deadline is increased from 5 seconds to 10 seconds. + - The tests are not running in parallel anymore. + - Some `Sleep` calls were removed, they do not appear to be necessary + (and if they were, sleeping is the wrong solution to solve race + conditions). + +Overall the tests are taking a few seconds more, but on the other hand +they seem to be passing more reliable. At least for me, on my laptop +(and hopefully also in CI). + +Signed-off-by: Elliott Sales de Andrade +--- + tests/wasm/chan_test.go | 7 ++----- + tests/wasm/event_test.go | 9 ++------- + tests/wasm/fmt_test.go | 8 ++------ + tests/wasm/fmtprint_test.go | 8 ++------ + tests/wasm/log_test.go | 8 ++------ + tests/wasm/setup_test.go | 13 ++++++------- + 6 files changed, 16 insertions(+), 37 deletions(-) + +diff --git a/tests/wasm/chan_test.go b/tests/wasm/chan_test.go +index e44d7ebe..fe981974 100644 +--- a/tests/wasm/chan_test.go ++++ b/tests/wasm/chan_test.go +@@ -2,23 +2,20 @@ package wasm + + import ( + "testing" +- "time" + + "github.com/chromedp/chromedp" + ) + + func TestChan(t *testing.T) { + +- t.Parallel() +- + wasmTmpDir, server := startServer(t) + +- err := run("tinygo build -o " + wasmTmpDir + "/chan.wasm -target wasm testdata/chan.go") ++ err := run(t, "tinygo build -o "+wasmTmpDir+"/chan.wasm -target wasm testdata/chan.go") + if err != nil { + t.Fatal(err) + } + +- ctx, cancel := chromectx(5 * time.Second) ++ ctx, cancel := chromectx() + defer cancel() + + err = chromedp.Run(ctx, +diff --git a/tests/wasm/event_test.go b/tests/wasm/event_test.go +index 038a500a..a29a01c7 100644 +--- a/tests/wasm/event_test.go ++++ b/tests/wasm/event_test.go +@@ -2,35 +2,30 @@ package wasm + + import ( + "testing" +- "time" + + "github.com/chromedp/chromedp" + ) + + func TestEvent(t *testing.T) { + +- t.Parallel() +- + wasmTmpDir, server := startServer(t) + +- err := run("tinygo build -o " + wasmTmpDir + "/event.wasm -target wasm testdata/event.go") ++ err := run(t, "tinygo build -o "+wasmTmpDir+"/event.wasm -target wasm testdata/event.go") + if err != nil { + t.Fatal(err) + } + +- ctx, cancel := chromectx(5 * time.Second) ++ ctx, cancel := chromectx() + defer cancel() + + var log1, log2 string + err = chromedp.Run(ctx, + chromedp.Navigate(server.URL+"/run?file=event.wasm"), + chromedp.WaitVisible("#log"), +- chromedp.Sleep(time.Second), + chromedp.InnerHTML("#log", &log1), + waitLog(`1 + 4`), + chromedp.Click("#testbtn"), +- chromedp.Sleep(time.Second), + chromedp.InnerHTML("#log", &log2), + waitLog(`1 + 4 +diff --git a/tests/wasm/fmt_test.go b/tests/wasm/fmt_test.go +index f9f2f77b..d3695f07 100644 +--- a/tests/wasm/fmt_test.go ++++ b/tests/wasm/fmt_test.go +@@ -2,29 +2,25 @@ package wasm + + import ( + "testing" +- "time" + + "github.com/chromedp/chromedp" + ) + + func TestFmt(t *testing.T) { + +- t.Parallel() +- + wasmTmpDir, server := startServer(t) + +- err := run("tinygo build -o " + wasmTmpDir + "/fmt.wasm -target wasm testdata/fmt.go") ++ err := run(t, "tinygo build -o "+wasmTmpDir+"/fmt.wasm -target wasm testdata/fmt.go") + if err != nil { + t.Fatal(err) + } + +- ctx, cancel := chromectx(5 * time.Second) ++ ctx, cancel := chromectx() + defer cancel() + + var log1 string + err = chromedp.Run(ctx, + chromedp.Navigate(server.URL+"/run?file=fmt.wasm"), +- chromedp.Sleep(time.Second), + chromedp.InnerHTML("#log", &log1), + waitLog(`did not panic`), + ) +diff --git a/tests/wasm/fmtprint_test.go b/tests/wasm/fmtprint_test.go +index 90825ba0..3c750239 100644 +--- a/tests/wasm/fmtprint_test.go ++++ b/tests/wasm/fmtprint_test.go +@@ -2,29 +2,25 @@ package wasm + + import ( + "testing" +- "time" + + "github.com/chromedp/chromedp" + ) + + func TestFmtprint(t *testing.T) { + +- t.Parallel() +- + wasmTmpDir, server := startServer(t) + +- err := run("tinygo build -o " + wasmTmpDir + "/fmtprint.wasm -target wasm testdata/fmtprint.go") ++ err := run(t, "tinygo build -o "+wasmTmpDir+"/fmtprint.wasm -target wasm testdata/fmtprint.go") + if err != nil { + t.Fatal(err) + } + +- ctx, cancel := chromectx(5 * time.Second) ++ ctx, cancel := chromectx() + defer cancel() + + var log1 string + err = chromedp.Run(ctx, + chromedp.Navigate(server.URL+"/run?file=fmtprint.wasm"), +- chromedp.Sleep(time.Second), + chromedp.InnerHTML("#log", &log1), + waitLog(`test from fmtprint 1 + test from fmtprint 2 +diff --git a/tests/wasm/log_test.go b/tests/wasm/log_test.go +index fae4c670..1f6c79fe 100644 +--- a/tests/wasm/log_test.go ++++ b/tests/wasm/log_test.go +@@ -2,29 +2,25 @@ package wasm + + import ( + "testing" +- "time" + + "github.com/chromedp/chromedp" + ) + + func TestLog(t *testing.T) { + +- t.Parallel() +- + wasmTmpDir, server := startServer(t) + +- err := run("tinygo build -o " + wasmTmpDir + "/log.wasm -target wasm testdata/log.go") ++ err := run(t, "tinygo build -o "+wasmTmpDir+"/log.wasm -target wasm testdata/log.go") + if err != nil { + t.Fatal(err) + } + +- ctx, cancel := chromectx(5 * time.Second) ++ ctx, cancel := chromectx() + defer cancel() + + var log1 string + err = chromedp.Run(ctx, + chromedp.Navigate(server.URL+"/run?file=log.wasm"), +- chromedp.Sleep(time.Second), + chromedp.InnerHTML("#log", &log1), + waitLogRe(`^..../../.. ..:..:.. log 1 + ..../../.. ..:..:.. log 2 +diff --git a/tests/wasm/setup_test.go b/tests/wasm/setup_test.go +index 0071076c..e5a18daf 100644 +--- a/tests/wasm/setup_test.go ++++ b/tests/wasm/setup_test.go +@@ -4,7 +4,6 @@ import ( + "context" + "errors" + "fmt" +- "log" + "net/http" + "net/http/httptest" + "os/exec" +@@ -18,29 +17,29 @@ import ( + "github.com/chromedp/chromedp" + ) + +-func run(cmdline string) error { ++func run(t *testing.T, cmdline string) error { + args := strings.Fields(cmdline) +- return runargs(args...) ++ return runargs(t, args...) + } + +-func runargs(args ...string) error { ++func runargs(t *testing.T, args ...string) error { + cmd := exec.Command(args[0], args[1:]...) + b, err := cmd.CombinedOutput() +- log.Printf("Command: %s; err=%v; full output:\n%s", strings.Join(args, " "), err, b) ++ t.Logf("Command: %s; err=%v; full output:\n%s", strings.Join(args, " "), err, b) + if err != nil { + return err + } + return nil + } + +-func chromectx(timeout time.Duration) (context.Context, context.CancelFunc) { ++func chromectx() (context.Context, context.CancelFunc) { + + var ctx context.Context + + // looks for locally installed Chrome + ctx, _ = chromedp.NewContext(context.Background()) + +- ctx, cancel := context.WithTimeout(ctx, timeout) ++ ctx, cancel := context.WithTimeout(ctx, 10*time.Second) + + return ctx, cancel + } +-- +2.31.1 + diff --git a/0008-internal-task-swap-stack-chain-when-switching-gorout.patch b/0008-internal-task-swap-stack-chain-when-switching-gorout.patch new file mode 100644 index 0000000..5cbdbd8 --- /dev/null +++ b/0008-internal-task-swap-stack-chain-when-switching-gorout.patch @@ -0,0 +1,195 @@ +From 1349a7cfc72b3ed0ee6f6d529b8f57ca7d419ecc Mon Sep 17 00:00:00 2001 +From: Nia Waldvogel +Date: Tue, 14 Dec 2021 16:48:11 -0500 +Subject: [PATCH 8/9] internal/task: swap stack chain when switching goroutines + +This change swaps the stack chain when switching goroutines, ensuring that the chain is maintained consistently. +This is only really currently necessary with asyncify on wasm. + +Signed-off-by: Elliott Sales de Andrade +--- + compiler/testdata/channel.ll | 3 ++- + .../testdata/goroutine-cortex-m-qemu-tasks.ll | 3 ++- + compiler/testdata/goroutine-wasm-asyncify.ll | 3 ++- + .../testdata/goroutine-wasm-coroutines.ll | 3 ++- + src/internal/task/gc_stack_chain.go | 19 +++++++++++++++++++ + src/internal/task/gc_stack_noop.go | 9 +++++++++ + src/internal/task/task.go | 3 +++ + src/internal/task/task_asyncify.go | 2 ++ + src/internal/task/task_stack.go | 3 +++ + src/runtime/gc_stack_portable.go | 7 +++++++ + 10 files changed, 51 insertions(+), 4 deletions(-) + create mode 100644 src/internal/task/gc_stack_chain.go + create mode 100644 src/internal/task/gc_stack_noop.go + +diff --git a/compiler/testdata/channel.ll b/compiler/testdata/channel.ll +index 36d7fd96..3f4d5235 100644 +--- a/compiler/testdata/channel.ll ++++ b/compiler/testdata/channel.ll +@@ -5,7 +5,8 @@ target triple = "wasm32-unknown-wasi" + + %runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* } + %runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } } +-%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.state" } ++%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state" } ++%"internal/task.gcData" = type { i8* } + %"internal/task.state" = type { i32, i8*, %"internal/task.stackState", i1 } + %"internal/task.stackState" = type { i32, i32 } + %runtime.chanSelectState = type { %runtime.channel*, i8* } +diff --git a/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll b/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll +index d34a1eb4..6224f256 100644 +--- a/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll ++++ b/compiler/testdata/goroutine-cortex-m-qemu-tasks.ll +@@ -5,7 +5,8 @@ target triple = "thumbv7m-unknown-unknown-eabi" + + %runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* } + %runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } } +-%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.state" } ++%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state" } ++%"internal/task.gcData" = type {} + %"internal/task.state" = type { i32, i32* } + %runtime.chanSelectState = type { %runtime.channel*, i8* } + +diff --git a/compiler/testdata/goroutine-wasm-asyncify.ll b/compiler/testdata/goroutine-wasm-asyncify.ll +index 1ecf0c79..70ec4ef4 100644 +--- a/compiler/testdata/goroutine-wasm-asyncify.ll ++++ b/compiler/testdata/goroutine-wasm-asyncify.ll +@@ -5,7 +5,8 @@ target triple = "wasm32-unknown-wasi" + + %runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* } + %runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } } +-%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.state" } ++%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state" } ++%"internal/task.gcData" = type { i8* } + %"internal/task.state" = type { i32, i8*, %"internal/task.stackState", i1 } + %"internal/task.stackState" = type { i32, i32 } + %runtime.chanSelectState = type { %runtime.channel*, i8* } +diff --git a/compiler/testdata/goroutine-wasm-coroutines.ll b/compiler/testdata/goroutine-wasm-coroutines.ll +index 6f308247..a0c42991 100644 +--- a/compiler/testdata/goroutine-wasm-coroutines.ll ++++ b/compiler/testdata/goroutine-wasm-coroutines.ll +@@ -6,7 +6,8 @@ target triple = "wasm32-unknown-wasi" + %runtime.funcValueWithSignature = type { i32, i8* } + %runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* } + %runtime.channelBlockedList = type { %runtime.channelBlockedList*, %"internal/task.Task"*, %runtime.chanSelectState*, { %runtime.channelBlockedList*, i32, i32 } } +-%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.state" } ++%"internal/task.Task" = type { %"internal/task.Task"*, i8*, i64, %"internal/task.gcData", %"internal/task.state" } ++%"internal/task.gcData" = type {} + %"internal/task.state" = type { i8* } + %runtime.chanSelectState = type { %runtime.channel*, i8* } + +diff --git a/src/internal/task/gc_stack_chain.go b/src/internal/task/gc_stack_chain.go +new file mode 100644 +index 00000000..d3e400d3 +--- /dev/null ++++ b/src/internal/task/gc_stack_chain.go +@@ -0,0 +1,19 @@ ++//go:build (gc.conservative || gc.extalloc) && tinygo.wasm && !scheduler.coroutines ++// +build gc.conservative gc.extalloc ++// +build tinygo.wasm ++// +build !scheduler.coroutines ++ ++package task ++ ++import "unsafe" ++ ++//go:linkname swapStackChain runtime.swapStackChain ++func swapStackChain(dst *unsafe.Pointer) ++ ++type gcData struct { ++ stackChain unsafe.Pointer ++} ++ ++func (gcd *gcData) swap() { ++ swapStackChain(&gcd.stackChain) ++} +diff --git a/src/internal/task/gc_stack_noop.go b/src/internal/task/gc_stack_noop.go +new file mode 100644 +index 00000000..63674805 +--- /dev/null ++++ b/src/internal/task/gc_stack_noop.go +@@ -0,0 +1,9 @@ ++//go:build (!gc.conservative && !gc.extalloc) || !tinygo.wasm || scheduler.coroutines ++// +build !gc.conservative,!gc.extalloc !tinygo.wasm scheduler.coroutines ++ ++package task ++ ++type gcData struct{} ++ ++func (gcd *gcData) swap() { ++} +diff --git a/src/internal/task/task.go b/src/internal/task/task.go +index bad501b6..b490a202 100644 +--- a/src/internal/task/task.go ++++ b/src/internal/task/task.go +@@ -15,6 +15,9 @@ type Task struct { + // Data is a field which can be used for storing state information. + Data uint64 + ++ // gcData holds data for the GC. ++ gcData gcData ++ + // state is the underlying running state of the task. + state state + } +diff --git a/src/internal/task/task_asyncify.go b/src/internal/task/task_asyncify.go +index d67f0e1c..939008bc 100644 +--- a/src/internal/task/task_asyncify.go ++++ b/src/internal/task/task_asyncify.go +@@ -104,6 +104,7 @@ func (*stackState) unwind() + func (t *Task) Resume() { + // The current task must be saved and restored because this can nest on WASM with JS. + prevTask := currentTask ++ t.gcData.swap() + currentTask = t + if !t.state.launched { + t.state.launch() +@@ -112,6 +113,7 @@ func (t *Task) Resume() { + t.state.rewind() + } + currentTask = prevTask ++ t.gcData.swap() + if t.state.asyncifysp > t.state.csp { + runtimePanic("stack overflow") + } +diff --git a/src/internal/task/task_stack.go b/src/internal/task/task_stack.go +index a703d10a..59af6503 100644 +--- a/src/internal/task/task_stack.go ++++ b/src/internal/task/task_stack.go +@@ -1,3 +1,4 @@ ++//go:build scheduler.tasks + // +build scheduler.tasks + + package task +@@ -54,7 +55,9 @@ func pause() { + // This may only be called from the scheduler. + func (t *Task) Resume() { + currentTask = t ++ t.gcData.swap() + t.state.resume() ++ t.gcData.swap() + currentTask = nil + } + +diff --git a/src/runtime/gc_stack_portable.go b/src/runtime/gc_stack_portable.go +index d4a04637..1cdd31f3 100644 +--- a/src/runtime/gc_stack_portable.go ++++ b/src/runtime/gc_stack_portable.go +@@ -1,3 +1,4 @@ ++//go:build (gc.conservative || gc.extalloc) && tinygo.wasm + // +build gc.conservative gc.extalloc + // +build tinygo.wasm + +@@ -37,3 +38,9 @@ func markStack() { + // construction. Calls to it are later replaced with regular stack bookkeeping + // code. + func trackPointer(ptr unsafe.Pointer) ++ ++// swapStackChain swaps the stack chain. ++// This is called from internal/task when switching goroutines. ++func swapStackChain(dst **stackChainObject) { ++ *dst, stackChainStart = stackChainStart, *dst ++} +-- +2.31.1 + diff --git a/0009-all-switch-to-LLVM-13.patch b/0009-all-switch-to-LLVM-13.patch new file mode 100644 index 0000000..1f9d50a --- /dev/null +++ b/0009-all-switch-to-LLVM-13.patch @@ -0,0 +1,960 @@ +From b88f3a8bac4ee3daf56bb1a1dda3211974251043 Mon Sep 17 00:00:00 2001 +From: Ayke van Laethem +Date: Thu, 9 Dec 2021 02:52:08 +0100 +Subject: [PATCH 9/9] all: switch to LLVM 13 + +This adds support for building with `-tags=llvm13` and switches to LLVM +13 for tinygo binaries that are statically linked against LLVM. + +Some notes on this commit: + + * Added `-mfloat-abi=soft` to all Cortex-M targets because otherwise + nrfx would complain that floating point was enabled on Cortex-M0. + That's not the case, but with `-mfloat-abi=soft` the `__SOFTFP__` + macro is defined which silences this warning. + See: https://reviews.llvm.org/D100372 + * Changed from `--sysroot=` to `-nostdlib -isystem ` for + musl because with Clang 13, even with `--sysroot` some system + libraries are used which we don't want. + * Changed all `-Xclang -internal-isystem -Xclang` to simply + `-isystem`, for consistency with the above change. It appears to + have the same effect. + * Moved WebAssembly function declarations to the top of the file in + task_asyncify_wasm.S because (apparently) the assembler has become + more strict. + +Signed-off-by: Elliott Sales de Andrade +--- + .circleci/config.yml | 12 +-- + .github/workflows/windows.yml | 4 +- + Makefile | 8 +- + builder/cc1as.cpp | 79 ++++++++++--------- + builder/cc1as.h | 2 + + builder/picolibc.go | 2 +- + cgo/libclang_config.go | 2 +- + cgo/libclang_config_llvm13.go | 14 ++++ + compileopts/config.go | 13 +-- + compileopts/target.go | 6 +- + compiler/compiler_test.go | 7 +- + compiler/inlineasm.go | 16 ++-- + compiler/syscall.go | 8 +- + compiler/testdata/basic.ll | 2 +- + compiler/testdata/channel.ll | 2 +- + compiler/testdata/float.ll | 2 +- + compiler/testdata/func-coroutines.ll | 2 +- + compiler/testdata/gc.ll | 2 +- + compiler/testdata/go1.17.ll | 2 +- + compiler/testdata/goroutine-wasm-asyncify.ll | 2 +- + .../testdata/goroutine-wasm-coroutines.ll | 2 +- + compiler/testdata/interface.ll | 2 +- + compiler/testdata/intrinsics-wasm.ll | 2 +- + compiler/testdata/pointer.ll | 2 +- + compiler/testdata/pragma.ll | 2 +- + compiler/testdata/slice.ll | 2 +- + compiler/testdata/string.ll | 2 +- + go.mod | 2 +- + go.sum | 4 +- + loader/loader.go | 2 +- + src/internal/task/task_asyncify_wasm.S | 18 ++--- + targets/cortex-m.json | 1 + + targets/cortex-m0.json | 2 +- + targets/cortex-m0plus.json | 2 +- + targets/cortex-m3.json | 2 +- + targets/cortex-m33.json | 5 +- + targets/cortex-m4.json | 5 +- + targets/cortex-m7.json | 5 +- + targets/gameboy-advance.json | 2 +- + targets/k210.json | 2 +- + transform/optimizer.go | 1 + + 41 files changed, 137 insertions(+), 117 deletions(-) + create mode 100644 cgo/libclang_config_llvm13.go + +diff --git a/.circleci/config.yml b/.circleci/config.yml +index 50bdd087..8005a7bb 100644 +--- a/.circleci/config.yml ++++ b/.circleci/config.yml +@@ -52,12 +52,12 @@ commands: + steps: + - restore_cache: + keys: +- - llvm-source-12-v1 ++ - llvm-source-13-v1 + - run: + name: "Fetch LLVM source" + command: make llvm-source + - save_cache: +- key: llvm-source-12-v1 ++ key: llvm-source-13-v1 + paths: + - llvm-project/clang/lib/Headers + - llvm-project/clang/include +@@ -332,12 +332,12 @@ commands: + - go-cache-macos-v3-{{ checksum "go.mod" }} + - restore_cache: + keys: +- - llvm-source-12-macos-v1 ++ - llvm-source-13-macos-v1 + - run: + name: "Fetch LLVM source" + command: make llvm-source + - save_cache: +- key: llvm-source-12-macos-v1 ++ key: llvm-source-13-macos-v1 + paths: + - llvm-project/clang/lib/Headers + - llvm-project/clang/include +@@ -345,7 +345,7 @@ commands: + - llvm-project/llvm/include + - restore_cache: + keys: +- - llvm-build-12-macos-v1 ++ - llvm-build-13-macos-v1 + - run: + name: "Build LLVM" + command: | +@@ -359,7 +359,7 @@ commands: + find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \; + fi + - save_cache: +- key: llvm-build-12-macos-v1 ++ key: llvm-build-13-macos-v1 + paths: + llvm-build + - restore_cache: +diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml +index 8649f635..4aa92532 100644 +--- a/.github/workflows/windows.yml ++++ b/.github/workflows/windows.yml +@@ -27,7 +27,7 @@ jobs: + uses: actions/cache@v2 + id: cache-llvm-source + with: +- key: llvm-source-12-windows-v1 ++ key: llvm-source-13-windows-v1 + path: | + llvm-project/clang/lib/Headers + llvm-project/clang/include +@@ -40,7 +40,7 @@ jobs: + uses: actions/cache@v2 + id: cache-llvm-build + with: +- key: llvm-build-12-windows-v1 ++ key: llvm-build-13-windows-v1 + path: llvm-build + - name: Build LLVM + if: steps.cache-llvm-build.outputs.cache-hit != 'true' +diff --git a/Makefile b/Makefile +index 0ebfcd82..987376f4 100644 +--- a/Makefile ++++ b/Makefile +@@ -10,9 +10,9 @@ LLD_SRC ?= $(LLVM_PROJECTDIR)/lld + + # Try to autodetect LLVM build tools. + detect = $(shell command -v $(1) 2> /dev/null && echo $(1)) +-CLANG ?= $(word 1,$(abspath $(call detect,llvm-build/bin/clang))$(call detect,clang-11)$(call detect,clang)) +-LLVM_AR ?= $(word 1,$(abspath $(call detect,llvm-build/bin/llvm-ar))$(call detect,llvm-ar-11)$(call detect,llvm-ar)) +-LLVM_NM ?= $(word 1,$(abspath $(call detect,llvm-build/bin/llvm-nm))$(call detect,llvm-nm-11)$(call detect,llvm-nm)) ++CLANG ?= $(word 1,$(abspath $(call detect,llvm-build/bin/clang))$(call detect,clang-13)$(call detect,clang-12)$(call detect,clang-11)$(call detect,clang)) ++LLVM_AR ?= $(word 1,$(abspath $(call detect,llvm-build/bin/llvm-ar))$(call detect,llvm-ar-13)$(call detect,llvm-ar-12)$(call detect,llvm-ar-11)$(call detect,llvm-ar)) ++LLVM_NM ?= $(word 1,$(abspath $(call detect,llvm-build/bin/llvm-nm))$(call detect,llvm-nm-13)$(call detect,llvm-nm-12)$(call detect,llvm-nm-11)$(call detect,llvm-nm)) + + # Go binary and GOROOT to select + GO ?= go +@@ -160,7 +160,7 @@ gen-device-rp: build/gen-device-svd + + # Get LLVM sources. + $(LLVM_PROJECTDIR)/llvm: +- git clone -b xtensa_release_12.0.1 --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR) ++ git clone -b xtensa_release_13.0.0 --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR) + llvm-source: $(LLVM_PROJECTDIR)/llvm + + # Configure LLVM. +diff --git a/builder/cc1as.cpp b/builder/cc1as.cpp +index 2553e0e2..ece54124 100644 +--- a/builder/cc1as.cpp ++++ b/builder/cc1as.cpp +@@ -115,29 +115,26 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts, + // Any DebugInfoKind implies GenDwarfForAssembly. + Opts.GenDwarfForAssembly = Args.hasArg(OPT_debug_info_kind_EQ); + +- if (const Arg *A = Args.getLastArg(OPT_compress_debug_sections, +- OPT_compress_debug_sections_EQ)) { +- if (A->getOption().getID() == OPT_compress_debug_sections) { +- // TODO: be more clever about the compression type auto-detection +- Opts.CompressDebugSections = llvm::DebugCompressionType::GNU; +- } else { +- Opts.CompressDebugSections = +- llvm::StringSwitch(A->getValue()) +- .Case("none", llvm::DebugCompressionType::None) +- .Case("zlib", llvm::DebugCompressionType::Z) +- .Case("zlib-gnu", llvm::DebugCompressionType::GNU) +- .Default(llvm::DebugCompressionType::None); +- } ++ if (const Arg *A = Args.getLastArg(OPT_compress_debug_sections_EQ)) { ++ Opts.CompressDebugSections = ++ llvm::StringSwitch(A->getValue()) ++ .Case("none", llvm::DebugCompressionType::None) ++ .Case("zlib", llvm::DebugCompressionType::Z) ++ .Case("zlib-gnu", llvm::DebugCompressionType::GNU) ++ .Default(llvm::DebugCompressionType::None); + } + + Opts.RelaxELFRelocations = Args.hasArg(OPT_mrelax_relocations); ++ if (auto *DwarfFormatArg = Args.getLastArg(OPT_gdwarf64, OPT_gdwarf32)) ++ Opts.Dwarf64 = DwarfFormatArg->getOption().matches(OPT_gdwarf64); + Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 2, Diags); + Opts.DwarfDebugFlags = + std::string(Args.getLastArgValue(OPT_dwarf_debug_flags)); + Opts.DwarfDebugProducer = + std::string(Args.getLastArgValue(OPT_dwarf_debug_producer)); +- Opts.DebugCompilationDir = +- std::string(Args.getLastArgValue(OPT_fdebug_compilation_dir)); ++ if (const Arg *A = Args.getLastArg(options::OPT_ffile_compilation_dir_EQ, ++ options::OPT_fdebug_compilation_dir_EQ)) ++ Opts.DebugCompilationDir = A->getValue(); + Opts.MainFileName = std::string(Args.getLastArgValue(OPT_main_file_name)); + + for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) { +@@ -219,7 +216,7 @@ getOutputStream(StringRef Path, DiagnosticsEngine &Diags, bool Binary) { + + std::error_code EC; + auto Out = std::make_unique( +- Path, EC, (Binary ? sys::fs::OF_None : sys::fs::OF_Text)); ++ Path, EC, (Binary ? sys::fs::OF_None : sys::fs::OF_TextWithCRLF)); + if (EC) { + Diags.Report(diag::err_fe_unable_to_open_output) << Path << EC.message(); + return nullptr; +@@ -228,7 +225,8 @@ getOutputStream(StringRef Path, DiagnosticsEngine &Diags, bool Binary) { + return Out; + } + +-bool ExecuteAssembler(AssemblerInvocation &Opts, DiagnosticsEngine &Diags) { ++static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts, ++ DiagnosticsEngine &Diags) { + // Get the target specific parser. + std::string Error; + const Target *TheTarget = TargetRegistry::lookupTarget(Opts.Triple, Error); +@@ -236,7 +234,7 @@ bool ExecuteAssembler(AssemblerInvocation &Opts, DiagnosticsEngine &Diags) { + return Diags.Report(diag::err_target_unknown_triple) << Opts.Triple; + + ErrorOr> Buffer = +- MemoryBuffer::getFileOrSTDIN(Opts.InputFile); ++ MemoryBuffer::getFileOrSTDIN(Opts.InputFile, /*IsText=*/true); + + if (std::error_code EC = Buffer.getError()) { + Error = EC.message(); +@@ -277,11 +275,15 @@ bool ExecuteAssembler(AssemblerInvocation &Opts, DiagnosticsEngine &Diags) { + if (!Opts.SplitDwarfOutput.empty()) + DwoOS = getOutputStream(Opts.SplitDwarfOutput, Diags, IsBinary); + +- // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and +- // MCObjectFileInfo needs a MCContext reference in order to initialize itself. +- std::unique_ptr MOFI(new MCObjectFileInfo()); ++ // Build up the feature string from the target feature list. ++ std::string FS = llvm::join(Opts.Features, ","); + +- MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr, &MCOptions); ++ std::unique_ptr STI( ++ TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS)); ++ assert(STI && "Unable to create subtarget info!"); ++ ++ MCContext Ctx(Triple(Opts.Triple), MAI.get(), MRI.get(), STI.get(), &SrcMgr, ++ &MCOptions); + + bool PIC = false; + if (Opts.RelocationModel == "static") { +@@ -294,7 +296,12 @@ bool ExecuteAssembler(AssemblerInvocation &Opts, DiagnosticsEngine &Diags) { + PIC = false; + } + +- MOFI->InitMCObjectFileInfo(Triple(Opts.Triple), PIC, Ctx); ++ // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and ++ // MCObjectFileInfo needs a MCContext reference in order to initialize itself. ++ std::unique_ptr MOFI( ++ TheTarget->createMCObjectFileInfo(Ctx, PIC)); ++ Ctx.setObjectFileInfo(MOFI.get()); ++ + if (Opts.SaveTemporaryLabels) + Ctx.setAllowTemporaryLabels(false); + if (Opts.GenDwarfForAssembly) +@@ -316,19 +323,16 @@ bool ExecuteAssembler(AssemblerInvocation &Opts, DiagnosticsEngine &Diags) { + Ctx.addDebugPrefixMapEntry(KV.first, KV.second); + if (!Opts.MainFileName.empty()) + Ctx.setMainFileName(StringRef(Opts.MainFileName)); ++ Ctx.setDwarfFormat(Opts.Dwarf64 ? dwarf::DWARF64 : dwarf::DWARF32); + Ctx.setDwarfVersion(Opts.DwarfVersion); + if (Opts.GenDwarfForAssembly) + Ctx.setGenDwarfRootFile(Opts.InputFile, + SrcMgr.getMemoryBuffer(BufferIndex)->getBuffer()); + +- // Build up the feature string from the target feature list. +- std::string FS = llvm::join(Opts.Features, ","); +- + std::unique_ptr Str; + + std::unique_ptr MCII(TheTarget->createMCInstrInfo()); +- std::unique_ptr STI( +- TheTarget->createMCSubtargetInfo(Opts.Triple, Opts.CPU, FS)); ++ assert(MCII && "Unable to create instruction info!"); + + raw_pwrite_stream *Out = FDOS.get(); + std::unique_ptr BOS; +@@ -367,6 +371,8 @@ bool ExecuteAssembler(AssemblerInvocation &Opts, DiagnosticsEngine &Diags) { + TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx)); + std::unique_ptr MAB( + TheTarget->createMCAsmBackend(*STI, *MRI, MCOptions)); ++ assert(MAB && "Unable to create asm backend!"); ++ + std::unique_ptr OW = + DwoOS ? MAB->createDwoObjectWriter(*Out, *DwoOS) + : MAB->createObjectWriter(*Out); +@@ -381,8 +387,7 @@ bool ExecuteAssembler(AssemblerInvocation &Opts, DiagnosticsEngine &Diags) { + + // When -fembed-bitcode is passed to clang_as, a 1-byte marker + // is emitted in __LLVM,__asm section if the object file is MachO format. +- if (Opts.EmbedBitcode && Ctx.getObjectFileInfo()->getObjectFileType() == +- MCObjectFileInfo::IsMachO) { ++ if (Opts.EmbedBitcode && Ctx.getObjectFileType() == MCContext::IsMachO) { + MCSection *AsmLabel = Ctx.getMachOSection( + "__LLVM", "__asm", MachO::S_REGULAR, 4, SectionKind::getReadOnly()); + Str.get()->SwitchSection(AsmLabel); +@@ -419,12 +424,12 @@ bool ExecuteAssembler(AssemblerInvocation &Opts, DiagnosticsEngine &Diags) { + Failed = Parser->Run(Opts.NoInitialTextSection); + } + +- // Close Streamer first. +- // It might have a reference to the output stream. +- Str.reset(); +- // Close the output stream early. +- BOS.reset(); +- FDOS.reset(); ++ return Failed; ++} ++ ++bool ExecuteAssembler(AssemblerInvocation &Opts, ++ DiagnosticsEngine &Diags) { ++ bool Failed = ExecuteAssemblerImpl(Opts, Diags); + + // Delete output file if there were errors. + if (Failed) { +@@ -472,7 +477,7 @@ int cc1as_main(ArrayRef Argv, const char *Argv0, void *MainAddr) { + return 1; + + if (Asm.ShowHelp) { +- getDriverOptTable().PrintHelp( ++ getDriverOptTable().printHelp( + llvm::outs(), "clang -cc1as [options] file...", + "Clang Integrated Assembler", + /*Include=*/driver::options::CC1AsOption, /*Exclude=*/0, +diff --git a/builder/cc1as.h b/builder/cc1as.h +index ce9a1781..538e9a26 100644 +--- a/builder/cc1as.h ++++ b/builder/cc1as.h +@@ -39,6 +39,7 @@ struct AssemblerInvocation { + unsigned SaveTemporaryLabels : 1; + unsigned GenDwarfForAssembly : 1; + unsigned RelaxELFRelocations : 1; ++ unsigned Dwarf64 : 1; + unsigned DwarfVersion; + std::string DwarfDebugFlags; + std::string DwarfDebugProducer; +@@ -108,6 +109,7 @@ public: + FatalWarnings = 0; + NoWarn = 0; + IncrementalLinkerCompatible = 0; ++ Dwarf64 = 0; + DwarfVersion = 0; + EmbedBitcode = 0; + } +diff --git a/builder/picolibc.go b/builder/picolibc.go +index 75c93e91..af34f7ef 100644 +--- a/builder/picolibc.go ++++ b/builder/picolibc.go +@@ -28,7 +28,7 @@ var Picolibc = Library{ + "-DHAVE_ALIAS_ATTRIBUTE", + "-DTINY_STDIO", + "-nostdlibinc", +- "-Xclang", "-internal-isystem", "-Xclang", picolibcDir + "/include", ++ "-isystem", picolibcDir + "/include", + "-I" + picolibcDir + "/tinystdio", + "-I" + headerPath, + } +diff --git a/cgo/libclang_config.go b/cgo/libclang_config.go +index 9f7cdc1c..ed929f79 100644 +--- a/cgo/libclang_config.go ++++ b/cgo/libclang_config.go +@@ -1,5 +1,5 @@ + // +build !byollvm +-// +build !llvm12 ++// +build !llvm12,!llvm13 + + package cgo + +diff --git a/cgo/libclang_config_llvm13.go b/cgo/libclang_config_llvm13.go +new file mode 100644 +index 00000000..3c961a3f +--- /dev/null ++++ b/cgo/libclang_config_llvm13.go +@@ -0,0 +1,14 @@ ++// +build !byollvm ++// +build llvm13 ++ ++package cgo ++ ++/* ++#cgo linux CFLAGS: -I/usr/lib/llvm-13/include ++#cgo darwin CFLAGS: -I/usr/local/opt/llvm@13/include ++#cgo freebsd CFLAGS: -I/usr/local/llvm13/include ++#cgo linux LDFLAGS: -L/usr/lib/llvm-13/lib -lclang ++#cgo darwin LDFLAGS: -L/usr/local/opt/llvm@13/lib -lclang -lffi ++#cgo freebsd LDFLAGS: -L/usr/local/llvm13/lib -lclang ++*/ ++import "C" +diff --git a/compileopts/config.go b/compileopts/config.go +index 1f54e157..6dc44c79 100644 +--- a/compileopts/config.go ++++ b/compileopts/config.go +@@ -257,17 +257,18 @@ func (c *Config) CFlags() []string { + path, _ := c.LibcPath("picolibc") + cflags = append(cflags, + "--sysroot="+path, +- "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(picolibcDir, "include"), +- "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(picolibcDir, "tinystdio"), ++ "-isystem", filepath.Join(picolibcDir, "include"), ++ "-isystem", filepath.Join(picolibcDir, "tinystdio"), + ) + case "musl": + root := goenv.Get("TINYGOROOT") + path, _ := c.LibcPath("musl") + arch := MuslArchitecture(c.Triple()) + cflags = append(cflags, +- "--sysroot="+path, +- "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(root, "lib", "musl", "arch", arch), +- "-Xclang", "-internal-isystem", "-Xclang", filepath.Join(root, "lib", "musl", "include"), ++ "-nostdlibinc", ++ "-isystem", filepath.Join(path, "include"), ++ "-isystem", filepath.Join(root, "lib", "musl", "arch", arch), ++ "-isystem", filepath.Join(root, "lib", "musl", "include"), + ) + case "wasi-libc": + root := goenv.Get("TINYGOROOT") +@@ -275,7 +276,7 @@ func (c *Config) CFlags() []string { + case "mingw-w64": + cflags = append(cflags, + "--sysroot=/usr/x86_64-w64-mingw32/sys-root", +- "-Xclang", "-internal-isystem", "-Xclang", "/usr/x86_64-w64-mingw32/sys-root/mingw/include", ++ "-isystem", "/usr/x86_64-w64-mingw32/sys-root/mingw/include", + "-D_UCRT", + ) + case "": +diff --git a/compileopts/target.go b/compileopts/target.go +index 57b5bd84..ffdf7365 100644 +--- a/compileopts/target.go ++++ b/compileopts/target.go +@@ -261,11 +261,11 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { + spec.CFlags = append(spec.CFlags, "-fno-unwind-tables") + switch strings.Split(triple, "-")[0] { + case "armv5": +- spec.Features = "+armv5t,+strict-align,-thumb-mode" ++ spec.Features = "+armv5t,+strict-align,-aes,-bf16,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-mve.fp,-neon,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" + case "armv6": +- spec.Features = "+armv6,+dsp,+fp64,+strict-align,+vfp2,+vfp2sp,-thumb-mode" ++ spec.Features = "+armv6,+dsp,+fp64,+strict-align,+vfp2,+vfp2sp,-aes,-d32,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-neon,-sha2,-thumb-mode,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" + case "armv7": +- spec.Features = "+armv7-a,+d32,+dsp,+fp64,+neon,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,-thumb-mode" ++ spec.Features = "+armv7-a,+d32,+dsp,+fp64,+neon,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,-aes,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fullfp16,-sha2,-thumb-mode,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" + } + case "arm64": + spec.CPU = "generic" +diff --git a/compiler/compiler_test.go b/compiler/compiler_test.go +index 3c978274..65a1c626 100644 +--- a/compiler/compiler_test.go ++++ b/compiler/compiler_test.go +@@ -224,7 +224,12 @@ func filterIrrelevantIRLines(lines []string) []string { + } + if llvmVersion < 12 && strings.HasPrefix(line, "attributes ") { + // Ignore attribute groups. These may change between LLVM versions. +- // Right now test outputs are for LLVM 12. ++ // Right now test outputs are for LLVM 12 and higher. ++ continue ++ } ++ if llvmVersion < 13 && strings.HasPrefix(line, "target datalayout = ") { ++ // The datalayout string may vary betewen LLVM versions. ++ // Right now test outputs are for LLVM 13 and higher. + continue + } + out = append(out, line) +diff --git a/compiler/inlineasm.go b/compiler/inlineasm.go +index e32a4f39..635aed98 100644 +--- a/compiler/inlineasm.go ++++ b/compiler/inlineasm.go +@@ -24,7 +24,7 @@ func (b *builder) createInlineAsm(args []ssa.Value) (llvm.Value, error) { + // Magic function: insert inline assembly instead of calling it. + fnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{}, false) + asm := constant.StringVal(args[0].(*ssa.Const).Value) +- target := llvm.InlineAsm(fnType, asm, "", true, false, 0) ++ target := llvm.InlineAsm(fnType, asm, "", true, false, 0, false) + return b.CreateCall(target, nil, ""), nil + } + +@@ -116,7 +116,7 @@ func (b *builder) createInlineAsmFull(instr *ssa.CallCommon) (llvm.Value, error) + outputType = b.ctx.VoidType() + } + fnType := llvm.FunctionType(outputType, argTypes, false) +- target := llvm.InlineAsm(fnType, asmString, strings.Join(constraints, ","), true, false, 0) ++ target := llvm.InlineAsm(fnType, asmString, strings.Join(constraints, ","), true, false, 0, false) + result := b.CreateCall(target, args, "") + if hasOutput { + return result, nil +@@ -159,7 +159,7 @@ func (b *builder) emitSVCall(args []ssa.Value) (llvm.Value, error) { + // marked as clobbered. + constraints += ",~{r1},~{r2},~{r3}" + fnType := llvm.FunctionType(b.uintptrType, argTypes, false) +- target := llvm.InlineAsm(fnType, asm, constraints, true, false, 0) ++ target := llvm.InlineAsm(fnType, asm, constraints, true, false, 0, false) + return b.CreateCall(target, llvmArgs, ""), nil + } + +@@ -197,7 +197,7 @@ func (b *builder) emitSV64Call(args []ssa.Value) (llvm.Value, error) { + // marked as clobbered. + constraints += ",~{x1},~{x2},~{x3},~{x4},~{x5},~{x6},~{x7}" + fnType := llvm.FunctionType(b.uintptrType, argTypes, false) +- target := llvm.InlineAsm(fnType, asm, constraints, true, false, 0) ++ target := llvm.InlineAsm(fnType, asm, constraints, true, false, 0, false) + return b.CreateCall(target, llvmArgs, ""), nil + } + +@@ -222,24 +222,24 @@ func (b *builder) emitCSROperation(call *ssa.CallCommon) (llvm.Value, error) { + // marked as such. + fnType := llvm.FunctionType(b.uintptrType, nil, false) + asm := fmt.Sprintf("csrr $0, %d", csr) +- target := llvm.InlineAsm(fnType, asm, "=r", true, false, 0) ++ target := llvm.InlineAsm(fnType, asm, "=r", true, false, 0, false) + return b.CreateCall(target, nil, ""), nil + case "Set": + fnType := llvm.FunctionType(b.ctx.VoidType(), []llvm.Type{b.uintptrType}, false) + asm := fmt.Sprintf("csrw %d, $0", csr) +- target := llvm.InlineAsm(fnType, asm, "r", true, false, 0) ++ target := llvm.InlineAsm(fnType, asm, "r", true, false, 0, false) + return b.CreateCall(target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil + case "SetBits": + // Note: it may be possible to optimize this to csrrsi in many cases. + fnType := llvm.FunctionType(b.uintptrType, []llvm.Type{b.uintptrType}, false) + asm := fmt.Sprintf("csrrs $0, %d, $1", csr) +- target := llvm.InlineAsm(fnType, asm, "=r,r", true, false, 0) ++ target := llvm.InlineAsm(fnType, asm, "=r,r", true, false, 0, false) + return b.CreateCall(target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil + case "ClearBits": + // Note: it may be possible to optimize this to csrrci in many cases. + fnType := llvm.FunctionType(b.uintptrType, []llvm.Type{b.uintptrType}, false) + asm := fmt.Sprintf("csrrc $0, %d, $1", csr) +- target := llvm.InlineAsm(fnType, asm, "=r,r", true, false, 0) ++ target := llvm.InlineAsm(fnType, asm, "=r,r", true, false, 0, false) + return b.CreateCall(target, []llvm.Value{b.getValue(call.Args[1])}, ""), nil + default: + return llvm.Value{}, b.makeError(call.Pos(), "unknown CSR operation: "+name) +diff --git a/compiler/syscall.go b/compiler/syscall.go +index db379d52..37330684 100644 +--- a/compiler/syscall.go ++++ b/compiler/syscall.go +@@ -56,7 +56,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) { + } + constraints += ",~{rcx},~{r11}" + fnType := llvm.FunctionType(b.uintptrType, argTypes, false) +- target := llvm.InlineAsm(fnType, "syscall", constraints, true, false, llvm.InlineAsmDialectIntel) ++ target := llvm.InlineAsm(fnType, "syscall", constraints, true, false, llvm.InlineAsmDialectIntel, false) + return b.CreateCall(target, args, ""), nil + case b.GOARCH == "386" && b.GOOS == "linux": + // Sources: +@@ -82,7 +82,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) { + argTypes = append(argTypes, llvmValue.Type()) + } + fnType := llvm.FunctionType(b.uintptrType, argTypes, false) +- target := llvm.InlineAsm(fnType, "int 0x80", constraints, true, false, llvm.InlineAsmDialectIntel) ++ target := llvm.InlineAsm(fnType, "int 0x80", constraints, true, false, llvm.InlineAsmDialectIntel, false) + return b.CreateCall(target, args, ""), nil + case b.GOARCH == "arm" && b.GOOS == "linux": + // Implement the EABI system call convention for Linux. +@@ -114,7 +114,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) { + constraints += ",~{r" + strconv.Itoa(i) + "}" + } + fnType := llvm.FunctionType(b.uintptrType, argTypes, false) +- target := llvm.InlineAsm(fnType, "svc #0", constraints, true, false, 0) ++ target := llvm.InlineAsm(fnType, "svc #0", constraints, true, false, 0, false) + return b.CreateCall(target, args, ""), nil + case b.GOARCH == "arm64" && b.GOOS == "linux": + // Source: syscall(2) man page. +@@ -146,7 +146,7 @@ func (b *builder) createRawSyscall(call *ssa.CallCommon) (llvm.Value, error) { + } + constraints += ",~{x16},~{x17}" // scratch registers + fnType := llvm.FunctionType(b.uintptrType, argTypes, false) +- target := llvm.InlineAsm(fnType, "svc #0", constraints, true, false, 0) ++ target := llvm.InlineAsm(fnType, "svc #0", constraints, true, false, 0, false) + return b.CreateCall(target, args, ""), nil + default: + return llvm.Value{}, b.makeError(call.Pos(), "unknown GOOS/GOARCH for syscall: "+b.GOOS+"/"+b.GOARCH) +diff --git a/compiler/testdata/basic.ll b/compiler/testdata/basic.ll +index 56baf3a7..69b72f27 100644 +--- a/compiler/testdata/basic.ll ++++ b/compiler/testdata/basic.ll +@@ -1,6 +1,6 @@ + ; ModuleID = 'basic.go' + source_filename = "basic.go" +-target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" ++target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20" + target triple = "wasm32-unknown-wasi" + + %main.kv = type { float } +diff --git a/compiler/testdata/channel.ll b/compiler/testdata/channel.ll +index 3f4d5235..fa80db5d 100644 +--- a/compiler/testdata/channel.ll ++++ b/compiler/testdata/channel.ll +@@ -1,6 +1,6 @@ + ; ModuleID = 'channel.go' + source_filename = "channel.go" +-target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" ++target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20" + target triple = "wasm32-unknown-wasi" + + %runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* } +diff --git a/compiler/testdata/float.ll b/compiler/testdata/float.ll +index c6964058..e96f8cd7 100644 +--- a/compiler/testdata/float.ll ++++ b/compiler/testdata/float.ll +@@ -1,6 +1,6 @@ + ; ModuleID = 'float.go' + source_filename = "float.go" +-target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" ++target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20" + target triple = "wasm32-unknown-wasi" + + declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +diff --git a/compiler/testdata/func-coroutines.ll b/compiler/testdata/func-coroutines.ll +index eeefa43c..b88ce514 100644 +--- a/compiler/testdata/func-coroutines.ll ++++ b/compiler/testdata/func-coroutines.ll +@@ -1,6 +1,6 @@ + ; ModuleID = 'func.go' + source_filename = "func.go" +-target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" ++target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20" + target triple = "wasm32-unknown-wasi" + + %runtime.funcValueWithSignature = type { i32, i8* } +diff --git a/compiler/testdata/gc.ll b/compiler/testdata/gc.ll +index 375763f3..90e6b6e8 100644 +--- a/compiler/testdata/gc.ll ++++ b/compiler/testdata/gc.ll +@@ -1,6 +1,6 @@ + ; ModuleID = 'gc.go' + source_filename = "gc.go" +-target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" ++target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20" + target triple = "wasm32-unknown-wasi" + + %runtime.typecodeID = type { %runtime.typecodeID*, i32, %runtime.interfaceMethodInfo*, %runtime.typecodeID*, i32 } +diff --git a/compiler/testdata/go1.17.ll b/compiler/testdata/go1.17.ll +index 5c26166a..1499547f 100644 +--- a/compiler/testdata/go1.17.ll ++++ b/compiler/testdata/go1.17.ll +@@ -1,6 +1,6 @@ + ; ModuleID = 'go1.17.go' + source_filename = "go1.17.go" +-target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" ++target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20" + target triple = "wasm32-unknown-wasi" + + declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +diff --git a/compiler/testdata/goroutine-wasm-asyncify.ll b/compiler/testdata/goroutine-wasm-asyncify.ll +index 70ec4ef4..0220bd5b 100644 +--- a/compiler/testdata/goroutine-wasm-asyncify.ll ++++ b/compiler/testdata/goroutine-wasm-asyncify.ll +@@ -1,6 +1,6 @@ + ; ModuleID = 'goroutine.go' + source_filename = "goroutine.go" +-target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" ++target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20" + target triple = "wasm32-unknown-wasi" + + %runtime.channel = type { i32, i32, i8, %runtime.channelBlockedList*, i32, i32, i32, i8* } +diff --git a/compiler/testdata/goroutine-wasm-coroutines.ll b/compiler/testdata/goroutine-wasm-coroutines.ll +index a0c42991..fe7b89b5 100644 +--- a/compiler/testdata/goroutine-wasm-coroutines.ll ++++ b/compiler/testdata/goroutine-wasm-coroutines.ll +@@ -1,6 +1,6 @@ + ; ModuleID = 'goroutine.go' + source_filename = "goroutine.go" +-target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" ++target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20" + target triple = "wasm32-unknown-wasi" + + %runtime.funcValueWithSignature = type { i32, i8* } +diff --git a/compiler/testdata/interface.ll b/compiler/testdata/interface.ll +index f5afb0f3..c27142ec 100644 +--- a/compiler/testdata/interface.ll ++++ b/compiler/testdata/interface.ll +@@ -1,6 +1,6 @@ + ; ModuleID = 'interface.go' + source_filename = "interface.go" +-target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" ++target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20" + target triple = "wasm32-unknown-wasi" + + %runtime.typecodeID = type { %runtime.typecodeID*, i32, %runtime.interfaceMethodInfo*, %runtime.typecodeID*, i32 } +diff --git a/compiler/testdata/intrinsics-wasm.ll b/compiler/testdata/intrinsics-wasm.ll +index 9e6687d5..ce20dfd0 100644 +--- a/compiler/testdata/intrinsics-wasm.ll ++++ b/compiler/testdata/intrinsics-wasm.ll +@@ -1,6 +1,6 @@ + ; ModuleID = 'intrinsics.go' + source_filename = "intrinsics.go" +-target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" ++target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20" + target triple = "wasm32-unknown-wasi" + + declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +diff --git a/compiler/testdata/pointer.ll b/compiler/testdata/pointer.ll +index 4072816b..7020c0fa 100644 +--- a/compiler/testdata/pointer.ll ++++ b/compiler/testdata/pointer.ll +@@ -1,6 +1,6 @@ + ; ModuleID = 'pointer.go' + source_filename = "pointer.go" +-target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" ++target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20" + target triple = "wasm32-unknown-wasi" + + declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +diff --git a/compiler/testdata/pragma.ll b/compiler/testdata/pragma.ll +index 31fe6236..943b574d 100644 +--- a/compiler/testdata/pragma.ll ++++ b/compiler/testdata/pragma.ll +@@ -1,6 +1,6 @@ + ; ModuleID = 'pragma.go' + source_filename = "pragma.go" +-target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" ++target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20" + target triple = "wasm32-unknown-wasi" + + @extern_global = external global [0 x i8], align 1 +diff --git a/compiler/testdata/slice.ll b/compiler/testdata/slice.ll +index 847d29fb..0cca8970 100644 +--- a/compiler/testdata/slice.ll ++++ b/compiler/testdata/slice.ll +@@ -1,6 +1,6 @@ + ; ModuleID = 'slice.go' + source_filename = "slice.go" +-target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" ++target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20" + target triple = "wasm32-unknown-wasi" + + declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*, i8*) +diff --git a/compiler/testdata/string.ll b/compiler/testdata/string.ll +index e8d6e631..93f76059 100644 +--- a/compiler/testdata/string.ll ++++ b/compiler/testdata/string.ll +@@ -1,6 +1,6 @@ + ; ModuleID = 'string.go' + source_filename = "string.go" +-target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" ++target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128-ni:1:10:20" + target triple = "wasm32-unknown-wasi" + + %runtime._string = type { i8*, i32 } +diff --git a/go.mod b/go.mod +index 52dd71c3..c1df4c2b 100644 +--- a/go.mod ++++ b/go.mod +@@ -13,5 +13,5 @@ require ( + go.bug.st/serial v1.1.3 + golang.org/x/sys v0.0.0-20210510120138-977fb7262007 + golang.org/x/tools v0.1.6-0.20210813165731-45389f592fe9 +- tinygo.org/x/go-llvm v0.0.0-20210907125547-fd2d62ea06be ++ tinygo.org/x/go-llvm v0.0.0-20211230181020-1ddc904f6bf6 + ) +diff --git a/go.sum b/go.sum +index 73697653..4e394e71 100644 +--- a/go.sum ++++ b/go.sum +@@ -68,5 +68,5 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= + gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +-tinygo.org/x/go-llvm v0.0.0-20210907125547-fd2d62ea06be h1:syIpWbi/yESuoyijF2nhRdgX4422sNfmij+o73B3+vU= +-tinygo.org/x/go-llvm v0.0.0-20210907125547-fd2d62ea06be/go.mod h1:fv1F0BSNpxMfCL0zF3M4OPFbgYHnhtB6ST0HvUtu/LE= ++tinygo.org/x/go-llvm v0.0.0-20211230181020-1ddc904f6bf6 h1:p9huJkDeMFLOE5A4puIPRIewaTpQXX6OmjguUmGXJj4= ++tinygo.org/x/go-llvm v0.0.0-20211230181020-1ddc904f6bf6/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0= +diff --git a/loader/loader.go b/loader/loader.go +index 1f43e07e..489ed24f 100644 +--- a/loader/loader.go ++++ b/loader/loader.go +@@ -406,7 +406,7 @@ func (p *Package) parseFiles() ([]*ast.File, error) { + initialCFlags = append(initialCFlags, p.program.config.CFlags()...) + initialCFlags = append(initialCFlags, "-I"+p.Dir) + if p.program.clangHeaders != "" { +- initialCFlags = append(initialCFlags, "-Xclang", "-internal-isystem", "-Xclang", p.program.clangHeaders) ++ initialCFlags = append(initialCFlags, "-isystem", p.program.clangHeaders) + } + generated, headerCode, cflags, ldflags, accessedFiles, errs := cgo.Process(files, p.program.workingDir, p.program.fset, initialCFlags) + p.CFlags = append(initialCFlags, cflags...) +diff --git a/src/internal/task/task_asyncify_wasm.S b/src/internal/task/task_asyncify_wasm.S +index da00dcae..3b00ede1 100644 +--- a/src/internal/task/task_asyncify_wasm.S ++++ b/src/internal/task/task_asyncify_wasm.S +@@ -1,5 +1,14 @@ + .globaltype __stack_pointer, i32 + ++.functype start_unwind (i32) -> () ++.import_module start_unwind, asyncify ++.functype stop_unwind () -> () ++.import_module stop_unwind, asyncify ++.functype start_rewind (i32) -> () ++.import_module start_rewind, asyncify ++.functype stop_rewind () -> () ++.import_module stop_rewind, asyncify ++ + .global tinygo_unwind + .hidden tinygo_unwind + .type tinygo_unwind,@function +@@ -84,15 +93,6 @@ tinygo_rewind: // func (state *state) rewind() + return + end_function + +-.functype start_unwind (i32) -> () +-.import_module start_unwind, asyncify +-.functype stop_unwind () -> () +-.import_module stop_unwind, asyncify +-.functype start_rewind (i32) -> () +-.import_module start_rewind, asyncify +-.functype stop_rewind () -> () +-.import_module stop_rewind, asyncify +- + .hidden tinygo_rewinding # @tinygo_rewinding + .type tinygo_rewinding,@object + .section .bss.tinygo_rewinding,"",@ +diff --git a/targets/cortex-m.json b/targets/cortex-m.json +index c2661393..5c057d61 100644 +--- a/targets/cortex-m.json ++++ b/targets/cortex-m.json +@@ -13,6 +13,7 @@ + "-Werror", + "-fshort-enums", + "-fomit-frame-pointer", ++ "-mfloat-abi=soft", + "-fno-exceptions", "-fno-unwind-tables", + "-ffunction-sections", "-fdata-sections" + ], +diff --git a/targets/cortex-m0.json b/targets/cortex-m0.json +index 315d6658..fe356805 100644 +--- a/targets/cortex-m0.json ++++ b/targets/cortex-m0.json +@@ -2,5 +2,5 @@ + "inherits": ["cortex-m"], + "llvm-target": "thumbv6m-unknown-unknown-eabi", + "cpu": "cortex-m0", +- "features": "+armv6-m,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2" ++ "features": "+armv6-m,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" + } +diff --git a/targets/cortex-m0plus.json b/targets/cortex-m0plus.json +index 6ac9b531..a21d06ca 100644 +--- a/targets/cortex-m0plus.json ++++ b/targets/cortex-m0plus.json +@@ -2,5 +2,5 @@ + "inherits": ["cortex-m"], + "llvm-target": "thumbv6m-unknown-unknown-eabi", + "cpu": "cortex-m0plus", +- "features": "+armv6-m,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2" ++ "features": "+armv6-m,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" + } +diff --git a/targets/cortex-m3.json b/targets/cortex-m3.json +index 07d88dfe..7b878d52 100644 +--- a/targets/cortex-m3.json ++++ b/targets/cortex-m3.json +@@ -2,5 +2,5 @@ + "inherits": ["cortex-m"], + "llvm-target": "thumbv7m-unknown-unknown-eabi", + "cpu": "cortex-m3", +- "features": "+armv7-m,+hwdiv,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2" ++ "features": "+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" + } +diff --git a/targets/cortex-m33.json b/targets/cortex-m33.json +index 9b74ad16..6e77c3f2 100644 +--- a/targets/cortex-m33.json ++++ b/targets/cortex-m33.json +@@ -1,7 +1,4 @@ + { + "inherits": ["cortex-m"], +- "llvm-target": "thumbv7m-unknown-unknown-eabi", +- "cflags": [ +- "-mfloat-abi=soft" +- ] ++ "llvm-target": "thumbv7m-unknown-unknown-eabi" + } +diff --git a/targets/cortex-m4.json b/targets/cortex-m4.json +index ce947efb..8bcbf767 100644 +--- a/targets/cortex-m4.json ++++ b/targets/cortex-m4.json +@@ -2,8 +2,5 @@ + "inherits": ["cortex-m"], + "llvm-target": "thumbv7em-unknown-unknown-eabi", + "cpu": "cortex-m4", +- "features": "+armv7e-m,+dsp,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp", +- "cflags": [ +- "-mfloat-abi=soft" +- ] ++ "features": "+armv7e-m,+dsp,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" + } +diff --git a/targets/cortex-m7.json b/targets/cortex-m7.json +index 43fe532f..3ec505f6 100644 +--- a/targets/cortex-m7.json ++++ b/targets/cortex-m7.json +@@ -2,8 +2,5 @@ + "inherits": ["cortex-m"], + "llvm-target": "thumbv7em-unknown-unknown-eabi", + "cpu": "cortex-m7", +- "features": "+armv7e-m,+dsp,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp", +- "cflags": [ +- "-mfloat-abi=soft" +- ] ++ "features": "+armv7e-m,+dsp,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" + } +diff --git a/targets/gameboy-advance.json b/targets/gameboy-advance.json +index 2467b4b9..fc647702 100644 +--- a/targets/gameboy-advance.json ++++ b/targets/gameboy-advance.json +@@ -1,7 +1,7 @@ + { + "llvm-target": "armv4t-unknown-unknown-eabi", + "cpu": "arm7tdmi", +- "features": "+armv4t,+strict-align,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-dotprod,-dsp,-fp16fml,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-ras,-sb,-sha2,-thumb-mode", ++ "features": "+armv4t,+strict-align,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-ras,-sb,-sha2,-thumb-mode,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp", + "build-tags": ["gameboyadvance", "arm7tdmi", "baremetal", "linux", "arm"], + "goos": "linux", + "goarch": "arm", +diff --git a/targets/k210.json b/targets/k210.json +index 2416a593..cc0d2ed4 100644 +--- a/targets/k210.json ++++ b/targets/k210.json +@@ -1,6 +1,6 @@ + { + "inherits": ["riscv64"], +- "features": "+a,+c,+d,+f,+m,-relax,-save-restore", ++ "features": "+64bit,+a,+c,+d,+f,+m,-relax,-save-restore", + "build-tags": ["k210", "kendryte"], + "code-model": "medium" + } +diff --git a/transform/optimizer.go b/transform/optimizer.go +index 64c3d0b5..cd79340c 100644 +--- a/transform/optimizer.go ++++ b/transform/optimizer.go +@@ -59,6 +59,7 @@ func Optimize(mod llvm.Module, config *compileopts.Config, optLevel, sizeLevel i + goPasses.AddGlobalDCEPass() + goPasses.AddGlobalOptimizerPass() + goPasses.AddIPSCCPPass() ++ goPasses.AddInstructionCombiningPass() // necessary for OptimizeReflectImplements + goPasses.AddAggressiveDCEPass() + goPasses.AddFunctionAttrsPass() + goPasses.Run(mod) +-- +2.31.1 + diff --git a/tinygo.spec b/tinygo.spec index 8f370b8..741f315 100644 --- a/tinygo.spec +++ b/tinygo.spec @@ -10,7 +10,11 @@ Version: 0.21.0 %global CMSIS_commit 9fe411cef1cef5de58e5957b89760759de44e393 %global avr_commit 6624554c02b237b23dc17d53e992bf54033fc228 +%if %{fedora} > 34 +%global clang_llvm_version 13 +%else %global clang_llvm_version 12 +%endif %global cmsis_svd_commit df75ff974c76a911fc2815e29807f5ecaae06fc2 %global compiler_rt_version 9.0.0 %global musl_version 1.2.2 @@ -61,21 +65,26 @@ Source8: https://github.com/keith-packard/picolibc/archive/%{picolibc_com Source9: https://github.com/WebAssembly/wasi-libc/archive/%{wasi_libc_commit}/wasi-libc-%{wasi_libc_commit}.tar.gz # We don't have wasmtime to run these. Patch0001: 0001-Skip-WASI-tests.patch -# Prep for LLVM 13 -Patch0002: 0002-Add-canThrow-argument-to-llvm.InlineAsm-calls.patch # Unbundling things -Patch0003: 0003-Use-system-mingw64-headers-and-crt.patch +Patch0002: 0002-Use-system-mingw64-headers-and-crt.patch # https://github.com/tinygo-org/tinygo/pull/2482 -Patch0004: 0004-arm-Explicitly-disable-unwind-tables.patch +Patch0003: 0003-arm-Explicitly-disable-unwind-tables.patch # Skip testing some things where qemu is broken: # https://gitlab.com/qemu-project/qemu/-/issues/447 # https://gitlab.com/qemu-project/qemu/-/issues/690 -Patch0005: 0005-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch +Patch0004: 0004-Skip-some-cross-Linux-tests-where-qemu-is-broken.patch # Backport support for LLVM 12 # https://github.com/tinygo-org/tinygo/pull/2291 -Patch0006: 0006-targets-change-LLVM-features-to-match-vanilla-Clang.patch +Patch0005: 0005-targets-change-LLVM-features-to-match-vanilla-Clang.patch # https://github.com/tinygo-org/tinygo/pull/2300 -Patch0007: 0007-all-add-LLVM-12-support.patch +Patch0006: 0006-all-add-LLVM-12-support.patch +# Backport support for LLVM 13 +# https://github.com/tinygo-org/tinygo/pull/2289 +Patch0007: 0007-tests-improve-wasm-tests-slightly.patch +# https://github.com/tinygo-org/tinygo/pull/2388 +Patch0008: 0008-internal-task-swap-stack-chain-when-switching-gorout.patch +# https://github.com/tinygo-org/tinygo/pull/2365 +Patch0009: 0009-all-switch-to-LLVM-13.patch # Not supported upstream yet. ExcludeArch: armv7hl ppc64le s390x