mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-27 07:08:42 +00:00
Compare commits
74 Commits
v0.31.0
...
race-debug
| Author | SHA1 | Date | |
|---|---|---|---|
| 43e104e675 | |||
| 20b58a0128 | |||
| bfccf3592a | |||
| 272fea13e7 | |||
| b6fd0c818e | |||
| c383a407e3 | |||
| 7b7601d77c | |||
| f7c0466f78 | |||
| 81ce7fb738 | |||
| c2776dcf78 | |||
| ad0340d437 | |||
| 30c4df16f2 | |||
| fe27b674cd | |||
| c78dbcd3f2 | |||
| 8890b57ba0 | |||
| ee3a05f1de | |||
| 9307204111 | |||
| 71878c2c0c | |||
| cef2a82c97 | |||
| 1d9f26cee1 | |||
| 6e58c44390 | |||
| 7d6b667bba | |||
| 72f30ca6ec | |||
| 293b620faf | |||
| ad0af607ef | |||
| da23cdeae4 | |||
| d419cc11bf | |||
| 441dfc98d7 | |||
| 2b3b870bfe | |||
| 7748c4922e | |||
| 50f700ddb5 | |||
| f986ea84ac | |||
| 797a5a2031 | |||
| 3d433fe9f1 | |||
| 1154212c15 | |||
| 22bf045c9a | |||
| 39029cc376 | |||
| 7122755725 | |||
| dcee228c4e | |||
| 9d6e30701b | |||
| 85b59e66da | |||
| 90b0bf646c | |||
| c55ac9f28e | |||
| 2733e376bd | |||
| 331cfb65b7 | |||
| 055950421a | |||
| cfcc894855 | |||
| 8bd0155c51 | |||
| 32a056c32a | |||
| 8e8ad9004f | |||
| 62d8cdb218 | |||
| b6fdbee14e | |||
| a5ceb793be | |||
| 7c546525ea | |||
| d628e3e2cb | |||
| d97e4dbccf | |||
| a7ddb33bea | |||
| 8a93196f1f | |||
| 6714974aba | |||
| d67ec3b266 | |||
| 78775007fa | |||
| ad4d722f54 | |||
| 6384ecace0 | |||
| 38881a2850 | |||
| 0f1cf14743 | |||
| 7c34f7704e | |||
| 377415a6c3 | |||
| 1e13c6d18f | |||
| 14121f4b0e | |||
| 7768195835 | |||
| c095b7e9c4 | |||
| 1f6d34d995 | |||
| 9951eb9990 | |||
| c8f77d26a8 |
+10
-10
@@ -5,17 +5,17 @@ commands:
|
||||
steps:
|
||||
- run:
|
||||
name: "Pull submodules"
|
||||
command: git submodule update --init --recursive
|
||||
command: git submodule update --init
|
||||
llvm-source-linux:
|
||||
steps:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- llvm-source-17-v1
|
||||
- llvm-source-18-v1
|
||||
- run:
|
||||
name: "Fetch LLVM source"
|
||||
command: make llvm-source
|
||||
- save_cache:
|
||||
key: llvm-source-17-v1
|
||||
key: llvm-source-18-v1
|
||||
paths:
|
||||
- llvm-project/clang/lib/Headers
|
||||
- llvm-project/clang/include
|
||||
@@ -33,13 +33,13 @@ commands:
|
||||
steps:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- binaryen-linux-v2
|
||||
- binaryen-linux-v3
|
||||
- run:
|
||||
name: "Build Binaryen"
|
||||
command: |
|
||||
make binaryen
|
||||
- save_cache:
|
||||
key: binaryen-linux-v2
|
||||
key: binaryen-linux-v3
|
||||
paths:
|
||||
- build/wasm-opt
|
||||
test-linux:
|
||||
@@ -88,7 +88,7 @@ commands:
|
||||
# Do this before gen-device so that it doesn't check the
|
||||
# formatting of generated files.
|
||||
name: Check Go code formatting
|
||||
command: make fmt-check
|
||||
command: make fmt-check lint
|
||||
- run: make gen-device -j4
|
||||
- run: make smoketest XTENSA=0
|
||||
- save_cache:
|
||||
@@ -105,12 +105,12 @@ jobs:
|
||||
- test-linux:
|
||||
llvm: "15"
|
||||
resource_class: large
|
||||
test-llvm17-go122:
|
||||
test-llvm18-go122:
|
||||
docker:
|
||||
- image: golang:1.22-bullseye
|
||||
steps:
|
||||
- test-linux:
|
||||
llvm: "17"
|
||||
llvm: "18"
|
||||
resource_class: large
|
||||
|
||||
workflows:
|
||||
@@ -119,5 +119,5 @@ workflows:
|
||||
# This tests our lowest supported versions of Go and LLVM, to make sure at
|
||||
# least the smoke tests still pass.
|
||||
- test-llvm15-go118
|
||||
# This tests LLVM 17 support when linking against system libraries.
|
||||
- test-llvm17-go122
|
||||
# This tests LLVM 18 support when linking against system libraries.
|
||||
- test-llvm18-go122
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-source
|
||||
with:
|
||||
key: llvm-source-17-${{ matrix.os }}-v1
|
||||
key: llvm-source-18-${{ matrix.os }}-v2
|
||||
path: |
|
||||
llvm-project/clang/lib/Headers
|
||||
llvm-project/clang/include
|
||||
@@ -68,7 +68,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-17-${{ matrix.os }}-v1
|
||||
key: llvm-build-18-${{ matrix.os }}-v2
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
@@ -128,7 +128,7 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
matrix:
|
||||
version: [16, 17]
|
||||
version: [16, 17, 18]
|
||||
steps:
|
||||
- name: Set up Homebrew
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
@@ -152,8 +152,8 @@ jobs:
|
||||
- name: Check binary
|
||||
run: tinygo version
|
||||
- name: Build TinyGo (default LLVM)
|
||||
if: matrix.version == 17
|
||||
if: matrix.version == 18
|
||||
run: go install
|
||||
- name: Check binary
|
||||
if: matrix.version == 17
|
||||
if: matrix.version == 18
|
||||
run: tinygo version
|
||||
|
||||
@@ -64,7 +64,6 @@ jobs:
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
build-contexts: tinygo-llvm-build=docker-image://tinygo/llvm-17
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
- name: Trigger Drivers repo build on Github Actions
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
# tar: needed for actions/cache@v4
|
||||
# git+openssh: needed for checkout (I think?)
|
||||
# ruby: needed to install fpm
|
||||
run: apk add tar git openssh make g++ ruby
|
||||
run: apk add tar git openssh make g++ ruby-dev
|
||||
- name: Work around CVE-2022-24765
|
||||
# We're not on a multi-user machine, so this is safe.
|
||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-source
|
||||
with:
|
||||
key: llvm-source-17-linux-alpine-v1
|
||||
key: llvm-source-18-linux-alpine-v1
|
||||
path: |
|
||||
llvm-project/clang/lib/Headers
|
||||
llvm-project/clang/include
|
||||
@@ -68,7 +68,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-17-linux-alpine-v1
|
||||
key: llvm-build-18-linux-alpine-v1
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
@@ -113,6 +113,8 @@ jobs:
|
||||
gem install --version 4.0.7 public_suffix
|
||||
gem install --version 2.7.6 dotenv
|
||||
gem install --no-document fpm
|
||||
- name: Run linter
|
||||
run: make lint
|
||||
- name: Build TinyGo release
|
||||
run: |
|
||||
make release deb -j3 STATIC=1
|
||||
@@ -194,7 +196,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-source
|
||||
with:
|
||||
key: llvm-source-17-linux-asserts-v1
|
||||
key: llvm-source-18-linux-asserts-v1
|
||||
path: |
|
||||
llvm-project/clang/lib/Headers
|
||||
llvm-project/clang/include
|
||||
@@ -219,7 +221,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-17-linux-asserts-v1
|
||||
key: llvm-build-18-linux-asserts-v1
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
@@ -307,7 +309,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-source
|
||||
with:
|
||||
key: llvm-source-17-linux-v1
|
||||
key: llvm-source-18-linux-v1
|
||||
path: |
|
||||
llvm-project/clang/lib/Headers
|
||||
llvm-project/clang/include
|
||||
@@ -332,7 +334,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-17-linux-${{ matrix.goarch }}-v1
|
||||
key: llvm-build-18-linux-${{ matrix.goarch }}-v1
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
@@ -356,13 +358,13 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
id: cache-binaryen
|
||||
with:
|
||||
key: binaryen-linux-${{ matrix.goarch }}-v3
|
||||
key: binaryen-linux-${{ matrix.goarch }}-v4
|
||||
path: build/wasm-opt
|
||||
- name: Build Binaryen
|
||||
if: steps.cache-binaryen.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
sudo apt-get install --no-install-recommends ninja-build
|
||||
git submodule update --init --recursive lib/binaryen
|
||||
git submodule update --init lib/binaryen
|
||||
make CROSS=${{ matrix.toolchain }} binaryen
|
||||
- name: Install fpm
|
||||
run: |
|
||||
|
||||
@@ -35,8 +35,8 @@ jobs:
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
tinygo/llvm-17
|
||||
ghcr.io/${{ github.repository_owner }}/llvm-17
|
||||
tinygo/llvm-18
|
||||
ghcr.io/${{ github.repository_owner }}/llvm-18
|
||||
tags: |
|
||||
type=sha,format=long
|
||||
type=raw,value=latest
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-source
|
||||
with:
|
||||
key: llvm-source-17-linux-nix-v1
|
||||
key: llvm-source-18-linux-nix-v1
|
||||
path: |
|
||||
llvm-project/compiler-rt
|
||||
- name: Download LLVM source
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
# still works after checking out the dev branch (that is, when going from LLVM
|
||||
# 16 to LLVM 17 for example, both Clang 16 and Clang 17 are installed).
|
||||
|
||||
echo 'deb https://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main' | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||
echo 'deb https://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main' | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||
sudo apt-get update
|
||||
sudo apt-get install --no-install-recommends -y \
|
||||
llvm-17-dev \
|
||||
clang-17 \
|
||||
libclang-17-dev \
|
||||
lld-17
|
||||
llvm-18-dev \
|
||||
clang-18 \
|
||||
libclang-18-dev \
|
||||
lld-18
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
uses: actions/cache@v4
|
||||
id: cache-llvm-source
|
||||
with:
|
||||
key: llvm-source-17-sizediff-v1
|
||||
key: llvm-source-18-sizediff-v1
|
||||
path: |
|
||||
llvm-project/compiler-rt
|
||||
- name: Download LLVM source
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
- name: Cache Go
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
key: go-cache-linux-sizediff-v1-${{ hashFiles('go.mod') }}
|
||||
key: go-cache-linux-sizediff-v2-${{ hashFiles('go.mod') }}
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-source
|
||||
with:
|
||||
key: llvm-source-17-windows-v1
|
||||
key: llvm-source-18-windows-v1
|
||||
path: |
|
||||
llvm-project/clang/lib/Headers
|
||||
llvm-project/clang/include
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
uses: actions/cache/restore@v4
|
||||
id: cache-llvm-build
|
||||
with:
|
||||
key: llvm-build-17-windows-v1
|
||||
key: llvm-build-18-windows-v1
|
||||
path: llvm-build
|
||||
- name: Build LLVM
|
||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@ Now that we have a working static build, it's time to make a release tarball:
|
||||
|
||||
If you did not clone the repository with the `--recursive` option, you will get errors until you initialize the project submodules:
|
||||
|
||||
git submodule update --init --recursive
|
||||
git submodule update --init
|
||||
|
||||
The release tarball is stored in build/release.tar.gz, and can be extracted with
|
||||
the following command (for example in ~/lib):
|
||||
|
||||
+28
-1
@@ -1,3 +1,30 @@
|
||||
0.31.2
|
||||
---
|
||||
|
||||
* **general**
|
||||
* update the `net` submodule to updated version with `Buffers` implementation
|
||||
|
||||
* **compiler**
|
||||
* `syscall`: add wasm_unknown tag to some additional files so it can compile more code
|
||||
|
||||
* **standard library**
|
||||
* `runtime`: add Frame.Entry field
|
||||
|
||||
|
||||
0.31.1
|
||||
---
|
||||
|
||||
* **general**
|
||||
* fix Binaryen build in make task
|
||||
* update final build stage of Docker `dev` image to go1.22
|
||||
* only use GHA cache for building Docker `dev` image
|
||||
* update the `net` submodule to latest version
|
||||
|
||||
* **compiler**
|
||||
* `interp`: make getelementptr offsets signed
|
||||
* `interp`: return a proper error message when indexing out of range
|
||||
|
||||
|
||||
0.31.0
|
||||
---
|
||||
|
||||
@@ -64,7 +91,7 @@
|
||||
* `mksnanov3`: add support for the MKS Robin Nano V3.x
|
||||
* `nrf52840-generic`: add generic nrf52840 chip support
|
||||
* `thumby`: add support for Thumby
|
||||
* `wasm`: add new `wasm-generic` target that doesn't depend on WASI or a browser
|
||||
* `wasm`: add new `wasm-unknown` target that doesn't depend on WASI or a browser
|
||||
* **boards**
|
||||
* `arduino-mkrwifi1010`, `arduino-nano33`, `nano-rp2040`, `matrixportal-m4`, `metro-m4-airlift`, `pybadge`, `pyportal`: add `ninafw` build tag and some constants for BLE support
|
||||
* `gopher-badge`: fix typo in USB product name
|
||||
|
||||
+2
-2
@@ -27,13 +27,13 @@ COPY . /tinygo
|
||||
|
||||
# build the compiler and tools
|
||||
RUN cd /tinygo/ && \
|
||||
git submodule update --init --recursive && \
|
||||
git submodule update --init && \
|
||||
make gen-device -j4 && \
|
||||
make build/release
|
||||
|
||||
# tinygo-compiler copies the compiler build over to a base Go container (without
|
||||
# all the build tools etc).
|
||||
FROM golang:1.21 AS tinygo-compiler
|
||||
FROM golang:1.22 AS tinygo-compiler
|
||||
|
||||
# Copy tinygo build.
|
||||
COPY --from=tinygo-compiler-build /tinygo/build/release/tinygo /tinygo
|
||||
|
||||
+48
-15
@@ -10,7 +10,7 @@ LLD_SRC ?= $(LLVM_PROJECTDIR)/lld
|
||||
|
||||
# Try to autodetect LLVM build tools.
|
||||
# Versions are listed here in descending priority order.
|
||||
LLVM_VERSIONS = 17 16 15
|
||||
LLVM_VERSIONS = 18 17 16 15
|
||||
errifempty = $(if $(1),$(1),$(error $(2)))
|
||||
detect = $(shell which $(call errifempty,$(firstword $(foreach p,$(2),$(shell command -v $(p) 2> /dev/null && echo $(p)))),failed to locate $(1) at any of: $(2)))
|
||||
toolSearchPathsVersion = $(1)-$(2)
|
||||
@@ -31,6 +31,7 @@ export GOROOT = $(shell $(GO) env GOROOT)
|
||||
|
||||
# Flags to pass to go test.
|
||||
GOTESTFLAGS ?=
|
||||
GOTESTPKGS ?= ./builder ./cgo ./compileopts ./compiler ./interp ./transform .
|
||||
|
||||
# tinygo binary for tests
|
||||
TINYGO ?= $(call detect,tinygo,tinygo $(CURDIR)/build/tinygo)
|
||||
@@ -110,7 +111,7 @@ endif
|
||||
|
||||
.PHONY: all tinygo test $(LLVM_BUILDDIR) llvm-source clean fmt gen-device gen-device-nrf gen-device-nxp gen-device-avr gen-device-rp
|
||||
|
||||
LLVM_COMPONENTS = all-targets analysis asmparser asmprinter bitreader bitwriter codegen core coroutines coverage debuginfodwarf debuginfopdb executionengine frontendhlsl frontendopenmp instrumentation interpreter ipo irreader libdriver linker lto mc mcjit objcarcopts option profiledata scalaropts support target windowsdriver windowsmanifest
|
||||
LLVM_COMPONENTS = all-targets analysis asmparser asmprinter bitreader bitwriter codegen core coroutines coverage debuginfodwarf debuginfopdb executionengine frontenddriver frontendhlsl frontendopenmp instrumentation interpreter ipo irreader libdriver linker lto mc mcjit objcarcopts option profiledata scalaropts support target windowsdriver windowsmanifest
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
EXE = .exe
|
||||
@@ -146,7 +147,7 @@ endif
|
||||
MD5SUM ?= md5sum
|
||||
|
||||
# Libraries that should be linked in for the statically linked Clang.
|
||||
CLANG_LIB_NAMES = clangAnalysis clangAST clangASTMatchers clangBasic clangCodeGen clangCrossTU clangDriver clangDynamicASTMatchers clangEdit clangExtractAPI clangFormat clangFrontend clangFrontendTool clangHandleCXX clangHandleLLVM clangIndex clangLex clangParse clangRewrite clangRewriteFrontend clangSema clangSerialization clangSupport clangTooling clangToolingASTDiff clangToolingCore clangToolingInclusions
|
||||
CLANG_LIB_NAMES = clangAnalysis clangAPINotes clangAST clangASTMatchers clangBasic clangCodeGen clangCrossTU clangDriver clangDynamicASTMatchers clangEdit clangExtractAPI clangFormat clangFrontend clangFrontendTool clangHandleCXX clangHandleLLVM clangIndex clangLex clangParse clangRewrite clangRewriteFrontend clangSema clangSerialization clangSupport clangTooling clangToolingASTDiff clangToolingCore clangToolingInclusions
|
||||
CLANG_LIBS = $(START_GROUP) $(addprefix -l,$(CLANG_LIB_NAMES)) $(END_GROUP) -lstdc++
|
||||
|
||||
# Libraries that should be linked in for the statically linked LLD.
|
||||
@@ -165,7 +166,7 @@ LIB_NAMES = clang $(CLANG_LIB_NAMES) $(LLD_LIB_NAMES) $(EXTRA_LIB_NAMES)
|
||||
# library path (for ninja).
|
||||
# This list also includes a few tools that are necessary as part of the full
|
||||
# TinyGo build.
|
||||
NINJA_BUILD_TARGETS = clang llvm-config llvm-ar llvm-nm $(addprefix lib/lib,$(addsuffix .a,$(LIB_NAMES)))
|
||||
NINJA_BUILD_TARGETS = clang llvm-config llvm-ar llvm-nm lld $(addprefix lib/lib,$(addsuffix .a,$(LIB_NAMES)))
|
||||
|
||||
# For static linking.
|
||||
ifneq ("$(wildcard $(LLVM_BUILDDIR)/bin/llvm-config*)","")
|
||||
@@ -190,7 +191,7 @@ gen-device: gen-device-stm32
|
||||
endif
|
||||
|
||||
gen-device-avr:
|
||||
@if [ ! -e lib/avr/README.md ]; then echo "Submodules have not been downloaded. Please download them using:\n git submodule update --init --recursive"; exit 1; fi
|
||||
@if [ ! -e lib/avr/README.md ]; then echo "Submodules have not been downloaded. Please download them using:\n git submodule update --init"; exit 1; fi
|
||||
$(GO) build -o ./build/gen-device-avr ./tools/gen-device-avr/
|
||||
./build/gen-device-avr lib/avr/packs/atmega src/device/avr/
|
||||
./build/gen-device-avr lib/avr/packs/tiny src/device/avr/
|
||||
@@ -238,7 +239,7 @@ gen-device-renesas: build/gen-device-svd
|
||||
|
||||
# Get LLVM sources.
|
||||
$(LLVM_PROJECTDIR)/llvm:
|
||||
git clone -b xtensa_release_17.0.1 --depth=1 https://github.com/espressif/llvm-project $(LLVM_PROJECTDIR)
|
||||
git clone -b tinygo_xtensa_release_18.1.2 --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR)
|
||||
llvm-source: $(LLVM_PROJECTDIR)/llvm
|
||||
|
||||
# Configure LLVM.
|
||||
@@ -264,7 +265,7 @@ endif
|
||||
.PHONY: wasi-libc
|
||||
wasi-libc: lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a
|
||||
lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a:
|
||||
@if [ ! -e lib/wasi-libc/Makefile ]; then echo "Submodules have not been downloaded. Please download them using:\n git submodule update --init --recursive"; exit 1; fi
|
||||
@if [ ! -e lib/wasi-libc/Makefile ]; then echo "Submodules have not been downloaded. Please download them using:\n git submodule update --init"; exit 1; fi
|
||||
cd lib/wasi-libc && $(MAKE) -j4 EXTRA_CFLAGS="-O2 -g -DNDEBUG -mnontrapping-fptoint -msign-ext" MALLOC_IMPL=none CC="$(CLANG)" AR=$(LLVM_AR) NM=$(LLVM_NM)
|
||||
|
||||
# Check for Node.js used during WASM tests.
|
||||
@@ -283,7 +284,7 @@ tinygo:
|
||||
@if [ ! -f "$(LLVM_BUILDDIR)/bin/llvm-config" ]; then echo "Fetch and build LLVM first by running:"; echo " $(MAKE) llvm-source"; echo " $(MAKE) $(LLVM_BUILDDIR)"; exit 1; fi
|
||||
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GOENVFLAGS) $(GO) build -buildmode exe -o build/tinygo$(EXE) -tags "byollvm osusergo" -ldflags="-X github.com/tinygo-org/tinygo/goenv.GitSha1=`git rev-parse --short HEAD`" .
|
||||
test: wasi-libc check-nodejs-version
|
||||
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=20m -buildmode exe -tags "byollvm osusergo" ./builder ./cgo ./compileopts ./compiler ./interp ./transform .
|
||||
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=20m -buildmode exe -tags "byollvm osusergo" $(GOTESTPKGS)
|
||||
|
||||
# Standard library packages that pass tests on darwin, linux, wasi, and windows, but take over a minute in wasi
|
||||
TEST_PACKAGES_SLOW = \
|
||||
@@ -426,17 +427,17 @@ tinygo-bench-fast:
|
||||
|
||||
# Same thing, except for wasi rather than the current platform.
|
||||
tinygo-test-wasi:
|
||||
$(TINYGO) test -target wasi $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
||||
$(TINYGO) test -target wasip1 $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
||||
tinygo-test-wasip1:
|
||||
GOOS=wasip1 GOARCH=wasm $(TINYGO) test $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
||||
tinygo-test-wasi-fast:
|
||||
$(TINYGO) test -target wasi $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
||||
$(TINYGO) test -target wasip1 $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
||||
tinygo-test-wasip1-fast:
|
||||
GOOS=wasip1 GOARCH=wasm $(TINYGO) test $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
||||
tinygo-bench-wasi:
|
||||
$(TINYGO) test -target wasi -bench . $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW)
|
||||
$(TINYGO) test -target wasip1 -bench . $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW)
|
||||
tinygo-bench-wasi-fast:
|
||||
$(TINYGO) test -target wasi -bench . $(TEST_PACKAGES_FAST)
|
||||
$(TINYGO) test -target wasip1 -bench . $(TEST_PACKAGES_FAST)
|
||||
|
||||
# Test external packages in a large corpus.
|
||||
test-corpus:
|
||||
@@ -444,7 +445,7 @@ test-corpus:
|
||||
test-corpus-fast:
|
||||
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags byollvm -run TestCorpus -short . -corpus=testdata/corpus.yaml
|
||||
test-corpus-wasi: wasi-libc
|
||||
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags byollvm -run TestCorpus . -corpus=testdata/corpus.yaml -target=wasi
|
||||
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test $(GOTESTFLAGS) -timeout=1h -buildmode exe -tags byollvm -run TestCorpus . -corpus=testdata/corpus.yaml -target=wasip1
|
||||
|
||||
tinygo-baremetal:
|
||||
# Regression tests that run on a baremetal target and don't fit in either main_test.go or smoketest.
|
||||
@@ -524,6 +525,8 @@ ifneq ($(WASM), 0)
|
||||
@$(MD5SUM) test.wasm
|
||||
$(TINYGO) build -size short -o test.wasm -tags=mch2022 examples/serial
|
||||
@$(MD5SUM) test.wasm
|
||||
$(TINYGO) build -size short -o test.wasm -tags=gopher_badge examples/blinky1
|
||||
@$(MD5SUM) test.wasm
|
||||
endif
|
||||
# test all targets/boards
|
||||
$(TINYGO) build -size short -o test.hex -target=pca10040-s132v6 examples/blinky1
|
||||
@@ -598,6 +601,8 @@ endif
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=pca10056-s140v7 examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=pca10059-s140v7 examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=reelboard-s140v7 examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=wioterminal examples/blinky1
|
||||
@@ -654,6 +659,8 @@ endif
|
||||
@$(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=badger2040-w 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
|
||||
@@ -703,6 +710,8 @@ ifneq ($(STM32), 0)
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=nucleo-l432kc examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=nucleo-l476rg examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=nucleo-l552ze examples/blinky1
|
||||
@$(MD5SUM) test.hex
|
||||
$(TINYGO) build -size short -o test.hex -target=nucleo-wl55jc examples/blinky1
|
||||
@@ -759,6 +768,8 @@ ifneq ($(XTENSA), 0)
|
||||
@$(MD5SUM) test.bin
|
||||
$(TINYGO) build -size short -o test.bin -target m5stick-c examples/serial
|
||||
@$(MD5SUM) test.bin
|
||||
$(TINYGO) build -size short -o test.bin -target m5paper examples/serial
|
||||
@$(MD5SUM) test.bin
|
||||
$(TINYGO) build -size short -o test.bin -target mch2022 examples/serial
|
||||
@$(MD5SUM) test.bin
|
||||
endif
|
||||
@@ -818,7 +829,9 @@ build/release: tinygo gen-device wasi-libc $(if $(filter 1,$(USE_SYSTEM_BINARYEN
|
||||
@mkdir -p build/release/tinygo/lib/nrfx
|
||||
@mkdir -p build/release/tinygo/lib/picolibc/newlib/libc
|
||||
@mkdir -p build/release/tinygo/lib/picolibc/newlib/libm
|
||||
@mkdir -p build/release/tinygo/lib/wasi-libc
|
||||
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-bottom-half/headers
|
||||
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
|
||||
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
|
||||
@mkdir -p build/release/tinygo/pkg/thumbv6m-unknown-unknown-eabi-cortex-m0
|
||||
@mkdir -p build/release/tinygo/pkg/thumbv6m-unknown-unknown-eabi-cortex-m0plus
|
||||
@mkdir -p build/release/tinygo/pkg/thumbv7em-unknown-unknown-eabi-cortex-m4
|
||||
@@ -869,7 +882,15 @@ endif
|
||||
@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 lib/wasi-libc/libc-bottom-half/headers/public build/release/tinygo/lib/wasi-libc/libc-bottom-half/headers
|
||||
@cp -rp lib/wasi-libc/libc-top-half/musl/arch/generic build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
|
||||
@cp -rp lib/wasi-libc/libc-top-half/musl/arch/wasm32 build/release/tinygo/lib/wasi-libc/libc-top-half/musl/arch
|
||||
@cp -rp lib/wasi-libc/libc-top-half/musl/src/include build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
|
||||
@cp -rp lib/wasi-libc/libc-top-half/musl/src/internal build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
|
||||
@cp -rp lib/wasi-libc/libc-top-half/musl/src/math build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
|
||||
@cp -rp lib/wasi-libc/libc-top-half/musl/src/string build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
|
||||
@cp -rp lib/wasi-libc/libc-top-half/musl/include build/release/tinygo/lib/wasi-libc/libc-top-half/musl
|
||||
@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
|
||||
@cp -rp llvm-project/compiler-rt/LICENSE.TXT build/release/tinygo/lib/compiler-rt-builtins
|
||||
@cp -rp src build/release/tinygo/src
|
||||
@@ -896,3 +917,15 @@ ifneq ($(RELEASEONLY), 1)
|
||||
release: build/release
|
||||
deb: build/release
|
||||
endif
|
||||
|
||||
lint:
|
||||
go run github.com/mgechev/revive -version
|
||||
# TODO: lint more directories!
|
||||
# revive.toml isn't flexible enough to filter out just one kind of error from a checker, so do it with grep here.
|
||||
# Can't use grep with friendly formatter. Plain output isn't too bad, though.
|
||||
# Use 'grep .' to get rid of stray blank line
|
||||
go run github.com/mgechev/revive -config revive.toml compiler/... src/{os,reflect}/*.go | grep -v "should have comment or be unexported" | grep '.' | awk '{print}; END {exit NR>0}'
|
||||
|
||||
spell:
|
||||
# Check for typos in comments. Skip git submodules etc.
|
||||
go run github.com/client9/misspell/cmd/misspell -i 'ackward,devided,extint,inbetween,programmmer,rela' $$( find . -depth 1 -type d | egrep -w -v 'lib|llvm|src/net' )
|
||||
|
||||
@@ -41,7 +41,7 @@ tinygo flash -target arduino examples/blinky1
|
||||
|
||||
TinyGo is very useful for compiling programs both for use in browsers (WASM) as well as for use on servers and other edge devices (WASI).
|
||||
|
||||
TinyGo programs can run in Fastly Compute@Edge (https://developer.fastly.com/learning/compute/go/), Fermyon Spin (https://developer.fermyon.com/spin/go-components), wazero (https://wazero.io/languages/tinygo/) and many other WebAssembly runtimes.
|
||||
TinyGo programs can run in [Fastly Compute](https://www.fastly.com/documentation/guides/compute/go/), [Fermyon Spin](https://developer.fermyon.com/spin/go-components), [wazero](https://wazero.io/languages/tinygo/) and many other WebAssembly runtimes.
|
||||
|
||||
Here is a small TinyGo program for use by a WASI host application:
|
||||
|
||||
@@ -54,14 +54,14 @@ func add(x, y uint32) uint32 {
|
||||
return x + y
|
||||
}
|
||||
|
||||
// main is required for the `wasi` target, even if it isn't used.
|
||||
// main is required for the `wasip1` target, even if it isn't used.
|
||||
func main() {}
|
||||
```
|
||||
|
||||
This compiles the above TinyGo program for use on any WASI runtime:
|
||||
|
||||
```shell
|
||||
tinygo build -o main.wasm -target=wasi main.go
|
||||
tinygo build -o main.wasm -target=wasip1 main.go
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
+16
-6
@@ -78,17 +78,27 @@ func makeArchive(arfile *os.File, objs []string) error {
|
||||
} else if dbg, err := wasm.Parse(objfile); err == nil {
|
||||
for _, s := range dbg.Sections {
|
||||
switch section := s.(type) {
|
||||
case *wasm.SectionImport:
|
||||
for _, ln := range section.Entries {
|
||||
|
||||
if ln.Kind != wasm.ExtKindFunction {
|
||||
// Not a function
|
||||
case *wasm.SectionLinking:
|
||||
for _, symbol := range section.Symbols {
|
||||
if symbol.Flags&wasm.LinkingSymbolFlagUndefined != 0 {
|
||||
// Don't list undefined functions.
|
||||
continue
|
||||
}
|
||||
if symbol.Flags&wasm.LinkingSymbolFlagBindingLocal != 0 {
|
||||
// Don't include local symbols.
|
||||
continue
|
||||
}
|
||||
if symbol.Kind != wasm.LinkingSymbolKindFunction && symbol.Kind != wasm.LinkingSymbolKindData {
|
||||
// Link functions and data symbols.
|
||||
// Some data symbols need to be included, such as
|
||||
// __log_data.
|
||||
continue
|
||||
}
|
||||
// Include in the archive.
|
||||
symbolTable = append(symbolTable, struct {
|
||||
name string
|
||||
fileIndex int
|
||||
}{ln.Field, i})
|
||||
}{symbol.Name, i})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+33
-5
@@ -168,6 +168,13 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
return BuildResult{}, errors.New("could not find wasi-libc, perhaps you need to run `make wasi-libc`?")
|
||||
}
|
||||
libcDependencies = append(libcDependencies, dummyCompileJob(path))
|
||||
case "wasmbuiltins":
|
||||
libcJob, unlock, err := WasmBuiltins.load(config, tmpdir)
|
||||
if err != nil {
|
||||
return BuildResult{}, err
|
||||
}
|
||||
defer unlock()
|
||||
libcDependencies = append(libcDependencies, libcJob)
|
||||
case "mingw-w64":
|
||||
_, unlock, err := MinGW.load(config, tmpdir)
|
||||
if err != nil {
|
||||
@@ -200,6 +207,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
MaxStackAlloc: config.MaxStackAlloc(),
|
||||
NeedsStackObjects: config.NeedsStackObjects(),
|
||||
Debug: !config.Options.SkipDWARF, // emit DWARF except when -internal-nodwarf is passed
|
||||
PanicStrategy: config.PanicStrategy(),
|
||||
}
|
||||
|
||||
// Load the target machine, which is the LLVM object that contains all
|
||||
@@ -235,6 +243,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
// Create the *ssa.Program. This does not yet build the entire SSA of the
|
||||
// program so it's pretty fast and doesn't need to be parallelized.
|
||||
program := lprogram.LoadSSA()
|
||||
program.Build()
|
||||
|
||||
// Add jobs to compile each package.
|
||||
// Packages that have a cache hit will not be compiled again.
|
||||
@@ -346,8 +355,8 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
packageActionIDJobs[pkg.ImportPath] = packageActionIDJob
|
||||
|
||||
// Build the SSA for the given package.
|
||||
ssaPkg := program.Package(pkg.Pkg)
|
||||
ssaPkg.Build()
|
||||
//ssaPkg := program.Package(pkg.Pkg)
|
||||
//ssaPkg.Build()
|
||||
|
||||
// Now create the job to actually build the package. It will exit early
|
||||
// if the package is already compiled.
|
||||
@@ -362,7 +371,12 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
|
||||
if _, err := os.Stat(job.result); err == nil {
|
||||
// Already cached, don't recreate this package.
|
||||
return nil
|
||||
switch pkg.ImportPath {
|
||||
case "context": // seems to be needed
|
||||
case "time": // often crashes in this package, so probably needed
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Compile AST to IR. The compiler.CompilePackage function will
|
||||
@@ -509,6 +523,8 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
run: func(*compileJob) error {
|
||||
// Load and link all the bitcode files. This does not yet optimize
|
||||
// anything, it only links the bitcode files together.
|
||||
println("exit")
|
||||
os.Exit(0)
|
||||
ctx := llvm.NewContext()
|
||||
mod = ctx.NewModule("main")
|
||||
for _, pkgJob := range packageJobs {
|
||||
@@ -765,7 +781,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
if sizeLevel >= 2 {
|
||||
// Workaround with roughly the same effect as
|
||||
// https://reviews.llvm.org/D119342.
|
||||
// Can hopefully be removed in LLVM 18.
|
||||
// Can hopefully be removed in LLVM 19.
|
||||
ldflags = append(ldflags,
|
||||
"-mllvm", "--rotation-max-header-size=0")
|
||||
}
|
||||
@@ -817,13 +833,25 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
||||
args = append(args, "--asyncify")
|
||||
}
|
||||
|
||||
exeunopt := result.Executable
|
||||
|
||||
if config.Options.Work {
|
||||
// Keep the work direction around => don't overwrite the .wasm binary with the optimized version
|
||||
exeunopt += ".pre-wasm-opt"
|
||||
os.Rename(result.Executable, exeunopt)
|
||||
}
|
||||
|
||||
args = append(args,
|
||||
opt,
|
||||
"-g",
|
||||
result.Executable,
|
||||
exeunopt,
|
||||
"--output", result.Executable,
|
||||
)
|
||||
|
||||
if config.Options.PrintCommands != nil {
|
||||
config.Options.PrintCommands(goenv.Get("WASMOPT"), args...)
|
||||
}
|
||||
|
||||
cmd := exec.Command(goenv.Get("WASMOPT"), args...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
@@ -33,7 +33,7 @@ func TestClangAttributes(t *testing.T) {
|
||||
"k210",
|
||||
"nintendoswitch",
|
||||
"riscv-qemu",
|
||||
"wasi",
|
||||
"wasip1",
|
||||
"wasm",
|
||||
"wasm-unknown",
|
||||
}
|
||||
|
||||
+5
-7
@@ -8,14 +8,14 @@ import (
|
||||
"github.com/tinygo-org/tinygo/goenv"
|
||||
)
|
||||
|
||||
// These are the GENERIC_SOURCES according to CMakeList.txt.
|
||||
// These are the GENERIC_SOURCES according to CMakeList.txt except for
|
||||
// divmodsi4.c and udivmodsi4.c.
|
||||
var genericBuiltins = []string{
|
||||
"absvdi2.c",
|
||||
"absvsi2.c",
|
||||
"absvti2.c",
|
||||
"adddf3.c",
|
||||
"addsf3.c",
|
||||
"addtf3.c",
|
||||
"addvdi3.c",
|
||||
"addvsi3.c",
|
||||
"addvti3.c",
|
||||
@@ -40,12 +40,12 @@ var genericBuiltins = []string{
|
||||
"divdf3.c",
|
||||
"divdi3.c",
|
||||
"divmoddi4.c",
|
||||
//"divmodsi4.c",
|
||||
"divmodti4.c",
|
||||
"divsc3.c",
|
||||
"divsf3.c",
|
||||
"divsi3.c",
|
||||
"divtc3.c",
|
||||
"divti3.c",
|
||||
"divtf3.c",
|
||||
"extendsfdf2.c",
|
||||
"extendhfsf2.c",
|
||||
"ffsdi2.c",
|
||||
@@ -91,7 +91,6 @@ var genericBuiltins = []string{
|
||||
"mulsc3.c",
|
||||
"mulsf3.c",
|
||||
"multi3.c",
|
||||
"multf3.c",
|
||||
"mulvdi3.c",
|
||||
"mulvsi3.c",
|
||||
"mulvti3.c",
|
||||
@@ -111,13 +110,11 @@ var genericBuiltins = []string{
|
||||
"popcountti2.c",
|
||||
"powidf2.c",
|
||||
"powisf2.c",
|
||||
"powitf2.c",
|
||||
"subdf3.c",
|
||||
"subsf3.c",
|
||||
"subvdi3.c",
|
||||
"subvsi3.c",
|
||||
"subvti3.c",
|
||||
"subtf3.c",
|
||||
"trampoline_setup.c",
|
||||
"truncdfhf2.c",
|
||||
"truncdfsf2.c",
|
||||
@@ -126,6 +123,7 @@ var genericBuiltins = []string{
|
||||
"ucmpti2.c",
|
||||
"udivdi3.c",
|
||||
"udivmoddi4.c",
|
||||
//"udivmodsi4.c",
|
||||
"udivmodti4.c",
|
||||
"udivsi3.c",
|
||||
"udivti3.c",
|
||||
|
||||
+8
-7
@@ -82,10 +82,10 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
|
||||
// Parse the arguments.
|
||||
const OptTable &OptTbl = getDriverOptTable();
|
||||
|
||||
const unsigned IncludedFlagsBitmask = options::CC1AsOption;
|
||||
llvm::opt::Visibility VisibilityMask(options::CC1AsOption);
|
||||
unsigned MissingArgIndex, MissingArgCount;
|
||||
InputArgList Args = OptTbl.ParseArgs(Argv, MissingArgIndex, MissingArgCount,
|
||||
IncludedFlagsBitmask);
|
||||
InputArgList Args =
|
||||
OptTbl.ParseArgs(Argv, MissingArgIndex, MissingArgCount, VisibilityMask);
|
||||
|
||||
// Check for missing argument error.
|
||||
if (MissingArgCount) {
|
||||
@@ -98,7 +98,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
|
||||
for (const Arg *A : Args.filtered(OPT_UNKNOWN)) {
|
||||
auto ArgString = A->getAsString(Args);
|
||||
std::string Nearest;
|
||||
if (OptTbl.findNearest(ArgString, Nearest, IncludedFlagsBitmask) > 1)
|
||||
if (OptTbl.findNearest(ArgString, Nearest, VisibilityMask) > 1)
|
||||
Diags.Report(diag::err_drv_unknown_argument) << ArgString;
|
||||
else
|
||||
Diags.Report(diag::err_drv_unknown_argument_with_suggestion)
|
||||
@@ -521,9 +521,10 @@ int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
|
||||
if (Asm.ShowHelp) {
|
||||
getDriverOptTable().printHelp(
|
||||
llvm::outs(), "clang -cc1as [options] file...",
|
||||
"Clang Integrated Assembler",
|
||||
/*Include=*/driver::options::CC1AsOption, /*Exclude=*/0,
|
||||
/*ShowAllAliases=*/false);
|
||||
"Clang Integrated Assembler", /*ShowHidden=*/false,
|
||||
/*ShowAllAliases=*/false,
|
||||
llvm::opt::Visibility(driver::options::CC1AsOption));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,9 +41,9 @@ func TestBinarySize(t *testing.T) {
|
||||
// This is a small number of very diverse targets that we want to test.
|
||||
tests := []sizeTest{
|
||||
// microcontrollers
|
||||
{"hifive1b", "examples/echo", 4476, 280, 0, 2252},
|
||||
{"microbit", "examples/serial", 2724, 388, 8, 2256},
|
||||
{"wioterminal", "examples/pininterrupt", 5996, 1484, 116, 6816},
|
||||
{"hifive1b", "examples/echo", 4484, 280, 0, 2252},
|
||||
{"microbit", "examples/serial", 2732, 388, 8, 2256},
|
||||
{"wioterminal", "examples/pininterrupt", 6016, 1484, 116, 6816},
|
||||
|
||||
// TODO: also check wasm. Right now this is difficult, because
|
||||
// wasm binaries are run through wasm-opt and therefore the
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/tinygo-org/tinygo/goenv"
|
||||
)
|
||||
|
||||
var WasmBuiltins = Library{
|
||||
name: "wasmbuiltins",
|
||||
makeHeaders: func(target, includeDir string) error {
|
||||
if err := os.Mkdir(includeDir+"/bits", 0o777); err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.Create(includeDir + "/bits/alltypes.h")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := f.Write([]byte(wasmAllTypes)); err != nil {
|
||||
return err
|
||||
}
|
||||
return f.Close()
|
||||
},
|
||||
cflags: func(target, headerPath string) []string {
|
||||
libcDir := filepath.Join(goenv.Get("TINYGOROOT"), "lib/wasi-libc")
|
||||
return []string{
|
||||
"-Werror",
|
||||
"-Wall",
|
||||
"-std=gnu11",
|
||||
"-nostdlibinc",
|
||||
"-isystem", libcDir + "/libc-top-half/musl/arch/wasm32",
|
||||
"-isystem", libcDir + "/libc-top-half/musl/arch/generic",
|
||||
"-isystem", libcDir + "/libc-top-half/musl/src/internal",
|
||||
"-isystem", libcDir + "/libc-top-half/musl/src/include",
|
||||
"-isystem", libcDir + "/libc-top-half/musl/include",
|
||||
"-isystem", libcDir + "/libc-bottom-half/headers/public",
|
||||
"-I" + headerPath,
|
||||
}
|
||||
},
|
||||
sourceDir: func() string { return filepath.Join(goenv.Get("TINYGOROOT"), "lib/wasi-libc") },
|
||||
librarySources: func(target string) ([]string, error) {
|
||||
return []string{
|
||||
// memory builtins needed for llvm.memcpy.*, llvm.memmove.*, and
|
||||
// llvm.memset.* LLVM intrinsics.
|
||||
"libc-top-half/musl/src/string/memcpy.c",
|
||||
"libc-top-half/musl/src/string/memmove.c",
|
||||
"libc-top-half/musl/src/string/memset.c",
|
||||
|
||||
// exp, exp2, and log are needed for LLVM math builtin functions
|
||||
// like llvm.exp.*.
|
||||
"libc-top-half/musl/src/math/__math_divzero.c",
|
||||
"libc-top-half/musl/src/math/__math_invalid.c",
|
||||
"libc-top-half/musl/src/math/__math_oflow.c",
|
||||
"libc-top-half/musl/src/math/__math_uflow.c",
|
||||
"libc-top-half/musl/src/math/__math_xflow.c",
|
||||
"libc-top-half/musl/src/math/exp.c",
|
||||
"libc-top-half/musl/src/math/exp_data.c",
|
||||
"libc-top-half/musl/src/math/exp2.c",
|
||||
"libc-top-half/musl/src/math/log.c",
|
||||
"libc-top-half/musl/src/math/log_data.c",
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
// alltypes.h for wasm-libc, using the types as defined inside Clang.
|
||||
const wasmAllTypes = `
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
typedef __INT8_TYPE__ int8_t;
|
||||
typedef __INT16_TYPE__ int16_t;
|
||||
typedef __INT32_TYPE__ int32_t;
|
||||
typedef __INT64_TYPE__ int64_t;
|
||||
typedef __UINT8_TYPE__ uint8_t;
|
||||
typedef __UINT16_TYPE__ uint16_t;
|
||||
typedef __UINT32_TYPE__ uint32_t;
|
||||
typedef __UINT64_TYPE__ uint64_t;
|
||||
typedef __UINTPTR_TYPE__ uintptr_t;
|
||||
|
||||
// This type is used internally in wasi-libc.
|
||||
typedef double double_t;
|
||||
`
|
||||
+1
-1
@@ -216,7 +216,7 @@ func (i simpleImporter) Import(path string) (*types.Package, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// formatDiagnostics formats the error message to be an indented comment. It
|
||||
// formatDiagnostic formats the error message to be an indented comment. It
|
||||
// also fixes Windows path name issues (backward slashes).
|
||||
func formatDiagnostic(err error) string {
|
||||
msg := err.Error()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//go:build !byollvm && !llvm15 && !llvm16
|
||||
//go:build !byollvm && llvm17
|
||||
|
||||
package cgo
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
//go:build !byollvm && !llvm15 && !llvm16 && !llvm17
|
||||
|
||||
package cgo
|
||||
|
||||
/*
|
||||
#cgo linux CFLAGS: -I/usr/include/llvm-18 -I/usr/include/llvm-c-18 -I/usr/lib/llvm-18/include
|
||||
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@18/include
|
||||
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@18/include
|
||||
#cgo freebsd CFLAGS: -I/usr/local/llvm18/include
|
||||
#cgo linux LDFLAGS: -L/usr/lib/llvm-18/lib -lclang
|
||||
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@18/lib -lclang
|
||||
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@18/lib -lclang
|
||||
#cgo freebsd LDFLAGS: -L/usr/local/llvm18/lib -lclang
|
||||
*/
|
||||
import "C"
|
||||
+10
-5
@@ -74,7 +74,8 @@ func (c *Config) GOARM() string {
|
||||
|
||||
// BuildTags returns the complete list of build tags used during this build.
|
||||
func (c *Config) BuildTags() []string {
|
||||
tags := append(c.Target.BuildTags, []string{
|
||||
tags := append([]string(nil), c.Target.BuildTags...) // copy slice (avoid a race)
|
||||
tags = append(tags, []string{
|
||||
"tinygo", // that's the compiler
|
||||
"purego", // to get various crypto packages to work
|
||||
"math_big_pure_go", // to get math/big to work
|
||||
@@ -310,7 +311,11 @@ func (c *Config) CFlags(libclang bool) []string {
|
||||
)
|
||||
case "wasi-libc":
|
||||
root := goenv.Get("TINYGOROOT")
|
||||
cflags = append(cflags, "--sysroot="+root+"/lib/wasi-libc/sysroot")
|
||||
cflags = append(cflags,
|
||||
"-nostdlibinc",
|
||||
"-isystem", root+"/lib/wasi-libc/sysroot/include")
|
||||
case "wasmbuiltins":
|
||||
// nothing to add (library is purely for builtins)
|
||||
case "mingw-w64":
|
||||
root := goenv.Get("TINYGOROOT")
|
||||
path, _ := c.LibcPath("mingw-w64")
|
||||
@@ -475,9 +480,6 @@ func (c *Config) OpenOCDConfiguration() (args []string, err error) {
|
||||
return nil, fmt.Errorf("unknown OpenOCD transport: %#v", c.Target.OpenOCDTransport)
|
||||
}
|
||||
args = []string{"-f", "interface/" + openocdInterface + ".cfg"}
|
||||
for _, cmd := range c.Target.OpenOCDCommands {
|
||||
args = append(args, "-c", cmd)
|
||||
}
|
||||
if c.Target.OpenOCDTransport != "" {
|
||||
transport := c.Target.OpenOCDTransport
|
||||
if transport == "swd" {
|
||||
@@ -489,6 +491,9 @@ func (c *Config) OpenOCDConfiguration() (args []string, err error) {
|
||||
args = append(args, "-c", "transport select "+transport)
|
||||
}
|
||||
args = append(args, "-f", "target/"+c.Target.OpenOCDTarget+".cfg")
|
||||
for _, cmd := range c.Target.OpenOCDCommands {
|
||||
args = append(args, "-c", cmd)
|
||||
}
|
||||
return args, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ type TargetSpec struct {
|
||||
Inherits []string `json:"inherits,omitempty"`
|
||||
Triple string `json:"llvm-target,omitempty"`
|
||||
CPU string `json:"cpu,omitempty"`
|
||||
ABI string `json:"target-abi,omitempty"` // rougly equivalent to -mabi= flag
|
||||
ABI string `json:"target-abi,omitempty"` // roughly equivalent to -mabi= flag
|
||||
Features string `json:"features,omitempty"`
|
||||
GOOS string `json:"goos,omitempty"`
|
||||
GOARCH string `json:"goarch,omitempty"`
|
||||
@@ -319,11 +319,11 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
||||
case "arm64":
|
||||
spec.CPU = "generic"
|
||||
if goos == "darwin" {
|
||||
spec.Features = "+neon"
|
||||
spec.Features = "+fp-armv8,+neon"
|
||||
} else if goos == "windows" {
|
||||
spec.Features = "+neon,-fmv"
|
||||
spec.Features = "+fp-armv8,+neon,-fmv"
|
||||
} else { // linux
|
||||
spec.Features = "+neon,-fmv,-outline-atomics"
|
||||
spec.Features = "+fp-armv8,+neon,-fmv,-outline-atomics"
|
||||
}
|
||||
case "wasm":
|
||||
spec.CPU = "generic"
|
||||
|
||||
+6
-2
@@ -16,14 +16,18 @@ 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/ed25519/internal/edwards25519/field.feMul": "crypto/ed25519/internal/edwards25519/field.feMulGeneric",
|
||||
"crypto/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",
|
||||
"crypto/sha256.block": "crypto/sha256.blockGeneric",
|
||||
"crypto/sha512.blockAMD64": "crypto/sha512.blockGeneric",
|
||||
|
||||
// AES
|
||||
"crypto/aes.decryptBlockAsm": "crypto/aes.decryptBlock",
|
||||
"crypto/aes.encryptBlockAsm": "crypto/aes.encryptBlock",
|
||||
|
||||
// math package
|
||||
"math.archHypot": "math.hypot",
|
||||
"math.archMax": "math.max",
|
||||
|
||||
+2
-2
@@ -135,7 +135,7 @@ func (b *builder) createChanBoundsCheck(elementSize uint64, bufSize llvm.Value,
|
||||
|
||||
// Calculate (^uintptr(0)) >> 1, which is the max value that fits in an
|
||||
// uintptr if uintptrs were signed.
|
||||
maxBufSize := llvm.ConstLShr(llvm.ConstNot(llvm.ConstInt(b.uintptrType, 0, false)), llvm.ConstInt(b.uintptrType, 1, false))
|
||||
maxBufSize := b.CreateLShr(llvm.ConstNot(llvm.ConstInt(b.uintptrType, 0, false)), llvm.ConstInt(b.uintptrType, 1, false), "")
|
||||
if elementSize > maxBufSize.ZExtValue() {
|
||||
b.addError(pos, fmt.Sprintf("channel element type is too big (%v bytes)", elementSize))
|
||||
return
|
||||
@@ -150,7 +150,7 @@ func (b *builder) createChanBoundsCheck(elementSize uint64, bufSize llvm.Value,
|
||||
|
||||
// Make sure maxBufSize has the same type as bufSize.
|
||||
if maxBufSize.Type() != bufSize.Type() {
|
||||
maxBufSize = llvm.ConstZExt(maxBufSize, bufSize.Type())
|
||||
maxBufSize = b.CreateZExt(maxBufSize, bufSize.Type(), "")
|
||||
}
|
||||
|
||||
// Do the check for a too large (or negative) buffer size.
|
||||
|
||||
+10
-2
@@ -56,6 +56,7 @@ type Config struct {
|
||||
MaxStackAlloc uint64
|
||||
NeedsStackObjects bool
|
||||
Debug bool // Whether to emit debug information in the LLVM module.
|
||||
PanicStrategy string
|
||||
}
|
||||
|
||||
// compilerContext contains function-independent data that should still be
|
||||
@@ -1855,6 +1856,13 @@ func (b *builder) createFunctionCall(instr *ssa.CallCommon) (llvm.Value, error)
|
||||
supportsRecover = 1
|
||||
}
|
||||
return llvm.ConstInt(b.ctx.Int1Type(), supportsRecover, false), nil
|
||||
case name == "runtime.panicStrategy":
|
||||
// These constants are defined in src/runtime/panic.go.
|
||||
panicStrategy := map[string]uint64{
|
||||
"print": 1, // panicStrategyPrint
|
||||
"trap": 2, // panicStrategyTrap
|
||||
}[b.Config.PanicStrategy]
|
||||
return llvm.ConstInt(b.ctx.Int8Type(), panicStrategy, false), nil
|
||||
case name == "runtime/interrupt.New":
|
||||
return b.createInterruptGlobal(instr)
|
||||
}
|
||||
@@ -2173,7 +2181,7 @@ func (b *builder) createExpr(expr ssa.Value) (llvm.Value, error) {
|
||||
return llvm.Value{}, b.makeError(expr.Pos(), "todo: indexaddr: "+ptrTyp.String())
|
||||
}
|
||||
|
||||
// Make sure index is at least the size of uintptr becuase getelementptr
|
||||
// Make sure index is at least the size of uintptr because getelementptr
|
||||
// assumes index is a signed integer.
|
||||
index = b.extendInteger(index, expr.Index.Type(), b.uintptrType)
|
||||
|
||||
@@ -2549,7 +2557,7 @@ func (b *builder) createBinOp(op token.Token, typ, ytyp types.Type, x, y llvm.Va
|
||||
sizeY := b.targetData.TypeAllocSize(y.Type())
|
||||
|
||||
// Check if the shift is bigger than the bit-width of the shifted value.
|
||||
// This is UB in LLVM, so it needs to be handled seperately.
|
||||
// This is UB in LLVM, so it needs to be handled separately.
|
||||
// The Go spec indirectly defines the result as 0.
|
||||
// Negative shifts are handled earlier, so we can treat y as unsigned.
|
||||
overshifted := b.CreateICmp(llvm.IntUGE, y, llvm.ConstInt(y.Type(), 8*sizeX, false), "shift.overflow")
|
||||
|
||||
@@ -124,16 +124,19 @@ func (c *compilerContext) pkgPathPtr(pkgpath string) llvm.Value {
|
||||
func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
|
||||
ms := c.program.MethodSets.MethodSet(typ)
|
||||
hasMethodSet := ms.Len() != 0
|
||||
if _, ok := typ.Underlying().(*types.Interface); ok {
|
||||
_, isInterface := typ.Underlying().(*types.Interface)
|
||||
if isInterface {
|
||||
hasMethodSet = false
|
||||
}
|
||||
|
||||
// As defined in https://pkg.go.dev/reflect#Type:
|
||||
// NumMethod returns the number of methods accessible using Method.
|
||||
// For a non-interface type, it returns the number of exported methods.
|
||||
// For an interface type, it returns the number of exported and unexported methods.
|
||||
var numMethods int
|
||||
if hasMethodSet {
|
||||
for i := 0; i < ms.Len(); i++ {
|
||||
if ms.At(i).Obj().Exported() {
|
||||
numMethods++
|
||||
}
|
||||
for i := 0; i < ms.Len(); i++ {
|
||||
if isInterface || ms.At(i).Obj().Exported() {
|
||||
numMethods++
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ func (b *builder) defineIntrinsicFunction() {
|
||||
b.createMemoryCopyImpl()
|
||||
case name == "runtime.memzero":
|
||||
b.createMemoryZeroImpl()
|
||||
case name == "runtime.stacksave":
|
||||
b.createStackSaveImpl()
|
||||
case name == "runtime.KeepAlive":
|
||||
b.createKeepAliveImpl()
|
||||
case strings.HasPrefix(name, "runtime/volatile.Load"):
|
||||
@@ -77,6 +79,14 @@ func (b *builder) createMemoryZeroImpl() {
|
||||
b.CreateRetVoid()
|
||||
}
|
||||
|
||||
// createStackSaveImpl creates a call to llvm.stacksave.p0 to read the current
|
||||
// stack pointer.
|
||||
func (b *builder) createStackSaveImpl() {
|
||||
b.createFunctionStart(true)
|
||||
sp := b.readStackPointer()
|
||||
b.CreateRet(sp)
|
||||
}
|
||||
|
||||
// Return the llvm.memset.p0.i8 function declaration.
|
||||
func (c *compilerContext) getMemsetFunc() llvm.Value {
|
||||
fnName := "llvm.memset.p0.i" + strconv.Itoa(c.uintptrType.IntTypeWidth())
|
||||
|
||||
+6
-2
@@ -451,10 +451,14 @@ func (c *compilerContext) isThumb() bool {
|
||||
// readStackPointer emits a LLVM intrinsic call that returns the current stack
|
||||
// pointer as an *i8.
|
||||
func (b *builder) readStackPointer() llvm.Value {
|
||||
stacksave := b.mod.NamedFunction("llvm.stacksave")
|
||||
name := "llvm.stacksave.p0"
|
||||
if llvmutil.Version() < 18 {
|
||||
name = "llvm.stacksave" // backwards compatibility with LLVM 17 and below
|
||||
}
|
||||
stacksave := b.mod.NamedFunction(name)
|
||||
if stacksave.IsNil() {
|
||||
fnType := llvm.FunctionType(b.dataPtrType, nil, false)
|
||||
stacksave = llvm.AddFunction(b.mod, "llvm.stacksave", fnType)
|
||||
stacksave = llvm.AddFunction(b.mod, name, fnType)
|
||||
}
|
||||
return b.CreateCall(stacksave.GlobalValueType(), stacksave, nil, "")
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Package llvmutil contains utility functions used across multiple compiler
|
||||
// packages. For example, they may be used by both the compiler pacakge and
|
||||
// packages. For example, they may be used by both the compiler package and
|
||||
// transformation packages.
|
||||
//
|
||||
// Normally, utility packages are avoided. However, in this case, the utility
|
||||
@@ -8,6 +8,9 @@
|
||||
package llvmutil
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"tinygo.org/x/go-llvm"
|
||||
)
|
||||
|
||||
@@ -28,7 +31,7 @@ func CreateEntryBlockAlloca(builder llvm.Builder, t llvm.Type, name string) llvm
|
||||
}
|
||||
|
||||
// CreateTemporaryAlloca creates a new alloca in the entry block and adds
|
||||
// lifetime start infromation in the IR signalling that the alloca won't be used
|
||||
// lifetime start information in the IR signalling that the alloca won't be used
|
||||
// before this point.
|
||||
//
|
||||
// This is useful for creating temporary allocas for intrinsics. Don't forget to
|
||||
@@ -173,7 +176,7 @@ func SplitBasicBlock(builder llvm.Builder, afterInst llvm.Value, insertAfter llv
|
||||
return newBlock
|
||||
}
|
||||
|
||||
// Append the given values to a global array like llvm.used. The global might
|
||||
// AppendToGlobal appends the given values to a global array like llvm.used. The global might
|
||||
// not exist yet. The values can be any pointer type, they will be cast to i8*.
|
||||
func AppendToGlobal(mod llvm.Module, globalName string, values ...llvm.Value) {
|
||||
// Read the existing values in the llvm.used array (if it exists).
|
||||
@@ -203,3 +206,13 @@ func AppendToGlobal(mod llvm.Module, globalName string, values ...llvm.Value) {
|
||||
used.SetInitializer(usedInitializer)
|
||||
used.SetLinkage(llvm.AppendingLinkage)
|
||||
}
|
||||
|
||||
// Return the LLVM major version.
|
||||
func Version() int {
|
||||
majorStr := strings.Split(llvm.Version, ".")[0]
|
||||
major, err := strconv.Atoi(majorStr)
|
||||
if err != nil {
|
||||
panic("unexpected error while parsing LLVM version: " + err.Error()) // should not happen
|
||||
}
|
||||
return major
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -81,11 +81,11 @@ entry:
|
||||
%select.send.value = alloca i32, align 4
|
||||
store i32 1, ptr %select.send.value, align 4
|
||||
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %select.states.alloca)
|
||||
store ptr %ch1, ptr %select.states.alloca, align 8
|
||||
store ptr %ch1, ptr %select.states.alloca, align 4
|
||||
%select.states.alloca.repack1 = getelementptr inbounds %runtime.chanSelectState, ptr %select.states.alloca, i32 0, i32 1
|
||||
store ptr %select.send.value, ptr %select.states.alloca.repack1, align 4
|
||||
%0 = getelementptr inbounds [2 x %runtime.chanSelectState], ptr %select.states.alloca, i32 0, i32 1
|
||||
store ptr %ch2, ptr %0, align 8
|
||||
store ptr %ch2, ptr %0, align 4
|
||||
%.repack3 = getelementptr inbounds [2 x %runtime.chanSelectState], ptr %select.states.alloca, i32 0, i32 1, i32 1
|
||||
store ptr null, ptr %.repack3, align 4
|
||||
%select.result = call { i32, i1 } @runtime.tryChanSelect(ptr undef, ptr nonnull %select.states.alloca, i32 2, i32 2, ptr undef) #4
|
||||
|
||||
+3
-3
@@ -25,7 +25,7 @@ entry:
|
||||
%deferPtr = alloca ptr, align 4
|
||||
store ptr null, ptr %deferPtr, align 4
|
||||
%deferframe.buf = alloca %runtime.deferFrame, align 4
|
||||
%0 = call ptr @llvm.stacksave()
|
||||
%0 = call ptr @llvm.stacksave.p0()
|
||||
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
|
||||
store i32 0, ptr %defer.alloca, align 4
|
||||
%defer.alloca.repack15 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1
|
||||
@@ -113,7 +113,7 @@ rundefers.end3: ; preds = %rundefers.loophead6
|
||||
}
|
||||
|
||||
; Function Attrs: nocallback nofree nosync nounwind willreturn
|
||||
declare ptr @llvm.stacksave() #3
|
||||
declare ptr @llvm.stacksave.p0() #3
|
||||
|
||||
declare void @runtime.setupDeferFrame(ptr dereferenceable_or_null(24), ptr, ptr) #2
|
||||
|
||||
@@ -136,7 +136,7 @@ entry:
|
||||
%deferPtr = alloca ptr, align 4
|
||||
store ptr null, ptr %deferPtr, align 4
|
||||
%deferframe.buf = alloca %runtime.deferFrame, align 4
|
||||
%0 = call ptr @llvm.stacksave()
|
||||
%0 = call ptr @llvm.stacksave.p0()
|
||||
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
|
||||
store i32 0, ptr %defer.alloca, align 4
|
||||
%defer.alloca.repack22 = getelementptr inbounds { i32, ptr }, ptr %defer.alloca, i32 0, i32 1
|
||||
|
||||
Vendored
+9
-9
@@ -16,9 +16,9 @@ target triple = "wasm32-unknown-wasi"
|
||||
@main.struct2 = hidden global ptr null, align 4
|
||||
@main.struct3 = hidden global ptr null, align 4
|
||||
@main.struct4 = hidden global ptr null, align 4
|
||||
@main.slice1 = hidden global { ptr, i32, i32 } zeroinitializer, align 8
|
||||
@main.slice2 = hidden global { ptr, i32, i32 } zeroinitializer, align 8
|
||||
@main.slice3 = hidden global { ptr, i32, i32 } zeroinitializer, align 8
|
||||
@main.slice1 = hidden global { ptr, i32, i32 } zeroinitializer, align 4
|
||||
@main.slice2 = hidden global { ptr, i32, i32 } zeroinitializer, align 4
|
||||
@main.slice3 = hidden global { ptr, i32, i32 } zeroinitializer, align 4
|
||||
@"runtime/gc.layout:62-2000000000000001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\01\00\00\00\00\00\00 " }
|
||||
@"runtime/gc.layout:62-0001" = linkonce_odr unnamed_addr constant { i32, [8 x i8] } { i32 62, [8 x i8] c"\01\00\00\00\00\00\00\00" }
|
||||
@"reflect/types.type:basic:complex128" = linkonce_odr constant { i8, ptr } { i8 80, ptr @"reflect/types.type:pointer:basic:complex128" }, align 4
|
||||
@@ -104,19 +104,19 @@ entry:
|
||||
%stackalloc = alloca i8, align 1
|
||||
%makeslice = call dereferenceable(5) ptr @runtime.alloc(i32 5, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr nonnull %stackalloc, ptr undef) #3
|
||||
store ptr %makeslice, ptr @main.slice1, align 8
|
||||
store ptr %makeslice, ptr @main.slice1, align 4
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 1), align 4
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 2), align 8
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice1, i32 0, i32 2), align 4
|
||||
%makeslice1 = call dereferenceable(20) ptr @runtime.alloc(i32 20, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice1, ptr nonnull %stackalloc, ptr undef) #3
|
||||
store ptr %makeslice1, ptr @main.slice2, align 8
|
||||
store ptr %makeslice1, ptr @main.slice2, align 4
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 1), align 4
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 2), align 8
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice2, i32 0, i32 2), align 4
|
||||
%makeslice3 = call dereferenceable(60) ptr @runtime.alloc(i32 60, ptr nonnull inttoptr (i32 71 to ptr), ptr undef) #3
|
||||
call void @runtime.trackPointer(ptr nonnull %makeslice3, ptr nonnull %stackalloc, ptr undef) #3
|
||||
store ptr %makeslice3, ptr @main.slice3, align 8
|
||||
store ptr %makeslice3, ptr @main.slice3, align 4
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 1), align 4
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 2), align 8
|
||||
store i32 5, ptr getelementptr inbounds ({ ptr, i32, i32 }, ptr @main.slice3, i32 0, i32 2), align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -9,7 +9,7 @@ target triple = "wasm32-unknown-wasi"
|
||||
@"reflect/types.type:basic:int" = linkonce_odr constant { i8, ptr } { i8 -62, ptr @"reflect/types.type:pointer:basic:int" }, align 4
|
||||
@"reflect/types.type:pointer:basic:int" = linkonce_odr constant { i8, i16, ptr } { i8 -43, i16 0, ptr @"reflect/types.type:basic:int" }, align 4
|
||||
@"reflect/types.type:pointer:named:error" = linkonce_odr constant { i8, i16, ptr } { i8 -43, i16 0, ptr @"reflect/types.type:named:error" }, align 4
|
||||
@"reflect/types.type:named:error" = linkonce_odr constant { i8, i16, ptr, ptr, ptr, [7 x i8] } { i8 116, i16 0, ptr @"reflect/types.type:pointer:named:error", ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", ptr @"reflect/types.type.pkgpath.empty", [7 x i8] c".error\00" }, align 4
|
||||
@"reflect/types.type:named:error" = linkonce_odr constant { i8, i16, ptr, ptr, ptr, [7 x i8] } { i8 116, i16 1, ptr @"reflect/types.type:pointer:named:error", ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}", ptr @"reflect/types.type.pkgpath.empty", [7 x i8] c".error\00" }, align 4
|
||||
@"reflect/types.type.pkgpath.empty" = linkonce_odr unnamed_addr constant [1 x i8] zeroinitializer, align 1
|
||||
@"reflect/types.type:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant { i8, ptr } { i8 84, ptr @"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" }, align 4
|
||||
@"reflect/types.type:pointer:interface:{Error:func:{}{basic:string}}" = linkonce_odr constant { i8, i16, ptr } { i8 -43, i16 0, ptr @"reflect/types.type:interface:{Error:func:{}{basic:string}}" }, align 4
|
||||
|
||||
Vendored
+2
-2
@@ -122,7 +122,7 @@ entry:
|
||||
br i1 %slice.maxcap, label %slice.throw, label %slice.next
|
||||
|
||||
slice.next: ; preds = %entry
|
||||
%makeslice.cap = shl i32 %len, 1
|
||||
%makeslice.cap = shl nuw i32 %len, 1
|
||||
%makeslice.buf = call ptr @runtime.alloc(i32 %makeslice.cap, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
||||
@@ -164,7 +164,7 @@ entry:
|
||||
br i1 %slice.maxcap, label %slice.throw, label %slice.next
|
||||
|
||||
slice.next: ; preds = %entry
|
||||
%makeslice.cap = shl i32 %len, 2
|
||||
%makeslice.cap = shl nuw i32 %len, 2
|
||||
%makeslice.buf = call ptr @runtime.alloc(i32 %makeslice.cap, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||
%0 = insertvalue { ptr, i32, i32 } undef, ptr %makeslice.buf, 0
|
||||
%1 = insertvalue { ptr, i32, i32 } %0, i32 %len, 1
|
||||
|
||||
Vendored
+4
-4
@@ -26,7 +26,7 @@ entry:
|
||||
%2 = insertvalue %main.hasPadding %1, i1 %s.b2, 2
|
||||
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
|
||||
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
|
||||
store %main.hasPadding %2, ptr %hashmap.key, align 8
|
||||
store %main.hasPadding %2, ptr %hashmap.key, align 4
|
||||
%3 = getelementptr inbounds i8, ptr %hashmap.key, i32 1
|
||||
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
||||
%4 = getelementptr inbounds i8, ptr %hashmap.key, i32 9
|
||||
@@ -59,7 +59,7 @@ entry:
|
||||
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
|
||||
store i32 5, ptr %hashmap.value, align 4
|
||||
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
|
||||
store %main.hasPadding %2, ptr %hashmap.key, align 8
|
||||
store %main.hasPadding %2, ptr %hashmap.key, align 4
|
||||
%3 = getelementptr inbounds i8, ptr %hashmap.key, i32 1
|
||||
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
||||
%4 = getelementptr inbounds i8, ptr %hashmap.key, i32 9
|
||||
@@ -80,7 +80,7 @@ entry:
|
||||
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
|
||||
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
|
||||
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
|
||||
store %main.hasPadding %s.elt, ptr %hashmap.key, align 8
|
||||
store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
|
||||
%hashmap.key.repack1 = getelementptr inbounds [2 x %main.hasPadding], ptr %hashmap.key, i32 0, i32 1
|
||||
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
|
||||
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4
|
||||
@@ -108,7 +108,7 @@ entry:
|
||||
store i32 5, ptr %hashmap.value, align 4
|
||||
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
|
||||
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
|
||||
store %main.hasPadding %s.elt, ptr %hashmap.key, align 8
|
||||
store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
|
||||
%hashmap.key.repack1 = getelementptr inbounds [2 x %main.hasPadding], ptr %hashmap.key, i32 0, i32 1
|
||||
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
|
||||
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4
|
||||
|
||||
+3
-2
@@ -51,6 +51,7 @@ func TestCorpus(t *testing.T) {
|
||||
if *testTarget != "" {
|
||||
target = *testTarget
|
||||
}
|
||||
isWASI := strings.HasPrefix(target, "wasi")
|
||||
|
||||
repos, err := loadRepos(*corpus)
|
||||
if err != nil {
|
||||
@@ -69,7 +70,7 @@ func TestCorpus(t *testing.T) {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if target == "wasi" && repo.SkipWASI {
|
||||
if isWASI && repo.SkipWASI {
|
||||
t.Skip("skip wasi")
|
||||
}
|
||||
if repo.Slow && testing.Short() {
|
||||
@@ -135,7 +136,7 @@ func TestCorpus(t *testing.T) {
|
||||
t.Run(dir.Pkg, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if target == "wasi" && dir.SkipWASI {
|
||||
if isWASI && dir.SkipWASI {
|
||||
t.Skip("skip wasi")
|
||||
}
|
||||
if dir.Slow && testing.Short() {
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
#
|
||||
# But you'll need a bit more to make TinyGo actually able to compile code:
|
||||
#
|
||||
# make llvm-source # fetch compiler-rt
|
||||
# git submodule update --init --recursive # fetch lots of other libraries and SVD files
|
||||
# make gen-device -j4 # build src/device/*/*.go files
|
||||
# make wasi-libc # build support for wasi/wasm
|
||||
# make llvm-source # fetch compiler-rt
|
||||
# git submodule update --init # fetch lots of other libraries and SVD files
|
||||
# make gen-device -j4 # build src/device/*/*.go files
|
||||
# make wasi-libc # build support for wasi/wasm
|
||||
#
|
||||
# With this, you should have an environment that can compile anything - except
|
||||
# for the Xtensa architecture (ESP8266/ESP32) because support for that lives in
|
||||
@@ -51,7 +51,6 @@
|
||||
go
|
||||
llvmPackages_17.llvm
|
||||
llvmPackages_17.libclang
|
||||
llvmPackages_17.libcxx
|
||||
# Additional dependencies needed at runtime, for building and/or
|
||||
# flashing.
|
||||
llvmPackages_17.lld
|
||||
@@ -78,7 +77,7 @@
|
||||
export MD5SUM=md5sum
|
||||
|
||||
# Ugly hack to make the Clang resources directory available.
|
||||
export GOFLAGS="\"-ldflags=-X github.com/tinygo-org/tinygo/goenv.clangResourceDir=${llvmPackages_17.clang.cc.lib}/lib/clang/17"\"
|
||||
export GOFLAGS="\"-ldflags=-X github.com/tinygo-org/tinygo/goenv.clangResourceDir=${llvmPackages_17.clang.cc.lib}/lib/clang/17\" -tags=llvm17"
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3,33 +3,45 @@ module github.com/tinygo-org/tinygo
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/aykevl/go-wasm v0.0.2-0.20220616010729-4a0a888aebdc
|
||||
github.com/aykevl/go-wasm v0.0.2-0.20240312204833-50275154210c
|
||||
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2
|
||||
github.com/chromedp/cdproto v0.0.0-20220113222801-0725d94bb6ee
|
||||
github.com/chromedp/chromedp v0.7.6
|
||||
github.com/client9/misspell v0.3.4
|
||||
github.com/gofrs/flock v0.8.1
|
||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
|
||||
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf
|
||||
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892
|
||||
github.com/mattn/go-colorable v0.1.8
|
||||
github.com/mattn/go-colorable v0.1.13
|
||||
github.com/mattn/go-tty v0.0.4
|
||||
github.com/mgechev/revive v1.3.7
|
||||
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3
|
||||
go.bug.st/serial v1.6.0
|
||||
golang.org/x/net v0.20.0
|
||||
golang.org/x/sys v0.16.0
|
||||
golang.org/x/tools v0.17.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
tinygo.org/x/go-llvm v0.0.0-20240106122909-c2c543540318
|
||||
tinygo.org/x/go-llvm v0.0.0-20240518103902-697964f2a9dc
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
||||
github.com/chavacava/garif v0.1.0 // indirect
|
||||
github.com/chromedp/sysutil v1.0.0 // indirect
|
||||
github.com/creack/goselect v0.1.2 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/fatih/structtag v1.2.0 // 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
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
)
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
github.com/aykevl/go-wasm v0.0.2-0.20220616010729-4a0a888aebdc h1:Yp49g+qqgQRPk/gcRSmAsXgnT16XPJ6Y5JM1poc6gYM=
|
||||
github.com/aykevl/go-wasm v0.0.2-0.20220616010729-4a0a888aebdc/go.mod h1:7sXyiaA0WtSogCu67R2252fQpVmJMh9JWJ9ddtGkpWw=
|
||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/aykevl/go-wasm v0.0.2-0.20240312204833-50275154210c h1:4T0Vj1UkGgcpkRrmn7SbokebnlfxJcMZPgWtOYACAAA=
|
||||
github.com/aykevl/go-wasm v0.0.2-0.20240312204833-50275154210c/go.mod h1:7sXyiaA0WtSogCu67R2252fQpVmJMh9JWJ9ddtGkpWw=
|
||||
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2 h1:oMCHnXa6CCCafdPDbMh/lWRhRByN0VFLvv+g+ayx1SI=
|
||||
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
||||
github.com/chavacava/garif v0.1.0 h1:2JHa3hbYf5D9dsgseMKAmc/MZ109otzgNFk5s87H9Pc=
|
||||
github.com/chavacava/garif v0.1.0/go.mod h1:XMyYCkEL58DF0oyW4qDjjnPWONs2HBqYKI+UIPD+Gww=
|
||||
github.com/chromedp/cdproto v0.0.0-20211126220118-81fa0469ad77/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
|
||||
github.com/chromedp/cdproto v0.0.0-20220113222801-0725d94bb6ee h1:+SFdIVfQpG0s0DHYzou0kgfE0n0ZjKPwbiRJsXrZegU=
|
||||
github.com/chromedp/cdproto v0.0.0-20220113222801-0725d94bb6ee/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
|
||||
@@ -9,9 +13,17 @@ github.com/chromedp/chromedp v0.7.6 h1:2juGaktzjwULlsn+DnvIZXFUckEp5xs+GOBroaea+
|
||||
github.com/chromedp/chromedp v0.7.6/go.mod h1:ayT4YU/MGAALNfOg9gNrpGSAdnU51PMx+FCeuT1iXzo=
|
||||
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
|
||||
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
|
||||
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
||||
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
|
||||
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
|
||||
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
|
||||
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
|
||||
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
|
||||
@@ -31,21 +43,43 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
|
||||
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892 h1:6J+qramlHVLmiBOgRiBOnQkno8uprqG6YFFQTt6uYIw=
|
||||
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892/go.mod h1:Pb6XcsXyropB9LNHhnqaknG/vEwYztLkQzVCHv8sQ3M=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-tty v0.0.4 h1:NVikla9X8MN0SQAqCYzpGyXv0jY7MNl3HOWD2dkle7E=
|
||||
github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3pxse28=
|
||||
github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517 h1:zpIH83+oKzcpryru8ceC6BxnoG8TBrhgAvRg8obzup0=
|
||||
github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
|
||||
github.com/mgechev/revive v1.3.7 h1:502QY0vQGe9KtYJ9FpxMz9rL+Fc/P13CI5POL4uHCcE=
|
||||
github.com/mgechev/revive v1.3.7/go.mod h1:RJ16jUbF0OWC3co/+XTxmFNgEpUPwnnA0BRllX2aDNA=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5 h1:1SoBaSPudixRecmlHXb/GxmaD3fLMtHIDN13QujwQuc=
|
||||
github.com/orisano/pixelmatch v0.0.0-20210112091706-4fa4c7ba91d5/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 h1:aQKxg3+2p+IFXXg97McgDGT5zcMrQoi0EICZs8Pgchs=
|
||||
github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
go.bug.st/serial v1.6.0 h1:mAbRGN4cKE2J5gMwsMHC2KQisdLRQssO9WSM+rbZJ8A=
|
||||
go.bug.st/serial v1.6.0/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE=
|
||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
||||
@@ -54,10 +88,10 @@ golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
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-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
@@ -68,6 +102,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
tinygo.org/x/go-llvm v0.0.0-20240106122909-c2c543540318 h1:4KjZvPtcN1UwobevcGbdzeinx0L1i8HDdJu84bu7NI8=
|
||||
tinygo.org/x/go-llvm v0.0.0-20240106122909-c2c543540318/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
tinygo.org/x/go-llvm v0.0.0-20240518103902-697964f2a9dc h1:TCzibFa4oLu+njEP3fnRUmZ+QQeb8BjtOwctgcjzL0k=
|
||||
tinygo.org/x/go-llvm v0.0.0-20240518103902-697964f2a9dc/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
// Version of TinyGo.
|
||||
// Update this value before release of new version of software.
|
||||
const version = "0.31.0"
|
||||
const version = "0.32.0-dev"
|
||||
|
||||
var (
|
||||
// This variable is set at build time using -ldflags parameters.
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
# Docker hub does a recursive clone, then checks the branch out,
|
||||
# so when a PR adds a submodule (or updates it), it fails.
|
||||
git submodule update --init --recursive
|
||||
git submodule update --init
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
//go:build tools
|
||||
|
||||
// Install linter versions specified in go.mod
|
||||
// See https://marcofranssen.nl/manage-go-tools-via-go-modules for idom
|
||||
package tools
|
||||
|
||||
import (
|
||||
_ "github.com/client9/misspell"
|
||||
_ "github.com/mgechev/revive"
|
||||
)
|
||||
+34
-9
@@ -427,7 +427,22 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
|
||||
if err != nil {
|
||||
return nil, mem, r.errorAt(inst, err)
|
||||
}
|
||||
methodSetPtr, err := mem.load(typecodePtr.addOffset(-int64(r.pointerSize)), r.pointerSize).asPointer(r)
|
||||
// typecodePtr always point to the numMethod field in the type
|
||||
// description struct. The methodSet, when present, comes right
|
||||
// before the numMethod field (the compiler doesn't generate
|
||||
// method sets for concrete types without methods).
|
||||
// Considering that the compiler doesn't emit interface type
|
||||
// asserts for interfaces with no methods (as the always succeed)
|
||||
// then if the offset is zero, this assert must always fail.
|
||||
if typecodePtr.offset() == 0 {
|
||||
locals[inst.localIndex] = literalValue{uint8(0)}
|
||||
break
|
||||
}
|
||||
typecodePtrOffset, err := typecodePtr.addOffset(-int64(r.pointerSize))
|
||||
if err != nil {
|
||||
return nil, mem, r.errorAt(inst, err)
|
||||
}
|
||||
methodSetPtr, err := mem.load(typecodePtrOffset, r.pointerSize).asPointer(r)
|
||||
if err != nil {
|
||||
return nil, mem, r.errorAt(inst, err)
|
||||
}
|
||||
@@ -473,7 +488,11 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
|
||||
if err != nil {
|
||||
return nil, mem, r.errorAt(inst, err)
|
||||
}
|
||||
methodSetPtr, err := mem.load(typecodePtr.addOffset(-int64(r.pointerSize)), r.pointerSize).asPointer(r)
|
||||
typecodePtrOffset, err := typecodePtr.addOffset(-int64(r.pointerSize))
|
||||
if err != nil {
|
||||
return nil, mem, r.errorAt(inst, err)
|
||||
}
|
||||
methodSetPtr, err := mem.load(typecodePtrOffset, r.pointerSize).asPointer(r)
|
||||
if err != nil {
|
||||
return nil, mem, r.errorAt(inst, err)
|
||||
}
|
||||
@@ -636,11 +655,11 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
|
||||
case llvm.GetElementPtr:
|
||||
// GetElementPtr does pointer arithmetic, changing the offset of the
|
||||
// pointer into the underlying object.
|
||||
var offset uint64
|
||||
var offset int64
|
||||
for i := 1; i < len(operands); i += 2 {
|
||||
index := operands[i].Uint()
|
||||
elementSize := operands[i+1].Uint()
|
||||
if int64(elementSize) < 0 {
|
||||
index := operands[i].Int()
|
||||
elementSize := operands[i+1].Int()
|
||||
if elementSize < 0 {
|
||||
// This is a struct field.
|
||||
offset += index
|
||||
} else {
|
||||
@@ -654,11 +673,14 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
|
||||
return nil, mem, r.errorAt(inst, err)
|
||||
}
|
||||
// GEP on fixed pointer value (for example, memory-mapped I/O).
|
||||
ptrValue := operands[0].Uint() + offset
|
||||
ptrValue := operands[0].Uint() + uint64(offset)
|
||||
locals[inst.localIndex] = makeLiteralInt(ptrValue, int(operands[0].len(r)*8))
|
||||
continue
|
||||
}
|
||||
ptr = ptr.addOffset(int64(offset))
|
||||
ptr, err = ptr.addOffset(int64(offset))
|
||||
if err != nil {
|
||||
return nil, mem, r.errorAt(inst, err)
|
||||
}
|
||||
locals[inst.localIndex] = ptr
|
||||
if r.debug {
|
||||
fmt.Fprintln(os.Stderr, indent+"gep:", operands, "->", ptr)
|
||||
@@ -756,7 +778,10 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent
|
||||
if inst.opcode == llvm.Add {
|
||||
// This likely means this is part of a
|
||||
// unsafe.Pointer(uintptr(ptr) + offset) pattern.
|
||||
lhsPtr = lhsPtr.addOffset(int64(rhs.Uint()))
|
||||
lhsPtr, err = lhsPtr.addOffset(int64(rhs.Uint()))
|
||||
if err != nil {
|
||||
return nil, mem, r.errorAt(inst, err)
|
||||
}
|
||||
locals[inst.localIndex] = lhsPtr
|
||||
} else if inst.opcode == llvm.Xor && rhs.Uint() == 0 {
|
||||
// Special workaround for strings.noescape, see
|
||||
|
||||
+3
-3
@@ -517,12 +517,12 @@ func (v pointerValue) offset() uint32 {
|
||||
// addOffset essentially does a GEP operation (pointer arithmetic): it adds the
|
||||
// offset to the pointer. It also checks that the offset doesn't overflow the
|
||||
// maximum offset size (which is 4GB).
|
||||
func (v pointerValue) addOffset(offset int64) pointerValue {
|
||||
func (v pointerValue) addOffset(offset int64) (pointerValue, error) {
|
||||
result := pointerValue{v.pointer + uint64(offset)}
|
||||
if checks && v.index() != result.index() {
|
||||
panic("interp: offset out of range")
|
||||
return result, fmt.Errorf("interp: offset %d out of range for object %v", offset, v)
|
||||
}
|
||||
return result
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (v pointerValue) len(r *runner) uint32 {
|
||||
|
||||
Vendored
+7
@@ -10,6 +10,8 @@ target triple = "x86_64--linux"
|
||||
@main.exposedValue1 = global i16 0
|
||||
@main.exposedValue2 = global i16 0
|
||||
@main.insertedValue = global {i8, i32, {float, {i64, i16}}} zeroinitializer
|
||||
@main.gepArray = global [8 x i8] zeroinitializer
|
||||
@main.negativeGEP = global ptr null
|
||||
|
||||
declare void @runtime.printint64(i64) unnamed_addr
|
||||
|
||||
@@ -88,6 +90,11 @@ entry:
|
||||
%agg2 = insertvalue {i8, i32, {float, {i64, i16}}} %agg, i64 5, 2, 1, 0
|
||||
store {i8, i32, {float, {i64, i16}}} %agg2, ptr @main.insertedValue
|
||||
|
||||
; negative GEP instruction
|
||||
%ngep1 = getelementptr [8 x i8], ptr @main.negativeGEP, i32 0, i32 5
|
||||
%ngep2 = getelementptr [8 x i8], ptr %ngep1, i32 0, i32 -3
|
||||
store ptr %ngep2, ptr @main.negativeGEP
|
||||
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
Vendored
+2
@@ -9,6 +9,8 @@ target triple = "x86_64--linux"
|
||||
@main.exposedValue1 = global i16 0
|
||||
@main.exposedValue2 = local_unnamed_addr global i16 0
|
||||
@main.insertedValue = local_unnamed_addr global { i8, i32, { float, { i64, i16 } } } zeroinitializer
|
||||
@main.gepArray = local_unnamed_addr global [8 x i8] zeroinitializer
|
||||
@main.negativeGEP = global ptr getelementptr inbounds (i8, ptr @main.negativeGEP, i64 2)
|
||||
|
||||
declare void @runtime.printint64(i64) unnamed_addr
|
||||
|
||||
|
||||
+1
-1
@@ -214,7 +214,7 @@ func listGorootMergeLinks(goroot, tinygoroot string, overrides map[string]bool)
|
||||
return merges, nil
|
||||
}
|
||||
|
||||
// needsSyscallPackage returns whether the syscall package should be overriden
|
||||
// needsSyscallPackage returns whether the syscall package should be overridden
|
||||
// with the TinyGo version. This is the case on some targets.
|
||||
func needsSyscallPackage(buildTags []string) bool {
|
||||
for _, tag := range buildTags {
|
||||
|
||||
+1
-1
@@ -430,7 +430,7 @@ func (p *Package) parseFiles() ([]*ast.File, error) {
|
||||
var files []*ast.File
|
||||
var fileErrs []error
|
||||
|
||||
// Parse all files (incuding CgoFiles).
|
||||
// Parse all files (including CgoFiles).
|
||||
parseFile := func(file string) {
|
||||
if !filepath.IsAbs(file) {
|
||||
file = filepath.Join(p.Dir, file)
|
||||
|
||||
@@ -285,7 +285,7 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
|
||||
// Tests are always run in the package directory.
|
||||
cmd.Dir = result.MainDir
|
||||
|
||||
// wasmtime is the default emulator used for `-target=wasi`. wasmtime
|
||||
// wasmtime is the default emulator used for `-target=wasip1`. wasmtime
|
||||
// is a WebAssembly runtime CLI with WASI enabled by default. However,
|
||||
// only stdio are allowed by default. For example, while STDOUT routes
|
||||
// to the host, other files don't. It also does not inherit environment
|
||||
@@ -1033,9 +1033,10 @@ func findFATMounts(options *compileopts.Options) ([]mountPoint, error) {
|
||||
if fstype != "vfat" {
|
||||
continue
|
||||
}
|
||||
fspath := strings.ReplaceAll(fields[1], "\\040", " ")
|
||||
points = append(points, mountPoint{
|
||||
name: filepath.Base(fields[1]),
|
||||
path: fields[1],
|
||||
name: filepath.Base(fspath),
|
||||
path: fspath,
|
||||
})
|
||||
}
|
||||
return points, nil
|
||||
@@ -1411,7 +1412,7 @@ func main() {
|
||||
gc := flag.String("gc", "", "garbage collector to use (none, leaking, conservative)")
|
||||
panicStrategy := flag.String("panic", "print", "panic strategy (print, trap)")
|
||||
scheduler := flag.String("scheduler", "", "which scheduler to use (none, tasks, asyncify)")
|
||||
serial := flag.String("serial", "", "which serial output to use (none, uart, usb)")
|
||||
serial := flag.String("serial", "", "which serial output to use (none, uart, usb, rtt)")
|
||||
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")
|
||||
var tags buildutil.TagsFlag
|
||||
|
||||
+68
-5
@@ -15,11 +15,13 @@ import (
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aykevl/go-wasm"
|
||||
"github.com/tinygo-org/tinygo/builder"
|
||||
"github.com/tinygo-org/tinygo/compileopts"
|
||||
"github.com/tinygo-org/tinygo/goenv"
|
||||
@@ -177,7 +179,7 @@ func TestBuild(t *testing.T) {
|
||||
})
|
||||
t.Run("WASI", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runPlatTests(optionsFromTarget("wasi", sema), tests, t)
|
||||
runPlatTests(optionsFromTarget("wasip1", sema), tests, t)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -190,7 +192,10 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
|
||||
t.Fatal("failed to load target spec:", err)
|
||||
}
|
||||
|
||||
isWebAssembly := options.Target == "wasi" || options.Target == "wasm" || (options.Target == "" && options.GOARCH == "wasm")
|
||||
// FIXME: this should really be:
|
||||
// isWebAssembly := strings.HasPrefix(spec.Triple, "wasm")
|
||||
isWASI := strings.HasPrefix(options.Target, "wasi")
|
||||
isWebAssembly := isWASI || strings.HasPrefix(options.Target, "wasm") || (options.Target == "" && strings.HasPrefix(options.GOARCH, "wasm"))
|
||||
|
||||
for _, name := range tests {
|
||||
if options.GOOS == "linux" && (options.GOARCH == "arm" || options.GOARCH == "386") {
|
||||
@@ -250,13 +255,13 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) {
|
||||
runTest("alias.go", options, t, nil, nil)
|
||||
})
|
||||
}
|
||||
if options.Target == "" || options.Target == "wasi" {
|
||||
if options.Target == "" || isWASI {
|
||||
t.Run("filesystem.go", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runTest("filesystem.go", options, t, nil, nil)
|
||||
})
|
||||
}
|
||||
if options.Target == "" || options.Target == "wasi" || options.Target == "wasm" {
|
||||
if options.Target == "" || options.Target == "wasm" || isWASI {
|
||||
t.Run("rand.go", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runTest("rand.go", options, t, nil, nil)
|
||||
@@ -404,6 +409,64 @@ func runTestWithConfig(name string, t *testing.T, options compileopts.Options, c
|
||||
}
|
||||
}
|
||||
|
||||
// Test WebAssembly files for certain properties.
|
||||
func TestWebAssembly(t *testing.T) {
|
||||
t.Parallel()
|
||||
type testCase struct {
|
||||
name string
|
||||
panicStrategy string
|
||||
imports []string
|
||||
}
|
||||
for _, tc := range []testCase{
|
||||
// Test whether there really are no imports when using -panic=trap. This
|
||||
// tests the bugfix for https://github.com/tinygo-org/tinygo/issues/4161.
|
||||
{name: "panic-default", imports: []string{"wasi_snapshot_preview1.fd_write"}},
|
||||
{name: "panic-trap", panicStrategy: "trap", imports: []string{}},
|
||||
} {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
tmpdir := t.TempDir()
|
||||
options := optionsFromTarget("wasi", sema)
|
||||
options.PanicStrategy = tc.panicStrategy
|
||||
config, err := builder.NewConfig(&options)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
result, err := builder.Build("testdata/trivialpanic.go", ".wasm", tmpdir, config)
|
||||
if err != nil {
|
||||
t.Fatal("failed to build binary:", err)
|
||||
}
|
||||
f, err := os.Open(result.Binary)
|
||||
if err != nil {
|
||||
t.Fatal("could not open output binary:", err)
|
||||
}
|
||||
defer f.Close()
|
||||
module, err := wasm.Parse(f)
|
||||
if err != nil {
|
||||
t.Fatal("could not parse output binary:", err)
|
||||
}
|
||||
|
||||
// Test the list of imports.
|
||||
if tc.imports != nil {
|
||||
var imports []string
|
||||
for _, section := range module.Sections {
|
||||
switch section := section.(type) {
|
||||
case *wasm.SectionImport:
|
||||
for _, symbol := range section.Entries {
|
||||
imports = append(imports, symbol.Module+"."+symbol.Field)
|
||||
}
|
||||
}
|
||||
}
|
||||
if !slices.Equal(imports, tc.imports) {
|
||||
t.Errorf("import list not as expected!\nexpected: %v\nactual: %v", tc.imports, imports)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestTest(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -432,7 +495,7 @@ func TestTest(t *testing.T) {
|
||||
|
||||
// Node/Wasmtime
|
||||
targ{"WASM", optionsFromTarget("wasm", sema)},
|
||||
targ{"WASI", optionsFromTarget("wasi", sema)},
|
||||
targ{"WASI", optionsFromTarget("wasip1", sema)},
|
||||
)
|
||||
}
|
||||
for _, targ := range targs {
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
ignoreGeneratedHeader = false
|
||||
severity = "warning"
|
||||
confidence = 0.8
|
||||
errorCode = 0
|
||||
warningCode = 0
|
||||
|
||||
# Enable these as we fix them
|
||||
[rule.blank-imports]
|
||||
Exclude=["src/os/file_other.go"]
|
||||
[rule.context-as-argument]
|
||||
[rule.context-keys-type]
|
||||
[rule.dot-imports]
|
||||
Exclude=["**/*_test.go"]
|
||||
[rule.error-return]
|
||||
[rule.error-strings]
|
||||
[rule.error-naming]
|
||||
[rule.exported]
|
||||
Exclude=["src/reflect/*.go"]
|
||||
[rule.increment-decrement]
|
||||
[rule.var-naming]
|
||||
Exclude=["src/os/*.go"]
|
||||
[rule.var-declaration]
|
||||
#[rule.package-comments]
|
||||
[rule.range]
|
||||
[rule.receiver-naming]
|
||||
[rule.time-naming]
|
||||
[rule.unexported-return]
|
||||
#[rule.indent-error-flow]
|
||||
[rule.errorf]
|
||||
#[rule.empty-block]
|
||||
[rule.superfluous-else]
|
||||
#[rule.unused-parameter]
|
||||
[rule.unreachable-code]
|
||||
Exclude=["src/reflect/visiblefields_test.go", "src/reflect/all_test.go"]
|
||||
#[rule.redefines-builtin-id]
|
||||
@@ -1,4 +1,4 @@
|
||||
//go:build linux && !baremetal && !wasi
|
||||
//go:build linux && !baremetal && !wasip1
|
||||
|
||||
// This implementation of crypto/rand uses the /dev/urandom pseudo-file to
|
||||
// generate random numbers.
|
||||
|
||||
@@ -57,7 +57,7 @@ func Count(b []byte, c byte) int {
|
||||
// Count the number of instances of a byte in a string.
|
||||
func CountString(s string, c byte) int {
|
||||
// Use a simple implementation, as there is no intrinsic that does this like we want.
|
||||
// Currently, the compiler does not generate zero-copy byte-string conversions, so this needs to be seperate from Count.
|
||||
// Currently, the compiler does not generate zero-copy byte-string conversions, so this needs to be separate from Count.
|
||||
n := 0
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] == c {
|
||||
@@ -216,7 +216,7 @@ func HashStrRev[T string | []byte](sep T) (uint32, uint32) {
|
||||
}
|
||||
|
||||
// IndexRabinKarpBytes uses the Rabin-Karp search algorithm to return the index of the
|
||||
// first occurence of substr in s, or -1 if not present.
|
||||
// first occurrence of substr in s, or -1 if not present.
|
||||
//
|
||||
// This function was removed in Go 1.22.
|
||||
func IndexRabinKarpBytes(s, sep []byte) int {
|
||||
|
||||
@@ -44,7 +44,7 @@ func Current() *Task {
|
||||
// This function may only be called when running on a goroutine stack, not when running on the system stack or in an interrupt.
|
||||
func Pause() {
|
||||
// Check whether the canary (the lowest address of the stack) is still
|
||||
// valid. If it is not, a stack overflow has occured.
|
||||
// valid. If it is not, a stack overflow has occurred.
|
||||
if *currentTask.state.canaryPtr != stackCanary {
|
||||
runtimePanic("goroutine stack overflow")
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ tinygo_startTask:
|
||||
// After return, exit this goroutine. This is a tail call.
|
||||
#if __AVR_ARCH__ == 2 || __AVR_ARCH__ == 25
|
||||
// Small memory devices (≤8kB flash) that do not have the long call
|
||||
// instruction availble will need to use rcall instead.
|
||||
// instruction available will need to use rcall instead.
|
||||
// Note that they will probably not be able to run more than the main
|
||||
// goroutine anyway, but this file is compiled for all AVRs so it needs to
|
||||
// compile at least.
|
||||
|
||||
@@ -78,7 +78,7 @@ tinygo_swapTask:
|
||||
// Switch to the new stack pointer (newStack).
|
||||
mov.n sp, a2
|
||||
|
||||
// Load a0, which is the previous return addres from before the previous
|
||||
// Load a0, which is the previous return address from before the previous
|
||||
// switch or the constructed return address to tinygo_startTask. This
|
||||
// register also stores the parent register window.
|
||||
l32i.n a0, sp, 0
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
//go:build adafruit_esp32_feather_v2
|
||||
|
||||
package machine
|
||||
|
||||
const GPIO20 Pin = 20
|
||||
|
||||
const (
|
||||
IO0 = GPIO0
|
||||
IO2 = GPIO2
|
||||
IO4 = GPIO4
|
||||
IO5 = GPIO5
|
||||
IO7 = GPIO7
|
||||
IO8 = GPIO8
|
||||
IO12 = GPIO12
|
||||
IO13 = GPIO13
|
||||
IO14 = GPIO14
|
||||
IO15 = GPIO15
|
||||
IO19 = GPIO19
|
||||
IO20 = GPIO20
|
||||
IO21 = GPIO21
|
||||
IO22 = GPIO22
|
||||
IO25 = GPIO25
|
||||
IO26 = GPIO26
|
||||
IO27 = GPIO27
|
||||
IO32 = GPIO32
|
||||
IO33 = GPIO33
|
||||
IO34 = GPIO34
|
||||
IO35 = GPIO35
|
||||
IO36 = GPIO36
|
||||
IO37 = GPIO37
|
||||
IO38 = GPIO38
|
||||
IO39 = GPIO39
|
||||
)
|
||||
|
||||
// Digital pins
|
||||
const (
|
||||
D12 = IO12
|
||||
D13 = IO13
|
||||
D14 = IO14
|
||||
D15 = IO15
|
||||
D27 = IO27
|
||||
D32 = IO32
|
||||
D33 = IO33
|
||||
D37 = IO37
|
||||
)
|
||||
|
||||
// Analog pins
|
||||
const (
|
||||
A0 = IO26
|
||||
A1 = IO25
|
||||
A2 = IO34
|
||||
A3 = IO39
|
||||
A4 = IO36
|
||||
A5 = IO4
|
||||
)
|
||||
|
||||
// Built-in LEDs and Button
|
||||
const (
|
||||
WS2812 = IO0
|
||||
NEOPIXEL = WS2812
|
||||
NEOPIXEL_I2C_POWER = IO2
|
||||
LED = IO13
|
||||
BUTTON = IO38
|
||||
)
|
||||
|
||||
// SPI pins
|
||||
const (
|
||||
SPI_SCK_PIN = IO5
|
||||
SPI_MOSI_PIN = IO19
|
||||
SPI_MISO_PIN = IO21
|
||||
|
||||
SPI_SDO_PIN = SPI_MOSI_PIN
|
||||
SPI_SDI_PIN = SPI_MISO_PIN
|
||||
|
||||
// Silk labels
|
||||
SCK = SPI_SCK_PIN
|
||||
MO = SPI_MOSI_PIN
|
||||
MI = SPI_MISO_PIN
|
||||
)
|
||||
|
||||
// I2C pins
|
||||
const (
|
||||
I2C_SCL_PIN = IO20
|
||||
I2C_SDA_PIN = IO22
|
||||
|
||||
// Silk labels
|
||||
SCL = I2C_SCL_PIN
|
||||
SDA = I2C_SDA_PIN
|
||||
)
|
||||
|
||||
// ADC pins
|
||||
const (
|
||||
ADC1_0 = IO36
|
||||
ADC1_1 = IO37
|
||||
ADC1_2 = IO38
|
||||
ADC1_3 = IO39
|
||||
ADC1_4 = IO32
|
||||
ADC1_5 = IO33
|
||||
ADC1_6 = IO34
|
||||
ADC1_7 = IO35
|
||||
|
||||
ADC2_0 = IO4
|
||||
ADC2_1 = IO0
|
||||
ADC2_2 = IO2
|
||||
ADC2_3 = IO15
|
||||
ADC2_4 = IO13
|
||||
ADC2_5 = IO12
|
||||
ADC2_6 = IO14
|
||||
ADC2_7 = IO27
|
||||
ADC2_8 = IO25
|
||||
ADC2_9 = IO26
|
||||
)
|
||||
|
||||
// UART pins
|
||||
const (
|
||||
UART_TX_PIN = IO19
|
||||
UART_RX_PIN = IO22
|
||||
|
||||
UART2_TX_PIN = IO8
|
||||
UART2_RX_PIN = IO7
|
||||
|
||||
// Silk labels
|
||||
RX = UART2_RX_PIN
|
||||
TX = UART2_TX_PIN
|
||||
)
|
||||
@@ -2,11 +2,6 @@
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/rp"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// GPIO pins
|
||||
const (
|
||||
GP0 Pin = GPIO0
|
||||
@@ -77,28 +72,8 @@ const (
|
||||
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 = "AE-RP2040"
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
//go:build badger2040_w
|
||||
|
||||
// This contains the pin mappings for the Badger 2040 W board.
|
||||
//
|
||||
// For more information, see: https://shop.pimoroni.com/products/badger-2040-w
|
||||
// Also
|
||||
// - Badger 2040 W schematic: https://cdn.shopify.com/s/files/1/0174/1800/files/badger_w_schematic.pdf?v=1675859004
|
||||
package machine
|
||||
|
||||
const (
|
||||
LED Pin = GPIO22
|
||||
|
||||
BUTTON_A Pin = GPIO12
|
||||
BUTTON_B Pin = GPIO13
|
||||
BUTTON_C Pin = GPIO14
|
||||
BUTTON_UP Pin = GPIO15
|
||||
BUTTON_DOWN Pin = GPIO11
|
||||
BUTTON_USER Pin = NoPin // Not available on Badger 2040 W
|
||||
|
||||
EPD_BUSY_PIN Pin = GPIO26
|
||||
EPD_RESET_PIN Pin = GPIO21
|
||||
EPD_DC_PIN Pin = GPIO20
|
||||
EPD_CS_PIN Pin = GPIO17
|
||||
EPD_SCK_PIN Pin = GPIO18
|
||||
EPD_SDO_PIN Pin = GPIO19
|
||||
|
||||
VBUS_DETECT Pin = GPIO24
|
||||
VREF_POWER Pin = GPIO27
|
||||
VREF_1V24 Pin = GPIO28
|
||||
VBAT_SENSE Pin = GPIO29
|
||||
ENABLE_3V3 Pin = GPIO10
|
||||
|
||||
BATTERY = VBAT_SENSE
|
||||
RTC_ALARM = GPIO8
|
||||
)
|
||||
|
||||
// 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 = GPIO18
|
||||
SPI0_SDO_PIN Pin = GPIO19
|
||||
SPI0_SDI_PIN Pin = GPIO16
|
||||
|
||||
SPI1_SCK_PIN Pin = NoPin
|
||||
SPI1_SDO_PIN Pin = NoPin
|
||||
SPI1_SDI_PIN Pin = NoPin
|
||||
)
|
||||
|
||||
// QSPI pins¿?
|
||||
const (
|
||||
/*
|
||||
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
|
||||
*/
|
||||
)
|
||||
|
||||
// Onboard crystal oscillator frequency, in MHz.
|
||||
const (
|
||||
xoscFreq = 12 // MHz
|
||||
)
|
||||
|
||||
// USB CDC identifiers
|
||||
const (
|
||||
usb_STRING_PRODUCT = "Badger 2040 W"
|
||||
usb_STRING_MANUFACTURER = "Pimoroni"
|
||||
)
|
||||
|
||||
var (
|
||||
usb_VID uint16 = 0x2e8a
|
||||
usb_PID uint16 = 0x0003
|
||||
)
|
||||
|
||||
// UART pins
|
||||
const (
|
||||
UART0_TX_PIN = GPIO0
|
||||
UART0_RX_PIN = GPIO1
|
||||
UART_TX_PIN = UART0_TX_PIN
|
||||
UART_RX_PIN = UART0_RX_PIN
|
||||
)
|
||||
|
||||
var DefaultUART = UART0
|
||||
@@ -1,17 +1,12 @@
|
||||
//go:build badger2040
|
||||
|
||||
// This contains the pin mappings for the Badger 2040 Connect board.
|
||||
// This contains the pin mappings for the Badger 2040 board.
|
||||
//
|
||||
// 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 (
|
||||
"device/rp"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
const (
|
||||
LED Pin = GPIO25
|
||||
|
||||
@@ -30,8 +25,12 @@ const (
|
||||
EPD_SDO_PIN Pin = GPIO19
|
||||
|
||||
VBUS_DETECT Pin = GPIO24
|
||||
BATTERY Pin = GPIO29
|
||||
VREF_POWER Pin = GPIO27
|
||||
VREF_1V24 Pin = GPIO28
|
||||
VBAT_SENSE Pin = GPIO29
|
||||
ENABLE_3V3 Pin = GPIO10
|
||||
|
||||
BATTERY = VBAT_SENSE
|
||||
)
|
||||
|
||||
// I2C pins
|
||||
@@ -92,17 +91,4 @@ const (
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/rp"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
const (
|
||||
LED = GPIO24
|
||||
|
||||
@@ -84,28 +79,8 @@ const (
|
||||
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 = "Challenger 2040 LoRa"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
package machine
|
||||
|
||||
const HasLowFrequencyCrystal = true
|
||||
const HasLowFrequencyCrystal = false
|
||||
|
||||
// GPIO Pins
|
||||
const (
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/rp"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// Onboard crystal oscillator frequency, in MHz.
|
||||
const xoscFreq = 12 // MHz
|
||||
|
||||
@@ -73,28 +68,8 @@ const (
|
||||
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 = "Feather RP2040"
|
||||
|
||||
@@ -5,11 +5,6 @@
|
||||
// For more information, see: https://gopherbadge.com/
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/rp"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
const (
|
||||
/*ADC0 Pin = GPIO26
|
||||
ADC1 Pin = GPIO27
|
||||
@@ -92,17 +87,4 @@ const (
|
||||
UART_RX_PIN = UART0_RX_PIN
|
||||
)
|
||||
|
||||
// UART on the RP2040
|
||||
var (
|
||||
UART1 = &_UART1
|
||||
_UART1 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: rp.UART1,
|
||||
}
|
||||
)
|
||||
|
||||
var DefaultUART = UART1
|
||||
|
||||
func init() {
|
||||
UART1.Interrupt = interrupt.New(rp.IRQ_UART1_IRQ, _UART1.handleInterrupt)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/rp"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// Onboard crystal oscillator frequency, in MHz.
|
||||
const xoscFreq = 12 // MHz
|
||||
|
||||
@@ -75,28 +70,8 @@ const (
|
||||
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 = "KB2040"
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
//go:build m5paper
|
||||
|
||||
package machine
|
||||
|
||||
const (
|
||||
IO0 = GPIO0
|
||||
IO1 = GPIO1
|
||||
IO2 = GPIO2
|
||||
IO3 = GPIO3
|
||||
IO4 = GPIO4
|
||||
IO5 = GPIO5
|
||||
IO6 = GPIO6
|
||||
IO7 = GPIO7
|
||||
IO8 = GPIO8
|
||||
IO9 = GPIO9
|
||||
IO10 = GPIO10
|
||||
IO11 = GPIO11
|
||||
IO12 = GPIO12
|
||||
IO13 = GPIO13
|
||||
IO14 = GPIO14
|
||||
IO15 = GPIO15
|
||||
IO16 = GPIO16
|
||||
IO17 = GPIO17
|
||||
IO18 = GPIO18
|
||||
IO19 = GPIO19
|
||||
IO21 = GPIO21
|
||||
IO22 = GPIO22
|
||||
IO23 = GPIO23
|
||||
IO25 = GPIO25
|
||||
IO26 = GPIO26
|
||||
IO27 = GPIO27
|
||||
IO32 = GPIO32
|
||||
IO33 = GPIO33
|
||||
IO34 = GPIO34
|
||||
IO35 = GPIO35
|
||||
IO36 = GPIO36
|
||||
IO37 = GPIO37
|
||||
IO38 = GPIO38
|
||||
IO39 = GPIO39
|
||||
)
|
||||
|
||||
const (
|
||||
POWER_PIN = IO2
|
||||
EXT_POWER_PIN = IO5
|
||||
EPD_POWER_PIN = IO23
|
||||
|
||||
// Buttons
|
||||
BUTTON_RIGHT = IO39
|
||||
BUTTON_PUSH = IO38
|
||||
BUTTON_LEFT = IO37
|
||||
BUTTON = BUTTON_PUSH
|
||||
|
||||
// Touch Screen Interrupt
|
||||
TOUCH_INT = IO36
|
||||
)
|
||||
|
||||
// SPI pins
|
||||
const (
|
||||
SPI0_SCK_PIN = IO14
|
||||
SPI0_SDO_PIN = IO12
|
||||
SPI0_SDI_PIN = IO13
|
||||
|
||||
// EPD (IT8951)
|
||||
EPD_SCK_PIN = SPI0_SCK_PIN
|
||||
EPD_SDO_PIN = SPI0_SDO_PIN
|
||||
EPD_SDI_PIN = SPI0_SDI_PIN
|
||||
EPD_CS_PIN = IO15
|
||||
EPD_BUSY_PIN = IO27
|
||||
|
||||
// SD CARD
|
||||
SDCARD_SCK_PIN = SPI0_SCK_PIN
|
||||
SDCARD_SDO_PIN = SPI0_SDO_PIN
|
||||
SDCARD_SDI_PIN = SPI0_SDI_PIN
|
||||
SDCARD_CS_PIN = IO4
|
||||
)
|
||||
|
||||
// I2C pins
|
||||
const (
|
||||
SDA0_PIN = IO21
|
||||
SCL0_PIN = IO22
|
||||
|
||||
SDA_PIN = SDA0_PIN
|
||||
SCL_PIN = SCL0_PIN
|
||||
|
||||
I2C_TEMP_ADDR = 0x44 // temperature sensor (SHT30)
|
||||
I2C_CLOCK_ADDR = 0x51 // real time clock (BM8563)
|
||||
I2C_TOUCH_ADDR = 0x5D // touch screen controller (GT911)
|
||||
)
|
||||
|
||||
// ADC pins
|
||||
const (
|
||||
ADC1 Pin = IO35
|
||||
ADC2 Pin = IO36
|
||||
|
||||
BATTERY_ADC_PIN = ADC1
|
||||
)
|
||||
|
||||
// DAC pins
|
||||
const (
|
||||
DAC1 Pin = IO25
|
||||
DAC2 Pin = IO26
|
||||
)
|
||||
|
||||
// UART pins
|
||||
const (
|
||||
// UART0 (CP2104)
|
||||
UART0_TX_PIN = IO1
|
||||
UART0_RX_PIN = IO3
|
||||
|
||||
UART_TX_PIN = UART0_TX_PIN
|
||||
UART_RX_PIN = UART0_RX_PIN
|
||||
)
|
||||
@@ -2,11 +2,6 @@
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/rp"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
const (
|
||||
NeopixelCount = 12
|
||||
|
||||
@@ -78,21 +73,8 @@ const (
|
||||
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)
|
||||
}
|
||||
|
||||
// USB identifiers
|
||||
const (
|
||||
usb_STRING_PRODUCT = "MacroPad RP2040"
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
// SoftDevice (s140v7) must be flashed first to enable use of bluetooth on this board.
|
||||
// See https://github.com/tinygo-org/bluetooth
|
||||
//
|
||||
// SoftDevice overwrites original bootloader and flashing method described above is not avalable anymore.
|
||||
// SoftDevice overwrites original bootloader and flashing method described above is not available anymore.
|
||||
// Instead, please use debug probe and flash your code with "nano-33-ble-s140v7" target.
|
||||
package machine
|
||||
|
||||
|
||||
@@ -11,11 +11,6 @@
|
||||
// - Nano RP2040 Connect technical reference: https://docs.arduino.cc/tutorials/nano-rp2040-connect/rp2040-01-technical-reference
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/rp"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// Digital Pins
|
||||
const (
|
||||
D2 Pin = GPIO25
|
||||
@@ -125,27 +120,7 @@ const (
|
||||
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,
|
||||
}
|
||||
|
||||
// UART_NINA on the Arduino Nano RP2040 connects to the NINA HCI.
|
||||
UART_NINA = UART1
|
||||
)
|
||||
// UART_NINA on the Arduino Nano RP2040 connects to the NINA HCI.
|
||||
var UART_NINA = 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)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
//go:build nucleol476rg
|
||||
|
||||
// Schematic: https://www.st.com/resource/en/user_manual/um1724-stm32-nucleo64-boards-mb1136-stmicroelectronics.pdf
|
||||
// Datasheet: https://www.st.com/resource/en/datasheet/stm32l476je.pdf
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/stm32"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
const (
|
||||
// Arduino Pins
|
||||
A0 = PA0
|
||||
A1 = PA1
|
||||
A2 = PA4
|
||||
A3 = PB0
|
||||
A4 = PC1
|
||||
A5 = PC0
|
||||
|
||||
D0 = PA3
|
||||
D1 = PA2
|
||||
D2 = PA10
|
||||
D3 = PB3
|
||||
D4 = PB5
|
||||
D5 = PB4
|
||||
D6 = PB10
|
||||
D7 = PA8
|
||||
D8 = PA9
|
||||
D9 = PC7
|
||||
D10 = PB6
|
||||
D11 = PA7
|
||||
D12 = PA6
|
||||
D13 = PA5
|
||||
D14 = PB9
|
||||
D15 = PB8
|
||||
)
|
||||
|
||||
// User LD2: the green LED is a user LED connected to ARDUINO® signal D13 corresponding
|
||||
// to STM32 I/O PA5 (pin 21) or PB13 (pin 34) depending on the STM32 target.
|
||||
const (
|
||||
LED = LED_BUILTIN
|
||||
LED_BUILTIN = LED_GREEN
|
||||
LED_GREEN = PA5
|
||||
)
|
||||
|
||||
const (
|
||||
// This board does not have a user button, so
|
||||
// use first GPIO pin by default
|
||||
BUTTON = PA0
|
||||
)
|
||||
|
||||
const (
|
||||
// UART pins
|
||||
// PA2 and PA3 are connected to the ST-Link Virtual Com Port (VCP)
|
||||
UART_TX_PIN = PA2
|
||||
UART_RX_PIN = PA3
|
||||
|
||||
// I2C pins
|
||||
// With default solder bridge settings:
|
||||
// PB8 / Arduino D5 / CN3 Pin 8 is SCL
|
||||
// PB7 / Arduino D4 / CN3 Pin 7 is SDA
|
||||
I2C0_SCL_PIN = PB8
|
||||
I2C0_SDA_PIN = PB9
|
||||
|
||||
// SPI pins
|
||||
SPI1_SCK_PIN = PA5
|
||||
SPI1_SDI_PIN = PA6
|
||||
SPI1_SDO_PIN = PA7
|
||||
SPI0_SCK_PIN = SPI1_SCK_PIN
|
||||
SPI0_SDI_PIN = SPI1_SDI_PIN
|
||||
SPI0_SDO_PIN = SPI1_SDO_PIN
|
||||
)
|
||||
|
||||
var (
|
||||
// USART2 is the hardware serial port connected to the onboard ST-LINK
|
||||
// debugger to be exposed as virtual COM port over USB on Nucleo boards.
|
||||
UART1 = &_UART1
|
||||
_UART1 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: stm32.USART2,
|
||||
TxAltFuncSelector: AF7_USART1_2_3,
|
||||
RxAltFuncSelector: AF7_USART1_2_3,
|
||||
}
|
||||
DefaultUART = UART1
|
||||
|
||||
// I2C1 is documented, alias to I2C0 as well
|
||||
I2C1 = &I2C{
|
||||
Bus: stm32.I2C1,
|
||||
AltFuncSelector: AF4_I2C1_2_3,
|
||||
}
|
||||
I2C0 = I2C1
|
||||
|
||||
// SPI1 is documented, alias to SPI0 as well
|
||||
SPI1 = &SPI{
|
||||
Bus: stm32.SPI1,
|
||||
AltFuncSelector: AF5_SPI1_2,
|
||||
}
|
||||
SPI0 = SPI1
|
||||
)
|
||||
|
||||
func init() {
|
||||
UART1.Interrupt = interrupt.New(stm32.IRQ_USART2, _UART1.handleInterrupt)
|
||||
}
|
||||
@@ -2,11 +2,6 @@
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/rp"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// GPIO pins
|
||||
const (
|
||||
GP0 Pin = GPIO0
|
||||
@@ -79,28 +74,8 @@ const (
|
||||
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 = "Pico"
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/rp"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// Onboard crystal oscillator frequency, in MHz.
|
||||
const xoscFreq = 12 // MHz
|
||||
|
||||
@@ -84,28 +79,8 @@ const (
|
||||
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"
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/rp"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// Onboard crystal oscillator frequency, in MHz.
|
||||
const xoscFreq = 12 // MHz
|
||||
|
||||
@@ -51,7 +46,11 @@ const (
|
||||
A3 = GPIO29
|
||||
)
|
||||
|
||||
const LED = GPIO25
|
||||
// Onboard LEDs
|
||||
const (
|
||||
LED = GPIO25
|
||||
WS2812 = GPIO8
|
||||
)
|
||||
|
||||
// I2C Pins.
|
||||
const (
|
||||
@@ -90,21 +89,8 @@ const (
|
||||
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)
|
||||
}
|
||||
|
||||
// USB identifiers
|
||||
const (
|
||||
usb_STRING_PRODUCT = "Thing Plus RP2040"
|
||||
|
||||
@@ -5,11 +5,6 @@
|
||||
// https://thumby.us/
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/rp"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
const (
|
||||
THUMBY_SCK_PIN = I2C1_SDA_PIN
|
||||
THUMBY_SDA_PIN = I2C1_SCL_PIN
|
||||
@@ -78,17 +73,4 @@ const (
|
||||
UART_RX_PIN = UART0_RX_PIN
|
||||
)
|
||||
|
||||
// UART on the Thumby
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -7,11 +7,6 @@
|
||||
// - 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
|
||||
|
||||
@@ -87,17 +82,4 @@ const (
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -7,11 +7,6 @@
|
||||
// - https://www.waveshare.com/wiki/RP2040-Zero
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/rp"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// Digital Pins
|
||||
const (
|
||||
D0 Pin = GPIO0
|
||||
@@ -57,6 +52,7 @@ const (
|
||||
// Onboard LEDs
|
||||
const (
|
||||
NEOPIXEL = GPIO16
|
||||
WS2812 = GPIO16
|
||||
)
|
||||
|
||||
// I2C pins
|
||||
@@ -94,27 +90,8 @@ const (
|
||||
UART1_RX_PIN = GPIO9
|
||||
)
|
||||
|
||||
// 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 CDC identifiers
|
||||
const (
|
||||
usb_STRING_PRODUCT = "RP2040-Zero"
|
||||
|
||||
@@ -7,11 +7,6 @@
|
||||
// - https://wiki.seeedstudio.com/XIAO-RP2040/
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/rp"
|
||||
"runtime/interrupt"
|
||||
)
|
||||
|
||||
// Digital Pins
|
||||
const (
|
||||
D0 Pin = GPIO26
|
||||
@@ -81,21 +76,8 @@ const (
|
||||
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)
|
||||
}
|
||||
|
||||
// USB CDC identifiers
|
||||
const (
|
||||
usb_STRING_PRODUCT = "XIAO RP2040"
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
//go:build atmega || nrf || sam || stm32 || fe310 || k210 || rp2040 || mimxrt1062 || (esp32c3 && !m5stamp_c3)
|
||||
//go:build !baremetal || atmega || nrf || sam || stm32 || fe310 || k210 || rp2040 || mimxrt1062 || (esp32c3 && !m5stamp_c3) || esp32
|
||||
|
||||
package machine
|
||||
|
||||
|
||||
@@ -1304,7 +1304,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
|
||||
return byte(spi.Bus.DATA.Get()), nil
|
||||
}
|
||||
|
||||
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read
|
||||
// Tx handles read/write operation for SPI interface. Since SPI is a synchronous write/read
|
||||
// interface, there must always be the same number of bytes written as bytes read.
|
||||
// The Tx method knows about this, and offers a few different ways of calling it.
|
||||
//
|
||||
@@ -1459,7 +1459,7 @@ func (tcc *TCC) Configure(config PWMConfig) error {
|
||||
for tcc.timer().SYNCBUSY.Get() != 0 {
|
||||
}
|
||||
|
||||
// Return any error that might have occured in the tcc.setPeriod call.
|
||||
// Return any error that might have occurred in the tcc.setPeriod call.
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1606,7 +1606,7 @@ func (tcc *TCC) Counter() uint32 {
|
||||
return tcc.timer().COUNT.Get()
|
||||
}
|
||||
|
||||
// Some constans to make pinTimerMapping below easier to read.
|
||||
// Some constants to make pinTimerMapping below easier to read.
|
||||
const (
|
||||
pinTCC0 = 1
|
||||
pinTCC1 = 2
|
||||
@@ -1657,7 +1657,7 @@ var pinTimerMapping = [...]uint8{
|
||||
PB30 / 2: pinTCC0Ch0 | pinTCC1Ch2<<4,
|
||||
}
|
||||
|
||||
// findPinPadMapping returns the pin mode (PinTCC or PinTCCAlt) and the channel
|
||||
// findPinTimerMapping returns the pin mode (PinTCC or PinTCCAlt) and the channel
|
||||
// number for a given timer and pin. A zero PinMode is returned if no mapping
|
||||
// could be found.
|
||||
func findPinTimerMapping(timer uint8, pin Pin) (PinMode, uint8) {
|
||||
@@ -1759,7 +1759,7 @@ func (tcc *TCC) Set(channel uint8, value uint32) {
|
||||
}
|
||||
}
|
||||
|
||||
// EnterBootloader should perform a system reset in preperation
|
||||
// EnterBootloader should perform a system reset in preparation
|
||||
// to switch to the bootloader to flash new firmware.
|
||||
func EnterBootloader() {
|
||||
arm.DisableInterrupts()
|
||||
|
||||
@@ -1587,7 +1587,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
|
||||
return byte(spi.Bus.DATA.Get()), nil
|
||||
}
|
||||
|
||||
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read
|
||||
// Tx handles read/write operation for SPI interface. Since SPI is a synchronous write/read
|
||||
// interface, there must always be the same number of bytes written as bytes read.
|
||||
// The Tx method knows about this, and offers a few different ways of calling it.
|
||||
//
|
||||
@@ -1720,7 +1720,7 @@ func (tcc *TCC) Configure(config PWMConfig) error {
|
||||
for tcc.timer().SYNCBUSY.Get() != 0 {
|
||||
}
|
||||
|
||||
// Return any error that might have occured in the tcc.setPeriod call.
|
||||
// Return any error that might have occurred in the tcc.setPeriod call.
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1928,7 +1928,7 @@ var pinTimerMapping = [...]struct{ F, G uint8 }{
|
||||
PB02 / 2: {pinTCC2_2, 0},
|
||||
}
|
||||
|
||||
// findPinPadMapping returns the pin mode (PinTCCF or PinTCCG) and the channel
|
||||
// findPinTimerMapping returns the pin mode (PinTCCF or PinTCCG) and the channel
|
||||
// number for a given timer and pin. A zero PinMode is returned if no mapping
|
||||
// could be found.
|
||||
func findPinTimerMapping(timer uint8, pin Pin) (PinMode, uint8) {
|
||||
|
||||
@@ -155,7 +155,7 @@ func (can *CAN) Configure(config CANConfig) error {
|
||||
}
|
||||
|
||||
// Callbacks to be called for CAN.SetInterrupt(). Wre're using the magic
|
||||
// constant 2 and 32 here beacuse th SAM E51/E54 has 2 CAN and 32 interrupt
|
||||
// constant 2 and 32 here because the SAM E51/E54 has 2 CAN and 32 interrupt
|
||||
// sources.
|
||||
var (
|
||||
canInstances [2]*CAN
|
||||
@@ -221,6 +221,11 @@ func (can *CAN) TxFifoIsFull() bool {
|
||||
return (can.Bus.TXFQS.Get() & sam.CAN_TXFQS_TFQF_Msk) == sam.CAN_TXFQS_TFQF_Msk
|
||||
}
|
||||
|
||||
// TxFifoFreeLevel returns how many messages can still be set in the TxFifo.
|
||||
func (can *CAN) TxFifoFreeLevel() int {
|
||||
return int(can.Bus.GetTXFQS_TFFL())
|
||||
}
|
||||
|
||||
// TxRaw sends a CAN Frame according to CANTxBufferElement.
|
||||
func (can *CAN) TxRaw(e *CANTxBufferElement) {
|
||||
putIndex := (can.Bus.TXFQS.Get() & sam.CAN_TXFQS_TFQPI_Msk) >> sam.CAN_TXFQS_TFQPI_Pos
|
||||
|
||||
@@ -460,7 +460,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
|
||||
return byte(spi.Bus.W0.Get()), nil
|
||||
}
|
||||
|
||||
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read
|
||||
// Tx handles read/write operation for SPI interface. Since SPI is a synchronous write/read
|
||||
// interface, there must always be the same number of bytes written as bytes read.
|
||||
// This is accomplished by sending zero bits if r is bigger than w or discarding
|
||||
// the incoming data if w is bigger than r.
|
||||
|
||||
@@ -0,0 +1,412 @@
|
||||
//go:build esp32
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"device/esp"
|
||||
"runtime/volatile"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
I2C0 = &I2C{Bus: esp.I2C0, funcSCL: 29, funcSDA: 30}
|
||||
I2C1 = &I2C{Bus: esp.I2C1, funcSCL: 95, funcSDA: 96}
|
||||
)
|
||||
|
||||
type I2C struct {
|
||||
Bus *esp.I2C_Type
|
||||
funcSCL, funcSDA uint32
|
||||
config I2CConfig
|
||||
}
|
||||
|
||||
// I2CConfig is used to store config info for I2C.
|
||||
type I2CConfig struct {
|
||||
Frequency uint32 // in Hz
|
||||
SCL Pin
|
||||
SDA Pin
|
||||
}
|
||||
|
||||
const (
|
||||
i2cClkSourceFrequency = uint32(80 * MHz)
|
||||
)
|
||||
|
||||
func (i2c *I2C) Configure(config I2CConfig) error {
|
||||
if config.Frequency == 0 {
|
||||
config.Frequency = 400 * KHz
|
||||
}
|
||||
if config.SCL == 0 {
|
||||
config.SCL = SCL_PIN
|
||||
}
|
||||
if config.SDA == 0 {
|
||||
config.SDA = SDA_PIN
|
||||
}
|
||||
i2c.config = config
|
||||
|
||||
i2c.initAll()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i2c *I2C) initAll() {
|
||||
i2c.initClock()
|
||||
i2c.initNoiseFilter()
|
||||
i2c.initPins()
|
||||
i2c.initFrequency()
|
||||
i2c.startMaster()
|
||||
}
|
||||
|
||||
//go:inline
|
||||
func (i2c *I2C) initClock() {
|
||||
// reset I2C clock
|
||||
if i2c.Bus == esp.I2C0 {
|
||||
esp.DPORT.SetPERIP_RST_EN_I2C0_EXT0_RST(1)
|
||||
esp.DPORT.SetPERIP_CLK_EN_I2C0_EXT0_CLK_EN(1)
|
||||
esp.DPORT.SetPERIP_RST_EN_I2C0_EXT0_RST(0)
|
||||
} else {
|
||||
esp.DPORT.SetPERIP_RST_EN_I2C_EXT1_RST(1)
|
||||
esp.DPORT.SetPERIP_CLK_EN_I2C_EXT1_CLK_EN(1)
|
||||
esp.DPORT.SetPERIP_RST_EN_I2C_EXT1_RST(0)
|
||||
}
|
||||
// disable interrupts
|
||||
i2c.Bus.INT_ENA.Set(0)
|
||||
i2c.Bus.INT_CLR.Set(0x3fff)
|
||||
|
||||
i2c.Bus.SetCTR_CLK_EN(1)
|
||||
}
|
||||
|
||||
//go:inline
|
||||
func (i2c *I2C) initNoiseFilter() {
|
||||
i2c.Bus.SCL_FILTER_CFG.Set(0xF)
|
||||
i2c.Bus.SDA_FILTER_CFG.Set(0xF)
|
||||
}
|
||||
|
||||
//go:inline
|
||||
func (i2c *I2C) initPins() {
|
||||
var muxConfig uint32
|
||||
const function = 2 // function 2 is just GPIO
|
||||
|
||||
// SDA
|
||||
muxConfig = function << esp.IO_MUX_GPIO0_MCU_SEL_Pos
|
||||
// Make this pin an input pin (always).
|
||||
muxConfig |= esp.IO_MUX_GPIO0_FUN_IE
|
||||
// Set drive strength: 0 is lowest, 3 is highest.
|
||||
muxConfig |= 1 << esp.IO_MUX_GPIO0_FUN_DRV_Pos
|
||||
i2c.config.SDA.mux().Set(muxConfig)
|
||||
i2c.config.SDA.outFunc().Set(i2c.funcSDA)
|
||||
inFunc(i2c.funcSDA).Set(uint32(esp.GPIO_FUNC_IN_SEL_CFG_SEL | i2c.config.SDA))
|
||||
i2c.config.SDA.Set(true)
|
||||
// Configure the pad with the given IO mux configuration.
|
||||
i2c.config.SDA.pinReg().SetBits(esp.GPIO_PIN_PAD_DRIVER)
|
||||
|
||||
esp.GPIO.ENABLE_W1TS.Set(1 << int(i2c.config.SDA))
|
||||
i2c.Bus.SetCTR_SDA_FORCE_OUT(1)
|
||||
|
||||
// SCL
|
||||
muxConfig = function << esp.IO_MUX_GPIO0_MCU_SEL_Pos
|
||||
// Make this pin an input pin (always).
|
||||
muxConfig |= esp.IO_MUX_GPIO0_FUN_IE
|
||||
// Set drive strength: 0 is lowest, 3 is highest.
|
||||
muxConfig |= 1 << esp.IO_MUX_GPIO0_FUN_DRV_Pos
|
||||
i2c.config.SCL.mux().Set(muxConfig)
|
||||
i2c.config.SCL.outFunc().Set(i2c.funcSCL)
|
||||
inFunc(i2c.funcSCL).Set(uint32(esp.GPIO_FUNC_IN_SEL_CFG_SEL | i2c.config.SCL))
|
||||
i2c.config.SCL.Set(true)
|
||||
// Configure the pad with the given IO mux configuration.
|
||||
i2c.config.SCL.pinReg().SetBits(esp.GPIO_PIN_PAD_DRIVER)
|
||||
|
||||
esp.GPIO.ENABLE_W1TS.Set(1 << int(i2c.config.SCL))
|
||||
i2c.Bus.SetCTR_SCL_FORCE_OUT(1)
|
||||
}
|
||||
|
||||
//go:inline
|
||||
func (i2c *I2C) initFrequency() {
|
||||
clkmDiv := i2cClkSourceFrequency/(i2c.config.Frequency*1024) + 1
|
||||
sclkFreq := i2cClkSourceFrequency / clkmDiv
|
||||
halfCycle := sclkFreq / i2c.config.Frequency / 2
|
||||
//SCL
|
||||
sclLow := halfCycle
|
||||
sclWaitHigh := uint32(0)
|
||||
if i2c.config.Frequency > 50000 {
|
||||
sclWaitHigh = halfCycle / 8 // compensate the time when freq > 50K
|
||||
}
|
||||
sclHigh := halfCycle - sclWaitHigh
|
||||
// SDA
|
||||
sdaHold := halfCycle / 4
|
||||
sda_sample := halfCycle / 2
|
||||
setup := halfCycle
|
||||
hold := halfCycle
|
||||
|
||||
i2c.Bus.SetSCL_LOW_PERIOD(sclLow - 1)
|
||||
i2c.Bus.SetSCL_HIGH_PERIOD(sclHigh)
|
||||
i2c.Bus.SetSCL_RSTART_SETUP_TIME(setup)
|
||||
i2c.Bus.SetSCL_STOP_SETUP_TIME(setup)
|
||||
i2c.Bus.SetSCL_START_HOLD_TIME(hold - 1)
|
||||
i2c.Bus.SetSCL_STOP_HOLD_TIME(hold - 1)
|
||||
i2c.Bus.SetSDA_SAMPLE_TIME(sda_sample)
|
||||
i2c.Bus.SetSDA_HOLD_TIME(sdaHold)
|
||||
// set timeout value
|
||||
i2c.Bus.SetTO_TIME_OUT(20 * halfCycle)
|
||||
}
|
||||
|
||||
//go:inline
|
||||
func (i2c *I2C) startMaster() {
|
||||
// FIFO mode for data
|
||||
i2c.Bus.SetFIFO_CONF_NONFIFO_EN(0)
|
||||
// Reset TX & RX buffers
|
||||
i2c.Bus.SetFIFO_CONF_RX_FIFO_RST(1)
|
||||
i2c.Bus.SetFIFO_CONF_RX_FIFO_RST(0)
|
||||
i2c.Bus.SetFIFO_CONF_TX_FIFO_RST(1)
|
||||
i2c.Bus.SetFIFO_CONF_TX_FIFO_RST(0)
|
||||
// enable master mode
|
||||
i2c.Bus.SetCTR_MS_MODE(1)
|
||||
}
|
||||
|
||||
func (i2c *I2C) resetBus() {
|
||||
// unlike esp32c3, the esp32 i2c modules do not have a reset fsm register,
|
||||
// so we need to:
|
||||
// 1. disconnect the pins
|
||||
// 2. generate a stop condition manually
|
||||
// 3. do a full reset
|
||||
// 4. redo all configuration
|
||||
|
||||
i2c.config.SDA.mux().Set(2<<esp.IO_MUX_GPIO0_MCU_SEL_Pos | esp.IO_MUX_GPIO0_FUN_IE | 1<<esp.IO_MUX_GPIO0_FUN_DRV_Pos)
|
||||
i2c.config.SDA.outFunc().Set(0x500)
|
||||
i2c.config.SDA.pinReg().SetBits(esp.GPIO_PIN_PAD_DRIVER)
|
||||
i2c.config.SCL.mux().Set(2<<esp.IO_MUX_GPIO0_MCU_SEL_Pos | esp.IO_MUX_GPIO0_FUN_IE | 1<<esp.IO_MUX_GPIO0_FUN_DRV_Pos)
|
||||
i2c.config.SCL.outFunc().Set(0x500)
|
||||
i2c.config.SCL.pinReg().SetBits(esp.GPIO_PIN_PAD_DRIVER)
|
||||
|
||||
// bit-bang a read-NACK in case any device on the bus is in the middle of a write
|
||||
i2c.config.SCL.Low()
|
||||
i2c.config.SDA.High()
|
||||
wait()
|
||||
for i := 0; i < 9; i++ {
|
||||
if i2c.config.SDA.Get() {
|
||||
break
|
||||
}
|
||||
i2c.config.SCL.High()
|
||||
wait()
|
||||
i2c.config.SCL.Low()
|
||||
wait()
|
||||
}
|
||||
i2c.config.SDA.Low()
|
||||
i2c.config.SCL.High()
|
||||
wait()
|
||||
i2c.config.SDA.High()
|
||||
|
||||
// initAll contains initClock which contains a reset
|
||||
i2c.initAll()
|
||||
}
|
||||
|
||||
func wait() {
|
||||
end := nanotime() + 5_000
|
||||
for nanotime() < end {
|
||||
//spin
|
||||
}
|
||||
}
|
||||
|
||||
type i2cCommandType = uint32
|
||||
type i2cAck = uint32
|
||||
|
||||
const (
|
||||
i2cCMD_RSTART i2cCommandType = 0 << 11
|
||||
i2cCMD_WRITE i2cCommandType = 1<<11 | 1<<8 // WRITE + ack_check_en
|
||||
i2cCMD_READ i2cCommandType = 2 << 11
|
||||
i2cCMD_READLAST i2cCommandType = 2<<11 | 1<<10 // READ + NACK
|
||||
i2cCMD_STOP i2cCommandType = 3 << 11
|
||||
i2cCMD_END i2cCommandType = 4 << 11
|
||||
)
|
||||
|
||||
type i2cCommand struct {
|
||||
cmd i2cCommandType
|
||||
data []byte
|
||||
head int
|
||||
}
|
||||
|
||||
//go:linkname nanotime runtime.nanotime
|
||||
func nanotime() int64
|
||||
|
||||
func (i2c *I2C) transmit(addr uint16, cmd []i2cCommand, timeoutMS int) error {
|
||||
if i2c.Bus.GetSR_BUS_BUSY() == 1 {
|
||||
i2c.resetBus()
|
||||
}
|
||||
|
||||
const intMask = esp.I2C_INT_STATUS_END_DETECT_INT_ST_Msk | esp.I2C_INT_STATUS_TRANS_COMPLETE_INT_ST_Msk | esp.I2C_INT_STATUS_TIME_OUT_INT_ST_Msk | esp.I2C_INT_STATUS_ACK_ERR_INT_ST_Msk | esp.I2C_INT_STATUS_ARBITRATION_LOST_INT_ST_Msk
|
||||
i2c.Bus.INT_CLR.Set(intMask)
|
||||
i2c.Bus.INT_ENA.Set(intMask)
|
||||
|
||||
defer func() {
|
||||
i2c.Bus.INT_CLR.Set(intMask)
|
||||
i2c.Bus.INT_ENA.Set(0)
|
||||
}()
|
||||
|
||||
timeoutNS := int64(timeoutMS) * 1000000
|
||||
needAddress := true
|
||||
needRestart := false
|
||||
readLast := false
|
||||
var readTo []byte
|
||||
for cmdIdx, reg := 0, &i2c.Bus.COMD0; cmdIdx < len(cmd); {
|
||||
c := &cmd[cmdIdx]
|
||||
|
||||
switch c.cmd {
|
||||
case i2cCMD_RSTART:
|
||||
reg.Set(i2cCMD_RSTART)
|
||||
reg = nextAddress(reg)
|
||||
cmdIdx++
|
||||
|
||||
case i2cCMD_WRITE:
|
||||
count := 32
|
||||
if needAddress {
|
||||
needAddress = false
|
||||
i2c.Bus.SetDATA_FIFO_RDATA((uint32(addr) & 0x7f) << 1)
|
||||
count--
|
||||
i2c.Bus.SLAVE_ADDR.Set(uint32(addr))
|
||||
}
|
||||
for ; count > 0 && c.head < len(c.data); count, c.head = count-1, c.head+1 {
|
||||
i2c.Bus.SetDATA_FIFO_RDATA(uint32(c.data[c.head]))
|
||||
}
|
||||
reg.Set(i2cCMD_WRITE | uint32(32-count))
|
||||
reg = nextAddress(reg)
|
||||
|
||||
if c.head < len(c.data) {
|
||||
reg.Set(i2cCMD_END)
|
||||
reg = nil
|
||||
} else {
|
||||
cmdIdx++
|
||||
}
|
||||
needRestart = true
|
||||
|
||||
case i2cCMD_READ:
|
||||
if needAddress {
|
||||
needAddress = false
|
||||
i2c.Bus.SetDATA_FIFO_RDATA((uint32(addr)&0x7f)<<1 | 1)
|
||||
i2c.Bus.SLAVE_ADDR.Set(uint32(addr))
|
||||
reg.Set(i2cCMD_WRITE | 1)
|
||||
reg = nextAddress(reg)
|
||||
}
|
||||
if needRestart {
|
||||
// We need to send RESTART again after i2cCMD_WRITE.
|
||||
reg.Set(i2cCMD_RSTART)
|
||||
|
||||
reg = nextAddress(reg)
|
||||
reg.Set(i2cCMD_WRITE | 1)
|
||||
|
||||
reg = nextAddress(reg)
|
||||
i2c.Bus.SetDATA_FIFO_RDATA((uint32(addr)&0x7f)<<1 | 1)
|
||||
needRestart = false
|
||||
}
|
||||
count := 32
|
||||
bytes := len(c.data) - c.head
|
||||
// Only last byte in sequence must be sent with ACK set to 1 to indicate end of data.
|
||||
split := bytes <= count
|
||||
if split {
|
||||
bytes--
|
||||
}
|
||||
if bytes > 32 {
|
||||
bytes = 32
|
||||
}
|
||||
if bytes > 0 {
|
||||
reg.Set(i2cCMD_READ | uint32(bytes))
|
||||
reg = nextAddress(reg)
|
||||
}
|
||||
|
||||
if split {
|
||||
readLast = true
|
||||
reg.Set(i2cCMD_READLAST | 1)
|
||||
reg = nextAddress(reg)
|
||||
readTo = c.data[c.head : c.head+bytes+1] // read bytes + 1 last byte
|
||||
cmdIdx++
|
||||
} else {
|
||||
reg.Set(i2cCMD_END)
|
||||
readTo = c.data[c.head : c.head+bytes]
|
||||
reg = nil
|
||||
}
|
||||
|
||||
case i2cCMD_STOP:
|
||||
reg.Set(i2cCMD_STOP)
|
||||
reg = nil
|
||||
cmdIdx++
|
||||
}
|
||||
if reg == nil {
|
||||
// transmit now
|
||||
i2c.Bus.SetCTR_TRANS_START(1)
|
||||
end := nanotime() + timeoutNS
|
||||
var mask uint32
|
||||
for mask = i2c.Bus.INT_STATUS.Get(); mask&intMask == 0; mask = i2c.Bus.INT_STATUS.Get() {
|
||||
if nanotime() > end {
|
||||
// timeout leaves the bus in an undefined state, reset
|
||||
i2c.resetBus()
|
||||
if readTo != nil {
|
||||
return errI2CReadTimeout
|
||||
}
|
||||
return errI2CWriteTimeout
|
||||
}
|
||||
}
|
||||
switch {
|
||||
case mask&esp.I2C_INT_STATUS_ACK_ERR_INT_ST_Msk != 0 && !readLast:
|
||||
return errI2CAckExpected
|
||||
case mask&esp.I2C_INT_STATUS_TIME_OUT_INT_ST_Msk != 0:
|
||||
// timeout leaves the bus in an undefined state, reset
|
||||
i2c.resetBus()
|
||||
if readTo != nil {
|
||||
return errI2CReadTimeout
|
||||
}
|
||||
return errI2CWriteTimeout
|
||||
}
|
||||
i2c.Bus.INT_CLR.SetBits(intMask)
|
||||
for i := 0; i < len(readTo); i++ {
|
||||
readTo[i] = byte(i2c.Bus.GetDATA_FIFO_RDATA() & 0xff)
|
||||
c.head++
|
||||
}
|
||||
readTo = nil
|
||||
reg = &i2c.Bus.COMD0
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Tx does a single I2C transaction at the specified address.
|
||||
// It clocks out the given address, writes the bytes in w, reads back len(r)
|
||||
// bytes and stores them in r, and generates a stop condition on the bus.
|
||||
func (i2c *I2C) Tx(addr uint16, w, r []byte) (err error) {
|
||||
// timeout in microseconds.
|
||||
const timeout = 40 // 40ms is a reasonable time for a real-time system.
|
||||
|
||||
cmd := make([]i2cCommand, 0, 8)
|
||||
cmd = append(cmd, i2cCommand{cmd: i2cCMD_RSTART})
|
||||
if len(w) > 0 {
|
||||
cmd = append(cmd, i2cCommand{cmd: i2cCMD_WRITE, data: w})
|
||||
}
|
||||
if len(r) > 0 {
|
||||
cmd = append(cmd, i2cCommand{cmd: i2cCMD_READ, data: r})
|
||||
}
|
||||
cmd = append(cmd, i2cCommand{cmd: i2cCMD_STOP})
|
||||
|
||||
return i2c.transmit(addr, cmd, timeout)
|
||||
}
|
||||
|
||||
func (i2c *I2C) SetBaudRate(br uint32) error {
|
||||
return errI2CNotImplemented
|
||||
}
|
||||
|
||||
func (p Pin) pinReg() *volatile.Register32 {
|
||||
return (*volatile.Register32)(unsafe.Pointer((uintptr(unsafe.Pointer(&esp.GPIO.PIN0)) + uintptr(p)*4)))
|
||||
}
|
||||
|
||||
func nextAddress(reg *volatile.Register32) *volatile.Register32 {
|
||||
return (*volatile.Register32)(unsafe.Add(unsafe.Pointer(reg), 4))
|
||||
}
|
||||
|
||||
// CheckDevice does an empty I2C transaction at the specified address.
|
||||
// This can be used to find out if any device with that address is
|
||||
// connected, e.g. for enumerating all devices on the bus.
|
||||
func (i2c *I2C) CheckDevice(addr uint16) bool {
|
||||
// timeout in microseconds.
|
||||
const timeout = 40 // 40ms is a reasonable time for a real-time system.
|
||||
|
||||
cmd := []i2cCommand{
|
||||
{cmd: i2cCMD_RSTART},
|
||||
{cmd: i2cCMD_WRITE},
|
||||
{cmd: i2cCMD_STOP},
|
||||
}
|
||||
return i2c.transmit(addr, cmd, timeout) == nil
|
||||
}
|
||||
@@ -312,7 +312,7 @@ func (uart *UART) configure(config UARTConfig, regs registerSet) error {
|
||||
|
||||
initUARTClock(uart.Bus, regs)
|
||||
|
||||
// - disbale TX/RX clock to make sure the UART transmitter or receiver is not at work during configuration
|
||||
// - disable TX/RX clock to make sure the UART transmitter or receiver is not at work during configuration
|
||||
uart.Bus.SetCLK_CONF_TX_SCLK_EN(0)
|
||||
uart.Bus.SetCLK_CONF_RX_SCLK_EN(0)
|
||||
|
||||
|
||||
@@ -234,7 +234,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
|
||||
return byte(spi.Bus.GetW0()), nil
|
||||
}
|
||||
|
||||
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read
|
||||
// Tx handles read/write operation for SPI interface. Since SPI is a synchronous write/read
|
||||
// interface, there must always be the same number of bytes written as bytes read.
|
||||
// This is accomplished by sending zero bits if r is bigger than w or discarding
|
||||
// the incoming data if w is bigger than r.
|
||||
|
||||
@@ -2,20 +2,23 @@
|
||||
|
||||
package machine
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
)
|
||||
|
||||
// Dummy machine package that calls out to external functions.
|
||||
|
||||
const deviceName = "generic"
|
||||
|
||||
var (
|
||||
UART0 = &UART{0}
|
||||
USB = &UART{100}
|
||||
USB = &UART{100}
|
||||
)
|
||||
|
||||
// The Serial port always points to the default UART in a simulated environment.
|
||||
//
|
||||
// TODO: perhaps this should be a special serial object that outputs via WASI
|
||||
// stdout calls.
|
||||
var Serial = UART0
|
||||
var Serial = hardwareUART0
|
||||
|
||||
const (
|
||||
PinInput PinMode = iota
|
||||
@@ -67,12 +70,47 @@ func (spi SPI) Transfer(w byte) (byte, error) {
|
||||
return spiTransfer(spi.Bus, w), nil
|
||||
}
|
||||
|
||||
// Tx handles read/write operation for SPI interface. Since SPI is a synchronous write/read
|
||||
// interface, there must always be the same number of bytes written as bytes read.
|
||||
// The Tx method knows about this, and offers a few different ways of calling it.
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// This form sends zeros, putting the result into the rx buffer. Good for reading a "result packet":
|
||||
//
|
||||
// spi.Tx(nil, rx)
|
||||
func (spi SPI) Tx(w, r []byte) error {
|
||||
var wptr, rptr *byte
|
||||
var wlen, rlen int
|
||||
if len(w) != 0 {
|
||||
wptr = &w[0]
|
||||
wlen = len(w)
|
||||
}
|
||||
if len(r) != 0 {
|
||||
rptr = &r[0]
|
||||
rlen = len(r)
|
||||
}
|
||||
spiTX(spi.Bus, wptr, wlen, rptr, rlen)
|
||||
return nil
|
||||
}
|
||||
|
||||
//export __tinygo_spi_configure
|
||||
func spiConfigure(bus uint8, sck Pin, SDO Pin, SDI Pin)
|
||||
|
||||
//export __tinygo_spi_transfer
|
||||
func spiTransfer(bus uint8, w uint8) uint8
|
||||
|
||||
//export __tinygo_spi_tx
|
||||
func spiTX(bus uint8, wptr *byte, wlen int, rptr *byte, rlen int) uint8
|
||||
|
||||
// InitADC enables support for ADC peripherals.
|
||||
func InitADC() {
|
||||
// Nothing to do here.
|
||||
@@ -116,7 +154,17 @@ func (i2c *I2C) SetBaudRate(br uint32) error {
|
||||
|
||||
// Tx does a single I2C transaction at the specified address.
|
||||
func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
|
||||
i2cTransfer(i2c.Bus, &w[0], len(w), &r[0], len(r))
|
||||
var wptr, rptr *byte
|
||||
var wlen, rlen int
|
||||
if len(w) != 0 {
|
||||
wptr = &w[0]
|
||||
wlen = len(w)
|
||||
}
|
||||
if len(r) != 0 {
|
||||
rptr = &r[0]
|
||||
rlen = len(r)
|
||||
}
|
||||
i2cTransfer(i2c.Bus, wptr, wlen, rptr, rlen)
|
||||
// TODO: do something with the returned error code.
|
||||
return nil
|
||||
}
|
||||
@@ -176,6 +224,11 @@ func uartRead(bus uint8, buf *byte, bufLen int) int
|
||||
//export __tinygo_uart_write
|
||||
func uartWrite(bus uint8, buf *byte, bufLen int) int
|
||||
|
||||
var (
|
||||
hardwareUART0 = &UART{0}
|
||||
hardwareUART1 = &UART{1}
|
||||
)
|
||||
|
||||
// Some objects used by Atmel SAM D chips (samd21, samd51).
|
||||
// Defined here (without build tag) for convenience.
|
||||
var (
|
||||
@@ -204,3 +257,13 @@ var (
|
||||
sercomSPIM6 = SPI{6}
|
||||
sercomSPIM7 = SPI{7}
|
||||
)
|
||||
|
||||
// GetRNG returns 32 bits of random data from the WASI random source.
|
||||
func GetRNG() (uint32, error) {
|
||||
var buf [4]byte
|
||||
_, err := rand.Read(buf[:])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint32(buf[0])<<0 | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24, nil
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@ package machine
|
||||
// boards that define their peripherals in the board file (e.g. board_qtpy.go).
|
||||
|
||||
var (
|
||||
SPI0 = SPI{0}
|
||||
I2C0 = &I2C{0}
|
||||
UART0 = hardwareUART0
|
||||
UART1 = hardwareUART1
|
||||
SPI0 = SPI{0}
|
||||
SPI1 = SPI{1}
|
||||
I2C0 = &I2C{0}
|
||||
)
|
||||
|
||||
@@ -108,7 +108,7 @@ func (p Pin) Get() bool {
|
||||
func (p Pin) SetInterrupt(change PinChange, callback func(Pin)) error {
|
||||
// Some variables to easily check whether a channel was already configured
|
||||
// as an event channel for the given pin.
|
||||
// This is not just an optimization, this is requred: the datasheet says
|
||||
// This is not just an optimization, this is required: the datasheet says
|
||||
// that configuring more than one channel for a given pin results in
|
||||
// unpredictable behavior.
|
||||
expectedConfigMask := uint32(nrf.GPIOTE_CONFIG_MODE_Msk | nrf.GPIOTE_CONFIG_PSEL_Msk)
|
||||
|
||||
@@ -133,7 +133,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
|
||||
return byte(r), nil
|
||||
}
|
||||
|
||||
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read
|
||||
// Tx handles read/write operation for SPI interface. Since SPI is a synchronous write/read
|
||||
// interface, there must always be the same number of bytes written as bytes read.
|
||||
// The Tx method knows about this, and offers a few different ways of calling it.
|
||||
//
|
||||
|
||||
@@ -277,7 +277,7 @@ func (spi SPI) Transfer(w byte) (byte, error) {
|
||||
return buf[0], err
|
||||
}
|
||||
|
||||
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous
|
||||
// Tx handles read/write operation for SPI interface. Since SPI is a synchronous
|
||||
// write/read interface, there must always be the same number of bytes written
|
||||
// as bytes read. Therefore, if the number of bytes don't match it will be
|
||||
// padded until they fit: if len(w) > len(r) the extra bytes received will be
|
||||
|
||||
@@ -10,46 +10,6 @@ import (
|
||||
|
||||
const deviceName = rp.Device
|
||||
|
||||
const (
|
||||
// GPIO pins
|
||||
GPIO0 Pin = 0 // peripherals: PWM0 channel A
|
||||
GPIO1 Pin = 1 // peripherals: PWM0 channel B
|
||||
GPIO2 Pin = 2 // peripherals: PWM1 channel A
|
||||
GPIO3 Pin = 3 // peripherals: PWM1 channel B
|
||||
GPIO4 Pin = 4 // peripherals: PWM2 channel A
|
||||
GPIO5 Pin = 5 // peripherals: PWM2 channel B
|
||||
GPIO6 Pin = 6 // peripherals: PWM3 channel A
|
||||
GPIO7 Pin = 7 // peripherals: PWM3 channel B
|
||||
GPIO8 Pin = 8 // peripherals: PWM4 channel A
|
||||
GPIO9 Pin = 9 // peripherals: PWM4 channel B
|
||||
GPIO10 Pin = 10 // peripherals: PWM5 channel A
|
||||
GPIO11 Pin = 11 // peripherals: PWM5 channel B
|
||||
GPIO12 Pin = 12 // peripherals: PWM6 channel A
|
||||
GPIO13 Pin = 13 // peripherals: PWM6 channel B
|
||||
GPIO14 Pin = 14 // peripherals: PWM7 channel A
|
||||
GPIO15 Pin = 15 // peripherals: PWM7 channel B
|
||||
GPIO16 Pin = 16 // peripherals: PWM0 channel A
|
||||
GPIO17 Pin = 17 // peripherals: PWM0 channel B
|
||||
GPIO18 Pin = 18 // peripherals: PWM1 channel A
|
||||
GPIO19 Pin = 19 // peripherals: PWM1 channel B
|
||||
GPIO20 Pin = 20 // peripherals: PWM2 channel A
|
||||
GPIO21 Pin = 21 // peripherals: PWM2 channel B
|
||||
GPIO22 Pin = 22 // peripherals: PWM3 channel A
|
||||
GPIO23 Pin = 23 // peripherals: PWM3 channel B
|
||||
GPIO24 Pin = 24 // peripherals: PWM4 channel A
|
||||
GPIO25 Pin = 25 // peripherals: PWM4 channel B
|
||||
GPIO26 Pin = 26 // peripherals: PWM5 channel A
|
||||
GPIO27 Pin = 27 // peripherals: PWM5 channel B
|
||||
GPIO28 Pin = 28 // peripherals: PWM6 channel A
|
||||
GPIO29 Pin = 29 // peripherals: PWM6 channel B
|
||||
|
||||
// Analog pins
|
||||
ADC0 Pin = GPIO26
|
||||
ADC1 Pin = GPIO27
|
||||
ADC2 Pin = GPIO28
|
||||
ADC3 Pin = GPIO29
|
||||
)
|
||||
|
||||
//go:linkname machineInit runtime.machineInit
|
||||
func machineInit() {
|
||||
// Reset all peripherals to put system into a known state,
|
||||
|
||||
@@ -331,3 +331,23 @@ func (p Pin) ioIntBit(change PinChange) uint32 {
|
||||
func getIntChange(p Pin, status uint32) PinChange {
|
||||
return PinChange(status>>(4*(p%8))) & 0xf
|
||||
}
|
||||
|
||||
// UART on the RP2040
|
||||
var (
|
||||
UART0 = &_UART0
|
||||
_UART0 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: rp.UART0,
|
||||
}
|
||||
|
||||
UART1 = &_UART1
|
||||
_UART1 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
Bus: rp.UART1,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
UART0.Interrupt = interrupt.New(rp.IRQ_UART0_IRQ, _UART0.handleInterrupt)
|
||||
UART1.Interrupt = interrupt.New(rp.IRQ_UART1_IRQ, _UART1.handleInterrupt)
|
||||
}
|
||||
|
||||
@@ -348,7 +348,7 @@ func (i2c *I2C) tx(addr uint8, tx, rx []byte, timeout_us uint64) (err error) {
|
||||
}
|
||||
if abort || last {
|
||||
// If the transaction was aborted or if it completed
|
||||
// successfully wait until the STOP condition has occured.
|
||||
// successfully wait until the STOP condition has occurred.
|
||||
|
||||
// TODO Could there be an abort while waiting for the STOP
|
||||
// condition here? If so, additional code would be needed here
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
//go:build rp2040 || ae_rp2040 || badger2040 || challenger_rp2040 || feather_rp2040 || gopher_badge || kb2040 || macropad_rp2040 || nano_rp2040 || pico || qtpy_rp2040 || thingplus_rp2040 || thumby || tufty2040 || waveshare_rp2040_zero || xiao_rp2040
|
||||
|
||||
package machine
|
||||
|
||||
const (
|
||||
// GPIO pins
|
||||
GPIO0 Pin = 0 // peripherals: PWM0 channel A
|
||||
GPIO1 Pin = 1 // peripherals: PWM0 channel B
|
||||
GPIO2 Pin = 2 // peripherals: PWM1 channel A
|
||||
GPIO3 Pin = 3 // peripherals: PWM1 channel B
|
||||
GPIO4 Pin = 4 // peripherals: PWM2 channel A
|
||||
GPIO5 Pin = 5 // peripherals: PWM2 channel B
|
||||
GPIO6 Pin = 6 // peripherals: PWM3 channel A
|
||||
GPIO7 Pin = 7 // peripherals: PWM3 channel B
|
||||
GPIO8 Pin = 8 // peripherals: PWM4 channel A
|
||||
GPIO9 Pin = 9 // peripherals: PWM4 channel B
|
||||
GPIO10 Pin = 10 // peripherals: PWM5 channel A
|
||||
GPIO11 Pin = 11 // peripherals: PWM5 channel B
|
||||
GPIO12 Pin = 12 // peripherals: PWM6 channel A
|
||||
GPIO13 Pin = 13 // peripherals: PWM6 channel B
|
||||
GPIO14 Pin = 14 // peripherals: PWM7 channel A
|
||||
GPIO15 Pin = 15 // peripherals: PWM7 channel B
|
||||
GPIO16 Pin = 16 // peripherals: PWM0 channel A
|
||||
GPIO17 Pin = 17 // peripherals: PWM0 channel B
|
||||
GPIO18 Pin = 18 // peripherals: PWM1 channel A
|
||||
GPIO19 Pin = 19 // peripherals: PWM1 channel B
|
||||
GPIO20 Pin = 20 // peripherals: PWM2 channel A
|
||||
GPIO21 Pin = 21 // peripherals: PWM2 channel B
|
||||
GPIO22 Pin = 22 // peripherals: PWM3 channel A
|
||||
GPIO23 Pin = 23 // peripherals: PWM3 channel B
|
||||
GPIO24 Pin = 24 // peripherals: PWM4 channel A
|
||||
GPIO25 Pin = 25 // peripherals: PWM4 channel B
|
||||
GPIO26 Pin = 26 // peripherals: PWM5 channel A
|
||||
GPIO27 Pin = 27 // peripherals: PWM5 channel B
|
||||
GPIO28 Pin = 28 // peripherals: PWM6 channel A
|
||||
GPIO29 Pin = 29 // peripherals: PWM6 channel B
|
||||
|
||||
// Analog pins
|
||||
ADC0 Pin = GPIO26
|
||||
ADC1 Pin = GPIO27
|
||||
ADC2 Pin = GPIO28
|
||||
ADC3 Pin = GPIO29
|
||||
)
|
||||
@@ -48,7 +48,7 @@ type SPI struct {
|
||||
Bus *rp.SPI0_Type
|
||||
}
|
||||
|
||||
// Tx handles read/write operation for SPI interface. Since SPI is a syncronous write/read
|
||||
// Tx handles read/write operation for SPI interface. Since SPI is a synchronous write/read
|
||||
// interface, there must always be the same number of bytes written as bytes read.
|
||||
// The Tx method knows about this, and offers a few different ways of calling it.
|
||||
//
|
||||
|
||||
@@ -45,11 +45,21 @@ type I2C struct {
|
||||
|
||||
// I2CConfig is used to store config info for I2C.
|
||||
type I2CConfig struct {
|
||||
SCL Pin
|
||||
SDA Pin
|
||||
Frequency uint32
|
||||
SCL Pin
|
||||
SDA Pin
|
||||
}
|
||||
|
||||
func (i2c *I2C) Configure(config I2CConfig) error {
|
||||
// Frequency range
|
||||
switch config.Frequency {
|
||||
case 0:
|
||||
config.Frequency = 100 * KHz
|
||||
case 10 * KHz, 100 * KHz, 400 * KHz, 500 * KHz:
|
||||
default:
|
||||
return errI2CNotImplemented
|
||||
}
|
||||
|
||||
// disable I2C interface before any configuration changes
|
||||
i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_PE)
|
||||
|
||||
@@ -63,8 +73,7 @@ func (i2c *I2C) Configure(config I2CConfig) error {
|
||||
}
|
||||
i2c.configurePins(config)
|
||||
|
||||
// Frequency range
|
||||
i2c.Bus.TIMINGR.Set(i2c.getFreqRange())
|
||||
i2c.Bus.TIMINGR.Set(i2c.getFreqRange(config.Frequency))
|
||||
|
||||
// Disable Own Address1 before set the Own Address1 configuration
|
||||
i2c.Bus.OAR1.ClearBits(stm32.I2C_OAR1_OA1EN)
|
||||
@@ -86,8 +95,21 @@ func (i2c *I2C) Configure(config I2CConfig) error {
|
||||
|
||||
// SetBaudRate sets the communication speed for I2C.
|
||||
func (i2c *I2C) SetBaudRate(br uint32) error {
|
||||
// TODO: implement
|
||||
return errI2CNotImplemented
|
||||
switch br {
|
||||
case 10 * KHz, 100 * KHz, 400 * KHz, 500 * KHz:
|
||||
default:
|
||||
return errI2CNotImplemented
|
||||
}
|
||||
|
||||
// disable I2C interface before any configuration changes
|
||||
i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_PE)
|
||||
|
||||
i2c.Bus.TIMINGR.Set(i2c.getFreqRange(br))
|
||||
|
||||
// Disable Generalcall and NoStretch, Enable peripheral
|
||||
i2c.Bus.CR1.Set(stm32.I2C_CR1_PE)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user