Skip to content

rand.Int() does not work on avr #2882

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ysoldak opened this issue May 30, 2022 · 8 comments
Closed

rand.Int() does not work on avr #2882

ysoldak opened this issue May 30, 2022 · 8 comments
Labels
avr AVR (Arduino Uno, etc.)

Comments

@ysoldak
Copy link
Contributor

ysoldak commented May 30, 2022

rand.Int() does not work for me on dev branch.
Did not try on latest release 0.23.0, rumour has it does not work there either.

Compilation for targets "arduino" and "arduino-nano" fails with:
error: interp: ptrtoint integer size does not equal pointer size

Simple reproducer:

package main

import "math/rand"

func main() {
	println(rand.Int())
}
@ysoldak
Copy link
Contributor Author

ysoldak commented May 30, 2022

Can be related to #2389

@dgryski
Copy link
Member

dgryski commented May 30, 2022

@deadprogram deadprogram added the avr AVR (Arduino Uno, etc.) label Jun 1, 2022
@deadprogram
Copy link
Member

@ysoldak is this still an issue with the latest dev branch?

@ysoldak
Copy link
Contributor Author

ysoldak commented Sep 22, 2023

On latest release v0.30.0 and LLVM 16

$ tinygo version
tinygo version 0.30.0 darwin/amd64 (using go version go1.21.1 and LLVM version 16.0.6)

Arduino (AVR) target

$ tinygo build -size short -o test.hex -target=arduino examples/rnd
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 6 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 15 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 19 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 25 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 35 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 42 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 53 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 64 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 77 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 83 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 94 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 104 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 115 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 128 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 143 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 156 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 175 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 192 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 206 bytes
ld.lld: error: section '.data' will not fit in region 'RAM': overflowed by 218 bytes
ld.lld: error: too many errors emitted, stopping now (use --error-limit=0 to see all errors)
error: failed to link /var/folders/57/6jf43mbj1tlck52fwrd0jcscmwt5rh/T/tinygo1749568963/main: exit status 1

Same code for nano-rp2040 target

$ tinygo build -size short -o test.uf2 -target=nano-rp2040 examples/rnd
   code    data     bss |   flash     ram
  26756     832    3168 |   27588    4000

Same happens on dev branch

@aykevl
Copy link
Member

aykevl commented Sep 22, 2023

That means the binary is too big to fit on an AVR. I don't think there is anything to fix here.

@ysoldak
Copy link
Contributor Author

ysoldak commented Sep 27, 2023

So random generator is basically not available on AVR. We could mention that in docs and close the ticket then?..

@aykevl
Copy link
Member

aykevl commented Sep 27, 2023

We could mention that in docs and close the ticket then?..

There are so many things that are too large for AVR, it doesn't make sense to spell out every little thing that doesn't work.
And I do agree the error is not super helpful, this is somewhat out of our control because we use the LLVM linker.

It is of course possible to build a different pseudorandom number generator instead, for example there is one at the bottom of https://github.com/aykevl/things/blob/master/earring-ring/main.go:

var xorshift32State uint32 = 1

func random() uint32 {
	x := xorshift32State
	x = xorshift32(x)
	xorshift32State = x
	return x
}

// Xorshift32 RNG. The usual algorithm uses the shift amounts [13, 17, 5], but
// [7, 1, 9] as used below are a much better fit for AVR. It is "only" 37
// instructions (excluding return) when compiled with Clang 16 while the usual
// algorithm uses 57 instructions.
// On the other hand, avr-gcc (tested most versions starting with 5.4.0) is just
// terrible in both cases, using loops for these shifts.
//
// The [7, 1, 9] algorithm is mentioned on page 9 of this paper:
// http://www.iro.umontreal.ca/~lecuyer/myftp/papers/xorshift.pdf
//
// Godbolt reference (both algorithms in avr-gcc and Clang 16):
// https://godbolt.org/z/KdeKhP54d
func xorshift32(x uint32) uint32
	x ^= x << 7
	x ^= x >> 1
	x ^= x << 9
	return x
}

@aykevl
Copy link
Member

aykevl commented Sep 27, 2023

Closing because the original bug has been fixed and the followup issue is not really something we can fix.

@aykevl aykevl closed this as completed Sep 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
avr AVR (Arduino Uno, etc.)
Projects
None yet
Development

No branches or pull requests

4 participants