From ca7c849da36ff6bc614a1d3a4520b74fcbc2b5cf Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 6 Aug 2021 01:37:41 +0200 Subject: [PATCH] 386: bump minimum requirement to the Pentium 4 Previously we used the i386 target, probably with all optional features disabled. However, the Pentium 4 has been released a _long_ time ago and it seems reasonable to me to take that as a minimum requirement. Upstream Go now also seems to move in this direction: https://github.com/golang/go/issues/40255 The main motivation for this is that there were floating point issues when running the tests for the math package: GOARCH=386 tinygo test math I haven't investigated what's the issue, but I strongly suspect it's caused by the weird x87 80-bit floating point format. This could perhaps be fixed in a different way (by setting the FPU precision to 64 bits) but I figured that just setting the minimum requirement to the Pentium 4 would probably be fine. If needed, we can respect the GO386 environment variable to support these very old CPUs. To support this newer CPU, I had to make sure that the stack is aligned to 16 bytes everywhere. This was not yet always the case. --- compileopts/target.go | 3 +++ src/internal/task/task_stack_386.go | 3 +++ src/runtime/arch_386.go | 2 +- src/runtime/gc_386.S | 3 ++- src/runtime/math.go | 2 +- 5 files changed, 10 insertions(+), 3 deletions(-) diff --git a/compileopts/target.go b/compileopts/target.go index ba5f7382..19951426 100644 --- a/compileopts/target.go +++ b/compileopts/target.go @@ -253,6 +253,9 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) { GDB: []string{"gdb"}, PortReset: "false", } + if goarch == "386" { + spec.CPU = "pentium4" + } if goos == "darwin" { spec.CFlags = append(spec.CFlags, "-isysroot", "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk") spec.LDFlags = append(spec.LDFlags, "-Wl,-dead_strip") diff --git a/src/internal/task/task_stack_386.go b/src/internal/task/task_stack_386.go index 3f1cd3ee..c0f06659 100644 --- a/src/internal/task/task_stack_386.go +++ b/src/internal/task/task_stack_386.go @@ -16,6 +16,9 @@ type calleeSavedRegs struct { ebp uintptr pc uintptr + + // Pad this struct so that tasks start on a 16-byte aligned stack. + _ [3]uintptr } // archInit runs architecture-specific setup for the goroutine startup. diff --git a/src/runtime/arch_386.go b/src/runtime/arch_386.go index 2dd7c9ff..9f1a99c0 100644 --- a/src/runtime/arch_386.go +++ b/src/runtime/arch_386.go @@ -9,7 +9,7 @@ const TargetBits = 32 // Align on word boundary. func align(ptr uintptr) uintptr { - return (ptr + 3) &^ 3 + return (ptr + 15) &^ 15 } func getCurrentStackPointer() uintptr { diff --git a/src/runtime/gc_386.S b/src/runtime/gc_386.S index 3ca80151..9604ddbd 100644 --- a/src/runtime/gc_386.S +++ b/src/runtime/gc_386.S @@ -13,10 +13,11 @@ tinygo_scanCurrentStack: pushl %ebp // Scan the stack. + subl $8, %esp // adjust the stack before the call to maintain 16-byte alignment pushl %esp calll tinygo_scanstack // Restore the stack pointer. Registers do not need to be restored as they // were only pushed to be discoverable by the GC. - addl $20, %esp + addl $28, %esp retl diff --git a/src/runtime/math.go b/src/runtime/math.go index 5498da6f..f1617385 100644 --- a/src/runtime/math.go +++ b/src/runtime/math.go @@ -217,7 +217,7 @@ func math_sinh(x float64) float64 //go:linkname math_Sqrt math.Sqrt func math_Sqrt(x float64) float64 { - if GOARCH == "x86" || GOARCH == "amd64" || GOARCH == "wasm" { + if GOARCH == "386" || GOARCH == "amd64" || GOARCH == "wasm" { return llvm_sqrt(x) } return math_sqrt(x)