Compare commits

...

56 Commits

Author SHA1 Message Date
Isaac Rodman 4223a60823 Add qtpy-rp2040 to TinyGo v0.25.0 2022-09-02 09:26:23 +09:00
Ayke van Laethem e955aa1941 reflect: implement CanInterface and fix string Index()
This commit fixes two related issues:

 1. CanInterface was unimplemented. It now uses the same check as is
    used in Interface() itself.
    This issue led to https://github.com/tinygo-org/tinygo/issues/3033
 2. Allow making an interface out of a string char element.

Doing this in one commit (instead of two) because they are shown to be
correct with the same tests.
2022-09-01 21:42:22 +02:00
sago35 edaf13f951 wioterminal: add UART3 for RTL8720DN 2022-09-01 19:22:01 +02:00
Ayke van Laethem 5f6cf665f5 compileopts: fix windows/arm target triple
This is just a papercut, and not really something important. But I
noticed something weird:

    $ GOOS=windows GOARCH=arm tinygo info ""
    LLVM triple:       armv7-unknown-windows-gnueabihf-gnu
    GOOS:              windows
    GOARCH:            arm

That -gnueabihf-gnu ending is weird, it should pick one of the two. I've
fixed it as follows:

    $ GOOS=windows GOARCH=arm tinygo info ""
    LLVM triple:       armv7-unknown-windows-gnu
    GOOS:              windows
    GOARCH:            arm
    [...]

We're probably never going to support windows/arm (this is 32-bit arm,
not arm64) so it doesn't really matter which one we pick. And this patch
shouldn't affect any other system.
2022-09-01 16:23:24 +02:00
Ayke van Laethem c6db89ff05 main: remove GOARM from tinygo info
I think it is more confusing than helpful because it is only relevant
when compiling an actual linux/arm binary (and in that case, it is also
included in the LLVM triple).

See: https://github.com/tinygo-org/tinygo/issues/3034
2022-09-01 13:17:37 +02:00
deadprogram 61d651c947 flash: update serial package to v1.3.5 for latest bugfixes
Signed-off-by: deadprogram <ron@hybridgroup.com>
2022-09-01 11:40:52 +02:00
Damian Gryski 227a55d891 loader,crypto: fix link error for crypto/internal/boring/sig.StandardCrypto 2022-09-01 09:48:40 +02:00
Ayke van Laethem b485e8bfbd compiler: fix unsafe.Sizeof for chan and map values
These types are simply pointers. For some reason, they were never
implemented.

Fixes https://github.com/tinygo-org/tinygo/issues/3083.
2022-09-01 03:53:27 +02:00
Ayke van Laethem 9e8739bb47 compiler: replace math aliases with intrinsics
This is really a few more-or-less separate changes:

  * Remove all math aliases that were used in Go 1.16 and below (the
    math.[A-Z] aliases).
  * Replace math aliases with an assembly implementation (the math.arch*
    aliases) with a LLVM intrinsic, where one is available.
  * Include missing math functions in picolibc build.

This leaves just four math aliases:

  * math.archHypot and math.archModf do not have a LLVM builtin
    equivalent. They could be replaced with calls to libm, and I think
    that would be a good idea in the long term.
  * math.archMax and math.archMin do have a LLVM builtin equivalent
    (llvm.maximum.f64, llvm.minimum.f64), but unfortunately they crash
    when used. Apparently these exact operations are not yet widely
    supported in hardware and they don't have a libm equivalent either.

There are more LLVM builtins that we could use for the math package
(such as FMA), but I will leave that to a future change. It could
potentially speed up some math operations.
2022-08-30 17:33:16 +02:00
Ayke van Laethem 20a7a6fd54 compiler: replace some math operation bodies with fast intrinsics
Instead of changing the calls, replace the function bodies themselves.
This is useful for a number of reasons, see
https://github.com/tinygo-org/tinygo/pull/2920 for more information.

I have removed the math intrinsics tests because they are no longer
useful. Instead, I think `tinygo test math` should suffice.
2022-08-30 17:33:16 +02:00
Ayke van Laethem 4695da83b7 all: drop support for Go 1.16 and Go 1.17 2022-08-30 12:38:06 +02:00
Yurii Soldak f094e895c5 p1am-100: remove duplicate build tags 2022-08-29 09:44:03 +02:00
Yurii Soldak 55573c6729 targets: fail fast on duplicate values in target field slices 2022-08-29 09:44:03 +02:00
Ayke van Laethem b8a6a1f62b compiler: use the LLVM builtins everywhere
This gives some more optimization opportunities to LLVM, because it
understands these intrinsics. For example, it might convert
llvm.sqrt.f64 to llvm.sqrt.f32 if possible.
2022-08-28 23:37:56 +02:00
Matt Schultz ef912a132d machine: Add support for Adafruit QT2040 board. 2022-08-28 10:16:52 +02:00
Yurii Soldak fb603a471c boards: Add XIAO ESP32C3 board 2022-08-26 12:44:04 +02:00
Joe Shaw f439514703 runtime: implement resetTimer 2022-08-25 11:30:33 +02:00
sago35 303410d3fc main: ignore ports with VID/PID if not candidates 2022-08-24 19:42:49 +02:00
Daniel Esteban aa13b5d83b Add Pimoroni's Tufty2040 board 2022-08-24 13:50:02 +02:00
Kenneth Bell 12d63d9642 runtime: improve reliability of timers test in CI 2022-08-24 11:05:40 +02:00
Kenneth Bell 24b45555bd runtime: add support for time.NewTimer and time.NewTicker
This commit adds support for time.NewTimer and time.NewTicker. It also
adds support for the Stop() method on time.Timer, but doesn't (yet) add
support for the Reset() method.

The implementation has been carefully written so that programs that
don't use these timers will normally not see an increase in RAM or
binary size. None of the examples in the drivers repo change as a result
of this commit. This comes at the cost of slightly more complex code and
possibly slower execution of the timers when they are used.
2022-08-23 12:37:25 +02:00
Damian Gryski 80c17c0f32 testdata: add russross/blackfriday markdown parser to corpus 2022-08-22 23:06:14 +02:00
Ayke van Laethem f6e6aca8d9 compiler: fix incorrect DWARF type in some generic parameters
For some reason, the type of a function parameter can sometimes be of
interface type, while it should be the underlying type. This might be a
bug in the x/tools/go/ssa package but this is a simple workaround.
2022-08-22 10:31:30 +02:00
Damian Gryski c4d99e5297 src/testing: add support for -benchmem 2022-08-20 11:41:20 +02:00
Damian Gryski 697e8c725b runtime: add MemStats.Mallocs and Frees 2022-08-20 11:41:20 +02:00
Damian Gryski a87e5cdbf0 runtime: add MemStats.TotalAlloc 2022-08-20 11:41:20 +02:00
Damian Gryski b56baa7aad runtime: make MemStats available to leaking collector 2022-08-20 11:41:20 +02:00
deadprogram ee94f92ede build: pin public_suffix Ruby gem to version 4.0.7
Signed-off-by: deadprogram <ron@hybridgroup.com>
2022-08-20 08:57:47 +02:00
Damian Gryski 0b77e92c50 make interp timeout configurable from command line 2022-08-20 07:40:39 +02:00
Avi a4ee98e0e1 Add aliases for edwards25519/field.feMul and field.feSquare
ed25519vectors_test.go still fails because:
* It relies on "go mod download" which doesn't work, as well as fork/exec.
* It relies on JSON parsing which has problems with reflection.

But, with the vectors hard coded in the test file the tests *do* succeed, so the encryption is working.
2022-08-18 18:57:16 +02:00
Miguel Angel d0808c93f6 runtime/pprof: add WriteHeapProfile
Fixes: #3071
2022-08-16 09:16:55 +02:00
Ayke van Laethem a0407be7b7 goenv: support GOOS=android
TinyGo doesn't currently support Android directly. However, GOOS=linux
works fine on Android. Therefore, force GOOS=linux on Android.
2022-08-13 12:43:38 +02:00
Elliott Sales de Andrade e70dfa4dd6 Fix skip message for missing emulators 2022-08-09 18:10:35 +02:00
Yeicor f34a0d44ca Fix for builds of tinygo using an Android host 2022-08-09 11:14:39 +02:00
Elliott Sales de Andrade df52b500bf Fix tinygo-test with Go 1.19
One of the internal packages used for tests was moved in that version.
2022-08-09 09:18:49 +02:00
Elliott Sales de Andrade c2f437e0b7 Add ErrProcessDone error
This is used in upstream Go's `os` package now.
2022-08-09 09:18:49 +02:00
Yurii Soldak 2365c7cfec nrf52: cleanup s140v7 uf2 targets 2022-08-07 12:58:36 +02:00
Yurii Soldak a5d28bdcca nrf52: cleanup s140v6 uf2 targets 2022-08-07 11:27:49 +02:00
Damian Gryski f12ddfe164 all: update _test.go files for os.IsFoo changes 2022-08-07 10:32:23 +02:00
Damian Gryski f9ba99344a all: update _test.go files for ioutil changes 2022-08-07 10:32:23 +02:00
Damian Gryski 1784bcd728 compileopts: use backticks for regexp to avoid extra escapes 2022-08-07 10:32:23 +02:00
Damian Gryski a2704f1435 all: move from os.IsFoo to errors.Is(err, ErrFoo) 2022-08-07 10:32:23 +02:00
Damian Gryski edbbca5614 all: remove calls to deprecated ioutil package
Fixes produced via semgrep and https://github.com/dgryski/semgrep-go/blob/master/ioutil.yml
2022-08-07 10:32:23 +02:00
Roman Volosatovs 13f21477b1 syscall/darwin: add ENOTCONN
Signed-off-by: Roman Volosatovs <roman@profian.com>
2022-08-07 09:04:57 +02:00
Roman Volosatovs 9d73e6cfe4 os: add SyscallError.Timeout
Signed-off-by: Roman Volosatovs <roman@profian.com>
2022-08-06 12:40:15 +02:00
Roman Volosatovs 9e7667ffae syscall: add WASI {D,R}SYNC, NONBLOCK FD flags
Signed-off-by: Roman Volosatovs <roman@profian.com>
2022-08-06 09:38:00 +02:00
Roman Volosatovs b86467f9c5 syscall: group WASI consts by purpose
Signed-off-by: Roman Volosatovs <roman@profian.com>
2022-08-06 09:38:00 +02:00
Roman Volosatovs 13a16afc2a net: sync net.go with Go 1.18 stdlib
Signed-off-by: Roman Volosatovs <roman@profian.com>
2022-08-06 08:05:29 +02:00
Roman Volosatovs a107b4d459 syscall: ensure correct C prototype WASI function signature
Signed-off-by: Roman Volosatovs <roman@profian.com>
2022-08-05 21:05:46 +02:00
Ayke van Laethem 5c176f80d5 ci: add check that TinyGo can be built using Homebrew LLVM
This is supposed to work, but there was no CI check. Add it to make sure
it continues to work.
2022-08-05 16:21:34 +02:00
Ayke van Laethem c4392d9472 all: rename assembly files to .S extension
The Go tools only consider lowercase .s files to be assembly files. By
renaming these to uppercase .S files they won't be discovered by the Go
toolchain and listed as the SFiles to be assembled.

There is a difference between .s and .S: only uppercase .S will be
passed through the preprocessor. Doing that is normally safe, and
definitely safe in the case of these files.
2022-08-04 15:43:42 +02:00
Ayke van Laethem b6d6efde07 all: remove support for LLVM 13 2022-08-04 14:31:54 +02:00
sago35 8b67282f91 examples/wasm: improve Makefile 2022-08-04 13:10:41 +02:00
Ayke van Laethem c7a23183e8 all: format code according to Go 1.19 rules
Go 1.19 started reformatting code in a way that makes it more obvious
how it will be rendered on pkg.go.dev. It gets it almost right, but not
entirely. Therefore, I had to modify some of the comments so that they
are formatted correctly.
2022-08-04 12:18:32 +02:00
Ayke van Laethem f936125658 main: use tags parser from buildutil
This should add support for things like quotes around tags, if they are
ever needed.

Only making this change now because I happened to stumble across
buildutil.TagsFlag.
2022-08-04 11:17:43 +02:00
sago35 3cfaceeb16 all: update version for next development iteration 2022-08-04 09:11:18 +02:00
240 changed files with 2462 additions and 1719 deletions
+4 -4
View File
@@ -112,12 +112,12 @@ commands:
- /go/pkg/mod
jobs:
test-llvm13-go116:
test-llvm14-go118:
docker:
- image: golang:1.16-buster
- image: golang:1.18-buster
steps:
- test-linux:
llvm: "13"
llvm: "14"
test-llvm14-go119:
docker:
- image: golang:1.19beta1-buster
@@ -131,7 +131,7 @@ workflows:
jobs:
# This tests our lowest supported versions of Go and LLVM, to make sure at
# least the smoke tests still pass.
- test-llvm13-go116
- test-llvm14-go118
# This tests a beta version of Go. It should be removed once regular
# release builds are built using this version.
- test-llvm14-go119
+25
View File
@@ -100,3 +100,28 @@ jobs:
- name: Smoke tests
shell: bash
run: make smoketest TINYGO=$(PWD)/build/tinygo AVR=0
test-macos-homebrew:
name: homebrew-install
runs-on: macos-latest
steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: '1.18'
- name: Install LLVM
shell: bash
run: |
HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@14
- name: Checkout
uses: actions/checkout@v2
- name: Cache Go
uses: actions/cache@v2
with:
key: go-cache-macos-homebrew-v1-${{ hashFiles('go.mod') }}
path: |
~/Library/Caches/go-build
~/go/pkg/mod
- name: Build TinyGo
run: go install
- name: Check binary
run: tinygo version
+3
View File
@@ -98,6 +98,7 @@ jobs:
run: make wasi-libc
- name: Install fpm
run: |
gem install --version 4.0.7 public_suffix
gem install --version 2.7.6 dotenv
gem install --no-document fpm
- name: Build TinyGo release
@@ -334,6 +335,7 @@ jobs:
make CROSS=arm-linux-gnueabihf binaryen
- name: Install fpm
run: |
sudo gem install --version 4.0.7 public_suffix
sudo gem install --version 2.7.6 dotenv
sudo gem install --no-document fpm
- name: Build TinyGo binary
@@ -436,6 +438,7 @@ jobs:
make CROSS=aarch64-linux-gnu binaryen
- name: Install fpm
run: |
sudo gem install --version 4.0.7 public_suffix
sudo gem install --version 2.7.6 dotenv
sudo gem install --no-document fpm
- name: Build TinyGo binary
+1 -1
View File
@@ -18,7 +18,7 @@ tarball. If you want to help with development of TinyGo itself, you should follo
LLVM, Clang and LLD are quite light on dependencies, requiring only standard
build tools to be built. Go is of course necessary to build TinyGo itself.
* Go (1.16+)
* Go (1.18+)
* Standard build tools (gcc/clang)
* git
* CMake
+18 -1
View File
@@ -280,7 +280,6 @@ TEST_PACKAGES_FAST = \
container/list \
container/ring \
crypto/des \
crypto/elliptic/internal/fiat \
crypto/internal/subtle \
crypto/md5 \
crypto/rc4 \
@@ -317,6 +316,14 @@ TEST_PACKAGES_FAST = \
unicode \
unicode/utf16 \
unicode/utf8 \
$(nil)
# Assume this will go away before Go2, so only check minor version.
ifeq ($(filter $(shell $(GO) env GOVERSION | cut -f 2 -d.), 16 17 18), )
TEST_PACKAGES_FAST += crypto/internal/nistec/fiat
else
TEST_PACKAGES_FAST += crypto/elliptic/internal/fiat
endif
# archive/zip requires os.ReadAt, which is not yet supported on windows
# debug/plan9obj requires os.ReadAt, which is not yet supported on windows
@@ -578,16 +585,22 @@ endif
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=feather-rp2040 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=qtpy-rp2040 examples/echo
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=macropad-rp2040 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=badger2040 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=tufty2040 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=thingplus-rp2040 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=xiao-rp2040 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=challenger-rp2040 examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=trinkey-qt2040 examples/adc_rp2040
@$(MD5SUM) test.hex
# test pwm
$(TINYGO) build -size short -o test.hex -target=itsybitsy-m0 examples/pwm
@$(MD5SUM) test.hex
@@ -672,6 +685,8 @@ endif
@$(MD5SUM) test.bin
$(TINYGO) build -size short -o test.bin -target=m5stamp-c3 examples/serial
@$(MD5SUM) test.bin
$(TINYGO) build -size short -o test.bin -target=xiao-esp32c3 examples/serial
@$(MD5SUM) test.bin
$(TINYGO) build -size short -o test.hex -target=hifive1b examples/blinky1
@$(MD5SUM) test.hex
$(TINYGO) build -size short -o test.hex -target=hifive1-qemu examples/serial
@@ -748,6 +763,7 @@ endif
@cp -rp lib/musl/src/internal build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/malloc build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/mman build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/math build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/signal build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/stdio build/release/tinygo/lib/musl/src
@cp -rp lib/musl/src/string build/release/tinygo/lib/musl/src
@@ -766,6 +782,7 @@ endif
@cp -rp lib/picolibc/newlib/libc/string build/release/tinygo/lib/picolibc/newlib/libc
@cp -rp lib/picolibc/newlib/libc/tinystdio build/release/tinygo/lib/picolibc/newlib/libc
@cp -rp lib/picolibc/newlib/libm/common build/release/tinygo/lib/picolibc/newlib/libm
@cp -rp lib/picolibc/newlib/libm/math build/release/tinygo/lib/picolibc/newlib/libm
@cp -rp lib/picolibc-stdio.c build/release/tinygo/lib
@cp -rp lib/wasi-libc/sysroot build/release/tinygo/lib/wasi-libc/sysroot
@cp -rp llvm-project/compiler-rt/lib/builtins build/release/tinygo/lib/compiler-rt-builtins
+5 -1
View File
@@ -43,7 +43,7 @@ See the [getting started instructions](https://tinygo.org/getting-started/) for
You can compile TinyGo programs for microcontrollers, WebAssembly and Linux.
The following 88 microcontroller boards are currently supported:
The following 91 microcontroller boards are currently supported:
* [Adafruit Circuit Playground Bluefruit](https://www.adafruit.com/product/4333)
* [Adafruit Circuit Playground Express](https://www.adafruit.com/product/3333)
@@ -66,7 +66,9 @@ The following 88 microcontroller boards are currently supported:
* [Adafruit PyGamer](https://www.adafruit.com/product/4242)
* [Adafruit PyPortal](https://www.adafruit.com/product/4116)
* [Adafruit QT Py](https://www.adafruit.com/product/4600)
* [Adafruit QT Py RP2040](https://www.adafruit.com/product/4900)
* [Adafruit Trinket M0](https://www.adafruit.com/product/3500)
* [Adafruit Trinkey QT2040](https://adafruit.com/product/5056)
* [Arduino Mega 1280](https://www.arduino.cc/en/Main/arduinoBoardMega/)
* [Arduino Mega 2560](https://store.arduino.cc/arduino-mega-2560-rev3)
* [Arduino MKR1000](https://store.arduino.cc/arduino-mkr1000-wifi)
@@ -108,6 +110,7 @@ The following 88 microcontroller boards are currently supported:
* [Particle Xenon](https://docs.particle.io/datasheets/discontinued/xenon-datasheet/)
* [Phytec reel board](https://www.phytec.eu/product-eu/internet-of-things/reelboard/)
* [Pimoroni Badger2040](https://shop.pimoroni.com/products/badger-2040)
* [Pimoroni Tufty2040](https://shop.pimoroni.com/products/tufty-2040)
* [PineTime DevKit](https://www.pine64.org/pinetime/)
* [PJRC Teensy 3.6](https://www.pjrc.com/store/teensy36.html)
* [PJRC Teensy 4.0](https://www.pjrc.com/store/teensy40.html)
@@ -117,6 +120,7 @@ The following 88 microcontroller boards are currently supported:
* [Raytac MDBT50Q-RX Dongle (with TinyUF2 bootloader)](https://www.adafruit.com/product/5199)
* [Seeed Seeeduino XIAO](https://www.seeedstudio.com/Seeeduino-XIAO-Arduino-Microcontroller-SAMD21-Cortex-M0+-p-4426.html)
* [Seeed XIAO BLE](https://www.seeedstudio.com/Seeed-XIAO-BLE-nRF52840-p-5201.html)
* [Seeed XIAO ESP32C3](https://www.seeedstudio.com/Seeed-XIAO-ESP32C3-p-5431.html)
* [Seeed XIAO RP2040](https://www.seeedstudio.com/XIAO-RP2040-v1-0-p-5026.html)
* [Seeed LoRa-E5 Development Kit](https://www.seeedstudio.com/LoRa-E5-Dev-Kit-p-4868.html)
* [Seeed Sipeed MAix BiT](https://www.seeedstudio.com/Sipeed-MAix-BiT-for-RISC-V-AI-IoT-p-2872.html)
+1 -1
View File
@@ -18,7 +18,7 @@ import (
// makeArchive creates an arcive for static linking from a list of object files
// given as a parameter. It is equivalent to the following command:
//
// ar -rcs <archivePath> <objs...>
// ar -rcs <archivePath> <objs...>
func makeArchive(arfile *os.File, objs []string) error {
// Open the archive file.
arwriter := ar.NewWriter(arfile)
+15 -15
View File
@@ -14,7 +14,7 @@ import (
"fmt"
"go/types"
"hash/crc32"
"io/ioutil"
"io/fs"
"math/bits"
"os"
"os/exec"
@@ -103,7 +103,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
}
// Create a temporary directory for intermediary files.
dir, err := ioutil.TempDir("", "tinygo")
dir, err := os.MkdirTemp("", "tinygo")
if err != nil {
return err
}
@@ -148,7 +148,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
libcDependencies = append(libcDependencies, libcJob)
case "wasi-libc":
path := filepath.Join(root, "lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a")
if _, err := os.Stat(path); os.IsNotExist(err) {
if _, err := os.Stat(path); errors.Is(err, fs.ErrNotExist) {
return errors.New("could not find wasi-libc, perhaps you need to run `make wasi-libc`?")
}
libcDependencies = append(libcDependencies, dummyCompileJob(path))
@@ -370,7 +370,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
// Packages are compiled independently anyway.
for _, cgoHeader := range pkg.CGoHeaders {
// Store the header text in a temporary file.
f, err := ioutil.TempFile(dir, "cgosnippet-*.c")
f, err := os.CreateTemp(dir, "cgosnippet-*.c")
if err != nil {
return err
}
@@ -431,7 +431,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
if pkgInit.IsNil() {
panic("init not found for " + pkg.Pkg.Path())
}
err := interp.RunFunc(pkgInit, config.DumpSSA())
err := interp.RunFunc(pkgInit, config.Options.InterpTimeout, config.DumpSSA())
if err != nil {
return err
}
@@ -445,7 +445,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
// Write to a temporary path that is renamed to the destination
// file to avoid race conditions with other TinyGo invocatiosn
// that might also be compiling this package at the same time.
f, err := ioutil.TempFile(filepath.Dir(job.result), filepath.Base(job.result))
f, err := os.CreateTemp(filepath.Dir(job.result), filepath.Base(job.result))
if err != nil {
return err
}
@@ -589,7 +589,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
return err
}
defer llvmBuf.Dispose()
return ioutil.WriteFile(outpath, llvmBuf.Bytes(), 0666)
return os.WriteFile(outpath, llvmBuf.Bytes(), 0666)
case ".bc":
var buf llvm.MemoryBuffer
if config.UseThinLTO() {
@@ -598,10 +598,10 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
buf = llvm.WriteBitcodeToMemoryBuffer(mod)
}
defer buf.Dispose()
return ioutil.WriteFile(outpath, buf.Bytes(), 0666)
return os.WriteFile(outpath, buf.Bytes(), 0666)
case ".ll":
data := []byte(mod.String())
return ioutil.WriteFile(outpath, data, 0666)
return os.WriteFile(outpath, data, 0666)
default:
panic("unreachable")
}
@@ -629,7 +629,7 @@ func Build(pkgName, outpath string, config *compileopts.Config, action func(Buil
}
}
defer llvmBuf.Dispose()
return ioutil.WriteFile(objfile, llvmBuf.Bytes(), 0666)
return os.WriteFile(objfile, llvmBuf.Bytes(), 0666)
},
}
@@ -1055,7 +1055,7 @@ func createEmbedObjectFile(data, hexSum, sourceFile, sourceDir, tmpdir string, c
// needed to convert a program to its final form. Some transformations are not
// optional and must be run as the compiler expects them to run.
func optimizeProgram(mod llvm.Module, config *compileopts.Config) error {
err := interp.Run(mod, config.DumpSSA())
err := interp.Run(mod, config.Options.InterpTimeout, config.DumpSSA())
if err != nil {
return err
}
@@ -1367,10 +1367,10 @@ func modifyStackSizes(executable string, stackSizeLoads []string, stackSizes map
//
// It might print something like the following:
//
// function stack usage (in bytes)
// Reset_Handler 316
// examples/blinky2.led1 92
// runtime.run$1 300
// function stack usage (in bytes)
// Reset_Handler 316
// examples/blinky2.led1 92
// runtime.run$1 300
func printStacks(calculatedStacks []string, stackSizes map[string]functionStackSize) {
// Print the sizes of all stacks.
fmt.Printf("%-32s %s\n", "function", "stack usage (in bytes)")
+1 -2
View File
@@ -2,7 +2,6 @@ package builder
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"runtime"
@@ -90,7 +89,7 @@ func testClangAttributes(t *testing.T, options *compileopts.Options) {
// Create a very simple C input file.
srcpath := filepath.Join(testDir, "test.c")
err = ioutil.WriteFile(srcpath, []byte("int add(int a, int b) { return a + b; }"), 0o666)
err = os.WriteFile(srcpath, []byte("int add(int a, int b) { return a + b; }"), 0o666)
if err != nil {
t.Fatalf("could not write target file %s: %s", srcpath, err)
}
+1 -1
View File
@@ -24,7 +24,7 @@ func ReadBuildID() ([]byte, error) {
defer f.Close()
switch runtime.GOOS {
case "linux", "freebsd":
case "linux", "freebsd", "android":
// Read the GNU build id section. (Not sure about FreeBSD though...)
file, err := elf.NewFile(f)
if err != nil {
+37 -36
View File
@@ -10,7 +10,7 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"io/fs"
"os"
"path/filepath"
"sort"
@@ -33,29 +33,29 @@ import (
// Because of this complexity, every file has in fact two cached build outputs:
// the file itself, and the list of dependencies. Its operation is as follows:
//
// depfile = hash(path, compiler, cflags, ...)
// if depfile exists:
// outfile = hash of all files and depfile name
// if outfile exists:
// # cache hit
// return outfile
// # cache miss
// tmpfile = compile file
// read dependencies (side effect of compile)
// write depfile
// outfile = hash of all files and depfile name
// rename tmpfile to outfile
// depfile = hash(path, compiler, cflags, ...)
// if depfile exists:
// outfile = hash of all files and depfile name
// if outfile exists:
// # cache hit
// return outfile
// # cache miss
// tmpfile = compile file
// read dependencies (side effect of compile)
// write depfile
// outfile = hash of all files and depfile name
// rename tmpfile to outfile
//
// There are a few edge cases that are not handled:
// - If a file is added to an include path, that file may be included instead of
// some other file. This would be fixed by also including lookup failures in the
// dependencies file, but I'm not aware of a compiler which does that.
// - The Makefile syntax that compilers output has issues, see readDepFile for
// details.
// - A header file may be changed to add/remove an include. This invalidates the
// depfile but without invalidating its name. For this reason, the depfile is
// written on each new compilation (even when it seems unnecessary). However, it
// could in rare cases lead to a stale file fetched from the cache.
// - If a file is added to an include path, that file may be included instead of
// some other file. This would be fixed by also including lookup failures in the
// dependencies file, but I'm not aware of a compiler which does that.
// - The Makefile syntax that compilers output has issues, see readDepFile for
// details.
// - A header file may be changed to add/remove an include. This invalidates the
// depfile but without invalidating its name. For this reason, the depfile is
// written on each new compilation (even when it seems unnecessary). However, it
// could in rare cases lead to a stale file fetched from the cache.
func compileAndCacheCFile(abspath, tmpdir string, cflags []string, thinlto bool, printCommands func(string, ...string)) (string, error) {
// Hash input file.
fileHash, err := hashFile(abspath)
@@ -93,7 +93,7 @@ func compileAndCacheCFile(abspath, tmpdir string, cflags []string, thinlto bool,
// Load dependencies file, if possible.
depfileName := "dep-" + depfileNameHash + ".json"
depfileCachePath := filepath.Join(goenv.Get("GOCACHE"), depfileName)
depfileBuf, err := ioutil.ReadFile(depfileCachePath)
depfileBuf, err := os.ReadFile(depfileCachePath)
var dependencies []string // sorted list of dependency paths
if err == nil {
// There is a dependency file, that's great!
@@ -108,21 +108,21 @@ func compileAndCacheCFile(abspath, tmpdir string, cflags []string, thinlto bool,
if err == nil {
if _, err := os.Stat(outpath); err == nil {
return outpath, nil
} else if !os.IsNotExist(err) {
} else if !errors.Is(err, fs.ErrNotExist) {
return "", err
}
}
} else if !os.IsNotExist(err) {
} else if !errors.Is(err, fs.ErrNotExist) {
// expected either nil or IsNotExist
return "", err
}
objTmpFile, err := ioutil.TempFile(goenv.Get("GOCACHE"), "tmp-*"+ext)
objTmpFile, err := os.CreateTemp(goenv.Get("GOCACHE"), "tmp-*"+ext)
if err != nil {
return "", err
}
objTmpFile.Close()
depTmpFile, err := ioutil.TempFile(tmpdir, "dep-*.d")
depTmpFile, err := os.CreateTemp(tmpdir, "dep-*.d")
if err != nil {
return "", err
}
@@ -166,7 +166,7 @@ func compileAndCacheCFile(abspath, tmpdir string, cflags []string, thinlto bool,
sort.Strings(dependencySlice)
// Write dependencies file.
f, err := ioutil.TempFile(filepath.Dir(depfileCachePath), depfileName)
f, err := os.CreateTemp(filepath.Dir(depfileCachePath), depfileName)
if err != nil {
return "", err
}
@@ -252,13 +252,14 @@ func hashFile(path string) (string, error) {
// file is assumed to have a single target named deps.
//
// There are roughly three make syntax variants:
// - BSD make, which doesn't support any escaping. This means that many special
// characters are not supported in file names.
// - GNU make, which supports escaping using a backslash but when it fails to
// find a file it tries to fall back with the literal path name (to match BSD
// make).
// - NMake (Visual Studio) and Jom, which simply quote the string if there are
// any weird characters.
// - BSD make, which doesn't support any escaping. This means that many special
// characters are not supported in file names.
// - GNU make, which supports escaping using a backslash but when it fails to
// find a file it tries to fall back with the literal path name (to match BSD
// make).
// - NMake (Visual Studio) and Jom, which simply quote the string if there are
// any weird characters.
//
// Clang supports two variants: a format that's a compromise between BSD and GNU
// make (and is buggy to match GCC which is equally buggy), and NMake/Jom, which
// is at least somewhat sane. This last format isn't perfect either: it does not
@@ -266,7 +267,7 @@ func hashFile(path string) (string, error) {
// allowed on Windows, but of course can be used on POSIX like systems. Still,
// it's the most sane of any of the formats so readDepFile will use that format.
func readDepFile(filename string) ([]string, error) {
buf, err := ioutil.ReadFile(filename)
buf, err := os.ReadFile(filename)
if err != nil {
return nil, err
}
+2 -2
View File
@@ -33,8 +33,8 @@ func NewConfig(options *compileopts.Options) (*compileopts.Config, error) {
if err != nil {
return nil, fmt.Errorf("could not read version from GOROOT (%v): %v", goroot, err)
}
if major != 1 || minor < 16 || minor > 19 {
return nil, fmt.Errorf("requires go version 1.16 through 1.19, got go%d.%d", major, minor)
if major != 1 || minor < 18 || minor > 19 {
return nil, fmt.Errorf("requires go version 1.18 through 1.19, got go%d.%d", major, minor)
}
clangHeaderPath := getClangHeaderPath(goenv.Get("TINYGOROOT"))
+4 -2
View File
@@ -1,6 +1,8 @@
package builder
import (
"errors"
"io/fs"
"io/ioutil"
"os"
"os/exec"
@@ -17,13 +19,13 @@ import (
func getClangHeaderPath(TINYGOROOT string) string {
// Check whether we're running from the source directory.
path := filepath.Join(TINYGOROOT, "llvm-project", "clang", "lib", "Headers")
if _, err := os.Stat(path); !os.IsNotExist(err) {
if _, err := os.Stat(path); !errors.Is(err, fs.ErrNotExist) {
return path
}
// Check whether we're running from the installation directory.
path = filepath.Join(TINYGOROOT, "lib", "clang", "include")
if _, err := os.Stat(path); !os.IsNotExist(err) {
if _, err := os.Stat(path); !errors.Is(err, fs.ErrNotExist) {
return path
}
+2 -2
View File
@@ -13,7 +13,7 @@ import (
"debug/elf"
"encoding/binary"
"fmt"
"io/ioutil"
"os"
"sort"
"strings"
)
@@ -189,5 +189,5 @@ func makeESPFirmareImage(infile, outfile, format string) error {
}
// Write the image to the output file.
return ioutil.WriteFile(outfile, outf.Bytes(), 0666)
return os.WriteFile(outfile, outf.Bytes(), 0666)
}
+12 -7
View File
@@ -1,7 +1,8 @@
package builder
import (
"io/ioutil"
"errors"
"io/fs"
"os"
"path/filepath"
"runtime"
@@ -94,7 +95,7 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
target := config.Triple()
if l.makeHeaders != nil {
if _, err = os.Stat(headerPath); err != nil {
temporaryHeaderPath, err := ioutil.TempDir(outdir, "include.tmp*")
temporaryHeaderPath, err := os.MkdirTemp(outdir, "include.tmp*")
if err != nil {
return nil, nil, err
}
@@ -110,10 +111,10 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
err = os.Rename(temporaryHeaderPath, headerPath)
if err != nil {
switch {
case os.IsExist(err):
case errors.Is(err, fs.ErrExist):
// Another invocation of TinyGo also seems to have already created the headers.
case runtime.GOOS == "windows" && os.IsPermission(err):
case runtime.GOOS == "windows" && errors.Is(err, fs.ErrPermission):
// On Windows, a rename with a destination directory that already
// exists does not result in an IsExist error, but rather in an
// access denied error. To be sure, check for this case by checking
@@ -155,7 +156,11 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
}
}
if strings.HasPrefix(target, "arm") || strings.HasPrefix(target, "thumb") {
args = append(args, "-fshort-enums", "-fomit-frame-pointer", "-mfloat-abi=soft", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
if strings.Split(target, "-")[2] == "linux" {
args = append(args, "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
} else {
args = append(args, "-fshort-enums", "-fomit-frame-pointer", "-mfloat-abi=soft", "-fno-unwind-tables", "-fno-asynchronous-unwind-tables")
}
}
if strings.HasPrefix(target, "avr") {
// AVR defaults to C float and double both being 32-bit. This deviates
@@ -189,7 +194,7 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
defer once.Do(unlock)
// Create an archive of all object files.
f, err := ioutil.TempFile(outdir, "libc.a.tmp*")
f, err := os.CreateTemp(outdir, "libc.a.tmp*")
if err != nil {
return err
}
@@ -250,7 +255,7 @@ func (l *Library) load(config *compileopts.Config, tmpdir string) (job *compileJ
run: func(*compileJob) error {
var compileArgs []string
compileArgs = append(compileArgs, args...)
tmpfile, err := ioutil.TempFile(outdir, "crt1.o.tmp*")
tmpfile, err := os.CreateTemp(outdir, "crt1.o.tmp*")
if err != nil {
return err
}
+1 -1
View File
@@ -78,7 +78,7 @@ func makeMinGWExtraLibs(tmpdir string) []*compileJob {
// .in files need to be preprocessed by a preprocessor (-E)
// first.
defpath = outpath + ".def"
err := runCCompiler("-E", "-x", "c", "-Wp,-w", "-P", "-DDEF_X64", "-o", defpath, inpath, "-I"+goenv.Get("TINYGOROOT")+"/lib/mingw-w64/mingw-w64-crt/def-include/")
err := runCCompiler("-E", "-x", "c", "-Wp,-w", "-P", "-DDEF_X64", "-DDATA", "-o", defpath, inpath, "-I"+goenv.Get("TINYGOROOT")+"/lib/mingw-w64/mingw-w64-crt/def-include/")
if err != nil {
return err
}
+4 -3
View File
@@ -3,7 +3,6 @@ package builder
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
@@ -35,7 +34,7 @@ var Musl = Library{
filepath.Join(muslDir, "include", "alltypes.h.in"),
}
for _, infile := range infiles {
data, err := ioutil.ReadFile(infile)
data, err := os.ReadFile(infile)
if err != nil {
return err
}
@@ -63,7 +62,7 @@ var Musl = Library{
if err != nil {
return err
}
data, err := ioutil.ReadFile(filepath.Join(muslDir, "arch", arch, "bits", "syscall.h.in"))
data, err := os.ReadFile(filepath.Join(muslDir, "arch", arch, "bits", "syscall.h.in"))
if err != nil {
return err
}
@@ -90,6 +89,7 @@ var Musl = Library{
"-Wno-shift-op-parentheses",
"-Wno-ignored-attributes",
"-Wno-string-plus-int",
"-Wno-ignored-pragmas",
"-Qunused-arguments",
// Select include dirs. Don't include standard library includes
// (that would introduce host dependencies and other complications),
@@ -118,6 +118,7 @@ var Musl = Library{
"legacy/*.c",
"malloc/*.c",
"mman/*.c",
"math/*.c",
"signal/*.c",
"stdio/*.c",
"string/*.c",
+2 -2
View File
@@ -2,7 +2,7 @@ package builder
import (
"fmt"
"io/ioutil"
"io"
"os/exec"
"github.com/tinygo-org/tinygo/compileopts"
@@ -18,7 +18,7 @@ func makeDFUFirmwareImage(options *compileopts.Options, infile, outfile string)
}
cmd := exec.Command(cmdLine[0], cmdLine[1:]...)
cmd.Stdout = ioutil.Discard
cmd.Stdout = io.Discard
err := cmd.Run()
if err != nil {
return fmt.Errorf("could not run nrfutil pkg generate: %w", err)
+2 -2
View File
@@ -2,7 +2,7 @@ package builder
import (
"debug/elf"
"io/ioutil"
"io"
"os"
"sort"
@@ -87,7 +87,7 @@ func extractROM(path string) (uint64, []byte, error) {
// Pad the difference
rom = append(rom, make([]byte, diff)...)
}
data, err := ioutil.ReadAll(prog.Open())
data, err := io.ReadAll(prog.Open())
if err != nil {
return 0, nil, objcopyError{"failed to extract segment from ELF file: " + path, err}
}
+380 -204
View File
@@ -19,7 +19,7 @@ var Picolibc = Library{
return f.Close()
},
cflags: func(target, headerPath string) []string {
picolibcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib/libc")
newlibDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib")
return []string{
"-Werror",
"-Wall",
@@ -27,219 +27,395 @@ var Picolibc = Library{
"-D_COMPILING_NEWLIB",
"-DHAVE_ALIAS_ATTRIBUTE",
"-DTINY_STDIO",
"-D_IEEE_LIBM",
"-D__OBSOLETE_MATH_FLOAT=1", // use old math code that doesn't expect a FPU
"-D__OBSOLETE_MATH_DOUBLE=0",
"-nostdlibinc",
"-isystem", picolibcDir + "/include",
"-I" + picolibcDir + "/tinystdio",
"-isystem", newlibDir + "/libc/include",
"-I" + newlibDir + "/libc/tinystdio",
"-I" + newlibDir + "/libm/common",
"-I" + headerPath,
}
},
sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib/libc") },
sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/picolibc/newlib") },
librarySources: func(target string) []string {
return picolibcSources
},
}
var picolibcSources = []string{
"../../../picolibc-stdio.c",
"../../picolibc-stdio.c",
"tinystdio/asprintf.c",
"tinystdio/atod_engine.c",
"tinystdio/atod_ryu.c",
"tinystdio/atof_engine.c",
"tinystdio/atof_ryu.c",
//"tinystdio/atold_engine.c", // have_long_double and not long_double_equals_double
"tinystdio/clearerr.c",
"tinystdio/compare_exchange.c",
"tinystdio/dtoa_data.c",
"tinystdio/dtoa_engine.c",
"tinystdio/dtoa_ryu.c",
"tinystdio/ecvtbuf.c",
"tinystdio/ecvt.c",
"tinystdio/ecvt_data.c",
"tinystdio/ecvtfbuf.c",
"tinystdio/ecvtf.c",
"tinystdio/ecvtf_data.c",
"tinystdio/exchange.c",
//"tinystdio/fclose.c", // posix-io
"tinystdio/fcvtbuf.c",
"tinystdio/fcvt.c",
"tinystdio/fcvtfbuf.c",
"tinystdio/fcvtf.c",
"tinystdio/fdevopen.c",
//"tinystdio/fdopen.c", // posix-io
"tinystdio/feof.c",
"tinystdio/ferror.c",
"tinystdio/fflush.c",
"tinystdio/fgetc.c",
"tinystdio/fgets.c",
"tinystdio/fileno.c",
"tinystdio/filestrget.c",
"tinystdio/filestrputalloc.c",
"tinystdio/filestrput.c",
//"tinystdio/fopen.c", // posix-io
"tinystdio/fprintf.c",
"tinystdio/fputc.c",
"tinystdio/fputs.c",
"tinystdio/fread.c",
"tinystdio/fscanf.c",
"tinystdio/fseek.c",
"tinystdio/ftell.c",
"tinystdio/ftoa_data.c",
"tinystdio/ftoa_engine.c",
"tinystdio/ftoa_ryu.c",
"tinystdio/fwrite.c",
"tinystdio/gcvtbuf.c",
"tinystdio/gcvt.c",
"tinystdio/gcvtfbuf.c",
"tinystdio/gcvtf.c",
"tinystdio/getchar.c",
"tinystdio/gets.c",
"tinystdio/matchcaseprefix.c",
"tinystdio/perror.c",
//"tinystdio/posixiob.c", // posix-io
//"tinystdio/posixio.c", // posix-io
"tinystdio/printf.c",
"tinystdio/putchar.c",
"tinystdio/puts.c",
"tinystdio/ryu_divpow2.c",
"tinystdio/ryu_log10.c",
"tinystdio/ryu_log2pow5.c",
"tinystdio/ryu_pow5bits.c",
"tinystdio/ryu_table.c",
"tinystdio/ryu_umul128.c",
"tinystdio/scanf.c",
"tinystdio/setbuf.c",
"tinystdio/setvbuf.c",
//"tinystdio/sflags.c", // posix-io
"tinystdio/snprintf.c",
"tinystdio/snprintfd.c",
"tinystdio/snprintff.c",
"tinystdio/sprintf.c",
"tinystdio/sprintfd.c",
"tinystdio/sprintff.c",
"tinystdio/sscanf.c",
"tinystdio/strfromd.c",
"tinystdio/strfromf.c",
"tinystdio/strtod.c",
"tinystdio/strtod_l.c",
"tinystdio/strtof.c",
//"tinystdio/strtold.c", // have_long_double and not long_double_equals_double
//"tinystdio/strtold_l.c", // have_long_double and not long_double_equals_double
"tinystdio/ungetc.c",
"tinystdio/vasprintf.c",
"tinystdio/vfiprintf.c",
"tinystdio/vfiscanf.c",
"tinystdio/vfprintf.c",
"tinystdio/vfprintff.c",
"tinystdio/vfscanf.c",
"tinystdio/vfscanff.c",
"tinystdio/vprintf.c",
"tinystdio/vscanf.c",
"tinystdio/vsnprintf.c",
"tinystdio/vsprintf.c",
"tinystdio/vsscanf.c",
"libc/tinystdio/asprintf.c",
"libc/tinystdio/atod_engine.c",
"libc/tinystdio/atod_ryu.c",
"libc/tinystdio/atof_engine.c",
"libc/tinystdio/atof_ryu.c",
//"libc/tinystdio/atold_engine.c", // have_long_double and not long_double_equals_double
"libc/tinystdio/clearerr.c",
"libc/tinystdio/compare_exchange.c",
"libc/tinystdio/dtoa_data.c",
"libc/tinystdio/dtoa_engine.c",
"libc/tinystdio/dtoa_ryu.c",
"libc/tinystdio/ecvtbuf.c",
"libc/tinystdio/ecvt.c",
"libc/tinystdio/ecvt_data.c",
"libc/tinystdio/ecvtfbuf.c",
"libc/tinystdio/ecvtf.c",
"libc/tinystdio/ecvtf_data.c",
"libc/tinystdio/exchange.c",
//"libc/tinystdio/fclose.c", // posix-io
"libc/tinystdio/fcvtbuf.c",
"libc/tinystdio/fcvt.c",
"libc/tinystdio/fcvtfbuf.c",
"libc/tinystdio/fcvtf.c",
"libc/tinystdio/fdevopen.c",
//"libc/tinystdio/fdopen.c", // posix-io
"libc/tinystdio/feof.c",
"libc/tinystdio/ferror.c",
"libc/tinystdio/fflush.c",
"libc/tinystdio/fgetc.c",
"libc/tinystdio/fgets.c",
"libc/tinystdio/fileno.c",
"libc/tinystdio/filestrget.c",
"libc/tinystdio/filestrputalloc.c",
"libc/tinystdio/filestrput.c",
//"libc/tinystdio/fopen.c", // posix-io
"libc/tinystdio/fprintf.c",
"libc/tinystdio/fputc.c",
"libc/tinystdio/fputs.c",
"libc/tinystdio/fread.c",
"libc/tinystdio/fscanf.c",
"libc/tinystdio/fseek.c",
"libc/tinystdio/ftell.c",
"libc/tinystdio/ftoa_data.c",
"libc/tinystdio/ftoa_engine.c",
"libc/tinystdio/ftoa_ryu.c",
"libc/tinystdio/fwrite.c",
"libc/tinystdio/gcvtbuf.c",
"libc/tinystdio/gcvt.c",
"libc/tinystdio/gcvtfbuf.c",
"libc/tinystdio/gcvtf.c",
"libc/tinystdio/getchar.c",
"libc/tinystdio/gets.c",
"libc/tinystdio/matchcaseprefix.c",
"libc/tinystdio/perror.c",
//"libc/tinystdio/posixiob.c", // posix-io
//"libc/tinystdio/posixio.c", // posix-io
"libc/tinystdio/printf.c",
"libc/tinystdio/putchar.c",
"libc/tinystdio/puts.c",
"libc/tinystdio/ryu_divpow2.c",
"libc/tinystdio/ryu_log10.c",
"libc/tinystdio/ryu_log2pow5.c",
"libc/tinystdio/ryu_pow5bits.c",
"libc/tinystdio/ryu_table.c",
"libc/tinystdio/ryu_umul128.c",
"libc/tinystdio/scanf.c",
"libc/tinystdio/setbuf.c",
"libc/tinystdio/setvbuf.c",
//"libc/tinystdio/sflags.c", // posix-io
"libc/tinystdio/snprintf.c",
"libc/tinystdio/snprintfd.c",
"libc/tinystdio/snprintff.c",
"libc/tinystdio/sprintf.c",
"libc/tinystdio/sprintfd.c",
"libc/tinystdio/sprintff.c",
"libc/tinystdio/sscanf.c",
"libc/tinystdio/strfromd.c",
"libc/tinystdio/strfromf.c",
"libc/tinystdio/strtod.c",
"libc/tinystdio/strtod_l.c",
"libc/tinystdio/strtof.c",
//"libc/tinystdio/strtold.c", // have_long_double and not long_double_equals_double
//"libc/tinystdio/strtold_l.c", // have_long_double and not long_double_equals_double
"libc/tinystdio/ungetc.c",
"libc/tinystdio/vasprintf.c",
"libc/tinystdio/vfiprintf.c",
"libc/tinystdio/vfiscanf.c",
"libc/tinystdio/vfprintf.c",
"libc/tinystdio/vfprintff.c",
"libc/tinystdio/vfscanf.c",
"libc/tinystdio/vfscanff.c",
"libc/tinystdio/vprintf.c",
"libc/tinystdio/vscanf.c",
"libc/tinystdio/vsnprintf.c",
"libc/tinystdio/vsprintf.c",
"libc/tinystdio/vsscanf.c",
"string/bcmp.c",
"string/bcopy.c",
"string/bzero.c",
"string/explicit_bzero.c",
"string/ffsl.c",
"string/ffsll.c",
"string/fls.c",
"string/flsl.c",
"string/flsll.c",
"string/gnu_basename.c",
"string/index.c",
"string/memccpy.c",
"string/memchr.c",
"string/memcmp.c",
"string/memcpy.c",
"string/memmem.c",
"string/memmove.c",
"string/mempcpy.c",
"string/memrchr.c",
"string/memset.c",
"string/rawmemchr.c",
"string/rindex.c",
"string/stpcpy.c",
"string/stpncpy.c",
"string/strcasecmp.c",
"string/strcasecmp_l.c",
"string/strcasestr.c",
"string/strcat.c",
"string/strchr.c",
"string/strchrnul.c",
"string/strcmp.c",
"string/strcoll.c",
"string/strcoll_l.c",
"string/strcpy.c",
"string/strcspn.c",
"string/strdup.c",
"string/strerror.c",
"string/strerror_r.c",
"string/strlcat.c",
"string/strlcpy.c",
"string/strlen.c",
"string/strlwr.c",
"string/strncasecmp.c",
"string/strncasecmp_l.c",
"string/strncat.c",
"string/strncmp.c",
"string/strncpy.c",
"string/strndup.c",
"string/strnlen.c",
"string/strnstr.c",
"string/strpbrk.c",
"string/strrchr.c",
"string/strsep.c",
"string/strsignal.c",
"string/strspn.c",
"string/strstr.c",
"string/strtok.c",
"string/strtok_r.c",
"string/strupr.c",
"string/strverscmp.c",
"string/strxfrm.c",
"string/strxfrm_l.c",
"string/swab.c",
"string/timingsafe_bcmp.c",
"string/timingsafe_memcmp.c",
"string/u_strerr.c",
"string/wcpcpy.c",
"string/wcpncpy.c",
"string/wcscasecmp.c",
"string/wcscasecmp_l.c",
"string/wcscat.c",
"string/wcschr.c",
"string/wcscmp.c",
"string/wcscoll.c",
"string/wcscoll_l.c",
"string/wcscpy.c",
"string/wcscspn.c",
"string/wcsdup.c",
"string/wcslcat.c",
"string/wcslcpy.c",
"string/wcslen.c",
"string/wcsncasecmp.c",
"string/wcsncasecmp_l.c",
"string/wcsncat.c",
"string/wcsncmp.c",
"string/wcsncpy.c",
"string/wcsnlen.c",
"string/wcspbrk.c",
"string/wcsrchr.c",
"string/wcsspn.c",
"string/wcsstr.c",
"string/wcstok.c",
"string/wcswidth.c",
"string/wcsxfrm.c",
"string/wcsxfrm_l.c",
"string/wcwidth.c",
"string/wmemchr.c",
"string/wmemcmp.c",
"string/wmemcpy.c",
"string/wmemmove.c",
"string/wmempcpy.c",
"string/wmemset.c",
"string/xpg_strerror_r.c",
"libc/string/bcmp.c",
"libc/string/bcopy.c",
"libc/string/bzero.c",
"libc/string/explicit_bzero.c",
"libc/string/ffsl.c",
"libc/string/ffsll.c",
"libc/string/fls.c",
"libc/string/flsl.c",
"libc/string/flsll.c",
"libc/string/gnu_basename.c",
"libc/string/index.c",
"libc/string/memccpy.c",
"libc/string/memchr.c",
"libc/string/memcmp.c",
"libc/string/memcpy.c",
"libc/string/memmem.c",
"libc/string/memmove.c",
"libc/string/mempcpy.c",
"libc/string/memrchr.c",
"libc/string/memset.c",
"libc/string/rawmemchr.c",
"libc/string/rindex.c",
"libc/string/stpcpy.c",
"libc/string/stpncpy.c",
"libc/string/strcasecmp.c",
"libc/string/strcasecmp_l.c",
"libc/string/strcasestr.c",
"libc/string/strcat.c",
"libc/string/strchr.c",
"libc/string/strchrnul.c",
"libc/string/strcmp.c",
"libc/string/strcoll.c",
"libc/string/strcoll_l.c",
"libc/string/strcpy.c",
"libc/string/strcspn.c",
"libc/string/strdup.c",
"libc/string/strerror.c",
"libc/string/strerror_r.c",
"libc/string/strlcat.c",
"libc/string/strlcpy.c",
"libc/string/strlen.c",
"libc/string/strlwr.c",
"libc/string/strncasecmp.c",
"libc/string/strncasecmp_l.c",
"libc/string/strncat.c",
"libc/string/strncmp.c",
"libc/string/strncpy.c",
"libc/string/strndup.c",
"libc/string/strnlen.c",
"libc/string/strnstr.c",
"libc/string/strpbrk.c",
"libc/string/strrchr.c",
"libc/string/strsep.c",
"libc/string/strsignal.c",
"libc/string/strspn.c",
"libc/string/strstr.c",
"libc/string/strtok.c",
"libc/string/strtok_r.c",
"libc/string/strupr.c",
"libc/string/strverscmp.c",
"libc/string/strxfrm.c",
"libc/string/strxfrm_l.c",
"libc/string/swab.c",
"libc/string/timingsafe_bcmp.c",
"libc/string/timingsafe_memcmp.c",
"libc/string/u_strerr.c",
"libc/string/wcpcpy.c",
"libc/string/wcpncpy.c",
"libc/string/wcscasecmp.c",
"libc/string/wcscasecmp_l.c",
"libc/string/wcscat.c",
"libc/string/wcschr.c",
"libc/string/wcscmp.c",
"libc/string/wcscoll.c",
"libc/string/wcscoll_l.c",
"libc/string/wcscpy.c",
"libc/string/wcscspn.c",
"libc/string/wcsdup.c",
"libc/string/wcslcat.c",
"libc/string/wcslcpy.c",
"libc/string/wcslen.c",
"libc/string/wcsncasecmp.c",
"libc/string/wcsncasecmp_l.c",
"libc/string/wcsncat.c",
"libc/string/wcsncmp.c",
"libc/string/wcsncpy.c",
"libc/string/wcsnlen.c",
"libc/string/wcspbrk.c",
"libc/string/wcsrchr.c",
"libc/string/wcsspn.c",
"libc/string/wcsstr.c",
"libc/string/wcstok.c",
"libc/string/wcswidth.c",
"libc/string/wcsxfrm.c",
"libc/string/wcsxfrm_l.c",
"libc/string/wcwidth.c",
"libc/string/wmemchr.c",
"libc/string/wmemcmp.c",
"libc/string/wmemcpy.c",
"libc/string/wmemmove.c",
"libc/string/wmempcpy.c",
"libc/string/wmemset.c",
"libc/string/xpg_strerror_r.c",
"libm/common/sf_finite.c",
"libm/common/sf_copysign.c",
"libm/common/sf_modf.c",
"libm/common/sf_scalbn.c",
"libm/common/sf_cbrt.c",
"libm/common/sf_exp10.c",
"libm/common/sf_expm1.c",
"libm/common/sf_ilogb.c",
"libm/common/sf_infinity.c",
"libm/common/sf_isinf.c",
"libm/common/sf_isinff.c",
"libm/common/sf_isnan.c",
"libm/common/sf_isnanf.c",
"libm/common/sf_issignaling.c",
"libm/common/sf_log1p.c",
"libm/common/sf_nan.c",
"libm/common/sf_nextafter.c",
"libm/common/sf_pow10.c",
"libm/common/sf_rint.c",
"libm/common/sf_logb.c",
"libm/common/sf_fdim.c",
"libm/common/sf_fma.c",
"libm/common/sf_fmax.c",
"libm/common/sf_fmin.c",
"libm/common/sf_fpclassify.c",
"libm/common/sf_lrint.c",
"libm/common/sf_llrint.c",
"libm/common/sf_lround.c",
"libm/common/sf_llround.c",
"libm/common/sf_nearbyint.c",
"libm/common/sf_remquo.c",
"libm/common/sf_round.c",
"libm/common/sf_scalbln.c",
"libm/common/sf_trunc.c",
"libm/common/sf_exp.c",
"libm/common/sf_exp2.c",
"libm/common/sf_exp2_data.c",
"libm/common/sf_log.c",
"libm/common/sf_log_data.c",
"libm/common/sf_log2.c",
"libm/common/sf_log2_data.c",
"libm/common/sf_pow_log2_data.c",
"libm/common/sf_pow.c",
"libm/common/s_finite.c",
"libm/common/s_copysign.c",
"libm/common/s_modf.c",
"libm/common/s_scalbn.c",
"libm/common/s_cbrt.c",
"libm/common/s_exp10.c",
"libm/common/s_expm1.c",
"libm/common/s_ilogb.c",
"libm/common/s_infinity.c",
"libm/common/s_isinf.c",
"libm/common/s_isinfd.c",
"libm/common/s_isnan.c",
"libm/common/s_isnand.c",
"libm/common/s_issignaling.c",
"libm/common/s_log1p.c",
"libm/common/s_nan.c",
"libm/common/s_nextafter.c",
"libm/common/s_pow10.c",
"libm/common/s_rint.c",
"libm/common/s_logb.c",
"libm/common/s_log2.c",
"libm/common/s_fdim.c",
"libm/common/s_fma.c",
"libm/common/s_fmax.c",
"libm/common/s_fmin.c",
"libm/common/s_fpclassify.c",
"libm/common/s_lrint.c",
"libm/common/s_llrint.c",
"libm/common/s_lround.c",
"libm/common/s_llround.c",
"libm/common/s_nearbyint.c",
"libm/common/s_remquo.c",
"libm/common/s_round.c",
"libm/common/s_scalbln.c",
"libm/common/s_signbit.c",
"libm/common/s_trunc.c",
"libm/common/exp.c",
"libm/common/exp2.c",
"libm/common/exp_data.c",
"libm/common/math_err_with_errno.c",
"libm/common/math_err_xflow.c",
"libm/common/math_err_uflow.c",
"libm/common/math_err_oflow.c",
"libm/common/math_err_divzero.c",
"libm/common/math_err_invalid.c",
"libm/common/math_err_may_uflow.c",
"libm/common/math_err_check_uflow.c",
"libm/common/math_err_check_oflow.c",
"libm/common/log.c",
"libm/common/log_data.c",
"libm/common/log2.c",
"libm/common/log2_data.c",
"libm/common/pow.c",
"libm/common/pow_log_data.c",
"libm/math/e_acos.c",
"libm/math/e_acosh.c",
"libm/math/e_asin.c",
"libm/math/e_atan2.c",
"libm/math/e_atanh.c",
"libm/math/e_cosh.c",
"libm/math/e_exp.c",
"libm/math/ef_acos.c",
"libm/math/ef_acosh.c",
"libm/math/ef_asin.c",
"libm/math/ef_atan2.c",
"libm/math/ef_atanh.c",
"libm/math/ef_cosh.c",
"libm/math/ef_exp.c",
"libm/math/ef_fmod.c",
"libm/math/ef_hypot.c",
"libm/math/ef_j0.c",
"libm/math/ef_j1.c",
"libm/math/ef_jn.c",
"libm/math/ef_lgamma.c",
"libm/math/ef_log10.c",
"libm/math/ef_log.c",
"libm/math/e_fmod.c",
"libm/math/ef_pow.c",
"libm/math/ef_remainder.c",
"libm/math/ef_rem_pio2.c",
"libm/math/ef_scalb.c",
"libm/math/ef_sinh.c",
"libm/math/ef_sqrt.c",
"libm/math/ef_tgamma.c",
"libm/math/e_hypot.c",
"libm/math/e_j0.c",
"libm/math/e_j1.c",
"libm/math/e_jn.c",
"libm/math/e_lgamma.c",
"libm/math/e_log10.c",
"libm/math/e_log.c",
"libm/math/e_pow.c",
"libm/math/e_remainder.c",
"libm/math/e_rem_pio2.c",
"libm/math/erf_lgamma.c",
"libm/math/er_lgamma.c",
"libm/math/e_scalb.c",
"libm/math/e_sinh.c",
"libm/math/e_sqrt.c",
"libm/math/e_tgamma.c",
"libm/math/s_asinh.c",
"libm/math/s_atan.c",
"libm/math/s_ceil.c",
"libm/math/s_cos.c",
"libm/math/s_erf.c",
"libm/math/s_fabs.c",
"libm/math/sf_asinh.c",
"libm/math/sf_atan.c",
"libm/math/sf_ceil.c",
"libm/math/sf_cos.c",
"libm/math/sf_erf.c",
"libm/math/sf_fabs.c",
"libm/math/sf_floor.c",
"libm/math/sf_frexp.c",
"libm/math/sf_ldexp.c",
"libm/math/s_floor.c",
"libm/math/s_frexp.c",
"libm/math/sf_signif.c",
"libm/math/sf_sin.c",
"libm/math/sf_tan.c",
"libm/math/sf_tanh.c",
"libm/math/s_ldexp.c",
"libm/math/s_signif.c",
"libm/math/s_sin.c",
"libm/math/s_tan.c",
"libm/math/s_tanh.c",
}
+2 -2
View File
@@ -10,7 +10,7 @@ package builder
import (
"bytes"
"encoding/binary"
"io/ioutil"
"os"
"strconv"
)
@@ -26,7 +26,7 @@ func convertELFFileToUF2File(infile, outfile string, uf2FamilyID string) error {
if err != nil {
return err
}
return ioutil.WriteFile(outfile, output, 0644)
return os.WriteFile(outfile, output, 0644)
}
// convertBinToUF2 converts the binary bytes in input to UF2 formatted data.
+15 -15
View File
@@ -493,15 +493,15 @@ func (p *cgoPackage) makeUnionField(typ *elaboratedTypeInfo) *ast.StructType {
// createUnionAccessor creates a function that returns a typed pointer to a
// union field for each field in a union. For example:
//
// func (union *C.union_1) unionfield_d() *float64 {
// return (*float64)(unsafe.Pointer(&union.$union))
// }
// func (union *C.union_1) unionfield_d() *float64 {
// return (*float64)(unsafe.Pointer(&union.$union))
// }
//
// Where C.union_1 is defined as:
//
// type C.union_1 struct{
// $union uint64
// }
// type C.union_1 struct{
// $union uint64
// }
//
// The returned pointer can be used to get or set the field, or get the pointer
// to a subfield.
@@ -617,9 +617,9 @@ func (p *cgoPackage) createUnionAccessor(field *ast.Field, typeName string) {
// createBitfieldGetter creates a bitfield getter function like the following:
//
// func (s *C.struct_foo) bitfield_b() byte {
// return (s.__bitfield_1 >> 5) & 0x1
// }
// func (s *C.struct_foo) bitfield_b() byte {
// return (s.__bitfield_1 >> 5) & 0x1
// }
func (p *cgoPackage) createBitfieldGetter(bitfield bitfieldInfo, typeName string) {
// The value to return from the getter.
// Not complete: this is just an expression to get the complete field.
@@ -729,15 +729,15 @@ func (p *cgoPackage) createBitfieldGetter(bitfield bitfieldInfo, typeName string
// createBitfieldSetter creates a bitfield setter function like the following:
//
// func (s *C.struct_foo) set_bitfield_b(value byte) {
// s.__bitfield_1 = s.__bitfield_1 ^ 0x60 | ((value & 1) << 5)
// }
// func (s *C.struct_foo) set_bitfield_b(value byte) {
// s.__bitfield_1 = s.__bitfield_1 ^ 0x60 | ((value & 1) << 5)
// }
//
// Or the following:
//
// func (s *C.struct_foo) set_bitfield_c(value byte) {
// s.__bitfield_1 = s.__bitfield_1 & 0x3f | (value << 6)
// }
// func (s *C.struct_foo) set_bitfield_c(value byte) {
// s.__bitfield_1 = s.__bitfield_1 & 0x3f | (value << 6)
// }
func (p *cgoPackage) createBitfieldSetter(bitfield bitfieldInfo, typeName string) {
// The full field with all bitfields.
var field ast.Expr = &ast.SelectorExpr{
+3 -18
View File
@@ -5,12 +5,11 @@ import (
"flag"
"fmt"
"go/ast"
"go/build"
"go/format"
"go/parser"
"go/token"
"go/types"
"io/ioutil"
"os"
"path/filepath"
"runtime"
"strings"
@@ -40,20 +39,6 @@ func TestCGo(t *testing.T) {
} {
name := name // avoid a race condition
t.Run(name, func(t *testing.T) {
// Skip tests that require specific Go version.
if name == "errors" {
ok := false
for _, version := range build.Default.ReleaseTags {
if version == "go1.16" {
ok = true
break
}
}
if !ok {
t.Skip("Results for errors test are only valid for Go 1.16+")
}
}
// Read the AST in memory.
path := filepath.Join("testdata", name+".go")
fset := token.NewFileSet()
@@ -107,7 +92,7 @@ func TestCGo(t *testing.T) {
// Read the file with the expected output, to compare against.
outfile := filepath.Join("testdata", name+".out.go")
expectedBytes, err := ioutil.ReadFile(outfile)
expectedBytes, err := os.ReadFile(outfile)
if err != nil {
t.Fatalf("could not read expected output: %v", err)
}
@@ -118,7 +103,7 @@ func TestCGo(t *testing.T) {
// It is not. Test failed.
if *flagUpdate {
// Update the file with the expected data.
err := ioutil.WriteFile(outfile, []byte(actual), 0666)
err := os.WriteFile(outfile, []byte(actual), 0666)
if err != nil {
t.Error("could not write updated output file:", err)
}
-16
View File
@@ -1,16 +0,0 @@
//go:build !byollvm && llvm13
// +build !byollvm,llvm13
package cgo
/*
#cgo linux CFLAGS: -I/usr/lib/llvm-13/include
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@13/include
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@13/include
#cgo freebsd CFLAGS: -I/usr/local/llvm13/include
#cgo linux LDFLAGS: -L/usr/lib/llvm-13/lib -lclang
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@13/lib -lclang -lffi
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@13/lib -lclang -lffi
#cgo freebsd LDFLAGS: -L/usr/local/llvm13/lib -lclang
*/
import "C"
+2 -2
View File
@@ -1,5 +1,5 @@
//go:build !byollvm && !llvm13
// +build !byollvm,!llvm13
//go:build !byollvm
// +build !byollvm
package cgo
+3 -5
View File
@@ -73,9 +73,7 @@ func (c *Config) BuildTags() []string {
for i := 1; i <= c.GoMinorVersion; i++ {
tags = append(tags, fmt.Sprintf("go1.%d", i))
}
if extraTags := strings.Fields(c.Options.Tags); len(extraTags) != 0 {
tags = append(tags, extraTags...)
}
tags = append(tags, c.Options.Tags...)
return tags
}
@@ -442,13 +440,13 @@ func (c *Config) OpenOCDConfiguration() (args []string, err error) {
if openocdInterface == "" {
return nil, errors.New("OpenOCD programmer not set")
}
if !regexp.MustCompile("^[\\p{L}0-9_-]+$").MatchString(openocdInterface) {
if !regexp.MustCompile(`^[\p{L}0-9_-]+$`).MatchString(openocdInterface) {
return nil, fmt.Errorf("OpenOCD programmer has an invalid name: %#v", openocdInterface)
}
if c.Target.OpenOCDTarget == "" {
return nil, errors.New("OpenOCD chip not set")
}
if !regexp.MustCompile("^[\\p{L}0-9_-]+$").MatchString(c.Target.OpenOCDTarget) {
if !regexp.MustCompile(`^[\p{L}0-9_-]+$`).MatchString(c.Target.OpenOCDTarget) {
return nil, fmt.Errorf("OpenOCD target has an invalid name: %#v", c.Target.OpenOCDTarget)
}
if c.Target.OpenOCDTransport != "" && c.Target.OpenOCDTransport != "swd" {
+3 -1
View File
@@ -4,6 +4,7 @@ import (
"fmt"
"regexp"
"strings"
"time"
)
var (
@@ -29,6 +30,7 @@ type Options struct {
Scheduler string
Serial string
Work bool // -work flag to print temporary build directory
InterpTimeout time.Duration
PrintIR bool
DumpSSA bool
VerifyIR bool
@@ -38,7 +40,7 @@ type Options struct {
PrintSizes string
PrintAllocs *regexp.Regexp // regexp string
PrintStacks bool
Tags string
Tags []string
WasmAbi string
GlobalValues map[string]map[string]string // map[pkgpath]map[varname]value
TestConfig TestConfig
+12 -4
View File
@@ -88,8 +88,17 @@ func (spec *TargetSpec) overrideProperties(child *TargetSpec) {
if !src.IsNil() {
dst.Set(src)
}
case reflect.Slice: // for slices, append the field
case reflect.Slice: // for slices, append the field and check for duplicates
dst.Set(reflect.AppendSlice(dst, src))
for i := 0; i < dst.Len(); i++ {
v := dst.Index(i).String()
for j := i + 1; j < dst.Len(); j++ {
w := dst.Index(j).String()
if v == w {
panic("duplicate value '" + v + "' in field : " + field.Name)
}
}
}
default:
panic("unknown field type : " + kind.String())
}
@@ -193,11 +202,10 @@ func LoadTarget(options *Options) (*TargetSpec, error) {
// triples for historical reasons) have the form:
// arch-vendor-os-environment
target := llvmarch + "-unknown-" + llvmos
if options.GOARCH == "arm" {
target += "-gnueabihf"
}
if options.GOOS == "windows" {
target += "-gnu"
} else if options.GOARCH == "arm" {
target += "-gnueabihf"
}
return defaultTarget(options.GOOS, options.GOARCH, target)
}
+3 -2
View File
@@ -1,7 +1,8 @@
package compileopts
import (
"os"
"errors"
"io/fs"
"reflect"
"testing"
)
@@ -17,7 +18,7 @@ func TestLoadTarget(t *testing.T) {
t.Error("LoadTarget should have failed with non existing target")
}
if !os.IsNotExist(err) {
if !errors.Is(err, fs.ErrNotExist) {
t.Error("LoadTarget failed for wrong reason:", err)
}
}
+2 -43
View File
@@ -16,6 +16,8 @@ import "tinygo.org/x/go-llvm"
var stdlibAliases = map[string]string{
// crypto packages
"crypto/ed25519/internal/edwards25519/field.feMul": "crypto/ed25519/internal/edwards25519/field.feMulGeneric",
"crypto/ed25519/internal/edwards25519/field.feSquare": "crypto/ed25519/internal/edwards25519/field.feSquareGeneric",
"crypto/md5.block": "crypto/md5.blockGeneric",
"crypto/sha1.block": "crypto/sha1.blockGeneric",
"crypto/sha1.blockAMD64": "crypto/sha1.blockGeneric",
@@ -23,53 +25,10 @@ var stdlibAliases = map[string]string{
"crypto/sha512.blockAMD64": "crypto/sha512.blockGeneric",
// math package
"math.Asin": "math.asin",
"math.Asinh": "math.asinh",
"math.Acos": "math.acos",
"math.Acosh": "math.acosh",
"math.Atan": "math.atan",
"math.Atanh": "math.atanh",
"math.Atan2": "math.atan2",
"math.Cbrt": "math.cbrt",
"math.Ceil": "math.ceil",
"math.archCeil": "math.ceil",
"math.Cos": "math.cos",
"math.Cosh": "math.cosh",
"math.Erf": "math.erf",
"math.Erfc": "math.erfc",
"math.Exp": "math.exp",
"math.archExp": "math.exp",
"math.Expm1": "math.expm1",
"math.Exp2": "math.exp2",
"math.archExp2": "math.exp2",
"math.Floor": "math.floor",
"math.archFloor": "math.floor",
"math.Frexp": "math.frexp",
"math.Hypot": "math.hypot",
"math.archHypot": "math.hypot",
"math.Ldexp": "math.ldexp",
"math.Log": "math.log",
"math.archLog": "math.log",
"math.Log1p": "math.log1p",
"math.Log10": "math.log10",
"math.Log2": "math.log2",
"math.Max": "math.max",
"math.archMax": "math.max",
"math.Min": "math.min",
"math.archMin": "math.min",
"math.Mod": "math.mod",
"math.Modf": "math.modf",
"math.archModf": "math.modf",
"math.Pow": "math.pow",
"math.Remainder": "math.remainder",
"math.Sin": "math.sin",
"math.Sinh": "math.sinh",
"math.Sqrt": "math.sqrt",
"math.archSqrt": "math.sqrt",
"math.Tan": "math.tan",
"math.Tanh": "math.tanh",
"math.Trunc": "math.trunc",
"math.archTrunc": "math.trunc",
}
// createAlias implements the function (in the builder) as a call to the alias
+22 -23
View File
@@ -22,10 +22,6 @@ import (
"tinygo.org/x/go-llvm"
)
var typeParamUnderlyingType = func(t types.Type) types.Type {
return t
}
func init() {
llvm.InitializeAllTargets()
llvm.InitializeAllTargetMCs()
@@ -345,7 +341,6 @@ func (c *compilerContext) getLLVMType(goType types.Type) llvm.Type {
// makeLLVMType creates a LLVM type for a Go type. Don't call this, use
// getLLVMType instead.
func (c *compilerContext) makeLLVMType(goType types.Type) llvm.Type {
goType = typeParamUnderlyingType(goType)
switch typ := goType.(type) {
case *types.Array:
elemType := c.getLLVMType(typ.Elem())
@@ -420,6 +415,8 @@ func (c *compilerContext) makeLLVMType(goType types.Type) llvm.Type {
members[i] = c.getLLVMType(typ.Field(i).Type())
}
return c.ctx.StructType(members, false)
case *types.TypeParam:
return c.getLLVMType(typ.Underlying())
case *types.Tuple:
members := make([]llvm.Type, typ.Len())
for i := 0; i < typ.Len(); i++ {
@@ -455,7 +452,6 @@ func (c *compilerContext) getDIType(typ types.Type) llvm.Metadata {
// createDIType creates a new DWARF type. Don't call this function directly,
// call getDIType instead.
func (c *compilerContext) createDIType(typ types.Type) llvm.Metadata {
typ = typeParamUnderlyingType(typ)
llvmType := c.getLLVMType(typ)
sizeInBytes := c.targetData.TypeAllocSize(llvmType)
switch typ := typ.(type) {
@@ -619,6 +615,8 @@ func (c *compilerContext) createDIType(typ types.Type) llvm.Metadata {
})
temporaryMDNode.ReplaceAllUsesWith(md)
return md
case *types.TypeParam:
return c.getDIType(typ.Underlying())
default:
panic("unknown type while generating DWARF debug type: " + typ.String())
}
@@ -688,7 +686,7 @@ func (b *builder) getLocalVariable(variable *types.Var) llvm.Metadata {
Name: param.Name(),
File: b.getDIFile(pos.Filename),
Line: pos.Line,
Type: b.getDIType(variable.Type()),
Type: b.getDIType(param.Type()),
AlwaysPreserve: true,
ArgNo: i + 1,
})
@@ -792,6 +790,12 @@ func (c *compilerContext) createPackage(irbuilder llvm.Builder, pkg *ssa.Package
}
// Create the function definition.
b := newBuilder(c, irbuilder, member)
if _, ok := mathToLLVMMapping[member.RelString(nil)]; ok {
// The body of this function (if there is one) is ignored and
// replaced with a LLVM intrinsic call.
b.defineMathOp()
continue
}
if member.Blocks == nil {
// Try to define this as an intrinsic function.
b.defineIntrinsicFunction()
@@ -1026,7 +1030,7 @@ func (c *compilerContext) getEmbedFileString(file *loader.EmbedFile) llvm.Value
// parameters, create basic blocks, and set up debug information.
// This is separated out from createFunction() so that it is also usable to
// define compiler intrinsics like the atomic operations in sync/atomic.
func (b *builder) createFunctionStart() {
func (b *builder) createFunctionStart(intrinsic bool) {
if b.DumpSSA {
fmt.Printf("\nfunc %s:\n", b.fn)
}
@@ -1099,20 +1103,20 @@ func (b *builder) createFunctionStart() {
}
// Pre-create all basic blocks in the function.
for _, block := range b.fn.DomPreorder() {
llvmBlock := b.ctx.AddBasicBlock(b.llvmFn, block.Comment)
b.blockEntries[block] = llvmBlock
b.blockExits[block] = llvmBlock
}
var entryBlock llvm.BasicBlock
if len(b.fn.Blocks) != 0 {
// Normal functions have an entry block.
entryBlock = b.blockEntries[b.fn.Blocks[0]]
} else {
if intrinsic {
// This function isn't defined in Go SSA. It is probably a compiler
// intrinsic (like an atomic operation). Create the entry block
// manually.
entryBlock = b.ctx.AddBasicBlock(b.llvmFn, "entry")
} else {
for _, block := range b.fn.DomPreorder() {
llvmBlock := b.ctx.AddBasicBlock(b.llvmFn, block.Comment)
b.blockEntries[block] = llvmBlock
b.blockExits[block] = llvmBlock
}
// Normal functions have an entry block.
entryBlock = b.blockEntries[b.fn.Blocks[0]]
}
b.SetInsertPointAtEnd(entryBlock)
@@ -1194,7 +1198,7 @@ func (b *builder) createFunctionStart() {
// function must not yet be defined, otherwise this function will create a
// diagnostic.
func (b *builder) createFunction() {
b.createFunctionStart()
b.createFunctionStart(false)
// Fill blocks with instructions.
for _, block := range b.fn.DomPreorder() {
@@ -1656,11 +1660,6 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
// applied) function call. If it is anonymous, it may be a closure.
name := fn.RelString(nil)
switch {
case name == "math.Ceil" || name == "math.Floor" || name == "math.Sqrt" || name == "math.Trunc":
result, ok := b.createMathOp(instr)
if ok {
return result, nil
}
case name == "device.Asm" || name == "device/arm.Asm" || name == "device/arm64.Asm" || name == "device/avr.Asm" || name == "device/riscv.Asm":
return b.createInlineAsm(instr.Args)
case name == "device.AsmFull" || name == "device/arm.AsmFull" || name == "device/arm64.AsmFull" || name == "device/avr.AsmFull" || name == "device/riscv.AsmFull":
-18
View File
@@ -1,18 +0,0 @@
//go:build go1.18
// +build go1.18
package compiler
// Workaround for Go 1.17 support. Should be removed once we drop Go 1.17
// support.
import "go/types"
func init() {
typeParamUnderlyingType = func(t types.Type) types.Type {
if t, ok := t.(*types.TypeParam); ok {
return t.Underlying()
}
return t
}
}
+3 -28
View File
@@ -3,13 +3,12 @@ package compiler
import (
"flag"
"go/types"
"io/ioutil"
"os"
"strconv"
"strings"
"testing"
"github.com/tinygo-org/tinygo/compileopts"
"github.com/tinygo-org/tinygo/goenv"
"github.com/tinygo-org/tinygo/loader"
"tinygo.org/x/go-llvm"
)
@@ -28,18 +27,6 @@ type testCase struct {
func TestCompiler(t *testing.T) {
t.Parallel()
// Determine LLVM version.
llvmMajor, err := strconv.Atoi(strings.SplitN(llvm.Version, ".", 2)[0])
if err != nil {
t.Fatal("could not parse LLVM version:", llvm.Version)
}
// Determine Go minor version (e.g. 16 in go1.16.3).
_, goMinor, err := goenv.GetGorootVersion(goenv.Get("GOROOT"))
if err != nil {
t.Fatal("could not read Go version:", err)
}
// Determine which tests to run, depending on the Go and LLVM versions.
tests := []testCase{
{"basic.go", "", ""},
@@ -54,20 +41,8 @@ func TestCompiler(t *testing.T) {
{"goroutine.go", "wasm", "asyncify"},
{"goroutine.go", "cortex-m-qemu", "tasks"},
{"channel.go", "", ""},
{"intrinsics.go", "cortex-m-qemu", ""},
{"intrinsics.go", "wasm", ""},
{"gc.go", "", ""},
}
if llvmMajor >= 12 {
tests = append(tests, testCase{"intrinsics.go", "cortex-m-qemu", ""})
tests = append(tests, testCase{"intrinsics.go", "wasm", ""})
}
if goMinor >= 17 {
tests = append(tests, testCase{"go1.17.go", "", ""})
}
if goMinor >= 18 {
tests = append(tests, testCase{"generics.go", "", ""})
}
for _, tc := range tests {
name := tc.file
@@ -162,14 +137,14 @@ func TestCompiler(t *testing.T) {
// Update test if needed. Do not check the result.
if *flagUpdate {
err := ioutil.WriteFile(outPath, []byte(mod.String()), 0666)
err := os.WriteFile(outPath, []byte(mod.String()), 0666)
if err != nil {
t.Error("failed to write updated output file:", err)
}
return
}
expected, err := ioutil.ReadFile(outPath)
expected, err := os.ReadFile(outPath)
if err != nil {
t.Fatal("failed to read golden file:", err)
}
+7 -7
View File
@@ -120,16 +120,16 @@ func (b *builder) createGo(instr *ssa.Go) {
// createGoroutineStartWrapper creates a wrapper for the task-based
// implementation of goroutines. For example, to call a function like this:
//
// func add(x, y int) int { ... }
// func add(x, y int) int { ... }
//
// It creates a wrapper like this:
//
// func add$gowrapper(ptr *unsafe.Pointer) {
// args := (*struct{
// x, y int
// })(ptr)
// add(args.x, args.y)
// }
// func add$gowrapper(ptr *unsafe.Pointer) {
// args := (*struct{
// x, y int
// })(ptr)
// add(args.x, args.y)
// }
//
// This is useful because the task-based goroutine start implementation only
// allows a single (pointer) argument to the newly started goroutine. Also, it
+22 -22
View File
@@ -17,7 +17,7 @@ import (
// operands or return values. It is useful for trivial instructions, like wfi in
// ARM or sleep in AVR.
//
// func Asm(asm string)
// func Asm(asm string)
//
// The provided assembly must be a constant.
func (b *builder) createInlineAsm(args []ssa.Value) (llvm.Value, error) {
@@ -31,17 +31,17 @@ func (b *builder) createInlineAsm(args []ssa.Value) (llvm.Value, error) {
// This is a compiler builtin, which allows assembly to be called in a flexible
// way.
//
// func AsmFull(asm string, regs map[string]interface{}) uintptr
// func AsmFull(asm string, regs map[string]interface{}) uintptr
//
// The asm parameter must be a constant string. The regs parameter must be
// provided immediately. For example:
//
// arm.AsmFull(
// "str {value}, {result}",
// map[string]interface{}{
// "value": 1
// "result": &dest,
// })
// arm.AsmFull(
// "str {value}, {result}",
// map[string]interface{}{
// "value": 1
// "result": &dest,
// })
func (b *builder) createInlineAsmFull(instr *ssa.CallCommon) (llvm.Value, error) {
asmString := constant.StringVal(instr.Args[0].(*ssa.Const).Value)
registers := map[string]llvm.Value{}
@@ -132,11 +132,11 @@ func (b *builder) createInlineAsmFull(instr *ssa.CallCommon) (llvm.Value, error)
// This is a compiler builtin which emits an inline SVCall instruction. It can
// be one of:
//
// func SVCall0(num uintptr) uintptr
// func SVCall1(num uintptr, a1 interface{}) uintptr
// func SVCall2(num uintptr, a1, a2 interface{}) uintptr
// func SVCall3(num uintptr, a1, a2, a3 interface{}) uintptr
// func SVCall4(num uintptr, a1, a2, a3, a4 interface{}) uintptr
// func SVCall0(num uintptr) uintptr
// func SVCall1(num uintptr, a1 interface{}) uintptr
// func SVCall2(num uintptr, a1, a2 interface{}) uintptr
// func SVCall3(num uintptr, a1, a2, a3 interface{}) uintptr
// func SVCall4(num uintptr, a1, a2, a3, a4 interface{}) uintptr
//
// The num parameter must be a constant. All other parameters may be any scalar
// value supported by LLVM inline assembly.
@@ -169,11 +169,11 @@ func (b *builder) emitSVCall(args []ssa.Value) (llvm.Value, error) {
// This is a compiler builtin which emits an inline SVCall instruction. It can
// be one of:
//
// func SVCall0(num uintptr) uintptr
// func SVCall1(num uintptr, a1 interface{}) uintptr
// func SVCall2(num uintptr, a1, a2 interface{}) uintptr
// func SVCall3(num uintptr, a1, a2, a3 interface{}) uintptr
// func SVCall4(num uintptr, a1, a2, a3, a4 interface{}) uintptr
// func SVCall0(num uintptr) uintptr
// func SVCall1(num uintptr, a1 interface{}) uintptr
// func SVCall2(num uintptr, a1, a2 interface{}) uintptr
// func SVCall3(num uintptr, a1, a2, a3 interface{}) uintptr
// func SVCall4(num uintptr, a1, a2, a3, a4 interface{}) uintptr
//
// The num parameter must be a constant. All other parameters may be any scalar
// value supported by LLVM inline assembly.
@@ -206,10 +206,10 @@ func (b *builder) emitSV64Call(args []ssa.Value) (llvm.Value, error) {
// This is a compiler builtin which emits CSR instructions. It can be one of:
//
// func (csr CSR) Get() uintptr
// func (csr CSR) Set(uintptr)
// func (csr CSR) SetBits(uintptr) uintptr
// func (csr CSR) ClearBits(uintptr) uintptr
// func (csr CSR) Get() uintptr
// func (csr CSR) Set(uintptr)
// func (csr CSR) SetBits(uintptr) uintptr
// func (csr CSR) ClearBits(uintptr) uintptr
//
// The csr parameter (method receiver) must be a constant. Other parameter can
// be any value.
+4 -4
View File
@@ -550,8 +550,8 @@ func (c *compilerContext) getInterfaceInvokeWrapper(fn *ssa.Function, llvmFn llv
// internally to match interfaces and to call the correct method on an
// interface. Examples:
//
// String() string
// Read([]byte) (int, error)
// String() string
// Read([]byte) (int, error)
func methodSignature(method *types.Func) string {
return method.Name() + signature(method.Type().(*types.Signature))
}
@@ -559,8 +559,8 @@ func methodSignature(method *types.Func) string {
// Make a readable version of a function (pointer) signature.
// Examples:
//
// () string
// (string, int) (int, error)
// () string
// (string, int) (int, error)
func signature(sig *types.Signature) string {
s := ""
if sig.Params().Len() == 0 {
+30 -42
View File
@@ -7,7 +7,6 @@ import (
"strconv"
"strings"
"golang.org/x/tools/go/ssa"
"tinygo.org/x/go-llvm"
)
@@ -29,7 +28,7 @@ func (b *builder) defineIntrinsicFunction() {
case strings.HasPrefix(name, "runtime/volatile.Store"):
b.createVolatileStore()
case strings.HasPrefix(name, "sync/atomic.") && token.IsExported(b.fn.Name()):
b.createFunctionStart()
b.createFunctionStart(true)
returnValue := b.createAtomicOp(b.fn.Name())
if !returnValue.IsNil() {
b.CreateRet(returnValue)
@@ -44,7 +43,7 @@ func (b *builder) defineIntrinsicFunction() {
// specially by optimization passes possibly resulting in better generated code,
// and will otherwise be lowered to regular libc memcpy/memmove calls.
func (b *builder) createMemoryCopyImpl() {
b.createFunctionStart()
b.createFunctionStart(true)
fnName := "llvm." + b.fn.Name() + ".p0i8.p0i8.i" + strconv.Itoa(b.uintptrType.IntTypeWidth())
llvmFn := b.mod.NamedFunction(fnName)
if llvmFn.IsNil() {
@@ -64,7 +63,7 @@ func (b *builder) createMemoryCopyImpl() {
// memory, declaring the function if needed. These calls will be lowered to
// regular libc memset calls if they aren't optimized out in a different way.
func (b *builder) createMemoryZeroImpl() {
b.createFunctionStart()
b.createFunctionStart(true)
fnName := "llvm.memset.p0i8.i" + strconv.Itoa(b.uintptrType.IntTypeWidth())
llvmFn := b.mod.NamedFunction(fnName)
if llvmFn.IsNil() {
@@ -82,55 +81,44 @@ func (b *builder) createMemoryZeroImpl() {
}
var mathToLLVMMapping = map[string]string{
"math.Sqrt": "llvm.sqrt.f64",
"math.Floor": "llvm.floor.f64",
"math.Ceil": "llvm.ceil.f64",
"math.Exp": "llvm.exp.f64",
"math.Exp2": "llvm.exp2.f64",
"math.Floor": "llvm.floor.f64",
"math.Log": "llvm.log.f64",
"math.Sqrt": "llvm.sqrt.f64",
"math.Trunc": "llvm.trunc.f64",
}
// createMathOp tries to lower the given call as a LLVM math intrinsic, if
// possible. It returns the call result if possible, and a boolean whether it
// succeeded. If it doesn't succeed, the architecture doesn't support the given
// intrinsic.
func (b *builder) createMathOp(call *ssa.CallCommon) (llvm.Value, bool) {
// Check whether this intrinsic is supported on the given GOARCH.
// If it is unsupported, this can have two reasons:
//
// 1. LLVM can expand the intrinsic inline (using float instructions), but
// the result doesn't pass the tests of the math package.
// 2. LLVM cannot expand the intrinsic inline, will therefore lower it as a
// libm function call, but the libm function call also fails the math
// package tests.
//
// Whatever the implementation, it must pass the tests in the math package
// so unfortunately only the below intrinsic+architecture combinations are
// supported.
name := call.StaticCallee().RelString(nil)
switch name {
case "math.Ceil", "math.Floor", "math.Trunc":
if b.GOARCH != "wasm" && b.GOARCH != "arm64" {
return llvm.Value{}, false
}
case "math.Sqrt":
if b.GOARCH != "wasm" && b.GOARCH != "amd64" && b.GOARCH != "386" {
return llvm.Value{}, false
}
default:
return llvm.Value{}, false // only the above functions are supported.
// defineMathOp defines a math function body as a call to a LLVM intrinsic,
// instead of the regular Go implementation. This allows LLVM to reason about
// the math operation and (depending on the architecture) allows it to lower the
// operation to very fast floating point instructions. If this is not possible,
// LLVM will emit a call to a libm function that implements the same operation.
//
// One example of an optimization that LLVM can do is to convert
// float32(math.Sqrt(float64(v))) to a 32-bit floating point operation, which is
// beneficial on architectures where 64-bit floating point operations are (much)
// more expensive than 32-bit ones.
func (b *builder) defineMathOp() {
b.createFunctionStart(true)
llvmName := mathToLLVMMapping[b.fn.RelString(nil)]
if llvmName == "" {
panic("unreachable: unknown math operation") // sanity check
}
llvmFn := b.mod.NamedFunction(mathToLLVMMapping[name])
llvmFn := b.mod.NamedFunction(llvmName)
if llvmFn.IsNil() {
// The intrinsic doesn't exist yet, so declare it.
// At the moment, all supported intrinsics have the form "double
// foo(double %x)" so we can hardcode the signature here.
llvmType := llvm.FunctionType(b.ctx.DoubleType(), []llvm.Type{b.ctx.DoubleType()}, false)
llvmFn = llvm.AddFunction(b.mod, mathToLLVMMapping[name], llvmType)
llvmFn = llvm.AddFunction(b.mod, llvmName, llvmType)
}
// Create a call to the intrinsic.
args := make([]llvm.Value, len(call.Args))
for i, arg := range call.Args {
args[i] = b.getValue(arg)
args := make([]llvm.Value, len(b.fn.Params))
for i, param := range b.fn.Params {
args[i] = b.getValue(param)
}
return b.CreateCall(llvmFn, args, ""), true
result := b.CreateCall(llvmFn, args, "")
b.CreateRet(result)
}
+1 -1
View File
@@ -152,7 +152,7 @@ func (s *stdSizes) Sizeof(T types.Type) int64 {
return align(offsets[n-1]+s.Sizeof(fields[n-1].Type()), maxAlign)
case *types.Interface:
return s.PtrSize * 2
case *types.Pointer:
case *types.Pointer, *types.Chan, *types.Map:
return s.PtrSize
case *types.Signature:
// Func values in TinyGo are two words in size.
-41
View File
@@ -1,41 +0,0 @@
package main
// Test changes to the language introduced in Go 1.17.
// For details, see: https://tip.golang.org/doc/go1.17#language
// These tests should be merged into the regular slice tests once Go 1.17 is the
// minimun Go version for TinyGo.
import "unsafe"
func Add32(p unsafe.Pointer, len int) unsafe.Pointer {
return unsafe.Add(p, len)
}
func Add64(p unsafe.Pointer, len int64) unsafe.Pointer {
return unsafe.Add(p, len)
}
func SliceToArray(s []int) *[4]int {
return (*[4]int)(s)
}
func SliceToArrayConst() *[4]int {
s := make([]int, 6)
return (*[4]int)(s)
}
func SliceInt(ptr *int, len int) []int {
return unsafe.Slice(ptr, len)
}
func SliceUint16(ptr *byte, len uint16) []byte {
return unsafe.Slice(ptr, len)
}
func SliceUint64(ptr *int, len uint64) []int {
return unsafe.Slice(ptr, len)
}
func SliceInt64(ptr *int, len int64) []int {
return unsafe.Slice(ptr, len)
}
-161
View File
@@ -1,161 +0,0 @@
; ModuleID = 'go1.17.go'
source_filename = "go1.17.go"
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
target triple = "wasm32-unknown-wasi"
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0
; Function Attrs: nounwind
define hidden void @main.init(i8* %context) unnamed_addr #1 {
entry:
ret void
}
; Function Attrs: nounwind
define hidden i8* @main.Add32(i8* %p, i32 %len, i8* %context) unnamed_addr #1 {
entry:
%0 = getelementptr i8, i8* %p, i32 %len
call void @runtime.trackPointer(i8* %0, i8* undef) #2
ret i8* %0
}
; Function Attrs: nounwind
define hidden i8* @main.Add64(i8* %p, i64 %len, i8* %context) unnamed_addr #1 {
entry:
%0 = trunc i64 %len to i32
%1 = getelementptr i8, i8* %p, i32 %0
call void @runtime.trackPointer(i8* %1, i8* undef) #2
ret i8* %1
}
; Function Attrs: nounwind
define hidden [4 x i32]* @main.SliceToArray(i32* %s.data, i32 %s.len, i32 %s.cap, i8* %context) unnamed_addr #1 {
entry:
%0 = icmp ult i32 %s.len, 4
br i1 %0, label %slicetoarray.throw, label %slicetoarray.next
slicetoarray.next: ; preds = %entry
%1 = bitcast i32* %s.data to [4 x i32]*
ret [4 x i32]* %1
slicetoarray.throw: ; preds = %entry
call void @runtime.sliceToArrayPointerPanic(i8* undef) #2
unreachable
}
declare void @runtime.sliceToArrayPointerPanic(i8*) #0
; Function Attrs: nounwind
define hidden [4 x i32]* @main.SliceToArrayConst(i8* %context) unnamed_addr #1 {
entry:
%makeslice = call i8* @runtime.alloc(i32 24, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
call void @runtime.trackPointer(i8* nonnull %makeslice, i8* undef) #2
br i1 false, label %slicetoarray.throw, label %slicetoarray.next
slicetoarray.next: ; preds = %entry
%0 = bitcast i8* %makeslice to [4 x i32]*
ret [4 x i32]* %0
slicetoarray.throw: ; preds = %entry
unreachable
}
; Function Attrs: nounwind
define hidden { i32*, i32, i32 } @main.SliceInt(i32* dereferenceable_or_null(4) %ptr, i32 %len, i8* %context) unnamed_addr #1 {
entry:
%0 = icmp ugt i32 %len, 1073741823
%1 = icmp eq i32* %ptr, null
%2 = icmp ne i32 %len, 0
%3 = and i1 %1, %2
%4 = or i1 %3, %0
br i1 %4, label %unsafe.Slice.throw, label %unsafe.Slice.next
unsafe.Slice.next: ; preds = %entry
%5 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0
%6 = insertvalue { i32*, i32, i32 } %5, i32 %len, 1
%7 = insertvalue { i32*, i32, i32 } %6, i32 %len, 2
%8 = bitcast i32* %ptr to i8*
call void @runtime.trackPointer(i8* %8, i8* undef) #2
ret { i32*, i32, i32 } %7
unsafe.Slice.throw: ; preds = %entry
call void @runtime.unsafeSlicePanic(i8* undef) #2
unreachable
}
declare void @runtime.unsafeSlicePanic(i8*) #0
; Function Attrs: nounwind
define hidden { i8*, i32, i32 } @main.SliceUint16(i8* dereferenceable_or_null(1) %ptr, i16 %len, i8* %context) unnamed_addr #1 {
entry:
%0 = icmp eq i8* %ptr, null
%1 = icmp ne i16 %len, 0
%2 = and i1 %0, %1
br i1 %2, label %unsafe.Slice.throw, label %unsafe.Slice.next
unsafe.Slice.next: ; preds = %entry
%3 = zext i16 %len to i32
%4 = insertvalue { i8*, i32, i32 } undef, i8* %ptr, 0
%5 = insertvalue { i8*, i32, i32 } %4, i32 %3, 1
%6 = insertvalue { i8*, i32, i32 } %5, i32 %3, 2
call void @runtime.trackPointer(i8* %ptr, i8* undef) #2
ret { i8*, i32, i32 } %6
unsafe.Slice.throw: ; preds = %entry
call void @runtime.unsafeSlicePanic(i8* undef) #2
unreachable
}
; Function Attrs: nounwind
define hidden { i32*, i32, i32 } @main.SliceUint64(i32* dereferenceable_or_null(4) %ptr, i64 %len, i8* %context) unnamed_addr #1 {
entry:
%0 = icmp ugt i64 %len, 1073741823
%1 = icmp eq i32* %ptr, null
%2 = icmp ne i64 %len, 0
%3 = and i1 %1, %2
%4 = or i1 %3, %0
br i1 %4, label %unsafe.Slice.throw, label %unsafe.Slice.next
unsafe.Slice.next: ; preds = %entry
%5 = trunc i64 %len to i32
%6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0
%7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1
%8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2
%9 = bitcast i32* %ptr to i8*
call void @runtime.trackPointer(i8* %9, i8* undef) #2
ret { i32*, i32, i32 } %8
unsafe.Slice.throw: ; preds = %entry
call void @runtime.unsafeSlicePanic(i8* undef) #2
unreachable
}
; Function Attrs: nounwind
define hidden { i32*, i32, i32 } @main.SliceInt64(i32* dereferenceable_or_null(4) %ptr, i64 %len, i8* %context) unnamed_addr #1 {
entry:
%0 = icmp ugt i64 %len, 1073741823
%1 = icmp eq i32* %ptr, null
%2 = icmp ne i64 %len, 0
%3 = and i1 %1, %2
%4 = or i1 %3, %0
br i1 %4, label %unsafe.Slice.throw, label %unsafe.Slice.next
unsafe.Slice.next: ; preds = %entry
%5 = trunc i64 %len to i32
%6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0
%7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1
%8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2
%9 = bitcast i32* %ptr to i8*
call void @runtime.trackPointer(i8* %9, i8* undef) #2
ret { i32*, i32, i32 } %8
unsafe.Slice.throw: ; preds = %entry
call void @runtime.unsafeSlicePanic(i8* undef) #2
unreachable
}
attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
attributes #2 = { nounwind }
-34
View File
@@ -1,34 +0,0 @@
; ModuleID = 'intrinsics.go'
source_filename = "intrinsics.go"
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
target triple = "thumbv7m-unknown-unknown-eabi"
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
; Function Attrs: nounwind
define hidden void @main.init(i8* %context) unnamed_addr #1 {
entry:
ret void
}
; Function Attrs: nounwind
define hidden double @main.mySqrt(double %x, i8* %context) unnamed_addr #1 {
entry:
%0 = call double @math.Sqrt(double %x, i8* undef) #2
ret double %0
}
declare double @math.Sqrt(double, i8*) #0
; Function Attrs: nounwind
define hidden double @main.myTrunc(double %x, i8* %context) unnamed_addr #1 {
entry:
%0 = call double @math.Trunc(double %x, i8* undef) #2
ret double %0
}
declare double @math.Trunc(double, i8*) #0
attributes #0 = { "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" }
attributes #1 = { nounwind "target-features"="+armv7-m,+hwdiv,+soft-float,+strict-align,+thumb-mode,-aes,-bf16,-cdecp0,-cdecp1,-cdecp2,-cdecp3,-cdecp4,-cdecp5,-cdecp6,-cdecp7,-crc,-crypto,-d32,-dotprod,-dsp,-fp-armv8,-fp-armv8d16,-fp-armv8d16sp,-fp-armv8sp,-fp16,-fp16fml,-fp64,-fpregs,-fullfp16,-hwdiv-arm,-i8mm,-lob,-mve,-mve.fp,-neon,-pacbti,-ras,-sb,-sha2,-vfp2,-vfp2sp,-vfp3,-vfp3d16,-vfp3d16sp,-vfp3sp,-vfp4,-vfp4d16,-vfp4d16sp,-vfp4sp" }
attributes #2 = { nounwind }
-38
View File
@@ -1,38 +0,0 @@
; ModuleID = 'intrinsics.go'
source_filename = "intrinsics.go"
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
target triple = "wasm32-unknown-wasi"
declare noalias nonnull i8* @runtime.alloc(i32, i8*, i8*) #0
declare void @runtime.trackPointer(i8* nocapture readonly, i8*) #0
; Function Attrs: nounwind
define hidden void @main.init(i8* %context) unnamed_addr #1 {
entry:
ret void
}
; Function Attrs: nounwind
define hidden double @main.mySqrt(double %x, i8* %context) unnamed_addr #1 {
entry:
%0 = call double @llvm.sqrt.f64(double %x)
ret double %0
}
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
declare double @llvm.sqrt.f64(double) #2
; Function Attrs: nounwind
define hidden double @main.myTrunc(double %x, i8* %context) unnamed_addr #1 {
entry:
%0 = call double @llvm.trunc.f64(double %x)
ret double %0
}
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
declare double @llvm.trunc.f64(double) #2
attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
attributes #2 = { nofree nosync nounwind readnone speculatable willreturn }
-14
View File
@@ -1,14 +0,0 @@
package main
// Test how intrinsics are lowered: either as regular calls to the math
// functions or as LLVM builtins (such as llvm.sqrt.f64).
import "math"
func mySqrt(x float64) float64 {
return math.Sqrt(x)
}
func myTrunc(x float64) float64 {
return math.Trunc(x)
}
+10
View File
@@ -3,44 +3,53 @@ package main
import _ "unsafe"
// Creates an external global with name extern_global.
//
//go:extern extern_global
var externGlobal [0]byte
// Creates a
//
//go:align 32
var alignedGlobal [4]uint32
// Test conflicting pragmas (the last one counts).
//
//go:align 64
//go:align 16
var alignedGlobal16 [4]uint32
// Test exported functions.
//
//export extern_func
func externFunc() {
}
// Define a function in a different package using go:linkname.
//
//go:linkname withLinkageName1 somepkg.someFunction1
func withLinkageName1() {
}
// Import a function from a different package using go:linkname.
//
//go:linkname withLinkageName2 somepkg.someFunction2
func withLinkageName2()
// Function has an 'inline hint', similar to the inline keyword in C.
//
//go:inline
func inlineFunc() {
}
// Function should never be inlined, equivalent to GCC
// __attribute__((noinline)).
//
//go:noinline
func noinlineFunc() {
}
// This function should have the specified section.
//
//go:section .special_function_section
func functionInSection() {
}
@@ -51,6 +60,7 @@ func exportedFunctionInSection() {
}
// This function should not: it's only a declaration and not a definition.
//
//go:section .special_function_section
func undefinedFunctionNotInSection()
+35
View File
@@ -1,5 +1,7 @@
package main
import "unsafe"
func sliceLen(ints []int) int {
return len(ints)
}
@@ -41,3 +43,36 @@ func makeArraySlice(len int) [][3]byte {
func makeInt32Slice(len int) []int32 {
return make([]int32, len)
}
func Add32(p unsafe.Pointer, len int) unsafe.Pointer {
return unsafe.Add(p, len)
}
func Add64(p unsafe.Pointer, len int64) unsafe.Pointer {
return unsafe.Add(p, len)
}
func SliceToArray(s []int) *[4]int {
return (*[4]int)(s)
}
func SliceToArrayConst() *[4]int {
s := make([]int, 6)
return (*[4]int)(s)
}
func SliceInt(ptr *int, len int) []int {
return unsafe.Slice(ptr, len)
}
func SliceUint16(ptr *byte, len uint16) []byte {
return unsafe.Slice(ptr, len)
}
func SliceUint64(ptr *int, len uint64) []int {
return unsafe.Slice(ptr, len)
}
func SliceInt64(ptr *int, len int64) []int {
return unsafe.Slice(ptr, len)
}
+143
View File
@@ -183,6 +183,149 @@ slice.throw: ; preds = %entry
unreachable
}
; Function Attrs: nounwind
define hidden i8* @main.Add32(i8* %p, i32 %len, i8* %context) unnamed_addr #1 {
entry:
%0 = getelementptr i8, i8* %p, i32 %len
call void @runtime.trackPointer(i8* %0, i8* undef) #2
ret i8* %0
}
; Function Attrs: nounwind
define hidden i8* @main.Add64(i8* %p, i64 %len, i8* %context) unnamed_addr #1 {
entry:
%0 = trunc i64 %len to i32
%1 = getelementptr i8, i8* %p, i32 %0
call void @runtime.trackPointer(i8* %1, i8* undef) #2
ret i8* %1
}
; Function Attrs: nounwind
define hidden [4 x i32]* @main.SliceToArray(i32* %s.data, i32 %s.len, i32 %s.cap, i8* %context) unnamed_addr #1 {
entry:
%0 = icmp ult i32 %s.len, 4
br i1 %0, label %slicetoarray.throw, label %slicetoarray.next
slicetoarray.next: ; preds = %entry
%1 = bitcast i32* %s.data to [4 x i32]*
ret [4 x i32]* %1
slicetoarray.throw: ; preds = %entry
call void @runtime.sliceToArrayPointerPanic(i8* undef) #2
unreachable
}
declare void @runtime.sliceToArrayPointerPanic(i8*) #0
; Function Attrs: nounwind
define hidden [4 x i32]* @main.SliceToArrayConst(i8* %context) unnamed_addr #1 {
entry:
%makeslice = call i8* @runtime.alloc(i32 24, i8* nonnull inttoptr (i32 3 to i8*), i8* undef) #2
call void @runtime.trackPointer(i8* nonnull %makeslice, i8* undef) #2
br i1 false, label %slicetoarray.throw, label %slicetoarray.next
slicetoarray.next: ; preds = %entry
%0 = bitcast i8* %makeslice to [4 x i32]*
ret [4 x i32]* %0
slicetoarray.throw: ; preds = %entry
unreachable
}
; Function Attrs: nounwind
define hidden { i32*, i32, i32 } @main.SliceInt(i32* dereferenceable_or_null(4) %ptr, i32 %len, i8* %context) unnamed_addr #1 {
entry:
%0 = icmp ugt i32 %len, 1073741823
%1 = icmp eq i32* %ptr, null
%2 = icmp ne i32 %len, 0
%3 = and i1 %1, %2
%4 = or i1 %3, %0
br i1 %4, label %unsafe.Slice.throw, label %unsafe.Slice.next
unsafe.Slice.next: ; preds = %entry
%5 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0
%6 = insertvalue { i32*, i32, i32 } %5, i32 %len, 1
%7 = insertvalue { i32*, i32, i32 } %6, i32 %len, 2
%8 = bitcast i32* %ptr to i8*
call void @runtime.trackPointer(i8* %8, i8* undef) #2
ret { i32*, i32, i32 } %7
unsafe.Slice.throw: ; preds = %entry
call void @runtime.unsafeSlicePanic(i8* undef) #2
unreachable
}
declare void @runtime.unsafeSlicePanic(i8*) #0
; Function Attrs: nounwind
define hidden { i8*, i32, i32 } @main.SliceUint16(i8* dereferenceable_or_null(1) %ptr, i16 %len, i8* %context) unnamed_addr #1 {
entry:
%0 = icmp eq i8* %ptr, null
%1 = icmp ne i16 %len, 0
%2 = and i1 %0, %1
br i1 %2, label %unsafe.Slice.throw, label %unsafe.Slice.next
unsafe.Slice.next: ; preds = %entry
%3 = zext i16 %len to i32
%4 = insertvalue { i8*, i32, i32 } undef, i8* %ptr, 0
%5 = insertvalue { i8*, i32, i32 } %4, i32 %3, 1
%6 = insertvalue { i8*, i32, i32 } %5, i32 %3, 2
call void @runtime.trackPointer(i8* %ptr, i8* undef) #2
ret { i8*, i32, i32 } %6
unsafe.Slice.throw: ; preds = %entry
call void @runtime.unsafeSlicePanic(i8* undef) #2
unreachable
}
; Function Attrs: nounwind
define hidden { i32*, i32, i32 } @main.SliceUint64(i32* dereferenceable_or_null(4) %ptr, i64 %len, i8* %context) unnamed_addr #1 {
entry:
%0 = icmp ugt i64 %len, 1073741823
%1 = icmp eq i32* %ptr, null
%2 = icmp ne i64 %len, 0
%3 = and i1 %1, %2
%4 = or i1 %3, %0
br i1 %4, label %unsafe.Slice.throw, label %unsafe.Slice.next
unsafe.Slice.next: ; preds = %entry
%5 = trunc i64 %len to i32
%6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0
%7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1
%8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2
%9 = bitcast i32* %ptr to i8*
call void @runtime.trackPointer(i8* %9, i8* undef) #2
ret { i32*, i32, i32 } %8
unsafe.Slice.throw: ; preds = %entry
call void @runtime.unsafeSlicePanic(i8* undef) #2
unreachable
}
; Function Attrs: nounwind
define hidden { i32*, i32, i32 } @main.SliceInt64(i32* dereferenceable_or_null(4) %ptr, i64 %len, i8* %context) unnamed_addr #1 {
entry:
%0 = icmp ugt i64 %len, 1073741823
%1 = icmp eq i32* %ptr, null
%2 = icmp ne i64 %len, 0
%3 = and i1 %1, %2
%4 = or i1 %3, %0
br i1 %4, label %unsafe.Slice.throw, label %unsafe.Slice.next
unsafe.Slice.next: ; preds = %entry
%5 = trunc i64 %len to i32
%6 = insertvalue { i32*, i32, i32 } undef, i32* %ptr, 0
%7 = insertvalue { i32*, i32, i32 } %6, i32 %5, 1
%8 = insertvalue { i32*, i32, i32 } %7, i32 %5, 2
%9 = bitcast i32* %ptr to i8*
call void @runtime.trackPointer(i8* %9, i8* undef) #2
ret { i32*, i32, i32 } %8
unsafe.Slice.throw: ; preds = %entry
call void @runtime.unsafeSlicePanic(i8* undef) #2
unreachable
}
attributes #0 = { "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
attributes #1 = { nounwind "target-features"="+bulk-memory,+nontrapping-fptoint,+sign-ext" }
attributes #2 = { nounwind }
+2 -2
View File
@@ -6,7 +6,7 @@ package compiler
// createVolatileLoad is the implementation of the intrinsic function
// runtime/volatile.LoadT().
func (b *builder) createVolatileLoad() {
b.createFunctionStart()
b.createFunctionStart(true)
addr := b.getValue(b.fn.Params[0])
b.createNilCheck(b.fn.Params[0], addr, "deref")
val := b.CreateLoad(addr, "")
@@ -17,7 +17,7 @@ func (b *builder) createVolatileLoad() {
// createVolatileStore is the implementation of the intrinsic function
// runtime/volatile.StoreT().
func (b *builder) createVolatileStore() {
b.createFunctionStart()
b.createFunctionStart(true)
addr := b.getValue(b.fn.Params[0])
val := b.getValue(b.fn.Params[1])
b.createNilCheck(b.fn.Params[0], addr, "deref")
+5 -2
View File
@@ -8,6 +8,7 @@ import (
"sync"
"testing"
"golang.org/x/tools/go/buildutil"
yaml "gopkg.in/yaml.v2"
)
@@ -111,9 +112,11 @@ func TestCorpus(t *testing.T) {
opts := optionsFromTarget(target, sema)
opts.Directory = dir
opts.Tags = repo.Tags
var tags buildutil.TagsFlag
tags.Set(repo.Tags)
opts.Tags = []string(tags)
passed, err := Test(path, out, out, &opts, false, testing.Verbose(), false, "", "", "", "")
passed, err := Test(path, out, out, &opts, false, testing.Verbose(), false, "", "", "", false, "")
if err != nil {
t.Errorf("test error: %v", err)
}
+16 -4
View File
@@ -1,6 +1,6 @@
module github.com/tinygo-org/tinygo
go 1.16
go 1.18
require (
github.com/aykevl/go-wasm v0.0.2-0.20220616010729-4a0a888aebdc
@@ -11,9 +11,21 @@ require (
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892
github.com/mattn/go-colorable v0.1.8
go.bug.st/serial v1.1.3
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9
go.bug.st/serial v1.3.5
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261
golang.org/x/tools v0.1.11
gopkg.in/yaml.v2 v2.4.0
tinygo.org/x/go-llvm v0.0.0-20220626113704-45f1e2dbf887
tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7
)
require (
github.com/chromedp/sysutil v1.0.0 // indirect
github.com/creack/goselect v0.1.2 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
)
+6 -23
View File
@@ -40,44 +40,27 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.bug.st/serial v1.1.3 h1:YEBxJa9pKS9Wdg46B/jiaKbvvbUrjhZZZITfJHEJhaE=
go.bug.st/serial v1.1.3/go.mod h1:8TT7u/SwwNIpJ8QaG4s+HTjFt9ReXs2cdOU7ZEk50Dk=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
go.bug.st/serial v1.3.5 h1:k50SqGZCnHZ2MiBQgzccXWG+kd/XpOs1jUljpDDKzaE=
go.bug.st/serial v1.3.5/go.mod h1:z8CesKorE90Qr/oRSJiEuvzYRKol9r/anJZEb5kt304=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY=
golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
tinygo.org/x/go-llvm v0.0.0-20220626113704-45f1e2dbf887 h1:k+Y1DU/WoBDkTkRJGF149yk3S2K2VhNglN435DXDS5s=
tinygo.org/x/go-llvm v0.0.0-20220626113704-45f1e2dbf887/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7 h1:nSLR52mUw7DPQQVA3ZJFH63zjU4ME84fKiin6mdnYWc=
tinygo.org/x/go-llvm v0.0.0-20220802112859-5bb0b77907a7/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
+9 -4
View File
@@ -6,6 +6,7 @@ import (
"bytes"
"errors"
"fmt"
"io/fs"
"os"
"os/exec"
"os/user"
@@ -41,10 +42,14 @@ var TINYGOROOT string
func Get(name string) string {
switch name {
case "GOOS":
if dir := os.Getenv("GOOS"); dir != "" {
return dir
goos := os.Getenv("GOOS")
if goos == "" {
goos = runtime.GOOS
}
return runtime.GOOS
if goos == "android" {
goos = "linux"
}
return goos
case "GOARCH":
if dir := os.Getenv("GOARCH"); dir != "" {
return dir
@@ -122,7 +127,7 @@ func findWasmOpt() string {
}
_, err := os.Stat(path)
if err != nil && os.IsNotExist(err) {
if err != nil && errors.Is(err, fs.ErrNotExist) {
continue
}
+4 -4
View File
@@ -4,7 +4,7 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"strings"
@@ -12,7 +12,7 @@ import (
// Version of TinyGo.
// Update this value before release of new version of software.
const Version = "0.25.0"
const Version = "0.26.0-dev"
var (
// This variable is set at build time using -ldflags parameters.
@@ -54,10 +54,10 @@ func GetGorootVersion(goroot string) (major, minor int, err error) {
// toolchain for the given GOROOT path. It is usually of the form `go1.x.y` but
// can have some variations (for beta releases, for example).
func GorootVersionString(goroot string) (string, error) {
if data, err := ioutil.ReadFile(filepath.Join(goroot, "VERSION")); err == nil {
if data, err := os.ReadFile(filepath.Join(goroot, "VERSION")); err == nil {
return string(data), nil
} else if data, err := ioutil.ReadFile(filepath.Join(
} else if data, err := os.ReadFile(filepath.Join(
goroot, "src", "internal", "buildcfg", "zbootstrap.go")); err == nil {
r := regexp.MustCompile("const version = `(.*)`")
+7 -5
View File
@@ -30,10 +30,11 @@ type runner struct {
objects []object // slice of objects in memory
globals map[llvm.Value]int // map from global to index in objects slice
start time.Time
timeout time.Duration
callsExecuted uint64
}
func newRunner(mod llvm.Module, debug bool) *runner {
func newRunner(mod llvm.Module, timeout time.Duration, debug bool) *runner {
r := runner{
mod: mod,
targetData: llvm.NewTargetData(mod.DataLayout()),
@@ -42,6 +43,7 @@ func newRunner(mod llvm.Module, debug bool) *runner {
objects: []object{{}},
globals: make(map[llvm.Value]int),
start: time.Now(),
timeout: timeout,
}
r.pointerSize = uint32(r.targetData.PointerSize())
r.i8ptrType = llvm.PointerType(mod.Context().Int8Type(), 0)
@@ -58,8 +60,8 @@ func (r *runner) dispose() {
// Run evaluates runtime.initAll function as much as possible at compile time.
// Set debug to true if it should print output while running.
func Run(mod llvm.Module, debug bool) error {
r := newRunner(mod, debug)
func Run(mod llvm.Module, timeout time.Duration, debug bool) error {
r := newRunner(mod, timeout, debug)
defer r.dispose()
initAll := mod.NamedFunction("runtime.initAll")
@@ -199,10 +201,10 @@ func Run(mod llvm.Module, debug bool) error {
// RunFunc evaluates a single package initializer at compile time.
// Set debug to true if it should print output while running.
func RunFunc(fn llvm.Value, debug bool) error {
func RunFunc(fn llvm.Value, timeout time.Duration, debug bool) error {
// Create and initialize *runner object.
mod := fn.GlobalParent()
r := newRunner(mod, debug)
r := newRunner(mod, timeout, debug)
defer r.dispose()
initName := fn.Name()
if !strings.HasSuffix(initName, ".init") {
+3 -3
View File
@@ -1,11 +1,11 @@
package interp
import (
"io/ioutil"
"os"
"strconv"
"strings"
"testing"
"time"
"tinygo.org/x/go-llvm"
)
@@ -53,7 +53,7 @@ func runTest(t *testing.T, pathPrefix string) {
defer mod.Dispose()
// Perform the transform.
err = Run(mod, false)
err = Run(mod, 10*time.Minute, false)
if err != nil {
if err, match := err.(*Error); match {
println(err.Error())
@@ -87,7 +87,7 @@ func runTest(t *testing.T, pathPrefix string) {
pm.Run(mod)
// Read the expected output IR.
out, err := ioutil.ReadFile(pathPrefix + ".out.ll")
out, err := os.ReadFile(pathPrefix + ".out.ll")
if err != nil {
t.Fatalf("could not read output file %s: %v", pathPrefix+".out.ll", err)
}
+3 -6
View File
@@ -17,8 +17,6 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
locals := make([]value, len(fn.locals))
r.callsExecuted++
t0 := time.Since(r.start)
// Parameters are considered a kind of local values.
for i, param := range params {
locals[i] = param
@@ -143,11 +141,10 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
}
switch inst.opcode {
case llvm.Ret:
const maxInterpSeconds = 180
if t0 > maxInterpSeconds*time.Second {
// Running for more than maxInterpSeconds seconds. This should never happen, but does.
if time.Since(r.start) > r.timeout {
// Running for more than the allowed timeout; This shouldn't happen, but it does.
// See github.com/tinygo-org/tinygo/issues/2124
return nil, mem, r.errorAt(fn.blocks[0].instructions[0], fmt.Errorf("interp: running for more than %d seconds, timing out (executed calls: %d)", maxInterpSeconds, r.callsExecuted))
return nil, mem, r.errorAt(fn.blocks[0].instructions[0], fmt.Errorf("interp: running for more than %s, timing out (executed calls: %d)", r.timeout, r.callsExecuted))
}
if len(operands) != 0 {
+13 -6
View File
@@ -17,6 +17,7 @@ import (
"encoding/json"
"errors"
"io"
"io/fs"
"io/ioutil"
"os"
"os/exec"
@@ -45,7 +46,7 @@ func GetCachedGoroot(config *compileopts.Config) (string, error) {
}
// Find the overrides needed for the goroot.
overrides := pathsToOverride(needsSyscallPackage(config.BuildTags()))
overrides := pathsToOverride(config.GoMinorVersion, needsSyscallPackage(config.BuildTags()))
// Resolve the merge links within the goroot.
merge, err := listGorootMergeLinks(goroot, tinygoroot, overrides)
@@ -83,7 +84,7 @@ func GetCachedGoroot(config *compileopts.Config) (string, error) {
}
// Create a temporary directory to construct the goroot within.
tmpgoroot, err := ioutil.TempDir(goenv.Get("GOCACHE"), cachedGorootName+".tmp")
tmpgoroot, err := os.MkdirTemp(goenv.Get("GOCACHE"), cachedGorootName+".tmp")
if err != nil {
return "", err
}
@@ -122,13 +123,13 @@ func GetCachedGoroot(config *compileopts.Config) (string, error) {
// Rename the new merged gorooot into place.
err = os.Rename(tmpgoroot, cachedgoroot)
if err != nil {
if os.IsExist(err) {
if errors.Is(err, fs.ErrExist) {
// Another invocation of TinyGo also seems to have created a GOROOT.
// Use that one instead. Our new GOROOT will be automatically
// deleted by the defer above.
return cachedgoroot, nil
}
if runtime.GOOS == "windows" && os.IsPermission(err) {
if runtime.GOOS == "windows" && errors.Is(err, fs.ErrPermission) {
// On Windows, a rename with a destination directory that already
// exists does not result in an IsExist error, but rather in an
// access denied error. To be sure, check for this case by checking
@@ -222,7 +223,7 @@ func needsSyscallPackage(buildTags []string) bool {
// The boolean indicates whether to merge the subdirs. True means merge, false
// means use the TinyGo version.
func pathsToOverride(needsSyscallPackage bool) map[string]bool {
func pathsToOverride(goMinor int, needsSyscallPackage bool) map[string]bool {
paths := map[string]bool{
"": true,
"crypto/": true,
@@ -234,7 +235,6 @@ func pathsToOverride(needsSyscallPackage bool) map[string]bool {
"internal/bytealg/": false,
"internal/reflectlite/": false,
"internal/task/": false,
"internal/itoa/": false, // TODO: Remove when we drop support for go 1.16
"machine/": false,
"net/": true,
"os/": true,
@@ -243,6 +243,13 @@ func pathsToOverride(needsSyscallPackage bool) map[string]bool {
"sync/": true,
"testing/": true,
}
if goMinor >= 19 {
paths["crypto/internal/"] = true
paths["crypto/internal/boring/"] = true
paths["crypto/internal/boring/sig/"] = false
}
if needsSyscallPackage {
paths["syscall/"] = true // include syscall/js
}
+3 -8
View File
@@ -13,7 +13,6 @@ import (
"go/token"
"go/types"
"io"
"io/ioutil"
"os"
"os/exec"
"path"
@@ -28,8 +27,6 @@ import (
"github.com/tinygo-org/tinygo/goenv"
)
var addInstances func(*types.Info)
// Program holds all packages and some metadata about the program as a whole.
type Program struct {
config *compileopts.Config
@@ -159,6 +156,7 @@ func Load(config *compileopts.Config, inputPkg string, clangHeaders string, type
EmbedGlobals: make(map[string][]*EmbedFile),
info: types.Info{
Types: make(map[ast.Expr]types.TypeAndValue),
Instances: make(map[*ast.Ident]types.Instance),
Defs: make(map[*ast.Ident]types.Object),
Uses: make(map[*ast.Ident]types.Object),
Implicits: make(map[ast.Node]types.Object),
@@ -166,9 +164,6 @@ func Load(config *compileopts.Config, inputPkg string, clangHeaders string, type
Selections: make(map[*ast.SelectorExpr]*types.Selection),
},
}
if addInstances != nil {
addInstances(&pkg.info)
}
err := decoder.Decode(&pkg.PackageJSON)
if err != nil {
if err == io.EOF {
@@ -269,7 +264,7 @@ func (p *Program) getOriginalPath(path string) string {
originalPath = realgorootPath
}
maybeInTinyGoRoot := false
for prefix := range pathsToOverride(needsSyscallPackage(p.config.BuildTags())) {
for prefix := range pathsToOverride(p.config.GoMinorVersion, needsSyscallPackage(p.config.BuildTags())) {
if runtime.GOOS == "windows" {
prefix = strings.ReplaceAll(prefix, "/", "\\")
}
@@ -335,7 +330,7 @@ func (p *Package) OriginalDir() string {
// parseFile is a wrapper around parser.ParseFile.
func (p *Package) parseFile(path string, mode parser.Mode) (*ast.File, error) {
originalPath := p.program.getOriginalPath(path)
data, err := ioutil.ReadFile(path)
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
-18
View File
@@ -1,18 +0,0 @@
//go:build go1.18
// +build go1.18
package loader
// Workaround for Go 1.17 support. Should be removed once we drop Go 1.17
// support.
import (
"go/ast"
"go/types"
)
func init() {
addInstances = func(info *types.Info) {
info.Instances = make(map[*ast.Ident]types.Instance)
}
}
+16 -15
View File
@@ -32,6 +32,7 @@ import (
"github.com/tinygo-org/tinygo/goenv"
"github.com/tinygo-org/tinygo/interp"
"github.com/tinygo-org/tinygo/loader"
"golang.org/x/tools/go/buildutil"
"tinygo.org/x/go-llvm"
"go.bug.st/serial"
@@ -194,7 +195,7 @@ func Build(pkgName, outpath string, options *compileopts.Options) error {
// Test runs the tests in the given package. Returns whether the test passed and
// possibly an error if the test failed to run.
func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options, testCompileOnly, testVerbose, testShort bool, testRunRegexp string, testBenchRegexp string, testBenchTime string, outpath string) (bool, error) {
func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options, testCompileOnly, testVerbose, testShort bool, testRunRegexp string, testBenchRegexp string, testBenchTime string, testBenchMem bool, outpath string) (bool, error) {
options.TestConfig.CompileTestBinary = true
config, err := builder.NewConfig(options)
if err != nil {
@@ -218,6 +219,9 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
if testBenchTime != "" {
flags = append(flags, "-test.benchtime="+testBenchTime)
}
if testBenchMem {
flags = append(flags, "-test.benchmem")
}
passed := false
err = buildAndRun(pkgName, config, os.Stdout, flags, nil, 0, func(cmd *exec.Cmd, result builder.BuildResult) error {
@@ -250,7 +254,7 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
}
// create a new temp directory just for this run, announce it to os.TempDir() via TMPDIR
tmpdir, err := ioutil.TempDir("", "tinygotmp")
tmpdir, err := os.MkdirTemp("", "tinygotmp")
if err != nil {
return fmt.Errorf("failed to create temporary directory: %w", err)
}
@@ -974,8 +978,7 @@ func getDefaultPort(portFlag string, usbInterfaces []string) (port string, err e
preferredPortIDs = append(preferredPortIDs, [2]uint16{uint16(vid), uint16(pid)})
}
var primaryPorts []string // ports picked from preferred USB VID/PID
var secondaryPorts []string // other ports (as a fallback)
var primaryPorts []string // ports picked from preferred USB VID/PID
for _, p := range portsList {
if !p.IsUSB {
continue
@@ -997,8 +1000,6 @@ func getDefaultPort(portFlag string, usbInterfaces []string) (port string, err e
continue
}
}
secondaryPorts = append(secondaryPorts, p.Name)
}
if len(primaryPorts) == 1 {
// There is exactly one match in the set of preferred ports. Use
@@ -1010,10 +1011,6 @@ func getDefaultPort(portFlag string, usbInterfaces []string) (port string, err e
// one device of the same type are connected (e.g. two Arduino
// Unos).
ports = primaryPorts
} else {
// No preferred ports found. Fall back to other serial ports
// available in the system.
ports = secondaryPorts
}
if len(ports) == 0 {
@@ -1294,10 +1291,12 @@ func main() {
scheduler := flag.String("scheduler", "", "which scheduler to use (none, tasks, asyncify)")
serial := flag.String("serial", "", "which serial output to use (none, uart, usb)")
work := flag.Bool("work", false, "print the name of the temporary build directory and do not delete this directory on exit")
interpTimeout := flag.Duration("interp-timeout", 180*time.Second, "interp optimization pass timeout")
printIR := flag.Bool("printir", false, "print LLVM IR")
dumpSSA := flag.Bool("dumpssa", false, "dump internal Go SSA")
verifyIR := flag.Bool("verifyir", false, "run extra verification steps on LLVM IR")
tags := flag.String("tags", "", "a space-separated list of extra build tags")
var tags buildutil.TagsFlag
flag.Var(&tags, "tags", "a space-separated list of extra build tags")
target := flag.String("target", "", "chip/board name or JSON target specification file")
printSize := flag.String("size", "", "print sizes (none, short, full)")
printStacks := flag.Bool("print-stacks", false, "print stack sizes of goroutines")
@@ -1330,6 +1329,7 @@ func main() {
var testBenchRegexp *string
var testBenchTime *string
var testRunRegexp *string
var testBenchMem *bool
if command == "help" || command == "test" {
testCompileOnlyFlag = flag.Bool("c", false, "compile the test binary but do not run it")
testVerboseFlag = flag.Bool("v", false, "verbose: print additional output")
@@ -1337,6 +1337,7 @@ func main() {
testRunRegexp = flag.String("run", "", "run: regexp of tests to run")
testBenchRegexp = flag.String("bench", "", "run: regexp of benchmarks to run")
testBenchTime = flag.String("benchtime", "", "run each benchmark for duration `d`")
testBenchMem = flag.Bool("benchmem", false, "show memory stats for benchmarks")
}
// Early command processing, before commands are interpreted by the Go flag
@@ -1383,6 +1384,7 @@ func main() {
Scheduler: *scheduler,
Serial: *serial,
Work: *work,
InterpTimeout: *interpTimeout,
PrintIR: *printIR,
DumpSSA: *dumpSSA,
VerifyIR: *verifyIR,
@@ -1391,7 +1393,7 @@ func main() {
PrintSizes: *printSize,
PrintStacks: *printStacks,
PrintAllocs: printAllocs,
Tags: *tags,
Tags: []string(tags),
GlobalValues: globalVarValues,
WasmAbi: *wasmAbi,
Programmer: *programmer,
@@ -1465,7 +1467,7 @@ func main() {
fmt.Fprintf(os.Stderr, "Unknown library: %s\n", name)
os.Exit(1)
}
tmpdir, err := ioutil.TempDir("", "tinygo*")
tmpdir, err := os.MkdirTemp("", "tinygo*")
if err != nil {
handleCompilerError(err)
}
@@ -1566,7 +1568,7 @@ func main() {
defer close(buf.done)
stdout := (*testStdout)(buf)
stderr := (*testStderr)(buf)
passed, err := Test(pkgName, stdout, stderr, options, *testCompileOnlyFlag, *testVerboseFlag, *testShortFlag, *testRunRegexp, *testBenchRegexp, *testBenchTime, outpath)
passed, err := Test(pkgName, stdout, stderr, options, *testCompileOnlyFlag, *testVerboseFlag, *testShortFlag, *testRunRegexp, *testBenchRegexp, *testBenchTime, *testBenchMem, outpath)
if err != nil {
printCompilerError(func(args ...interface{}) {
fmt.Fprintln(stderr, args...)
@@ -1666,7 +1668,6 @@ func main() {
fmt.Printf("LLVM triple: %s\n", config.Triple())
fmt.Printf("GOOS: %s\n", config.GOOS())
fmt.Printf("GOARCH: %s\n", config.GOARCH())
fmt.Printf("GOARM: %s\n", config.GOARM())
fmt.Printf("build tags: %s\n", strings.Join(config.BuildTags(), " "))
fmt.Printf("garbage collector: %s\n", config.GC())
fmt.Printf("scheduler: %s\n", config.Scheduler())
+41 -36
View File
@@ -10,7 +10,6 @@ import (
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
"reflect"
@@ -52,6 +51,7 @@ func TestBuild(t *testing.T) {
"embed/",
"float.go",
"gc.go",
"generics.go",
"goroutines.go",
"init.go",
"init_multi.go",
@@ -66,21 +66,10 @@ func TestBuild(t *testing.T) {
"stdlib.go",
"string.go",
"structs.go",
"testing.go",
"timers.go",
"zeroalloc.go",
}
_, minor, err := goenv.GetGorootVersion(goenv.Get("GOROOT"))
if err != nil {
t.Fatal("could not read version from GOROOT:", err)
}
if minor >= 17 {
tests = append(tests, "go1.17.go")
}
if minor >= 18 {
tests = append(tests, "generics.go")
tests = append(tests, "testing_go118.go")
} else {
tests = append(tests, "testing.go")
}
if *testTarget != "" {
// This makes it possible to run one specific test (instead of all),
@@ -181,6 +170,14 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
}
for _, name := range tests {
if options.GOOS == "linux" && (options.GOARCH == "arm" || options.GOARCH == "386") {
switch name {
case "timers.go":
// Timer tests do not work because syscall.seek is implemented
// as Assembly in mainline Go and causes linker failure
continue
}
}
if options.Target == "simavr" {
// Not all tests are currently supported on AVR.
// Skip the ones that aren't.
@@ -193,7 +190,7 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
// Does not pass due to high mark false positive rate.
continue
case "json.go", "stdlib.go", "testing.go", "testing_go118.go":
case "json.go", "stdlib.go", "testing.go":
// Breaks interp.
continue
@@ -209,6 +206,11 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
// CGo does not work on AVR.
continue
case "timers.go":
// Doesn't compile:
// panic: compiler: could not store type code number inside interface type code
continue
default:
}
}
@@ -260,10 +262,11 @@ func emuCheck(t *testing.T, options compileopts.Options) {
t.Fatal("failed to load target spec:", err)
}
if spec.Emulator != "" {
_, err := exec.LookPath(strings.SplitN(spec.Emulator, " ", 2)[0])
emulatorCommand := strings.SplitN(spec.Emulator, " ", 2)[0]
_, err := exec.LookPath(emulatorCommand)
if err != nil {
if errors.Is(err, exec.ErrNotFound) {
t.Skipf("emulator not installed: %q", spec.Emulator[0])
t.Skipf("emulator not installed: %q", emulatorCommand)
}
t.Errorf("searching for emulator: %v", err)
@@ -275,14 +278,15 @@ func emuCheck(t *testing.T, options compileopts.Options) {
func optionsFromTarget(target string, sema chan struct{}) compileopts.Options {
return compileopts.Options{
// GOOS/GOARCH are only used if target == ""
GOOS: goenv.Get("GOOS"),
GOARCH: goenv.Get("GOARCH"),
GOARM: goenv.Get("GOARM"),
Target: target,
Semaphore: sema,
Debug: true,
VerifyIR: true,
Opt: "z",
GOOS: goenv.Get("GOOS"),
GOARCH: goenv.Get("GOARCH"),
GOARM: goenv.Get("GOARM"),
Target: target,
Semaphore: sema,
InterpTimeout: 180 * time.Second,
Debug: true,
VerifyIR: true,
Opt: "z",
}
}
@@ -292,12 +296,13 @@ func optionsFromTarget(target string, sema chan struct{}) compileopts.Options {
func optionsFromOSARCH(osarch string, sema chan struct{}) compileopts.Options {
parts := strings.Split(osarch, "/")
options := compileopts.Options{
GOOS: parts[0],
GOARCH: parts[1],
Semaphore: sema,
Debug: true,
VerifyIR: true,
Opt: "z",
GOOS: parts[0],
GOARCH: parts[1],
Semaphore: sema,
InterpTimeout: 180 * time.Second,
Debug: true,
VerifyIR: true,
Opt: "z",
}
if options.GOARCH == "arm" {
options.GOARM = parts[2]
@@ -319,7 +324,7 @@ func runTestWithConfig(name string, t *testing.T, options compileopts.Options, c
if path[len(path)-1] == '/' {
txtpath = path + "out.txt"
}
expected, err := ioutil.ReadFile(txtpath)
expected, err := os.ReadFile(txtpath)
if err != nil {
t.Fatal("could not read expected output file:", err)
}
@@ -430,7 +435,7 @@ func TestTest(t *testing.T) {
defer out.Close()
opts := targ.opts
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/pass", out, out, &opts, false, false, false, "", "", "", "")
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/pass", out, out, &opts, false, false, false, "", "", "", false, "")
if err != nil {
t.Errorf("test error: %v", err)
}
@@ -451,7 +456,7 @@ func TestTest(t *testing.T) {
defer out.Close()
opts := targ.opts
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/fail", out, out, &opts, false, false, false, "", "", "", "")
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/fail", out, out, &opts, false, false, false, "", "", "", false, "")
if err != nil {
t.Errorf("test error: %v", err)
}
@@ -478,7 +483,7 @@ func TestTest(t *testing.T) {
var output bytes.Buffer
opts := targ.opts
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/nothing", io.MultiWriter(&output, out), out, &opts, false, false, false, "", "", "", "")
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/nothing", io.MultiWriter(&output, out), out, &opts, false, false, false, "", "", "", false, "")
if err != nil {
t.Errorf("test error: %v", err)
}
@@ -502,7 +507,7 @@ func TestTest(t *testing.T) {
defer out.Close()
opts := targ.opts
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/builderr", out, out, &opts, false, false, false, "", "", "", "")
passed, err := Test("github.com/tinygo-org/tinygo/tests/testing/builderr", out, out, &opts, false, false, false, "", "", "", false, "")
if err == nil {
t.Error("test did not error")
}
@@ -0,0 +1,17 @@
// Package sig stubs crypto/internal/boring/sig
package sig
// BoringCrypto indicates that the BoringCrypto module is present.
func BoringCrypto() {
}
// FIPSOnly indicates that package crypto/tls/fipsonly is present.
func FIPSOnly() {
}
// StandardCrypto indicates that standard Go crypto is present.
func StandardCrypto() {
}
+1
View File
@@ -27,5 +27,6 @@ func (r *reader) Read(b []byte) (n int, err error) {
}
// void arc4random_buf(void *buf, size_t buflen);
//
//export arc4random_buf
func libc_arc4random_buf(buf unsafe.Pointer, buflen uint)
+1
View File
@@ -38,5 +38,6 @@ func (r *reader) Read(b []byte) (n int, err error) {
// Cryptographically secure random number generator.
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/rand-s?view=msvc-170
// errno_t rand_s(unsigned int* randomValue);
//
//export rand_s
func libc_rand_s(randomValue *uint32) int32
+29 -29
View File
@@ -2,31 +2,31 @@
//
// Original copyright:
//
// Copyright (c) 2009 - 2015 ARM LIMITED
// Copyright (c) 2009 - 2015 ARM LIMITED
//
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// - Neither the name of ARM nor the names of its contributors may be used
// to endorse or promote products derived from this software without
// specific prior written permission.
// All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// - Neither the name of ARM nor the names of its contributors may be used
// to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package arm
import (
@@ -46,12 +46,12 @@ func Asm(asm string)
// effects, as it would otherwise be optimized away. The inline assembly string
// recognizes template values in the form {name}, like so:
//
// arm.AsmFull(
// "str {value}, {result}",
// map[string]interface{}{
// "value": 1
// "result": &dest,
// })
// arm.AsmFull(
// "str {value}, {result}",
// map[string]interface{}{
// "value": 1
// "result": &dest,
// })
//
// You can use {} in the asm string (which expands to a register) to set the
// return value.
+1
View File
@@ -60,5 +60,6 @@ const (
// Call a semihosting function.
// TODO: implement it here using inline assembly.
//
//go:linkname SemihostingCall SemihostingCall
func SemihostingCall(num int, arg uintptr) int
+6 -6
View File
@@ -9,12 +9,12 @@ func Asm(asm string)
// effects, as it would otherwise be optimized away. The inline assembly string
// recognizes template values in the form {name}, like so:
//
// arm.AsmFull(
// "str {value}, {result}",
// map[string]interface{}{
// "value": 1
// "result": &dest,
// })
// arm.AsmFull(
// "str {value}, {result}",
// map[string]interface{}{
// "value": 1
// "result": &dest,
// })
//
// You can use {} in the asm string (which expands to a register) to set the
// return value.
+6 -6
View File
@@ -9,12 +9,12 @@ func Asm(asm string)
// effects, as it would otherwise be optimized away. The inline assembly string
// recognizes template values in the form {name}, like so:
//
// arm.AsmFull(
// "str {value}, {result}",
// map[string]interface{}{
// "value": 1
// "result": &dest,
// })
// arm.AsmFull(
// "str {value}, {result}",
// map[string]interface{}{
// "value": 1
// "result": &dest,
// })
//
// You can use {} in the asm string (which expands to a register) to set the
// return value.
+6 -6
View File
@@ -9,12 +9,12 @@ func Asm(asm string)
// effects, as it would otherwise be optimized away. The inline assembly string
// recognizes template values in the form {name}, like so:
//
// avr.AsmFull(
// "str {value}, {result}",
// map[string]interface{}{
// "value": 1
// "result": &dest,
// })
// avr.AsmFull(
// "str {value}, {result}",
// map[string]interface{}{
// "value": 1
// "result": &dest,
// })
//
// You can use {} in the asm string (which expands to a register) to set the
// return value.
+6 -6
View File
@@ -9,12 +9,12 @@ func Asm(asm string)
// effects, as it would otherwise be optimized away. The inline assembly string
// recognizes template values in the form {name}, like so:
//
// arm.AsmFull(
// "st {value}, {result}",
// map[string]interface{}{
// "value": 1
// "result": &dest,
// })
// arm.AsmFull(
// "st {value}, {result}",
// map[string]interface{}{
// "value": 1
// "result": &dest,
// })
//
// You can use {} in the asm string (which expands to a register) to set the
// return value.
-1
View File
@@ -1,6 +1,5 @@
// Example using the i2s hardware interface on the Adafruit Circuit Playground Express
// to read data from the onboard MEMS microphone.
//
package main
import (
+1 -1
View File
@@ -24,7 +24,7 @@ main: clean wasm_exec
cp ./main/index.html ./html/
wasm_exec:
cp ../../../targets/wasm_exec.js ./html/
cp `tinygo env TINYGOROOT`/targets/wasm_exec.js ./html/
clean:
rm -rf ./html
-2
View File
@@ -1,2 +0,0 @@
internal/itoa is new to go as of 1.17.
This directory should be removed when tinygo drops support for go 1.16.
-33
View File
@@ -1,33 +0,0 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Simple conversions to avoid depending on strconv.
package itoa
// Itoa converts val to a decimal string.
func Itoa(val int) string {
if val < 0 {
return "-" + Uitoa(uint(-val))
}
return Uitoa(uint(val))
}
// Uitoa converts val to a decimal string.
func Uitoa(val uint) string {
if val == 0 { // avoid string allocation
return "0"
}
var buf [20]byte // big enough for 64bit value base 10
i := len(buf) - 1
for val >= 10 {
q := val / 10
buf[i] = byte('0' + val - q*10)
i--
val = q
}
// val < 10
buf[i] = byte('0' + val)
return string(buf[i:])
}
-40
View File
@@ -1,40 +0,0 @@
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package itoa_test
import (
"fmt"
"internal/itoa"
"math"
"testing"
)
var (
minInt64 int64 = math.MinInt64
maxInt64 int64 = math.MaxInt64
maxUint64 uint64 = math.MaxUint64
)
func TestItoa(t *testing.T) {
tests := []int{int(minInt64), math.MinInt32, -999, -100, -1, 0, 1, 100, 999, math.MaxInt32, int(maxInt64)}
for _, tt := range tests {
got := itoa.Itoa(tt)
want := fmt.Sprint(tt)
if want != got {
t.Fatalf("Itoa(%d) = %s, want %s", tt, got, want)
}
}
}
func TestUitoa(t *testing.T) {
tests := []uint{0, 1, 100, 999, math.MaxUint32, uint(maxUint64)}
for _, tt := range tests {
got := itoa.Uitoa(tt)
want := fmt.Sprint(tt)
if want != got {
t.Fatalf("Uitoa(%d) = %s, want %s", tt, got, want)
}
}
}
+1
View File
@@ -89,6 +89,7 @@ func swapTask(oldStack uintptr, newStack *uintptr)
// startTask is a small wrapper function that sets up the first (and only)
// argument to the new goroutine and makes sure it is exited when the goroutine
// finishes.
//
//go:extern tinygo_startTask
var startTask [0]uint8
+1
View File
@@ -29,6 +29,7 @@ type calleeSavedRegs struct {
// archInit runs architecture-specific setup for the goroutine startup.
// Note: adding //go:noinline to work around an AVR backend bug.
//
//go:noinline
func (s *state) archInit(r *calleeSavedRegs, fn uintptr, args unsafe.Pointer) {
// Store the initial sp for the startTask function (implemented in assembly).
-1
View File
@@ -4,7 +4,6 @@
// This contains the pin mappings for the Arduino MKR1000 board.
//
// For more information, see: https://store.arduino.cc/usa/arduino-mkr1000-with-headers-mounted
//
package machine
// used to reset into bootloader
-1
View File
@@ -4,7 +4,6 @@
// This contains the pin mappings for the Arduino MKR WiFi 1010 board.
//
// For more information, see: https://store.arduino.cc/usa/mkr-wifi-1010
//
package machine
// used to reset into bootloader
-1
View File
@@ -4,7 +4,6 @@
// This contains the pin mappings for the Arduino Nano33 IoT board.
//
// For more information, see: https://store.arduino.cc/nano-33-iot
//
package machine
// used to reset into bootloader
+3 -3
View File
@@ -6,7 +6,6 @@
// For more information, see: https://shop.pimoroni.com/products/badger-2040
// Also
// - Badger 2040 schematic: https://cdn.shopify.com/s/files/1/0174/1800/files/badger_2040_schematic.pdf?v=1645702148
//
package machine
import (
@@ -58,14 +57,15 @@ const (
// QSPI pins¿?
const (
/* TODO
/*
TODO
SPI0_SD0_PIN Pin = QSPI_SD0
SPI0_SD1_PIN Pin = QSPI_SD1
SPI0_SD2_PIN Pin = QSPI_SD2
SPI0_SD3_PIN Pin = QSPI_SD3
SPI0_SCK_PIN Pin = QSPI_SCLKGPIO6
SPI0_CS_PIN Pin = QSPI_CS
*/
)
+5 -6
View File
@@ -10,11 +10,11 @@
//
// Special version of bossac is required.
// This executable can be obtained two ways:
// 1) In Arduino IDE, install support for the board ("Arduino Mbed OS Nano Boards")
// Search for "tools/bossac/1.9.1-arduino2/bossac" in Arduino IDEs directory
// 2) Download https://downloads.arduino.cc/packages/package_index.json
// Search for "bossac-1.9.1-arduino2" in that file
// Download tarball for your OS and unpack it
// 1. In Arduino IDE, install support for the board ("Arduino Mbed OS Nano Boards")
// Search for "tools/bossac/1.9.1-arduino2/bossac" in Arduino IDEs directory
// 2. Download https://downloads.arduino.cc/packages/package_index.json
// Search for "bossac-1.9.1-arduino2" in that file
// Download tarball for your OS and unpack it
//
// Once you have the executable, make it accessible in your PATH as "bossac_arduino2".
//
@@ -29,7 +29,6 @@
//
// SoftDevice overwrites original bootloader and flashing method described above is not avalable anymore.
// Instead, please use debug probe and flash your code with "nano-33-ble-s140v7" target.
//
package machine
const HasLowFrequencyCrystal = true
-1
View File
@@ -10,7 +10,6 @@
// Also
// - Datasheets: https://docs.arduino.cc/hardware/nano-rp2040-connect
// - Nano RP2040 Connect technical reference: https://docs.arduino.cc/tutorials/nano-rp2040-connect/rp2040-01-technical-reference
//
package machine
import (
-1
View File
@@ -4,7 +4,6 @@
// This contains the pin mappings for the ProductivityOpen P1AM-100 board.
//
// For more information, see: https://facts-engineering.github.io/
//
package machine
// used to reset into bootloader
+120
View File
@@ -0,0 +1,120 @@
//go:build qtpy_rp2040
// +build qtpy_rp2040
package machine
import (
"device/rp"
"runtime/interrupt"
)
// Onboard crystal oscillator frequency, in MHz.
const xoscFreq = 12 // MHz
// GPIO Pins
const (
SDA = GPIO24
SCL = GPIO25
TX = GPIO20
MO = GPIO3
MOSI = GPIO3
MI = GPIO4
MISO = GPIO4
SCK = GPIO6
RX = GPIO5
QT_SCL1 = GPIO23
QT_SDA1 = GPIO22
)
// Analog pins
const (
A0 = GPIO29
A1 = GPIO28
A2 = GPIO27
A3 = GPIO26
)
const (
NEOPIXELS = GPIO12
WS2812 = GPIO12
NEOPIXELS_POWER = GPIO11
LED = GPIO20
)
// I2C Pins.
const (
I2C0_SDA_PIN = GPIO24
I2C0_SCL_PIN = GPIO25
I2C1_SDA_PIN = GPIO26
I2C1_SCL_PIN = GPIO27
I2C1_QT_SDA_PIN = GPIO22
I2C1_QT_SCL_PIN = GPIO23
SDA_PIN = GPIO24
SCL_PIN = GPIO25
)
// SPI default pins
const (
// Default Serial Clock Bus 0 for SPI communications
SPI0_SCK_PIN = GPIO6
// Default Serial Out Bus 0 for SPI communications
SPI0_SDO_PIN = GPIO3 // Tx
// Default Serial In Bus 0 for SPI communications
SPI0_SDI_PIN = GPIO4 // Rx
SPI0_CS = GPIO5
// Default Serial Clock Bus 1 for SPI communications
SPI1_SCK_PIN = GPIO26
// Default Serial Out Bus 1 for SPI communications
SPI1_SDO_PIN = GPIO27 // Tx
// Default Serial In Bus 1 for SPI communications
SPI1_SDI_PIN = GPIO24 // Rx
SPI1_CS = GPIO25
)
// UART pins
const (
UART0_TX_PIN = GPIO28
UART0_RX_PIN = GPIO29
UART1_TX_PIN = GPIO20
UART1_RX_PIN = GPIO5
UART_TX_PIN = UART0_TX_PIN
UART_RX_PIN = UART0_RX_PIN
)
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
UART1 = &_UART1
_UART1 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART1,
}
)
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
UART1.Interrupt = interrupt.New(rp.IRQ_UART1_IRQ, _UART1.handleInterrupt)
}
// USB identifiers
const (
usb_STRING_PRODUCT = "QT Py RP2040"
usb_STRING_MANUFACTURER = "Adafruit"
)
var (
usb_VID uint16 = 0x239A
usb_PID uint16 = 0x80F1
)
+63
View File
@@ -0,0 +1,63 @@
//go:build trinkey_qt2040
// +build trinkey_qt2040
// This file contains the pin mappings for the Adafruit Trinkey QT2040 board.
//
// The Trinkey QT2040 is a small development board based on the RP2040 which
// plugs into a USB A port. The board has a minimal pinout: an integrated
// NeoPixel LED and a STEMMA QT I2C port.
//
// - Product: https://www.adafruit.com/product/5056
// - Overview: https://learn.adafruit.com/adafruit-trinkey-qt2040
// - Pinouts: https://learn.adafruit.com/adafruit-trinkey-qt2040/pinouts
// - Datasheets: https://learn.adafruit.com/adafruit-trinkey-qt2040/downloads
package machine
// Onboard crystal oscillator frequency, in MHz
const xoscFreq = 12 // MHz
// Onboard LEDs
const (
NEOPIXEL = GPIO27
WS2812 = NEOPIXEL
)
// I2C pins
const (
I2C0_SDA_PIN = GPIO16
I2C0_SCL_PIN = GPIO17
I2C1_SDA_PIN = NoPin
I2C1_SCL_PIN = NoPin
)
// SPI pins
const (
SPI0_SCK_PIN = NoPin
SPI0_SDO_PIN = NoPin
SPI0_SDI_PIN = NoPin
SPI1_SCK_PIN = NoPin
SPI1_SDO_PIN = NoPin
SPI1_SDI_PIN = NoPin
)
// UART pins
const (
UART0_TX_PIN = NoPin
UART0_RX_PIN = NoPin
UART_TX_PIN = UART0_TX_PIN
UART_RX_PIN = UART0_RX_PIN
)
// USB identifiers
const (
usb_STRING_PRODUCT = "Trinkey QT2040"
usb_STRING_MANUFACTURER = "Adafruit"
)
var (
usb_VID uint16 = 0x239a
usb_PID uint16 = 0x8109
)
+105
View File
@@ -0,0 +1,105 @@
//go:build tufty2040
// +build tufty2040
// This contains the pin mappings for the Badger 2040 Connect board.
//
// For more information, see: https://shop.pimoroni.com/products/tufty-2040
// Also
// - Tufty 2040 schematic: https://cdn.shopify.com/s/files/1/0174/1800/files/tufty_schematic.pdf?v=1655385675
//
package machine
import (
"device/rp"
"runtime/interrupt"
)
const (
LED Pin = GPIO25
BUTTON_A Pin = GPIO7
BUTTON_B Pin = GPIO8
BUTTON_C Pin = GPIO9
BUTTON_UP Pin = GPIO22
BUTTON_DOWN Pin = GPIO6
BUTTON_USER Pin = GPIO23
LCD_BACKLIGHT Pin = GPIO2
LCD_CS Pin = GPIO10
LCD_DC Pin = GPIO11
LCD_WR Pin = GPIO12
LCD_RD Pin = GPIO13
LCD_DB0 Pin = GPIO14
LCD_DB1 Pin = GPIO15
LCD_DB2 Pin = GPIO16
LCD_DB3 Pin = GPIO17
LCD_DB4 Pin = GPIO18
LCD_DB5 Pin = GPIO19
LCD_DB6 Pin = GPIO20
LCD_DB7 Pin = GPIO21
VBUS_DETECT Pin = GPIO24
BATTERY Pin = GPIO29
USER_LED Pin = GPIO25
LIGHT_SENSE Pin = GPIO26
SENSOR_POWER Pin = GPIO27
)
// I2C pins
const (
I2C0_SDA_PIN Pin = GPIO4
I2C0_SCL_PIN Pin = GPIO5
I2C1_SDA_PIN Pin = NoPin
I2C1_SCL_PIN Pin = NoPin
)
// SPI pins.
const (
SPI0_SCK_PIN Pin = NoPin
SPI0_SDO_PIN Pin = NoPin
SPI0_SDI_PIN Pin = NoPin
SPI1_SCK_PIN Pin = NoPin
SPI1_SDO_PIN Pin = NoPin
SPI1_SDI_PIN Pin = NoPin
)
// Onboard crystal oscillator frequency, in MHz.
const (
xoscFreq = 12 // MHz
)
// USB CDC identifiers
const (
usb_STRING_PRODUCT = "Tufty 2040"
usb_STRING_MANUFACTURER = "Pimoroni"
)
var (
usb_VID uint16 = 0x2e8a
usb_PID uint16 = 0x1002
)
// UART pins
const (
UART0_TX_PIN = GPIO0
UART0_RX_PIN = GPIO1
UART_TX_PIN = UART0_TX_PIN
UART_RX_PIN = UART0_RX_PIN
)
// UART on the RP2040
var (
UART0 = &_UART0
_UART0 = UART{
Buffer: NewRingBuffer(),
Bus: rp.UART0,
}
)
var DefaultUART = UART0
func init() {
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
}
+4 -1
View File
@@ -349,8 +349,11 @@ var (
UART1 = &sercomUSART2
// RTL8720D
// RTL8720D (tx: PC22, rx: PC23)
UART2 = &sercomUSART1
// RTL8720D (tx: PB24, rx: PC24)
UART3 = &sercomUSART0
)
// I2C pins
-1
View File
@@ -17,7 +17,6 @@
//
// - https://wiki.seeedstudio.com/XIAO_BLE/
// - https://github.com/Seeed-Studio/ArduinoCore-mbed/tree/master/variants/SEEED_XIAO_NRF52840_SENSE
//
package machine
const HasLowFrequencyCrystal = true
+54
View File
@@ -0,0 +1,54 @@
//go:build xiao_esp32c3
// +build xiao_esp32c3
// This file contains the pin mappings for the Seeed XIAO ESP32C3 boards.
//
// Seeed Studio XIAO ESP32C3 is an IoT mini development board based on
// the Espressif ESP32-C3 WiFi/Bluetooth dual-mode chip.
//
// - https://www.seeedstudio.com/Seeed-XIAO-ESP32C3-p-5431.html
// - https://wiki.seeedstudio.com/XIAO_ESP32C3_Getting_Started/
package machine
// Digital Pins
const (
D0 = GPIO2
D1 = GPIO3
D2 = GPIO4
D3 = GPIO5
D4 = GPIO6
D5 = GPIO7
D6 = GPIO21
D7 = GPIO20
D8 = GPIO8
D9 = GPIO9
D10 = GPIO10
)
// Analog pins
const (
A0 = GPIO2
A1 = GPIO3
A2 = GPIO4
A3 = GPIO5
)
// UART pins
const (
UART_RX_PIN = GPIO20
UART_TX_PIN = GPIO21
)
// I2C pins
const (
SDA_PIN = GPIO6
SCL_PIN = GPIO7
)
// SPI pins
const (
SPI_SCK_PIN = GPIO8
SPI_SDI_PIN = GPIO9
SPI_SDO_PIN = GPIO10
)
-1
View File
@@ -6,7 +6,6 @@
// XIAO RP2040 is a microcontroller using the Raspberry Pi RP2040 chip.
//
// - https://wiki.seeedstudio.com/XIAO-RP2040/
//
package machine
import (
+2 -2
View File
@@ -264,7 +264,7 @@ func (pwm PWM) Configure(config PWMConfig) error {
// SetPeriod updates the period of this PWM peripheral.
// To set a particular frequency, use the following formula:
//
// period = 1e9 / frequency
// period = 1e9 / frequency
//
// If you use a period of 0, a period that works well for LEDs will be picked.
//
@@ -694,7 +694,7 @@ func (pwm PWM) SetInverting(channel uint8, inverting bool) {
// cycle, in other words the fraction of time the channel output is high (or low
// when inverted). For example, to set it to a 25% duty cycle, use:
//
// pwm.Set(channel, pwm.Top() / 4)
// pwm.Set(channel, pwm.Top() / 4)
//
// pwm.Set(channel, 0) will set the output to low and pwm.Set(channel,
// pwm.Top()) will set the output to high, assuming the output isn't inverted.
+2 -2
View File
@@ -134,7 +134,7 @@ func (pwm PWM) Configure(config PWMConfig) error {
// SetPeriod updates the period of this PWM peripheral.
// To set a particular frequency, use the following formula:
//
// period = 1e9 / frequency
// period = 1e9 / frequency
//
// If you use a period of 0, a period that works well for LEDs will be picked.
//
@@ -375,7 +375,7 @@ func (pwm PWM) SetInverting(channel uint8, inverting bool) {
// cycle, in other words the fraction of time the channel output is high (or low
// when inverted). For example, to set it to a 25% duty cycle, use:
//
// pwm.Set(channel, pwm.Top() / 4)
// pwm.Set(channel, pwm.Top() / 4)
//
// pwm.Set(channel, 0) will set the output to low and pwm.Set(channel,
// pwm.Top()) will set the output to high, assuming the output isn't inverted.
+9 -10
View File
@@ -5,7 +5,6 @@
//
// Datasheet:
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAMD21-Family-DataSheet-DS40001882D.pdf
//
package machine
import (
@@ -88,10 +87,11 @@ const (
// SERCOM and SERCOM-ALT.
//
// Observations:
// * There are six SERCOMs. Those SERCOM numbers can be encoded in 3 bits.
// * Even pad numbers are always on even pins, and odd pad numbers are always on
// - There are six SERCOMs. Those SERCOM numbers can be encoded in 3 bits.
// - Even pad numbers are always on even pins, and odd pad numbers are always on
// odd pins.
// * Pin pads come in pairs. If PA00 has pad 0, then PA01 has pad 1.
// - Pin pads come in pairs. If PA00 has pad 0, then PA01 has pad 1.
//
// With this information, we can encode SERCOM pin/pad numbers much more
// efficiently. First of all, due to pads coming in pairs, we can ignore half
// the pins: the information for an odd pin can be calculated easily from the
@@ -1285,17 +1285,16 @@ var (
// This form sends the bytes in tx buffer, putting the resulting bytes read into the rx buffer.
// Note that the tx and rx buffers must be the same size:
//
// spi.Tx(tx, rx)
// spi.Tx(tx, rx)
//
// This form sends the tx buffer, ignoring the result. Useful for sending "commands" that return zeros
// until all the bytes in the command packet have been received:
//
// spi.Tx(tx, nil)
// spi.Tx(tx, nil)
//
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
//
// spi.Tx(nil, rx)
//
// spi.Tx(nil, rx)
func (spi SPI) Tx(w, r []byte) error {
switch {
case w == nil:
@@ -1441,7 +1440,7 @@ func (tcc *TCC) Configure(config PWMConfig) error {
// SetPeriod updates the period of this TCC peripheral.
// To set a particular frequency, use the following formula:
//
// period = 1e9 / frequency
// period = 1e9 / frequency
//
// If you use a period of 0, a period that works well for LEDs will be picked.
//
@@ -1709,7 +1708,7 @@ func (tcc *TCC) SetInverting(channel uint8, inverting bool) {
// cycle, in other words the fraction of time the channel output is high (or low
// when inverted). For example, to set it to a 25% duty cycle, use:
//
// tcc.Set(channel, tcc.Top() / 4)
// tcc.Set(channel, tcc.Top() / 4)
//
// tcc.Set(channel, 0) will set the output to low and tcc.Set(channel,
// tcc.Top()) will set the output to high, assuming the output isn't inverted.
-1
View File
@@ -5,7 +5,6 @@
//
// Datasheet:
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAMD21-Family-DataSheet-DS40001882D.pdf
//
package machine
import (
-1
View File
@@ -5,7 +5,6 @@
//
// Datasheet:
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAMD21-Family-DataSheet-DS40001882D.pdf
//
package machine
import (
+9 -10
View File
@@ -5,7 +5,6 @@
//
// Datasheet:
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
//
package machine
import (
@@ -250,12 +249,13 @@ const (
// SERCOM and SERCOM-ALT.
//
// Observations:
// * There are eight SERCOMs. Those SERCOM numbers can be encoded in 4 bits.
// * Even pad numbers are usually on even pins, and odd pad numbers are usually
// - There are eight SERCOMs. Those SERCOM numbers can be encoded in 4 bits.
// - Even pad numbers are usually on even pins, and odd pad numbers are usually
// on odd pins. The exception is SERCOM-ALT, which sometimes swaps pad 0 and 1.
// With that, there is still an invariant that the pad number for an odd pin is
// the pad number for the corresponding even pin with the low bit toggled.
// * Pin pads come in pairs. If PA00 has pad 0, then PA01 has pad 1.
// - Pin pads come in pairs. If PA00 has pad 0, then PA01 has pad 1.
//
// With this information, we can encode SERCOM pin/pad numbers much more
// efficiently. Due to pads coming in pairs, we can ignore half the pins: the
// information for an odd pin can be calculated easily from the preceding even
@@ -1538,17 +1538,16 @@ var (
// This form sends the bytes in tx buffer, putting the resulting bytes read into the rx buffer.
// Note that the tx and rx buffers must be the same size:
//
// spi.Tx(tx, rx)
// spi.Tx(tx, rx)
//
// This form sends the tx buffer, ignoring the result. Useful for sending "commands" that return zeros
// until all the bytes in the command packet have been received:
//
// spi.Tx(tx, nil)
// spi.Tx(tx, nil)
//
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
//
// spi.Tx(nil, rx)
//
// spi.Tx(nil, rx)
func (spi SPI) Tx(w, r []byte) error {
switch {
case w == nil:
@@ -1672,7 +1671,7 @@ func (tcc *TCC) Configure(config PWMConfig) error {
// SetPeriod updates the period of this TCC peripheral.
// To set a particular frequency, use the following formula:
//
// period = 1e9 / frequency
// period = 1e9 / frequency
//
// If you use a period of 0, a period that works well for LEDs will be picked.
//
@@ -1962,7 +1961,7 @@ func (tcc *TCC) SetInverting(channel uint8, inverting bool) {
// cycle, in other words the fraction of time the channel output is high (or low
// when inverted). For example, to set it to a 25% duty cycle, use:
//
// tcc.Set(channel, tcc.Top() / 4)
// tcc.Set(channel, tcc.Top() / 4)
//
// tcc.Set(channel, 0) will set the output to low and tcc.Set(channel,
// tcc.Top()) will set the output to high, assuming the output isn't inverted.
-1
View File
@@ -5,7 +5,6 @@
//
// Datasheet:
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
//
package machine
import "device/sam"
-1
View File
@@ -5,7 +5,6 @@
//
// Datasheet:
// http://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D5xE5x_Family_Data_Sheet_DS60001507F.pdf
//
package machine
import "device/sam"
-1
View File
@@ -5,7 +5,6 @@
//
// Datasheet:
// http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
//
package machine
import "device/sam"

Some files were not shown because too many files have changed in this diff Show More