diff --git a/compiler/intrinsics.go b/compiler/intrinsics.go index 9df0bda3b..a31359a33 100644 --- a/compiler/intrinsics.go +++ b/compiler/intrinsics.go @@ -201,6 +201,17 @@ func (b *builder) defineMathOp() bool { if !ok { return false } + if strings.HasPrefix(b.Triple, "avr") { + // LLVM assumes the traditional AVR ABI where double is 32 bits and + // therefore does not provide f64 runtime libcalls for sin and cos. + // TinyGo uses 64-bit doubles on AVR, which picolibc supports directly. + switch b.fn.Name() { + case "Cos": + llvmName = "cos" + case "Sin": + llvmName = "sin" + } + } if strings.HasSuffix(b.Triple, "-wasi") || llvmutil.Version() < 19 { // We don't have a real libc for wasip2. Until that is fixed, we need to // limit math intrinsics on WASI to a subset supported natively in diff --git a/main_test.go b/main_test.go index c32ceacd1..07c531a39 100644 --- a/main_test.go +++ b/main_test.go @@ -370,10 +370,6 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) { // Too big for AVR. Doesn't fit in flash/RAM. continue - case "math.go": - // LLVM fails to lower one of the required library calls. - continue - case "cgo/": // CGo function pointers don't work on AVR (needs LLVM 16 and // some compiler changes). @@ -432,6 +428,10 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) { if name == "finalizerinvariants.go" || name == "finalizerlarge.go" { testOptions.Tags = append(append([]string(nil), options.Tags...), "runtime_asserts") } + if testOptions.Target == "simavr" && name == "math.go" { + // This test exceeds simavr's default 384-byte goroutine stack. + testOptions.StackSize = 512 + } runTest(name, testOptions, t, nil, nil) }) }