mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-06 20:13:40 +00:00
Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 63e3c3ec24 | |||
| 109e0767e7 | |||
| 821f2aeae0 | |||
| 93a11e266f | |||
| e29e583919 | |||
| 310df7acb5 | |||
| b9387febe0 | |||
| 3dce224183 | |||
| 5d8afa25b8 | |||
| 0dca016749 | |||
| 28a911bcce | |||
| eb36120c6e | |||
| dfbb133ea6 | |||
| 79ab77facd | |||
| 2c99692019 | |||
| 0ca0aad7ce | |||
| 3ddba4e620 | |||
| eab3dceb48 | |||
| 663a94fcab | |||
| 373ca88f14 | |||
| be33de1086 | |||
| e5bdfb0962 | |||
| e80c6c48a1 | |||
| 381644a0c0 | |||
| 13bb59c334 | |||
| 632e5f9872 | |||
| 37531930b8 | |||
| 3869f76887 | |||
| 3e76703ff5 | |||
| deb48dd5f0 | |||
| 73fa5cd7bc | |||
| 1be7582106 | |||
| d5b7cdbca3 | |||
| c769262398 | |||
| 64caab1ade | |||
| 78914382c3 | |||
| 15e37ff927 | |||
| 91234060be | |||
| b33b6ce293 | |||
| 8911abbc6d | |||
| bc77922d47 | |||
| 34efc3a381 | |||
| 5c46efb4d1 | |||
| d6343d9d5c | |||
| e368551919 | |||
| 8b4624a420 | |||
| 9fd1b7b1a8 | |||
| a38829c692 | |||
| 1dbc6c83c4 | |||
| 9a6071920f | |||
| 0964176b4d | |||
| 1ffa9a4adf | |||
| 8c5886060f | |||
| 3bb092d4d4 | |||
| 20e62dea6f | |||
| 1b5d312c68 | |||
| 435ddc5f2d | |||
| 1de1f87c6b | |||
| 778164c98e | |||
| b3da00ac1f | |||
| e454ad1b61 | |||
| f845b469b1 | |||
| 35adbffa54 | |||
| 01f3d3eb59 | |||
| 0e43146d32 | |||
| 93f40992c1 | |||
| c6b47fe6a0 | |||
| 536deaa00a | |||
| df1d639deb |
+11
-9
@@ -92,26 +92,28 @@ commands:
|
|||||||
- /go/pkg/mod
|
- /go/pkg/mod
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test-llvm15-go122:
|
test-oldest:
|
||||||
|
# This tests our lowest supported versions of Go and LLVM, to make sure at
|
||||||
|
# least the smoke tests still pass.
|
||||||
docker:
|
docker:
|
||||||
- image: golang:1.22-bullseye
|
- image: golang:1.22-bullseye
|
||||||
steps:
|
steps:
|
||||||
- test-linux:
|
- test-linux:
|
||||||
llvm: "15"
|
llvm: "15"
|
||||||
resource_class: large
|
resource_class: large
|
||||||
test-llvm20-go124:
|
test-newest:
|
||||||
|
# This tests the latest supported LLVM version when linking against system
|
||||||
|
# libraries.
|
||||||
docker:
|
docker:
|
||||||
- image: golang:1.24-bullseye
|
- image: golang:1.25-bullseye
|
||||||
steps:
|
steps:
|
||||||
- test-linux:
|
- test-linux:
|
||||||
llvm: "20"
|
llvm: "21"
|
||||||
resource_class: large
|
resource_class: large
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
test-all:
|
test-all:
|
||||||
jobs:
|
jobs:
|
||||||
# This tests our lowest supported versions of Go and LLVM, to make sure at
|
- test-oldest
|
||||||
# least the smoke tests still pass.
|
# disable this test, since CircleCI seems unable to download due to rate-limits on Dockerhub.
|
||||||
- test-llvm15-go122
|
# - test-newest
|
||||||
# This tests LLVM 20 support when linking against system libraries.
|
|
||||||
- test-llvm20-go124
|
|
||||||
|
|||||||
@@ -30,22 +30,22 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install qemu binaryen
|
HOMEBREW_NO_AUTO_UPDATE=1 brew install qemu binaryen
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- name: Extract TinyGo version
|
- name: Extract TinyGo version
|
||||||
id: version
|
id: version
|
||||||
run: ./.github/workflows/tinygo-extract-version.sh | tee -a "$GITHUB_OUTPUT"
|
run: ./.github/workflows/tinygo-extract-version.sh | tee -a "$GITHUB_OUTPUT"
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v6
|
||||||
with:
|
with:
|
||||||
go-version: '1.24'
|
go-version: '1.25.1'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Restore LLVM source cache
|
- name: Restore LLVM source cache
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-19-${{ matrix.os }}-v1
|
key: llvm-source-20-${{ matrix.os }}-v1
|
||||||
path: |
|
path: |
|
||||||
llvm-project/clang/lib/Headers
|
llvm-project/clang/lib/Headers
|
||||||
llvm-project/clang/include
|
llvm-project/clang/include
|
||||||
@@ -70,7 +70,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-19-${{ matrix.os }}-v1
|
key: llvm-build-20-${{ matrix.os }}-v2
|
||||||
path: llvm-build
|
path: llvm-build
|
||||||
- name: Build LLVM
|
- name: Build LLVM
|
||||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||||
@@ -79,7 +79,7 @@ jobs:
|
|||||||
rm -rf llvm-project
|
rm -rf llvm-project
|
||||||
make llvm-source
|
make llvm-source
|
||||||
# install dependencies
|
# install dependencies
|
||||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install cmake ninja
|
HOMEBREW_NO_AUTO_UPDATE=1 brew install ninja
|
||||||
# build!
|
# build!
|
||||||
make llvm-build
|
make llvm-build
|
||||||
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
find llvm-build -name CMakeFiles -prune -exec rm -r '{}' \;
|
||||||
@@ -117,7 +117,7 @@ jobs:
|
|||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
version: [16, 17, 18, 19, 20]
|
version: [16, 17, 18, 19, 20, 21]
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Homebrew
|
- name: Set up Homebrew
|
||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@master
|
||||||
@@ -130,19 +130,19 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
brew install llvm@${{ matrix.version }}
|
brew install llvm@${{ matrix.version }}
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v5
|
||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v6
|
||||||
with:
|
with:
|
||||||
go-version: '1.24'
|
go-version: '1.25.1'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Build TinyGo (LLVM ${{ matrix.version }})
|
- name: Build TinyGo (LLVM ${{ matrix.version }})
|
||||||
run: go install -tags=llvm${{ matrix.version }}
|
run: go install -tags=llvm${{ matrix.version }}
|
||||||
- name: Check binary
|
- name: Check binary
|
||||||
run: tinygo version
|
run: tinygo version
|
||||||
- name: Build TinyGo (default LLVM)
|
- name: Build TinyGo (default LLVM)
|
||||||
if: matrix.version == 20
|
if: matrix.version == 21
|
||||||
run: go install
|
run: go install
|
||||||
- name: Check binary
|
- name: Check binary
|
||||||
if: matrix.version == 20
|
if: matrix.version == 21
|
||||||
run: tinygo version
|
run: tinygo version
|
||||||
|
|||||||
+11
-11
@@ -18,7 +18,7 @@ jobs:
|
|||||||
# statically linked binary.
|
# statically linked binary.
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: golang:1.24-alpine
|
image: golang:1.25-alpine
|
||||||
outputs:
|
outputs:
|
||||||
version: ${{ steps.version.outputs.version }}
|
version: ${{ steps.version.outputs.version }}
|
||||||
steps:
|
steps:
|
||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
# tar: needed for actions/cache@v4
|
# tar: needed for actions/cache@v4
|
||||||
# git+openssh: needed for checkout (I think?)
|
# git+openssh: needed for checkout (I think?)
|
||||||
# ruby: needed to install fpm
|
# ruby: needed to install fpm
|
||||||
run: apk add tar git openssh make g++ ruby-dev
|
run: apk add tar git openssh make g++ ruby-dev mold
|
||||||
- name: Work around CVE-2022-24765
|
- name: Work around CVE-2022-24765
|
||||||
# We're not on a multi-user machine, so this is safe.
|
# We're not on a multi-user machine, so this is safe.
|
||||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||||
@@ -48,7 +48,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-19-linux-alpine-v1
|
key: llvm-source-20-linux-alpine-v1
|
||||||
path: |
|
path: |
|
||||||
llvm-project/clang/lib/Headers
|
llvm-project/clang/lib/Headers
|
||||||
llvm-project/clang/include
|
llvm-project/clang/include
|
||||||
@@ -73,7 +73,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-19-linux-alpine-v1
|
key: llvm-build-20-linux-alpine-v1
|
||||||
path: llvm-build
|
path: llvm-build
|
||||||
- name: Build LLVM
|
- name: Build LLVM
|
||||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||||
@@ -137,7 +137,7 @@ jobs:
|
|||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.24'
|
go-version: '1.25.0'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Install wasmtime
|
- name: Install wasmtime
|
||||||
uses: bytecodealliance/actions/wasmtime/setup@v1
|
uses: bytecodealliance/actions/wasmtime/setup@v1
|
||||||
@@ -181,7 +181,7 @@ jobs:
|
|||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.24'
|
go-version: '1.25.0'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Install Node.js
|
- name: Install Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
@@ -197,7 +197,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-19-linux-asserts-v1
|
key: llvm-source-20-linux-asserts-v1
|
||||||
path: |
|
path: |
|
||||||
llvm-project/clang/lib/Headers
|
llvm-project/clang/lib/Headers
|
||||||
llvm-project/clang/include
|
llvm-project/clang/include
|
||||||
@@ -222,7 +222,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-19-linux-asserts-v1
|
key: llvm-build-20-linux-asserts-v1
|
||||||
path: llvm-build
|
path: llvm-build
|
||||||
- name: Build LLVM
|
- name: Build LLVM
|
||||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||||
@@ -298,13 +298,13 @@ jobs:
|
|||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.24'
|
go-version: '1.25.0'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Restore LLVM source cache
|
- name: Restore LLVM source cache
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-19-linux-v1
|
key: llvm-source-20-linux-v1
|
||||||
path: |
|
path: |
|
||||||
llvm-project/clang/lib/Headers
|
llvm-project/clang/lib/Headers
|
||||||
llvm-project/clang/include
|
llvm-project/clang/include
|
||||||
@@ -329,7 +329,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-19-linux-${{ matrix.goarch }}-v3
|
key: llvm-build-20-linux-${{ matrix.goarch }}-v1
|
||||||
path: llvm-build
|
path: llvm-build
|
||||||
- name: Build LLVM
|
- name: Build LLVM
|
||||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ jobs:
|
|||||||
uses: docker/metadata-action@v5
|
uses: docker/metadata-action@v5
|
||||||
with:
|
with:
|
||||||
images: |
|
images: |
|
||||||
tinygo/llvm-19
|
tinygo/llvm-20
|
||||||
ghcr.io/${{ github.repository_owner }}/llvm-19
|
ghcr.io/${{ github.repository_owner }}/llvm-20
|
||||||
tags: |
|
tags: |
|
||||||
type=sha,format=long
|
type=sha,format=long
|
||||||
type=raw,value=latest
|
type=raw,value=latest
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-19-linux-nix-v1
|
key: llvm-source-20-linux-nix-v1
|
||||||
path: |
|
path: |
|
||||||
llvm-project/compiler-rt
|
llvm-project/compiler-rt
|
||||||
- name: Download LLVM source
|
- name: Download LLVM source
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
# still works after checking out the dev branch (that is, when going from LLVM
|
# 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).
|
# 16 to LLVM 17 for example, both Clang 16 and Clang 17 are installed).
|
||||||
|
|
||||||
echo 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-20 main' | sudo tee /etc/apt/sources.list.d/llvm.list
|
echo 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-21 main' | sudo tee /etc/apt/sources.list.d/llvm.list
|
||||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install --no-install-recommends -y \
|
sudo apt-get install --no-install-recommends -y \
|
||||||
llvm-20-dev \
|
llvm-21-dev \
|
||||||
clang-20 \
|
clang-21 \
|
||||||
libclang-20-dev \
|
libclang-21-dev \
|
||||||
lld-20
|
lld-21
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ jobs:
|
|||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-19-sizediff-v1
|
key: llvm-source-20-sizediff-v1
|
||||||
path: |
|
path: |
|
||||||
llvm-project/compiler-rt
|
llvm-project/compiler-rt
|
||||||
- name: Download LLVM source
|
- name: Download LLVM source
|
||||||
|
|||||||
@@ -41,13 +41,13 @@ jobs:
|
|||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.24'
|
go-version: '1.25.0'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Restore cached LLVM source
|
- name: Restore cached LLVM source
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-source
|
id: cache-llvm-source
|
||||||
with:
|
with:
|
||||||
key: llvm-source-19-windows-v1
|
key: llvm-source-20-windows-v1
|
||||||
path: |
|
path: |
|
||||||
llvm-project/clang/lib/Headers
|
llvm-project/clang/lib/Headers
|
||||||
llvm-project/clang/include
|
llvm-project/clang/include
|
||||||
@@ -72,7 +72,7 @@ jobs:
|
|||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v4
|
||||||
id: cache-llvm-build
|
id: cache-llvm-build
|
||||||
with:
|
with:
|
||||||
key: llvm-build-19-windows-v1
|
key: llvm-build-20-windows-v2
|
||||||
path: llvm-build
|
path: llvm-build
|
||||||
- name: Build LLVM
|
- name: Build LLVM
|
||||||
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
if: steps.cache-llvm-build.outputs.cache-hit != 'true'
|
||||||
@@ -147,7 +147,7 @@ jobs:
|
|||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.24'
|
go-version: '1.25.0'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Download TinyGo build
|
- name: Download TinyGo build
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
@@ -177,7 +177,7 @@ jobs:
|
|||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.24'
|
go-version: '1.25.0'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Download TinyGo build
|
- name: Download TinyGo build
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
@@ -213,7 +213,7 @@ jobs:
|
|||||||
- name: Install Go
|
- name: Install Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.24'
|
go-version: '1.25.0'
|
||||||
cache: true
|
cache: true
|
||||||
- name: Download TinyGo build
|
- name: Download TinyGo build
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@
|
|||||||
url = https://github.com/tinygo-org/stm32-svd
|
url = https://github.com/tinygo-org/stm32-svd
|
||||||
[submodule "lib/musl"]
|
[submodule "lib/musl"]
|
||||||
path = lib/musl
|
path = lib/musl
|
||||||
url = git://git.musl-libc.org/musl
|
url = https://github.com/tinygo-org/musl-libc.git
|
||||||
[submodule "lib/binaryen"]
|
[submodule "lib/binaryen"]
|
||||||
path = lib/binaryen
|
path = lib/binaryen
|
||||||
url = https://github.com/WebAssembly/binaryen.git
|
url = https://github.com/WebAssembly/binaryen.git
|
||||||
|
|||||||
+8
-2
@@ -85,11 +85,17 @@ Try running TinyGo:
|
|||||||
|
|
||||||
./build/tinygo help
|
./build/tinygo help
|
||||||
|
|
||||||
Also, make sure the `tinygo` binary really is statically linked. Check this
|
Also, make sure the `tinygo` binary really is statically linked. The command to check for
|
||||||
using `ldd` (not to be confused with `lld`):
|
dynamic dependencies differs depending on your operating system.
|
||||||
|
|
||||||
|
On Linux, use `ldd` (not to be confused with `lld`):
|
||||||
|
|
||||||
ldd ./build/tinygo
|
ldd ./build/tinygo
|
||||||
|
|
||||||
|
On macOS, use otool -L:
|
||||||
|
|
||||||
|
otool -L ./build/tinygo
|
||||||
|
|
||||||
The result should not contain libclang or libLLVM.
|
The result should not contain libclang or libLLVM.
|
||||||
|
|
||||||
## Make a release tarball
|
## Make a release tarball
|
||||||
|
|||||||
@@ -1,3 +1,55 @@
|
|||||||
|
0.39.0
|
||||||
|
---
|
||||||
|
* **general**
|
||||||
|
- all: add Go 1.25 support
|
||||||
|
- net: update to latest tinygo net package
|
||||||
|
- docs: clarify build verification step for macOS users
|
||||||
|
- Add flag to skip Renesas SVD builds
|
||||||
|
* **build**
|
||||||
|
- Makefile: install missing dlmalloc files
|
||||||
|
- flash: add -o flag support to save built binary (Fixes #4937) (#4942)
|
||||||
|
- fix: update version of clang to 17 to accommodate latest Go 1.25 docker base image
|
||||||
|
* **ci**
|
||||||
|
- chore: update all CI builds to test Go 1.25 release
|
||||||
|
- fix: disable test-newest since CircleCI seems unable to download due to rate-limits on Dockerhub
|
||||||
|
- ci: rename some jobs to avoid churn on every Go/LLVM version bump
|
||||||
|
- ci: make the goroutines test less racy
|
||||||
|
- tests: de-flake goroutines test
|
||||||
|
* **compiler**
|
||||||
|
- compiler: implement internal/abi.Escape
|
||||||
|
* **main**
|
||||||
|
- main: show the compiler error (if any) for `tinygo test -c`
|
||||||
|
- chore: correct GOOS=js name in error messages for WASM
|
||||||
|
* **machine**
|
||||||
|
- machine: add international keys
|
||||||
|
- machine: remove some unnecessary "// peripherals:" comments
|
||||||
|
- machine: add I2C pin comments
|
||||||
|
- machine: standardize I2C errors with "i2c:" prefix
|
||||||
|
- machine: make I2C usable in the simulator
|
||||||
|
- fix: add SPI and I2C to teensy 4.1 (#4943)
|
||||||
|
- `rp2`: use the correct channel mask for rp2350 ADC; hold lock during read (#4938)
|
||||||
|
- `rp2`: disable digital input for analog inputs
|
||||||
|
* **runtime**
|
||||||
|
- runtime: ensure time.Sleep(d) sleeps at least d
|
||||||
|
- runtime: stub out weak pointer support
|
||||||
|
- runtime: implement dummy AddCleanup
|
||||||
|
- runtime: enable multi-core scheduler for rp2350
|
||||||
|
- `internal/task`: use -stack-size flag when starting a new thread
|
||||||
|
- `internal/task`: add SA_RESTART flag to GC interrupts
|
||||||
|
- `internal/task`: a few small correctness fixes
|
||||||
|
- `internal/gclayout`: make gclayout values constants
|
||||||
|
- darwin: add threading support and use it by default
|
||||||
|
* **standard library**
|
||||||
|
- `sync`: implement sync.Swap
|
||||||
|
- `reflect`: implement Method.IsExported
|
||||||
|
* **testing**
|
||||||
|
- testing: stub out testing.B.Loop
|
||||||
|
* **targets**
|
||||||
|
- `stm32`: add support for the STM32L031G6U6
|
||||||
|
- add metro-rp2350 board definition (#4989)
|
||||||
|
- `rp2040/rp2350`: set the default stack size to 8k for rp2040/rp2350 based boards where this was not already the case
|
||||||
|
|
||||||
|
|
||||||
0.38.0
|
0.38.0
|
||||||
---
|
---
|
||||||
* **general**
|
* **general**
|
||||||
|
|||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
# tinygo-llvm stage obtains the llvm source for TinyGo
|
# tinygo-llvm stage obtains the llvm source for TinyGo
|
||||||
FROM golang:1.24 AS tinygo-llvm
|
FROM golang:1.25 AS tinygo-llvm
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y apt-utils make cmake clang-15 ninja-build && \
|
apt-get install -y apt-utils make cmake clang-17 ninja-build && \
|
||||||
rm -rf \
|
rm -rf \
|
||||||
/var/lib/apt/lists/* \
|
/var/lib/apt/lists/* \
|
||||||
/var/log/* \
|
/var/log/* \
|
||||||
@@ -33,7 +33,7 @@ RUN cd /tinygo/ && \
|
|||||||
|
|
||||||
# tinygo-compiler copies the compiler build over to a base Go container (without
|
# tinygo-compiler copies the compiler build over to a base Go container (without
|
||||||
# all the build tools etc).
|
# all the build tools etc).
|
||||||
FROM golang:1.24 AS tinygo-compiler
|
FROM golang:1.25 AS tinygo-compiler
|
||||||
|
|
||||||
# Copy tinygo build.
|
# Copy tinygo build.
|
||||||
COPY --from=tinygo-compiler-build /tinygo/build/release/tinygo /tinygo
|
COPY --from=tinygo-compiler-build /tinygo/build/release/tinygo /tinygo
|
||||||
|
|||||||
+53
-14
@@ -79,6 +79,26 @@ ifeq (1, $(STATIC))
|
|||||||
BINARYEN_OPTION += -DCMAKE_CXX_FLAGS="-static" -DCMAKE_C_FLAGS="-static"
|
BINARYEN_OPTION += -DCMAKE_CXX_FLAGS="-static" -DCMAKE_C_FLAGS="-static"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Optimize the binary size for Linux.
|
||||||
|
# These flags may work on other platforms, but have only been tested on Linux.
|
||||||
|
ifeq ($(uname),Linux)
|
||||||
|
HAS_MOLD := $(shell command -v ld.mold 2> /dev/null)
|
||||||
|
HAS_LLD := $(shell command -v ld.lld 2> /dev/null)
|
||||||
|
LLVM_CFLAGS := -ffunction-sections -fdata-sections -fvisibility=hidden
|
||||||
|
LLVM_LDFLAGS := -Wl,--gc-sections
|
||||||
|
ifneq ($(HAS_MOLD),)
|
||||||
|
# Mold might be slightly faster.
|
||||||
|
LLVM_LDFLAGS += -fuse-ld=mold -Wl,--icf=all
|
||||||
|
else ifneq ($(HAS_LLD),)
|
||||||
|
# LLD is more commonly available.
|
||||||
|
LLVM_LDFLAGS += -fuse-ld=lld -Wl,--icf=all
|
||||||
|
endif
|
||||||
|
LLVM_OPTION += \
|
||||||
|
-DCMAKE_C_FLAGS="$(LLVM_CFLAGS)" \
|
||||||
|
-DCMAKE_CXX_FLAGS="$(LLVM_CFLAGS)"
|
||||||
|
CGO_LDFLAGS += $(LLVM_LDFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
# Cross compiling support.
|
# Cross compiling support.
|
||||||
ifneq ($(CROSS),)
|
ifneq ($(CROSS),)
|
||||||
CC = $(CROSS)-gcc
|
CC = $(CROSS)-gcc
|
||||||
@@ -187,7 +207,10 @@ fmt-check: ## Warn if any source needs reformatting
|
|||||||
@unformatted=$$(gofmt -l $(FMT_PATHS)); [ -z "$$unformatted" ] && exit 0; echo "Unformatted:"; for fn in $$unformatted; do echo " $$fn"; done; exit 1
|
@unformatted=$$(gofmt -l $(FMT_PATHS)); [ -z "$$unformatted" ] && exit 0; echo "Unformatted:"; for fn in $$unformatted; do echo " $$fn"; done; exit 1
|
||||||
|
|
||||||
|
|
||||||
gen-device: gen-device-avr gen-device-esp gen-device-nrf gen-device-sam gen-device-sifive gen-device-kendryte gen-device-nxp gen-device-rp gen-device-renesas ## Generate microcontroller-specific sources
|
gen-device: gen-device-avr gen-device-esp gen-device-nrf gen-device-sam gen-device-sifive gen-device-kendryte gen-device-nxp gen-device-rp ## Generate microcontroller-specific sources
|
||||||
|
ifneq ($(RENESAS), 0)
|
||||||
|
gen-device: gen-device-renesas
|
||||||
|
endif
|
||||||
ifneq ($(STM32), 0)
|
ifneq ($(STM32), 0)
|
||||||
gen-device: gen-device-stm32
|
gen-device: gen-device-stm32
|
||||||
endif
|
endif
|
||||||
@@ -240,7 +263,7 @@ gen-device-renesas: build/gen-device-svd
|
|||||||
GO111MODULE=off $(GO) fmt ./src/device/renesas
|
GO111MODULE=off $(GO) fmt ./src/device/renesas
|
||||||
|
|
||||||
$(LLVM_PROJECTDIR)/llvm:
|
$(LLVM_PROJECTDIR)/llvm:
|
||||||
git clone -b xtensa_release_19.1.2 --depth=1 https://github.com/espressif/llvm-project $(LLVM_PROJECTDIR)
|
git clone -b tinygo_20.x --depth=1 https://github.com/tinygo-org/llvm-project $(LLVM_PROJECTDIR)
|
||||||
llvm-source: $(LLVM_PROJECTDIR)/llvm ## Get LLVM sources
|
llvm-source: $(LLVM_PROJECTDIR)/llvm ## Get LLVM sources
|
||||||
|
|
||||||
# Configure LLVM.
|
# Configure LLVM.
|
||||||
@@ -457,11 +480,15 @@ TEST_PACKAGES_HOST := $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_WINDOWS)
|
|||||||
TEST_IOFS := false
|
TEST_IOFS := false
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
TEST_SKIP_FLAG := -skip='TestExtraMethods|TestParseAndBytesRoundTrip/P256/Generic'
|
||||||
|
|
||||||
# Test known-working standard library packages.
|
# Test known-working standard library packages.
|
||||||
# TODO: parallelize, and only show failing tests (no implied -v flag).
|
# TODO: parallelize, and only show failing tests (no implied -v flag).
|
||||||
.PHONY: tinygo-test
|
.PHONY: tinygo-test
|
||||||
tinygo-test:
|
tinygo-test:
|
||||||
$(TINYGO) test $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
|
@# TestExtraMethods: used by many crypto packages and uses reflect.Type.Method which is not implemented.
|
||||||
|
@# TestParseAndBytesRoundTrip/P256/Generic: relies on t.Skip() which is not implemented
|
||||||
|
$(TINYGO) test $(TEST_SKIP_FLAG) $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
|
||||||
@# io/fs requires os.ReadDir, not yet supported on windows or wasi. It also
|
@# io/fs requires os.ReadDir, not yet supported on windows or wasi. It also
|
||||||
@# requires a large stack-size. Hence, io/fs is only run conditionally.
|
@# requires a large stack-size. Hence, io/fs is only run conditionally.
|
||||||
@# For more details, see the comments on issue #3143.
|
@# For more details, see the comments on issue #3143.
|
||||||
@@ -469,7 +496,7 @@ ifeq ($(TEST_IOFS),true)
|
|||||||
$(TINYGO) test -stack-size=6MB io/fs
|
$(TINYGO) test -stack-size=6MB io/fs
|
||||||
endif
|
endif
|
||||||
tinygo-test-fast:
|
tinygo-test-fast:
|
||||||
$(TINYGO) test $(TEST_PACKAGES_HOST)
|
$(TINYGO) test $(TEST_SKIP_FLAG) $(TEST_PACKAGES_HOST)
|
||||||
tinygo-bench:
|
tinygo-bench:
|
||||||
$(TINYGO) test -bench . $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
|
$(TINYGO) test -bench . $(TEST_PACKAGES_HOST) $(TEST_PACKAGES_SLOW)
|
||||||
tinygo-bench-fast:
|
tinygo-bench-fast:
|
||||||
@@ -477,18 +504,18 @@ tinygo-bench-fast:
|
|||||||
|
|
||||||
# Same thing, except for wasi rather than the current platform.
|
# Same thing, except for wasi rather than the current platform.
|
||||||
tinygo-test-wasm:
|
tinygo-test-wasm:
|
||||||
$(TINYGO) test -target wasm $(TEST_PACKAGES_WASM)
|
$(TINYGO) test -target wasm $(TEST_SKIP_FLAG) $(TEST_PACKAGES_WASM)
|
||||||
tinygo-test-wasi:
|
tinygo-test-wasi:
|
||||||
$(TINYGO) test -target wasip1 $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
$(TINYGO) test -target wasip1 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
||||||
tinygo-test-wasip1:
|
tinygo-test-wasip1:
|
||||||
GOOS=wasip1 GOARCH=wasm $(TINYGO) test $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
GOOS=wasip1 GOARCH=wasm $(TINYGO) test $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) $(TEST_PACKAGES_SLOW) ./tests/runtime_wasi
|
||||||
tinygo-test-wasip1-fast:
|
tinygo-test-wasip1-fast:
|
||||||
$(TINYGO) test -target=wasip1 $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
$(TINYGO) test -target=wasip1 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
||||||
|
|
||||||
tinygo-test-wasip2-slow:
|
tinygo-test-wasip2-slow:
|
||||||
$(TINYGO) test -target=wasip2 $(TEST_PACKAGES_SLOW)
|
$(TINYGO) test -target=wasip2 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_SLOW)
|
||||||
tinygo-test-wasip2-fast:
|
tinygo-test-wasip2-fast:
|
||||||
$(TINYGO) test -target=wasip2 $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
$(TINYGO) test -target=wasip2 $(TEST_SKIP_FLAG) $(TEST_PACKAGES_FAST) ./tests/runtime_wasi
|
||||||
|
|
||||||
tinygo-test-wasip2-sum-slow:
|
tinygo-test-wasip2-sum-slow:
|
||||||
TINYGO=$(TINYGO) \
|
TINYGO=$(TINYGO) \
|
||||||
@@ -514,7 +541,7 @@ tinygo-bench-wasip2-fast:
|
|||||||
|
|
||||||
# Run tests on riscv-qemu since that one provides a large amount of memory.
|
# Run tests on riscv-qemu since that one provides a large amount of memory.
|
||||||
tinygo-test-baremetal:
|
tinygo-test-baremetal:
|
||||||
$(TINYGO) test -target riscv-qemu $(TEST_PACKAGES_BAREMETAL)
|
$(TINYGO) test -target riscv-qemu $(TEST_SKIP_FLAG) $(TEST_PACKAGES_BAREMETAL)
|
||||||
|
|
||||||
# Test external packages in a large corpus.
|
# Test external packages in a large corpus.
|
||||||
test-corpus:
|
test-corpus:
|
||||||
@@ -768,6 +795,8 @@ endif
|
|||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=gopher-badge examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=gopher-badge examples/blinky1
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
|
$(TINYGO) build -size short -o test.hex -target=gopher-arcade examples/blinky1
|
||||||
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=ae-rp2040 examples/echo
|
$(TINYGO) build -size short -o test.hex -target=ae-rp2040 examples/echo
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=thumby examples/echo
|
$(TINYGO) build -size short -o test.hex -target=thumby examples/echo
|
||||||
@@ -778,6 +807,8 @@ endif
|
|||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=pico-plus2 examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=pico-plus2 examples/blinky1
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
|
$(TINYGO) build -size short -o test.hex -target=metro-rp2350 examples/blinky1
|
||||||
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=waveshare-rp2040-tiny examples/echo
|
$(TINYGO) build -size short -o test.hex -target=waveshare-rp2040-tiny examples/echo
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
# test pwm
|
# test pwm
|
||||||
@@ -837,6 +868,8 @@ ifneq ($(STM32), 0)
|
|||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=mksnanov3 examples/blinky1
|
$(TINYGO) build -size short -o test.hex -target=mksnanov3 examples/blinky1
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
|
$(TINYGO) build -size short -o test.hex -target=stm32l0x1 examples/serial
|
||||||
|
@$(MD5SUM) test.hex
|
||||||
endif
|
endif
|
||||||
$(TINYGO) build -size short -o test.hex -target=atmega328pb examples/blinkm
|
$(TINYGO) build -size short -o test.hex -target=atmega328pb examples/blinkm
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
@@ -907,7 +940,7 @@ endif
|
|||||||
$(TINYGO) build -size short -o test.hex -target=hw-651 examples/machinetest
|
$(TINYGO) build -size short -o test.hex -target=hw-651 examples/machinetest
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
$(TINYGO) build -size short -o test.hex -target=hw-651-s110v8 examples/machinetest
|
$(TINYGO) build -size short -o test.hex -target=hw-651-s110v8 examples/machinetest
|
||||||
@$(MD5SUM) test.hex
|
@$(MD5SUM) test.hex
|
||||||
ifneq ($(WASM), 0)
|
ifneq ($(WASM), 0)
|
||||||
$(TINYGO) build -size short -o wasm.wasm -target=wasm examples/wasm/export
|
$(TINYGO) build -size short -o wasm.wasm -target=wasm examples/wasm/export
|
||||||
$(TINYGO) build -size short -o wasm.wasm -target=wasm examples/wasm/main
|
$(TINYGO) build -size short -o wasm.wasm -target=wasm examples/wasm/main
|
||||||
@@ -940,7 +973,7 @@ endif
|
|||||||
|
|
||||||
|
|
||||||
wasmtest:
|
wasmtest:
|
||||||
$(GO) test ./tests/wasm
|
cd ./tests/wasm && $(GO) test .
|
||||||
|
|
||||||
build/release: tinygo gen-device $(if $(filter 1,$(USE_SYSTEM_BINARYEN)),,binaryen)
|
build/release: tinygo gen-device $(if $(filter 1,$(USE_SYSTEM_BINARYEN)),,binaryen)
|
||||||
@mkdir -p build/release/tinygo/bin
|
@mkdir -p build/release/tinygo/bin
|
||||||
@@ -958,6 +991,7 @@ build/release: tinygo gen-device $(if $(filter 1,$(USE_SYSTEM_BINARYEN)),,binary
|
|||||||
@mkdir -p build/release/tinygo/lib/nrfx
|
@mkdir -p build/release/tinygo/lib/nrfx
|
||||||
@mkdir -p build/release/tinygo/lib/picolibc/newlib/libc
|
@mkdir -p build/release/tinygo/lib/picolibc/newlib/libc
|
||||||
@mkdir -p build/release/tinygo/lib/picolibc/newlib/libm
|
@mkdir -p build/release/tinygo/lib/picolibc/newlib/libm
|
||||||
|
@mkdir -p build/release/tinygo/lib/wasi-libc/dlmalloc
|
||||||
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-bottom-half
|
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-bottom-half
|
||||||
@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/arch
|
||||||
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
|
@mkdir -p build/release/tinygo/lib/wasi-libc/libc-top-half/musl/src
|
||||||
@@ -1029,6 +1063,7 @@ endif
|
|||||||
@cp -rp lib/picolibc/newlib/libm/common build/release/tinygo/lib/picolibc/newlib/libm
|
@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/newlib/libm/math build/release/tinygo/lib/picolibc/newlib/libm
|
||||||
@cp -rp lib/picolibc-stdio.c build/release/tinygo/lib
|
@cp -rp lib/picolibc-stdio.c build/release/tinygo/lib
|
||||||
|
@cp -rp lib/wasi-libc/dlmalloc/src build/release/tinygo/lib/wasi-libc/dlmalloc
|
||||||
@cp -rp lib/wasi-libc/libc-bottom-half/cloudlibc build/release/tinygo/lib/wasi-libc/libc-bottom-half
|
@cp -rp lib/wasi-libc/libc-bottom-half/cloudlibc build/release/tinygo/lib/wasi-libc/libc-bottom-half
|
||||||
@cp -rp lib/wasi-libc/libc-bottom-half/headers build/release/tinygo/lib/wasi-libc/libc-bottom-half
|
@cp -rp lib/wasi-libc/libc-bottom-half/headers build/release/tinygo/lib/wasi-libc/libc-bottom-half
|
||||||
@cp -rp lib/wasi-libc/libc-bottom-half/sources build/release/tinygo/lib/wasi-libc/libc-bottom-half
|
@cp -rp lib/wasi-libc/libc-bottom-half/sources build/release/tinygo/lib/wasi-libc/libc-bottom-half
|
||||||
@@ -1085,6 +1120,7 @@ endif
|
|||||||
tools:
|
tools:
|
||||||
cd internal/tools && go generate -tags tools ./
|
cd internal/tools && go generate -tags tools ./
|
||||||
|
|
||||||
|
LINTDIRS=src/os/ src/reflect/
|
||||||
.PHONY: lint
|
.PHONY: lint
|
||||||
lint: tools ## Lint source tree
|
lint: tools ## Lint source tree
|
||||||
revive -version
|
revive -version
|
||||||
@@ -1092,7 +1128,10 @@ lint: tools ## Lint source tree
|
|||||||
# revive.toml isn't flexible enough to filter out just one kind of error from a checker, so do it with grep here.
|
# 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.
|
# Can't use grep with friendly formatter. Plain output isn't too bad, though.
|
||||||
# Use 'grep .' to get rid of stray blank line
|
# Use 'grep .' to get rid of stray blank line
|
||||||
revive -config revive.toml compiler/... src/{os,reflect}/*.go | grep -v "should have comment or be unexported" | grep '.' | awk '{print}; END {exit NR>0}'
|
revive -config revive.toml compiler/... $$( find $(LINTDIRS) -type f -name '*.go' ) \
|
||||||
|
| grep -v "should have comment or be unexported" \
|
||||||
|
| grep '.' \
|
||||||
|
| awk '{print}; END {exit NR>0}'
|
||||||
|
|
||||||
SPELLDIRSCMD=find . -depth 1 -type d | egrep -wv '.git|lib|llvm|src'; find src -depth 1 | egrep -wv 'device|internal|net|vendor'; find src/internal -depth 1 -type d | egrep -wv src/internal/wasi
|
SPELLDIRSCMD=find . -depth 1 -type d | egrep -wv '.git|lib|llvm|src'; find src -depth 1 | egrep -wv 'device|internal|net|vendor'; find src/internal -depth 1 -type d | egrep -wv src/internal/wasi
|
||||||
.PHONY: spell
|
.PHONY: spell
|
||||||
|
|||||||
+1
-1
@@ -1046,7 +1046,7 @@ func Build(pkgName, outpath, tmpdir string, config *compileopts.Config) (BuildRe
|
|||||||
// Special format for the ESP family of chips (parsed by the ROM
|
// Special format for the ESP family of chips (parsed by the ROM
|
||||||
// bootloader).
|
// bootloader).
|
||||||
result.Binary = filepath.Join(tmpdir, "main"+outext)
|
result.Binary = filepath.Join(tmpdir, "main"+outext)
|
||||||
err := makeESPFirmareImage(result.Executable, result.Binary, outputBinaryFormat)
|
err := makeESPFirmwareImage(result.Executable, result.Binary, outputBinaryFormat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-8
@@ -144,8 +144,6 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
|
|||||||
.Default(llvm::DebugCompressionType::None);
|
.Default(llvm::DebugCompressionType::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
Opts.RelaxELFRelocations = !Args.hasArg(OPT_mrelax_relocations_no);
|
|
||||||
Opts.SSE2AVX = Args.hasArg(OPT_msse2avx);
|
|
||||||
if (auto *DwarfFormatArg = Args.getLastArg(OPT_gdwarf64, OPT_gdwarf32))
|
if (auto *DwarfFormatArg = Args.getLastArg(OPT_gdwarf64, OPT_gdwarf32))
|
||||||
Opts.Dwarf64 = DwarfFormatArg->getOption().matches(OPT_gdwarf64);
|
Opts.Dwarf64 = DwarfFormatArg->getOption().matches(OPT_gdwarf64);
|
||||||
Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 2, Diags);
|
Opts.DwarfVersion = getLastArgIntValue(Args, OPT_dwarf_version_EQ, 2, Diags);
|
||||||
@@ -236,6 +234,9 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
|
|||||||
Opts.EmitCompactUnwindNonCanonical =
|
Opts.EmitCompactUnwindNonCanonical =
|
||||||
Args.hasArg(OPT_femit_compact_unwind_non_canonical);
|
Args.hasArg(OPT_femit_compact_unwind_non_canonical);
|
||||||
Opts.Crel = Args.hasArg(OPT_crel);
|
Opts.Crel = Args.hasArg(OPT_crel);
|
||||||
|
Opts.ImplicitMapsyms = Args.hasArg(OPT_mmapsyms_implicit);
|
||||||
|
Opts.X86RelaxRelocations = !Args.hasArg(OPT_mrelax_relocations_no);
|
||||||
|
Opts.X86Sse2Avx = Args.hasArg(OPT_msse2avx);
|
||||||
|
|
||||||
Opts.AsSecureLogFile = Args.getLastArgValue(OPT_as_secure_log_file);
|
Opts.AsSecureLogFile = Args.getLastArgValue(OPT_as_secure_log_file);
|
||||||
|
|
||||||
@@ -294,8 +295,9 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
|
|||||||
MCOptions.EmitCompactUnwindNonCanonical = Opts.EmitCompactUnwindNonCanonical;
|
MCOptions.EmitCompactUnwindNonCanonical = Opts.EmitCompactUnwindNonCanonical;
|
||||||
MCOptions.MCSaveTempLabels = Opts.SaveTemporaryLabels;
|
MCOptions.MCSaveTempLabels = Opts.SaveTemporaryLabels;
|
||||||
MCOptions.Crel = Opts.Crel;
|
MCOptions.Crel = Opts.Crel;
|
||||||
MCOptions.X86RelaxRelocations = Opts.RelaxELFRelocations;
|
MCOptions.ImplicitMapSyms = Opts.ImplicitMapsyms;
|
||||||
MCOptions.X86Sse2Avx = Opts.SSE2AVX;
|
MCOptions.X86RelaxRelocations = Opts.X86RelaxRelocations;
|
||||||
|
MCOptions.X86Sse2Avx = Opts.X86Sse2Avx;
|
||||||
MCOptions.CompressDebugSections = Opts.CompressDebugSections;
|
MCOptions.CompressDebugSections = Opts.CompressDebugSections;
|
||||||
MCOptions.AsSecureLogFile = Opts.AsSecureLogFile;
|
MCOptions.AsSecureLogFile = Opts.AsSecureLogFile;
|
||||||
|
|
||||||
@@ -343,10 +345,6 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
|
|||||||
// MCObjectFileInfo needs a MCContext reference in order to initialize itself.
|
// MCObjectFileInfo needs a MCContext reference in order to initialize itself.
|
||||||
std::unique_ptr<MCObjectFileInfo> MOFI(
|
std::unique_ptr<MCObjectFileInfo> MOFI(
|
||||||
TheTarget->createMCObjectFileInfo(Ctx, PIC));
|
TheTarget->createMCObjectFileInfo(Ctx, PIC));
|
||||||
if (Opts.DarwinTargetVariantTriple)
|
|
||||||
MOFI->setDarwinTargetVariantTriple(*Opts.DarwinTargetVariantTriple);
|
|
||||||
if (!Opts.DarwinTargetVariantSDKVersion.empty())
|
|
||||||
MOFI->setDarwinTargetVariantSDKVersion(Opts.DarwinTargetVariantSDKVersion);
|
|
||||||
Ctx.setObjectFileInfo(MOFI.get());
|
Ctx.setObjectFileInfo(MOFI.get());
|
||||||
|
|
||||||
if (Opts.GenDwarfForAssembly)
|
if (Opts.GenDwarfForAssembly)
|
||||||
@@ -428,6 +426,13 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
|
|||||||
Str.reset(TheTarget->createMCObjectStreamer(
|
Str.reset(TheTarget->createMCObjectStreamer(
|
||||||
T, Ctx, std::move(MAB), std::move(OW), std::move(CE), *STI));
|
T, Ctx, std::move(MAB), std::move(OW), std::move(CE), *STI));
|
||||||
Str.get()->initSections(Opts.NoExecStack, *STI);
|
Str.get()->initSections(Opts.NoExecStack, *STI);
|
||||||
|
if (T.isOSBinFormatMachO() && T.isOSDarwin()) {
|
||||||
|
Triple *TVT = Opts.DarwinTargetVariantTriple
|
||||||
|
? &*Opts.DarwinTargetVariantTriple
|
||||||
|
: nullptr;
|
||||||
|
Str->emitVersionForTarget(T, VersionTuple(), TVT,
|
||||||
|
Opts.DarwinTargetVariantSDKVersion);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When -fembed-bitcode is passed to clang_as, a 1-byte marker
|
// When -fembed-bitcode is passed to clang_as, a 1-byte marker
|
||||||
|
|||||||
+10
-5
@@ -45,10 +45,6 @@ struct AssemblerInvocation {
|
|||||||
LLVM_PREFERRED_TYPE(bool)
|
LLVM_PREFERRED_TYPE(bool)
|
||||||
unsigned GenDwarfForAssembly : 1;
|
unsigned GenDwarfForAssembly : 1;
|
||||||
LLVM_PREFERRED_TYPE(bool)
|
LLVM_PREFERRED_TYPE(bool)
|
||||||
unsigned RelaxELFRelocations : 1;
|
|
||||||
LLVM_PREFERRED_TYPE(bool)
|
|
||||||
unsigned SSE2AVX : 1;
|
|
||||||
LLVM_PREFERRED_TYPE(bool)
|
|
||||||
unsigned Dwarf64 : 1;
|
unsigned Dwarf64 : 1;
|
||||||
unsigned DwarfVersion;
|
unsigned DwarfVersion;
|
||||||
std::string DwarfDebugFlags;
|
std::string DwarfDebugFlags;
|
||||||
@@ -117,6 +113,13 @@ struct AssemblerInvocation {
|
|||||||
|
|
||||||
LLVM_PREFERRED_TYPE(bool)
|
LLVM_PREFERRED_TYPE(bool)
|
||||||
unsigned Crel : 1;
|
unsigned Crel : 1;
|
||||||
|
LLVM_PREFERRED_TYPE(bool)
|
||||||
|
unsigned ImplicitMapsyms : 1;
|
||||||
|
|
||||||
|
LLVM_PREFERRED_TYPE(bool)
|
||||||
|
unsigned X86RelaxRelocations : 1;
|
||||||
|
LLVM_PREFERRED_TYPE(bool)
|
||||||
|
unsigned X86Sse2Avx : 1;
|
||||||
|
|
||||||
/// The name of the relocation model to use.
|
/// The name of the relocation model to use.
|
||||||
std::string RelocationModel;
|
std::string RelocationModel;
|
||||||
@@ -148,7 +151,6 @@ public:
|
|||||||
ShowInst = 0;
|
ShowInst = 0;
|
||||||
ShowEncoding = 0;
|
ShowEncoding = 0;
|
||||||
RelaxAll = 0;
|
RelaxAll = 0;
|
||||||
SSE2AVX = 0;
|
|
||||||
NoExecStack = 0;
|
NoExecStack = 0;
|
||||||
FatalWarnings = 0;
|
FatalWarnings = 0;
|
||||||
NoWarn = 0;
|
NoWarn = 0;
|
||||||
@@ -160,6 +162,9 @@ public:
|
|||||||
EmitDwarfUnwind = EmitDwarfUnwindType::Default;
|
EmitDwarfUnwind = EmitDwarfUnwindType::Default;
|
||||||
EmitCompactUnwindNonCanonical = false;
|
EmitCompactUnwindNonCanonical = false;
|
||||||
Crel = false;
|
Crel = false;
|
||||||
|
ImplicitMapsyms = 0;
|
||||||
|
X86RelaxRelocations = 0;
|
||||||
|
X86Sse2Avx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CreateFromArgs(AssemblerInvocation &Res,
|
static bool CreateFromArgs(AssemblerInvocation &Res,
|
||||||
|
|||||||
+1
-1
@@ -60,7 +60,7 @@ bool tinygo_clang_driver(int argc, char **argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create the actual diagnostics engine.
|
// Create the actual diagnostics engine.
|
||||||
Clang->createDiagnostics();
|
Clang->createDiagnostics(*llvm::vfs::getRealFileSystem());
|
||||||
if (!Clang->hasDiagnostics()) {
|
if (!Clang->hasDiagnostics()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@ func NewConfig(options *compileopts.Options) (*compileopts.Config, error) {
|
|||||||
|
|
||||||
// Version range supported by TinyGo.
|
// Version range supported by TinyGo.
|
||||||
const minorMin = 19
|
const minorMin = 19
|
||||||
const minorMax = 24
|
const minorMax = 25
|
||||||
|
|
||||||
// Check that we support this Go toolchain version.
|
// Check that we support this Go toolchain version.
|
||||||
gorootMajor, gorootMinor, err := goenv.GetGorootVersion()
|
gorootMajor, gorootMinor, err := goenv.GetGorootVersion()
|
||||||
|
|||||||
+2
-2
@@ -23,7 +23,7 @@ type espImageSegment struct {
|
|||||||
data []byte
|
data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeESPFirmareImage converts an input ELF file to an image file for an ESP32 or
|
// makeESPFirmwareImage converts an input ELF file to an image file for an ESP32 or
|
||||||
// ESP8266 chip. This is a special purpose image format just for the ESP chip
|
// ESP8266 chip. This is a special purpose image format just for the ESP chip
|
||||||
// family, and is parsed by the on-chip mask ROM bootloader.
|
// family, and is parsed by the on-chip mask ROM bootloader.
|
||||||
//
|
//
|
||||||
@@ -31,7 +31,7 @@ type espImageSegment struct {
|
|||||||
// https://github.com/espressif/esptool/wiki/Firmware-Image-Format
|
// https://github.com/espressif/esptool/wiki/Firmware-Image-Format
|
||||||
// https://github.com/espressif/esp-idf/blob/8fbb63c2a701c22ccf4ce249f43aded73e134a34/components/bootloader_support/include/esp_image_format.h#L58
|
// https://github.com/espressif/esp-idf/blob/8fbb63c2a701c22ccf4ce249f43aded73e134a34/components/bootloader_support/include/esp_image_format.h#L58
|
||||||
// https://github.com/espressif/esptool/blob/master/esptool.py
|
// https://github.com/espressif/esptool/blob/master/esptool.py
|
||||||
func makeESPFirmareImage(infile, outfile, format string) error {
|
func makeESPFirmwareImage(infile, outfile, format string) error {
|
||||||
inf, err := elf.Open(infile)
|
inf, err := elf.Open(infile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -42,9 +42,9 @@ func TestBinarySize(t *testing.T) {
|
|||||||
// This is a small number of very diverse targets that we want to test.
|
// This is a small number of very diverse targets that we want to test.
|
||||||
tests := []sizeTest{
|
tests := []sizeTest{
|
||||||
// microcontrollers
|
// microcontrollers
|
||||||
{"hifive1b", "examples/echo", 4556, 280, 0, 2264},
|
{"hifive1b", "examples/echo", 3884, 280, 0, 2268},
|
||||||
{"microbit", "examples/serial", 2920, 388, 8, 2272},
|
{"microbit", "examples/serial", 2924, 388, 8, 2272},
|
||||||
{"wioterminal", "examples/pininterrupt", 7379, 1489, 116, 6912},
|
{"wioterminal", "examples/pininterrupt", 7365, 1491, 116, 6912},
|
||||||
|
|
||||||
// TODO: also check wasm. Right now this is difficult, because
|
// TODO: also check wasm. Right now this is difficult, because
|
||||||
// wasm binaries are run through wasm-opt and therefore the
|
// wasm binaries are run through wasm-opt and therefore the
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
// Hide a warning in LLVM 21 that doesn't apply to us (appears to be a side
|
||||||
|
// effect of how CGo processes C header files).
|
||||||
|
#cgo CFLAGS: -Wno-deprecated-declarations
|
||||||
|
|
||||||
#include <clang-c/Index.h> // If this fails, libclang headers aren't available. Please take a look here: https://tinygo.org/docs/guides/build/
|
#include <clang-c/Index.h> // If this fails, libclang headers aren't available. Please take a look here: https://tinygo.org/docs/guides/build/
|
||||||
#include <llvm/Config/llvm-config.h>
|
#include <llvm/Config/llvm-config.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
//go:build !byollvm && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19
|
//go:build !byollvm && llvm20
|
||||||
|
|
||||||
package cgo
|
package cgo
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
//go:build !byollvm && !llvm15 && !llvm16 && !llvm17 && !llvm18 && !llvm19 && !llvm20
|
||||||
|
|
||||||
|
package cgo
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo linux CFLAGS: -I/usr/include/llvm-21 -I/usr/include/llvm-c-21 -I/usr/lib/llvm-21/include
|
||||||
|
#cgo darwin,amd64 CFLAGS: -I/usr/local/opt/llvm@21/include
|
||||||
|
#cgo darwin,arm64 CFLAGS: -I/opt/homebrew/opt/llvm@21/include
|
||||||
|
#cgo freebsd CFLAGS: -I/usr/local/llvm21/include
|
||||||
|
#cgo linux LDFLAGS: -L/usr/lib/llvm-21/lib -lclang
|
||||||
|
#cgo darwin,amd64 LDFLAGS: -L/usr/local/opt/llvm@21/lib -lclang
|
||||||
|
#cgo darwin,arm64 LDFLAGS: -L/opt/homebrew/opt/llvm@21/lib -lclang
|
||||||
|
#cgo freebsd LDFLAGS: -L/usr/local/llvm21/lib -lclang
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
@@ -189,7 +189,7 @@ func LoadTarget(options *Options) (*TargetSpec, error) {
|
|||||||
case "wasip2":
|
case "wasip2":
|
||||||
options.Target = "wasip2"
|
options.Target = "wasip2"
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("GOARCH=wasm but GOOS is not set correctly. Please set GOOS to wasm, wasip1, or wasip2.")
|
return nil, errors.New("GOARCH=wasm but GOOS is not set correctly. Please set GOOS to js, wasip1, or wasip2.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,7 +369,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
|
|||||||
return nil, fmt.Errorf("invalid GOMIPS=%s: must be hardfloat or softfloat", options.GOMIPS)
|
return nil, fmt.Errorf("invalid GOMIPS=%s: must be hardfloat or softfloat", options.GOMIPS)
|
||||||
}
|
}
|
||||||
case "wasm":
|
case "wasm":
|
||||||
return nil, fmt.Errorf("GOARCH=wasm but GOOS is unset. Please set GOOS to wasm, wasip1, or wasip2.")
|
return nil, fmt.Errorf("GOARCH=wasm but GOOS is unset. Please set GOOS to js, wasip1, or wasip2.")
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unknown GOARCH=%s", options.GOARCH)
|
return nil, fmt.Errorf("unknown GOARCH=%s", options.GOARCH)
|
||||||
}
|
}
|
||||||
@@ -385,7 +385,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
|
|||||||
platformVersion = "11.0.0" // first macosx platform with arm64 support
|
platformVersion = "11.0.0" // first macosx platform with arm64 support
|
||||||
}
|
}
|
||||||
llvmvendor = "apple"
|
llvmvendor = "apple"
|
||||||
spec.Scheduler = "tasks"
|
spec.Scheduler = "threads"
|
||||||
spec.Linker = "ld.lld"
|
spec.Linker = "ld.lld"
|
||||||
spec.Libc = "darwin-libSystem"
|
spec.Libc = "darwin-libSystem"
|
||||||
// Use macosx* instead of darwin, otherwise darwin/arm64 will refer to
|
// Use macosx* instead of darwin, otherwise darwin/arm64 will refer to
|
||||||
@@ -399,6 +399,7 @@ func defaultTarget(options *Options) (*TargetSpec, error) {
|
|||||||
)
|
)
|
||||||
spec.ExtraFiles = append(spec.ExtraFiles,
|
spec.ExtraFiles = append(spec.ExtraFiles,
|
||||||
"src/internal/futex/futex_darwin.c",
|
"src/internal/futex/futex_darwin.c",
|
||||||
|
"src/internal/task/task_threads.c",
|
||||||
"src/runtime/os_darwin.c",
|
"src/runtime/os_darwin.c",
|
||||||
"src/runtime/runtime_unix.c",
|
"src/runtime/runtime_unix.c",
|
||||||
"src/runtime/signal.c")
|
"src/runtime/signal.c")
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ type compilerContext struct {
|
|||||||
funcPtrType llvm.Type // pointer in function address space (1 for AVR, 0 elsewhere)
|
funcPtrType llvm.Type // pointer in function address space (1 for AVR, 0 elsewhere)
|
||||||
funcPtrAddrSpace int
|
funcPtrAddrSpace int
|
||||||
uintptrType llvm.Type
|
uintptrType llvm.Type
|
||||||
|
nocaptureAttr llvm.Attribute
|
||||||
program *ssa.Program
|
program *ssa.Program
|
||||||
diagnostics []error
|
diagnostics []error
|
||||||
functionInfos map[*ssa.Function]functionInfo
|
functionInfos map[*ssa.Function]functionInfo
|
||||||
@@ -135,6 +136,13 @@ func newCompilerContext(moduleName string, machine llvm.TargetMachine, config *C
|
|||||||
c.funcPtrType = dummyFunc.Type()
|
c.funcPtrType = dummyFunc.Type()
|
||||||
dummyFunc.EraseFromParentAsFunction()
|
dummyFunc.EraseFromParentAsFunction()
|
||||||
|
|
||||||
|
// The attribute "nocapture" changed to "captures(none)" in LLVM 21.
|
||||||
|
if llvmutil.Version() < 21 {
|
||||||
|
c.nocaptureAttr = c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0)
|
||||||
|
} else {
|
||||||
|
c.nocaptureAttr = c.ctx.CreateEnumAttribute(llvm.AttributeKindID("captures"), 0)
|
||||||
|
}
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -121,6 +121,29 @@ func (b *builder) createKeepAliveImpl() {
|
|||||||
b.CreateRetVoid()
|
b.CreateRetVoid()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// createAbiEscapeImpl implements the generic internal/abi.Escape function. It
|
||||||
|
// currently only supports pointer types.
|
||||||
|
func (b *builder) createAbiEscapeImpl() {
|
||||||
|
b.createFunctionStart(true)
|
||||||
|
|
||||||
|
// The first parameter is assumed to be a pointer. This is checked at the
|
||||||
|
// call site of createAbiEscapeImpl.
|
||||||
|
pointerValue := b.getValue(b.fn.Params[0], getPos(b.fn))
|
||||||
|
|
||||||
|
// Create an equivalent of the following C code, which is basically just a
|
||||||
|
// nop but ensures the pointerValue is kept alive:
|
||||||
|
//
|
||||||
|
// __asm__ __volatile__("" : : "r"(pointerValue))
|
||||||
|
//
|
||||||
|
// It should be portable to basically everything as the "r" register type
|
||||||
|
// exists basically everywhere.
|
||||||
|
asmType := llvm.FunctionType(b.dataPtrType, []llvm.Type{b.dataPtrType}, false)
|
||||||
|
asmFn := llvm.InlineAsm(asmType, "", "=r,0", true, false, 0, false)
|
||||||
|
result := b.createCall(asmType, asmFn, []llvm.Value{pointerValue}, "")
|
||||||
|
|
||||||
|
b.CreateRet(result)
|
||||||
|
}
|
||||||
|
|
||||||
var mathToLLVMMapping = map[string]string{
|
var mathToLLVMMapping = map[string]string{
|
||||||
"math.Ceil": "llvm.ceil.f64",
|
"math.Ceil": "llvm.ceil.f64",
|
||||||
"math.Exp": "llvm.exp.f64",
|
"math.Exp": "llvm.exp.f64",
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ func Version() int {
|
|||||||
return major
|
return major
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the byte order for the given target triple. Most targets are little
|
// ByteOrder returns the byte order for the given target triple. Most targets are little
|
||||||
// endian, but for example MIPS can be big-endian.
|
// endian, but for example MIPS can be big-endian.
|
||||||
func ByteOrder(target string) binary.ByteOrder {
|
func ByteOrder(target string) binary.ByteOrder {
|
||||||
if strings.HasPrefix(target, "mips-") {
|
if strings.HasPrefix(target, "mips-") {
|
||||||
|
|||||||
+41
-16
@@ -139,8 +139,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
|||||||
// not.
|
// not.
|
||||||
// (It may be safe to add the nocapture parameter to the context
|
// (It may be safe to add the nocapture parameter to the context
|
||||||
// parameter, but I'd like to stay on the safe side here).
|
// parameter, but I'd like to stay on the safe side here).
|
||||||
nocapture := c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0)
|
llvmFn.AddAttributeAtIndex(i+1, c.nocaptureAttr)
|
||||||
llvmFn.AddAttributeAtIndex(i+1, nocapture)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +152,7 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
|||||||
// Mark it as noreturn so LLVM can optimize away code.
|
// Mark it as noreturn so LLVM can optimize away code.
|
||||||
llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("noreturn"), 0))
|
llvmFn.AddFunctionAttr(c.ctx.CreateEnumAttribute(llvm.AttributeKindID("noreturn"), 0))
|
||||||
case "internal/abi.NoEscape":
|
case "internal/abi.NoEscape":
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
||||||
case "runtime.alloc":
|
case "runtime.alloc":
|
||||||
// Tell the optimizer that runtime.alloc is an allocator, meaning that it
|
// Tell the optimizer that runtime.alloc is an allocator, meaning that it
|
||||||
// returns values that are never null and never alias to an existing value.
|
// returns values that are never null and never alias to an existing value.
|
||||||
@@ -175,25 +174,25 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
|||||||
case "runtime.sliceAppend":
|
case "runtime.sliceAppend":
|
||||||
// Appending a slice will only read the to-be-appended slice, it won't
|
// Appending a slice will only read the to-be-appended slice, it won't
|
||||||
// be modified.
|
// be modified.
|
||||||
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
llvmFn.AddAttributeAtIndex(2, c.nocaptureAttr)
|
||||||
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||||
case "runtime.sliceCopy":
|
case "runtime.sliceCopy":
|
||||||
// Copying a slice won't capture any of the parameters.
|
// Copying a slice won't capture any of the parameters.
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("writeonly"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("writeonly"), 0))
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
||||||
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||||
llvmFn.AddAttributeAtIndex(2, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
llvmFn.AddAttributeAtIndex(2, c.nocaptureAttr)
|
||||||
case "runtime.stringFromBytes":
|
case "runtime.stringFromBytes":
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||||
case "runtime.stringFromRunes":
|
case "runtime.stringFromRunes":
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||||
case "runtime.trackPointer":
|
case "runtime.trackPointer":
|
||||||
// This function is necessary for tracking pointers on the stack in a
|
// This function is necessary for tracking pointers on the stack in a
|
||||||
// portable way (see gc_stack_portable.go). Indicate to the optimizer
|
// portable way (see gc_stack_portable.go). Indicate to the optimizer
|
||||||
// that the only thing we'll do is read the pointer.
|
// that the only thing we'll do is read the pointer.
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("nocapture"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.nocaptureAttr)
|
||||||
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
llvmFn.AddAttributeAtIndex(1, c.ctx.CreateEnumAttribute(llvm.AttributeKindID("readonly"), 0))
|
||||||
case "__mulsi3", "__divmodsi4", "__udivmodsi4":
|
case "__mulsi3", "__divmodsi4", "__udivmodsi4":
|
||||||
if strings.Split(c.Triple, "-")[0] == "avr" {
|
if strings.Split(c.Triple, "-")[0] == "avr" {
|
||||||
@@ -228,11 +227,9 @@ func (c *compilerContext) getFunction(fn *ssa.Function) (llvm.Type, llvm.Value)
|
|||||||
|
|
||||||
llvmFn.AddFunctionAttr(c.ctx.CreateStringAttribute("wasm-import-name", info.wasmName))
|
llvmFn.AddFunctionAttr(c.ctx.CreateStringAttribute("wasm-import-name", info.wasmName))
|
||||||
}
|
}
|
||||||
nocaptureKind := llvm.AttributeKindID("nocapture")
|
|
||||||
nocapture := c.ctx.CreateEnumAttribute(nocaptureKind, 0)
|
|
||||||
for i, typ := range paramTypes {
|
for i, typ := range paramTypes {
|
||||||
if typ.TypeKind() == llvm.PointerTypeKind {
|
if typ.TypeKind() == llvm.PointerTypeKind {
|
||||||
llvmFn.AddAttributeAtIndex(i+1, nocapture)
|
llvmFn.AddAttributeAtIndex(i+1, c.nocaptureAttr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,6 +250,23 @@ func (c *compilerContext) maybeCreateSyntheticFunction(fn *ssa.Function, llvmFn
|
|||||||
// The exception is the package initializer, which does appear in the
|
// The exception is the package initializer, which does appear in the
|
||||||
// *ssa.Package members and so shouldn't be created here.
|
// *ssa.Package members and so shouldn't be created here.
|
||||||
if fn.Synthetic != "" && fn.Synthetic != "package initializer" && fn.Synthetic != "generic function" && fn.Synthetic != "range-over-func yield" {
|
if fn.Synthetic != "" && fn.Synthetic != "package initializer" && fn.Synthetic != "generic function" && fn.Synthetic != "range-over-func yield" {
|
||||||
|
if origin := fn.Origin(); origin != nil && origin.RelString(nil) == "internal/abi.Escape" {
|
||||||
|
// This is a special implementation or internal/abi.Escape, which
|
||||||
|
// can only really be implemented in the compiler.
|
||||||
|
// For simplicity we'll only implement pointer parameters for now.
|
||||||
|
if _, ok := fn.Params[0].Type().Underlying().(*types.Pointer); ok {
|
||||||
|
irbuilder := c.ctx.NewBuilder()
|
||||||
|
defer irbuilder.Dispose()
|
||||||
|
b := newBuilder(c, irbuilder, fn)
|
||||||
|
b.createAbiEscapeImpl()
|
||||||
|
llvmFn.SetLinkage(llvm.LinkOnceODRLinkage)
|
||||||
|
llvmFn.SetUnnamedAddr(true)
|
||||||
|
}
|
||||||
|
// If the parameter is not of a pointer type, it will be left
|
||||||
|
// unimplemented. This will result in a linker error if the function
|
||||||
|
// is really called, making it clear it needs to be implemented.
|
||||||
|
return
|
||||||
|
}
|
||||||
if len(fn.Blocks) == 0 {
|
if len(fn.Blocks) == 0 {
|
||||||
c.addError(fn.Pos(), "missing function body")
|
c.addError(fn.Pos(), "missing function body")
|
||||||
return
|
return
|
||||||
@@ -613,7 +627,7 @@ func (c *compilerContext) addStandardAttributes(llvmFn llvm.Value) {
|
|||||||
// linkName is equal to .RelString(nil) on a global and extern is false, but for
|
// linkName is equal to .RelString(nil) on a global and extern is false, but for
|
||||||
// some symbols this is different (due to //go:extern for example).
|
// some symbols this is different (due to //go:extern for example).
|
||||||
type globalInfo struct {
|
type globalInfo struct {
|
||||||
linkName string // go:extern
|
linkName string // go:extern, go:linkname
|
||||||
extern bool // go:extern
|
extern bool // go:extern
|
||||||
align int // go:align
|
align int // go:align
|
||||||
section string // go:section
|
section string // go:section
|
||||||
@@ -698,14 +712,14 @@ func (c *compilerContext) getGlobalInfo(g *ssa.Global) globalInfo {
|
|||||||
// Check for //go: pragmas, which may change the link name (among others).
|
// Check for //go: pragmas, which may change the link name (among others).
|
||||||
doc := c.astComments[info.linkName]
|
doc := c.astComments[info.linkName]
|
||||||
if doc != nil {
|
if doc != nil {
|
||||||
info.parsePragmas(doc)
|
info.parsePragmas(doc, c, g)
|
||||||
}
|
}
|
||||||
return info
|
return info
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse //go: pragma comments from the source. In particular, it parses the
|
// Parse //go: pragma comments from the source. In particular, it parses the
|
||||||
// //go:extern pragma on globals.
|
// //go:extern and //go:linkname pragmas on globals.
|
||||||
func (info *globalInfo) parsePragmas(doc *ast.CommentGroup) {
|
func (info *globalInfo) parsePragmas(doc *ast.CommentGroup, c *compilerContext, g *ssa.Global) {
|
||||||
for _, comment := range doc.List {
|
for _, comment := range doc.List {
|
||||||
if !strings.HasPrefix(comment.Text, "//go:") {
|
if !strings.HasPrefix(comment.Text, "//go:") {
|
||||||
continue
|
continue
|
||||||
@@ -726,6 +740,17 @@ func (info *globalInfo) parsePragmas(doc *ast.CommentGroup) {
|
|||||||
if len(parts) == 2 {
|
if len(parts) == 2 {
|
||||||
info.section = parts[1]
|
info.section = parts[1]
|
||||||
}
|
}
|
||||||
|
case "//go:linkname":
|
||||||
|
if len(parts) != 3 || parts[1] != g.Name() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Only enable go:linkname when the package imports "unsafe".
|
||||||
|
// This is a slightly looser requirement than what gc uses: gc
|
||||||
|
// requires the file to import "unsafe", not the package as a
|
||||||
|
// whole.
|
||||||
|
if hasUnsafeImport(g.Pkg.Pkg) {
|
||||||
|
info.linkName = parts[2]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'basic.go'
|
; ModuleID = 'basic.go'
|
||||||
source_filename = "basic.go"
|
source_filename = "basic.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%main.kv = type { float, i32, i32, i32 }
|
%main.kv = type { float, i32, i32, i32 }
|
||||||
@@ -206,7 +206,7 @@ entry:
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind }
|
attributes #3 = { nounwind }
|
||||||
|
|||||||
Vendored
+7
-7
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'channel.go'
|
; ModuleID = 'channel.go'
|
||||||
source_filename = "channel.go"
|
source_filename = "channel.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%runtime.channelOp = type { ptr, ptr, i32, ptr }
|
%runtime.channelOp = type { ptr, ptr, i32, ptr }
|
||||||
@@ -82,11 +82,11 @@ entry:
|
|||||||
store i32 1, ptr %select.send.value, align 4
|
store i32 1, ptr %select.send.value, align 4
|
||||||
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %select.states.alloca)
|
call void @llvm.lifetime.start.p0(i64 16, ptr nonnull %select.states.alloca)
|
||||||
store ptr %ch1, ptr %select.states.alloca, align 4
|
store ptr %ch1, ptr %select.states.alloca, align 4
|
||||||
%select.states.alloca.repack1 = getelementptr inbounds i8, ptr %select.states.alloca, i32 4
|
%select.states.alloca.repack1 = getelementptr inbounds nuw i8, ptr %select.states.alloca, i32 4
|
||||||
store ptr %select.send.value, ptr %select.states.alloca.repack1, align 4
|
store ptr %select.send.value, ptr %select.states.alloca.repack1, align 4
|
||||||
%0 = getelementptr inbounds i8, ptr %select.states.alloca, i32 8
|
%0 = getelementptr inbounds nuw i8, ptr %select.states.alloca, i32 8
|
||||||
store ptr %ch2, ptr %0, align 4
|
store ptr %ch2, ptr %0, align 4
|
||||||
%.repack3 = getelementptr inbounds i8, ptr %select.states.alloca, i32 12
|
%.repack3 = getelementptr inbounds nuw i8, ptr %select.states.alloca, i32 12
|
||||||
store ptr null, ptr %.repack3, align 4
|
store ptr null, ptr %.repack3, align 4
|
||||||
%select.result = call { i32, i1 } @runtime.chanSelect(ptr undef, ptr nonnull %select.states.alloca, i32 2, i32 2, ptr null, i32 0, i32 0, ptr undef) #4
|
%select.result = call { i32, i1 } @runtime.chanSelect(ptr undef, ptr nonnull %select.states.alloca, i32 2, i32 2, ptr null, i32 0, i32 0, ptr undef) #4
|
||||||
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %select.states.alloca)
|
call void @llvm.lifetime.end.p0(i64 16, ptr nonnull %select.states.alloca)
|
||||||
@@ -107,8 +107,8 @@ select.body: ; preds = %select.next
|
|||||||
|
|
||||||
declare { i32, i1 } @runtime.chanSelect(ptr, ptr, i32, i32, ptr, i32, i32, ptr) #1
|
declare { i32, i1 } @runtime.chanSelect(ptr, ptr, i32, i32, ptr, i32, i32, ptr) #1
|
||||||
|
|
||||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
attributes #3 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
||||||
attributes #4 = { nounwind }
|
attributes #4 = { nounwind }
|
||||||
|
|||||||
+7
-7
@@ -27,7 +27,7 @@ entry:
|
|||||||
%0 = call ptr @llvm.stacksave.p0()
|
%0 = call ptr @llvm.stacksave.p0()
|
||||||
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
|
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
|
||||||
store i32 0, ptr %defer.alloca, align 4
|
store i32 0, ptr %defer.alloca, align 4
|
||||||
%defer.alloca.repack15 = getelementptr inbounds i8, ptr %defer.alloca, i32 4
|
%defer.alloca.repack15 = getelementptr inbounds nuw i8, ptr %defer.alloca, i32 4
|
||||||
store ptr null, ptr %defer.alloca.repack15, align 4
|
store ptr null, ptr %defer.alloca.repack15, align 4
|
||||||
store ptr %defer.alloca, ptr %deferPtr, align 4
|
store ptr %defer.alloca, ptr %deferPtr, align 4
|
||||||
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5
|
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5
|
||||||
@@ -51,7 +51,7 @@ rundefers.loophead: ; preds = %3, %rundefers.block
|
|||||||
br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop
|
br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop
|
||||||
|
|
||||||
rundefers.loop: ; preds = %rundefers.loophead
|
rundefers.loop: ; preds = %rundefers.loophead
|
||||||
%stack.next.gep = getelementptr inbounds i8, ptr %2, i32 4
|
%stack.next.gep = getelementptr inbounds nuw i8, ptr %2, i32 4
|
||||||
%stack.next = load ptr, ptr %stack.next.gep, align 4
|
%stack.next = load ptr, ptr %stack.next.gep, align 4
|
||||||
store ptr %stack.next, ptr %deferPtr, align 4
|
store ptr %stack.next, ptr %deferPtr, align 4
|
||||||
%callback = load i32, ptr %2, align 4
|
%callback = load i32, ptr %2, align 4
|
||||||
@@ -87,7 +87,7 @@ rundefers.loophead6: ; preds = %5, %lpad
|
|||||||
br i1 %stackIsNil7, label %rundefers.end3, label %rundefers.loop5
|
br i1 %stackIsNil7, label %rundefers.end3, label %rundefers.loop5
|
||||||
|
|
||||||
rundefers.loop5: ; preds = %rundefers.loophead6
|
rundefers.loop5: ; preds = %rundefers.loophead6
|
||||||
%stack.next.gep8 = getelementptr inbounds i8, ptr %4, i32 4
|
%stack.next.gep8 = getelementptr inbounds nuw i8, ptr %4, i32 4
|
||||||
%stack.next9 = load ptr, ptr %stack.next.gep8, align 4
|
%stack.next9 = load ptr, ptr %stack.next.gep8, align 4
|
||||||
store ptr %stack.next9, ptr %deferPtr, align 4
|
store ptr %stack.next9, ptr %deferPtr, align 4
|
||||||
%callback11 = load i32, ptr %4, align 4
|
%callback11 = load i32, ptr %4, align 4
|
||||||
@@ -144,11 +144,11 @@ entry:
|
|||||||
%0 = call ptr @llvm.stacksave.p0()
|
%0 = call ptr @llvm.stacksave.p0()
|
||||||
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
|
call void @runtime.setupDeferFrame(ptr nonnull %deferframe.buf, ptr %0, ptr undef) #4
|
||||||
store i32 0, ptr %defer.alloca, align 4
|
store i32 0, ptr %defer.alloca, align 4
|
||||||
%defer.alloca.repack22 = getelementptr inbounds i8, ptr %defer.alloca, i32 4
|
%defer.alloca.repack22 = getelementptr inbounds nuw i8, ptr %defer.alloca, i32 4
|
||||||
store ptr null, ptr %defer.alloca.repack22, align 4
|
store ptr null, ptr %defer.alloca.repack22, align 4
|
||||||
store ptr %defer.alloca, ptr %deferPtr, align 4
|
store ptr %defer.alloca, ptr %deferPtr, align 4
|
||||||
store i32 1, ptr %defer.alloca2, align 4
|
store i32 1, ptr %defer.alloca2, align 4
|
||||||
%defer.alloca2.repack23 = getelementptr inbounds i8, ptr %defer.alloca2, i32 4
|
%defer.alloca2.repack23 = getelementptr inbounds nuw i8, ptr %defer.alloca2, i32 4
|
||||||
store ptr %defer.alloca, ptr %defer.alloca2.repack23, align 4
|
store ptr %defer.alloca, ptr %defer.alloca2.repack23, align 4
|
||||||
store ptr %defer.alloca2, ptr %deferPtr, align 4
|
store ptr %defer.alloca2, ptr %deferPtr, align 4
|
||||||
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5
|
%setjmp = call i32 asm "\0Amovs r0, #0\0Amov r2, pc\0Astr r2, [r1, #4]", "={r0},{r1},~{r1},~{r2},~{r3},~{r4},~{r5},~{r6},~{r7},~{r8},~{r9},~{r10},~{r11},~{r12},~{lr},~{q0},~{q1},~{q2},~{q3},~{q4},~{q5},~{q6},~{q7},~{q8},~{q9},~{q10},~{q11},~{q12},~{q13},~{q14},~{q15},~{cpsr},~{memory}"(ptr nonnull %deferframe.buf) #5
|
||||||
@@ -172,7 +172,7 @@ rundefers.loophead: ; preds = %4, %3, %rundefers.b
|
|||||||
br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop
|
br i1 %stackIsNil, label %rundefers.end, label %rundefers.loop
|
||||||
|
|
||||||
rundefers.loop: ; preds = %rundefers.loophead
|
rundefers.loop: ; preds = %rundefers.loophead
|
||||||
%stack.next.gep = getelementptr inbounds i8, ptr %2, i32 4
|
%stack.next.gep = getelementptr inbounds nuw i8, ptr %2, i32 4
|
||||||
%stack.next = load ptr, ptr %stack.next.gep, align 4
|
%stack.next = load ptr, ptr %stack.next.gep, align 4
|
||||||
store ptr %stack.next, ptr %deferPtr, align 4
|
store ptr %stack.next, ptr %deferPtr, align 4
|
||||||
%callback = load i32, ptr %2, align 4
|
%callback = load i32, ptr %2, align 4
|
||||||
@@ -218,7 +218,7 @@ rundefers.loophead10: ; preds = %7, %6, %lpad
|
|||||||
br i1 %stackIsNil11, label %rundefers.end7, label %rundefers.loop9
|
br i1 %stackIsNil11, label %rundefers.end7, label %rundefers.loop9
|
||||||
|
|
||||||
rundefers.loop9: ; preds = %rundefers.loophead10
|
rundefers.loop9: ; preds = %rundefers.loophead10
|
||||||
%stack.next.gep12 = getelementptr inbounds i8, ptr %5, i32 4
|
%stack.next.gep12 = getelementptr inbounds nuw i8, ptr %5, i32 4
|
||||||
%stack.next13 = load ptr, ptr %stack.next.gep12, align 4
|
%stack.next13 = load ptr, ptr %stack.next.gep12, align 4
|
||||||
store ptr %stack.next13, ptr %deferPtr, align 4
|
store ptr %stack.next13, ptr %deferPtr, align 4
|
||||||
%callback15 = load i32, ptr %5, align 4
|
%callback15 = load i32, ptr %5, align 4
|
||||||
|
|||||||
Vendored
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'float.go'
|
; ModuleID = 'float.go'
|
||||||
source_filename = "float.go"
|
source_filename = "float.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||||
@@ -93,6 +93,6 @@ entry:
|
|||||||
ret i8 %0
|
ret i8 %0
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
|
|||||||
Vendored
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'func.go'
|
; ModuleID = 'func.go'
|
||||||
source_filename = "func.go"
|
source_filename = "func.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||||
@@ -44,7 +44,7 @@ entry:
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind }
|
attributes #3 = { nounwind }
|
||||||
|
|||||||
Vendored
+11
-11
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'gc.go'
|
; ModuleID = 'gc.go'
|
||||||
source_filename = "gc.go"
|
source_filename = "gc.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%runtime._interface = type { ptr, ptr }
|
%runtime._interface = type { ptr, ptr }
|
||||||
@@ -105,18 +105,18 @@ entry:
|
|||||||
%makeslice = call align 1 dereferenceable(5) ptr @runtime.alloc(i32 5, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
%makeslice = call align 1 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
|
call void @runtime.trackPointer(ptr nonnull %makeslice, ptr nonnull %stackalloc, ptr undef) #3
|
||||||
store ptr %makeslice, ptr @main.slice1, align 4
|
store ptr %makeslice, ptr @main.slice1, align 4
|
||||||
store i32 5, ptr getelementptr inbounds (i8, ptr @main.slice1, i32 4), align 4
|
store i32 5, ptr getelementptr inbounds nuw (i8, ptr @main.slice1, i32 4), align 4
|
||||||
store i32 5, ptr getelementptr inbounds (i8, ptr @main.slice1, i32 8), align 4
|
store i32 5, ptr getelementptr inbounds nuw (i8, ptr @main.slice1, i32 8), align 4
|
||||||
%makeslice1 = call align 4 dereferenceable(20) ptr @runtime.alloc(i32 20, ptr nonnull inttoptr (i32 67 to ptr), ptr undef) #3
|
%makeslice1 = call align 4 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
|
call void @runtime.trackPointer(ptr nonnull %makeslice1, ptr nonnull %stackalloc, ptr undef) #3
|
||||||
store ptr %makeslice1, ptr @main.slice2, align 4
|
store ptr %makeslice1, ptr @main.slice2, align 4
|
||||||
store i32 5, ptr getelementptr inbounds (i8, ptr @main.slice2, i32 4), align 4
|
store i32 5, ptr getelementptr inbounds nuw (i8, ptr @main.slice2, i32 4), align 4
|
||||||
store i32 5, ptr getelementptr inbounds (i8, ptr @main.slice2, i32 8), align 4
|
store i32 5, ptr getelementptr inbounds nuw (i8, ptr @main.slice2, i32 8), align 4
|
||||||
%makeslice3 = call align 4 dereferenceable(60) ptr @runtime.alloc(i32 60, ptr nonnull inttoptr (i32 71 to ptr), ptr undef) #3
|
%makeslice3 = call align 4 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
|
call void @runtime.trackPointer(ptr nonnull %makeslice3, ptr nonnull %stackalloc, ptr undef) #3
|
||||||
store ptr %makeslice3, ptr @main.slice3, align 4
|
store ptr %makeslice3, ptr @main.slice3, align 4
|
||||||
store i32 5, ptr getelementptr inbounds (i8, ptr @main.slice3, i32 4), align 4
|
store i32 5, ptr getelementptr inbounds nuw (i8, ptr @main.slice3, i32 4), align 4
|
||||||
store i32 5, ptr getelementptr inbounds (i8, ptr @main.slice3, i32 8), align 4
|
store i32 5, ptr getelementptr inbounds nuw (i8, ptr @main.slice3, i32 8), align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ entry:
|
|||||||
%0 = call align 8 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #3
|
%0 = call align 8 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #3
|
||||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #3
|
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #3
|
||||||
store double %v.r, ptr %0, align 8
|
store double %v.r, ptr %0, align 8
|
||||||
%.repack1 = getelementptr inbounds i8, ptr %0, i32 8
|
%.repack1 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
||||||
store double %v.i, ptr %.repack1, align 8
|
store double %v.i, ptr %.repack1, align 8
|
||||||
%1 = insertvalue %runtime._interface { ptr @"reflect/types.type:basic:complex128", ptr undef }, ptr %0, 1
|
%1 = insertvalue %runtime._interface { ptr @"reflect/types.type:basic:complex128", ptr undef }, ptr %0, 1
|
||||||
call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:basic:complex128", ptr nonnull %stackalloc, ptr undef) #3
|
call void @runtime.trackPointer(ptr nonnull @"reflect/types.type:basic:complex128", ptr nonnull %stackalloc, ptr undef) #3
|
||||||
@@ -135,7 +135,7 @@ entry:
|
|||||||
ret %runtime._interface %1
|
ret %runtime._interface %1
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind }
|
attributes #3 = { nounwind }
|
||||||
|
|||||||
Vendored
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'go1.20.go'
|
; ModuleID = 'go1.20.go'
|
||||||
source_filename = "go1.20.go"
|
source_filename = "go1.20.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%runtime._string = type { ptr, i32 }
|
%runtime._string = type { ptr, i32 }
|
||||||
@@ -57,7 +57,7 @@ entry:
|
|||||||
ret ptr %s.data
|
ret ptr %s.data
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind }
|
attributes #3 = { nounwind }
|
||||||
|
|||||||
Vendored
+6
-6
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'go1.21.go'
|
; ModuleID = 'go1.21.go'
|
||||||
source_filename = "go1.21.go"
|
source_filename = "go1.21.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%runtime._string = type { ptr, i32 }
|
%runtime._string = type { ptr, i32 }
|
||||||
@@ -86,7 +86,7 @@ entry:
|
|||||||
%stackalloc = alloca i8, align 1
|
%stackalloc = alloca i8, align 1
|
||||||
%4 = call i1 @runtime.stringLess(ptr %a.data, i32 %a.len, ptr %b.data, i32 %b.len, ptr undef) #5
|
%4 = call i1 @runtime.stringLess(ptr %a.data, i32 %a.len, ptr %b.data, i32 %b.len, ptr undef) #5
|
||||||
%5 = select i1 %4, %runtime._string %1, %runtime._string %3
|
%5 = select i1 %4, %runtime._string %1, %runtime._string %3
|
||||||
%6 = extractvalue %runtime._string %5, 0
|
%6 = select i1 %4, ptr %a.data, ptr %b.data
|
||||||
call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef) #5
|
call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef) #5
|
||||||
ret %runtime._string %5
|
ret %runtime._string %5
|
||||||
}
|
}
|
||||||
@@ -125,7 +125,7 @@ entry:
|
|||||||
%stackalloc = alloca i8, align 1
|
%stackalloc = alloca i8, align 1
|
||||||
%4 = call i1 @runtime.stringLess(ptr %b.data, i32 %b.len, ptr %a.data, i32 %a.len, ptr undef) #5
|
%4 = call i1 @runtime.stringLess(ptr %b.data, i32 %b.len, ptr %a.data, i32 %a.len, ptr undef) #5
|
||||||
%5 = select i1 %4, %runtime._string %1, %runtime._string %3
|
%5 = select i1 %4, %runtime._string %1, %runtime._string %3
|
||||||
%6 = extractvalue %runtime._string %5, 0
|
%6 = select i1 %4, ptr %a.data, ptr %b.data
|
||||||
call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef) #5
|
call void @runtime.trackPointer(ptr %6, ptr nonnull %stackalloc, ptr undef) #5
|
||||||
ret %runtime._string %5
|
ret %runtime._string %5
|
||||||
}
|
}
|
||||||
@@ -171,9 +171,9 @@ declare i32 @llvm.smax.i32(i32, i32) #4
|
|||||||
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
|
; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
|
||||||
declare i32 @llvm.umax.i32(i32, i32) #4
|
declare i32 @llvm.umax.i32(i32, i32) #4
|
||||||
|
|
||||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nocallback nofree nounwind willreturn memory(argmem: write) }
|
attributes #3 = { nocallback nofree nounwind willreturn memory(argmem: write) }
|
||||||
attributes #4 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
|
attributes #4 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
|
||||||
attributes #5 = { nounwind }
|
attributes #5 = { nounwind }
|
||||||
|
|||||||
+12
-12
@@ -65,7 +65,7 @@ entry:
|
|||||||
store i32 3, ptr %n, align 4
|
store i32 3, ptr %n, align 4
|
||||||
%0 = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr null, ptr undef) #9
|
%0 = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr null, ptr undef) #9
|
||||||
store i32 5, ptr %0, align 4
|
store i32 5, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds i8, ptr %0, i32 4
|
%1 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
||||||
store ptr %n, ptr %1, align 4
|
store ptr %n, ptr %1, align 4
|
||||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr undef) #9
|
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr undef) #9
|
||||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #9
|
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #9
|
||||||
@@ -87,7 +87,7 @@ entry:
|
|||||||
define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #5 {
|
define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #5 {
|
||||||
entry:
|
entry:
|
||||||
%1 = load i32, ptr %0, align 4
|
%1 = load i32, ptr %0, align 4
|
||||||
%2 = getelementptr inbounds i8, ptr %0, i32 4
|
%2 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
||||||
%3 = load ptr, ptr %2, align 4
|
%3 = load ptr, ptr %2, align 4
|
||||||
call void @"main.closureFunctionGoroutine$1"(i32 %1, ptr %3)
|
call void @"main.closureFunctionGoroutine$1"(i32 %1, ptr %3)
|
||||||
ret void
|
ret void
|
||||||
@@ -104,9 +104,9 @@ define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %co
|
|||||||
entry:
|
entry:
|
||||||
%0 = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr null, ptr undef) #9
|
%0 = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr null, ptr undef) #9
|
||||||
store i32 5, ptr %0, align 4
|
store i32 5, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds i8, ptr %0, i32 4
|
%1 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
||||||
store ptr %fn.context, ptr %1, align 4
|
store ptr %fn.context, ptr %1, align 4
|
||||||
%2 = getelementptr inbounds i8, ptr %0, i32 8
|
%2 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
||||||
store ptr %fn.funcptr, ptr %2, align 4
|
store ptr %fn.funcptr, ptr %2, align 4
|
||||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr undef) #9
|
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr undef) #9
|
||||||
call void @"internal/task.start"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #9
|
call void @"internal/task.start"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #9
|
||||||
@@ -117,9 +117,9 @@ entry:
|
|||||||
define linkonce_odr void @main.funcGoroutine.gowrapper(ptr %0) unnamed_addr #6 {
|
define linkonce_odr void @main.funcGoroutine.gowrapper(ptr %0) unnamed_addr #6 {
|
||||||
entry:
|
entry:
|
||||||
%1 = load i32, ptr %0, align 4
|
%1 = load i32, ptr %0, align 4
|
||||||
%2 = getelementptr inbounds i8, ptr %0, i32 4
|
%2 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
||||||
%3 = load ptr, ptr %2, align 4
|
%3 = load ptr, ptr %2, align 4
|
||||||
%4 = getelementptr inbounds i8, ptr %0, i32 8
|
%4 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
||||||
%5 = load ptr, ptr %4, align 4
|
%5 = load ptr, ptr %4, align 4
|
||||||
call void %5(i32 %1, ptr %3) #9
|
call void %5(i32 %1, ptr %3) #9
|
||||||
ret void
|
ret void
|
||||||
@@ -154,11 +154,11 @@ define hidden void @main.startInterfaceMethod(ptr %itf.typecode, ptr %itf.value,
|
|||||||
entry:
|
entry:
|
||||||
%0 = call align 4 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #9
|
%0 = call align 4 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #9
|
||||||
store ptr %itf.value, ptr %0, align 4
|
store ptr %itf.value, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds i8, ptr %0, i32 4
|
%1 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
||||||
store ptr @"main$string", ptr %1, align 4
|
store ptr @"main$string", ptr %1, align 4
|
||||||
%2 = getelementptr inbounds i8, ptr %0, i32 8
|
%2 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
||||||
store i32 4, ptr %2, align 4
|
store i32 4, ptr %2, align 4
|
||||||
%3 = getelementptr inbounds i8, ptr %0, i32 12
|
%3 = getelementptr inbounds nuw i8, ptr %0, i32 12
|
||||||
store ptr %itf.typecode, ptr %3, align 4
|
store ptr %itf.typecode, ptr %3, align 4
|
||||||
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr undef) #9
|
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr undef) #9
|
||||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #9
|
call void @"internal/task.start"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #9
|
||||||
@@ -171,11 +171,11 @@ declare void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr, ptr, i
|
|||||||
define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(ptr %0) unnamed_addr #8 {
|
define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(ptr %0) unnamed_addr #8 {
|
||||||
entry:
|
entry:
|
||||||
%1 = load ptr, ptr %0, align 4
|
%1 = load ptr, ptr %0, align 4
|
||||||
%2 = getelementptr inbounds i8, ptr %0, i32 4
|
%2 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
||||||
%3 = load ptr, ptr %2, align 4
|
%3 = load ptr, ptr %2, align 4
|
||||||
%4 = getelementptr inbounds i8, ptr %0, i32 8
|
%4 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
||||||
%5 = load i32, ptr %4, align 4
|
%5 = load i32, ptr %4, align 4
|
||||||
%6 = getelementptr inbounds i8, ptr %0, i32 12
|
%6 = getelementptr inbounds nuw i8, ptr %0, i32 12
|
||||||
%7 = load ptr, ptr %6, align 4
|
%7 = load ptr, ptr %6, align 4
|
||||||
call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr %1, ptr %3, i32 %5, ptr %7, ptr undef) #9
|
call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr %1, ptr %3, i32 %5, ptr %7, ptr undef) #9
|
||||||
ret void
|
ret void
|
||||||
|
|||||||
+22
-22
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'goroutine.go'
|
; ModuleID = 'goroutine.go'
|
||||||
source_filename = "goroutine.go"
|
source_filename = "goroutine.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
@"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1
|
@"main$string" = internal unnamed_addr constant [4 x i8] c"test", align 1
|
||||||
@@ -72,7 +72,7 @@ entry:
|
|||||||
%0 = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr null, ptr undef) #9
|
%0 = call align 4 dereferenceable(8) ptr @runtime.alloc(i32 8, ptr null, ptr undef) #9
|
||||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9
|
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9
|
||||||
store i32 5, ptr %0, align 4
|
store i32 5, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds i8, ptr %0, i32 4
|
%1 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
||||||
store ptr %n, ptr %1, align 4
|
store ptr %n, ptr %1, align 4
|
||||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr nonnull %0, i32 65536, ptr undef) #9
|
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr nonnull %0, i32 65536, ptr undef) #9
|
||||||
%2 = load i32, ptr %n, align 4
|
%2 = load i32, ptr %n, align 4
|
||||||
@@ -93,7 +93,7 @@ entry:
|
|||||||
define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #5 {
|
define linkonce_odr void @"main.closureFunctionGoroutine$1$gowrapper"(ptr %0) unnamed_addr #5 {
|
||||||
entry:
|
entry:
|
||||||
%1 = load i32, ptr %0, align 4
|
%1 = load i32, ptr %0, align 4
|
||||||
%2 = getelementptr inbounds i8, ptr %0, i32 4
|
%2 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
||||||
%3 = load ptr, ptr %2, align 4
|
%3 = load ptr, ptr %2, align 4
|
||||||
call void @"main.closureFunctionGoroutine$1"(i32 %1, ptr %3)
|
call void @"main.closureFunctionGoroutine$1"(i32 %1, ptr %3)
|
||||||
call void @runtime.deadlock(ptr undef) #9
|
call void @runtime.deadlock(ptr undef) #9
|
||||||
@@ -113,9 +113,9 @@ entry:
|
|||||||
%0 = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr null, ptr undef) #9
|
%0 = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr null, ptr undef) #9
|
||||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9
|
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9
|
||||||
store i32 5, ptr %0, align 4
|
store i32 5, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds i8, ptr %0, i32 4
|
%1 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
||||||
store ptr %fn.context, ptr %1, align 4
|
store ptr %fn.context, ptr %1, align 4
|
||||||
%2 = getelementptr inbounds i8, ptr %0, i32 8
|
%2 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
||||||
store ptr %fn.funcptr, ptr %2, align 4
|
store ptr %fn.funcptr, ptr %2, align 4
|
||||||
call void @"internal/task.start"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr nonnull %0, i32 65536, ptr undef) #9
|
call void @"internal/task.start"(i32 ptrtoint (ptr @main.funcGoroutine.gowrapper to i32), ptr nonnull %0, i32 65536, ptr undef) #9
|
||||||
ret void
|
ret void
|
||||||
@@ -125,9 +125,9 @@ entry:
|
|||||||
define linkonce_odr void @main.funcGoroutine.gowrapper(ptr %0) unnamed_addr #6 {
|
define linkonce_odr void @main.funcGoroutine.gowrapper(ptr %0) unnamed_addr #6 {
|
||||||
entry:
|
entry:
|
||||||
%1 = load i32, ptr %0, align 4
|
%1 = load i32, ptr %0, align 4
|
||||||
%2 = getelementptr inbounds i8, ptr %0, i32 4
|
%2 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
||||||
%3 = load ptr, ptr %2, align 4
|
%3 = load ptr, ptr %2, align 4
|
||||||
%4 = getelementptr inbounds i8, ptr %0, i32 8
|
%4 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
||||||
%5 = load ptr, ptr %4, align 4
|
%5 = load ptr, ptr %4, align 4
|
||||||
call void %5(i32 %1, ptr %3) #9
|
call void %5(i32 %1, ptr %3) #9
|
||||||
call void @runtime.deadlock(ptr undef) #9
|
call void @runtime.deadlock(ptr undef) #9
|
||||||
@@ -165,11 +165,11 @@ entry:
|
|||||||
%0 = call align 4 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #9
|
%0 = call align 4 dereferenceable(16) ptr @runtime.alloc(i32 16, ptr null, ptr undef) #9
|
||||||
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9
|
call void @runtime.trackPointer(ptr nonnull %0, ptr nonnull %stackalloc, ptr undef) #9
|
||||||
store ptr %itf.value, ptr %0, align 4
|
store ptr %itf.value, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds i8, ptr %0, i32 4
|
%1 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
||||||
store ptr @"main$string", ptr %1, align 4
|
store ptr @"main$string", ptr %1, align 4
|
||||||
%2 = getelementptr inbounds i8, ptr %0, i32 8
|
%2 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
||||||
store i32 4, ptr %2, align 4
|
store i32 4, ptr %2, align 4
|
||||||
%3 = getelementptr inbounds i8, ptr %0, i32 12
|
%3 = getelementptr inbounds nuw i8, ptr %0, i32 12
|
||||||
store ptr %itf.typecode, ptr %3, align 4
|
store ptr %itf.typecode, ptr %3, align 4
|
||||||
call void @"internal/task.start"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr nonnull %0, i32 65536, ptr undef) #9
|
call void @"internal/task.start"(i32 ptrtoint (ptr @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper" to i32), ptr nonnull %0, i32 65536, ptr undef) #9
|
||||||
ret void
|
ret void
|
||||||
@@ -181,24 +181,24 @@ declare void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr, ptr, i
|
|||||||
define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(ptr %0) unnamed_addr #8 {
|
define linkonce_odr void @"interface:{Print:func:{basic:string}{}}.Print$invoke$gowrapper"(ptr %0) unnamed_addr #8 {
|
||||||
entry:
|
entry:
|
||||||
%1 = load ptr, ptr %0, align 4
|
%1 = load ptr, ptr %0, align 4
|
||||||
%2 = getelementptr inbounds i8, ptr %0, i32 4
|
%2 = getelementptr inbounds nuw i8, ptr %0, i32 4
|
||||||
%3 = load ptr, ptr %2, align 4
|
%3 = load ptr, ptr %2, align 4
|
||||||
%4 = getelementptr inbounds i8, ptr %0, i32 8
|
%4 = getelementptr inbounds nuw i8, ptr %0, i32 8
|
||||||
%5 = load i32, ptr %4, align 4
|
%5 = load i32, ptr %4, align 4
|
||||||
%6 = getelementptr inbounds i8, ptr %0, i32 12
|
%6 = getelementptr inbounds nuw i8, ptr %0, i32 12
|
||||||
%7 = load ptr, ptr %6, align 4
|
%7 = load ptr, ptr %6, align 4
|
||||||
call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr %1, ptr %3, i32 %5, ptr %7, ptr undef) #9
|
call void @"interface:{Print:func:{basic:string}{}}.Print$invoke"(ptr %1, ptr %3, i32 %5, ptr %7, ptr undef) #9
|
||||||
call void @runtime.deadlock(ptr undef) #9
|
call void @runtime.deadlock(ptr undef) #9
|
||||||
unreachable
|
unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="main.regularFunction" }
|
attributes #3 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="main.regularFunction" }
|
||||||
attributes #4 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="main.inlineFunctionGoroutine$1" }
|
attributes #4 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="main.inlineFunctionGoroutine$1" }
|
||||||
attributes #5 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="main.closureFunctionGoroutine$1" }
|
attributes #5 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="main.closureFunctionGoroutine$1" }
|
||||||
attributes #6 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper" }
|
attributes #6 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper" }
|
||||||
attributes #7 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-invoke"="reflect/methods.Print(string)" "tinygo-methods"="reflect/methods.Print(string)" }
|
attributes #7 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-invoke"="reflect/methods.Print(string)" "tinygo-methods"="reflect/methods.Print(string)" }
|
||||||
attributes #8 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="interface:{Print:func:{basic:string}{}}.Print$invoke" }
|
attributes #8 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-gowrapper"="interface:{Print:func:{basic:string}{}}.Print$invoke" }
|
||||||
attributes #9 = { nounwind }
|
attributes #9 = { nounwind }
|
||||||
|
|||||||
Vendored
+8
-8
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'interface.go'
|
; ModuleID = 'interface.go'
|
||||||
source_filename = "interface.go"
|
source_filename = "interface.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%runtime._interface = type { ptr, ptr }
|
%runtime._interface = type { ptr, ptr }
|
||||||
@@ -130,11 +130,11 @@ entry:
|
|||||||
|
|
||||||
declare %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr, ptr, ptr) #6
|
declare %runtime._string @"interface:{Error:func:{}{basic:string}}.Error$invoke"(ptr, ptr, ptr) #6
|
||||||
|
|
||||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-methods"="reflect/methods.Error() string" }
|
attributes #3 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-methods"="reflect/methods.Error() string" }
|
||||||
attributes #4 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-methods"="reflect/methods.String() string" }
|
attributes #4 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-methods"="reflect/methods.String() string" }
|
||||||
attributes #5 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-invoke"="main.$methods.foo(int) uint8" "tinygo-methods"="reflect/methods.String() string; main.$methods.foo(int) uint8" }
|
attributes #5 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-invoke"="main.$methods.foo(int) uint8" "tinygo-methods"="reflect/methods.String() string; main.$methods.foo(int) uint8" }
|
||||||
attributes #6 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-invoke"="reflect/methods.Error() string" "tinygo-methods"="reflect/methods.Error() string" }
|
attributes #6 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "tinygo-invoke"="reflect/methods.Error() string" "tinygo-methods"="reflect/methods.Error() string" }
|
||||||
attributes #7 = { nounwind }
|
attributes #7 = { nounwind }
|
||||||
|
|||||||
Vendored
+4
-4
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'pointer.go'
|
; ModuleID = 'pointer.go'
|
||||||
source_filename = "pointer.go"
|
source_filename = "pointer.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||||
@@ -44,7 +44,7 @@ entry:
|
|||||||
ret ptr %x
|
ret ptr %x
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind }
|
attributes #3 = { nounwind }
|
||||||
|
|||||||
Vendored
+11
-11
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'pragma.go'
|
; ModuleID = 'pragma.go'
|
||||||
source_filename = "pragma.go"
|
source_filename = "pragma.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
@extern_global = external global [0 x i8], align 1
|
@extern_global = external global [0 x i8], align 1
|
||||||
@@ -93,13 +93,13 @@ entry:
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="extern_func" }
|
attributes #3 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="extern_func" }
|
||||||
attributes #4 = { inlinehint nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #4 = { inlinehint nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #5 = { noinline nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #5 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #6 = { noinline nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="exportedFunctionInSection" }
|
attributes #6 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="exportedFunctionInSection" }
|
||||||
attributes #7 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-import-module"="modulename" "wasm-import-name"="import1" }
|
attributes #7 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-import-module"="modulename" "wasm-import-name"="import1" }
|
||||||
attributes #8 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-import-module"="foobar" "wasm-import-name"="imported" }
|
attributes #8 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-import-module"="foobar" "wasm-import-name"="imported" }
|
||||||
attributes #9 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="exported" }
|
attributes #9 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" "wasm-export-name"="exported" }
|
||||||
|
|||||||
Vendored
+6
-6
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'slice.go'
|
; ModuleID = 'slice.go'
|
||||||
source_filename = "slice.go"
|
source_filename = "slice.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
; Function Attrs: allockind("alloc,zeroed") allocsize(0)
|
||||||
@@ -51,9 +51,9 @@ entry:
|
|||||||
%varargs = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
%varargs = call align 4 dereferenceable(12) ptr @runtime.alloc(i32 12, ptr nonnull inttoptr (i32 3 to ptr), ptr undef) #3
|
||||||
call void @runtime.trackPointer(ptr nonnull %varargs, ptr nonnull %stackalloc, ptr undef) #3
|
call void @runtime.trackPointer(ptr nonnull %varargs, ptr nonnull %stackalloc, ptr undef) #3
|
||||||
store i32 1, ptr %varargs, align 4
|
store i32 1, ptr %varargs, align 4
|
||||||
%0 = getelementptr inbounds i8, ptr %varargs, i32 4
|
%0 = getelementptr inbounds nuw i8, ptr %varargs, i32 4
|
||||||
store i32 2, ptr %0, align 4
|
store i32 2, ptr %0, align 4
|
||||||
%1 = getelementptr inbounds i8, ptr %varargs, i32 8
|
%1 = getelementptr inbounds nuw i8, ptr %varargs, i32 8
|
||||||
store i32 3, ptr %1, align 4
|
store i32 3, ptr %1, align 4
|
||||||
%append.new = call { ptr, i32, i32 } @runtime.sliceAppend(ptr %ints.data, ptr nonnull %varargs, i32 %ints.len, i32 %ints.cap, i32 3, i32 4, ptr undef) #3
|
%append.new = call { ptr, i32, i32 } @runtime.sliceAppend(ptr %ints.data, ptr nonnull %varargs, i32 %ints.len, i32 %ints.cap, i32 3, i32 4, ptr undef) #3
|
||||||
%append.newPtr = extractvalue { ptr, i32, i32 } %append.new, 0
|
%append.newPtr = extractvalue { ptr, i32, i32 } %append.new, 0
|
||||||
@@ -322,7 +322,7 @@ unsafe.Slice.throw: ; preds = %entry
|
|||||||
unreachable
|
unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind }
|
attributes #3 = { nounwind }
|
||||||
|
|||||||
Vendored
+6
-6
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'string.go'
|
; ModuleID = 'string.go'
|
||||||
source_filename = "string.go"
|
source_filename = "string.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%runtime._string = type { ptr, i32 }
|
%runtime._string = type { ptr, i32 }
|
||||||
@@ -84,11 +84,11 @@ declare i1 @runtime.stringLess(ptr, i32, ptr, i32, ptr) #1
|
|||||||
define hidden i8 @main.stringLookup(ptr %s.data, i32 %s.len, i8 %x, ptr %context) unnamed_addr #2 {
|
define hidden i8 @main.stringLookup(ptr %s.data, i32 %s.len, i8 %x, ptr %context) unnamed_addr #2 {
|
||||||
entry:
|
entry:
|
||||||
%0 = zext i8 %x to i32
|
%0 = zext i8 %x to i32
|
||||||
%.not = icmp ult i32 %0, %s.len
|
%.not = icmp ugt i32 %s.len, %0
|
||||||
br i1 %.not, label %lookup.next, label %lookup.throw
|
br i1 %.not, label %lookup.next, label %lookup.throw
|
||||||
|
|
||||||
lookup.next: ; preds = %entry
|
lookup.next: ; preds = %entry
|
||||||
%1 = getelementptr inbounds i8, ptr %s.data, i32 %0
|
%1 = getelementptr inbounds nuw i8, ptr %s.data, i32 %0
|
||||||
%2 = load i8, ptr %1, align 1
|
%2 = load i8, ptr %1, align 1
|
||||||
ret i8 %2
|
ret i8 %2
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ lookup.throw: ; preds = %entry
|
|||||||
unreachable
|
unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { nounwind }
|
attributes #3 = { nounwind }
|
||||||
|
|||||||
Vendored
+19
-19
@@ -1,6 +1,6 @@
|
|||||||
; ModuleID = 'zeromap.go'
|
; ModuleID = 'zeromap.go'
|
||||||
source_filename = "zeromap.go"
|
source_filename = "zeromap.go"
|
||||||
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
|
target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20"
|
||||||
target triple = "wasm32-unknown-wasi"
|
target triple = "wasm32-unknown-wasi"
|
||||||
|
|
||||||
%main.hasPadding = type { i1, i32, i1 }
|
%main.hasPadding = type { i1, i32, i1 }
|
||||||
@@ -27,9 +27,9 @@ entry:
|
|||||||
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
|
call void @llvm.lifetime.start.p0(i64 4, ptr nonnull %hashmap.value)
|
||||||
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
|
||||||
store %main.hasPadding %2, ptr %hashmap.key, align 4
|
store %main.hasPadding %2, ptr %hashmap.key, align 4
|
||||||
%3 = getelementptr inbounds i8, ptr %hashmap.key, i32 1
|
%3 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 1
|
||||||
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
||||||
%4 = getelementptr inbounds i8, ptr %hashmap.key, i32 9
|
%4 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 9
|
||||||
call void @runtime.memzero(ptr nonnull %4, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %4, i32 3, ptr undef) #5
|
||||||
%5 = call i1 @runtime.hashmapBinaryGet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, i32 4, ptr undef) #5
|
%5 = call i1 @runtime.hashmapBinaryGet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, i32 4, ptr undef) #5
|
||||||
call void @llvm.lifetime.end.p0(i64 12, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.end.p0(i64 12, ptr nonnull %hashmap.key)
|
||||||
@@ -60,9 +60,9 @@ entry:
|
|||||||
store i32 5, ptr %hashmap.value, align 4
|
store i32 5, ptr %hashmap.value, align 4
|
||||||
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.start.p0(i64 12, ptr nonnull %hashmap.key)
|
||||||
store %main.hasPadding %2, ptr %hashmap.key, align 4
|
store %main.hasPadding %2, ptr %hashmap.key, align 4
|
||||||
%3 = getelementptr inbounds i8, ptr %hashmap.key, i32 1
|
%3 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 1
|
||||||
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
||||||
%4 = getelementptr inbounds i8, ptr %hashmap.key, i32 9
|
%4 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 9
|
||||||
call void @runtime.memzero(ptr nonnull %4, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %4, i32 3, ptr undef) #5
|
||||||
call void @runtime.hashmapBinarySet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, ptr undef) #5
|
call void @runtime.hashmapBinarySet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, ptr undef) #5
|
||||||
call void @llvm.lifetime.end.p0(i64 12, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.end.p0(i64 12, ptr nonnull %hashmap.key)
|
||||||
@@ -81,16 +81,16 @@ entry:
|
|||||||
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
|
||||||
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
|
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
|
||||||
store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
|
store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
|
||||||
%hashmap.key.repack1 = getelementptr inbounds i8, ptr %hashmap.key, i32 12
|
%hashmap.key.repack1 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 12
|
||||||
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
|
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
|
||||||
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4
|
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4
|
||||||
%0 = getelementptr inbounds i8, ptr %hashmap.key, i32 1
|
%0 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 1
|
||||||
call void @runtime.memzero(ptr nonnull %0, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %0, i32 3, ptr undef) #5
|
||||||
%1 = getelementptr inbounds i8, ptr %hashmap.key, i32 9
|
%1 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 9
|
||||||
call void @runtime.memzero(ptr nonnull %1, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %1, i32 3, ptr undef) #5
|
||||||
%2 = getelementptr inbounds i8, ptr %hashmap.key, i32 13
|
%2 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 13
|
||||||
call void @runtime.memzero(ptr nonnull %2, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %2, i32 3, ptr undef) #5
|
||||||
%3 = getelementptr inbounds i8, ptr %hashmap.key, i32 21
|
%3 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 21
|
||||||
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
||||||
%4 = call i1 @runtime.hashmapBinaryGet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, i32 4, ptr undef) #5
|
%4 = call i1 @runtime.hashmapBinaryGet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, i32 4, ptr undef) #5
|
||||||
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %hashmap.key)
|
||||||
@@ -109,16 +109,16 @@ entry:
|
|||||||
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.start.p0(i64 24, ptr nonnull %hashmap.key)
|
||||||
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
|
%s.elt = extractvalue [2 x %main.hasPadding] %s, 0
|
||||||
store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
|
store %main.hasPadding %s.elt, ptr %hashmap.key, align 4
|
||||||
%hashmap.key.repack1 = getelementptr inbounds i8, ptr %hashmap.key, i32 12
|
%hashmap.key.repack1 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 12
|
||||||
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
|
%s.elt2 = extractvalue [2 x %main.hasPadding] %s, 1
|
||||||
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4
|
store %main.hasPadding %s.elt2, ptr %hashmap.key.repack1, align 4
|
||||||
%0 = getelementptr inbounds i8, ptr %hashmap.key, i32 1
|
%0 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 1
|
||||||
call void @runtime.memzero(ptr nonnull %0, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %0, i32 3, ptr undef) #5
|
||||||
%1 = getelementptr inbounds i8, ptr %hashmap.key, i32 9
|
%1 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 9
|
||||||
call void @runtime.memzero(ptr nonnull %1, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %1, i32 3, ptr undef) #5
|
||||||
%2 = getelementptr inbounds i8, ptr %hashmap.key, i32 13
|
%2 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 13
|
||||||
call void @runtime.memzero(ptr nonnull %2, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %2, i32 3, ptr undef) #5
|
||||||
%3 = getelementptr inbounds i8, ptr %hashmap.key, i32 21
|
%3 = getelementptr inbounds nuw i8, ptr %hashmap.key, i32 21
|
||||||
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
call void @runtime.memzero(ptr nonnull %3, i32 3, ptr undef) #5
|
||||||
call void @runtime.hashmapBinarySet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, ptr undef) #5
|
call void @runtime.hashmapBinarySet(ptr %m, ptr nonnull %hashmap.key, ptr nonnull %hashmap.value, ptr undef) #5
|
||||||
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %hashmap.key)
|
call void @llvm.lifetime.end.p0(i64 24, ptr nonnull %hashmap.key)
|
||||||
@@ -132,9 +132,9 @@ entry:
|
|||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #0 = { allockind("alloc,zeroed") allocsize(0) "alloc-family"="runtime.alloc" "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #1 = { "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #1 = { "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #2 = { nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #2 = { nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #3 = { noinline nounwind "target-features"="+bulk-memory,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
attributes #3 = { noinline nounwind "target-features"="+bulk-memory,+bulk-memory-opt,+call-indirect-overlong,+mutable-globals,+nontrapping-fptoint,+sign-ext,-multivalue,-reference-types" }
|
||||||
attributes #4 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
attributes #4 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
||||||
attributes #5 = { nounwind }
|
attributes #5 = { nounwind }
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ go 1.22.0
|
|||||||
require (
|
require (
|
||||||
github.com/aykevl/go-wasm v0.0.2-0.20250317121156-42b86c494139
|
github.com/aykevl/go-wasm v0.0.2-0.20250317121156-42b86c494139
|
||||||
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2
|
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/gofrs/flock v0.8.1
|
github.com/gofrs/flock v0.8.1
|
||||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
|
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
|
||||||
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf
|
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf
|
||||||
@@ -20,17 +18,11 @@ require (
|
|||||||
golang.org/x/sys v0.30.0
|
golang.org/x/sys v0.30.0
|
||||||
golang.org/x/tools v0.30.0
|
golang.org/x/tools v0.30.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74
|
tinygo.org/x/go-llvm v0.0.0-20250916101410-63740cfada08
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/chromedp/sysutil v1.0.0 // indirect
|
|
||||||
github.com/creack/goselect v0.1.2 // indirect
|
github.com/creack/goselect v0.1.2 // indirect
|
||||||
github.com/gobwas/httphead v0.1.0 // indirect
|
|
||||||
github.com/gobwas/pool v0.2.1 // indirect
|
|
||||||
github.com/gobwas/ws v1.1.0 // indirect
|
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
|
||||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
github.com/stretchr/testify v1.8.4 // indirect
|
github.com/stretchr/testify v1.8.4 // indirect
|
||||||
golang.org/x/text v0.22.0 // indirect
|
golang.org/x/text v0.22.0 // indirect
|
||||||
|
|||||||
@@ -2,33 +2,16 @@ github.com/aykevl/go-wasm v0.0.2-0.20250317121156-42b86c494139 h1:2O/WuAt8J5id3k
|
|||||||
github.com/aykevl/go-wasm v0.0.2-0.20250317121156-42b86c494139/go.mod h1:7sXyiaA0WtSogCu67R2252fQpVmJMh9JWJ9ddtGkpWw=
|
github.com/aykevl/go-wasm v0.0.2-0.20250317121156-42b86c494139/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 h1:oMCHnXa6CCCafdPDbMh/lWRhRByN0VFLvv+g+ayx1SI=
|
||||||
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
||||||
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=
|
|
||||||
github.com/chromedp/chromedp v0.7.6 h1:2juGaktzjwULlsn+DnvIZXFUckEp5xs+GOBroaea+jA=
|
|
||||||
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/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
||||||
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
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/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
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=
|
|
||||||
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
|
||||||
github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA=
|
|
||||||
github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
|
|
||||||
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
|
||||||
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
|
||||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg=
|
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf h1:7+FW5aGwISbqUtkfmIpZJGRgNFg2ioYPvFaUxdqpDsg=
|
||||||
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
|
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE=
|
||||||
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf h1:FtEj8sfIcaaBfAKrE1Cwb61YDtYq9JxChK1c7AKce7s=
|
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf h1:FtEj8sfIcaaBfAKrE1Cwb61YDtYq9JxChK1c7AKce7s=
|
||||||
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4=
|
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4=
|
||||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
|
||||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
|
||||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
|
||||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
|
||||||
github.com/marcinbor85/gohex v0.0.0-20200531091804-343a4b548892 h1:6J+qramlHVLmiBOgRiBOnQkno8uprqG6YFFQTt6uYIw=
|
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/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.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
@@ -42,8 +25,6 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
|
|||||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
github.com/mattn/go-tty v0.0.4 h1:NVikla9X8MN0SQAqCYzpGyXv0jY7MNl3HOWD2dkle7E=
|
github.com/mattn/go-tty v0.0.4 h1:NVikla9X8MN0SQAqCYzpGyXv0jY7MNl3HOWD2dkle7E=
|
||||||
github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3pxse28=
|
github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3pxse28=
|
||||||
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
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/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 h1:aQKxg3+2p+IFXXg97McgDGT5zcMrQoi0EICZs8Pgchs=
|
||||||
@@ -63,8 +44,6 @@ golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
|||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
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-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-20191120155948-bd437916bb0e/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.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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||||
@@ -79,5 +58,5 @@ 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.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74 h1:ovavgTdIBWCH8YWlcfq9gkpoyT1+IxMKSn+Df27QwE8=
|
tinygo.org/x/go-llvm v0.0.0-20250916101410-63740cfada08 h1:vvEVYF4Qb38C25U8Ae/1QUWlCSp4pIE0PR+/BwNPvBU=
|
||||||
tinygo.org/x/go-llvm v0.0.0-20250422114502-b8f170971e74/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
tinygo.org/x/go-llvm v0.0.0-20250916101410-63740cfada08/go.mod h1:GFbusT2VTA4I+l4j80b17KFK+6whv69Wtny5U+T8RR0=
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
// Version of TinyGo.
|
// Version of TinyGo.
|
||||||
// Update this value before release of new version of software.
|
// Update this value before release of new version of software.
|
||||||
const version = "0.38.0"
|
const version = "0.40.0-dev"
|
||||||
|
|
||||||
// Return TinyGo version, either in the form 0.30.0 or as a development version
|
// Return TinyGo version, either in the form 0.30.0 or as a development version
|
||||||
// (like 0.30.0-dev-abcd012).
|
// (like 0.30.0-dev-abcd012).
|
||||||
|
|||||||
Vendored
+1
-1
@@ -10,7 +10,7 @@ target triple = "x86_64--linux"
|
|||||||
@main.exposedValue2 = local_unnamed_addr global i16 0
|
@main.exposedValue2 = local_unnamed_addr global i16 0
|
||||||
@main.insertedValue = local_unnamed_addr global { i8, i32, { float, { i64, i16 } } } zeroinitializer
|
@main.insertedValue = local_unnamed_addr global { i8, i32, { float, { i64, i16 } } } zeroinitializer
|
||||||
@main.gepArray = local_unnamed_addr global [8 x i8] zeroinitializer
|
@main.gepArray = local_unnamed_addr global [8 x i8] zeroinitializer
|
||||||
@main.negativeGEP = global ptr getelementptr inbounds (i8, ptr @main.negativeGEP, i64 2)
|
@main.negativeGEP = global ptr getelementptr inbounds nuw (i8, ptr @main.negativeGEP, i64 2)
|
||||||
|
|
||||||
declare void @runtime.printint64(i64) unnamed_addr
|
declare void @runtime.printint64(i64) unnamed_addr
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -5,7 +5,7 @@ target triple = "x86_64--linux"
|
|||||||
@ptrToIntResult = local_unnamed_addr global i8 2
|
@ptrToIntResult = local_unnamed_addr global i8 2
|
||||||
@pointerTagResult = local_unnamed_addr global i64 2
|
@pointerTagResult = local_unnamed_addr global i64 2
|
||||||
@someArray = internal global { i16, i8, i8 } zeroinitializer
|
@someArray = internal global { i16, i8, i8 } zeroinitializer
|
||||||
@someArrayPointer = local_unnamed_addr global ptr getelementptr inbounds (i8, ptr @someArray, i64 2)
|
@someArrayPointer = local_unnamed_addr global ptr getelementptr inbounds nuw (i8, ptr @someArray, i64 2)
|
||||||
|
|
||||||
define void @runtime.initAll() local_unnamed_addr {
|
define void @runtime.initAll() local_unnamed_addr {
|
||||||
ret void
|
ret void
|
||||||
|
|||||||
@@ -291,7 +291,8 @@ func Test(pkgName string, stdout, stderr io.Writer, options *compileopts.Options
|
|||||||
})
|
})
|
||||||
|
|
||||||
if testConfig.CompileOnly {
|
if testConfig.CompileOnly {
|
||||||
return true, nil
|
// Return the compiler error, if there is one.
|
||||||
|
return true, err
|
||||||
}
|
}
|
||||||
|
|
||||||
importPath := strings.TrimSuffix(result.ImportPath, ".test")
|
importPath := strings.TrimSuffix(result.ImportPath, ".test")
|
||||||
@@ -339,8 +340,17 @@ func dirsToModuleRootAbs(maindir, modroot string) []string {
|
|||||||
return dirs
|
return dirs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// validateOutputFormat checks if the output file extension matches the expected format
|
||||||
|
func validateOutputFormat(outpath, expectedExt string) error {
|
||||||
|
actualExt := filepath.Ext(outpath)
|
||||||
|
if actualExt != expectedExt {
|
||||||
|
return fmt.Errorf("output format %s does not match target format %s", actualExt, expectedExt)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Flash builds and flashes the built binary to the given serial port.
|
// Flash builds and flashes the built binary to the given serial port.
|
||||||
func Flash(pkgName, port string, options *compileopts.Options) error {
|
func Flash(pkgName, port, outpath string, options *compileopts.Options) error {
|
||||||
config, err := builder.NewConfig(options)
|
config, err := builder.NewConfig(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -389,13 +399,24 @@ func Flash(pkgName, port string, options *compileopts.Options) error {
|
|||||||
if !options.Work {
|
if !options.Work {
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
}
|
}
|
||||||
|
// Validate output format before building
|
||||||
|
if outpath != "" {
|
||||||
|
if err := validateOutputFormat(outpath, fileExt); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
// Build the binary.
|
// Build the binary.
|
||||||
result, err := builder.Build(pkgName, fileExt, tmpdir, config)
|
result, err := builder.Build(pkgName, fileExt, tmpdir, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save output file if specified (after build, before flashing)
|
||||||
|
if outpath != "" {
|
||||||
|
if err := copyFile(result.Binary, outpath); err != nil {
|
||||||
|
return fmt.Errorf("failed to save output file: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
// do we need port reset to put MCU into bootloader mode?
|
// do we need port reset to put MCU into bootloader mode?
|
||||||
if config.Target.PortReset == "true" && flashMethod != "openocd" {
|
if config.Target.PortReset == "true" && flashMethod != "openocd" {
|
||||||
port, err := getDefaultPort(port, config.Target.SerialPort)
|
port, err := getDefaultPort(port, config.Target.SerialPort)
|
||||||
@@ -1297,6 +1318,11 @@ extension at all.`
|
|||||||
(https://tinygo.org/docs/reference/microcontrollers/).
|
(https://tinygo.org/docs/reference/microcontrollers/).
|
||||||
Examples: "arduino-nano", "d1mini", "xiao".
|
Examples: "arduino-nano", "d1mini", "xiao".
|
||||||
|
|
||||||
|
-o={filename}:
|
||||||
|
Save the built binary to the specified output file. The file
|
||||||
|
format must match the target's expected format (e.g., .hex,
|
||||||
|
.uf2). Both flashing and saving will be performed.
|
||||||
|
|
||||||
-monitor:
|
-monitor:
|
||||||
Start the serial monitor (see below) immediately after
|
Start the serial monitor (see below) immediately after
|
||||||
flashing. However, some microcontrollers need a split second
|
flashing. However, some microcontrollers need a split second
|
||||||
@@ -1627,7 +1653,7 @@ func main() {
|
|||||||
flag.BoolVar(&flagTest, "test", false, "supply -test flag to go list")
|
flag.BoolVar(&flagTest, "test", false, "supply -test flag to go list")
|
||||||
}
|
}
|
||||||
var outpath string
|
var outpath string
|
||||||
if command == "help" || command == "build" || command == "test" {
|
if command == "help" || command == "build" || command == "test" || command == "flash" {
|
||||||
flag.StringVar(&outpath, "o", "", "output filename")
|
flag.StringVar(&outpath, "o", "", "output filename")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1778,7 +1804,7 @@ func main() {
|
|||||||
case "flash", "gdb", "lldb":
|
case "flash", "gdb", "lldb":
|
||||||
pkgName := filepath.ToSlash(flag.Arg(0))
|
pkgName := filepath.ToSlash(flag.Arg(0))
|
||||||
if command == "flash" {
|
if command == "flash" {
|
||||||
err := Flash(pkgName, *port, options)
|
err := Flash(pkgName, *port, outpath, options)
|
||||||
printBuildOutput(err, *flagJSON)
|
printBuildOutput(err, *flagJSON)
|
||||||
} else {
|
} else {
|
||||||
if !options.Debug {
|
if !options.Debug {
|
||||||
@@ -1864,6 +1890,7 @@ func main() {
|
|||||||
wd = ""
|
wd = ""
|
||||||
}
|
}
|
||||||
diagnostics.CreateDiagnostics(err).WriteTo(os.Stderr, wd)
|
diagnostics.CreateDiagnostics(err).WriteTo(os.Stderr, wd)
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
if !passed {
|
if !passed {
|
||||||
select {
|
select {
|
||||||
|
|||||||
@@ -424,10 +424,12 @@ func optionsFromOSARCH(osarch string, sema chan struct{}) compileopts.Options {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func runTest(name string, options compileopts.Options, t *testing.T, cmdArgs, environmentVars []string) {
|
func runTest(name string, options compileopts.Options, t *testing.T, cmdArgs, environmentVars []string) {
|
||||||
|
t.Helper()
|
||||||
runTestWithConfig(name, t, options, cmdArgs, environmentVars)
|
runTestWithConfig(name, t, options, cmdArgs, environmentVars)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runTestWithConfig(name string, t *testing.T, options compileopts.Options, cmdArgs, environmentVars []string) {
|
func runTestWithConfig(name string, t *testing.T, options compileopts.Options, cmdArgs, environmentVars []string) {
|
||||||
|
t.Helper()
|
||||||
// Get the expected output for this test.
|
// Get the expected output for this test.
|
||||||
// Note: not using filepath.Join as it strips the path separator at the end
|
// Note: not using filepath.Join as it strips the path separator at the end
|
||||||
// of the path.
|
// of the path.
|
||||||
@@ -876,6 +878,7 @@ func TestWasmExit(t *testing.T) {
|
|||||||
|
|
||||||
// Check whether the output of a test equals the expected output.
|
// Check whether the output of a test equals the expected output.
|
||||||
func checkOutput(t *testing.T, filename string, actual []byte) {
|
func checkOutput(t *testing.T, filename string, actual []byte) {
|
||||||
|
t.Helper()
|
||||||
expectedOutput, err := os.ReadFile(filename)
|
expectedOutput, err := os.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("could not read output file:", err)
|
t.Fatal("could not read output file:", err)
|
||||||
@@ -884,6 +887,7 @@ func checkOutput(t *testing.T, filename string, actual []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func checkOutputData(t *testing.T, expectedOutput, actual []byte) {
|
func checkOutputData(t *testing.T, expectedOutput, actual []byte) {
|
||||||
|
t.Helper()
|
||||||
expectedOutput = bytes.ReplaceAll(expectedOutput, []byte("\r\n"), []byte("\n"))
|
expectedOutput = bytes.ReplaceAll(expectedOutput, []byte("\r\n"), []byte("\n"))
|
||||||
actual = bytes.ReplaceAll(actual, []byte("\r\n"), []byte("\n"))
|
actual = bytes.ReplaceAll(actual, []byte("\r\n"), []byte("\n"))
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -35,8 +35,8 @@ func Monitor(executable, port string, config *compileopts.Config) error {
|
|||||||
// Use the RTT interface, which is documented (in part) here:
|
// Use the RTT interface, which is documented (in part) here:
|
||||||
// https://wiki.segger.com/RTT
|
// https://wiki.segger.com/RTT
|
||||||
|
|
||||||
// Try to find the "machine.rttSerialInstance" symbol, which is the RTT
|
// Try to find the "_SEGGER_RTT" symbol (machine.rttSerialInstance)
|
||||||
// control block.
|
// symbol, which is the RTT control block.
|
||||||
file, err := elf.Open(executable)
|
file, err := elf.Open(executable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not open ELF file to determine RTT control block: %w", err)
|
return fmt.Errorf("could not open ELF file to determine RTT control block: %w", err)
|
||||||
@@ -48,7 +48,7 @@ func Monitor(executable, port string, config *compileopts.Config) error {
|
|||||||
}
|
}
|
||||||
var address uint64
|
var address uint64
|
||||||
for _, symbol := range symbols {
|
for _, symbol := range symbols {
|
||||||
if symbol.Name == "machine.rttSerialInstance" {
|
if symbol.Name == "_SEGGER_RTT" {
|
||||||
address = symbol.Value
|
address = symbol.Value
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,10 @@ func SecCertificateCopyData(cert CFRef) ([]byte, error) {
|
|||||||
return nil, errors.New("not implemented")
|
return nil, errors.New("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SecTrustCopyCertificateChain(trustObj CFRef) (CFRef, error) {
|
||||||
|
return 0, errors.New("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
func SecTrustEvaluateWithError(trustObj CFRef) (int, error) {
|
func SecTrustEvaluateWithError(trustObj CFRef) (int, error) {
|
||||||
return 0, errors.New("not implemented")
|
return 0, errors.New("not implemented")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,3 +8,10 @@ import "unsafe"
|
|||||||
func NoEscape(p unsafe.Pointer) unsafe.Pointer {
|
func NoEscape(p unsafe.Pointer) unsafe.Pointer {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Escape[T any](x T) T {
|
||||||
|
// This function is either implemented in the compiler, or left undefined
|
||||||
|
// for some variation of T. The body of this function should not be compiled
|
||||||
|
// as-is.
|
||||||
|
panic("internal/abi.Escape: unreachable (implemented in the compiler)")
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,29 +5,20 @@ import "unsafe"
|
|||||||
// Internal constants for gc layout
|
// Internal constants for gc layout
|
||||||
// See runtime/gc_precise.go
|
// See runtime/gc_precise.go
|
||||||
|
|
||||||
var (
|
type Layout uintptr
|
||||||
NoPtrs unsafe.Pointer
|
|
||||||
Pointer unsafe.Pointer
|
const (
|
||||||
String unsafe.Pointer
|
// 16-bit int => bits = 4
|
||||||
Slice unsafe.Pointer
|
// 32-bit int => bits = 5
|
||||||
|
// 64-bit int => bits = 6
|
||||||
|
sizeBits = 4 + unsafe.Sizeof(uintptr(0))/4
|
||||||
|
|
||||||
|
sizeShift = sizeBits + 1
|
||||||
|
|
||||||
|
NoPtrs = Layout(uintptr(0b0<<sizeShift) | uintptr(0b1<<1) | uintptr(1))
|
||||||
|
Pointer = Layout(uintptr(0b1<<sizeShift) | uintptr(0b1<<1) | uintptr(1))
|
||||||
|
String = Layout(uintptr(0b01<<sizeShift) | uintptr(0b10<<1) | uintptr(1))
|
||||||
|
Slice = Layout(uintptr(0b001<<sizeShift) | uintptr(0b11<<1) | uintptr(1))
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func (l Layout) AsPtr() unsafe.Pointer { return unsafe.Pointer(l) }
|
||||||
var sizeBits uintptr
|
|
||||||
|
|
||||||
switch unsafe.Sizeof(uintptr(0)) {
|
|
||||||
case 8:
|
|
||||||
sizeBits = 6
|
|
||||||
case 4:
|
|
||||||
sizeBits = 5
|
|
||||||
case 2:
|
|
||||||
sizeBits = 4
|
|
||||||
}
|
|
||||||
|
|
||||||
var sizeShift = sizeBits + 1
|
|
||||||
|
|
||||||
NoPtrs = unsafe.Pointer(uintptr(0b0<<sizeShift) | uintptr(0b1<<1) | uintptr(1))
|
|
||||||
Pointer = unsafe.Pointer(uintptr(0b1<<sizeShift) | uintptr(0b1<<1) | uintptr(1))
|
|
||||||
String = unsafe.Pointer(uintptr(0b01<<sizeShift) | uintptr(0b10<<1) | uintptr(1))
|
|
||||||
Slice = unsafe.Pointer(uintptr(0b001<<sizeShift) | uintptr(0b11<<1) | uintptr(1))
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -708,16 +708,16 @@ func (r *RawType) gcLayout() unsafe.Pointer {
|
|||||||
kind := r.Kind()
|
kind := r.Kind()
|
||||||
|
|
||||||
if kind < String {
|
if kind < String {
|
||||||
return gclayout.NoPtrs
|
return gclayout.NoPtrs.AsPtr()
|
||||||
}
|
}
|
||||||
|
|
||||||
switch kind {
|
switch kind {
|
||||||
case Pointer, UnsafePointer, Chan, Map:
|
case Pointer, UnsafePointer, Chan, Map:
|
||||||
return gclayout.Pointer
|
return gclayout.Pointer.AsPtr()
|
||||||
case String:
|
case String:
|
||||||
return gclayout.String
|
return gclayout.String.AsPtr()
|
||||||
case Slice:
|
case Slice:
|
||||||
return gclayout.Slice
|
return gclayout.Slice.AsPtr()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unknown (for now); let the conservative pointer scanning handle it
|
// Unknown (for now); let the conservative pointer scanning handle it
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
//go:build darwin
|
||||||
|
|
||||||
|
package task
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// MacOS uses a pointer so unsafe.Pointer should be fine:
|
||||||
|
//
|
||||||
|
// typedef struct _opaque_pthread_t *__darwin_pthread_t;
|
||||||
|
// typedef __darwin_pthread_t pthread_t;
|
||||||
|
type threadID unsafe.Pointer
|
||||||
@@ -2,16 +2,28 @@
|
|||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <semaphore.h>
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
// BDWGC also uses SIGRTMIN+6 on Linux, which seems like a reasonable choice.
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
#include <semaphore.h>
|
||||||
|
|
||||||
|
// BDWGC also uses SIGRTMIN+6 on Linux, which seems like a reasonable choice.
|
||||||
#define taskPauseSignal (SIGRTMIN + 6)
|
#define taskPauseSignal (SIGRTMIN + 6)
|
||||||
#endif
|
|
||||||
|
#elif __APPLE__
|
||||||
|
#include <dispatch/dispatch.h>
|
||||||
|
// SIGIO is for interrupt-driven I/O.
|
||||||
|
// I don't think anybody should be using this nowadays, so I think we can
|
||||||
|
// repurpose it as a signal for GC.
|
||||||
|
// BDWGC uses a special way to pause/resume other threads on MacOS, which may be
|
||||||
|
// better but needs more work. Using signal keeps the code similar between Linux
|
||||||
|
// and MacOS.
|
||||||
|
#define taskPauseSignal SIGIO
|
||||||
|
|
||||||
|
#endif // __linux__, __APPLE__
|
||||||
|
|
||||||
// Pointer to the current task.Task structure.
|
// Pointer to the current task.Task structure.
|
||||||
// Ideally the entire task.Task structure would be a thread-local variable but
|
// Ideally the entire task.Task structure would be a thread-local variable but
|
||||||
@@ -23,7 +35,11 @@ struct state_pass {
|
|||||||
void *args;
|
void *args;
|
||||||
void *task;
|
void *task;
|
||||||
uintptr_t *stackTop;
|
uintptr_t *stackTop;
|
||||||
|
#if __APPLE__
|
||||||
|
dispatch_semaphore_t startlock;
|
||||||
|
#else
|
||||||
sem_t startlock;
|
sem_t startlock;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle the GC pause in Go.
|
// Handle the GC pause in Go.
|
||||||
@@ -41,8 +57,8 @@ void tinygo_task_init(void *mainTask, pthread_t *thread, int *numCPU, void *cont
|
|||||||
// Register the "GC pause" signal for the entire process.
|
// Register the "GC pause" signal for the entire process.
|
||||||
// Using pthread_kill, we can still send the signal to a specific thread.
|
// Using pthread_kill, we can still send the signal to a specific thread.
|
||||||
struct sigaction act = { 0 };
|
struct sigaction act = { 0 };
|
||||||
act.sa_flags = SA_SIGINFO;
|
act.sa_handler = tinygo_task_gc_pause;
|
||||||
act.sa_handler = &tinygo_task_gc_pause;
|
act.sa_flags = SA_RESTART;
|
||||||
sigaction(taskPauseSignal, &act, NULL);
|
sigaction(taskPauseSignal, &act, NULL);
|
||||||
|
|
||||||
// Obtain the number of CPUs available on program start (for NumCPU).
|
// Obtain the number of CPUs available on program start (for NumCPU).
|
||||||
@@ -69,7 +85,11 @@ static void* start_wrapper(void *arg) {
|
|||||||
|
|
||||||
// Notify the caller that the thread has successfully started and
|
// Notify the caller that the thread has successfully started and
|
||||||
// initialized.
|
// initialized.
|
||||||
|
#if __APPLE__
|
||||||
|
dispatch_semaphore_signal(state->startlock);
|
||||||
|
#else
|
||||||
sem_post(&state->startlock);
|
sem_post(&state->startlock);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Run the goroutine function.
|
// Run the goroutine function.
|
||||||
start(args);
|
start(args);
|
||||||
@@ -81,7 +101,7 @@ static void* start_wrapper(void *arg) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Start a new goroutine in an OS thread.
|
// Start a new goroutine in an OS thread.
|
||||||
int tinygo_task_start(uintptr_t fn, void *args, void *task, pthread_t *thread, uintptr_t *stackTop, void *context) {
|
int tinygo_task_start(uintptr_t fn, void *args, void *task, pthread_t *thread, uintptr_t *stackTop, uintptr_t stackSize, void *context) {
|
||||||
// Sanity check. Should get optimized away.
|
// Sanity check. Should get optimized away.
|
||||||
if (sizeof(pthread_t) != sizeof(void*)) {
|
if (sizeof(pthread_t) != sizeof(void*)) {
|
||||||
__builtin_trap();
|
__builtin_trap();
|
||||||
@@ -93,11 +113,23 @@ int tinygo_task_start(uintptr_t fn, void *args, void *task, pthread_t *thread, u
|
|||||||
.task = task,
|
.task = task,
|
||||||
.stackTop = stackTop,
|
.stackTop = stackTop,
|
||||||
};
|
};
|
||||||
|
#if __APPLE__
|
||||||
|
state.startlock = dispatch_semaphore_create(0);
|
||||||
|
#else
|
||||||
sem_init(&state.startlock, 0, 0);
|
sem_init(&state.startlock, 0, 0);
|
||||||
int result = pthread_create(thread, NULL, &start_wrapper, &state);
|
#endif
|
||||||
|
pthread_attr_t attrs;
|
||||||
|
pthread_attr_init(&attrs);
|
||||||
|
pthread_attr_setstacksize(&attrs, stackSize);
|
||||||
|
int result = pthread_create(thread, &attrs, &start_wrapper, &state);
|
||||||
|
pthread_attr_destroy(&attrs);
|
||||||
|
|
||||||
// Wait until the thread has been created and read all state_pass variables.
|
// Wait until the thread has been created and read all state_pass variables.
|
||||||
|
#if __APPLE__
|
||||||
|
dispatch_semaphore_wait(state.startlock, DISPATCH_TIME_FOREVER);
|
||||||
|
#else
|
||||||
sem_wait(&state.startlock);
|
sem_wait(&state.startlock);
|
||||||
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ func start(fn uintptr, args unsafe.Pointer, stackSize uintptr) {
|
|||||||
// and the stop-the-world GC won't see threads that haven't started yet or
|
// and the stop-the-world GC won't see threads that haven't started yet or
|
||||||
// are not fully started yet.
|
// are not fully started yet.
|
||||||
activeTaskLock.Lock()
|
activeTaskLock.Lock()
|
||||||
errCode := tinygo_task_start(fn, args, t, &t.state.thread, &t.state.stackTop)
|
errCode := tinygo_task_start(fn, args, t, &t.state.thread, &t.state.stackTop, stackSize)
|
||||||
if errCode != 0 {
|
if errCode != 0 {
|
||||||
runtimePanic("could not start thread")
|
runtimePanic("could not start thread")
|
||||||
}
|
}
|
||||||
@@ -220,7 +220,7 @@ func gcScanGlobals()
|
|||||||
var stackScanLock PMutex
|
var stackScanLock PMutex
|
||||||
|
|
||||||
//export tinygo_task_gc_pause
|
//export tinygo_task_gc_pause
|
||||||
func tingyo_task_gc_pause() {
|
func tingyo_task_gc_pause(sig int32) {
|
||||||
// Wait until we get the signal to start scanning the stack.
|
// Wait until we get the signal to start scanning the stack.
|
||||||
Current().state.gcSem.Wait()
|
Current().state.gcSem.Wait()
|
||||||
|
|
||||||
@@ -266,7 +266,7 @@ func tinygo_task_init(t *Task, thread *threadID, numCPU *int32)
|
|||||||
// Here same as for tinygo_task_init.
|
// Here same as for tinygo_task_init.
|
||||||
//
|
//
|
||||||
//go:linkname tinygo_task_start tinygo_task_start
|
//go:linkname tinygo_task_start tinygo_task_start
|
||||||
func tinygo_task_start(fn uintptr, args unsafe.Pointer, t *Task, thread *threadID, stackTop *uintptr) int32
|
func tinygo_task_start(fn uintptr, args unsafe.Pointer, t *Task, thread *threadID, stackTop *uintptr, stackSize uintptr) int32
|
||||||
|
|
||||||
// Pause the thread by sending it a signal.
|
// Pause the thread by sending it a signal.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ const (
|
|||||||
PC1 = portC + 1
|
PC1 = portC + 1
|
||||||
PC2 = portC + 2
|
PC2 = portC + 2
|
||||||
PC3 = portC + 3
|
PC3 = portC + 3
|
||||||
PC4 = portC + 4
|
PC4 = portC + 4 // peripherals: I2C0 SDA
|
||||||
PC5 = portC + 5
|
PC5 = portC + 5 // peripherals: I2C0 SCL
|
||||||
PC6 = portC + 6
|
PC6 = portC + 6
|
||||||
PC7 = portC + 7
|
PC7 = portC + 7
|
||||||
PD0 = portD + 0
|
PD0 = portD + 0
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ const (
|
|||||||
PC1 = portC + 1
|
PC1 = portC + 1
|
||||||
PC2 = portC + 2
|
PC2 = portC + 2
|
||||||
PC3 = portC + 3
|
PC3 = portC + 3
|
||||||
PC4 = portC + 4
|
PC4 = portC + 4 // peripherals: I2C0 SDA
|
||||||
PC5 = portC + 5
|
PC5 = portC + 5 // peripherals: I2C0 SCL
|
||||||
PC6 = portC + 6
|
PC6 = portC + 6
|
||||||
PC7 = portC + 7
|
PC7 = portC + 7
|
||||||
PD0 = portD + 0
|
PD0 = portD + 0
|
||||||
@@ -40,8 +40,8 @@ const (
|
|||||||
PD5 = portD + 5 // peripherals: Timer0 channel B
|
PD5 = portD + 5 // peripherals: Timer0 channel B
|
||||||
PD6 = portD + 6 // peripherals: Timer0 channel A
|
PD6 = portD + 6 // peripherals: Timer0 channel A
|
||||||
PD7 = portD + 7
|
PD7 = portD + 7
|
||||||
PE0 = portE + 0
|
PE0 = portE + 0 // peripherals: I2C1 SDA
|
||||||
PE1 = portE + 1
|
PE1 = portE + 1 // peripherals: I2C1 SCL
|
||||||
PE2 = portE + 2
|
PE2 = portE + 2
|
||||||
PE3 = portE + 3
|
PE3 = portE + 3
|
||||||
PE4 = portE + 4
|
PE4 = portE + 4
|
||||||
|
|||||||
@@ -7,32 +7,36 @@ func CPUFrequency() uint32 {
|
|||||||
return 48000000
|
return 48000000
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note that the below pins have a few I2C pins listed that according to the
|
||||||
|
// datasheet don't support I2C yet they are used in practice on boards from
|
||||||
|
// Adafruit and Arduino. See machine_atsamd21_simulator.go for details.
|
||||||
|
|
||||||
// Hardware pins
|
// Hardware pins
|
||||||
const (
|
const (
|
||||||
PA00 Pin = 0 // peripherals: TCC2 channel 0
|
PA00 Pin = 0 // peripherals: TCC2 channel 0, sercomI2CM1 SDA
|
||||||
PA01 Pin = 1 // peripherals: TCC2 channel 1
|
PA01 Pin = 1 // peripherals: TCC2 channel 1, sercomI2CM1 SCL
|
||||||
PA02 Pin = 2
|
PA02 Pin = 2
|
||||||
PA03 Pin = 3
|
PA03 Pin = 3
|
||||||
PA04 Pin = 4 // peripherals: TCC0 channel 0
|
PA04 Pin = 4 // peripherals: TCC0 channel 0
|
||||||
PA05 Pin = 5 // peripherals: TCC0 channel 1
|
PA05 Pin = 5 // peripherals: TCC0 channel 1
|
||||||
PA06 Pin = 6 // peripherals: TCC1 channel 0
|
PA06 Pin = 6 // peripherals: TCC1 channel 0
|
||||||
PA07 Pin = 7 // peripherals: TCC1 channel 1
|
PA07 Pin = 7 // peripherals: TCC1 channel 1
|
||||||
PA08 Pin = 8 // peripherals: TCC0 channel 0, TCC1 channel 2
|
PA08 Pin = 8 // peripherals: TCC0 channel 0, TCC1 channel 2, sercomI2CM0 SDA, sercomI2CM2 SDA
|
||||||
PA09 Pin = 9 // peripherals: TCC0 channel 1, TCC1 channel 3
|
PA09 Pin = 9 // peripherals: TCC0 channel 1, TCC1 channel 3, sercomI2CM0 SCL, sercomI2CM2 SCL
|
||||||
PA10 Pin = 10 // peripherals: TCC1 channel 0, TCC0 channel 2
|
PA10 Pin = 10 // peripherals: TCC1 channel 0, TCC0 channel 2
|
||||||
PA11 Pin = 11 // peripherals: TCC1 channel 1, TCC0 channel 3
|
PA11 Pin = 11 // peripherals: TCC1 channel 1, TCC0 channel 3
|
||||||
PA12 Pin = 12 // peripherals: TCC2 channel 0, TCC0 channel 2
|
PA12 Pin = 12 // peripherals: TCC2 channel 0, TCC0 channel 2, sercomI2CM2 SDA, sercomI2CM4 SDA
|
||||||
PA13 Pin = 13 // peripherals: TCC2 channel 1, TCC0 channel 3
|
PA13 Pin = 13 // peripherals: TCC2 channel 1, TCC0 channel 3, sercomI2CM2 SCL, sercomI2CM4 SCL
|
||||||
PA14 Pin = 14 // peripherals: TCC0 channel 0
|
PA14 Pin = 14 // peripherals: TCC0 channel 0
|
||||||
PA15 Pin = 15 // peripherals: TCC0 channel 1
|
PA15 Pin = 15 // peripherals: TCC0 channel 1
|
||||||
PA16 Pin = 16 // peripherals: TCC2 channel 0, TCC0 channel 2
|
PA16 Pin = 16 // peripherals: TCC2 channel 0, TCC0 channel 2, sercomI2CM1 SDA, sercomI2CM3 SDA
|
||||||
PA17 Pin = 17 // peripherals: TCC2 channel 1, TCC0 channel 3
|
PA17 Pin = 17 // peripherals: TCC2 channel 1, TCC0 channel 3, sercomI2CM1 SCL, sercomI2CM3 SCL
|
||||||
PA18 Pin = 18 // peripherals: TCC0 channel 2
|
PA18 Pin = 18 // peripherals: TCC0 channel 2
|
||||||
PA19 Pin = 19 // peripherals: TCC0 channel 3
|
PA19 Pin = 19 // peripherals: TCC0 channel 3
|
||||||
PA20 Pin = 20 // peripherals: TCC0 channel 2
|
PA20 Pin = 20 // peripherals: TCC0 channel 2
|
||||||
PA21 Pin = 21 // peripherals: TCC0 channel 3
|
PA21 Pin = 21 // peripherals: TCC0 channel 3
|
||||||
PA22 Pin = 22 // peripherals: TCC0 channel 0
|
PA22 Pin = 22 // peripherals: TCC0 channel 0, sercomI2CM3 SDA, sercomI2CM5 SDA
|
||||||
PA23 Pin = 23 // peripherals: TCC0 channel 1
|
PA23 Pin = 23 // peripherals: TCC0 channel 1, sercomI2CM3 SCL, sercomI2CM5 SCL
|
||||||
PA24 Pin = 24 // peripherals: TCC1 channel 2
|
PA24 Pin = 24 // peripherals: TCC1 channel 2
|
||||||
PA25 Pin = 25 // peripherals: TCC1 channel 3
|
PA25 Pin = 25 // peripherals: TCC1 channel 3
|
||||||
PA26 Pin = 26
|
PA26 Pin = 26
|
||||||
@@ -43,22 +47,22 @@ const (
|
|||||||
PA31 Pin = 31 // peripherals: TCC1 channel 1
|
PA31 Pin = 31 // peripherals: TCC1 channel 1
|
||||||
PB00 Pin = 32
|
PB00 Pin = 32
|
||||||
PB01 Pin = 33
|
PB01 Pin = 33
|
||||||
PB02 Pin = 34
|
PB02 Pin = 34 // peripherals: sercomI2CM5 SDA
|
||||||
PB03 Pin = 35
|
PB03 Pin = 35 // peripherals: sercomI2CM5 SCL
|
||||||
PB04 Pin = 36
|
PB04 Pin = 36
|
||||||
PB05 Pin = 37
|
PB05 Pin = 37
|
||||||
PB06 Pin = 38
|
PB06 Pin = 38
|
||||||
PB07 Pin = 39
|
PB07 Pin = 39
|
||||||
PB08 Pin = 40
|
PB08 Pin = 40 // peripherals: sercomI2CM4 SDA
|
||||||
PB09 Pin = 41
|
PB09 Pin = 41 // peripherals: sercomI2CM4 SCL
|
||||||
PB10 Pin = 42 // peripherals: TCC0 channel 0
|
PB10 Pin = 42 // peripherals: TCC0 channel 0
|
||||||
PB11 Pin = 43 // peripherals: TCC0 channel 1
|
PB11 Pin = 43 // peripherals: TCC0 channel 1
|
||||||
PB12 Pin = 44 // peripherals: TCC0 channel 2
|
PB12 Pin = 44 // peripherals: TCC0 channel 2, sercomI2CM4 SDA
|
||||||
PB13 Pin = 45 // peripherals: TCC0 channel 3
|
PB13 Pin = 45 // peripherals: TCC0 channel 3, sercomI2CM4 SCL
|
||||||
PB14 Pin = 46
|
PB14 Pin = 46
|
||||||
PB15 Pin = 47
|
PB15 Pin = 47
|
||||||
PB16 Pin = 48 // peripherals: TCC0 channel 0
|
PB16 Pin = 48 // peripherals: TCC0 channel 0, sercomI2CM5 SDA
|
||||||
PB17 Pin = 49 // peripherals: TCC0 channel 1
|
PB17 Pin = 49 // peripherals: TCC0 channel 1, sercomI2CM5 SCL
|
||||||
PB18 Pin = 50
|
PB18 Pin = 50
|
||||||
PB19 Pin = 51
|
PB19 Pin = 51
|
||||||
PB20 Pin = 52
|
PB20 Pin = 52
|
||||||
@@ -71,6 +75,6 @@ const (
|
|||||||
PB27 Pin = 59
|
PB27 Pin = 59
|
||||||
PB28 Pin = 60
|
PB28 Pin = 60
|
||||||
PB29 Pin = 61
|
PB29 Pin = 61
|
||||||
PB30 Pin = 62 // peripherals: TCC0 channel 0, TCC1 channel 2
|
PB30 Pin = 62 // peripherals: TCC0 channel 0, TCC1 channel 2, sercomI2CM5 SDA
|
||||||
PB31 Pin = 63 // peripherals: TCC0 channel 1, TCC1 channel 3
|
PB31 Pin = 63 // peripherals: TCC0 channel 1, TCC1 channel 3, sercomI2CM5 SCL
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
//go:build gopher_arcade
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
// Return the current CPU frequency in hertz.
|
||||||
|
func CPUFrequency() uint32 {
|
||||||
|
return 8000000
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
P5 Pin = PB0
|
||||||
|
P6 Pin = PB1
|
||||||
|
P7 Pin = PB2
|
||||||
|
P2 Pin = PB3
|
||||||
|
P3 Pin = PB4
|
||||||
|
P1 Pin = PB5
|
||||||
|
|
||||||
|
LED = P1
|
||||||
|
BUTTON_LEFT = P7
|
||||||
|
BUTTON_RIGHT = P5
|
||||||
|
SPEAKER = P6
|
||||||
|
)
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
//go:build metro_rp2350
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
// GPIO pins
|
||||||
|
const (
|
||||||
|
GP0 Pin = GPIO0
|
||||||
|
GP1 Pin = GPIO1
|
||||||
|
GP2 Pin = GPIO2
|
||||||
|
GP3 Pin = GPIO3
|
||||||
|
GP4 Pin = GPIO4
|
||||||
|
GP5 Pin = GPIO5
|
||||||
|
GP6 Pin = GPIO6
|
||||||
|
GP7 Pin = GPIO7
|
||||||
|
GP8 Pin = GPIO8
|
||||||
|
GP9 Pin = GPIO9
|
||||||
|
GP10 Pin = GPIO10
|
||||||
|
GP11 Pin = GPIO11
|
||||||
|
GP12 Pin = GPIO12
|
||||||
|
GP13 Pin = GPIO13
|
||||||
|
GP14 Pin = GPIO14
|
||||||
|
GP15 Pin = GPIO15
|
||||||
|
GP16 Pin = GPIO16
|
||||||
|
GP17 Pin = GPIO17
|
||||||
|
GP18 Pin = GPIO18
|
||||||
|
GP19 Pin = GPIO19
|
||||||
|
GP20 Pin = GPIO20
|
||||||
|
GP21 Pin = GPIO21
|
||||||
|
GP22 Pin = GPIO22
|
||||||
|
GP23 Pin = GPIO23
|
||||||
|
GP24 Pin = GPIO24
|
||||||
|
GP25 Pin = GPIO25
|
||||||
|
GP26 Pin = GPIO26
|
||||||
|
GP27 Pin = GPIO27
|
||||||
|
GP28 Pin = GPIO28
|
||||||
|
GP29 Pin = GPIO29
|
||||||
|
GP30 Pin = GPIO30
|
||||||
|
GP31 Pin = GPIO31
|
||||||
|
GP32 Pin = GPIO32
|
||||||
|
GP33 Pin = GPIO33
|
||||||
|
GP34 Pin = GPIO34
|
||||||
|
GP35 Pin = GPIO35
|
||||||
|
GP36 Pin = GPIO36
|
||||||
|
GP37 Pin = GPIO37
|
||||||
|
GP38 Pin = GPIO38
|
||||||
|
GP39 Pin = GPIO39
|
||||||
|
GP40 Pin = GPIO40
|
||||||
|
GP41 Pin = GPIO41
|
||||||
|
GP42 Pin = GPIO42
|
||||||
|
GP43 Pin = GPIO43
|
||||||
|
GP44 Pin = GPIO44
|
||||||
|
GP45 Pin = GPIO45
|
||||||
|
GP46 Pin = GPIO46
|
||||||
|
|
||||||
|
// Boot button
|
||||||
|
BUTTON Pin = GPIO24
|
||||||
|
|
||||||
|
// Onboard LED
|
||||||
|
LED Pin = GPIO23
|
||||||
|
|
||||||
|
// Onboard NeoPixel
|
||||||
|
NEOPIXEL Pin = GPIO25
|
||||||
|
WS2812 Pin = GPIO25
|
||||||
|
|
||||||
|
// Onboard crystal oscillator frequency, in MHz.
|
||||||
|
xoscFreq = 12 // MHz
|
||||||
|
)
|
||||||
|
|
||||||
|
// Arduino-header digital pins
|
||||||
|
const (
|
||||||
|
RX Pin = GPIO1
|
||||||
|
TX Pin = GPIO0
|
||||||
|
D2 Pin = GPIO2
|
||||||
|
D3 Pin = GPIO3
|
||||||
|
D4 Pin = GPIO4
|
||||||
|
D5 Pin = GPIO5
|
||||||
|
D6 Pin = GPIO6
|
||||||
|
D7 Pin = GPIO7
|
||||||
|
D8 Pin = GPIO8
|
||||||
|
D9 Pin = GPIO9
|
||||||
|
D10 Pin = GPIO10
|
||||||
|
D11 Pin = GPIO11
|
||||||
|
D22 Pin = GPIO22
|
||||||
|
D23 Pin = GPIO23
|
||||||
|
)
|
||||||
|
|
||||||
|
// Arduino-header analog pins
|
||||||
|
const (
|
||||||
|
A0 Pin = GPIO41
|
||||||
|
A1 Pin = GPIO42
|
||||||
|
A2 Pin = GPIO43
|
||||||
|
A3 Pin = GPIO44
|
||||||
|
A4 Pin = GPIO45
|
||||||
|
A5 Pin = GPIO46
|
||||||
|
)
|
||||||
|
|
||||||
|
// I2C Default pins on Raspberry Pico.
|
||||||
|
const (
|
||||||
|
I2C0_SDA_PIN = GP20
|
||||||
|
I2C0_SCL_PIN = GP21
|
||||||
|
|
||||||
|
I2C1_SDA_PIN = GP2
|
||||||
|
I2C1_SCL_PIN = GP3
|
||||||
|
)
|
||||||
|
|
||||||
|
// SPI default pins
|
||||||
|
const (
|
||||||
|
// Default Serial Clock Bus 0 for SPI communications
|
||||||
|
SPI0_SCK_PIN = GPIO18
|
||||||
|
// Default Serial Out Bus 0 for SPI communications
|
||||||
|
SPI0_SDO_PIN = GPIO19 // Tx
|
||||||
|
// Default Serial In Bus 0 for SPI communications
|
||||||
|
SPI0_SDI_PIN = GPIO16 // Rx
|
||||||
|
|
||||||
|
// Default Serial Clock Bus 1 for SPI communications
|
||||||
|
SPI1_SCK_PIN = GPIO30
|
||||||
|
// Default Serial Out Bus 1 for SPI communications
|
||||||
|
SPI1_SDO_PIN = GPIO31 // Tx
|
||||||
|
// Default Serial In Bus 1 for SPI communications
|
||||||
|
SPI1_SDI_PIN = GPIO28 // Rx
|
||||||
|
|
||||||
|
// SPI header pins
|
||||||
|
MOSI Pin = SPI1_SDO_PIN
|
||||||
|
MISO Pin = SPI1_SDI_PIN
|
||||||
|
SCK Pin = SPI1_SCK_PIN
|
||||||
|
)
|
||||||
|
|
||||||
|
// SD card reader pins
|
||||||
|
const (
|
||||||
|
SD_SCK = GPIO34
|
||||||
|
SD_MOSI = GPIO35
|
||||||
|
SD_MISO = GPIO36
|
||||||
|
SDIO_DATA1 = GPIO37
|
||||||
|
SDIO_DATA2 = GPIO38
|
||||||
|
SD_CS = GPIO39
|
||||||
|
SD_CARD_DETECT = GPIO40
|
||||||
|
)
|
||||||
|
|
||||||
|
// HSTX pins
|
||||||
|
const (
|
||||||
|
CKN Pin = GPIO15
|
||||||
|
CKP Pin = GPIO14
|
||||||
|
D0N Pin = GPIO19
|
||||||
|
D0P Pin = GPIO18
|
||||||
|
D1N Pin = GPIO17
|
||||||
|
D1P Pin = GPIO16
|
||||||
|
D2N Pin = GPIO13
|
||||||
|
D2P Pin = GPIO12
|
||||||
|
D26 Pin = GPIO26
|
||||||
|
D27 Pin = GPIO27
|
||||||
|
SCL Pin = GPIO21
|
||||||
|
SDA Pin = GPIO20
|
||||||
|
)
|
||||||
|
|
||||||
|
// USB host header pins
|
||||||
|
const (
|
||||||
|
USB_HOST_DATA_PLUS Pin = GPIO32
|
||||||
|
USB_HOST_DATA_MINUS Pin = GPIO33
|
||||||
|
USB_HOST_5V_POWER Pin = GPIO29
|
||||||
|
)
|
||||||
|
|
||||||
|
// UART pins
|
||||||
|
const (
|
||||||
|
UART0_TX_PIN = GPIO0
|
||||||
|
UART0_RX_PIN = GPIO1
|
||||||
|
UART1_TX_PIN = GPIO8
|
||||||
|
UART1_RX_PIN = GPIO9
|
||||||
|
UART_TX_PIN = UART0_TX_PIN
|
||||||
|
UART_RX_PIN = UART0_RX_PIN
|
||||||
|
)
|
||||||
|
|
||||||
|
var DefaultUART = UART0
|
||||||
|
|
||||||
|
// USB identifiers
|
||||||
|
const (
|
||||||
|
usb_STRING_PRODUCT = "Metro RP2350"
|
||||||
|
usb_STRING_MANUFACTURER = "Adafruit"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
usb_VID uint16 = 0x239A
|
||||||
|
usb_PID uint16 = 0x814E
|
||||||
|
)
|
||||||
@@ -31,25 +31,24 @@ const (
|
|||||||
GP27 = GPIO27
|
GP27 = GPIO27
|
||||||
GP28 = GPIO28
|
GP28 = GPIO28
|
||||||
GP29 = GPIO29
|
GP29 = GPIO29
|
||||||
GP30 = GPIO30 // peripherals: PWM7 channel A
|
GP30 = GPIO30
|
||||||
GP31 = GPIO31 // peripherals: PWM7 channel B
|
GP31 = GPIO31
|
||||||
GP32 = GPIO32 // peripherals: PWM8 channel A
|
GP32 = GPIO32
|
||||||
GP33 = GPIO33 // peripherals: PWM8 channel B
|
GP33 = GPIO33
|
||||||
GP34 = GPIO34 // peripherals: PWM9 channel A
|
GP34 = GPIO34
|
||||||
GP35 = GPIO35 // peripherals: PWM9 channel B
|
GP35 = GPIO35
|
||||||
GP36 = GPIO36 // peripherals: PWM10 channel A
|
GP36 = GPIO36
|
||||||
GP37 = GPIO37 // peripherals: PWM10 channel B
|
GP37 = GPIO37
|
||||||
GP38 = GPIO38 // peripherals: PWM11 channel A
|
GP38 = GPIO38
|
||||||
GP39 = GPIO39 // peripherals: PWM11 channel B
|
GP39 = GPIO39
|
||||||
GP40 = GPIO40 // peripherals: PWM8 channel A
|
GP40 = GPIO40
|
||||||
GP41 = GPIO41 // peripherals: PWM8 channel B
|
GP41 = GPIO41
|
||||||
GP42 = GPIO42 // peripherals: PWM9 channel A
|
GP42 = GPIO42
|
||||||
GP43 = GPIO43 // peripherals: PWM9 channel B
|
GP43 = GPIO43
|
||||||
GP44 = GPIO44 // peripherals: PWM10 channel A
|
GP44 = GPIO44
|
||||||
GP45 = GPIO45 // peripherals: PWM10 channel B
|
GP45 = GPIO45
|
||||||
GP46 = GPIO46 // peripherals: PWM11 channel A
|
GP46 = GPIO46
|
||||||
GP47 = GPIO47 // peripherals: PWM11 channel B
|
GP47 = GPIO47
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var DefaultUART = UART0
|
var DefaultUART = UART0
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
//go:build stm32l0x1 && !nucleol031k6
|
||||||
|
|
||||||
|
// This file is for the bare STM32L0x1 (not for any specific board that is based
|
||||||
|
// on the STM32L0x1).
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
const (
|
||||||
|
I2C0_SCL_PIN = NoPin
|
||||||
|
I2C0_SDA_PIN = NoPin
|
||||||
|
|
||||||
|
UART_TX_PIN = NoPin
|
||||||
|
UART_RX_PIN = NoPin
|
||||||
|
|
||||||
|
SPI0_SDI_PIN = NoPin
|
||||||
|
SPI0_SDO_PIN = NoPin
|
||||||
|
SPI0_SCK_PIN = NoPin
|
||||||
|
)
|
||||||
@@ -279,7 +279,7 @@ var (
|
|||||||
// #===========#==========#===============#=================-=========#
|
// #===========#==========#===============#=================-=========#
|
||||||
// | SPI1 | LPSPI4 | PLL2(132 MHz) | D12/D11/D13/D10 : 3/3/3/3 |
|
// | SPI1 | LPSPI4 | PLL2(132 MHz) | D12/D11/D13/D10 : 3/3/3/3 |
|
||||||
// | SPI2 | LPSPI3 | PLL2(132 MHz) | D1/D26/D27/D0 : 7/2/2/7 |
|
// | SPI2 | LPSPI3 | PLL2(132 MHz) | D1/D26/D27/D0 : 7/2/2/7 |
|
||||||
// | SPI3 | LPSPI1 | PLL2(132 MHz) | D34/D35/D37/D36 : 4/4/4/4 |
|
// | SPI3 | LPSPI1 | PLL2(132 MHz) | D42/D43/D45/D44 : 4/4/4/4 |
|
||||||
// #===========#==========#===============#=================-=========#
|
// #===========#==========#===============#=================-=========#
|
||||||
const (
|
const (
|
||||||
SPI1_SDI_PIN = D12
|
SPI1_SDI_PIN = D12
|
||||||
@@ -292,10 +292,52 @@ const (
|
|||||||
SPI2_SCK_PIN = D27
|
SPI2_SCK_PIN = D27
|
||||||
SPI2_CS_PIN = D0
|
SPI2_CS_PIN = D0
|
||||||
|
|
||||||
SPI3_SDI_PIN = D34
|
SPI3_SDI_PIN = D42
|
||||||
SPI3_SDO_PIN = D35
|
SPI3_SDO_PIN = D43
|
||||||
SPI3_SCK_PIN = D37
|
SPI3_SCK_PIN = D45
|
||||||
SPI3_CS_PIN = D36
|
SPI3_CS_PIN = D44
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
SPI0 = SPI1 // SPI0 is an alias of SPI1 (LPSPI4)
|
||||||
|
SPI1 = &SPI{
|
||||||
|
Bus: nxp.LPSPI4,
|
||||||
|
muxSDI: muxSelect{ // D12 (PB1 [B0_01])
|
||||||
|
mux: nxp.IOMUXC_LPSPI4_SDI_SELECT_INPUT_DAISY_GPIO_B0_01_ALT3,
|
||||||
|
sel: &nxp.IOMUXC.LPSPI4_SDI_SELECT_INPUT,
|
||||||
|
},
|
||||||
|
muxSDO: muxSelect{ // D11 (PB2 [B0_02])
|
||||||
|
mux: nxp.IOMUXC_LPSPI4_SDO_SELECT_INPUT_DAISY_GPIO_B0_02_ALT3,
|
||||||
|
sel: &nxp.IOMUXC.LPSPI4_SDO_SELECT_INPUT,
|
||||||
|
},
|
||||||
|
muxSCK: muxSelect{ // D13 (PB3 [B0_03])
|
||||||
|
mux: nxp.IOMUXC_LPSPI4_SCK_SELECT_INPUT_DAISY_GPIO_B0_03_ALT3,
|
||||||
|
sel: &nxp.IOMUXC.LPSPI4_SCK_SELECT_INPUT,
|
||||||
|
},
|
||||||
|
muxCS: muxSelect{ // D10 (PB0 [B0_00])
|
||||||
|
mux: nxp.IOMUXC_LPSPI4_PCS0_SELECT_INPUT_DAISY_GPIO_B0_00_ALT3,
|
||||||
|
sel: &nxp.IOMUXC.LPSPI4_PCS0_SELECT_INPUT,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
SPI2 = &SPI{
|
||||||
|
Bus: nxp.LPSPI3,
|
||||||
|
muxSDI: muxSelect{ // D1 (PA2 [AD_B0_02])
|
||||||
|
mux: nxp.IOMUXC_LPSPI3_SDI_SELECT_INPUT_DAISY_GPIO_AD_B0_02_ALT7,
|
||||||
|
sel: &nxp.IOMUXC.LPSPI3_SDI_SELECT_INPUT,
|
||||||
|
},
|
||||||
|
muxSDO: muxSelect{ // D26 (PA30 [AD_B1_14])
|
||||||
|
mux: nxp.IOMUXC_LPSPI3_SDO_SELECT_INPUT_DAISY_GPIO_AD_B1_14_ALT2,
|
||||||
|
sel: &nxp.IOMUXC.LPSPI3_SDO_SELECT_INPUT,
|
||||||
|
},
|
||||||
|
muxSCK: muxSelect{ // D27 (PA31 [AD_B1_15])
|
||||||
|
mux: nxp.IOMUXC_LPSPI3_SCK_SELECT_INPUT_DAISY_GPIO_AD_B1_15,
|
||||||
|
sel: &nxp.IOMUXC.LPSPI3_SCK_SELECT_INPUT,
|
||||||
|
},
|
||||||
|
muxCS: muxSelect{ // D0 (PA3 [AD_B0_03])
|
||||||
|
mux: nxp.IOMUXC_LPSPI3_PCS0_SELECT_INPUT_DAISY_GPIO_AD_B0_03_ALT7,
|
||||||
|
sel: &nxp.IOMUXC.LPSPI3_PCS0_SELECT_INPUT,
|
||||||
|
},
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// #====================================================#
|
// #====================================================#
|
||||||
@@ -317,3 +359,49 @@ const (
|
|||||||
I2C3_SDA_PIN = D25
|
I2C3_SDA_PIN = D25
|
||||||
I2C3_SCL_PIN = D24
|
I2C3_SCL_PIN = D24
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
I2C0 = I2C1 // I2C0 is an alias for I2C1 (LPI2C1)
|
||||||
|
I2C1 = &_I2C1
|
||||||
|
_I2C1 = I2C{
|
||||||
|
Bus: nxp.LPI2C1,
|
||||||
|
sda: I2C1_SDA_PIN, // D18 (PA17 [AD_B1_01])
|
||||||
|
scl: I2C1_SCL_PIN, // D19 (PA16 [AD_B1_00])
|
||||||
|
muxSDA: muxSelect{
|
||||||
|
mux: nxp.IOMUXC_LPI2C1_SDA_SELECT_INPUT_DAISY_GPIO_AD_B1_01_ALT3,
|
||||||
|
sel: &nxp.IOMUXC.LPI2C1_SDA_SELECT_INPUT,
|
||||||
|
},
|
||||||
|
muxSCL: muxSelect{
|
||||||
|
mux: nxp.IOMUXC_LPI2C1_SCL_SELECT_INPUT_DAISY_GPIO_AD_B1_00_ALT3,
|
||||||
|
sel: &nxp.IOMUXC.LPI2C1_SCL_SELECT_INPUT,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
I2C2 = &_I2C2
|
||||||
|
_I2C2 = I2C{
|
||||||
|
Bus: nxp.LPI2C3,
|
||||||
|
sda: I2C2_SDA_PIN, // D17 (PA22 [AD_B1_06])
|
||||||
|
scl: I2C2_SCL_PIN, // D16 (PA23 [AD_B1_07])
|
||||||
|
muxSDA: muxSelect{
|
||||||
|
mux: nxp.IOMUXC_LPI2C3_SDA_SELECT_INPUT_DAISY_GPIO_AD_B1_06_ALT1,
|
||||||
|
sel: &nxp.IOMUXC.LPI2C3_SDA_SELECT_INPUT,
|
||||||
|
},
|
||||||
|
muxSCL: muxSelect{
|
||||||
|
mux: nxp.IOMUXC_LPI2C3_SCL_SELECT_INPUT_DAISY_GPIO_AD_B1_07_ALT1,
|
||||||
|
sel: &nxp.IOMUXC.LPI2C3_SCL_SELECT_INPUT,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
I2C3 = &_I2C3
|
||||||
|
_I2C3 = I2C{
|
||||||
|
Bus: nxp.LPI2C4,
|
||||||
|
sda: I2C3_SDA_PIN, // D25 (PA13 [AD_B0_13])
|
||||||
|
scl: I2C3_SCL_PIN, // D24 (PA12 [AD_B0_12])
|
||||||
|
muxSDA: muxSelect{
|
||||||
|
mux: nxp.IOMUXC_LPI2C4_SDA_SELECT_INPUT_DAISY_GPIO_AD_B0_13_ALT0,
|
||||||
|
sel: &nxp.IOMUXC.LPI2C4_SDA_SELECT_INPUT,
|
||||||
|
},
|
||||||
|
muxSCL: muxSelect{
|
||||||
|
mux: nxp.IOMUXC_LPI2C4_SCL_SELECT_INPUT_DAISY_GPIO_AD_B0_12_ALT0,
|
||||||
|
sel: &nxp.IOMUXC.LPI2C4_SCL_SELECT_INPUT,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
+14
-11
@@ -26,17 +26,20 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errI2CWriteTimeout = errors.New("I2C timeout during write")
|
errI2CWriteTimeout = errors.New("i2c: timeout during write")
|
||||||
errI2CReadTimeout = errors.New("I2C timeout during read")
|
errI2CReadTimeout = errors.New("i2c: timeout during read")
|
||||||
errI2CBusReadyTimeout = errors.New("I2C timeout on bus ready")
|
errI2CBusReadyTimeout = errors.New("i2c: timeout on bus ready")
|
||||||
errI2CSignalStartTimeout = errors.New("I2C timeout on signal start")
|
errI2CSignalStartTimeout = errors.New("i2c: timeout on signal start")
|
||||||
errI2CSignalReadTimeout = errors.New("I2C timeout on signal read")
|
errI2CSignalReadTimeout = errors.New("i2c: timeout on signal read")
|
||||||
errI2CSignalStopTimeout = errors.New("I2C timeout on signal stop")
|
errI2CSignalStopTimeout = errors.New("i2c: timeout on signal stop")
|
||||||
errI2CAckExpected = errors.New("I2C error: expected ACK not NACK")
|
errI2CAckExpected = errors.New("i2c: error: expected ACK not NACK")
|
||||||
errI2CBusError = errors.New("I2C bus error")
|
errI2CBusError = errors.New("i2c: bus error")
|
||||||
errI2COverflow = errors.New("I2C receive buffer overflow")
|
errI2COverflow = errors.New("i2c: receive buffer overflow")
|
||||||
errI2COverread = errors.New("I2C transmit buffer overflow")
|
errI2COverread = errors.New("i2c: transmit buffer overflow")
|
||||||
errI2CNotImplemented = errors.New("I2C operation not yet implemented")
|
errI2CNotImplemented = errors.New("i2c: operation not yet implemented")
|
||||||
|
errI2CNoDevices = errors.New("i2c: bus has no devices") // simulator only
|
||||||
|
errI2CMultipleDevices = errors.New("i2c: bus has address conflict") // simulator only
|
||||||
|
errI2CWrongAddress = errors.New("i2c: bus has devices but none with this address") // simulator only
|
||||||
)
|
)
|
||||||
|
|
||||||
// I2CTargetEvent reflects events on the I2C bus
|
// I2CTargetEvent reflects events on the I2C bus
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ const (
|
|||||||
PC5 = portC + 5
|
PC5 = portC + 5
|
||||||
PC6 = portC + 6
|
PC6 = portC + 6
|
||||||
PC7 = portC + 7
|
PC7 = portC + 7
|
||||||
PD0 = portD + 0
|
PD0 = portD + 0 // peripherals: I2C0 SCL
|
||||||
PD1 = portD + 1
|
PD1 = portD + 1 // peripherals: I2C0 SDA
|
||||||
PD2 = portD + 2
|
PD2 = portD + 2
|
||||||
PD3 = portD + 3
|
PD3 = portD + 3
|
||||||
PD7 = portD + 7
|
PD7 = portD + 7
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
//go:build !baremetal && (arduino || arduino_nano)
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
var I2C0 = &I2C{Bus: 0, PinsSDA: []Pin{PC4}, PinsSCL: []Pin{PC5}}
|
||||||
@@ -43,3 +43,21 @@ var TCC2 = &timerType{
|
|||||||
{PA01, PA13, PA17}, // channel 1
|
{PA01, PA13, PA17}, // channel 1
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// According to the datasheet, only some pins have I2C support. However it
|
||||||
|
// looks like many boards just use any SERCOM I2C instance, even if the
|
||||||
|
// datasheet says those don't support I2C. I guess they do work in practice,
|
||||||
|
// then.
|
||||||
|
// These are:
|
||||||
|
// * PA00/PA01 for the Adafruit Circuit Playground Express (I2C1, SERCOM1).
|
||||||
|
// * PB02/PB03 for the Adafruit Circuit Playground Express (I2C0, SERCOM5).
|
||||||
|
// * PB08/PB09 for the Arduino Nano 33 IoT (I2C0, SERCOM4).
|
||||||
|
// https://cdn.sparkfun.com/datasheets/Dev/Arduino/Boards/Atmel-42181-SAM-D21_Datasheet.pdf
|
||||||
|
sercomI2CM0 = &I2C{Bus: 0, PinsSDA: []Pin{PA08}, PinsSCL: []Pin{PA09}}
|
||||||
|
sercomI2CM1 = &I2C{Bus: 1, PinsSDA: []Pin{PA00, PA16}, PinsSCL: []Pin{PA01, PA17}}
|
||||||
|
sercomI2CM2 = &I2C{Bus: 2, PinsSDA: []Pin{PA08, PA12}, PinsSCL: []Pin{PA09, PA13}}
|
||||||
|
sercomI2CM3 = &I2C{Bus: 3, PinsSDA: []Pin{PA16, PA22}, PinsSCL: []Pin{PA17, PA23}}
|
||||||
|
sercomI2CM4 = &I2C{Bus: 4, PinsSDA: []Pin{PA12, PB08, PB12}, PinsSCL: []Pin{PA13, PB09, PB13}}
|
||||||
|
sercomI2CM5 = &I2C{Bus: 5, PinsSDA: []Pin{PA22, PB02, PB16, PB30}, PinsSCL: []Pin{PA23, PB03, PB17, PB31}}
|
||||||
|
)
|
||||||
|
|||||||
@@ -81,22 +81,22 @@ const (
|
|||||||
PA05 Pin = 5
|
PA05 Pin = 5
|
||||||
PA06 Pin = 6
|
PA06 Pin = 6
|
||||||
PA07 Pin = 7
|
PA07 Pin = 7
|
||||||
PA08 Pin = 8 // peripherals: TCC0 channel 0, TCC1 channel 4
|
PA08 Pin = 8 // peripherals: TCC0 channel 0, TCC1 channel 4, sercomI2CM0 SDA, sercomI2CM2 SDA
|
||||||
PA09 Pin = 9 // peripherals: TCC0 channel 1, TCC1 channel 5
|
PA09 Pin = 9 // peripherals: TCC0 channel 1, TCC1 channel 5, sercomI2CM0 SCL, sercomI2CM2 SCL
|
||||||
PA10 Pin = 10 // peripherals: TCC0 channel 2, TCC1 channel 6
|
PA10 Pin = 10 // peripherals: TCC0 channel 2, TCC1 channel 6
|
||||||
PA11 Pin = 11 // peripherals: TCC0 channel 3, TCC1 channel 7
|
PA11 Pin = 11 // peripherals: TCC0 channel 3, TCC1 channel 7
|
||||||
PA12 Pin = 12 // peripherals: TCC0 channel 6, TCC1 channel 2
|
PA12 Pin = 12 // peripherals: TCC0 channel 6, TCC1 channel 2, sercomI2CM2 SDA, sercomI2CM4 SDA
|
||||||
PA13 Pin = 13 // peripherals: TCC0 channel 7, TCC1 channel 3
|
PA13 Pin = 13 // peripherals: TCC0 channel 7, TCC1 channel 3, sercomI2CM2 SCL, sercomI2CM4 SCL
|
||||||
PA14 Pin = 14 // peripherals: TCC2 channel 0, TCC1 channel 2
|
PA14 Pin = 14 // peripherals: TCC2 channel 0, TCC1 channel 2
|
||||||
PA15 Pin = 15 // peripherals: TCC2 channel 1, TCC1 channel 3
|
PA15 Pin = 15 // peripherals: TCC2 channel 1, TCC1 channel 3
|
||||||
PA16 Pin = 16 // peripherals: TCC1 channel 0, TCC0 channel 4
|
PA16 Pin = 16 // peripherals: TCC1 channel 0, TCC0 channel 4, sercomI2CM1 SDA, sercomI2CM3 SDA
|
||||||
PA17 Pin = 17 // peripherals: TCC1 channel 1, TCC0 channel 5
|
PA17 Pin = 17 // peripherals: TCC1 channel 1, TCC0 channel 5, sercomI2CM1 SCL, sercomI2CM3 SCL
|
||||||
PA18 Pin = 18 // peripherals: TCC1 channel 2, TCC0 channel 6
|
PA18 Pin = 18 // peripherals: TCC1 channel 2, TCC0 channel 6
|
||||||
PA19 Pin = 19 // peripherals: TCC1 channel 3, TCC0 channel 7
|
PA19 Pin = 19 // peripherals: TCC1 channel 3, TCC0 channel 7
|
||||||
PA20 Pin = 20 // peripherals: TCC1 channel 4, TCC0 channel 0
|
PA20 Pin = 20 // peripherals: TCC1 channel 4, TCC0 channel 0
|
||||||
PA21 Pin = 21 // peripherals: TCC1 channel 5, TCC0 channel 1
|
PA21 Pin = 21 // peripherals: TCC1 channel 5, TCC0 channel 1
|
||||||
PA22 Pin = 22 // peripherals: TCC1 channel 6, TCC0 channel 2
|
PA22 Pin = 22 // peripherals: TCC1 channel 6, TCC0 channel 2, sercomI2CM3 SDA, sercomI2CM5 SDA
|
||||||
PA23 Pin = 23 // peripherals: TCC1 channel 7, TCC0 channel 3
|
PA23 Pin = 23 // peripherals: TCC1 channel 7, TCC0 channel 3, sercomI2CM3 SCL, sercomI2CM5 SCL
|
||||||
PA24 Pin = 24 // peripherals: TCC2 channel 2
|
PA24 Pin = 24 // peripherals: TCC2 channel 2
|
||||||
PA25 Pin = 25 // peripherals: TCC2 channel 3
|
PA25 Pin = 25 // peripherals: TCC2 channel 3
|
||||||
PA26 Pin = 26
|
PA26 Pin = 26
|
||||||
@@ -177,8 +177,8 @@ const (
|
|||||||
PD05 Pin = 101
|
PD05 Pin = 101
|
||||||
PD06 Pin = 102
|
PD06 Pin = 102
|
||||||
PD07 Pin = 103
|
PD07 Pin = 103
|
||||||
PD08 Pin = 104 // peripherals: TCC0 channel 1
|
PD08 Pin = 104 // peripherals: TCC0 channel 1, sercomI2CM6 SDA, sercomI2CM7 SDA
|
||||||
PD09 Pin = 105 // peripherals: TCC0 channel 2
|
PD09 Pin = 105 // peripherals: TCC0 channel 2, sercomI2CM6 SCL, sercomI2CM7 SCL
|
||||||
PD10 Pin = 106 // peripherals: TCC0 channel 3
|
PD10 Pin = 106 // peripherals: TCC0 channel 3
|
||||||
PD11 Pin = 107 // peripherals: TCC0 channel 4
|
PD11 Pin = 107 // peripherals: TCC0 channel 4
|
||||||
PD12 Pin = 108 // peripherals: TCC0 channel 5
|
PD12 Pin = 108 // peripherals: TCC0 channel 5
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
//go:build !baremetal && hifive1b
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
var I2C0 = &I2C{Bus: 0, PinsSDA: []Pin{P12}, PinsSCL: []Pin{P13}}
|
||||||
@@ -4,6 +4,8 @@ package machine
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"errors"
|
||||||
|
"slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Dummy machine package that calls out to external functions.
|
// Dummy machine package that calls out to external functions.
|
||||||
@@ -227,7 +229,9 @@ func adcRead(pin Pin) uint16
|
|||||||
|
|
||||||
// I2C is a generic implementation of the Inter-IC communication protocol.
|
// I2C is a generic implementation of the Inter-IC communication protocol.
|
||||||
type I2C struct {
|
type I2C struct {
|
||||||
Bus uint8
|
Bus uint8
|
||||||
|
PinsSCL []Pin
|
||||||
|
PinsSDA []Pin
|
||||||
}
|
}
|
||||||
|
|
||||||
// I2CConfig is used to store config info for I2C.
|
// I2CConfig is used to store config info for I2C.
|
||||||
@@ -239,7 +243,21 @@ type I2CConfig struct {
|
|||||||
|
|
||||||
// Configure is intended to setup the I2C interface.
|
// Configure is intended to setup the I2C interface.
|
||||||
func (i2c *I2C) Configure(config I2CConfig) error {
|
func (i2c *I2C) Configure(config I2CConfig) error {
|
||||||
i2cConfigure(i2c.Bus, config.SCL, config.SDA)
|
if i2c.PinsSCL != nil {
|
||||||
|
matchSCL := slices.Index(i2c.PinsSCL, config.SCL) >= 0
|
||||||
|
matchSDA := slices.Index(i2c.PinsSDA, config.SDA) >= 0
|
||||||
|
if !matchSCL && !matchSDA {
|
||||||
|
return errors.New("i2c: SCL and SDA pins are incorrect for this I2C instance")
|
||||||
|
} else if !matchSCL {
|
||||||
|
return errors.New("i2c: SCL pin is incorrect for this I2C instance")
|
||||||
|
} else if !matchSDA {
|
||||||
|
return errors.New("i2c: SDA pin is incorrect for this I2C instance")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if config.Frequency == 0 {
|
||||||
|
config.Frequency = 100 * KHz
|
||||||
|
}
|
||||||
|
i2cConfigure(i2c.Bus, config.SCL, config.SDA, config.Frequency)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,19 +279,29 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) error {
|
|||||||
rptr = &r[0]
|
rptr = &r[0]
|
||||||
rlen = len(r)
|
rlen = len(r)
|
||||||
}
|
}
|
||||||
i2cTransfer(i2c.Bus, wptr, wlen, rptr, rlen)
|
errCode := i2cTransfer(i2c.Bus, addr, wptr, wlen, rptr, rlen)
|
||||||
// TODO: do something with the returned error code.
|
switch errCode {
|
||||||
return nil
|
case 0:
|
||||||
|
return nil
|
||||||
|
case 1:
|
||||||
|
return errI2CNoDevices
|
||||||
|
case 2:
|
||||||
|
return errI2CMultipleDevices
|
||||||
|
case 3:
|
||||||
|
return errI2CWrongAddress
|
||||||
|
default:
|
||||||
|
return errI2CBusError // unknown error code
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//export __tinygo_i2c_configure
|
//export __tinygo_i2c_configure
|
||||||
func i2cConfigure(bus uint8, scl Pin, sda Pin)
|
func i2cConfigure(bus uint8, scl Pin, sda Pin, frequency uint32)
|
||||||
|
|
||||||
//export __tinygo_i2c_set_baud_rate
|
//export __tinygo_i2c_set_baud_rate
|
||||||
func i2cSetBaudRate(bus uint8, br uint32)
|
func i2cSetBaudRate(bus uint8, br uint32)
|
||||||
|
|
||||||
//export __tinygo_i2c_transfer
|
//export __tinygo_i2c_transfer
|
||||||
func i2cTransfer(bus uint8, w *byte, wlen int, r *byte, rlen int) int
|
func i2cTransfer(bus uint8, addr uint16, w *byte, wlen int, r *byte, rlen int) int
|
||||||
|
|
||||||
type UART struct {
|
type UART struct {
|
||||||
Bus uint8
|
Bus uint8
|
||||||
@@ -336,15 +364,6 @@ var (
|
|||||||
sercomUSART4 = UART{4}
|
sercomUSART4 = UART{4}
|
||||||
sercomUSART5 = UART{5}
|
sercomUSART5 = UART{5}
|
||||||
|
|
||||||
sercomI2CM0 = &I2C{0}
|
|
||||||
sercomI2CM1 = &I2C{1}
|
|
||||||
sercomI2CM2 = &I2C{2}
|
|
||||||
sercomI2CM3 = &I2C{3}
|
|
||||||
sercomI2CM4 = &I2C{4}
|
|
||||||
sercomI2CM5 = &I2C{5}
|
|
||||||
sercomI2CM6 = &I2C{6}
|
|
||||||
sercomI2CM7 = &I2C{7}
|
|
||||||
|
|
||||||
sercomSPIM0 = &SPI{0}
|
sercomSPIM0 = &SPI{0}
|
||||||
sercomSPIM1 = &SPI{1}
|
sercomSPIM1 = &SPI{1}
|
||||||
sercomSPIM2 = &SPI{2}
|
sercomSPIM2 = &SPI{2}
|
||||||
|
|||||||
@@ -10,5 +10,4 @@ var (
|
|||||||
UART1 = hardwareUART1
|
UART1 = hardwareUART1
|
||||||
SPI0 = &SPI{0}
|
SPI0 = &SPI{0}
|
||||||
SPI1 = &SPI{1}
|
SPI1 = &SPI{1}
|
||||||
I2C0 = &I2C{0}
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
//go:build !baremetal && (microbit || pca10031 || hw_651)
|
||||||
|
|
||||||
|
package machine
|
||||||
|
|
||||||
|
var I2C0 = &I2C{Bus: 0}
|
||||||
|
var I2C1 = &I2C{Bus: 1}
|
||||||
@@ -58,3 +58,6 @@ var PWM3 = &timerType{
|
|||||||
nil, // channel 3
|
nil, // channel 3
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var I2C0 = &I2C{Bus: 0}
|
||||||
|
var I2C1 = &I2C{Bus: 1}
|
||||||
|
|||||||
@@ -78,14 +78,14 @@ func (i2c *I2C) Tx(addr uint16, w, r []byte) (err error) {
|
|||||||
// Allow scheduler to run
|
// Allow scheduler to run
|
||||||
gosched()
|
gosched()
|
||||||
|
|
||||||
// Handle errors by ensuring STOP sent on bus
|
// Handle first occurrence of error by ensuring STOP sent on bus
|
||||||
if i2c.Bus.EVENTS_ERROR.Get() != 0 {
|
if err == nil && i2c.Bus.EVENTS_ERROR.Get() != 0 {
|
||||||
|
err = twiCError(i2c.Bus.ERRORSRC.Get())
|
||||||
if i2c.Bus.EVENTS_STOPPED.Get() == 0 {
|
if i2c.Bus.EVENTS_STOPPED.Get() == 0 {
|
||||||
// STOP cannot be sent during SUSPEND
|
// STOP cannot be sent during SUSPEND
|
||||||
i2c.Bus.TASKS_RESUME.Set(1)
|
i2c.Bus.TASKS_RESUME.Set(1)
|
||||||
i2c.Bus.TASKS_STOP.Set(1)
|
i2c.Bus.TASKS_STOP.Set(1)
|
||||||
}
|
}
|
||||||
err = twiCError(i2c.Bus.ERRORSRC.Get())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ func machineInit() {
|
|||||||
|
|
||||||
// Peripheral clocks should now all be running
|
// Peripheral clocks should now all be running
|
||||||
unresetBlockWait(RESETS_RESET_Msk)
|
unresetBlockWait(RESETS_RESET_Msk)
|
||||||
|
|
||||||
|
// DBGPAUSE pauses the timer when a debugger is connected. This prevents
|
||||||
|
// sleep functions from ever returning, so disable it.
|
||||||
|
timer.setDbgPause(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:linkname ticks runtime.machineTicks
|
//go:linkname ticks runtime.machineTicks
|
||||||
|
|||||||
@@ -94,3 +94,15 @@ var PWM7 = &timerType{
|
|||||||
{GPIO15}, // channel B (1)
|
{GPIO15}, // channel B (1)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var I2C0 = &I2C{
|
||||||
|
Bus: 0,
|
||||||
|
PinsSCL: []Pin{GPIO1, GPIO5, GPIO9, GPIO13, GPIO17, GPIO21},
|
||||||
|
PinsSDA: []Pin{GPIO0, GPIO4, GPIO8, GPIO12, GPIO16, GPIO20},
|
||||||
|
}
|
||||||
|
|
||||||
|
var I2C1 = &I2C{
|
||||||
|
Bus: 0,
|
||||||
|
PinsSCL: []Pin{GPIO3, GPIO7, GPIO11, GPIO15, GPIO19, GPIO27},
|
||||||
|
PinsSDA: []Pin{GPIO2, GPIO6, GPIO10, GPIO14, GPIO18, GPIO26},
|
||||||
|
}
|
||||||
|
|||||||
@@ -150,6 +150,8 @@ func (p Pin) Configure(config PinConfig) {
|
|||||||
case PinAnalog:
|
case PinAnalog:
|
||||||
p.setFunc(fnNULL)
|
p.setFunc(fnNULL)
|
||||||
p.pulloff()
|
p.pulloff()
|
||||||
|
// Disable digital input.
|
||||||
|
p.padCtrl().ClearBits(rp.PADS_BANK0_GPIO0_IE)
|
||||||
case PinUART:
|
case PinUART:
|
||||||
p.setFunc(fnUART)
|
p.setFunc(fnUART)
|
||||||
case PinPWM:
|
case PinPWM:
|
||||||
|
|||||||
@@ -5,24 +5,24 @@ package machine
|
|||||||
// RP2350B has additional pins.
|
// RP2350B has additional pins.
|
||||||
|
|
||||||
const (
|
const (
|
||||||
GPIO30 Pin = 30 // peripherals: PWM7 channel A
|
GPIO30 Pin = 30 // peripherals: PWM7 channel A, I2C1 SDA
|
||||||
GPIO31 Pin = 31 // peripherals: PWM7 channel B
|
GPIO31 Pin = 31 // peripherals: PWM7 channel B, I2C1 SCL
|
||||||
GPIO32 Pin = 32 // peripherals: PWM8 channel A
|
GPIO32 Pin = 32 // peripherals: PWM8 channel A, I2C0 SDA
|
||||||
GPIO33 Pin = 33 // peripherals: PWM8 channel B
|
GPIO33 Pin = 33 // peripherals: PWM8 channel B, I2C0 SCL
|
||||||
GPIO34 Pin = 34 // peripherals: PWM9 channel A
|
GPIO34 Pin = 34 // peripherals: PWM9 channel A, I2C1 SDA
|
||||||
GPIO35 Pin = 35 // peripherals: PWM9 channel B
|
GPIO35 Pin = 35 // peripherals: PWM9 channel B, I2C1 SCL
|
||||||
GPIO36 Pin = 36 // peripherals: PWM10 channel A
|
GPIO36 Pin = 36 // peripherals: PWM10 channel A, I2C0 SDA
|
||||||
GPIO37 Pin = 37 // peripherals: PWM10 channel B
|
GPIO37 Pin = 37 // peripherals: PWM10 channel B, I2C0 SCL
|
||||||
GPIO38 Pin = 38 // peripherals: PWM11 channel A
|
GPIO38 Pin = 38 // peripherals: PWM11 channel A, I2C1 SDA
|
||||||
GPIO39 Pin = 39 // peripherals: PWM11 channel B
|
GPIO39 Pin = 39 // peripherals: PWM11 channel B, I2C1 SCL
|
||||||
GPIO40 Pin = 40 // peripherals: PWM8 channel A
|
GPIO40 Pin = 40 // peripherals: PWM8 channel A, I2C0 SDA
|
||||||
GPIO41 Pin = 41 // peripherals: PWM8 channel B
|
GPIO41 Pin = 41 // peripherals: PWM8 channel B, I2C0 SCL
|
||||||
GPIO42 Pin = 42 // peripherals: PWM9 channel A
|
GPIO42 Pin = 42 // peripherals: PWM9 channel A, I2C1 SDA
|
||||||
GPIO43 Pin = 43 // peripherals: PWM9 channel B
|
GPIO43 Pin = 43 // peripherals: PWM9 channel B, I2C1 SCL
|
||||||
GPIO44 Pin = 44 // peripherals: PWM10 channel A
|
GPIO44 Pin = 44 // peripherals: PWM10 channel A, I2C0 SDA
|
||||||
GPIO45 Pin = 45 // peripherals: PWM10 channel B
|
GPIO45 Pin = 45 // peripherals: PWM10 channel B, I2C0 SCL
|
||||||
GPIO46 Pin = 46 // peripherals: PWM11 channel A
|
GPIO46 Pin = 46 // peripherals: PWM11 channel A, I2C1 SDA
|
||||||
GPIO47 Pin = 47 // peripherals: PWM11 channel B
|
GPIO47 Pin = 47 // peripherals: PWM11 channel B, I2C1 SCL
|
||||||
)
|
)
|
||||||
|
|
||||||
// Analog pins on 2350b.
|
// Analog pins on 2350b.
|
||||||
|
|||||||
@@ -73,14 +73,15 @@ func (c ADCChannel) Configure(config ADCConfig) error {
|
|||||||
func (c ADCChannel) getOnce() uint16 {
|
func (c ADCChannel) getOnce() uint16 {
|
||||||
// Make it safe to sample multiple ADC channels in separate go routines.
|
// Make it safe to sample multiple ADC channels in separate go routines.
|
||||||
adcLock.Lock()
|
adcLock.Lock()
|
||||||
rp.ADC.CS.ReplaceBits(uint32(c), 0b111, rp.ADC_CS_AINSEL_Pos)
|
rp.ADC.CS.ReplaceBits(uint32(c)<<rp.ADC_CS_AINSEL_Pos, rp.ADC_CS_AINSEL_Msk, 0)
|
||||||
rp.ADC.CS.SetBits(rp.ADC_CS_START_ONCE)
|
rp.ADC.CS.SetBits(rp.ADC_CS_START_ONCE)
|
||||||
|
|
||||||
waitForReady()
|
waitForReady()
|
||||||
|
v := rp.ADC.RESULT.Get()
|
||||||
adcLock.Unlock()
|
adcLock.Unlock()
|
||||||
|
|
||||||
// rp2040 is a 12-bit ADC, scale raw reading to 16-bits.
|
// rp2040 is a 12-bit ADC, scale raw reading to 16-bits.
|
||||||
return uint16(rp.ADC.RESULT.Get()) << 4
|
return uint16(v) << 4
|
||||||
}
|
}
|
||||||
|
|
||||||
// getVoltage does a one-shot sample and returns a millivolts reading.
|
// getVoltage does a one-shot sample and returns a millivolts reading.
|
||||||
@@ -99,7 +100,8 @@ func ReadTemperature() (millicelsius int32) {
|
|||||||
rp.ADC.CS.SetBits(rp.ADC_CS_TS_EN)
|
rp.ADC.CS.SetBits(rp.ADC_CS_TS_EN)
|
||||||
|
|
||||||
// T = 27 - (ADC_voltage - 0.706)/0.001721
|
// T = 27 - (ADC_voltage - 0.706)/0.001721
|
||||||
return (27000<<16 - (int32(thermChan.getVoltage())-706<<16)*581) >> 16
|
// 1/0.001721 ≈ 581
|
||||||
|
return int32(((int64(27000) << 16) - ((int64(thermChan.getVoltage()) - (int64(706) << 16)) * 581)) >> 16)
|
||||||
}
|
}
|
||||||
|
|
||||||
// waitForReady spins waiting for the ADC peripheral to become ready.
|
// waitForReady spins waiting for the ADC peripheral to become ready.
|
||||||
|
|||||||
@@ -4,34 +4,34 @@ package machine
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
// GPIO pins
|
// GPIO pins
|
||||||
GPIO0 Pin = 0 // peripherals: PWM0 channel A
|
GPIO0 Pin = 0 // peripherals: PWM0 channel A, I2C0 SDA
|
||||||
GPIO1 Pin = 1 // peripherals: PWM0 channel B
|
GPIO1 Pin = 1 // peripherals: PWM0 channel B, I2C0 SCL
|
||||||
GPIO2 Pin = 2 // peripherals: PWM1 channel A
|
GPIO2 Pin = 2 // peripherals: PWM1 channel A, I2C1 SDA
|
||||||
GPIO3 Pin = 3 // peripherals: PWM1 channel B
|
GPIO3 Pin = 3 // peripherals: PWM1 channel B, I2C1 SCL
|
||||||
GPIO4 Pin = 4 // peripherals: PWM2 channel A
|
GPIO4 Pin = 4 // peripherals: PWM2 channel A, I2C0 SDA
|
||||||
GPIO5 Pin = 5 // peripherals: PWM2 channel B
|
GPIO5 Pin = 5 // peripherals: PWM2 channel B, I2C0 SCL
|
||||||
GPIO6 Pin = 6 // peripherals: PWM3 channel A
|
GPIO6 Pin = 6 // peripherals: PWM3 channel A, I2C1 SDA
|
||||||
GPIO7 Pin = 7 // peripherals: PWM3 channel B
|
GPIO7 Pin = 7 // peripherals: PWM3 channel B, I2C1 SCL
|
||||||
GPIO8 Pin = 8 // peripherals: PWM4 channel A
|
GPIO8 Pin = 8 // peripherals: PWM4 channel A, I2C0 SDA
|
||||||
GPIO9 Pin = 9 // peripherals: PWM4 channel B
|
GPIO9 Pin = 9 // peripherals: PWM4 channel B, I2C0 SCL
|
||||||
GPIO10 Pin = 10 // peripherals: PWM5 channel A
|
GPIO10 Pin = 10 // peripherals: PWM5 channel A, I2C1 SDA
|
||||||
GPIO11 Pin = 11 // peripherals: PWM5 channel B
|
GPIO11 Pin = 11 // peripherals: PWM5 channel B, I2C1 SCL
|
||||||
GPIO12 Pin = 12 // peripherals: PWM6 channel A
|
GPIO12 Pin = 12 // peripherals: PWM6 channel A, I2C0 SDA
|
||||||
GPIO13 Pin = 13 // peripherals: PWM6 channel B
|
GPIO13 Pin = 13 // peripherals: PWM6 channel B, I2C0 SCL
|
||||||
GPIO14 Pin = 14 // peripherals: PWM7 channel A
|
GPIO14 Pin = 14 // peripherals: PWM7 channel A, I2C1 SDA
|
||||||
GPIO15 Pin = 15 // peripherals: PWM7 channel B
|
GPIO15 Pin = 15 // peripherals: PWM7 channel B, I2C1 SCL
|
||||||
GPIO16 Pin = 16 // peripherals: PWM0 channel A
|
GPIO16 Pin = 16 // peripherals: PWM0 channel A, I2C0 SDA
|
||||||
GPIO17 Pin = 17 // peripherals: PWM0 channel B
|
GPIO17 Pin = 17 // peripherals: PWM0 channel B, I2C0 SCL
|
||||||
GPIO18 Pin = 18 // peripherals: PWM1 channel A
|
GPIO18 Pin = 18 // peripherals: PWM1 channel A, I2C1 SDA
|
||||||
GPIO19 Pin = 19 // peripherals: PWM1 channel B
|
GPIO19 Pin = 19 // peripherals: PWM1 channel B, I2C1 SCL
|
||||||
GPIO20 Pin = 20 // peripherals: PWM2 channel A
|
GPIO20 Pin = 20 // peripherals: PWM2 channel A, I2C0 SDA
|
||||||
GPIO21 Pin = 21 // peripherals: PWM2 channel B
|
GPIO21 Pin = 21 // peripherals: PWM2 channel B, I2C0 SCL
|
||||||
GPIO22 Pin = 22 // peripherals: PWM3 channel A
|
GPIO22 Pin = 22 // peripherals: PWM3 channel A
|
||||||
GPIO23 Pin = 23 // peripherals: PWM3 channel B
|
GPIO23 Pin = 23 // peripherals: PWM3 channel B
|
||||||
GPIO24 Pin = 24 // peripherals: PWM4 channel A
|
GPIO24 Pin = 24 // peripherals: PWM4 channel A
|
||||||
GPIO25 Pin = 25 // peripherals: PWM4 channel B
|
GPIO25 Pin = 25 // peripherals: PWM4 channel B
|
||||||
GPIO26 Pin = 26 // peripherals: PWM5 channel A
|
GPIO26 Pin = 26 // peripherals: PWM5 channel A, I2C1 SDA
|
||||||
GPIO27 Pin = 27 // peripherals: PWM5 channel B
|
GPIO27 Pin = 27 // peripherals: PWM5 channel B, I2C1 SCL
|
||||||
GPIO28 Pin = 28 // peripherals: PWM6 channel A
|
GPIO28 Pin = 28 // peripherals: PWM6 channel A
|
||||||
GPIO29 Pin = 29 // peripherals: PWM6 channel B
|
GPIO29 Pin = 29 // peripherals: PWM6 channel B
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -101,3 +101,15 @@ func (tmr *timerType) lightSleep(us uint64) {
|
|||||||
// Disable interrupt
|
// Disable interrupt
|
||||||
intr.Disable()
|
intr.Disable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setDbgPause sets whether this timer is paused when a debugger is connected.
|
||||||
|
func (tmr *timerType) setDbgPause(enable bool) {
|
||||||
|
const bitPos = 1
|
||||||
|
const bitMask = 0b11
|
||||||
|
val := uint32(0b00)
|
||||||
|
if enable {
|
||||||
|
// Disable timer when debugger is connected to either core.
|
||||||
|
val = 0b11
|
||||||
|
}
|
||||||
|
tmr.dbgPause.ReplaceBits(val, bitMask, bitPos)
|
||||||
|
}
|
||||||
|
|||||||
@@ -104,7 +104,9 @@ func (uart *UART) SetBaudRate(br uint32) {
|
|||||||
func (uart *UART) writeByte(c byte) error {
|
func (uart *UART) writeByte(c byte) error {
|
||||||
// wait until buffer is not full
|
// wait until buffer is not full
|
||||||
for uart.Bus.UARTFR.HasBits(rp.UART0_UARTFR_TXFF) {
|
for uart.Bus.UARTFR.HasBits(rp.UART0_UARTFR_TXFF) {
|
||||||
gosched()
|
if !interrupt.In() {
|
||||||
|
gosched()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write data
|
// write data
|
||||||
@@ -114,7 +116,9 @@ func (uart *UART) writeByte(c byte) error {
|
|||||||
|
|
||||||
func (uart *UART) flush() {
|
func (uart *UART) flush() {
|
||||||
for uart.Bus.UARTFR.HasBits(rp.UART0_UARTFR_BUSY) {
|
for uart.Bus.UARTFR.HasBits(rp.UART0_UARTFR_BUSY) {
|
||||||
gosched()
|
if !interrupt.In() {
|
||||||
|
gosched()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// This symbol name is known by the compiler, see monitor.go.
|
// This symbol name is known by the compiler, see monitor.go.
|
||||||
|
//
|
||||||
|
//go:linkname rttSerialInstance _SEGGER_RTT
|
||||||
var rttSerialInstance rttSerial
|
var rttSerialInstance rttSerial
|
||||||
|
|
||||||
var Serial = &rttSerialInstance
|
var Serial = &rttSerialInstance
|
||||||
|
|||||||
@@ -209,6 +209,21 @@ const (
|
|||||||
KeyF23 Keycode = 114 | 0xF000
|
KeyF23 Keycode = 114 | 0xF000
|
||||||
KeyF24 Keycode = 115 | 0xF000
|
KeyF24 Keycode = 115 | 0xF000
|
||||||
|
|
||||||
|
// International keys for Japanese and other language keyboards
|
||||||
|
KeyInternational1 Keycode = 0x87 | 0xF000 // JIS "\" and "_"
|
||||||
|
KeyInternational2 Keycode = 0x88 | 0xF000 // JIS Katakana/Hiragana
|
||||||
|
KeyInternational3 Keycode = 0x89 | 0xF000 // JIS "¥" and "|"
|
||||||
|
KeyInternational4 Keycode = 0x8A | 0xF000 // JIS Henkan
|
||||||
|
KeyInternational5 Keycode = 0x8B | 0xF000 // JIS Muhenkan
|
||||||
|
KeyInternational6 Keycode = 0x8C | 0xF000 // JIS Numpad ","
|
||||||
|
|
||||||
|
// Language keys for input method switching
|
||||||
|
KeyLanguage1 Keycode = 0x90 | 0xF000 // Hangul/English
|
||||||
|
KeyLanguage2 Keycode = 0x91 | 0xF000 // Hanja
|
||||||
|
KeyLanguage3 Keycode = 0x92 | 0xF000 // JIS Katakana
|
||||||
|
KeyLanguage4 Keycode = 0x93 | 0xF000 // JIS Hiragana
|
||||||
|
KeyLanguage5 Keycode = 0x94 | 0xF000 // JIS Zenkaku/Hankaku
|
||||||
|
|
||||||
KeyUpArrow Keycode = KeyUp
|
KeyUpArrow Keycode = KeyUp
|
||||||
KeyDownArrow Keycode = KeyDown
|
KeyDownArrow Keycode = KeyDown
|
||||||
KeyLeftArrow Keycode = KeyLeft
|
KeyLeftArrow Keycode = KeyLeft
|
||||||
@@ -222,6 +237,34 @@ const (
|
|||||||
KeyRightShift Keycode = KeyModifierRightShift
|
KeyRightShift Keycode = KeyModifierRightShift
|
||||||
KeyRightAlt Keycode = KeyModifierRightAlt
|
KeyRightAlt Keycode = KeyModifierRightAlt
|
||||||
KeyRightGUI Keycode = KeyModifierRightGUI
|
KeyRightGUI Keycode = KeyModifierRightGUI
|
||||||
|
|
||||||
|
// QMK compatibility aliases for international keys
|
||||||
|
KeyInt1 Keycode = KeyInternational1
|
||||||
|
KeyInt2 Keycode = KeyInternational2
|
||||||
|
KeyInt3 Keycode = KeyInternational3
|
||||||
|
KeyInt4 Keycode = KeyInternational4
|
||||||
|
KeyInt5 Keycode = KeyInternational5
|
||||||
|
KeyInt6 Keycode = KeyInternational6
|
||||||
|
|
||||||
|
// QMK compatibility aliases for language keys
|
||||||
|
KeyLng1 Keycode = KeyLanguage1
|
||||||
|
KeyLng2 Keycode = KeyLanguage2
|
||||||
|
KeyLng3 Keycode = KeyLanguage3
|
||||||
|
KeyLng4 Keycode = KeyLanguage4
|
||||||
|
KeyLng5 Keycode = KeyLanguage5
|
||||||
|
|
||||||
|
// Common keyboard layout aliases
|
||||||
|
KeyRo Keycode = KeyInternational1 // Japanese "ろ"
|
||||||
|
KeyKatakanaHiragana Keycode = KeyInternational2 // Japanese Katakana/Hiragana
|
||||||
|
KeyYen Keycode = KeyInternational3 // Japanese "¥"
|
||||||
|
KeyHenkan Keycode = KeyInternational4 // Japanese Henkan
|
||||||
|
KeyMuhenkan Keycode = KeyInternational5 // Japanese Muhenkan
|
||||||
|
KeyKpJpComma Keycode = KeyInternational6 // Japanese Numpad ","
|
||||||
|
KeyHangeul Keycode = KeyLanguage1 // Korean Hangul/English
|
||||||
|
KeyHanja Keycode = KeyLanguage2 // Korean Hanja
|
||||||
|
KeyKatakana Keycode = KeyLanguage3 // Japanese Katakana
|
||||||
|
KeyHiragana Keycode = KeyLanguage4 // Japanese Hiragana
|
||||||
|
KeyZenkakuHankaku Keycode = KeyLanguage5 // Japanese Zenkaku/Hankaku
|
||||||
)
|
)
|
||||||
|
|
||||||
// Keycodes for layout US English (0x0904)
|
// Keycodes for layout US English (0x0904)
|
||||||
|
|||||||
+1
-1
Submodule src/net updated: 77be3968d1...bb43b40f19
@@ -12,7 +12,6 @@ package os
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"syscall"
|
"syscall"
|
||||||
_ "unsafe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const DevNull = "/dev/null"
|
const DevNull = "/dev/null"
|
||||||
|
|||||||
@@ -127,6 +127,11 @@ type Method struct {
|
|||||||
Index int // index for Type.Method
|
Index int // index for Type.Method
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsExported reports whether the method is exported.
|
||||||
|
func (m Method) IsExported() bool {
|
||||||
|
return m.PkgPath == ""
|
||||||
|
}
|
||||||
|
|
||||||
// The following Type type has been copied almost entirely from
|
// The following Type type has been copied almost entirely from
|
||||||
// https://github.com/golang/go/blob/go1.15/src/reflect/type.go#L27-L212.
|
// https://github.com/golang/go/blob/go1.15/src/reflect/type.go#L27-L212.
|
||||||
// Some methods have been commented out as they haven't yet been implemented.
|
// Some methods have been commented out as they haven't yet been implemented.
|
||||||
|
|||||||
@@ -81,8 +81,8 @@ func (it *MapIter) Next() bool {
|
|||||||
return ((*reflectlite.MapIter)(it)).Next()
|
return ((*reflectlite.MapIter)(it)).Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (iter *MapIter) Reset(v Value) {
|
func (it *MapIter) Reset(v Value) {
|
||||||
(*reflectlite.MapIter)(iter).Reset(v.Value)
|
(*reflectlite.MapIter)(it).Reset(v.Value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Value) Set(x Value) {
|
func (v Value) Set(x Value) {
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
|
|||||||
gcLock.Lock()
|
gcLock.Lock()
|
||||||
needsResumeWorld = false
|
needsResumeWorld = false
|
||||||
var ptr unsafe.Pointer
|
var ptr unsafe.Pointer
|
||||||
if layout == gclayout.NoPtrs {
|
if layout == gclayout.NoPtrs.AsPtr() {
|
||||||
// This object is entirely pointer free, for example make([]int, ...).
|
// This object is entirely pointer free, for example make([]int, ...).
|
||||||
// Make sure the GC knows this so it doesn't scan the object
|
// Make sure the GC knows this so it doesn't scan the object
|
||||||
// unnecessarily to improve performance.
|
// unnecessarily to improve performance.
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package runtime
|
||||||
|
|
||||||
|
import _ "unsafe"
|
||||||
|
|
||||||
|
// TODO: Use hardware when available
|
||||||
|
//
|
||||||
|
//go:linkname vgetrandom
|
||||||
|
func vgetrandom(p []byte, flags uint32) (ret int, supported bool) { return 0, false }
|
||||||
|
|
||||||
|
//go:linkname fatal crypto/internal/sysrand.fatal
|
||||||
|
func fatal(msg string) { runtimePanic(msg) }
|
||||||
@@ -106,6 +106,33 @@ func UnlockOSThread() {
|
|||||||
// point of the call.
|
// point of the call.
|
||||||
func KeepAlive(x interface{})
|
func KeepAlive(x interface{})
|
||||||
|
|
||||||
|
// AddCleanup is a dummy cleanup implementation. It doesn't do any cleaning up.
|
||||||
|
//
|
||||||
|
// We base this on the following loophole in the official runtime.AddCleanup
|
||||||
|
// documentation:
|
||||||
|
//
|
||||||
|
// > The cleanup(arg) call is not always guaranteed to run; in particular it is
|
||||||
|
// > not guaranteed to run before program exit.
|
||||||
|
//
|
||||||
|
// So it's technically correct (the best kind of correct) to not run any
|
||||||
|
// cleanups. But of course, this can lead to resource leaks so cleanups may need
|
||||||
|
// to be implemented eventually.
|
||||||
|
func AddCleanup[T, S any](ptr *T, cleanup func(S), arg S) Cleanup {
|
||||||
|
return Cleanup{}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Cleanup struct{}
|
||||||
|
|
||||||
|
func (c Cleanup) Stop() {}
|
||||||
|
|
||||||
|
//go:linkname registerWeakPointer weak.runtime_registerWeakPointer
|
||||||
|
func registerWeakPointer(ptr unsafe.Pointer) unsafe.Pointer {
|
||||||
|
// TODO: unimplemented.
|
||||||
|
// I hope not implementing this won't break anything, like packages that
|
||||||
|
// expect weak pointers to be GC'd before they actually are.
|
||||||
|
return ptr
|
||||||
|
}
|
||||||
|
|
||||||
var godebugUpdate func(string, string)
|
var godebugUpdate func(string, string)
|
||||||
|
|
||||||
//go:linkname godebug_setUpdate internal/godebug.setUpdate
|
//go:linkname godebug_setUpdate internal/godebug.setUpdate
|
||||||
|
|||||||
@@ -0,0 +1,380 @@
|
|||||||
|
//go:build rp2040 || rp2350
|
||||||
|
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"device/arm"
|
||||||
|
"device/rp"
|
||||||
|
"internal/task"
|
||||||
|
"machine"
|
||||||
|
"machine/usb/cdc"
|
||||||
|
"runtime/interrupt"
|
||||||
|
"runtime/volatile"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const numCPU = 2
|
||||||
|
const numSpinlocks = 32
|
||||||
|
|
||||||
|
// machineTicks is provided by package machine.
|
||||||
|
func machineTicks() uint64
|
||||||
|
|
||||||
|
// machineLightSleep is provided by package machine.
|
||||||
|
func machineLightSleep(uint64)
|
||||||
|
|
||||||
|
// ticks returns the number of ticks (microseconds) elapsed since power up.
|
||||||
|
func ticks() timeUnit {
|
||||||
|
t := machineTicks()
|
||||||
|
return timeUnit(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ticksToNanoseconds(ticks timeUnit) int64 {
|
||||||
|
return int64(ticks) * 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
func nanosecondsToTicks(ns int64) timeUnit {
|
||||||
|
return timeUnit(ns / 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
func sleepTicks(d timeUnit) {
|
||||||
|
if hasScheduler {
|
||||||
|
// With scheduler, sleepTicks may return early if an interrupt or
|
||||||
|
// event fires - so scheduler can schedule any go routines now
|
||||||
|
// eligible to run
|
||||||
|
machineLightSleep(uint64(d))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Busy loop
|
||||||
|
sleepUntil := ticks() + d
|
||||||
|
for ticks() < sleepUntil {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Currently sleeping core, or 0xff.
|
||||||
|
// Must only be accessed with the scheduler lock held.
|
||||||
|
var sleepingCore uint8 = 0xff
|
||||||
|
|
||||||
|
// Return whether another core is sleeping.
|
||||||
|
// May only be called with the scheduler lock held.
|
||||||
|
func hasSleepingCore() bool {
|
||||||
|
return sleepingCore != 0xff
|
||||||
|
}
|
||||||
|
|
||||||
|
// Almost identical to sleepTicks, except that it will unlock/lock the scheduler
|
||||||
|
// while sleeping and is interruptible by interruptSleepTicksMulticore.
|
||||||
|
// This may only be called with the scheduler lock held.
|
||||||
|
func sleepTicksMulticore(d timeUnit) {
|
||||||
|
sleepingCore = uint8(currentCPU())
|
||||||
|
|
||||||
|
// Note: interruptSleepTicksMulticore will be able to interrupt this, since
|
||||||
|
// it executes the "sev" instruction which would make sleepTicks return
|
||||||
|
// immediately without sleeping. Even if it happens while configuring the
|
||||||
|
// sleep operation.
|
||||||
|
|
||||||
|
schedulerLock.Unlock()
|
||||||
|
sleepTicks(d)
|
||||||
|
schedulerLock.Lock()
|
||||||
|
|
||||||
|
sleepingCore = 0xff
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interrupt an ongoing call to sleepTicksMulticore on another core.
|
||||||
|
func interruptSleepTicksMulticore(wakeup timeUnit) {
|
||||||
|
arm.Asm("sev")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number of cores that are currently in schedulerUnlockAndWait.
|
||||||
|
// It is possible for both cores to be sleeping, if the program is waiting for
|
||||||
|
// an interrupt (or is deadlocked).
|
||||||
|
var waitingCore uint8
|
||||||
|
|
||||||
|
// Put the scheduler to sleep, since there are no tasks to run.
|
||||||
|
// This will unlock the scheduler lock, and must be called with the scheduler
|
||||||
|
// lock held.
|
||||||
|
func schedulerUnlockAndWait() {
|
||||||
|
waitingCore++
|
||||||
|
schedulerLock.Unlock()
|
||||||
|
arm.Asm("wfe")
|
||||||
|
schedulerLock.Lock()
|
||||||
|
waitingCore--
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wake another core, if one is sleeping. Must be called with the scheduler lock
|
||||||
|
// held.
|
||||||
|
func schedulerWake() {
|
||||||
|
if waitingCore != 0 {
|
||||||
|
arm.Asm("sev")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the current core number: 0 or 1.
|
||||||
|
func currentCPU() uint32 {
|
||||||
|
return rp.SIO.CPUID.Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the secondary cores for this chip.
|
||||||
|
// On the RP2040/RP2350, there is only one other core to start.
|
||||||
|
func startSecondaryCores() {
|
||||||
|
// Start the second core of the RP2040/RP2350.
|
||||||
|
// See sections 2.8.2 and 5.3 in the datasheets for RP2040 and RP2350 respectively.
|
||||||
|
seq := 0
|
||||||
|
for {
|
||||||
|
cmd := core1StartSequence[seq]
|
||||||
|
if cmd == 0 {
|
||||||
|
multicore_fifo_drain()
|
||||||
|
arm.Asm("sev")
|
||||||
|
}
|
||||||
|
multicore_fifo_push_blocking(cmd)
|
||||||
|
response := multicore_fifo_pop_blocking()
|
||||||
|
if cmd != response {
|
||||||
|
seq = 0
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
seq = seq + 1
|
||||||
|
if seq >= len(core1StartSequence) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable the FIFO interrupt for the GC stop the world phase.
|
||||||
|
// We can only do this after we don't need the FIFO anymore for starting the
|
||||||
|
// second core.
|
||||||
|
intr := interrupt.New(sioIrqFifoProc0, func(intr interrupt.Interrupt) {
|
||||||
|
switch rp.SIO.FIFO_RD.Get() {
|
||||||
|
case 1:
|
||||||
|
gcInterruptHandler(0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
intr.Enable()
|
||||||
|
intr.SetPriority(0xff)
|
||||||
|
}
|
||||||
|
|
||||||
|
var core1StartSequence = [...]uint32{
|
||||||
|
0, 0, 1,
|
||||||
|
uint32(uintptr(unsafe.Pointer(&__isr_vector))),
|
||||||
|
uint32(uintptr(unsafe.Pointer(&stack1TopSymbol))),
|
||||||
|
uint32(exportedFuncPtr(runCore1)),
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:extern __isr_vector
|
||||||
|
var __isr_vector [0]uint32
|
||||||
|
|
||||||
|
//go:extern _stack1_top
|
||||||
|
var stack1TopSymbol [0]uint32
|
||||||
|
|
||||||
|
// The function that is started on the second core.
|
||||||
|
//
|
||||||
|
//export tinygo_runCore1
|
||||||
|
func runCore1() {
|
||||||
|
// Clear sticky bit that seems to have been set while starting this core.
|
||||||
|
rp.SIO.FIFO_ST.Set(rp.SIO_FIFO_ST_ROE)
|
||||||
|
|
||||||
|
// Enable the FIFO interrupt, mainly used for the stop-the-world phase of
|
||||||
|
// the GC.
|
||||||
|
// Use the lowest possible priority (highest priority value), so that other
|
||||||
|
// interrupts can still happen while the GC is running.
|
||||||
|
intr := interrupt.New(sioIrqFifoProc1, func(intr interrupt.Interrupt) {
|
||||||
|
switch rp.SIO.FIFO_RD.Get() {
|
||||||
|
case 1:
|
||||||
|
gcInterruptHandler(1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
intr.Enable()
|
||||||
|
intr.SetPriority(0xff)
|
||||||
|
|
||||||
|
// Now start running the scheduler on this core.
|
||||||
|
schedulerLock.Lock()
|
||||||
|
scheduler(false)
|
||||||
|
schedulerLock.Unlock()
|
||||||
|
|
||||||
|
// The main function returned.
|
||||||
|
exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The below multicore_fifo_* functions have been translated from the Raspberry
|
||||||
|
// Pi Pico SDK.
|
||||||
|
|
||||||
|
func multicore_fifo_rvalid() bool {
|
||||||
|
return rp.SIO.FIFO_ST.Get()&rp.SIO_FIFO_ST_VLD != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func multicore_fifo_wready() bool {
|
||||||
|
return rp.SIO.FIFO_ST.Get()&rp.SIO_FIFO_ST_RDY != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func multicore_fifo_drain() {
|
||||||
|
for multicore_fifo_rvalid() {
|
||||||
|
rp.SIO.FIFO_RD.Get()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func multicore_fifo_push_blocking(data uint32) {
|
||||||
|
for !multicore_fifo_wready() {
|
||||||
|
}
|
||||||
|
rp.SIO.FIFO_WR.Set(data)
|
||||||
|
arm.Asm("sev")
|
||||||
|
}
|
||||||
|
|
||||||
|
func multicore_fifo_pop_blocking() uint32 {
|
||||||
|
for !multicore_fifo_rvalid() {
|
||||||
|
arm.Asm("wfe")
|
||||||
|
}
|
||||||
|
|
||||||
|
return rp.SIO.FIFO_RD.Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value used to communicate between the GC core and the other (paused) cores.
|
||||||
|
var gcSignalWait volatile.Register8
|
||||||
|
|
||||||
|
// The GC interrupted this core for the stop-the-world phase.
|
||||||
|
// This function handles that, and only returns after the stop-the-world phase
|
||||||
|
// ended.
|
||||||
|
func gcInterruptHandler(hartID uint32) {
|
||||||
|
// Let the GC know we're ready.
|
||||||
|
gcScanState.Add(1)
|
||||||
|
arm.Asm("sev")
|
||||||
|
|
||||||
|
// Wait until we get a signal to start scanning.
|
||||||
|
for gcSignalWait.Get() == 0 {
|
||||||
|
arm.Asm("wfe")
|
||||||
|
}
|
||||||
|
gcSignalWait.Set(0)
|
||||||
|
|
||||||
|
// Scan the stack(s) of this core.
|
||||||
|
scanCurrentStack()
|
||||||
|
if !task.OnSystemStack() {
|
||||||
|
// Mark system stack.
|
||||||
|
markRoots(task.SystemStack(), coreStackTop(hartID))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal we've finished scanning.
|
||||||
|
gcScanState.Store(1)
|
||||||
|
arm.Asm("sev")
|
||||||
|
|
||||||
|
// Wait until we get a signal that the stop-the-world phase has ended.
|
||||||
|
for gcSignalWait.Get() == 0 {
|
||||||
|
arm.Asm("wfe")
|
||||||
|
}
|
||||||
|
gcSignalWait.Set(0)
|
||||||
|
|
||||||
|
// Signal we received the signal and are going to exit the interrupt.
|
||||||
|
gcScanState.Add(1)
|
||||||
|
arm.Asm("sev")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pause the given core by sending it an interrupt.
|
||||||
|
func gcPauseCore(core uint32) {
|
||||||
|
rp.SIO.FIFO_WR.Set(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal the given core that it can resume one step.
|
||||||
|
// This is called twice after gcPauseCore: the first time to scan the stack of
|
||||||
|
// the core, and the second time to end the stop-the-world phase.
|
||||||
|
func gcSignalCore(core uint32) {
|
||||||
|
gcSignalWait.Set(1)
|
||||||
|
arm.Asm("sev")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the stack top (highest address) of the system stack of the given
|
||||||
|
// core.
|
||||||
|
func coreStackTop(core uint32) uintptr {
|
||||||
|
switch core {
|
||||||
|
case 0:
|
||||||
|
return uintptr(unsafe.Pointer(&stackTopSymbol))
|
||||||
|
case 1:
|
||||||
|
return uintptr(unsafe.Pointer(&stack1TopSymbol))
|
||||||
|
default:
|
||||||
|
runtimePanic("unexpected core")
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// These spinlocks are needed by the runtime.
|
||||||
|
var (
|
||||||
|
printLock = spinLock{id: 20}
|
||||||
|
schedulerLock = spinLock{id: 21}
|
||||||
|
atomicsLock = spinLock{id: 22}
|
||||||
|
futexLock = spinLock{id: 23}
|
||||||
|
)
|
||||||
|
|
||||||
|
func resetSpinLocks() {
|
||||||
|
for i := uint8(0); i < numSpinlocks; i++ {
|
||||||
|
l := &spinLock{id: i}
|
||||||
|
l.spinlock().Set(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A hardware spinlock, one of the 32 spinlocks defined in the SIO peripheral.
|
||||||
|
type spinLock struct {
|
||||||
|
id uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the spinlock register: rp.SIO.SPINLOCKx
|
||||||
|
func (l *spinLock) spinlock() *volatile.Register32 {
|
||||||
|
return (*volatile.Register32)(unsafe.Add(unsafe.Pointer(&rp.SIO.SPINLOCK0), l.id*4))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *spinLock) Lock() {
|
||||||
|
// Wait for the lock to be available.
|
||||||
|
spinlock := l.spinlock()
|
||||||
|
for spinlock.Get() == 0 {
|
||||||
|
arm.Asm("wfe")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *spinLock) Unlock() {
|
||||||
|
l.spinlock().Set(0)
|
||||||
|
arm.Asm("sev")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait until a signal is received, indicating that it can resume from the
|
||||||
|
// spinloop.
|
||||||
|
func spinLoopWait() {
|
||||||
|
arm.Asm("wfe")
|
||||||
|
}
|
||||||
|
|
||||||
|
func waitForEvents() {
|
||||||
|
arm.Asm("wfe")
|
||||||
|
}
|
||||||
|
|
||||||
|
func putchar(c byte) {
|
||||||
|
machine.Serial.WriteByte(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getchar() byte {
|
||||||
|
for machine.Serial.Buffered() == 0 {
|
||||||
|
Gosched()
|
||||||
|
}
|
||||||
|
v, _ := machine.Serial.ReadByte()
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func buffered() int {
|
||||||
|
return machine.Serial.Buffered()
|
||||||
|
}
|
||||||
|
|
||||||
|
// machineInit is provided by package machine.
|
||||||
|
func machineInit()
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
machineInit()
|
||||||
|
|
||||||
|
cdc.EnableUSBCDC()
|
||||||
|
machine.USBDev.Configure(machine.UARTConfig{})
|
||||||
|
machine.InitSerial()
|
||||||
|
}
|
||||||
|
|
||||||
|
func prerun() {
|
||||||
|
// Reset spinlocks before the full machineInit() so the scheduler doesn't
|
||||||
|
// hang waiting for schedulerLock after a soft reset.
|
||||||
|
resetSpinLocks()
|
||||||
|
}
|
||||||
|
|
||||||
|
//export Reset_Handler
|
||||||
|
func main() {
|
||||||
|
preinit()
|
||||||
|
prerun()
|
||||||
|
run()
|
||||||
|
exit(0)
|
||||||
|
}
|
||||||
@@ -3,365 +3,10 @@
|
|||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"device/arm"
|
|
||||||
"device/rp"
|
"device/rp"
|
||||||
"internal/task"
|
|
||||||
"machine"
|
|
||||||
"machine/usb/cdc"
|
|
||||||
"runtime/interrupt"
|
|
||||||
"runtime/volatile"
|
|
||||||
"unsafe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const numCPU = 2
|
const (
|
||||||
|
sioIrqFifoProc0 = rp.IRQ_SIO_IRQ_PROC0
|
||||||
// machineTicks is provided by package machine.
|
sioIrqFifoProc1 = rp.IRQ_SIO_IRQ_PROC1
|
||||||
func machineTicks() uint64
|
|
||||||
|
|
||||||
// machineLightSleep is provided by package machine.
|
|
||||||
func machineLightSleep(uint64)
|
|
||||||
|
|
||||||
// ticks returns the number of ticks (microseconds) elapsed since power up.
|
|
||||||
func ticks() timeUnit {
|
|
||||||
t := machineTicks()
|
|
||||||
return timeUnit(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ticksToNanoseconds(ticks timeUnit) int64 {
|
|
||||||
return int64(ticks) * 1000
|
|
||||||
}
|
|
||||||
|
|
||||||
func nanosecondsToTicks(ns int64) timeUnit {
|
|
||||||
return timeUnit(ns / 1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
func sleepTicks(d timeUnit) {
|
|
||||||
if hasScheduler {
|
|
||||||
// With scheduler, sleepTicks may return early if an interrupt or
|
|
||||||
// event fires - so scheduler can schedule any go routines now
|
|
||||||
// eligible to run
|
|
||||||
machineLightSleep(uint64(d))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Busy loop
|
|
||||||
sleepUntil := ticks() + d
|
|
||||||
for ticks() < sleepUntil {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Currently sleeping core, or 0xff.
|
|
||||||
// Must only be accessed with the scheduler lock held.
|
|
||||||
var sleepingCore uint8 = 0xff
|
|
||||||
|
|
||||||
// Return whether another core is sleeping.
|
|
||||||
// May only be called with the scheduler lock held.
|
|
||||||
func hasSleepingCore() bool {
|
|
||||||
return sleepingCore != 0xff
|
|
||||||
}
|
|
||||||
|
|
||||||
// Almost identical to sleepTicks, except that it will unlock/lock the scheduler
|
|
||||||
// while sleeping and is interruptible by interruptSleepTicksMulticore.
|
|
||||||
// This may only be called with the scheduler lock held.
|
|
||||||
func sleepTicksMulticore(d timeUnit) {
|
|
||||||
sleepingCore = uint8(currentCPU())
|
|
||||||
|
|
||||||
// Note: interruptSleepTicksMulticore will be able to interrupt this, since
|
|
||||||
// it executes the "sev" instruction which would make sleepTicks return
|
|
||||||
// immediately without sleeping. Even if it happens while configuring the
|
|
||||||
// sleep operation.
|
|
||||||
|
|
||||||
schedulerLock.Unlock()
|
|
||||||
sleepTicks(d)
|
|
||||||
schedulerLock.Lock()
|
|
||||||
|
|
||||||
sleepingCore = 0xff
|
|
||||||
}
|
|
||||||
|
|
||||||
// Interrupt an ongoing call to sleepTicksMulticore on another core.
|
|
||||||
func interruptSleepTicksMulticore(wakeup timeUnit) {
|
|
||||||
arm.Asm("sev")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Number of cores that are currently in schedulerUnlockAndWait.
|
|
||||||
// It is possible for both cores to be sleeping, if the program is waiting for
|
|
||||||
// an interrupt (or is deadlocked).
|
|
||||||
var waitingCore uint8
|
|
||||||
|
|
||||||
// Put the scheduler to sleep, since there are no tasks to run.
|
|
||||||
// This will unlock the scheduler lock, and must be called with the scheduler
|
|
||||||
// lock held.
|
|
||||||
func schedulerUnlockAndWait() {
|
|
||||||
waitingCore++
|
|
||||||
schedulerLock.Unlock()
|
|
||||||
arm.Asm("wfe")
|
|
||||||
schedulerLock.Lock()
|
|
||||||
waitingCore--
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wake another core, if one is sleeping. Must be called with the scheduler lock
|
|
||||||
// held.
|
|
||||||
func schedulerWake() {
|
|
||||||
if waitingCore != 0 {
|
|
||||||
arm.Asm("sev")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the current core number: 0 or 1.
|
|
||||||
func currentCPU() uint32 {
|
|
||||||
return rp.SIO.CPUID.Get()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start the secondary cores for this chip.
|
|
||||||
// On the RP2040, there is only one other core to start.
|
|
||||||
func startSecondaryCores() {
|
|
||||||
// Start the second core of the RP2040.
|
|
||||||
// See section 2.8.2 in the datasheet.
|
|
||||||
seq := 0
|
|
||||||
for {
|
|
||||||
cmd := core1StartSequence[seq]
|
|
||||||
if cmd == 0 {
|
|
||||||
multicore_fifo_drain()
|
|
||||||
arm.Asm("sev")
|
|
||||||
}
|
|
||||||
multicore_fifo_push_blocking(cmd)
|
|
||||||
response := multicore_fifo_pop_blocking()
|
|
||||||
if cmd != response {
|
|
||||||
seq = 0
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
seq = seq + 1
|
|
||||||
if seq >= len(core1StartSequence) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable the FIFO interrupt for the GC stop the world phase.
|
|
||||||
// We can only do this after we don't need the FIFO anymore for starting the
|
|
||||||
// second core.
|
|
||||||
intr := interrupt.New(rp.IRQ_SIO_IRQ_PROC0, func(intr interrupt.Interrupt) {
|
|
||||||
switch rp.SIO.FIFO_RD.Get() {
|
|
||||||
case 1:
|
|
||||||
gcInterruptHandler(0)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
intr.Enable()
|
|
||||||
intr.SetPriority(0xff)
|
|
||||||
}
|
|
||||||
|
|
||||||
var core1StartSequence = [...]uint32{
|
|
||||||
0, 0, 1,
|
|
||||||
uint32(uintptr(unsafe.Pointer(&__isr_vector))),
|
|
||||||
uint32(uintptr(unsafe.Pointer(&stack1TopSymbol))),
|
|
||||||
uint32(exportedFuncPtr(runCore1)),
|
|
||||||
}
|
|
||||||
|
|
||||||
//go:extern __isr_vector
|
|
||||||
var __isr_vector [0]uint32
|
|
||||||
|
|
||||||
//go:extern _stack1_top
|
|
||||||
var stack1TopSymbol [0]uint32
|
|
||||||
|
|
||||||
// The function that is started on the second core.
|
|
||||||
//
|
|
||||||
//export tinygo_runCore1
|
|
||||||
func runCore1() {
|
|
||||||
// Clear sticky bit that seems to have been set while starting this core.
|
|
||||||
rp.SIO.FIFO_ST.Set(rp.SIO_FIFO_ST_ROE)
|
|
||||||
|
|
||||||
// Enable the FIFO interrupt, mainly used for the stop-the-world phase of
|
|
||||||
// the GC.
|
|
||||||
// Use the lowest possible priority (highest priority value), so that other
|
|
||||||
// interrupts can still happen while the GC is running.
|
|
||||||
intr := interrupt.New(rp.IRQ_SIO_IRQ_PROC1, func(intr interrupt.Interrupt) {
|
|
||||||
switch rp.SIO.FIFO_RD.Get() {
|
|
||||||
case 1:
|
|
||||||
gcInterruptHandler(1)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
intr.Enable()
|
|
||||||
intr.SetPriority(0xff)
|
|
||||||
|
|
||||||
// Now start running the scheduler on this core.
|
|
||||||
schedulerLock.Lock()
|
|
||||||
scheduler(false)
|
|
||||||
schedulerLock.Unlock()
|
|
||||||
|
|
||||||
// The main function returned.
|
|
||||||
exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The below multicore_fifo_* functions have been translated from the Raspberry
|
|
||||||
// Pi Pico SDK.
|
|
||||||
|
|
||||||
func multicore_fifo_rvalid() bool {
|
|
||||||
return rp.SIO.FIFO_ST.Get()&rp.SIO_FIFO_ST_VLD != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func multicore_fifo_wready() bool {
|
|
||||||
return rp.SIO.FIFO_ST.Get()&rp.SIO_FIFO_ST_RDY != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func multicore_fifo_drain() {
|
|
||||||
for multicore_fifo_rvalid() {
|
|
||||||
rp.SIO.FIFO_RD.Get()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func multicore_fifo_push_blocking(data uint32) {
|
|
||||||
for !multicore_fifo_wready() {
|
|
||||||
}
|
|
||||||
rp.SIO.FIFO_WR.Set(data)
|
|
||||||
arm.Asm("sev")
|
|
||||||
}
|
|
||||||
|
|
||||||
func multicore_fifo_pop_blocking() uint32 {
|
|
||||||
for !multicore_fifo_rvalid() {
|
|
||||||
arm.Asm("wfe")
|
|
||||||
}
|
|
||||||
|
|
||||||
return rp.SIO.FIFO_RD.Get()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Value used to communicate between the GC core and the other (paused) cores.
|
|
||||||
var gcSignalWait volatile.Register8
|
|
||||||
|
|
||||||
// The GC interrupted this core for the stop-the-world phase.
|
|
||||||
// This function handles that, and only returns after the stop-the-world phase
|
|
||||||
// ended.
|
|
||||||
func gcInterruptHandler(hartID uint32) {
|
|
||||||
// Let the GC know we're ready.
|
|
||||||
gcScanState.Add(1)
|
|
||||||
arm.Asm("sev")
|
|
||||||
|
|
||||||
// Wait until we get a signal to start scanning.
|
|
||||||
for gcSignalWait.Get() == 0 {
|
|
||||||
arm.Asm("wfe")
|
|
||||||
}
|
|
||||||
gcSignalWait.Set(0)
|
|
||||||
|
|
||||||
// Scan the stack(s) of this core.
|
|
||||||
scanCurrentStack()
|
|
||||||
if !task.OnSystemStack() {
|
|
||||||
// Mark system stack.
|
|
||||||
markRoots(task.SystemStack(), coreStackTop(hartID))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signal we've finished scanning.
|
|
||||||
gcScanState.Store(1)
|
|
||||||
arm.Asm("sev")
|
|
||||||
|
|
||||||
// Wait until we get a signal that the stop-the-world phase has ended.
|
|
||||||
for gcSignalWait.Get() == 0 {
|
|
||||||
arm.Asm("wfe")
|
|
||||||
}
|
|
||||||
gcSignalWait.Set(0)
|
|
||||||
|
|
||||||
// Signal we received the signal and are going to exit the interrupt.
|
|
||||||
gcScanState.Add(1)
|
|
||||||
arm.Asm("sev")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pause the given core by sending it an interrupt.
|
|
||||||
func gcPauseCore(core uint32) {
|
|
||||||
rp.SIO.FIFO_WR.Set(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signal the given core that it can resume one step.
|
|
||||||
// This is called twice after gcPauseCore: the first time to scan the stack of
|
|
||||||
// the core, and the second time to end the stop-the-world phase.
|
|
||||||
func gcSignalCore(core uint32) {
|
|
||||||
gcSignalWait.Set(1)
|
|
||||||
arm.Asm("sev")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the stack top (highest address) of the system stack of the given
|
|
||||||
// core.
|
|
||||||
func coreStackTop(core uint32) uintptr {
|
|
||||||
switch core {
|
|
||||||
case 0:
|
|
||||||
return uintptr(unsafe.Pointer(&stackTopSymbol))
|
|
||||||
case 1:
|
|
||||||
return uintptr(unsafe.Pointer(&stack1TopSymbol))
|
|
||||||
default:
|
|
||||||
runtimePanic("unexpected core")
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// These spinlocks are needed by the runtime.
|
|
||||||
var (
|
|
||||||
printLock = spinLock{id: 0}
|
|
||||||
schedulerLock = spinLock{id: 1}
|
|
||||||
atomicsLock = spinLock{id: 2}
|
|
||||||
futexLock = spinLock{id: 3}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// A hardware spinlock, one of the 32 spinlocks defined in the SIO peripheral.
|
|
||||||
type spinLock struct {
|
|
||||||
id uint8
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the spinlock register: rp.SIO.SPINLOCKx
|
|
||||||
func (l *spinLock) spinlock() *volatile.Register32 {
|
|
||||||
return (*volatile.Register32)(unsafe.Add(unsafe.Pointer(&rp.SIO.SPINLOCK0), l.id*4))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *spinLock) Lock() {
|
|
||||||
// Wait for the lock to be available.
|
|
||||||
spinlock := l.spinlock()
|
|
||||||
for spinlock.Get() == 0 {
|
|
||||||
// TODO: use wfe and send an event when unlocking so the CPU can go to
|
|
||||||
// sleep while waiting for the lock.
|
|
||||||
// Unfortunately when doing that, time.Sleep() seems to hang somewhere.
|
|
||||||
// This needs some debugging to figure out.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *spinLock) Unlock() {
|
|
||||||
l.spinlock().Set(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait until a signal is received, indicating that it can resume from the
|
|
||||||
// spinloop.
|
|
||||||
func spinLoopWait() {
|
|
||||||
arm.Asm("wfe")
|
|
||||||
}
|
|
||||||
|
|
||||||
func waitForEvents() {
|
|
||||||
arm.Asm("wfe")
|
|
||||||
}
|
|
||||||
|
|
||||||
func putchar(c byte) {
|
|
||||||
machine.Serial.WriteByte(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getchar() byte {
|
|
||||||
for machine.Serial.Buffered() == 0 {
|
|
||||||
Gosched()
|
|
||||||
}
|
|
||||||
v, _ := machine.Serial.ReadByte()
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func buffered() int {
|
|
||||||
return machine.Serial.Buffered()
|
|
||||||
}
|
|
||||||
|
|
||||||
// machineInit is provided by package machine.
|
|
||||||
func machineInit()
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
machineInit()
|
|
||||||
|
|
||||||
cdc.EnableUSBCDC()
|
|
||||||
machine.USBDev.Configure(machine.UARTConfig{})
|
|
||||||
machine.InitSerial()
|
|
||||||
}
|
|
||||||
|
|
||||||
//export Reset_Handler
|
|
||||||
func main() {
|
|
||||||
preinit()
|
|
||||||
run()
|
|
||||||
exit(0)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,84 +3,14 @@
|
|||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"device/arm"
|
"device/rp"
|
||||||
"machine"
|
|
||||||
"machine/usb/cdc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// machineTicks is provided by package machine.
|
const (
|
||||||
func machineTicks() uint64
|
// On RP2040 each core has a different IRQ number: SIO_IRQ_PROC0 and SIO_IRQ_PROC1.
|
||||||
|
// On RP2350 both cores share the same irq number (SIO_IRQ_PROC) just with a
|
||||||
// machineLightSleep is provided by package machine.
|
// different SIO interrupt output routed to that IRQ input on each core.
|
||||||
func machineLightSleep(uint64)
|
// https://www.raspberrypi.com/documentation/pico-sdk/high_level.html#group_pico_multicore_1ga1413ebfa65114c6f408f4675897ac5ee
|
||||||
|
sioIrqFifoProc0 = rp.IRQ_SIO_IRQ_FIFO
|
||||||
// ticks returns the number of ticks (microseconds) elapsed since power up.
|
sioIrqFifoProc1 = rp.IRQ_SIO_IRQ_FIFO
|
||||||
func ticks() timeUnit {
|
)
|
||||||
t := machineTicks()
|
|
||||||
return timeUnit(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ticksToNanoseconds(ticks timeUnit) int64 {
|
|
||||||
return int64(ticks) * 1000
|
|
||||||
}
|
|
||||||
|
|
||||||
func nanosecondsToTicks(ns int64) timeUnit {
|
|
||||||
return timeUnit(ns / 1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
func sleepTicks(d timeUnit) {
|
|
||||||
if d <= 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if hasScheduler {
|
|
||||||
// With scheduler, sleepTicks may return early if an interrupt or
|
|
||||||
// event fires - so scheduler can schedule any go routines now
|
|
||||||
// eligible to run
|
|
||||||
machineLightSleep(uint64(d))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Busy loop
|
|
||||||
sleepUntil := ticks() + d
|
|
||||||
for ticks() < sleepUntil {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func waitForEvents() {
|
|
||||||
arm.Asm("wfe")
|
|
||||||
}
|
|
||||||
|
|
||||||
func putchar(c byte) {
|
|
||||||
machine.Serial.WriteByte(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getchar() byte {
|
|
||||||
for machine.Serial.Buffered() == 0 {
|
|
||||||
Gosched()
|
|
||||||
}
|
|
||||||
v, _ := machine.Serial.ReadByte()
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
|
|
||||||
func buffered() int {
|
|
||||||
return machine.Serial.Buffered()
|
|
||||||
}
|
|
||||||
|
|
||||||
// machineInit is provided by package machine.
|
|
||||||
func machineInit()
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
machineInit()
|
|
||||||
|
|
||||||
cdc.EnableUSBCDC()
|
|
||||||
machine.USBDev.Configure(machine.UARTConfig{})
|
|
||||||
machine.InitSerial()
|
|
||||||
}
|
|
||||||
|
|
||||||
//export Reset_Handler
|
|
||||||
func main() {
|
|
||||||
preinit()
|
|
||||||
run()
|
|
||||||
exit(0)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ func addSleepTask(t *task.Task, duration timeUnit) {
|
|||||||
panic("runtime: addSleepTask: expected next task to be nil")
|
panic("runtime: addSleepTask: expected next task to be nil")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.Data = uint64(duration)
|
|
||||||
now := ticks()
|
now := ticks()
|
||||||
if sleepQueue == nil {
|
if sleepQueue == nil {
|
||||||
scheduleLog(" -> sleep new queue")
|
scheduleLog(" -> sleep new queue")
|
||||||
@@ -85,6 +84,7 @@ func addSleepTask(t *task.Task, duration timeUnit) {
|
|||||||
// set new base time
|
// set new base time
|
||||||
sleepQueueBaseTime = now
|
sleepQueueBaseTime = now
|
||||||
}
|
}
|
||||||
|
t.Data = uint64(duration + (now - sleepQueueBaseTime))
|
||||||
|
|
||||||
// Add to sleep queue.
|
// Add to sleep queue.
|
||||||
q := &sleepQueue
|
q := &sleepQueue
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func sliceGrow(oldBuf unsafe.Pointer, oldLen, oldCap, newCap, elemSize uintptr)
|
|||||||
var layout unsafe.Pointer
|
var layout unsafe.Pointer
|
||||||
// less type info here; can only go off element size
|
// less type info here; can only go off element size
|
||||||
if elemSize < unsafe.Sizeof(uintptr(0)) {
|
if elemSize < unsafe.Sizeof(uintptr(0)) {
|
||||||
layout = gclayout.NoPtrs
|
layout = gclayout.NoPtrs.AsPtr()
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := alloc(newCap*elemSize, layout)
|
buf := alloc(newCap*elemSize, layout)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user