Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions builder/picolibc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"os"
"path/filepath"

"github.com/tinygo-org/tinygo/compileopts"
"github.com/tinygo-org/tinygo/goenv"
)

Expand All @@ -19,8 +20,9 @@ var libPicolibc = Library{
return f.Close()
},
cflags: func(target, headerPath string) []string {
picolibcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc")
return []string{
root := goenv.Get("TINYGOROOT")
picolibcDir := filepath.Join(root, "lib/picolibc")
flags := []string{
"-Werror",
"-Wall",
"-std=gnu11",
Expand All @@ -39,10 +41,22 @@ var libPicolibc = Library{
"-I" + picolibcDir + "/libm/common",
"-I" + headerPath,
}
if compileopts.CanonicalArchName(target) == "xtensa" {
flags = append(flags,
"-I"+filepath.Join(root, "lib/xtensa/include"),
"-I"+picolibcDir+"/libc/machine/xtensa",
"-D_XTENSA_HAVE_CONFIG_CORE_ISA_H",
)
}
return flags
},
sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc") },
librarySources: func(target string, _ bool) ([]string, error) {
return append([]string(nil), picolibcSources...), nil
sources := append([]string(nil), picolibcSources...)
if compileopts.CanonicalArchName(target) == "xtensa" {
sources = append(sources, "libc/machine/xtensa/setjmp.S")
}
return sources, nil
},
}

Expand Down
2 changes: 1 addition & 1 deletion compileopts/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
var libVersions = map[string]int{
"musl": 3,
"bdwgc": 2,
"picolibc": 1,
"picolibc": 2,
"wasmbuiltins": 1,
}

Expand Down
21 changes: 14 additions & 7 deletions compiler/defer.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ func (b *builder) supportsRecover() bool {
// proposal of WebAssembly:
// https://github.com/WebAssembly/exception-handling
return false
case "xtensa":
// TODO: add support for these architectures
return false
default:
return true
}
Expand Down Expand Up @@ -109,11 +106,21 @@ func (b *builder) createLandingPad() {
b.CreateBr(b.blockInfo[b.fn.Recover.Index].entry)
}

// Create a checkpoint (similar to setjmp). This emits inline assembly that
// stores the current program counter inside the ptr address (actually
// ptr+sizeof(ptr)) and then returns a boolean indicating whether this is the
// normal flow (false) or we jumped here from somewhere else (true).
// Create a checkpoint (similar to setjmp). It returns whether execution is
// continuing normally instead of resuming after a longjmp.
func (b *builder) createCheckpoint(ptr llvm.Value) llvm.Value {
if b.archFamily() == "xtensa" {
fnType := llvm.FunctionType(b.ctx.Int32Type(), []llvm.Type{b.dataPtrType}, false)
fn := b.mod.NamedFunction("setjmp")
if fn.IsNil() {
fn = llvm.AddFunction(b.mod, "setjmp", fnType)
fn.AddFunctionAttr(b.ctx.CreateEnumAttribute(llvm.AttributeKindID("returns_twice"), 0))
}
result := b.CreateCall(fnType, fn, []llvm.Value{ptr}, "setjmp")
result.AddCallSiteAttribute(-1, b.ctx.CreateEnumAttribute(llvm.AttributeKindID("returns_twice"), 0))
return b.CreateICmp(llvm.IntEQ, result, llvm.ConstInt(b.ctx.Int32Type(), 0, false), "setjmp.result")
}

// Construct inline assembly equivalents of setjmp.
// The assembly works as follows:
// * Registers are either clobbered or, on 386, saved for longjmp to
Expand Down
18 changes: 18 additions & 0 deletions lib/xtensa/include/xtensa/config/core-isa.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef TINYGO_XTENSA_CONFIG_CORE_ISA_H
#define TINYGO_XTENSA_CONFIG_CORE_ISA_H

#ifdef __XTENSA_WINDOWED_ABI__
#define XCHAL_HAVE_WINDOWED 1
#else
#define XCHAL_HAVE_WINDOWED 0
#endif

#ifdef __XTENSA_EB__
#define XCHAL_HAVE_BE 1
#else
#define XCHAL_HAVE_BE 0
#endif

#define XCHAL_MAYHAVE_ERRATUM_XEA1KWIN 1

#endif
7 changes: 6 additions & 1 deletion main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,12 @@ func TestESP32QEMU(t *testing.T) {
if !regexp.MustCompile(`(?m)^esp32\s`).Match(machines) {
t.Skip("qemu-system-xtensa does not support the ESP32 machine")
}
runTest("print.go", options, t, nil, nil)
for _, name := range []string{"print.go", "recover.go"} {
t.Run(name, func(t *testing.T) {
t.Parallel()
runTest(name, options, t, nil, nil)
})
}
}

func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
Expand Down
22 changes: 13 additions & 9 deletions make/release.mk
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ build/release: tinygo gen-device $(if $(filter 1,$(USE_SYSTEM_BINARYEN)),,binary
@mkdir -p build/release/tinygo/lib/musl/src
@mkdir -p build/release/tinygo/lib/nrfx
@mkdir -p build/release/tinygo/lib/picolibc/libc
@mkdir -p build/release/tinygo/lib/picolibc/libc/machine
@mkdir -p build/release/tinygo/lib/picolibc/libm
@mkdir -p build/release/tinygo/lib/wasi-libc/dlmalloc
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-bottom-half
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@mkdir -p build/release/tinygo/lib/wasi-cli/
@mkdir -p build/release/tinygo/lib/xtensa
@echo copying source files
@cp -p build/tinygo$(EXE) build/release/tinygo/bin
ifneq ($(USE_SYSTEM_BINARYEN),1)
Expand Down Expand Up @@ -80,15 +82,16 @@ endif
@cp -rp lib/mingw-w64/mingw-w64-headers/defaults/include build/release/tinygo/lib/mingw-w64/mingw-w64-headers/defaults
@cp -rp lib/mingw-w64/mingw-w64-headers/include build/release/tinygo/lib/mingw-w64/mingw-w64-headers
@cp -rp lib/nrfx/* build/release/tinygo/lib/nrfx
@cp -rp lib/picolibc/libc/ctype build/release/tinygo/lib/picolibc/libc
@cp -rp lib/picolibc/libc/include build/release/tinygo/lib/picolibc/libc
@cp -rp lib/picolibc/libc/locale build/release/tinygo/lib/picolibc/libc
@cp -rp lib/picolibc/libc/stdlib build/release/tinygo/lib/picolibc/libc
@cp -rp lib/picolibc/libc/string build/release/tinygo/lib/picolibc/libc
@cp -rp lib/picolibc/libc/stdio build/release/tinygo/lib/picolibc/libc
@cp -rp lib/picolibc/libm/common build/release/tinygo/lib/picolibc/libm
@cp -rp lib/picolibc/libm/math build/release/tinygo/lib/picolibc/libm
@cp -rp lib/picolibc-stdio.c build/release/tinygo/lib
@cp -rp lib/picolibc/libc/ctype build/release/tinygo/lib/picolibc/libc
@cp -rp lib/picolibc/libc/include build/release/tinygo/lib/picolibc/libc
@cp -rp lib/picolibc/libc/locale build/release/tinygo/lib/picolibc/libc
@cp -rp lib/picolibc/libc/machine/xtensa build/release/tinygo/lib/picolibc/libc/machine
@cp -rp lib/picolibc/libc/stdlib build/release/tinygo/lib/picolibc/libc
@cp -rp lib/picolibc/libc/string build/release/tinygo/lib/picolibc/libc
@cp -rp lib/picolibc/libc/stdio build/release/tinygo/lib/picolibc/libc
@cp -rp lib/picolibc/libm/common build/release/tinygo/lib/picolibc/libm
@cp -rp lib/picolibc/libm/math build/release/tinygo/lib/picolibc/libm
@cp -rp lib/picolibc-stdio.c build/release/tinygo/lib
@cp -rp lib/wasi-libc/dlmalloc/src build/release/tinygo/lib/wasi-libc/dlmalloc
@cp -rp lib/wasi-libc/libc-bottom-half/cloudlibc build/release/tinygo/lib/wasi-libc/libc-bottom-half
@cp -rp lib/wasi-libc/libc-bottom-half/headers build/release/tinygo/lib/wasi-libc/libc-bottom-half
Expand Down Expand Up @@ -121,6 +124,7 @@ endif
@cp -rp lib/wasi-libc/libc-top-half/musl/src/unistd build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
@cp -rp lib/wasi-libc/libc-top-half/sources build/release/tinygo/lib/wasi-libc/libc-top-half
@cp -rp lib/wasi-cli/wit build/release/tinygo/lib/wasi-cli/wit
@cp -rp lib/xtensa/include build/release/tinygo/lib/xtensa
@cp -rp ${LLVM_PROJECTDIR}/compiler-rt/lib/builtins build/release/tinygo/lib/compiler-rt-builtins
@cp -rp ${LLVM_PROJECTDIR}/compiler-rt/LICENSE.TXT build/release/tinygo/lib/compiler-rt-builtins
@cp -rp src build/release/tinygo/src
Expand Down
12 changes: 7 additions & 5 deletions src/machine/machine_esp32.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ var (
rtsctsSignal: 199,
}

onceUart = sync.Once{}
uartInterruptConfigured bool
)

// CPU interrupt line used for all UART peripherals.
Expand Down Expand Up @@ -588,11 +588,13 @@ func (uart *UART) configureInterrupt() {
}

// Register the ISR only once (shared across all UARTs on the same CPU int).
// interrupt.New is a compiler intrinsic and requires a plain (non-capturing)
// handler function, so we use a named package-level function.
onceUart.Do(func() {
// Avoid sync.Once here because serial is initialized before a task exists.
state := interrupt.Disable()
if !uartInterruptConfigured {
_ = interrupt.New(cpuInterruptFromUART, handleUARTInterrupt).Enable()
})
uartInterruptConfigured = true
}
interrupt.Restore(state)
}

// handleUARTInterrupt is the shared UART interrupt handler. It must be a plain
Expand Down
4 changes: 3 additions & 1 deletion src/runtime/arch_xtensa.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ const zeroSizeAllocPtr uintptr = 16 // part of early flash: partition table, etc
// The bitness of the CPU (e.g. 8, 32, 64).
const TargetBits = 32

const deferExtraRegs = 0
// Xtensa's windowed ABI uses a 17-word jmp_buf. JumpSP and JumpPC provide the
// first two words.
const deferExtraRegs = 15

const callInstSize = 3 // "callx0 someFunction" (and similar) is 3 bytes

Expand Down
34 changes: 34 additions & 0 deletions src/runtime/asm_xtensa.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#ifdef __XTENSA_WINDOWED_ABI__
.section .text.__xtensa_libgcc_window_spill,"ax",@progbits
.global __xtensa_libgcc_window_spill
.type __xtensa_libgcc_window_spill, %function
__xtensa_libgcc_window_spill:
entry sp, 16
movi a6, 15
call4 .Lspill_windows
retw
.size __xtensa_libgcc_window_spill, .-__xtensa_libgcc_window_spill

.balign 4
.Lspill_windows:
entry sp, 16
beqz a2, .Lspill_done
addi a2, a2, -1
mov a6, a2
call4 .Lspill_windows
.Lspill_done:
retw
#endif

.section .text.tinygo_longjmp,"ax",@progbits
.global tinygo_longjmp
.type tinygo_longjmp, %function
tinygo_longjmp:
#ifdef __XTENSA_WINDOWED_ABI__
// longjmp's entry rotates a10/a11 into its a2/a3 arguments.
movi a11, 1
#else
movi a3, 1
#endif
j longjmp
.size tinygo_longjmp, .-tinygo_longjmp
3 changes: 2 additions & 1 deletion targets/xtensa.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@
],
"ldflags": [
"--gc-sections"
]
],
"extra-files": ["src/runtime/asm_xtensa.S"]
}
Loading