This commit makes the output of `tinygo test` similar to that of `go
test`. It changes the following things in the process:
* Running multiple tests in a single command is now possible. They
aren't paralellized yet.
* Packages with no test files won't crash TinyGo, instead it logs it
in the same way the Go toolchain does.
With this is possible to enable e.g., SIMD in WASM using -llvm-features
+simd128. Multiple features can be specified separated by comma,
e.g., -llvm-features +simd128,+tail-call
With help from @deadprogram and @aykevl.
It is always implemented exactly the same way (as an uint8) so there is
no reason to implement it in each target separately.
This also makes it easier to add some documentation to it.
Instead, leave args at its default value (which provides a fake argv[0] as it has for a long time).
linux and mac do not seem affected.
Fixes#1862 (tinygo apps after v0.17.0-113-g7b761fa crash if run without argv[0])
This commit does two things:
1. It makes it possible to grow the heap on Linux and MacOS by
allocating 1GB of virtual memory on startup and then slowly using it
as necessary, when running out of available heap space.
2. It switches the default GC to be the conservative GC (previously
extalloc). This is good for consistency with other platforms that
all use this same GC.
This makes the extalloc GC unused by default.
This heap allocation would normally be optimized away, but with -opt=0
perhaps not. This is a problem if the conservative GC is used, because
the conservative GC needs to be initialized before use.
These two passes are related, but can definitely work independently.
Which is what this change does: it splits the two passes. This should
make it easier to change these two new passes in the future.
This change now also enables slightly better testing by testing these
two passes independently. In particular, the reflect lowering pass got
some actual tests: it was barely unit-tested before.
I have verified that this doesn't really change code size, at least not
on the microbit target. Two tests do change, but in a very minor way
(and in opposite direction).
The CircleCI macOS builds are failing, probably due to the old macOS
version that's used. This version (10.13 High Sierra) isn't supported
anymore on Homebrew so it seems best to me to simply bump the version.
I picked Xcode 11.1.0 because 10.3.0 is somehow triggering an error
while trying to install QEMU (the Python install fails).
Because of this newer Xcode version, I had to add an extra flag
(-isysroot) to the default command line for MacOS. The reason is that
this newer Xcode version no longer stores header files in /usr/local, an
SDK must be specified manually. With this change, the default SDK is
used.
Since 2018, Arduino Nanos and clones are sold with a new bootloader, which
requires programming at 115200 baud instead of the 57600 baud required
by the old one.
In many cases, position information is not stored in Go SSA instructions
because they don't exit directly in the source code. This includes
implicit type conversions, implicit returns at the end of a function,
the creation of a (hidden) slice when calling a variadic function, and
many other cases. I'm not sure where this information is supposed to
come from, but this patch takes the value (usually) from the value the
instruction refers to. This seems to work well for these implicit
conversions.
I've also added a few extra tests to the heap-to-stack transform pass,
of which one requires this improved position information.
On some boards the FPU is already enabled on startup, probably as part
of the bootloader. On other chips it was enabled as part of the runtime
startup code. In all these cases, enabling the FPU is currently
unsupported: the automatic stack sizing of goroutines assumes that the
processor won't need to reserve space for FPU registers. Enabling the
FPU therefore can lead to a stack overflow.
This commit either removes the code that enables the FPU, or simply
disables it in startup code. A future change should fully enable the FPU
so that operations on float32 can be performed by the FPU instead of in
software, greatly speeding up such code.
- Add some extra fields: FPUPresent, CPU and NVICPrioBits which may
come in handy at a later time (and are easy to add).
- Rename DEVICE to Device, to match Go style.
This is in preparation to the next commit, which requires the FPUPresent
flag.
This commit replaces most heap allocations in USB related code with
stack allocations. This is important for several reasons:
- It avoids running the GC unnecessarily.
- It reduces code size by 400-464 bytes.
- USB code might be called from interrupt handlers. The heap may be in
an inconsistent state when that happens if main thread code also
performs heap allocations.
The last one is by far the most important one: not doing heap
allocations in interrupts is critical for correctness. But the code size
reduction alone should be worth it.
There are two heap allocations in USB related code left: in the function
receiveUSBControlPacket (SAMD21 and SAMD51). This heap allocation must
also be removed because it runs in an interrupt, but I've left that for
a future change.
This allows better escape analysis even without being able to see the
entire program. This makes the stack allocation test case more complete
but probably won't have much of an effect outside of that (as the
compiler is able to infer these attributes in the whole-program
functionattrs pass).
This flag, if set, is a regexp for function names. If there are heap
allocations in the matching function names, these heap allocations will
be printed with an explanation why the heap allocation exists (and why
the object can't be stack allocated).
This allows for adding more advanced tests, for example tests that use
the compiler package so that test sources can be written in Go instead
of LLVM IR.
The interp package is in many cases able to execute map functions in the
runtime directly. This is probably slower than adding special support
for them in the interp package and also doesn't cover all cases (most
importantly, map keys that contain pointers) but removing this code also
removes a large amount of code that needs to be maintained and is
susceptible to hard-to-find bugs.
As a side effect, this resulted in different output of the
testdata/map.go test because the test relied on the existing iteration
order of TinyGo maps. I've updated the test to not rely on this test,
making the output compatible with what the Go toolchain would output.
I've discovered a bug in the implementation of the PHI instruction in
the interp package. This commit fixes the bug.
I've found this issue while investigating an issue with maps after
running interp per package.
At the moment, all targets use the Clang compiler to compile C and
assembly files. There is no good reason to make this configurable
anymore and in fact it will make future changes more complicated (and
thus more likely to have bugs). Therefore, I've removed support for
setting the compiler.
Note that the same is not true for the linker. While it makes sense to
standardize on the Clang compiler (because if Clang doesn't support a
target, TinyGo is unlikely to support it either), linkers will remain
configurable for the foreseeable future. One example is Xtensa, which is
supported by the Xtensa LLVM fork but doesn't have support in ld.lld
yet.
I've also fixed a bug in compileAndCacheCFile: it wasn't using the right
CFlags for caching purposes. This could lead to using stale caches. This
commit fixes that too.
This improves compatibility between the regular browser target
(-target=wasm) and the WASI target (-target=wasi). Specifically, it
allows running WASI tests like this:
tinygo test -target=wasi encoding/base32
This doesn't change the firmware, but it does make the disassembly of
the ELF files. Before:
Disassembly of section .text:
00000000 <(machine.UART).Write-0x100>:
0: 20001000 .word 0x20001000
4: 000009db .word 0x000009db
8: 00000f05 .word 0x00000f05
c: 00000f0b .word 0x00000f0b
10: 00000f05 .word 0x00000f05
After:
Disassembly of section .text:
00000000 <__isr_vector>:
0: 20001000 .word 0x20001000
4: 000009db .word 0x000009db
8: 00000f05 .word 0x00000f05
c: 00000f0b .word 0x00000f0b
10: 00000f05 .word 0x00000f05
The difference is that the disassembler will now use a proper symbol name
instead of using the closest by symbol (in this case, (machine.UART).Write).
This makes the disassembly easier to read.
This currently doesn't work with `tinygo flash` yet (even with
`-programmer=openocd`), you can use pyocd instead. For example, from the
Bluetooth package:
tinygo build -o test.hex -target=microbit-v2-s113v7 ./examples/advertisement/
pyocd flash --target=nrf52 test.hex
I intend to add support for pyocd to work around this issue, so that a simple
`tinygo flash` suffices.
There doesn't appear to be a user-controllable LED outside of the LED
matrix. In fact, the pin assigned for this was P13, which was connected
to the SPI SCK pin.
In this commit I've moved all core-specific flags to files for that
specific core. This is a bit of a cleanup (less duplicated JSON) but
should also help in the future when core-specific changes are made, such
as core specific build tags or when the FPU finally gets supported in
TinyGo.
Some notable specific changes:
- I've removed floating point flags from the Teensy 3.6 target. The
reason is that the FPU is not yet supported in TinyGo (in goroutine
stack switching for example) and floating point numbers would only
be supported by C files, not Go files (because the LLVM FPU feature
flags aren't used). This would create an ABI mismatch across CGo.
- I've added the "cpu":"cortex-m7" to the cortex-m7.json file to match
the configuration for the Teensy 4.0. This implies a change to the
nucleo-f722ze (because now it has its CPU field set). Somehow that
reduces the code size, so it looks like a good change.
I don't believe any of these changes should have any practical
consequences.
One issue I've found is in the Cortex-M33 target: it uses armv7m, which
is incorrect: it should be armv8m. But the chip is backwards compatible
so this should mostly work. Switching to armv8m led to a compilation
failure because PRIMASK isn't defined, this may be an actual bug.
The -Qunused-arguments flag disables the warning where some flags are
not relevant to a compilation. This commonly happens when compiling
assembly files (.s or .S files) because some flags are specific to C and
not relevant to assembly.
Because practically all baremetal targets need some form of assembly,
this flag is added to most CFlags. This creates a lot of noise. And it
is also added for compiling C code where it might hide bugs (by hiding
the fact a flag is actually unused).
This commit adds the flag to all assembly compilations and removes them
from all target JSON files.
See "STM32F40x and STM32F41x Errata sheet" - SPI CLK port must be 'fast' or 'very fast' to avoid data corruption on last bit (at the APB clocks we configure).