
This has been a *lot* of work, trying to understand the Xtensa windowed registers ABI. But in the end I managed to come up with a very simple implementation that so far seems to work very well. I tested this with both blinky examples (with blinky2 slightly edited) and ./testdata/coroutines.go to verify that it actually works. Most development happened on the ESP32 QEMU fork from Espressif (https://github.com/espressif/qemu/wiki) but I also verified that it works on a real ESP32.
20 строки
377 Б
Go
20 строки
377 Б
Go
// +build xtensa
|
|
|
|
package runtime
|
|
|
|
import "device"
|
|
|
|
const GOARCH = "arm" // xtensa pretends to be arm
|
|
|
|
// The bitness of the CPU (e.g. 8, 32, 64).
|
|
const TargetBits = 32
|
|
|
|
// Align on a word boundary.
|
|
func align(ptr uintptr) uintptr {
|
|
return (ptr + 3) &^ 3
|
|
}
|
|
|
|
func getCurrentStackPointer() uintptr {
|
|
// The stack pointer (sp) is a1.
|
|
return device.AsmFull("mov {}, sp", nil)
|
|
}
|