Граф коммитов

475 коммитов

Автор SHA1 Сообщение Дата
Ayke van Laethem
41bcad9c19 runtime: only use CRLF on baremetal systems
We should only do this on baremetal systems, not on Linux, macOS, and
Windows. In fact, Windows will convert LF into CRLF in its putchar
function.
2021-11-16 11:08:30 +01:00
Nia Waldvogel
641dcd7c16 internal/task: use asyncify on webassembly
This change implements a new "scheduler" for WebAssembly using binaryen's asyncify transform.
This is more reliable than the current "coroutines" transform, and works with non-Go code in the call stack.

runtime (js/wasm): handle scheduler nesting

If WASM calls into JS which calls back into WASM, it is possible for the scheduler to nest.
The event from the callback must be handled immediately, so the task cannot simply be deferred to the outer scheduler.
This creates a minimal scheduler loop which is used to handle such nesting.
2021-11-14 10:49:28 +01:00
Ayke van Laethem
edcece33ca transform: refactor interrupt lowering
Instead of doing everything in the interrupt lowering pass, generate
some more code in gen-device to declare interrupt handler functions and
do some work in the compiler so that interrupt lowering becomes a lot
simpler.

This has several benefits:

  - Overall code is smaller, in particular the interrupt lowering pass.
  - The code should be a bit less "magical" and instead a bit easier to
    read. In particular, instead of having a magic
    runtime.callInterruptHandler (that is fully written by the interrupt
    lowering pass), the runtime calls a generated function like
    device/sifive.InterruptHandler where this switch already exists in
    code.
  - Debug information is improved. This can be helpful during actual
    debugging but is also useful for other uses of DWARF debug
    information.

For an example on debug information improvement, this is what a
backtrace might look like before this commit:

    Breakpoint 1, 0x00000b46 in UART0_IRQHandler ()
    (gdb) bt
    #0  0x00000b46 in UART0_IRQHandler ()
    #1  <signal handler called>
    [..etc]

Notice that the debugger doesn't see the source code location where it
has stopped.

After this commit, breaking at the same line might look like this:

    Breakpoint 1, (*machine.UART).handleInterrupt (arg1=..., uart=<optimized out>) at /home/ayke/src/github.com/tinygo-org/tinygo/src/machine/machine_nrf.go:200
    200			uart.Receive(byte(nrf.UART0.RXD.Get()))
    (gdb) bt
    #0  (*machine.UART).handleInterrupt (arg1=..., uart=<optimized out>) at /home/ayke/src/github.com/tinygo-org/tinygo/src/machine/machine_nrf.go:200
    #1  UART0_IRQHandler () at /home/ayke/src/github.com/tinygo-org/tinygo/src/device/nrf/nrf51.go:176
    #2  <signal handler called>
    [..etc]

By now, the debugger sees an actual source location for UART0_IRQHandler
(in the generated file) and an inlined function.
2021-11-06 09:40:15 +01:00
Ayke van Laethem
fb33f3813d runtime: only initialize os.runtime_args when needed
This generally means that code size is reduced, especially when the os
package is not imported.

Specifically:

  - On Linux (which currently statically links musl), it avoids calling
    malloc, which avoids including the musl C heap for small programs
    saving around 1.6kB.
  - On WASI, it avoids initializing the args slice when the os package
    is not used. This reduces binary size by around 1kB.
2021-11-05 08:50:36 +01:00
Ayke van Laethem
670fcf59d8 linux: reduce binary size in the common case
This commit changes the runtime.putchar implementation to directly call
the `write` system call. This reduces the binary size by around 2.7kB.
2021-11-05 08:50:36 +01:00
Ayke van Laethem
403d93560b builder: build static binaries using musl on Linux
This commit adds support for musl-libc and uses it by default on Linux.
The main benefit of it is that binaries are always statically linked
instead of depending on the host libc, even when using CGo.

Advantages:
  - The resulting binaries are always statically linked.
  - No need for any tools on the host OS, like a compiler, linker, or
    libc in a release build of TinyGo.
  - This also simplifies cross compilation as no cross compiler is
    needed (it's all built into the TinyGo release build).

Disadvantages:
  - Binary size increases by 5-6 kilobytes if -no-debug is used. Binary
    size increases by a much larger margin when debugging symbols are
    included (the default behavior) because musl is built with debugging
    symbols enabled.
  - Musl does things a bit differently than glibc, and some CGo code
    might rely on the glibc behavior.
  - The first build takes a bit longer because musl needs to be built.

As an additional bonus, time is now obtained from the system in a way
that fixes the Y2038 problem because musl has been a bit more agressive
in switching to 64-bit time_t.
2021-11-04 17:15:38 +01:00
Ayke van Laethem
f24a93c51d compiler, runtime: add layout parameter to runtime.alloc
This layout parameter is currently always nil and ignored, but will
eventually contain a pointer to a memory layout.

This commit also adds module verification to the transform tests, as I
found out that it didn't (and therefore didn't initially catch all
bugs).
2021-11-02 22:16:15 +01:00
Ayke van Laethem
a4afc3b4b0 compiler: simplify interface lowering
This commit simplifies the IR a little bit: instead of calling
pseudo-functions runtime.interfaceImplements and
runtime.interfaceMethod, real declared functions are being called that
are then defined in the interface lowering pass. This should simplify
the interaction between various transformation passes. It also reduces
the number of lines of code, which is generally a good thing.
2021-10-31 14:17:25 +01:00
Ayke van Laethem
90076f9401 all: drop support for LLVM 10 2021-10-31 10:44:17 +01:00
Ayke van Laethem
86f1e6aec4 compiler: properly implement div and rem operations
The division and remainder operations were lowered directly to LLVM IR.
This is wrong however because the Go specification defines exactly what
happens on a divide by zero or signed integer overflow and LLVM IR
itself treats those cases as undefined behavior. Therefore, this commit
implements divide by zero and signed integer overflow according to the
Go specification.

This does have an impact on the generated code, but it is surprisingly
small. I've used the drivers repo to test the code before and after, and
to my surprise most driver smoke tests are not changed at all. Those
that are, have only a small increase in code size. At the same time,
this change makes TinyGo more compliant to the Go specification.
2021-10-28 15:55:02 +02:00
Ayke van Laethem
14bb90c3c0 cgo: add support for stdio in picolibc and wasi-libc
This adds support for stdio in picolibc and fixes wasm_exec.js so that
it can also support C puts. With this, C stdout works on all supported
platforms.
2021-10-26 17:08:30 +02:00
Rouven Broszeit
112b369636 Call __wasm_call_ctors() in wasi init function 2021-10-25 13:12:23 +02:00
Dmitriy
43efe94041 add support for CPU interrupts for ESP32-C3 2021-10-23 03:31:37 +02:00
Ayke van Laethem
3f89fa0bee fe310: increase CPU frequency from 16MHz to 320MHz
This chip can run so much faster! Let's update the default frequency.

Also, change the UART implementation to be more fexible regarding the
clock frequency.
2021-10-21 07:13:57 +02:00
Damian Gryski
18aaed63b9 src/runtime: add another set of invalid unicode runes to encodeUTF8() 2021-10-16 01:37:48 +02:00
Damian Gryski
a413d5dfe9 rutime/gc_leaking: ensure heapptr is aligned on wasm 2021-10-14 01:56:05 +02:00
Ayke van Laethem
98f84a497d qemu: signal correct exit code to QEMU
There were a few issues that were causing qemu-system-arm and
qemu-system-riscv to give the wrong exit codes. They are in fact capable
of exiting with 0 or 1 signalled from the running application, but this
functionality wasn't used. This commit changes this in the following
ways:

  * It fixes SemiHosting codes, which were incorrectly written in
    decimal while they should have been written in hexadecimal (oops!).
  * It modifies all the baremetal main functions (aka reset handlers) to
    exit with `exit(0)` instead of `abort()`.
  * It changes `syscall.Exit` to call `exit(code)` instead of `abort()`
    on baremetal targets.
  * It adds these new exit functions where necessary, implemented in a
    way that signals the correct exit status if running under QEMU.

All in all, this means that `tinygo test` doesn't have to look at the
output of a test to determine the outcome. It can simply look at the
exit code.
2021-10-06 09:04:06 +02:00
Ayke van Laethem
af00e218a8 riscv: implement 32-bit atomic operations
This is necessary to support the ESP32-C3, which lacks the A (atomic)
extension and thus requires these 32-bit atomic operations.
With this commit, flashing ./testdata/atomic.go to the ESP32-C3 works
correctly and produces the expected output on the serial console.
2021-10-04 21:27:00 +02:00
Ayke van Laethem
cb147b9475 esp32c3: add support for this chip
This change adds support for the ESP32-C3, a new chip from Espressif. It
is a RISC-V core so porting was comparatively easy.

Most peripherals are shared with the (original) ESP32 chip, but with
subtle differences. Also, the SVD file I've used gives some
peripherals/registers a different name which makes sharing code harder.
Eventually, when an official SVD file for the ESP32 is released, I
expect that a lot of code can be shared between the two chips.

More information: https://www.espressif.com/en/products/socs/esp32-c3

TODO:
  - stack scheduler
  - interrupts
  - most peripherals (SPI, I2C, PWM, etc)
2021-09-16 20:13:04 +02:00
Ayke van Laethem
88b9c27dbf unix: check for mmap error and act accordingly
At startup, a large chunk of virtual memory is used up by the heap. This
works fine in emulation (qemu-arm), but doesn't work so well on an
actual Raspberry Pi. Therefore, this commit reduces the requested amount
until a heap size is found that works on the system.

This can certainly be improved, but for now it's an important fix
because it allows TinyGo built binaries to actually run on a Raspberry
Pi with just 1GB RAM.
2021-09-15 17:06:21 +02:00
Damian Gryski
da6c14481f runtime: fix a suspicious bitwise operation
The `0 << nxp.SIM_CLKDIV1_OUTDIV1_Pos` term was duplicated.
No effect other than triggering a static analysis check.
2021-09-09 17:51:46 +02:00
Damian Gryski
32de906f6d internal/task, runtime: add subsections_via_symbols to assembly files on darwin
This allows the assembly routines in these files to be stripped as dead
code if they're not referenced.  This solves the link issues on MacOS
when the `leaking` garbage collector or the `coroutines` scheduler
are selected.

Fixes #2081
2021-09-07 08:00:11 +02:00
Damian Gryski
5fa1e7163a src/runtime: reset heapptr to heapStart after preinit()
heapptr is assinged to heapStart (which is 0) when it's declared, but preinit()
may have moved the heap somewhere else.  Set heapptr to the proper value
of heapStart when we initialize the heap properly.

This allows the leaking allocator to work on unix.
2021-09-04 12:13:53 +02:00
Ayke van Laethem
255f35671d compiler: add support for new language features of Go 1.17 2021-08-30 09:18:58 +02:00
Ayke van Laethem
f57e9622fd baremetal,wasm: support command line params and environment variables
This is mainly useful to be able to run `tinygo test`, for example:

    tinygo test -target=cortex-m-qemu -v math

This is not currently supported, but will be in the future.
2021-08-12 21:19:24 +02:00
Ayke van Laethem
a3c4421f39 compiler: move math aliases from the runtime to the compiler
This makes them more flexible, especially with Go 1.17 making the
situation more complicated (see
1d20a362d0).
It also makes it possible to do the same for many other functions, such
as assembly implementations of cryptographich functions which are
similarly dependent on the architecture.
2021-08-10 20:08:27 +02:00
Ayke van Laethem
58565b42cc compiler: move LLVM math builtin support into the compiler
This simplifies src/runtime/math.go, which I eventually want to remove
entirely by moving the given functionality into the compiler.
2021-08-10 20:08:27 +02:00
Ayke van Laethem
ca7c849da3 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.
2021-08-10 20:08:27 +02:00
Ayke van Laethem
6c1301688b math: fix math.Max and math.Min
The math package failed the package tests on arm64 and wasm:

    GOARCH=arm64 tinygo test math

Apparently the builtins llvm.maximum.f64 and llvm.minimum.f64 have
slightly different behavior on arm64 and wasm compared to what Go
expects.
2021-08-10 20:08:27 +02:00
Ayke van Laethem
65c1978965 wasm: align heap to 16 bytes
This commit fixes two things:

  * It changes the alignment to 16 bytes (from 4), to match max_align_t
    in C.
  * It manually aligns heapStart on WebAssembly, to work around a bug in
    wasm-ld with --stack-first (see https://reviews.llvm.org/D106499).
2021-07-30 08:38:51 +02:00
Ayke van Laethem
03481789b0 runtime: fix time base for time.Now()
This function previously returned the atomic time, that isn't affected
by system time changes but also has a time base at some arbitrary time
in the past. This makes sense for baremetal platforms (which typically
don't know the wall time) but it gives surprising results on Linux and
macOS: time.Now() usually returns a time somewhere near the start of
1970.

This commit fixes this by obtaining both time values: the monotonic time
and the wall clock time. This is also how the Go runtime implements the
time.now function.
2021-07-20 22:19:13 +02:00
Ayke van Laethem
b40703e986 wasm: override dlmalloc heap implementation from wasi-libc
These two heaps conflict with each other, so that if any function uses
the dlmalloc heap implementation it will eventually result in memory
corruption.

This commit fixes this by implementing all heap-related functions. This
overrides the functions that are implemented in wasi-libc. That's why
all of them are implemented (even if they just panic): to make sure no
program accidentally uses the wrong one.
2021-07-15 00:13:17 +02:00
Ayke van Laethem
c3032660c9 wasi: remove wasm build tag
The wasm build tag together with GOARCH=arm was causing problems in the
internal/cpu package. In general, I think having two architecture build
tag will only cause problems (in this case, wasm and arm) so I've
removed the wasm build tag and replaced it with tinygo.wasm.

This is similar to the tinygo.riscv build tag, which is used for older
Go versions that don't yet have RISC-V support in the standard library
(and therefore pretend to be GOARCH=arm instead).
2021-06-22 09:03:23 +02:00
deadprogram
87e48c1057 machine/rp2040: implement UART0/UART1, can be used on all rp2040 boards
Signed-off-by: deadprogram <ron@hybridgroup.com>
2021-06-16 19:13:01 +02:00
Yurii Soldak
d62a9e24e5 runtime: expose memory stats 2021-06-10 22:03:00 +02:00
Federico G. Schwindt
62f9f61664 Add runtime stubs required for net/http
Continued from #1911.
2021-06-01 15:15:12 +02:00
Kenneth Bell
2f248bbf8b scheduler: task.Data made 64bit to avoid overflow 2021-06-01 15:00:07 +02:00
Ayke van Laethem
8b79e82686 nrf: avoid heap allocation in waitForEvent
Because arm.SVCall1 lets pointers escape, the return value of
sd_softdevice_is_enabled (passed as a pointer in a parameter) will
escape and thus this value will be heap allocated.

Use a global variable for this purpose instead to avoid the heap
allocation. This is safe as waitForEvent may only be called outside of
interrupts.
2021-05-30 20:56:01 +02:00
Rajiv Kanchan
722a3a5c94 add rp2040, pico
adds preliminary support (just enough to run blinky1) for the Raspberry Pi Pico board along with the rp2040 mcu.
2021-05-28 18:29:04 +02:00
deadprogram
ed2db8a26d Revert "scheduler: task.Data made 64bit to avoid overflow"
This reverts commit fd8938c634.
2021-05-28 07:38:59 +02:00
Kenneth Bell
fd8938c634 scheduler: task.Data made 64bit to avoid overflow 2021-05-28 00:02:46 +02:00
Kenneth Bell
fa3dd41a4f stm32: Use TIM for runtime clock 2021-05-28 00:02:46 +02:00
Kenneth Bell
2c4b507d34 stm32l5: add pwm 2021-05-28 00:02:46 +02:00
Yurii Soldak
422ebeeec7 Do not disable interrupts on abort
Allows panic messages to be printed fully into serial console
2021-05-27 09:28:08 +02:00
Ayke van Laethem
b67351babe machine: define Serial as the default output
Previously, the machine.UART0 object had two meanings:

  - it was the first UART on the chip
  - it was the default output for println

These two meanings conflict, and resulted in workarounds like:

  - Defining UART0 to refer to the USB-CDC interface (atsamd21,
    atsamd51, nrf52840), even though that clearly isn't an UART.
  - Defining NRF_UART0 to avoid a conflict with UART0 (which was
    redefined as a USB-CDC interface).
  - Defining aliases like UART0 = UART1, which refer to the same
    hardware peripheral (stm32).

This commit changes this to use a new machine.Serial object for the
default serial port. It might refer to the first or second UART
depending on the board, or even to the USB-CDC interface. Also, UART0
now really refers to the first UART on the chip, no longer to a USB-CDC
interface.

The changes in the runtime package are all just search+replace. The
changes in the machine package are a mixture of search+replace and
manual modifications.

This commit does not affect binary size, in fact it doesn't affect the
resulting binary at all.
2021-05-13 16:43:37 +02:00
Ayke van Laethem
aa5b8d0df7 machine: make UART objects pointer receivers
This means that machine.UART0, machine.UART1, etc are of type
*machine.UART, not machine.UART. This makes them easier to pass around
and avoids surprises when they are passed around by value while they
should be passed around by reference.

There is a small code size impact in some cases, but it is relatively
minor.
2021-05-13 16:43:37 +02:00
Ayke van Laethem
d1e96fd0a8 wasm: scan globals conservatively
Make the GC globals scan phase conservative instead of precise on
WebAssembly. This reduces code size at the risk of introducing some
false positives.

This is a stopgap measure to mitigate an issue with the precise scanning
of globals that doesn't track all pointers. It works for regular globals
but globals created in the interp package don't always have a type and
therefore may be missed by the AddGlobalsBitmap pass.
The same issue is present on Linux and macOS, but is not as noticeable
there.
2021-05-11 18:15:36 +02:00
sago35
e7c6bd3730 atsame5x: add support for CAN 2021-05-10 12:27:10 +02:00
Ayke van Laethem
8cd2a462b9 runtime: remove the asyncScheduler constant
There is no reason to specialize this per chip as it is only ever used
for JavaScript. Not only that, it is causing confusion and is yet
another quirk to learn when porting the runtime to a new
microcontroller.
2021-05-08 23:08:12 +02:00
Ayke van Laethem
25b045d0a7 runtime: improve timers on nrf, and samd chips
This commit improves the timers on various microcontrollers to better
deal with counter wraparound. The result is a reduction in RAM size of
around 12 bytes and a small effect (sometimes positive, sometimes
negative) on flash consumption. But perhaps more importantly: getting
the current time is now interrupt-safe (it previously could result in a
race condition) and the timer will now be correct when the timer isn't
retrieved for a long duration. Before this commit, a call to `time.Now`
more than 8 minutes after the previous call could result in an incorrect
time.

For more details, see:
https://www.eevblog.com/forum/microcontrollers/correct-timing-by-timer-overflow-count/msg749617/#msg749617
2021-05-08 20:59:40 +02:00