├── bin
└── .keep
├── testdata
├── gc.txt
├── zeroalloc.txt
├── alias.txt
├── init_multi.txt
├── zeroalloc.go
├── cgo
│ ├── extra.go
│ ├── out.txt
│ └── main.c
├── stdlib.txt
├── init.txt
├── init_multi.go
├── structs.txt
├── string.txt
├── print.txt
├── coroutines.txt
├── calls.txt
├── string.go
├── slice.txt
├── stdlib.go
├── interface.txt
├── alias.go
├── binop.txt
├── channel.txt
├── float.txt
├── print.go
├── init.go
└── map.txt
├── lib
└── picolibc-include
│ └── picolibc.h
├── src
├── examples
│ ├── wasm
│ │ ├── .gitignore
│ │ ├── main
│ │ │ ├── main.go
│ │ │ ├── README.md
│ │ │ └── index.html
│ │ ├── invoke
│ │ │ ├── wasm.go
│ │ │ ├── index.html
│ │ │ └── wasm.js
│ │ ├── slices
│ │ │ ├── wasm.go
│ │ │ ├── index.html
│ │ │ └── wasm.js
│ │ ├── callback
│ │ │ ├── index.html
│ │ │ ├── wasm.js
│ │ │ └── wasm.go
│ │ ├── export
│ │ │ ├── index.html
│ │ │ ├── wasm.go
│ │ │ └── wasm.js
│ │ ├── server.go
│ │ └── Makefile
│ ├── serial
│ │ └── serial.go
│ ├── blinky1
│ │ └── blinky1.go
│ ├── gba-display
│ │ └── gba-display.go
│ ├── systick
│ │ ├── systick.go
│ │ └── README.md
│ ├── button
│ │ └── button.go
│ ├── i2s
│ │ └── i2s.go
│ ├── adc
│ │ └── adc.go
│ ├── microbit-blink
│ │ └── microbit-blink.go
│ ├── blinkm
│ │ └── blinkm.go
│ ├── blinky2
│ │ └── blinky2.go
│ ├── echo
│ │ └── echo.go
│ ├── pwm
│ │ └── pwm.go
│ ├── button2
│ │ └── button2.go
│ └── mcp3008
│ │ └── mcp3008.go
├── runtime
│ ├── cgo
│ │ └── cgo.go
│ ├── internal
│ │ └── sys
│ │ │ └── zversion.go
│ ├── os_js.go
│ ├── os_linux.go
│ ├── os_darwin.go
│ ├── os_freebsd.go
│ ├── runtime_unix_noheap.go
│ ├── runtime_stm32.go
│ ├── defer.go
│ ├── bytes.go
│ ├── runtime_fe310_baremetal.go
│ ├── arch_386.go
│ ├── arch_arm64.go
│ ├── scheduler_tasks.go
│ ├── scheduler_coroutines.go
│ ├── stack.go
│ ├── runtime_attiny.go
│ ├── interrupt
│ │ ├── interrupt_hwvector.go
│ │ ├── interrupt_sifive.go
│ │ ├── interrupt_cortexm.go
│ │ └── interrupt_gameboyadvance.go
│ ├── runtime_unix_heap.go
│ ├── arch_avr.go
│ ├── sync.go
│ ├── strings_go111.go
│ ├── arch_arm.go
│ ├── arch_cortexm.go
│ ├── arch_amd64.go
│ ├── gc_globals_conservative.go
│ ├── arch_tinygoriscv.go
│ ├── runtime_fe310_qemu.go
│ ├── scheduler_gba.S
│ ├── scheduler_any.go
│ ├── scheduler_none.go
│ ├── atomic.go
│ ├── arch_wasm.go
│ ├── scheduler_tinygoriscv.S
│ ├── gc_none.go
│ ├── poll.go
│ ├── string_count.go
│ ├── runtime_tinygoriscv.go
│ ├── baremetal.go
│ ├── runtime_cortexm_qemu.go
│ ├── gc_globals_precise.go
│ ├── func.go
│ ├── runtime_atmega.go
│ ├── gc_leaking.go
│ ├── gc_stack_raw.go
│ ├── gc_stack_portable.go
│ ├── runtime_tinygoriscv_qemu.go
│ ├── volatile
│ │ └── volatile.go
│ ├── runtime_atsamd21e18.go
│ ├── float.go
│ ├── runtime_arm7tdmi.go
│ ├── runtime_atsamd51g19.go
│ └── runtime_atsamd51j19.go
├── syscall
│ ├── syscall.go
│ ├── str.go
│ ├── errno.go
│ ├── syscall_libc.go
│ └── syscall_darwin.go
├── machine
│ ├── usb_nrf52840_reset_none.go
│ ├── board_pca10056_baremetal.go
│ ├── board_reelboard_baremetal.go
│ ├── board_stm32.go
│ ├── board_hifive1b_baremetal.go
│ ├── board_digispark.go
│ ├── board_arduino.go
│ ├── board_arduino_nano.go
│ ├── machine_atmega1284p.go
│ ├── board_fe310.go
│ ├── machine_attiny.go
│ ├── board_x9pro.go
│ ├── machine_attiny85.go
│ ├── board_pca10031.go
│ ├── board_nrf52840-mdk.go
│ ├── board_circuitplay_express_baremetal.go
│ ├── machine_nrf51.go
│ ├── board_pca10040.go
│ ├── board_pca10056.go
│ ├── board_arduino_nano33_baremetal.go
│ ├── board_hifive1b.go
│ ├── buffer.go
│ ├── i2s.go
│ ├── machine_atmega328p.go
│ ├── machine_atsamd51g19.go
│ ├── machine_stm32.go
│ ├── machine.go
│ ├── usb_nrf52840_reset_uf2.go
│ ├── board_atsamd21.go
│ └── board_microbit.go
├── reflect
│ └── swapper.go
├── testing
│ ├── doc.go
│ └── benchmark.go
├── sync
│ ├── once.go
│ ├── pool.go
│ ├── mutex.go
│ └── map.go
├── device
│ ├── riscv
│ │ └── riscv.go
│ ├── avr
│ │ └── avr.go
│ ├── nrf
│ │ └── README.markdown
│ ├── stm32
│ │ └── stm32f407xx-altfunc-bitfields.go
│ └── arm
│ │ └── cortexm.s
├── internal
│ ├── task
│ │ ├── task.go
│ │ └── task_none.go
│ └── reflectlite
│ │ └── reflect.go
└── os
│ ├── proc.go
│ ├── file_unix.go
│ └── file_other.go
├── cgo
├── testdata
│ ├── include
│ │ └── foo.h
│ ├── basic.go
│ ├── const.go
│ ├── basic.out.go
│ ├── flags.go
│ ├── const.out.go
│ ├── errors.go
│ ├── flags.out.go
│ └── errors.out.go
├── libclang_config_llvm9.go
├── libclang_config.go
└── sync.go
├── targets
├── pca10040-s132v6.json
├── pca10056-s140v7.json
├── reelboard-s140v7.json
├── particle-argon.json
├── particle-boron.json
├── particle-xenon.json
├── nrf52-s132v6.json
├── fe310.json
├── nrf52840-s140v7.json
├── nrf52840-mdk.json
├── particle-3rd-gen.json
├── pca10031.json
├── microbit.json
├── stm32.ld
├── lm3s6965.ld
├── nrf52840.ld
├── stm32f103rb.ld
├── stm32f407.ld
├── hifive1-qemu.json
├── hifive1b.ld
├── reelboard.json
├── nrf51.ld
├── nrf52.ld
├── pyportal.json
├── x9pro.json
├── arduino-nano33.json
├── pca10040.json
├── hifive1b.json
├── pybadge.json
├── pca10056.json
├── riscv-qemu.json
├── feather-m0.json
├── feather-m4.json
├── itsybitsy-m0.json
├── pinetime-devkit0.json
├── trinket-m0.json
├── itsybitsy-m4.json
├── nrf52840-s140v7.ld
├── arduino-mega2560.json
├── arduino.json
├── atsamd21.ld
├── metro-m4-airlift.json
├── atsamd51.ld
├── circuitplay-express.json
├── nrf52-s132v6.ld
├── arduino-nano.json
├── atsamd21e18a.json
├── atsamd21g18a.json
├── atsamd51g19a.json
├── atsamd51j19a.json
├── atsamd51j20a.json
├── hifive1-qemu.ld
├── clue_alpha.json
├── avr.json
├── circuitplay-bluefruit.json
├── circuitplay-bluefruit.ld
├── cortex-m-qemu.json
├── bluepill.json
├── atmega328p.json
├── stm32f4disco.json
├── nrf51.json
├── nucleo-f103rb.json
├── atmega2560.json
├── nrf52.json
├── nrf52840.json
├── riscv-qemu.ld
├── wasm.json
├── digispark.json
├── atmega1284p.json
├── cortex-m.json
├── riscv.json
├── gameboy-advance.json
└── avr.ld
├── version.go
├── transform
├── allocs_test.go
├── testdata
│ ├── globals-non-const.ll
│ ├── globals-non-const.out.ll
│ ├── globals-function-sections.ll
│ ├── globals-function-sections.out.ll
│ ├── wasm-abi.ll
│ ├── panic.ll
│ ├── panic.out.ll
│ ├── stringtobytes.out.ll
│ ├── stringtobytes.ll
│ ├── wasm-abi.out.ll
│ ├── gc-globals.ll
│ └── maps.out.ll
├── panic_test.go
├── func-lowering_test.go
├── stringtobytes_test.go
├── goroutine_test.go
├── interface-lowering_test.go
├── wasm-abi_test.go
├── gc_test.go
├── globals_test.go
├── interrupt_test.go
├── maps_test.go
├── transform.go
├── panic.go
├── globals.go
└── maps.go
├── tests
└── tinygotest
│ ├── main.go
│ └── main_test.go
├── interp
└── testdata
│ ├── interface.out.ll
│ ├── consteval.out.ll
│ ├── slice-copy.out.ll
│ ├── basic.out.ll
│ ├── consteval.ll
│ └── interface.ll
├── docs
├── moved.rst
└── index.rst
├── .gitignore
├── util_windows.go
├── go.mod
├── util_unix.go
├── loader
├── ssa.go
└── errors.go
├── compileopts
├── target_test.go
└── options.go
├── CONTRIBUTORS
├── .gitmodules
├── colorwriter.go
└── compiler
├── volatile.go
└── ircheck
└── errors.go
/bin/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/testdata/gc.txt:
--------------------------------------------------------------------------------
1 | ok
2 |
--------------------------------------------------------------------------------
/testdata/zeroalloc.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lib/picolibc-include/picolibc.h:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/examples/wasm/.gitignore:
--------------------------------------------------------------------------------
1 | html/*
2 |
--------------------------------------------------------------------------------
/cgo/testdata/include/foo.h:
--------------------------------------------------------------------------------
1 | #define FOO_H 1
2 |
--------------------------------------------------------------------------------
/testdata/alias.txt:
--------------------------------------------------------------------------------
1 | x
2 | apple
3 | true
4 | false
5 |
--------------------------------------------------------------------------------
/testdata/init_multi.txt:
--------------------------------------------------------------------------------
1 | init1
2 | init2
3 | main
4 |
--------------------------------------------------------------------------------
/cgo/testdata/basic.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "C"
4 |
--------------------------------------------------------------------------------
/src/runtime/cgo/cgo.go:
--------------------------------------------------------------------------------
1 | package cgo
2 |
3 | // dummy
4 |
--------------------------------------------------------------------------------
/src/syscall/syscall.go:
--------------------------------------------------------------------------------
1 | package syscall
2 |
3 | func Exit(code int)
4 |
--------------------------------------------------------------------------------
/targets/pca10040-s132v6.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["pca10040", "nrf52-s132v6"]
3 | }
4 |
--------------------------------------------------------------------------------
/src/runtime/internal/sys/zversion.go:
--------------------------------------------------------------------------------
1 | package sys
2 |
3 | const TheVersion = `go0.1.0`
4 |
--------------------------------------------------------------------------------
/src/runtime/os_js.go:
--------------------------------------------------------------------------------
1 | // +build js
2 |
3 | package runtime
4 |
5 | const GOOS = "js"
6 |
--------------------------------------------------------------------------------
/targets/pca10056-s140v7.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["pca10056", "nrf52840-s140v7"]
3 | }
4 |
--------------------------------------------------------------------------------
/targets/reelboard-s140v7.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["reelboard", "nrf52840-s140v7"]
3 | }
4 |
--------------------------------------------------------------------------------
/src/runtime/os_linux.go:
--------------------------------------------------------------------------------
1 | // +build linux
2 |
3 | package runtime
4 |
5 | const GOOS = "linux"
6 |
--------------------------------------------------------------------------------
/src/runtime/os_darwin.go:
--------------------------------------------------------------------------------
1 | // +build darwin
2 |
3 | package runtime
4 |
5 | const GOOS = "darwin"
6 |
--------------------------------------------------------------------------------
/src/examples/wasm/main/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | func main() {
4 | println("Hello world!")
5 | }
6 |
--------------------------------------------------------------------------------
/src/runtime/os_freebsd.go:
--------------------------------------------------------------------------------
1 | // +build freebsd
2 |
3 | package runtime
4 |
5 | const GOOS = "freebsd"
6 |
--------------------------------------------------------------------------------
/targets/particle-argon.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["particle-3rd-gen"],
3 | "build-tags": ["particle_argon"]
4 | }
5 |
--------------------------------------------------------------------------------
/targets/particle-boron.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["particle-3rd-gen"],
3 | "build-tags": ["particle_boron"]
4 | }
5 |
--------------------------------------------------------------------------------
/targets/particle-xenon.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["particle-3rd-gen"],
3 | "build-tags": ["particle_xenon"]
4 | }
5 |
--------------------------------------------------------------------------------
/testdata/zeroalloc.go:
--------------------------------------------------------------------------------
1 | package main
2 | func main() {
3 | p := []byte{}
4 | for len(p) >= 1 {
5 | p = p[1:]
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/targets/nrf52-s132v6.json:
--------------------------------------------------------------------------------
1 | {
2 | "build-tags": ["softdevice", "s132v6"],
3 | "linkerscript": "targets/nrf52-s132v6.ld"
4 | }
5 |
--------------------------------------------------------------------------------
/targets/fe310.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["riscv"],
3 | "features": ["+a", "+c", "+m"],
4 | "build-tags": ["fe310", "sifive"]
5 | }
6 |
--------------------------------------------------------------------------------
/targets/nrf52840-s140v7.json:
--------------------------------------------------------------------------------
1 | {
2 | "build-tags": ["softdevice", "s140v7"],
3 | "linkerscript": "targets/nrf52840-s140v7.ld"
4 | }
5 |
--------------------------------------------------------------------------------
/testdata/cgo/extra.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // Make sure CGo supports multiple files.
4 |
5 | // int fortytwo(void);
6 | import "C"
7 |
--------------------------------------------------------------------------------
/src/machine/usb_nrf52840_reset_none.go:
--------------------------------------------------------------------------------
1 | // +build nrf52840,!nrf52840_reset_uf2
2 |
3 | package machine
4 |
5 | func checkShouldReset() {
6 | }
7 |
--------------------------------------------------------------------------------
/src/reflect/swapper.go:
--------------------------------------------------------------------------------
1 | package reflect
2 |
3 | func Swapper(slice interface{}) func(i, j int) {
4 | panic("unimplemented: reflect.Swapper")
5 | }
6 |
--------------------------------------------------------------------------------
/testdata/stdlib.txt:
--------------------------------------------------------------------------------
1 | stdin: 0
2 | stdout: 1
3 | stderr: 2
4 | pseudorandom number: 1298498081
5 | strings.IndexByte: 2
6 | strings.Replace: An-example-string
7 |
--------------------------------------------------------------------------------
/version.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // version of this package.
4 | // Update this value before release of new version of software.
5 | const version = "0.13.1"
6 |
--------------------------------------------------------------------------------
/src/testing/doc.go:
--------------------------------------------------------------------------------
1 | package testing
2 |
3 | /*
4 | This is a sad stub of the upstream testing package because it doesn't compile
5 | with tinygo right now.
6 | */
7 |
--------------------------------------------------------------------------------
/src/machine/board_pca10056_baremetal.go:
--------------------------------------------------------------------------------
1 | // +build nrf52840,pca10056
2 |
3 | package machine
4 |
5 | // UART0 is the NRF UART
6 | var (
7 | UART0 = NRF_UART0
8 | )
9 |
--------------------------------------------------------------------------------
/src/machine/board_reelboard_baremetal.go:
--------------------------------------------------------------------------------
1 | // +build nrf52840,reelboard
2 |
3 | package machine
4 |
5 | // UART0 is the NRF UART
6 | var (
7 | UART0 = NRF_UART0
8 | )
9 |
--------------------------------------------------------------------------------
/testdata/init.txt:
--------------------------------------------------------------------------------
1 | init
2 | main
3 | v1: 3
4 | v2: 2 5
5 | v3: 4 4 2 7
6 | v4: 0 true
7 | v5: 0 false
8 | v6: false
9 | v7: 3 foo
10 | 3
11 | 3
12 | 5
13 | 5
14 |
--------------------------------------------------------------------------------
/targets/nrf52840-mdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["nrf52840"],
3 | "build-tags": ["nrf52840_mdk"],
4 | "flash-method": "openocd",
5 | "openocd-interface": "cmsis-dap"
6 | }
7 |
--------------------------------------------------------------------------------
/cgo/testdata/const.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | /*
4 | #define foo 3
5 | #define bar foo
6 | */
7 | import "C"
8 |
9 | const (
10 | Foo = C.foo
11 | Bar = C.bar
12 | )
13 |
--------------------------------------------------------------------------------
/src/runtime/runtime_unix_noheap.go:
--------------------------------------------------------------------------------
1 | // +build darwin linux,!baremetal freebsd,!baremetal
2 |
3 | // +build gc.none gc.extalloc
4 |
5 | package runtime
6 |
7 | func preinit() {}
8 |
--------------------------------------------------------------------------------
/targets/particle-3rd-gen.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["nrf52840"],
3 | "build-tags": ["particle_3rd_gen"],
4 | "flash-method": "openocd",
5 | "openocd-interface": "cmsis-dap"
6 | }
7 |
--------------------------------------------------------------------------------
/src/examples/serial/serial.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "time"
4 |
5 | func main() {
6 | for {
7 | println("hello world!")
8 | time.Sleep(time.Second)
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/testdata/init_multi.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | func init() {
4 | println("init1")
5 | }
6 |
7 | func init() {
8 | println("init2")
9 | }
10 |
11 | func main() {
12 | println("main")
13 | }
14 |
--------------------------------------------------------------------------------
/targets/pca10031.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["nrf51"],
3 | "build-tags": ["pca10031"],
4 | "flash-command": "nrfjprog -f nrf51 --sectorerase --program {hex} --reset",
5 | "openocd-interface": "cmsis-dap"
6 | }
7 |
--------------------------------------------------------------------------------
/transform/allocs_test.go:
--------------------------------------------------------------------------------
1 | package transform
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestAllocs(t *testing.T) {
8 | t.Parallel()
9 | testTransform(t, "testdata/allocs", OptimizeAllocs)
10 | }
11 |
--------------------------------------------------------------------------------
/tests/tinygotest/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | func main() {
8 | Thing()
9 | fmt.Println("normal main")
10 | }
11 |
12 | func Thing() {
13 | fmt.Println("THING")
14 | }
15 |
--------------------------------------------------------------------------------
/testdata/structs.txt:
--------------------------------------------------------------------------------
1 | test0
2 | test1 1
3 | test2 1 2
4 | test3 1 2 3
5 | test4 1 2 3 4
6 | test4b 1 2 3 4
7 | test4bp 1 2 3 4
8 | test5 1 2 3
9 | test6 foo 3 5
10 | test7 (0:nil) 8
11 | test8 2 3 12 13 6
12 | test9 nil
13 |
--------------------------------------------------------------------------------
/transform/testdata/globals-non-const.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
2 | target triple = "armv7em-none-eabi"
3 |
4 | @globalIntConst = constant i32 3
5 | @globalIntVar = global i32 5
6 |
--------------------------------------------------------------------------------
/targets/microbit.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["nrf51"],
3 | "build-tags": ["microbit"],
4 | "flash-method": "msd",
5 | "openocd-interface": "cmsis-dap",
6 | "msd-volume-name": "MICROBIT",
7 | "msd-firmware-name": "firmware.hex"
8 | }
9 |
--------------------------------------------------------------------------------
/targets/stm32.ld:
--------------------------------------------------------------------------------
1 |
2 | MEMORY
3 | {
4 | FLASH_TEXT (rw) : ORIGIN = 0x08000000, LENGTH = 64K
5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
6 | }
7 |
8 | _stack_size = 2K;
9 |
10 | INCLUDE "targets/arm.ld"
11 |
--------------------------------------------------------------------------------
/transform/panic_test.go:
--------------------------------------------------------------------------------
1 | package transform
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestReplacePanicsWithTrap(t *testing.T) {
8 | t.Parallel()
9 | testTransform(t, "testdata/panic", ReplacePanicsWithTrap)
10 | }
11 |
--------------------------------------------------------------------------------
/transform/testdata/globals-non-const.out.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
2 | target triple = "armv7em-none-eabi"
3 |
4 | @globalIntConst = global i32 3
5 | @globalIntVar = global i32 5
6 |
--------------------------------------------------------------------------------
/src/runtime/runtime_stm32.go:
--------------------------------------------------------------------------------
1 | // +build stm32
2 |
3 | package runtime
4 |
5 | type timeUnit int64
6 |
7 | func postinit() {}
8 |
9 | //export Reset_Handler
10 | func main() {
11 | preinit()
12 | run()
13 | abort()
14 | }
15 |
--------------------------------------------------------------------------------
/targets/lm3s6965.ld:
--------------------------------------------------------------------------------
1 |
2 | MEMORY
3 | {
4 | FLASH_TEXT (rw) : ORIGIN = 0x00000000, LENGTH = 256K
5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
6 | }
7 |
8 | _stack_size = 4K;
9 |
10 | INCLUDE "targets/arm.ld"
11 |
--------------------------------------------------------------------------------
/targets/nrf52840.ld:
--------------------------------------------------------------------------------
1 |
2 | MEMORY
3 | {
4 | FLASH_TEXT (rw) : ORIGIN = 0x00000000, LENGTH = 1M
5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 256K
6 | }
7 |
8 | _stack_size = 4K;
9 |
10 | INCLUDE "targets/arm.ld"
11 |
--------------------------------------------------------------------------------
/targets/stm32f103rb.ld:
--------------------------------------------------------------------------------
1 |
2 | MEMORY
3 | {
4 | FLASH_TEXT (rw) : ORIGIN = 0x08000000, LENGTH = 128K
5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
6 | }
7 |
8 | _stack_size = 2K;
9 |
10 | INCLUDE "targets/arm.ld"
11 |
--------------------------------------------------------------------------------
/targets/stm32f407.ld:
--------------------------------------------------------------------------------
1 |
2 | MEMORY
3 | {
4 | FLASH_TEXT (rw) : ORIGIN = 0x08000000, LENGTH = 1M
5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
6 | }
7 |
8 | _stack_size = 4K;
9 |
10 | INCLUDE "targets/arm.ld"
11 |
--------------------------------------------------------------------------------
/transform/func-lowering_test.go:
--------------------------------------------------------------------------------
1 | package transform
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestFuncLowering(t *testing.T) {
8 | t.Parallel()
9 | testTransform(t, "testdata/func-lowering", LowerFuncValues)
10 | }
11 |
--------------------------------------------------------------------------------
/src/runtime/defer.go:
--------------------------------------------------------------------------------
1 | package runtime
2 |
3 | // Some helper types for the defer statement.
4 | // See compiler/defer.go for details.
5 |
6 | type _defer struct {
7 | callback uintptr // callback number
8 | next *_defer
9 | }
10 |
--------------------------------------------------------------------------------
/targets/hifive1-qemu.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["fe310"],
3 | "build-tags": ["hifive1b", "qemu"],
4 | "linkerscript": "targets/hifive1-qemu.ld",
5 | "emulator": ["qemu-system-riscv32", "-machine", "sifive_e", "-nographic", "-kernel"]
6 | }
7 |
--------------------------------------------------------------------------------
/targets/hifive1b.ld:
--------------------------------------------------------------------------------
1 |
2 | MEMORY
3 | {
4 | FLASH_TEXT (rw) : ORIGIN = 0x20010000, LENGTH = 0x6a120
5 | RAM (xrw) : ORIGIN = 0x80000000, LENGTH = 0x4000
6 | }
7 |
8 | _stack_size = 2K;
9 |
10 | INCLUDE "targets/riscv.ld"
11 |
--------------------------------------------------------------------------------
/targets/reelboard.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["nrf52840"],
3 | "build-tags": ["reelboard"],
4 | "flash-method": "msd",
5 | "msd-volume-name": "reel-board",
6 | "msd-firmware-name": "firmware.hex",
7 | "openocd-interface": "cmsis-dap"
8 | }
9 |
--------------------------------------------------------------------------------
/transform/testdata/globals-function-sections.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
2 | target triple = "armv7em-none-eabi"
3 |
4 | declare void @foo()
5 |
6 | define void @bar() {
7 | ret void
8 | }
9 |
--------------------------------------------------------------------------------
/targets/nrf51.ld:
--------------------------------------------------------------------------------
1 |
2 | MEMORY
3 | {
4 | FLASH_TEXT (rw) : ORIGIN = 0x00000000, LENGTH = 256K /* .text */
5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K
6 | }
7 |
8 | _stack_size = 2K;
9 |
10 | INCLUDE "targets/arm.ld"
11 |
--------------------------------------------------------------------------------
/targets/nrf52.ld:
--------------------------------------------------------------------------------
1 |
2 | MEMORY
3 | {
4 | FLASH_TEXT (rw) : ORIGIN = 0x00000000, LENGTH = 256K /* .text */
5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K
6 | }
7 |
8 | _stack_size = 2K;
9 |
10 | INCLUDE "targets/arm.ld"
11 |
--------------------------------------------------------------------------------
/testdata/string.txt:
--------------------------------------------------------------------------------
1 | 0 97
2 | 1 98
3 | 2 99
4 | 3 252
5 | 5 162
6 | 7 8364
7 | 10 66376
8 | 14 176
9 | 16 120
10 | 0 97
11 | 1 98
12 | 2 99
13 | 3 252
14 | 4 162
15 | 5 8364
16 | 6 66376
17 | 7 176
18 | 8 120
19 | string from runes: abcü¢€𐍈°x
20 |
--------------------------------------------------------------------------------
/targets/pyportal.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["atsamd51j20a"],
3 | "build-tags": ["pyportal"],
4 | "flash-1200-bps-reset": "true",
5 | "flash-method": "msd",
6 | "msd-volume-name": "PORTALBOOT",
7 | "msd-firmware-name": "firmware.uf2"
8 | }
9 |
--------------------------------------------------------------------------------
/src/runtime/bytes.go:
--------------------------------------------------------------------------------
1 | package runtime
2 |
3 | //go:linkname indexBytePortable internal/bytealg.IndexByte
4 | func indexBytePortable(s []byte, c byte) int {
5 | for i, b := range s {
6 | if b == c {
7 | return i
8 | }
9 | }
10 | return -1
11 | }
12 |
--------------------------------------------------------------------------------
/src/sync/once.go:
--------------------------------------------------------------------------------
1 | package sync
2 |
3 | type Once struct {
4 | done bool
5 | m Mutex
6 | }
7 |
8 | func (o *Once) Do(f func()) {
9 | o.m.Lock()
10 | defer o.m.Unlock()
11 | if o.done {
12 | return
13 | }
14 | o.done = true
15 | f()
16 | }
17 |
--------------------------------------------------------------------------------
/targets/x9pro.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["nrf52"],
3 | "build-tags": ["x9pro"],
4 | "flash-method": "openocd",
5 | "flash-command": "nrfjprog -f nrf52 --sectorerase --program {hex} --reset",
6 | "openocd-interface": "jlink",
7 | "openocd-transport": "swd"
8 | }
9 |
--------------------------------------------------------------------------------
/targets/arduino-nano33.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["atsamd21g18a"],
3 | "build-tags": ["sam", "atsamd21g18a", "arduino_nano33"],
4 | "flash-command": "bossac -d -i -e -w -v -R --port={port} --offset=0x2000 {bin}",
5 | "flash-1200-bps-reset": "true"
6 | }
7 |
--------------------------------------------------------------------------------
/transform/testdata/globals-function-sections.out.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
2 | target triple = "armv7em-none-eabi"
3 |
4 | declare void @foo()
5 |
6 | define void @bar() section ".text.bar" {
7 | ret void
8 | }
9 |
--------------------------------------------------------------------------------
/targets/pca10040.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["nrf52"],
3 | "build-tags": ["pca10040"],
4 | "flash-method": "openocd",
5 | "flash-command": "nrfjprog -f nrf52 --sectorerase --program {hex} --reset",
6 | "openocd-interface": "jlink",
7 | "openocd-transport": "swd"
8 | }
9 |
--------------------------------------------------------------------------------
/interp/testdata/interface.out.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2 | target triple = "x86_64--linux"
3 |
4 | @main.v1 = local_unnamed_addr global i1 true
5 |
6 | define void @runtime.initAll() unnamed_addr {
7 | entry:
8 | ret void
9 | }
10 |
--------------------------------------------------------------------------------
/targets/hifive1b.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["fe310"],
3 | "build-tags": ["hifive1b"],
4 | "linkerscript": "targets/hifive1b.ld",
5 | "flash-method": "msd",
6 | "msd-volume-name": "HiFive",
7 | "msd-firmware-name": "firmware.hex",
8 | "jlink-device": "fe310"
9 | }
10 |
--------------------------------------------------------------------------------
/targets/pybadge.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["atsamd51j19a"],
3 | "build-tags": ["sam", "atsamd51j19a", "pybadge"],
4 | "flash-1200-bps-reset": "true",
5 | "flash-method": "msd",
6 | "msd-volume-name": "PYBADGEBOOT",
7 | "msd-firmware-name": "arcade.uf2"
8 | }
9 |
--------------------------------------------------------------------------------
/targets/pca10056.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["nrf52840"],
3 | "build-tags": ["pca10056"],
4 | "flash-method": "command",
5 | "flash-command": "nrfjprog -f nrf52 --sectorerase --program {hex} --reset",
6 | "msd-volume-name": "JLINK",
7 | "msd-firmware-name": "firmware.hex"
8 | }
9 |
--------------------------------------------------------------------------------
/targets/riscv-qemu.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["riscv"],
3 | "features": ["+a", "+c", "+m"],
4 | "build-tags": ["virt", "qemu"],
5 | "linkerscript": "targets/riscv-qemu.ld",
6 | "emulator": ["qemu-system-riscv32", "-machine", "virt", "-nographic", "-bios", "none", "-kernel"]
7 | }
8 |
--------------------------------------------------------------------------------
/targets/feather-m0.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["atsamd21g18a"],
3 | "build-tags": ["sam", "atsamd21g18a", "feather_m0"],
4 | "flash-1200-bps-reset": "true",
5 | "flash-method": "msd",
6 | "msd-volume-name": "FEATHERBOOT",
7 | "msd-firmware-name": "firmware.uf2"
8 | }
9 |
--------------------------------------------------------------------------------
/targets/feather-m4.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["atsamd51j19a"],
3 | "build-tags": ["sam", "atsamd51j19a", "feather_m4"],
4 | "flash-1200-bps-reset": "true",
5 | "flash-method": "msd",
6 | "msd-volume-name": "FEATHERBOOT",
7 | "msd-firmware-name": "firmware.uf2"
8 | }
9 |
--------------------------------------------------------------------------------
/targets/itsybitsy-m0.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["atsamd21g18a"],
3 | "build-tags": ["sam", "atsamd21g18a", "itsybitsy_m0"],
4 | "flash-1200-bps-reset": "true",
5 | "flash-method": "msd",
6 | "msd-volume-name": "ITSYBOOT",
7 | "msd-firmware-name": "firmware.uf2"
8 | }
9 |
--------------------------------------------------------------------------------
/targets/pinetime-devkit0.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["nrf52"],
3 | "build-tags": ["pinetime_devkit0"],
4 | "flash-method": "openocd",
5 | "flash-command": "nrfjprog -f nrf52 --sectorerase --program {hex} --reset",
6 | "openocd-interface": "jlink",
7 | "openocd-transport": "swd"
8 | }
9 |
--------------------------------------------------------------------------------
/targets/trinket-m0.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["atsamd21e18a"],
3 | "build-tags": ["sam", "atsamd21e18a", "trinket_m0"],
4 | "flash-1200-bps-reset": "true",
5 | "flash-method": "msd",
6 | "msd-volume-name": "TRINKETBOOT",
7 | "msd-firmware-name": "firmware.uf2"
8 | }
9 |
--------------------------------------------------------------------------------
/docs/moved.rst:
--------------------------------------------------------------------------------
1 | .. _moved:
2 |
3 | .. highlight:: none
4 |
5 | The TinyGo Docs Site Has Moved
6 | =========================
7 |
8 | The documentation web site for TinyGo has moved.
9 |
10 | You can find the new web site at `tinygo.org `_
11 |
12 | Thank you!
13 |
--------------------------------------------------------------------------------
/targets/itsybitsy-m4.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["atsamd51g19a"],
3 | "build-tags": ["sam", "atsamd51g19a", "itsybitsy_m4"],
4 | "flash-1200-bps-reset": "true",
5 | "flash-method": "msd",
6 | "msd-volume-name": "ITSYM4BOOT",
7 | "msd-firmware-name": "firmware.uf2"
8 | }
9 |
--------------------------------------------------------------------------------
/targets/nrf52840-s140v7.ld:
--------------------------------------------------------------------------------
1 |
2 | MEMORY
3 | {
4 | FLASH_TEXT (rw) : ORIGIN = 0x00000000 + 0x00027000, LENGTH = 1M - 0x00027000
5 | RAM (xrw) : ORIGIN = 0x20000000 + 0x000039c0, LENGTH = 256K - 0x000039c0
6 | }
7 |
8 | _stack_size = 4K;
9 |
10 | INCLUDE "targets/arm.ld"
11 |
--------------------------------------------------------------------------------
/src/machine/board_stm32.go:
--------------------------------------------------------------------------------
1 | // +build bluepill nucleof103rb stm32f4disco
2 |
3 | package machine
4 |
5 | // Peripheral abstraction layer for the stm32.
6 |
7 | const (
8 | portA Pin = iota * 16
9 | portB
10 | portC
11 | portD
12 | portE
13 | portF
14 | portG
15 | portH
16 | )
17 |
--------------------------------------------------------------------------------
/targets/arduino-mega2560.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["atmega2560"],
3 | "build-tags": ["arduino_mega2560"],
4 | "ldflags": [
5 | "-Wl,--defsym=_bootloader_size=8192"
6 | ],
7 | "flash-command":"avrdude -c wiring -b 115200 -p atmega2560 -P {port} -U flash:w:{hex} -v -D"
8 | }
9 |
--------------------------------------------------------------------------------
/targets/arduino.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["atmega328p"],
3 | "build-tags": ["arduino"],
4 | "ldflags": [
5 | "-Wl,--defsym=_bootloader_size=512",
6 | "-Wl,--defsym=_stack_size=512"
7 | ],
8 | "flash-command": "avrdude -c arduino -p atmega328p -P {port} -U flash:w:{hex}:i"
9 | }
10 |
--------------------------------------------------------------------------------
/targets/atsamd21.ld:
--------------------------------------------------------------------------------
1 |
2 | MEMORY
3 | {
4 | FLASH_TEXT (rw) : ORIGIN = 0x00000000+0x2000, LENGTH = 0x00040000-0x2000 /* First 8KB used by bootloader */
5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x00008000
6 | }
7 |
8 | _stack_size = 2K;
9 |
10 | INCLUDE "targets/arm.ld"
11 |
--------------------------------------------------------------------------------
/targets/metro-m4-airlift.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["atsamd51j19a"],
3 | "build-tags": ["sam", "atsamd51j19a", "metro_m4_airlift"],
4 | "flash-1200-bps-reset": "true",
5 | "flash-method": "msd",
6 | "msd-volume-name": "METROM4BOOT",
7 | "msd-firmware-name": "firmware.uf2"
8 | }
9 |
--------------------------------------------------------------------------------
/targets/atsamd51.ld:
--------------------------------------------------------------------------------
1 |
2 | MEMORY
3 | {
4 | FLASH_TEXT (rw) : ORIGIN = 0x00000000+0x4000, LENGTH = 0x00080000-0x4000 /* First 16KB used by bootloader */
5 | RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x00030000
6 | }
7 |
8 | _stack_size = 4K;
9 |
10 | INCLUDE "targets/arm.ld"
11 |
--------------------------------------------------------------------------------
/targets/circuitplay-express.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["atsamd21g18a"],
3 | "build-tags": ["sam", "atsamd21g18a", "circuitplay_express"],
4 | "flash-1200-bps-reset": "true",
5 | "flash-method": "msd",
6 | "msd-volume-name": "CPLAYBOOT",
7 | "msd-firmware-name": "firmware.uf2"
8 | }
9 |
--------------------------------------------------------------------------------
/src/runtime/runtime_fe310_baremetal.go:
--------------------------------------------------------------------------------
1 | // +build fe310,!qemu
2 |
3 | package runtime
4 |
5 | import (
6 | "device/riscv"
7 | )
8 |
9 | const tickMicros = 32768 // RTC clock runs at 32.768kHz
10 |
11 | func abort() {
12 | // lock up forever
13 | for {
14 | riscv.Asm("wfi")
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/targets/nrf52-s132v6.ld:
--------------------------------------------------------------------------------
1 |
2 | MEMORY
3 | {
4 | FLASH_TEXT (rw) : ORIGIN = 0x00000000 + 0x00026000 , LENGTH = 256K - 0x00026000 /* .text */
5 | RAM (xrw) : ORIGIN = 0x20000000 + 0x000039c0, LENGTH = 64K - 0x000039c0
6 | }
7 |
8 | _stack_size = 4K;
9 |
10 | INCLUDE "targets/arm.ld"
11 |
--------------------------------------------------------------------------------
/src/examples/wasm/main/README.md:
--------------------------------------------------------------------------------
1 | # WebAssembly main execution example
2 |
3 | A simple hello world that prints to the browser console.
4 |
5 | ## License
6 |
7 | Note that `index.html` is copied almost verbatim from the Go 1.12 source at
8 | `$GOROOT/misc/wasm/wasm_exec.html`. Its license applies to this file.
9 |
--------------------------------------------------------------------------------
/targets/arduino-nano.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["atmega328p"],
3 | "build-tags": ["arduino_nano"],
4 | "ldflags": [
5 | "-Wl,--defsym=_bootloader_size=512",
6 | "-Wl,--defsym=_stack_size=512"
7 | ],
8 | "flash-command": "avrdude -c arduino -p atmega328p -b 57600 -P {port} -U flash:w:{hex}:i"
9 | }
10 |
--------------------------------------------------------------------------------
/src/runtime/arch_386.go:
--------------------------------------------------------------------------------
1 | package runtime
2 |
3 | const GOARCH = "386"
4 |
5 | // The bitness of the CPU (e.g. 8, 32, 64).
6 | const TargetBits = 32
7 |
8 | // Align on word boundary.
9 | func align(ptr uintptr) uintptr {
10 | return (ptr + 3) &^ 3
11 | }
12 |
13 | func getCurrentStackPointer() uintptr
14 |
--------------------------------------------------------------------------------
/src/runtime/arch_arm64.go:
--------------------------------------------------------------------------------
1 | package runtime
2 |
3 | const GOARCH = "arm64"
4 |
5 | // The bitness of the CPU (e.g. 8, 32, 64).
6 | const TargetBits = 64
7 |
8 | // Align on word boundary.
9 | func align(ptr uintptr) uintptr {
10 | return (ptr + 7) &^ 7
11 | }
12 |
13 | func getCurrentStackPointer() uintptr
14 |
--------------------------------------------------------------------------------
/src/runtime/scheduler_tasks.go:
--------------------------------------------------------------------------------
1 | // +build scheduler.tasks
2 |
3 | package runtime
4 |
5 | // getSystemStackPointer returns the current stack pointer of the system stack.
6 | // This is not necessarily the same as the current stack pointer.
7 | //export tinygo_getSystemStackPointer
8 | func getSystemStackPointer() uintptr
9 |
--------------------------------------------------------------------------------
/src/runtime/scheduler_coroutines.go:
--------------------------------------------------------------------------------
1 | // +build scheduler.coroutines
2 |
3 | package runtime
4 |
5 | // getSystemStackPointer returns the current stack pointer of the system stack.
6 | // This is always the current stack pointer.
7 | func getSystemStackPointer() uintptr {
8 | return getCurrentStackPointer()
9 | }
10 |
--------------------------------------------------------------------------------
/src/runtime/stack.go:
--------------------------------------------------------------------------------
1 | package runtime
2 |
3 | type Func struct {
4 | }
5 |
6 | func FuncForPC(pc uintptr) *Func {
7 | return nil
8 | }
9 |
10 | func (f *Func) Name() string {
11 | return ""
12 | }
13 |
14 | func Caller(skip int) (pc uintptr, file string, line int, ok bool) {
15 | return 0, "", 0, false
16 | }
17 |
--------------------------------------------------------------------------------
/interp/testdata/consteval.out.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2 | target triple = "x86_64--linux"
3 |
4 | @intToPtrResult = local_unnamed_addr global i8 2
5 | @ptrToIntResult = local_unnamed_addr global i8 2
6 |
7 | define void @runtime.initAll() local_unnamed_addr {
8 | ret void
9 | }
10 |
--------------------------------------------------------------------------------
/testdata/print.txt:
--------------------------------------------------------------------------------
1 | hello world!
2 | 42
3 | 100000000
4 | abc
5 | a b c
6 | 123
7 | 123
8 | -123
9 | 12345
10 | 12345
11 | -12345
12 | 12345678
13 | 12345678
14 | -12345678
15 | 123456789012
16 | 123456789012
17 | -123456789012
18 | +3.140000e+000
19 | (+5.000000e+000+1.234500e+000i)
20 | (0:nil)
21 | map[2]
22 | true false
23 |
--------------------------------------------------------------------------------
/src/machine/board_hifive1b_baremetal.go:
--------------------------------------------------------------------------------
1 | // +build fe310,hifive1b
2 |
3 | package machine
4 |
5 | import "device/sifive"
6 |
7 | // SPI on the HiFive1.
8 | var (
9 | SPI1 = SPI{
10 | Bus: sifive.QSPI1,
11 | }
12 | )
13 |
14 | // I2C on the HiFive1 rev B.
15 | var (
16 | I2C0 = I2C{
17 | Bus: sifive.I2C0,
18 | }
19 | )
20 |
--------------------------------------------------------------------------------
/src/examples/wasm/invoke/wasm.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "syscall/js"
5 | )
6 |
7 | func runner(this js.Value, args []js.Value) interface{} {
8 | return args[0].Invoke(args[1]).String()
9 | }
10 |
11 | func main() {
12 | wait := make(chan struct{}, 0)
13 | js.Global().Set("runner", js.FuncOf(runner))
14 | <-wait
15 | }
16 |
--------------------------------------------------------------------------------
/src/runtime/runtime_attiny.go:
--------------------------------------------------------------------------------
1 | // +build avr,attiny
2 |
3 | package runtime
4 |
5 | import (
6 | "device/avr"
7 | )
8 |
9 | func sleepWDT(period uint8) {
10 | // TODO: use the watchdog timer instead of a busy loop.
11 | for i := 0x45; i != 0; i-- {
12 | for i := 0xff; i != 0; i-- {
13 | avr.Asm("nop")
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | build
2 | docs/_build
3 | src/device/avr/*.go
4 | src/device/avr/*.ld
5 | src/device/avr/*.s
6 | src/device/nrf/*.go
7 | src/device/nrf/*.s
8 | src/device/sam/*.go
9 | src/device/sam/*.s
10 | src/device/sifive/*.go
11 | src/device/sifive/*.s
12 | src/device/stm32/*.go
13 | src/device/stm32/*.s
14 | vendor
15 | llvm-build
16 | llvm-project
17 |
--------------------------------------------------------------------------------
/src/machine/board_digispark.go:
--------------------------------------------------------------------------------
1 | // +build digispark
2 |
3 | package machine
4 |
5 | // Return the current CPU frequency in hertz.
6 | func CPUFrequency() uint32 {
7 | return 16000000
8 | }
9 |
10 | const (
11 | P0 Pin = PB0
12 | P1 Pin = PB1
13 | P2 Pin = PB2
14 | P3 Pin = PB3
15 | P4 Pin = PB4
16 | P5 Pin = PB5
17 |
18 | LED = P1
19 | )
20 |
--------------------------------------------------------------------------------
/transform/stringtobytes_test.go:
--------------------------------------------------------------------------------
1 | package transform
2 |
3 | import (
4 | "testing"
5 |
6 | "tinygo.org/x/go-llvm"
7 | )
8 |
9 | func TestOptimizeStringToBytes(t *testing.T) {
10 | t.Parallel()
11 | testTransform(t, "testdata/stringtobytes", func(mod llvm.Module) {
12 | // Run optimization pass.
13 | OptimizeStringToBytes(mod)
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/util_windows.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // This file contains utility functions for Windows.
4 |
5 | import (
6 | "os/exec"
7 | )
8 |
9 | // setCommandAsDaemon makes sure this command does not receive signals sent to
10 | // the parent. It is unimplemented on Windows.
11 | func setCommandAsDaemon(daemon *exec.Cmd) {
12 | // Not implemented.
13 | }
14 |
--------------------------------------------------------------------------------
/src/runtime/interrupt/interrupt_hwvector.go:
--------------------------------------------------------------------------------
1 | // +build avr cortexm
2 |
3 | package interrupt
4 |
5 | // Register is used to declare an interrupt. You should not normally call this
6 | // function: it is only for telling the compiler about the mapping between an
7 | // interrupt number and the interrupt handler name.
8 | func Register(id int, handlerName string) int
9 |
--------------------------------------------------------------------------------
/targets/atsamd21e18a.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["cortex-m"],
3 | "llvm-target": "armv6m-none-eabi",
4 | "build-tags": ["atsamd21e18", "atsamd21", "sam"],
5 | "cflags": [
6 | "--target=armv6m-none-eabi",
7 | "-Qunused-arguments"
8 | ],
9 | "linkerscript": "targets/atsamd21.ld",
10 | "extra-files": [
11 | "src/device/sam/atsamd21e18a.s"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/targets/atsamd21g18a.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["cortex-m"],
3 | "llvm-target": "armv6m-none-eabi",
4 | "build-tags": ["atsamd21g18", "atsamd21", "sam"],
5 | "cflags": [
6 | "--target=armv6m-none-eabi",
7 | "-Qunused-arguments"
8 | ],
9 | "linkerscript": "targets/atsamd21.ld",
10 | "extra-files": [
11 | "src/device/sam/atsamd21g18a.s"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/targets/atsamd51g19a.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["cortex-m"],
3 | "llvm-target": "armv7em-none-eabi",
4 | "build-tags": ["atsamd51g19", "atsamd51", "sam"],
5 | "cflags": [
6 | "--target=armv7em-none-eabi",
7 | "-Qunused-arguments"
8 | ],
9 | "linkerscript": "targets/atsamd51.ld",
10 | "extra-files": [
11 | "src/device/sam/atsamd51g19a.s"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/targets/atsamd51j19a.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["cortex-m"],
3 | "llvm-target": "armv7em-none-eabi",
4 | "build-tags": ["atsamd51j19", "atsamd51", "sam"],
5 | "cflags": [
6 | "--target=armv7em-none-eabi",
7 | "-Qunused-arguments"
8 | ],
9 | "linkerscript": "targets/atsamd51.ld",
10 | "extra-files": [
11 | "src/device/sam/atsamd51j19a.s"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/transform/goroutine_test.go:
--------------------------------------------------------------------------------
1 | package transform
2 |
3 | import (
4 | "testing"
5 | "tinygo.org/x/go-llvm"
6 | )
7 |
8 | func TestGoroutineLowering(t *testing.T) {
9 | t.Parallel()
10 | testTransform(t, "testdata/coroutines", func(mod llvm.Module) {
11 | err := LowerCoroutines(mod, false)
12 | if err != nil {
13 | panic(err)
14 | }
15 | })
16 | }
17 |
--------------------------------------------------------------------------------
/src/runtime/runtime_unix_heap.go:
--------------------------------------------------------------------------------
1 | // +build darwin linux,!baremetal freebsd,!baremetal
2 |
3 | // +build gc.conservative gc.leaking
4 |
5 | package runtime
6 |
7 | const heapSize = 1 * 1024 * 1024 // 1MB to start
8 |
9 | var heapStart, heapEnd uintptr
10 |
11 | func preinit() {
12 | heapStart = uintptr(malloc(heapSize))
13 | heapEnd = heapStart + heapSize
14 | }
15 |
--------------------------------------------------------------------------------
/transform/interface-lowering_test.go:
--------------------------------------------------------------------------------
1 | package transform
2 |
3 | import (
4 | "testing"
5 |
6 | "tinygo.org/x/go-llvm"
7 | )
8 |
9 | func TestInterfaceLowering(t *testing.T) {
10 | t.Parallel()
11 | testTransform(t, "testdata/interface", func(mod llvm.Module) {
12 | err := LowerInterfaces(mod)
13 | if err != nil {
14 | t.Error(err)
15 | }
16 | })
17 | }
18 |
--------------------------------------------------------------------------------
/targets/atsamd51j20a.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["cortex-m"],
3 | "llvm-target": "armv7em-none-eabi",
4 | "build-tags": ["sam", "atsamd51", "atsamd51j20", "atsamd51j20a"],
5 | "cflags": [
6 | "--target=armv7em-none-eabi",
7 | "-Qunused-arguments"
8 | ],
9 | "linkerscript": "targets/atsamd51.ld",
10 | "extra-files": [
11 | "src/device/sam/atsamd51j20a.s"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/targets/hifive1-qemu.ld:
--------------------------------------------------------------------------------
1 |
2 | /* memory map:
3 | * https://github.com/sifive/freedom-e-sdk/blob/v201908-branch/bsp/sifive-hifive1/metal.default.lds
4 | */
5 | MEMORY
6 | {
7 | FLASH_TEXT (rw) : ORIGIN = 0x20400000, LENGTH = 0x1fc00000
8 | RAM (xrw) : ORIGIN = 0x80000000, LENGTH = 0x4000
9 | }
10 |
11 | _stack_size = 2K;
12 |
13 | INCLUDE "targets/riscv.ld"
14 |
--------------------------------------------------------------------------------
/testdata/coroutines.txt:
--------------------------------------------------------------------------------
1 | main 1
2 | sub 1
3 | main 2
4 | sub 2
5 | main 3
6 | wait:
7 | wait start
8 | wait end
9 | end waiting
10 | value produced after some time: 42
11 | non-blocking goroutine
12 | done with non-blocking goroutine
13 | async interface method call
14 | slept inside func pointer 8
15 | slept inside closure, with value: 20 8
16 | closure go call result: 1
17 |
--------------------------------------------------------------------------------
/targets/clue_alpha.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["nrf52840"],
3 | "build-tags": ["clue_alpha","nrf52840_reset_uf2"],
4 | "flash-1200-bps-reset": "true",
5 | "flash-method": "msd",
6 | "msd-volume-name": "FTHR840BOOT",
7 | "msd-firmware-name": "firmware.uf2",
8 | "uf2-family-id": "0xADA52840",
9 | "linkerscript": "targets/circuitplay-bluefruit.ld"
10 | }
11 |
--------------------------------------------------------------------------------
/targets/avr.json:
--------------------------------------------------------------------------------
1 | {
2 | "build-tags": ["avr", "baremetal", "linux", "arm"],
3 | "goos": "linux",
4 | "goarch": "arm",
5 | "compiler": "avr-gcc",
6 | "gc": "conservative",
7 | "linker": "avr-gcc",
8 | "scheduler": "none",
9 | "ldflags": [
10 | "-T", "targets/avr.ld",
11 | "-Wl,--gc-sections"
12 | ],
13 | "extra-files": [
14 | "src/runtime/scheduler_avr.S"
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/src/runtime/arch_avr.go:
--------------------------------------------------------------------------------
1 | // +build avr
2 |
3 | package runtime
4 |
5 | const GOARCH = "arm" // avr pretends to be arm
6 |
7 | // The bitness of the CPU (e.g. 8, 32, 64).
8 | const TargetBits = 8
9 |
10 | // Align on a word boundary.
11 | func align(ptr uintptr) uintptr {
12 | // No alignment necessary on the AVR.
13 | return ptr
14 | }
15 |
16 | func getCurrentStackPointer() uintptr
17 |
--------------------------------------------------------------------------------
/src/runtime/sync.go:
--------------------------------------------------------------------------------
1 | package runtime
2 |
3 | // This file contains stub implementations for internal/poll.
4 |
5 | //go:linkname semacquire internal/poll.runtime_Semacquire
6 | func semacquire(sema *uint32) {
7 | panic("todo: semacquire")
8 | }
9 |
10 | //go:linkname semrelease internal/poll.runtime_Semrelease
11 | func semrelease(sema *uint32) {
12 | panic("todo: semrelease")
13 | }
14 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. TinyGo documentation master file, created by
2 | sphinx-quickstart on Sat Sep 22 15:05:19 2018.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | The TinyGo site has moved!
7 | ==================================
8 |
9 | Contents:
10 |
11 | .. toctree::
12 | :maxdepth: 2
13 |
14 | moved
15 |
--------------------------------------------------------------------------------
/targets/circuitplay-bluefruit.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["nrf52840"],
3 | "build-tags": ["circuitplay_bluefruit","nrf52840_reset_uf2"],
4 | "flash-1200-bps-reset": "true",
5 | "flash-method": "msd",
6 | "msd-volume-name": "CPLAYBTBOOT",
7 | "msd-firmware-name": "firmware.uf2",
8 | "uf2-family-id": "0xADA52840",
9 | "linkerscript": "targets/circuitplay-bluefruit.ld"
10 | }
11 |
--------------------------------------------------------------------------------
/testdata/calls.txt:
--------------------------------------------------------------------------------
1 | hello from function pointer: 5
2 | deferring...
3 | Thing.Print: foo arg: bar
4 | ...run as defer 3
5 | ...run closure deferred: 4
6 | ...run as defer 1
7 | ...exported defer
8 | loop 3
9 | loop 2
10 | loop 1
11 | loop 0
12 | bound method: foo
13 | thing inside closure: foo
14 | inside fp closure: foo 3
15 | Thing.Print: arg: functional args 1
16 | Thing.Print: named thing arg: functional args 2
17 |
--------------------------------------------------------------------------------
/transform/wasm-abi_test.go:
--------------------------------------------------------------------------------
1 | package transform
2 |
3 | import (
4 | "testing"
5 |
6 | "tinygo.org/x/go-llvm"
7 | )
8 |
9 | func TestWasmABI(t *testing.T) {
10 | t.Parallel()
11 | testTransform(t, "testdata/wasm-abi", func(mod llvm.Module) {
12 | // Run ABI change pass.
13 | err := ExternalInt64AsPtr(mod)
14 | if err != nil {
15 | t.Errorf("failed to change wasm ABI: %v", err)
16 | }
17 | })
18 | }
19 |
--------------------------------------------------------------------------------
/src/runtime/strings_go111.go:
--------------------------------------------------------------------------------
1 | // +build !go1.12
2 |
3 | package runtime
4 |
5 | // indexByte provides compatibility with Go 1.11.
6 | // See the following:
7 | // https://github.com/tinygo-org/tinygo/issues/351
8 | // https://github.com/golang/go/commit/ad4a58e31501bce5de2aad90a620eaecdc1eecb8
9 | //go:linkname indexByte strings.IndexByte
10 | func indexByte(s string, c byte) int {
11 | return indexByteString(s, c)
12 | }
13 |
--------------------------------------------------------------------------------
/src/runtime/arch_arm.go:
--------------------------------------------------------------------------------
1 | // +build arm,!baremetal arm,arm7tdmi
2 |
3 | package runtime
4 |
5 | import "device/arm"
6 |
7 | const GOARCH = "arm"
8 |
9 | // The bitness of the CPU (e.g. 8, 32, 64).
10 | const TargetBits = 32
11 |
12 | // Align on word boundary.
13 | func align(ptr uintptr) uintptr {
14 | return (ptr + 3) &^ 3
15 | }
16 |
17 | func getCurrentStackPointer() uintptr {
18 | return arm.ReadRegister("sp")
19 | }
20 |
--------------------------------------------------------------------------------
/src/runtime/arch_cortexm.go:
--------------------------------------------------------------------------------
1 | // +build cortexm
2 |
3 | package runtime
4 |
5 | import (
6 | "device/arm"
7 | )
8 |
9 | const GOARCH = "arm"
10 |
11 | // The bitness of the CPU (e.g. 8, 32, 64).
12 | const TargetBits = 32
13 |
14 | // Align on word boundary.
15 | func align(ptr uintptr) uintptr {
16 | return (ptr + 3) &^ 3
17 | }
18 |
19 | func getCurrentStackPointer() uintptr {
20 | return arm.ReadRegister("sp")
21 | }
22 |
--------------------------------------------------------------------------------
/targets/circuitplay-bluefruit.ld:
--------------------------------------------------------------------------------
1 |
2 | MEMORY
3 | {
4 | FLASH_TEXT (rw) : ORIGIN = 0x00000000+0x26000, LENGTH = 0xED000-0x26000 /* SoftDevice S140. See https://learn.adafruit.com/introducing-the-adafruit-nrf52840-feather/hathach-memory-map. Application starts at 0x26000; user data starts at 0xED000 */
5 | RAM (xrw) : ORIGIN = 0x20004180, LENGTH = 37K
6 | }
7 |
8 | _stack_size = 2K;
9 |
10 | INCLUDE "targets/arm.ld"
11 |
--------------------------------------------------------------------------------
/src/runtime/arch_amd64.go:
--------------------------------------------------------------------------------
1 | package runtime
2 |
3 | const GOARCH = "amd64"
4 |
5 | // The bitness of the CPU (e.g. 8, 32, 64).
6 | const TargetBits = 64
7 |
8 | // Align a pointer.
9 | // Note that some amd64 instructions (like movaps) expect 16-byte aligned
10 | // memory, thus the result must be 16-byte aligned.
11 | func align(ptr uintptr) uintptr {
12 | return (ptr + 15) &^ 15
13 | }
14 |
15 | func getCurrentStackPointer() uintptr
16 |
--------------------------------------------------------------------------------
/src/runtime/gc_globals_conservative.go:
--------------------------------------------------------------------------------
1 | // +build gc.conservative gc.extalloc
2 | // +build baremetal
3 |
4 | package runtime
5 |
6 | // markGlobals marks all globals, which are reachable by definition.
7 | //
8 | // This implementation marks all globals conservatively and assumes it can use
9 | // linker-defined symbols for the start and end of the .data section.
10 | func markGlobals() {
11 | markRoots(globalsStart, globalsEnd)
12 | }
13 |
--------------------------------------------------------------------------------
/src/examples/blinky1/blinky1.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // This is the most minimal blinky example and should run almost everywhere.
4 |
5 | import (
6 | "machine"
7 | "time"
8 | )
9 |
10 | func main() {
11 | led := machine.LED
12 | led.Configure(machine.PinConfig{Mode: machine.PinOutput})
13 | for {
14 | led.Low()
15 | time.Sleep(time.Millisecond * 500)
16 |
17 | led.High()
18 | time.Sleep(time.Millisecond * 500)
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/targets/cortex-m-qemu.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["cortex-m"],
3 | "llvm-target": "armv7m-none-eabi",
4 | "build-tags": ["qemu", "lm3s6965"],
5 | "cflags": [
6 | "--target=armv7m-none-eabi",
7 | "-Qunused-arguments"
8 | ],
9 | "linkerscript": "targets/lm3s6965.ld",
10 | "extra-files": [
11 | "targets/cortex-m-qemu.s"
12 | ],
13 | "emulator": ["qemu-system-arm", "-machine", "lm3s6965evb", "-semihosting", "-nographic", "-kernel"]
14 | }
15 |
--------------------------------------------------------------------------------
/src/device/riscv/riscv.go:
--------------------------------------------------------------------------------
1 | package riscv
2 |
3 | // Run the given assembly code. The code will be marked as having side effects,
4 | // as it doesn't produce output and thus would normally be eliminated by the
5 | // optimizer.
6 | func Asm(asm string)
7 |
8 | // ReadRegister returns the contents of the specified register. The register
9 | // must be a processor register, reachable with the "mov" instruction.
10 | func ReadRegister(name string) uintptr
11 |
--------------------------------------------------------------------------------
/src/examples/gba-display/gba-display.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // Draw a red square on the GameBoy Advance screen.
4 |
5 | import (
6 | "image/color"
7 | "machine"
8 | )
9 |
10 | var display = machine.Display
11 |
12 | func main() {
13 | display.Configure()
14 |
15 | for x := int16(30); x < 50; x++ {
16 | for y := int16(80); y < 100; y++ {
17 | display.SetPixel(x, y, color.RGBA{255, 0, 0, 255})
18 | }
19 | }
20 | display.Display()
21 | }
22 |
--------------------------------------------------------------------------------
/src/runtime/arch_tinygoriscv.go:
--------------------------------------------------------------------------------
1 | // +build tinygo.riscv
2 |
3 | package runtime
4 |
5 | import "device/riscv"
6 |
7 | const GOARCH = "arm" // riscv pretends to be arm
8 |
9 | // The bitness of the CPU (e.g. 8, 32, 64).
10 | const TargetBits = 32
11 |
12 | // Align on word boundary.
13 | func align(ptr uintptr) uintptr {
14 | return (ptr + 3) &^ 3
15 | }
16 |
17 | func getCurrentStackPointer() uintptr {
18 | return riscv.ReadRegister("sp")
19 | }
20 |
--------------------------------------------------------------------------------
/cgo/libclang_config_llvm9.go:
--------------------------------------------------------------------------------
1 | // +build !byollvm
2 | // +build llvm9
3 |
4 | package cgo
5 |
6 | /*
7 | #cgo linux CFLAGS: -I/usr/lib/llvm-9/include
8 | #cgo darwin CFLAGS: -I/usr/local/opt/llvm@9/include
9 | #cgo freebsd CFLAGS: -I/usr/local/llvm9/include
10 | #cgo linux LDFLAGS: -L/usr/lib/llvm-9/lib -lclang
11 | #cgo darwin LDFLAGS: -L/usr/local/opt/llvm@9/lib -lclang -lffi
12 | #cgo freebsd LDFLAGS: -L/usr/local/llvm9/lib -lclang
13 | */
14 | import "C"
15 |
--------------------------------------------------------------------------------
/cgo/libclang_config.go:
--------------------------------------------------------------------------------
1 | // +build !byollvm
2 | // +build !llvm9
3 |
4 | package cgo
5 |
6 | /*
7 | #cgo linux CFLAGS: -I/usr/lib/llvm-10/include
8 | #cgo darwin CFLAGS: -I/usr/local/opt/llvm@10/include
9 | #cgo freebsd CFLAGS: -I/usr/local/llvm10/include
10 | #cgo linux LDFLAGS: -L/usr/lib/llvm-10/lib -lclang
11 | #cgo darwin LDFLAGS: -L/usr/local/opt/llvm@10/lib -lclang -lffi
12 | #cgo freebsd LDFLAGS: -L/usr/local/llvm10/lib -lclang
13 | */
14 | import "C"
15 |
--------------------------------------------------------------------------------
/targets/bluepill.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["cortex-m"],
3 | "llvm-target": "armv7m-none-eabi",
4 | "build-tags": ["bluepill", "stm32f103xx", "stm32"],
5 | "cflags": [
6 | "--target=armv7m-none-eabi",
7 | "-Qunused-arguments"
8 | ],
9 | "linkerscript": "targets/stm32.ld",
10 | "extra-files": [
11 | "src/device/stm32/stm32f103xx.s"
12 | ],
13 | "flash-method": "openocd",
14 | "openocd-interface": "stlink-v2",
15 | "openocd-target": "stm32f1x"
16 | }
17 |
--------------------------------------------------------------------------------
/src/sync/pool.go:
--------------------------------------------------------------------------------
1 | package sync
2 |
3 | // Pool is a very simple implementation of sync.Pool. It does not actually
4 | // implement a pool.
5 | type Pool struct {
6 | New func() interface{}
7 | }
8 |
9 | // Get returns the value of calling Pool.New().
10 | func (p *Pool) Get() interface{} {
11 | if p.New == nil {
12 | return nil
13 | }
14 | return p.New()
15 | }
16 |
17 | // Put drops the value put into the pool.
18 | func (p *Pool) Put(x interface{}) {
19 | }
20 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/tinygo-org/tinygo
2 |
3 | go 1.11
4 |
5 | require (
6 | github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2
7 | github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
8 | github.com/marcinbor85/gohex v0.0.0-20180128172054-7a43cd876e46
9 | go.bug.st/serial v1.0.0
10 | golang.org/x/tools v0.0.0-20200216192241-b320d3a0f5a2
11 | google.golang.org/appengine v1.4.0 // indirect
12 | tinygo.org/x/go-llvm v0.0.0-20200401165421-8d120882fc7a
13 | )
14 |
--------------------------------------------------------------------------------
/targets/atmega328p.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["avr"],
3 | "llvm-target": "avr-atmel-none",
4 | "cpu": "atmega328p",
5 | "build-tags": ["atmega328p", "atmega", "avr5"],
6 | "cflags": [
7 | "-mmcu=atmega328p"
8 | ],
9 | "ldflags": [
10 | "-mmcu=avr5"
11 | ],
12 | "linkerscript": "src/device/avr/atmega328p.ld",
13 | "extra-files": [
14 | "targets/avr.S",
15 | "src/device/avr/atmega328p.s"
16 | ],
17 | "emulator": ["simavr", "-m", "atmega328p", "-f", "16000000"]
18 | }
19 |
--------------------------------------------------------------------------------
/transform/gc_test.go:
--------------------------------------------------------------------------------
1 | package transform
2 |
3 | import (
4 | "testing"
5 |
6 | "tinygo.org/x/go-llvm"
7 | )
8 |
9 | func TestAddGlobalsBitmap(t *testing.T) {
10 | t.Parallel()
11 | testTransform(t, "testdata/gc-globals", func(mod llvm.Module) {
12 | AddGlobalsBitmap(mod)
13 | })
14 | }
15 |
16 | func TestMakeGCStackSlots(t *testing.T) {
17 | t.Parallel()
18 | testTransform(t, "testdata/gc-stackslots", func(mod llvm.Module) {
19 | MakeGCStackSlots(mod)
20 | })
21 | }
22 |
--------------------------------------------------------------------------------
/targets/stm32f4disco.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["cortex-m"],
3 | "llvm-target": "armv7em-none-eabi",
4 | "build-tags": ["stm32f4disco", "stm32f407", "stm32"],
5 | "cflags": [
6 | "--target=armv7em-none-eabi",
7 | "-Qunused-arguments"
8 | ],
9 | "linkerscript": "targets/stm32f407.ld",
10 | "extra-files": [
11 | "src/device/stm32/stm32f407.s"
12 | ],
13 | "flash-method": "openocd",
14 | "openocd-interface": "stlink-v2",
15 | "openocd-target": "stm32f4x"
16 | }
17 |
--------------------------------------------------------------------------------
/src/runtime/runtime_fe310_qemu.go:
--------------------------------------------------------------------------------
1 | // +build fe310,qemu
2 |
3 | package runtime
4 |
5 | import (
6 | "runtime/volatile"
7 | "unsafe"
8 | )
9 |
10 | const tickMicros = 100 // CLINT.MTIME increments every 100ns
11 |
12 | // Special memory-mapped device to exit tests, created by SiFive.
13 | var testExit = (*volatile.Register32)(unsafe.Pointer(uintptr(0x100000)))
14 |
15 | var timestamp timeUnit
16 |
17 | func abort() {
18 | // Signal a successful exit.
19 | testExit.Set(0x5555)
20 | }
21 |
--------------------------------------------------------------------------------
/targets/nrf51.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["cortex-m"],
3 | "llvm-target": "armv6m-none-eabi",
4 | "build-tags": ["nrf51822", "nrf51", "nrf"],
5 | "cflags": [
6 | "--target=armv6m-none-eabi",
7 | "-Qunused-arguments",
8 | "-DNRF51",
9 | "-I{root}/lib/CMSIS/CMSIS/Include",
10 | "-I{root}/lib/nrfx/mdk"
11 | ],
12 | "linkerscript": "targets/nrf51.ld",
13 | "extra-files": [
14 | "lib/nrfx/mdk/system_nrf51.c",
15 | "src/device/nrf/nrf51.s"
16 | ],
17 | "openocd-target": "nrf51"
18 | }
19 |
--------------------------------------------------------------------------------
/targets/nucleo-f103rb.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["cortex-m"],
3 | "llvm-target": "armv7m-none-eabi",
4 | "build-tags": ["nucleof103rb", "stm32f103xx", "stm32"],
5 | "cflags": [
6 | "--target=armv7m-none-eabi",
7 | "-Qunused-arguments"
8 | ],
9 | "linkerscript": "targets/stm32f103rb.ld",
10 | "extra-files": [
11 | "src/device/stm32/stm32f103xx.s"
12 | ],
13 | "flash-method": "openocd",
14 | "openocd-interface": "stlink-v2-1",
15 | "openocd-target": "stm32f1x"
16 | }
17 |
--------------------------------------------------------------------------------
/targets/atmega2560.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["avr"],
3 | "llvm-target": "avr-atmel-none",
4 | "cpu": "atmega2560",
5 | "build-tags": ["atmega2560", "atmega"],
6 | "cflags": [
7 | "-mmcu=atmega2560"
8 | ],
9 | "ldflags": [
10 | "-mmcu=avr6",
11 | "-Wl,--defsym=_stack_size=512"
12 | ],
13 | "linkerscript": "src/device/avr/atmega2560.ld",
14 | "extra-files": [
15 | "targets/avr.S",
16 | "src/device/avr/atmega2560.s"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/util_unix.go:
--------------------------------------------------------------------------------
1 | // +build !windows
2 |
3 | package main
4 |
5 | // This file contains utility functions for Unix-like systems (e.g. Linux).
6 |
7 | import (
8 | "os/exec"
9 | "syscall"
10 | )
11 |
12 | // setCommandAsDaemon makes sure this command does not receive signals sent to
13 | // the parent.
14 | func setCommandAsDaemon(daemon *exec.Cmd) {
15 | // https://stackoverflow.com/a/35435038/559350
16 | daemon.SysProcAttr = &syscall.SysProcAttr{
17 | Setpgid: true,
18 | Pgid: 0,
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/transform/globals_test.go:
--------------------------------------------------------------------------------
1 | package transform
2 |
3 | import (
4 | "testing"
5 |
6 | "tinygo.org/x/go-llvm"
7 | )
8 |
9 | func TestApplyFunctionSections(t *testing.T) {
10 | t.Parallel()
11 | testTransform(t, "testdata/globals-function-sections", func(mod llvm.Module) {
12 | ApplyFunctionSections(mod)
13 | })
14 | }
15 |
16 | func TestNonConstGlobals(t *testing.T) {
17 | t.Parallel()
18 | testTransform(t, "testdata/globals-non-const", func(mod llvm.Module) {
19 | NonConstGlobals(mod)
20 | })
21 | }
22 |
--------------------------------------------------------------------------------
/targets/nrf52.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["cortex-m"],
3 | "llvm-target": "armv7em-none-eabi",
4 | "build-tags": ["nrf52", "nrf"],
5 | "cflags": [
6 | "--target=armv7em-none-eabi",
7 | "-mfloat-abi=soft",
8 | "-Qunused-arguments",
9 | "-DNRF52832_XXAA",
10 | "-I{root}/lib/CMSIS/CMSIS/Include",
11 | "-I{root}/lib/nrfx/mdk"
12 | ],
13 | "linkerscript": "targets/nrf52.ld",
14 | "extra-files": [
15 | "lib/nrfx/mdk/system_nrf52.c",
16 | "src/device/nrf/nrf52.s"
17 | ],
18 | "openocd-target": "nrf51"
19 | }
20 |
--------------------------------------------------------------------------------
/loader/ssa.go:
--------------------------------------------------------------------------------
1 | package loader
2 |
3 | import (
4 | "golang.org/x/tools/go/ssa"
5 | )
6 |
7 | // LoadSSA constructs the SSA form of the loaded packages.
8 | //
9 | // The program must already be parsed and type-checked with the .Parse() method.
10 | func (p *Program) LoadSSA() *ssa.Program {
11 | prog := ssa.NewProgram(p.fset, ssa.SanityCheckFunctions|ssa.BareInits|ssa.GlobalDebug)
12 |
13 | for _, pkg := range p.Sorted() {
14 | prog.CreatePackage(pkg.Pkg, pkg.Files, &pkg.Info, true)
15 | }
16 |
17 | return prog
18 | }
19 |
--------------------------------------------------------------------------------
/src/examples/wasm/slices/wasm.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "strings"
5 | "syscall/js"
6 | )
7 |
8 | func splitter(this js.Value, args []js.Value) interface{} {
9 | values := strings.Split(args[0].String(), ",")
10 |
11 | result := make([]interface{}, 0)
12 | for _, each := range values {
13 | result = append(result, each)
14 | }
15 |
16 | return js.ValueOf(result)
17 | }
18 |
19 | func main() {
20 | wait := make(chan struct{}, 0)
21 | js.Global().Set("splitter", js.FuncOf(splitter))
22 | <-wait
23 | }
24 |
--------------------------------------------------------------------------------
/src/runtime/scheduler_gba.S:
--------------------------------------------------------------------------------
1 | .section .text.tinygo_scanCurrentStack
2 | .global tinygo_scanCurrentStack
3 | .type tinygo_scanCurrentStack, %function
4 | tinygo_scanCurrentStack:
5 | // Save callee-saved registers onto the stack.
6 | mov r0, r8
7 | mov r1, r9
8 | mov r2, r10
9 | mov r3, r11
10 | push {r0-r3, lr}
11 | push {r4-r7}
12 |
13 | // Scan the stack.
14 | mov r0, sp
15 | bl tinygo_scanstack
16 |
17 | // Restore stack state and return.
18 | add sp, #32
19 | pop {pc}
20 |
--------------------------------------------------------------------------------
/testdata/string.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | func testRangeString() {
4 | for i, c := range "abcü¢€𐍈°x" {
5 | println(i, c)
6 | }
7 | }
8 |
9 | func testStringToRunes() {
10 | var s = "abcü¢€𐍈°x"
11 | for i, c := range []rune(s) {
12 | println(i, c)
13 | }
14 | }
15 |
16 | func testRunesToString(r []rune) {
17 | println("string from runes:", string(r))
18 | }
19 |
20 | func main() {
21 | testRangeString()
22 | testStringToRunes()
23 | testRunesToString([]rune{97, 98, 99, 252, 162, 8364, 66376, 176, 120})
24 | }
25 |
--------------------------------------------------------------------------------
/src/internal/task/task.go:
--------------------------------------------------------------------------------
1 | package task
2 |
3 | import (
4 | "unsafe"
5 | )
6 |
7 | // Task is a state of goroutine for scheduling purposes.
8 | type Task struct {
9 | // Next is a field which can be used to make a linked list of tasks.
10 | Next *Task
11 |
12 | // Ptr is a field which can be used for storing a pointer.
13 | Ptr unsafe.Pointer
14 |
15 | // Data is a field which can be used for storing state information.
16 | Data uint
17 |
18 | // state is the underlying running state of the task.
19 | state state
20 | }
21 |
--------------------------------------------------------------------------------
/targets/nrf52840.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["cortex-m"],
3 | "llvm-target": "armv7em-none-eabi",
4 | "build-tags": ["nrf52840", "nrf"],
5 | "cflags": [
6 | "--target=armv7em-none-eabi",
7 | "-mfloat-abi=soft",
8 | "-Qunused-arguments",
9 | "-DNRF52840_XXAA",
10 | "-I{root}/lib/CMSIS/CMSIS/Include",
11 | "-I{root}/lib/nrfx/mdk"
12 | ],
13 | "linkerscript": "targets/nrf52840.ld",
14 | "extra-files": [
15 | "lib/nrfx/mdk/system_nrf52840.c",
16 | "src/device/nrf/nrf52840.s"
17 | ],
18 | "openocd-target": "nrf51"
19 | }
20 |
--------------------------------------------------------------------------------
/targets/riscv-qemu.ld:
--------------------------------------------------------------------------------
1 |
2 | /* Memory map:
3 | * https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c
4 | * RAM and flash are set to 1MB each. That should be enough for the foreseeable
5 | * future. QEMU does not seem to limit the flash/RAM size and in fact doesn't
6 | * seem to differentiate between it.
7 | */
8 | MEMORY
9 | {
10 | FLASH_TEXT (rw) : ORIGIN = 0x80000000, LENGTH = 0x100000
11 | RAM (xrw) : ORIGIN = 0x80100000, LENGTH = 0x100000
12 | }
13 |
14 | _stack_size = 2K;
15 |
16 | INCLUDE "targets/riscv.ld"
17 |
--------------------------------------------------------------------------------
/compileopts/target_test.go:
--------------------------------------------------------------------------------
1 | package compileopts
2 |
3 | import "testing"
4 |
5 | func TestLoadTarget(t *testing.T) {
6 | _, err := LoadTarget("arduino")
7 | if err != nil {
8 | t.Error("LoadTarget test failed:", err)
9 | }
10 |
11 | _, err = LoadTarget("notexist")
12 | if err == nil {
13 | t.Error("LoadTarget should have failed with non existing target")
14 | }
15 |
16 | if err.Error() != "expected a full LLVM target or a custom target in -target flag" {
17 | t.Error("LoadTarget failed for wrong reason:", err)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/testdata/slice.txt:
--------------------------------------------------------------------------------
1 | foo is nil? false false
2 | foo: len=4 cap=4 data: 1 2 4 5
3 | bar: len=3 cap=5 data: 0 0 0
4 | foo[1:2]: len=1 cap=3 data: 2
5 | sum foo: 12
6 | copy foo -> bar: 3
7 | bar: len=3 cap=5 data: 1 2 4
8 | slice is nil? true true
9 | grow: len=0 cap=0 data:
10 | grow: len=1 cap=1 data: 42
11 | grow: len=3 cap=4 data: 42 -1 -2
12 | grow: len=7 cap=8 data: 42 -1 -2 1 2 4 5
13 | grow: len=7 cap=8 data: 42 -1 -2 1 2 4 5
14 | grow: len=14 cap=16 data: 42 -1 -2 1 2 4 5 42 -1 -2 1 2 4 5
15 | bytes: len=6 cap=6 data: 1 2 3 102 111 111
16 |
--------------------------------------------------------------------------------
/src/examples/systick/systick.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "device/arm"
5 | "machine"
6 | )
7 |
8 | func main() {
9 | machine.LED.Configure(machine.PinConfig{Mode: machine.PinOutput})
10 |
11 | // timer fires 10 times per second
12 | arm.SetupSystemTimer(machine.CPUFrequency() / 10)
13 |
14 | for {
15 | }
16 | }
17 |
18 | var led_state bool
19 |
20 | //export SysTick_Handler
21 | func timer_isr() {
22 | if led_state {
23 | machine.LED.Low()
24 | } else {
25 | machine.LED.High()
26 | }
27 | led_state = !led_state
28 | }
29 |
--------------------------------------------------------------------------------
/src/machine/board_arduino.go:
--------------------------------------------------------------------------------
1 | // +build arduino
2 |
3 | package machine
4 |
5 | // Return the current CPU frequency in hertz.
6 | func CPUFrequency() uint32 {
7 | return 16000000
8 | }
9 |
10 | // LED on the Arduino
11 | const LED Pin = 13
12 |
13 | // ADC on the Arduino
14 | const (
15 | ADC0 Pin = 0
16 | ADC1 Pin = 1
17 | ADC2 Pin = 2
18 | ADC3 Pin = 3
19 | ADC4 Pin = 4 // Used by TWI for SDA
20 | ADC5 Pin = 5 // Used by TWI for SCL
21 | )
22 |
23 | // UART pins
24 | const (
25 | UART_TX_PIN Pin = 1
26 | UART_RX_PIN Pin = 0
27 | )
28 |
--------------------------------------------------------------------------------
/src/examples/wasm/slices/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Go WebAssembly
8 |
9 |
10 |
11 |
12 |
13 |
14 | WebAssembly
15 | type values separated by comma, using WebAssembly:
16 | ==
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/machine/board_arduino_nano.go:
--------------------------------------------------------------------------------
1 | // +build arduino_nano
2 |
3 | package machine
4 |
5 | // Return the current CPU frequency in hertz.
6 | func CPUFrequency() uint32 {
7 | return 16000000
8 | }
9 |
10 | // LED on the Arduino
11 | const LED Pin = 13
12 |
13 | // ADC on the Arduino
14 | const (
15 | ADC0 Pin = 0
16 | ADC1 Pin = 1
17 | ADC2 Pin = 2
18 | ADC3 Pin = 3
19 | ADC4 Pin = 4 // Used by TWI for SDA
20 | ADC5 Pin = 5 // Used by TWI for SCL
21 | )
22 |
23 | // UART pins
24 | const (
25 | UART_TX_PIN Pin = 1
26 | UART_RX_PIN Pin = 0
27 | )
28 |
--------------------------------------------------------------------------------
/src/examples/wasm/invoke/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Go WebAssembly
8 |
9 |
10 |
11 |
12 |
13 |
14 | WebAssembly
15 | Edit on either side to mimic values, using WebAssembly:
16 | ==
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/transform/interrupt_test.go:
--------------------------------------------------------------------------------
1 | package transform
2 |
3 | import (
4 | "testing"
5 |
6 | "tinygo.org/x/go-llvm"
7 | )
8 |
9 | func TestInterruptLowering(t *testing.T) {
10 | t.Parallel()
11 | for _, subtest := range []string{"avr", "cortexm"} {
12 | t.Run(subtest, func(t *testing.T) {
13 | testTransform(t, "testdata/interrupt-"+subtest, func(mod llvm.Module) {
14 | errs := LowerInterrupts(mod)
15 | if len(errs) != 0 {
16 | t.Fail()
17 | for _, err := range errs {
18 | t.Error(err)
19 | }
20 | }
21 | })
22 | })
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/transform/maps_test.go:
--------------------------------------------------------------------------------
1 | package transform
2 |
3 | import (
4 | "testing"
5 |
6 | "tinygo.org/x/go-llvm"
7 | )
8 |
9 | func TestOptimizeMaps(t *testing.T) {
10 | t.Parallel()
11 | testTransform(t, "testdata/maps", func(mod llvm.Module) {
12 | // Run optimization pass.
13 | OptimizeMaps(mod)
14 |
15 | // Run an optimization pass, to clean up the result.
16 | // This shows that all code related to the map is really eliminated.
17 | pm := llvm.NewPassManager()
18 | defer pm.Dispose()
19 | pm.AddDeadStoreEliminationPass()
20 | pm.Run(mod)
21 | })
22 | }
23 |
--------------------------------------------------------------------------------
/src/machine/machine_atmega1284p.go:
--------------------------------------------------------------------------------
1 | // +build avr,atmega1284p
2 |
3 | package machine
4 |
5 | import (
6 | "device/avr"
7 | "runtime/volatile"
8 | )
9 |
10 | const irq_USART0_RX = avr.IRQ_USART0_RX
11 |
12 | // Return the current CPU frequency in hertz.
13 | func CPUFrequency() uint32 {
14 | return 20000000
15 | }
16 |
17 | func (p Pin) getPortMask() (*volatile.Register8, uint8) {
18 | if p < 8 {
19 | return avr.PORTD, 1 << uint8(p)
20 | } else if p < 14 {
21 | return avr.PORTB, 1 << uint8(p-8)
22 | } else {
23 | return avr.PORTC, 1 << uint8(p-14)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/testdata/stdlib.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math/rand"
6 | "os"
7 | "strings"
8 | )
9 |
10 | func main() {
11 | // package os, fmt
12 | fmt.Println("stdin: ", os.Stdin.Fd())
13 | fmt.Println("stdout:", os.Stdout.Fd())
14 | fmt.Println("stderr:", os.Stderr.Fd())
15 |
16 | // package math/rand
17 | fmt.Println("pseudorandom number:", rand.Int31())
18 |
19 | // package strings
20 | fmt.Println("strings.IndexByte:", strings.IndexByte("asdf", 'd'))
21 | fmt.Println("strings.Replace:", strings.Replace("An example string", " ", "-", -1))
22 | }
23 |
--------------------------------------------------------------------------------
/src/examples/systick/README.md:
--------------------------------------------------------------------------------
1 | # TinyGo ARM SysTick example
2 |
3 | This example uses the ARM System Timer to blink an LED. The timer fires
4 | an interrupt 10 times per second. The interrupt handler toggles the LED on
5 | and off.
6 |
7 | Many ARM-based chips have this timer feature. If you run the example and the
8 | LED blinks, then you have one.
9 |
10 | The System Timer runs from a cycle counter. The more cycles, the slower the
11 | LED will blink. This counter is 24 bits wide, which places an upper bound on
12 | the number of cycles, and the slowness of the blinking.
13 |
--------------------------------------------------------------------------------
/src/os/proc.go:
--------------------------------------------------------------------------------
1 | // Package os implements a subset of the Go "os" package. See
2 | // https://godoc.org/os for details.
3 | //
4 | // Note that the current implementation is blocking. This limitation should be
5 | // removed in a future version.
6 | package os
7 |
8 | import (
9 | "syscall"
10 | )
11 |
12 | // Exit causes the current program to exit with the given status code.
13 | // Conventionally, code zero indicates success, non-zero an error.
14 | // The program terminates immediately; deferred functions are not run.
15 | func Exit(code int) {
16 | syscall.Exit(code)
17 | }
18 |
--------------------------------------------------------------------------------
/targets/wasm.json:
--------------------------------------------------------------------------------
1 | {
2 | "llvm-target": "wasm32--wasi",
3 | "build-tags": ["js", "wasm"],
4 | "goos": "js",
5 | "goarch": "wasm",
6 | "compiler": "clang",
7 | "linker": "wasm-ld",
8 | "cflags": [
9 | "--target=wasm32--wasi",
10 | "--sysroot={root}/lib/wasi-libc/sysroot",
11 | "-Oz"
12 | ],
13 | "ldflags": [
14 | "--allow-undefined",
15 | "--no-threads",
16 | "--stack-first",
17 | "--export-all",
18 | "{root}/lib/wasi-libc/sysroot/lib/wasm32-wasi/libc.a"
19 | ],
20 | "emulator": ["node", "targets/wasm_exec.js"]
21 | }
22 |
--------------------------------------------------------------------------------
/tests/tinygotest/main_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "testing" // This is the tinygo testing package
5 | )
6 |
7 | func TestFail1(t *testing.T) {
8 | t.Error("TestFail1 failed because of stuff and things")
9 | }
10 |
11 | func TestFail2(t *testing.T) {
12 | t.Fatalf("TestFail2 failed for %v ", "reasons")
13 | }
14 |
15 | func TestFail3(t *testing.T) {
16 | t.Fail()
17 | t.Logf("TestFail3 failed for %v ", "reasons")
18 | }
19 |
20 | func TestPass(t *testing.T) {
21 | t.Log("TestPass passed")
22 | }
23 |
24 | func BenchmarkNotImplemented(b *testing.B) {
25 | }
26 |
--------------------------------------------------------------------------------
/src/examples/wasm/callback/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Go WebAssembly
8 |
9 |
10 |
11 |
12 |
13 |
14 | WebAssembly
15 | Add two numbers, using WebAssembly:
16 | + =
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/examples/wasm/export/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Go WebAssembly
8 |
9 |
10 |
11 |
12 |
13 |
14 | WebAssembly
15 | Add two numbers, using WebAssembly:
16 | + =
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/examples/wasm/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "net/http"
6 | "strings"
7 | )
8 |
9 | const dir = "./html"
10 |
11 | func main() {
12 | fs := http.FileServer(http.Dir(dir))
13 | log.Print("Serving " + dir + " on http://localhost:8080")
14 | http.ListenAndServe(":8080", http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
15 | resp.Header().Add("Cache-Control", "no-cache")
16 | if strings.HasSuffix(req.URL.Path, ".wasm") {
17 | resp.Header().Set("content-type", "application/wasm")
18 | }
19 | fs.ServeHTTP(resp, req)
20 | }))
21 | }
22 |
--------------------------------------------------------------------------------
/interp/testdata/slice-copy.out.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2 | target triple = "x86_64--linux"
3 |
4 | declare void @runtime.printuint8(i8) local_unnamed_addr
5 |
6 | declare void @runtime.printint16(i16) local_unnamed_addr
7 |
8 | define void @runtime.initAll() unnamed_addr {
9 | entry:
10 | ret void
11 | }
12 |
13 | define void @main() unnamed_addr {
14 | entry:
15 | call void @runtime.printuint8(i8 3)
16 | call void @runtime.printuint8(i8 3)
17 | call void @runtime.printint16(i16 5)
18 | call void @runtime.printint16(i16 5)
19 | ret void
20 | }
21 |
--------------------------------------------------------------------------------
/testdata/interface.txt:
--------------------------------------------------------------------------------
1 | thing: foo
2 | Thing.Print: foo
3 | is int: 5
4 | is byte: 120
5 | is string: foo
6 | is Foo: 18
7 | is Thing: foo
8 | is *Thing: foo
9 | is *Thing: foo
10 | is struct{n int}
11 | is struct{n int `foo:"bar"`}
12 | is Doubler: 6
13 | is Tuple: 1 7 11 13
14 | Array len: 4
15 | is Tuple: 1 7 11 13
16 | ArrayStruct.Print: 4 3
17 | is Tuple: 0 8 16 24
18 | SmallPair.Print: 3 5
19 | Stringer.String(): foo
20 | Stringer.(*Thing).String(): foo
21 | s has String() method: foo
22 | nested switch: true
23 | non-blocking call on sometimes-blocking interface
24 | slept 1ms
25 | slept 1ms
26 |
--------------------------------------------------------------------------------
/src/examples/button/button.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "machine"
5 | "time"
6 | )
7 |
8 | // This example assumes that the button is connected to pin 8. Change the value
9 | // below to use a different pin.
10 | const (
11 | led = machine.LED
12 | button = machine.Pin(8)
13 | )
14 |
15 | func main() {
16 | led.Configure(machine.PinConfig{Mode: machine.PinOutput})
17 | button.Configure(machine.PinConfig{Mode: machine.PinInput})
18 |
19 | for {
20 | if button.Get() {
21 | led.Low()
22 | } else {
23 | led.High()
24 | }
25 |
26 | time.Sleep(time.Millisecond * 10)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/examples/wasm/export/wasm.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "strconv"
5 | "syscall/js"
6 | )
7 |
8 | func main() {
9 | }
10 |
11 | //export add
12 | func add(a, b int) int {
13 | return a + b
14 | }
15 |
16 | //export update
17 | func update() {
18 | document := js.Global().Get("document")
19 | aStr := document.Call("getElementById", "a").Get("value").String()
20 | bStr := document.Call("getElementById", "b").Get("value").String()
21 | a, _ := strconv.Atoi(aStr)
22 | b, _ := strconv.Atoi(bStr)
23 | result := add(a, b)
24 | document.Call("getElementById", "result").Set("value", result)
25 | }
26 |
--------------------------------------------------------------------------------
/cgo/testdata/basic.out.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "unsafe"
4 |
5 | var _ unsafe.Pointer
6 |
7 | type C.int16_t = int16
8 | type C.int32_t = int32
9 | type C.int64_t = int64
10 | type C.int8_t = int8
11 | type C.uint16_t = uint16
12 | type C.uint32_t = uint32
13 | type C.uint64_t = uint64
14 | type C.uint8_t = uint8
15 | type C.uintptr_t = uintptr
16 | type C.char uint8
17 | type C.int int32
18 | type C.long int32
19 | type C.longlong int64
20 | type C.schar int8
21 | type C.short int16
22 | type C.uchar uint8
23 | type C.uint uint32
24 | type C.ulong uint32
25 | type C.ulonglong uint64
26 | type C.ushort uint16
27 |
--------------------------------------------------------------------------------
/targets/digispark.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["avr"],
3 | "llvm-target": "avr-atmel-none",
4 | "cpu": "attiny85",
5 | "build-tags": ["digispark", "attiny85", "attiny", "avr2", "avr25"],
6 | "cflags": [
7 | "-mmcu=attiny85"
8 | ],
9 | "ldflags": [
10 | "-mmcu=avr25",
11 | "-Wl,--defsym=_bootloader_size=2180",
12 | "-Wl,--defsym=_stack_size=128"
13 | ],
14 | "linkerscript": "src/device/avr/attiny85.ld",
15 | "extra-files": [
16 | "targets/avr.S",
17 | "src/device/avr/attiny85.s"
18 | ],
19 | "flash-command": "micronucleus --run {hex}",
20 | "emulator": ["simavr", "-m", "attiny85", "-f", "16000000"]
21 | }
22 |
--------------------------------------------------------------------------------
/src/runtime/scheduler_any.go:
--------------------------------------------------------------------------------
1 | // +build !scheduler.none
2 |
3 | package runtime
4 |
5 | import "internal/task"
6 |
7 | // Pause the current task for a given time.
8 | //go:linkname sleep time.Sleep
9 | func sleep(duration int64) {
10 | addSleepTask(task.Current(), duration)
11 | task.Pause()
12 | }
13 |
14 | // run is called by the program entry point to execute the go program.
15 | // With a scheduler, init and the main function are invoked in a goroutine before starting the scheduler.
16 | func run() {
17 | initHeap()
18 | go func() {
19 | initAll()
20 | postinit()
21 | callMain()
22 | }()
23 | scheduler()
24 | }
25 |
--------------------------------------------------------------------------------
/targets/atmega1284p.json:
--------------------------------------------------------------------------------
1 | {
2 | "inherits": ["avr"],
3 | "llvm-target": "avr-atmel-none",
4 | "cpu": "atmega1284p",
5 | "build-tags": ["atmega1284p", "atmega"],
6 | "cflags": [
7 | "-mmcu=atmega1284p"
8 | ],
9 | "ldflags": [
10 | "-mmcu=avr51",
11 | "-Wl,--defsym=_bootloader_size=0",
12 | "-Wl,--defsym=_stack_size=512"
13 | ],
14 | "linkerscript": "src/device/avr/atmega1284p.ld",
15 | "extra-files": [
16 | "targets/avr.S",
17 | "src/device/avr/atmega1284p.s"
18 | ],
19 | "emulator": ["simavr", "-m", "atmega1284p", "-f", "20000000"]
20 | }
21 |
--------------------------------------------------------------------------------
/src/examples/i2s/i2s.go:
--------------------------------------------------------------------------------
1 | // Example using the i2s hardware interface on the Adafruit Circuit Playground Express
2 | // to read data from the onboard MEMS microphone.
3 | //
4 | package main
5 |
6 | import (
7 | "machine"
8 | )
9 |
10 | func main() {
11 | machine.I2S0.Configure(machine.I2SConfig{
12 | Mode: machine.I2SModePDM,
13 | ClockSource: machine.I2SClockSourceExternal,
14 | Stereo: true,
15 | })
16 |
17 | data := make([]uint32, 64)
18 |
19 | for {
20 | // get the next group of samples
21 | machine.I2S0.Read(data)
22 |
23 | println("data", data[0], data[1], data[2], data[4], "...")
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/testing/benchmark.go:
--------------------------------------------------------------------------------
1 | // Copyright 2009 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 | //
5 | // This file has been modified for use by the TinyGo compiler.
6 |
7 | package testing
8 |
9 | // B is a type passed to Benchmark functions to manage benchmark timing and to
10 | // specify the number of iterations to run.
11 | //
12 | // TODO: Implement benchmarks. This struct allows test files containing
13 | // benchmarks to compile and run, but will not run the benchmarks themselves.
14 | type B struct {
15 | common
16 | N int
17 | }
18 |
--------------------------------------------------------------------------------
/cgo/testdata/flags.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | /*
4 | // this name doesn't exist
5 | #cgo NOFLAGS: -foo
6 |
7 | // unknown flag
8 | #cgo CFLAGS: -fdoes-not-exist -DNOTDEFINED
9 |
10 | #cgo CFLAGS: -DFOO
11 |
12 | #cgo CFLAGS: -Iinclude
13 | #include "foo.h"
14 |
15 | #if defined(FOO)
16 | #define BAR 3
17 | #else
18 | #define BAR 5
19 | #endif
20 |
21 | #if defined(NOTDEFINED)
22 | #warning flag must not be defined
23 | #endif
24 |
25 | // Check Compiler flags
26 | #cgo LDFLAGS: -lc
27 |
28 | // This flag is not valid ldflags
29 | #cgo LDFLAGS: -does-not-exists
30 |
31 | */
32 | import "C"
33 |
34 | var (
35 | _ = C.BAR
36 | _ = C.FOO_H
37 | )
38 |
--------------------------------------------------------------------------------
/compileopts/options.go:
--------------------------------------------------------------------------------
1 | package compileopts
2 |
3 | // Options contains extra options to give to the compiler. These options are
4 | // usually passed from the command line.
5 | type Options struct {
6 | Target string
7 | Opt string
8 | GC string
9 | PanicStrategy string
10 | Scheduler string
11 | PrintIR bool
12 | DumpSSA bool
13 | VerifyIR bool
14 | Debug bool
15 | PrintSizes string
16 | CFlags []string
17 | LDFlags []string
18 | Tags string
19 | WasmAbi string
20 | HeapSize int64
21 | TestConfig TestConfig
22 | Programmer string
23 | }
24 |
--------------------------------------------------------------------------------
/src/syscall/str.go:
--------------------------------------------------------------------------------
1 | // Copyright 2009 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package syscall
6 |
7 | func itoa(val int) string { // do it here rather than with fmt to avoid dependency
8 | if val < 0 {
9 | return "-" + uitoa(uint(-val))
10 | }
11 | return uitoa(uint(val))
12 | }
13 |
14 | func uitoa(val uint) string {
15 | var buf [32]byte // big enough for int64
16 | i := len(buf) - 1
17 | for val >= 10 {
18 | buf[i] = byte(val%10 + '0')
19 | i--
20 | val /= 10
21 | }
22 | buf[i] = byte(val + '0')
23 | return string(buf[i:])
24 | }
25 |
--------------------------------------------------------------------------------
/cgo/testdata/const.out.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "unsafe"
4 |
5 | var _ unsafe.Pointer
6 |
7 | const C.bar = C.foo
8 | const C.foo = 3
9 |
10 | type C.int16_t = int16
11 | type C.int32_t = int32
12 | type C.int64_t = int64
13 | type C.int8_t = int8
14 | type C.uint16_t = uint16
15 | type C.uint32_t = uint32
16 | type C.uint64_t = uint64
17 | type C.uint8_t = uint8
18 | type C.uintptr_t = uintptr
19 | type C.char uint8
20 | type C.int int32
21 | type C.long int32
22 | type C.longlong int64
23 | type C.schar int8
24 | type C.short int16
25 | type C.uchar uint8
26 | type C.uint uint32
27 | type C.ulong uint32
28 | type C.ulonglong uint64
29 | type C.ushort uint16
30 |
--------------------------------------------------------------------------------
/testdata/alias.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | type x struct{}
4 |
5 | func (x x) name() string {
6 | return "x"
7 | }
8 |
9 | type y = x
10 |
11 | type a struct {
12 | n int
13 | }
14 |
15 | func (a a) fruit() string {
16 | return "apple"
17 | }
18 |
19 | type b = a
20 |
21 | type fruit interface {
22 | fruit() string
23 | }
24 |
25 | type f = fruit
26 |
27 | func main() {
28 | // test a basic alias
29 | println(y{}.name())
30 |
31 | // test using a type alias value as an interface
32 | var v f = b{}
33 | println(v.fruit())
34 |
35 | // test comparing an alias interface with the referred-to type
36 | println(a{} == b{})
37 | println(a{2} == b{3})
38 | }
39 |
--------------------------------------------------------------------------------
/src/examples/adc/adc.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "machine"
5 | "time"
6 | )
7 |
8 | // This example assumes that an analog sensor such as a rotary dial is connected to pin ADC0.
9 | // When the dial is turned past the midway point, the built-in LED will light up.
10 |
11 | func main() {
12 | machine.InitADC()
13 |
14 | led := machine.LED
15 | led.Configure(machine.PinConfig{Mode: machine.PinOutput})
16 |
17 | sensor := machine.ADC{machine.ADC2}
18 | sensor.Configure()
19 |
20 | for {
21 | val := sensor.Get()
22 | if val < 0x8000 {
23 | led.Low()
24 | } else {
25 | led.High()
26 | }
27 | time.Sleep(time.Millisecond * 100)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/CONTRIBUTORS:
--------------------------------------------------------------------------------
1 | # This is the official list of TinyGo authors for copyright purposes.
2 | #
3 | # This file is not actively maintained.
4 | # To be included, send a change adding the individual or
5 | # company who owns a contribution's copyright.
6 | #
7 | # Names should be added to this file as one of
8 | # Organization's name
9 | # Individual's name
10 | # Individual's name
11 | #
12 | # Please keep the list sorted.
13 |
14 | Ayke van Laethem
15 | Daniel Esteban
16 | Loon, LLC.
17 | Ron Evans
18 | Jaden Weiss
19 |
--------------------------------------------------------------------------------
/src/examples/wasm/callback/wasm.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const WASM_URL = 'wasm.wasm';
4 |
5 | var wasm;
6 |
7 | function init() {
8 | const go = new Go();
9 | if ('instantiateStreaming' in WebAssembly) {
10 | WebAssembly.instantiateStreaming(fetch(WASM_URL), go.importObject).then(function (obj) {
11 | wasm = obj.instance;
12 | go.run(wasm);
13 | })
14 | } else {
15 | fetch(WASM_URL).then(resp =>
16 | resp.arrayBuffer()
17 | ).then(bytes =>
18 | WebAssembly.instantiate(bytes, go.importObject).then(function (obj) {
19 | wasm = obj.instance;
20 | go.run(wasm);
21 | })
22 | )
23 | }
24 | }
25 |
26 | init();
27 |
--------------------------------------------------------------------------------
/src/machine/board_fe310.go:
--------------------------------------------------------------------------------
1 | // +build hifive1b
2 |
3 | package machine
4 |
5 | const (
6 | P00 Pin = 0
7 | P01 Pin = 1
8 | P02 Pin = 2
9 | P03 Pin = 3
10 | P04 Pin = 4
11 | P05 Pin = 5
12 | P06 Pin = 6
13 | P07 Pin = 7
14 | P08 Pin = 8
15 | P09 Pin = 9
16 | P10 Pin = 10
17 | P11 Pin = 11
18 | P12 Pin = 12
19 | P13 Pin = 13
20 | P14 Pin = 14
21 | P15 Pin = 15
22 | P16 Pin = 16
23 | P17 Pin = 17
24 | P18 Pin = 18
25 | P19 Pin = 19
26 | P20 Pin = 20
27 | P21 Pin = 21
28 | P22 Pin = 22
29 | P23 Pin = 23
30 | P24 Pin = 24
31 | P25 Pin = 25
32 | P26 Pin = 26
33 | P27 Pin = 27
34 | P28 Pin = 28
35 | P29 Pin = 29
36 | P30 Pin = 30
37 | P31 Pin = 31
38 | )
39 |
--------------------------------------------------------------------------------
/src/runtime/scheduler_none.go:
--------------------------------------------------------------------------------
1 | // +build scheduler.none
2 |
3 | package runtime
4 |
5 | //go:linkname sleep time.Sleep
6 | func sleep(duration int64) {
7 | sleepTicks(timeUnit(duration / tickMicros))
8 | }
9 |
10 | // getSystemStackPointer returns the current stack pointer of the system stack.
11 | // This is always the current stack pointer.
12 | func getSystemStackPointer() uintptr {
13 | return getCurrentStackPointer()
14 | }
15 |
16 | // run is called by the program entry point to execute the go program.
17 | // With the "none" scheduler, init and the main function are invoked directly.
18 | func run() {
19 | initHeap()
20 | initAll()
21 | postinit()
22 | callMain()
23 | }
24 |
--------------------------------------------------------------------------------
/src/runtime/interrupt/interrupt_sifive.go:
--------------------------------------------------------------------------------
1 | // +build sifive
2 |
3 | package interrupt
4 |
5 | import "device/sifive"
6 |
7 | // Enable enables this interrupt. Right after calling this function, the
8 | // interrupt may be invoked if it was already pending.
9 | func (irq Interrupt) Enable() {
10 | sifive.PLIC.ENABLE[irq.num/32].SetBits(1 << (uint(irq.num) % 32))
11 | }
12 |
13 | // SetPriority sets the interrupt priority for this interrupt. A higher priority
14 | // number means a higher priority (unlike Cortex-M). Priority 0 effectively
15 | // disables the interrupt.
16 | func (irq Interrupt) SetPriority(priority uint8) {
17 | sifive.PLIC.PRIORITY[irq.num].Set(uint32(priority))
18 | }
19 |
--------------------------------------------------------------------------------
/src/examples/wasm/callback/wasm.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "strconv"
5 | "syscall/js"
6 | )
7 |
8 | var a, b int
9 |
10 | func main() {
11 | document := js.Global().Get("document")
12 | document.Call("getElementById", "a").Set("oninput", updater(&a))
13 | document.Call("getElementById", "b").Set("oninput", updater(&b))
14 | update()
15 | }
16 |
17 | func updater(n *int) js.Func {
18 | return js.FuncOf(func(this js.Value, args []js.Value) interface{} {
19 | *n, _ = strconv.Atoi(this.Get("value").String())
20 | update()
21 | return nil
22 | })
23 | }
24 |
25 | func update() {
26 | js.Global().Get("document").Call("getElementById", "result").Set("value", a+b)
27 | }
28 |
--------------------------------------------------------------------------------
/src/runtime/atomic.go:
--------------------------------------------------------------------------------
1 | package runtime
2 |
3 | // This file contains implementations for the sync/atomic package.
4 |
5 | // All implementations assume there are no goroutines, threads or interrupts.
6 |
7 | //go:linkname loadUint64 sync/atomic.LoadUint64
8 | func loadUint64(addr *uint64) uint64 {
9 | return *addr
10 | }
11 |
12 | //go:linkname storeUint32 sync/atomic.StoreUint32
13 | func storeUint32(addr *uint32, val uint32) {
14 | *addr = val
15 | }
16 |
17 | //go:linkname compareAndSwapUint64 sync/atomic.CompareAndSwapUint64
18 | func compareAndSwapUint64(addr *uint64, old, new uint64) bool {
19 | if *addr == old {
20 | *addr = new
21 | return true
22 | }
23 | return false
24 | }
25 |
--------------------------------------------------------------------------------
/targets/cortex-m.json:
--------------------------------------------------------------------------------
1 | {
2 | "build-tags": ["cortexm", "baremetal", "linux", "arm"],
3 | "goos": "linux",
4 | "goarch": "arm",
5 | "compiler": "clang",
6 | "gc": "conservative",
7 | "scheduler": "tasks",
8 | "linker": "ld.lld",
9 | "rtlib": "compiler-rt",
10 | "libc": "picolibc",
11 | "cflags": [
12 | "-Oz",
13 | "-mthumb",
14 | "-Werror",
15 | "-fshort-enums",
16 | "-fomit-frame-pointer",
17 | "-fno-exceptions", "-fno-unwind-tables",
18 | "-ffunction-sections", "-fdata-sections"
19 | ],
20 | "ldflags": [
21 | "--gc-sections"
22 | ],
23 | "extra-files": [
24 | "src/device/arm/cortexm.s",
25 | "src/runtime/scheduler_cortexm.S"
26 | ],
27 | "gdb": "gdb-multiarch"
28 | }
29 |
--------------------------------------------------------------------------------
/src/runtime/arch_wasm.go:
--------------------------------------------------------------------------------
1 | // +build wasm
2 |
3 | package runtime
4 |
5 | import (
6 | "unsafe"
7 | )
8 |
9 | const GOARCH = "wasm"
10 |
11 | // The bitness of the CPU (e.g. 8, 32, 64).
12 | const TargetBits = 32
13 |
14 | //go:extern __heap_base
15 | var heapStartSymbol [0]byte
16 |
17 | //export llvm.wasm.memory.size.i32
18 | func wasm_memory_size(index int32) int32
19 |
20 | var (
21 | heapStart = uintptr(unsafe.Pointer(&heapStartSymbol))
22 | heapEnd = uintptr(wasm_memory_size(0) * wasmPageSize)
23 | )
24 |
25 | const wasmPageSize = 64 * 1024
26 |
27 | // Align on word boundary.
28 | func align(ptr uintptr) uintptr {
29 | return (ptr + 3) &^ 3
30 | }
31 |
32 | func getCurrentStackPointer() uintptr
33 |
--------------------------------------------------------------------------------
/src/device/avr/avr.go:
--------------------------------------------------------------------------------
1 | package avr
2 |
3 | // Run the given assembly code. The code will be marked as having side effects,
4 | // as it doesn't produce output and thus would normally be eliminated by the
5 | // optimizer.
6 | func Asm(asm string)
7 |
8 | // Run the given inline assembly. The code will be marked as having side
9 | // effects, as it would otherwise be optimized away. The inline assembly string
10 | // recognizes template values in the form {name}, like so:
11 | //
12 | // avr.AsmFull(
13 | // "str {value}, {result}",
14 | // map[string]interface{}{
15 | // "value": 1
16 | // "result": &dest,
17 | // })
18 | func AsmFull(asm string, regs map[string]interface{})
19 |
--------------------------------------------------------------------------------
/testdata/binop.txt:
--------------------------------------------------------------------------------
1 | string equality
2 | true
3 | false
4 | false
5 | true
6 | string inequality
7 | false
8 | true
9 | false
10 | true
11 | false
12 | true
13 | false
14 | true
15 | false
16 | true
17 | false
18 | true
19 | true
20 | false
21 | false
22 | true
23 | array equality
24 | true
25 | false
26 | false
27 | false
28 | false
29 | true
30 | struct equality
31 | true
32 | false
33 | false
34 | false
35 | false
36 | true
37 | true
38 | true
39 | blank fields in structs
40 | true
41 | false
42 | true
43 | false
44 | complex numbers
45 | true
46 | false
47 | false
48 | false
49 | true
50 | true
51 | false
52 | false
53 | false
54 | true
55 | true
56 | true
57 | shifts
58 | true
59 | true
60 | true
61 | true
62 | true
63 | true
64 | true
65 |
--------------------------------------------------------------------------------
/src/runtime/scheduler_tinygoriscv.S:
--------------------------------------------------------------------------------
1 | .section .text.tinygo_scanCurrentStack
2 | .global tinygo_scanCurrentStack
3 | .type tinygo_scanCurrentStack, %function
4 | tinygo_scanCurrentStack:
5 | // Push callee-saved registers onto the stack.
6 | addi sp, sp, -64
7 | sw ra, 60(sp)
8 | sw s11, 56(sp)
9 | sw s10, 52(sp)
10 | sw s9, 48(sp)
11 | sw s8, 44(sp)
12 | sw s7, 40(sp)
13 | sw s6, 36(sp)
14 | sw s5, 32(sp)
15 | sw s4, 28(sp)
16 | sw s3, 24(sp)
17 | sw s2, 20(sp)
18 | sw s1, 16(sp)
19 | sw s0, 12(sp)
20 |
21 | // Scan the stack.
22 | mv a0, sp
23 | call tinygo_scanstack
24 |
25 | // Restore stack state.
26 | addi sp, sp, 64
27 |
28 | // Return to the caller.
29 | ret
30 |
--------------------------------------------------------------------------------
/targets/riscv.json:
--------------------------------------------------------------------------------
1 | {
2 | "llvm-target": "riscv32--none",
3 | "goos": "linux",
4 | "goarch": "arm",
5 | "build-tags": ["tinygo.riscv", "baremetal", "linux", "arm"],
6 | "gc": "conservative",
7 | "compiler": "clang",
8 | "linker": "ld.lld",
9 | "rtlib": "compiler-rt",
10 | "libc": "picolibc",
11 | "cflags": [
12 | "--target=riscv32--none",
13 | "-march=rv32imac",
14 | "-mabi=ilp32",
15 | "-Os",
16 | "-Werror",
17 | "-fno-exceptions", "-fno-unwind-tables",
18 | "-ffunction-sections", "-fdata-sections"
19 | ],
20 | "ldflags": [
21 | "-melf32lriscv",
22 | "--gc-sections"
23 | ],
24 | "extra-files": [
25 | "src/device/riscv/start.S",
26 | "src/runtime/scheduler_tinygoriscv.S"
27 | ],
28 | "gdb": "riscv64-unknown-elf-gdb"
29 | }
30 |
--------------------------------------------------------------------------------
/src/examples/microbit-blink/microbit-blink.go:
--------------------------------------------------------------------------------
1 | // blink program for the BBC micro:bit
2 | package main
3 |
4 | import (
5 | "machine"
6 | "time"
7 | )
8 |
9 | // The LED matrix in the micro:bit is a multiplexed display: https://en.wikipedia.org/wiki/Multiplexed_display
10 | // Driver for easier control: https://github.com/tinygo-org/drivers/tree/master/microbitmatrix
11 | func main() {
12 | ledrow := machine.LED_ROW_1
13 | ledrow.Configure(machine.PinConfig{Mode: machine.PinOutput})
14 | ledcol := machine.LED_COL_1
15 | ledcol.Configure(machine.PinConfig{Mode: machine.PinOutput})
16 | ledcol.Low()
17 | for {
18 | ledrow.Low()
19 | time.Sleep(time.Millisecond * 500)
20 |
21 | ledrow.High()
22 | time.Sleep(time.Millisecond * 500)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/machine/machine_attiny.go:
--------------------------------------------------------------------------------
1 | // +build avr,attiny
2 |
3 | package machine
4 |
5 | // UART on the AVR is a dummy implementation. UART has not been implemented for ATtiny
6 | // devices.
7 | type UART struct {
8 | Buffer *RingBuffer
9 | }
10 |
11 | // Configure is a dummy implementation. UART has not been implemented for ATtiny
12 | // devices.
13 | func (uart UART) Configure(config UARTConfig) {
14 | }
15 |
16 | // WriteByte is a dummy implementation. UART has not been implemented for ATtiny
17 | // devices.
18 | func (uart UART) WriteByte(c byte) error {
19 | return nil
20 | }
21 |
22 | // Tx is a dummy implementation. I2C has not been implemented for ATtiny
23 | // devices.
24 | func (i2c I2C) Tx(addr uint16, w, r []byte) error {
25 | return nil
26 | }
27 |
--------------------------------------------------------------------------------
/src/device/nrf/README.markdown:
--------------------------------------------------------------------------------
1 | # Generated Go files for Nordic Semiconductors devices
2 |
3 | In this directory, Go register description files are stored that are generated
4 | by `gen-device.py` from .svd files provided by Nordic. See the SVD files [over
5 | here](https://github.com/NordicSemiconductor/nrfx/tree/master/mdk).
6 |
7 | The original files are provided under the 3-clause BSD license, see [this
8 | post](https://devzone.nordicsemi.com/b/blog/posts/introducing-nordics-new-software-licensing-schemes)
9 | for details. As the generated files transform most of the original file, I think
10 | they should be licensed under the same license as the original files. Generated
11 | files will contain the license statement that is included in the original SVD
12 | files.
13 |
--------------------------------------------------------------------------------
/cgo/testdata/errors.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | /*
4 | #warning some warning
5 |
6 | typedef struct {
7 | int x;
8 | int y;
9 | } point_t;
10 |
11 | typedef someType noType; // undefined type
12 |
13 | #define SOME_CONST_1 5) // invalid const syntax
14 | #define SOME_CONST_2 6) // const not used (so no error)
15 | #define SOME_CONST_3 1234 // const too large for byte
16 | */
17 | import "C"
18 |
19 | // Make sure that errors for the following lines won't change with future
20 | // additions to the CGo preamble.
21 | //line errors.go:100
22 | var (
23 | // constant too large
24 | _ C.uint8_t = 2 << 10
25 |
26 | // z member does not exist
27 | _ C.point_t = C.point_t{z: 3}
28 |
29 | // constant has syntax error
30 | _ = C.SOME_CONST_1
31 |
32 | _ byte = C.SOME_CONST_3
33 | )
34 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "lib/nrfx"]
2 | path = lib/nrfx
3 | url = https://github.com/NordicSemiconductor/nrfx.git
4 | [submodule "lib/CMSIS"]
5 | path = lib/CMSIS
6 | url = https://github.com/ARM-software/CMSIS.git
7 | [submodule "lib/avr"]
8 | path = lib/avr
9 | url = https://github.com/avr-rust/avr-mcu.git
10 | [submodule "lib/cmsis-svd"]
11 | path = lib/cmsis-svd
12 | url = https://github.com/posborne/cmsis-svd
13 | [submodule "lib/compiler-rt"]
14 | path = lib/compiler-rt
15 | url = https://github.com/llvm-mirror/compiler-rt.git
16 | branch = release_80
17 | [submodule "lib/wasi-libc"]
18 | path = lib/wasi-libc
19 | url = https://github.com/CraneStation/wasi-libc
20 | [submodule "lib/picolibc"]
21 | path = lib/picolibc
22 | url = https://github.com/keith-packard/picolibc.git
23 |
--------------------------------------------------------------------------------
/src/runtime/interrupt/interrupt_cortexm.go:
--------------------------------------------------------------------------------
1 | // +build cortexm
2 |
3 | package interrupt
4 |
5 | import (
6 | "device/arm"
7 | )
8 |
9 | // Enable enables this interrupt. Right after calling this function, the
10 | // interrupt may be invoked if it was already pending.
11 | func (irq Interrupt) Enable() {
12 | arm.EnableIRQ(uint32(irq.num))
13 | }
14 |
15 | // SetPriority sets the interrupt priority for this interrupt. A lower number
16 | // means a higher priority. Additionally, most hardware doesn't implement all
17 | // priority bits (only the uppoer bits).
18 | //
19 | // Examples: 0xff (lowest priority), 0xc0 (low priority), 0x00 (highest possible
20 | // priority).
21 | func (irq Interrupt) SetPriority(priority uint8) {
22 | arm.SetPriority(uint32(irq.num), uint32(priority))
23 | }
24 |
--------------------------------------------------------------------------------
/transform/testdata/wasm-abi.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
2 | target triple = "wasm32-unknown-unknown-wasm"
3 |
4 | declare i64 @externalCall(i8*, i32, i64)
5 |
6 | define internal i64 @testCall(i8* %ptr, i32 %len, i64 %foo) {
7 | %val = call i64 @externalCall(i8* %ptr, i32 %len, i64 %foo)
8 | ret i64 %val
9 | }
10 |
11 | define internal i64 @testCallNonEntry(i8* %ptr, i32 %len) {
12 | entry:
13 | br label %bb1
14 |
15 | bb1:
16 | %val = call i64 @externalCall(i8* %ptr, i32 %len, i64 3)
17 | ret i64 %val
18 | }
19 |
20 | define void @exportedFunction(i64 %foo) {
21 | %unused = shl i64 %foo, 1
22 | ret void
23 | }
24 |
25 | define internal void @callExportedFunction(i64 %foo) {
26 | call void @exportedFunction(i64 %foo)
27 | ret void
28 | }
29 |
--------------------------------------------------------------------------------
/transform/testdata/panic.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
2 | target triple = "armv7m-none-eabi"
3 |
4 | @"runtime.lookupPanic$string" = constant [18 x i8] c"index out of range"
5 |
6 | declare void @runtime.runtimePanic(i8*, i32)
7 |
8 | declare void @runtime._panic(i32, i8*)
9 |
10 | define void @runtime.lookupPanic() {
11 | call void @runtime.runtimePanic(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @"runtime.lookupPanic$string", i64 0, i64 0), i32 18)
12 | ret void
13 | }
14 |
15 | ; This is equivalent to the following code:
16 | ; func someFunc(x interface{}) {
17 | ; panic(x)
18 | ; }
19 | define void @someFunc(i32 %typecode, i8* %value) {
20 | call void @runtime._panic(i32 %typecode, i8* %value)
21 | unreachable
22 | }
23 |
--------------------------------------------------------------------------------
/src/runtime/gc_none.go:
--------------------------------------------------------------------------------
1 | // +build gc.none
2 |
3 | package runtime
4 |
5 | // This GC strategy provides no memory allocation at all. It can be useful to
6 | // detect where in a program memory is allocated, or to combine this runtime
7 | // with a separate (external) garbage collector.
8 |
9 | import (
10 | "unsafe"
11 | )
12 |
13 | func alloc(size uintptr) unsafe.Pointer
14 |
15 | func free(ptr unsafe.Pointer) {
16 | // Nothing to free when nothing gets allocated.
17 | }
18 |
19 | func GC() {
20 | // Unimplemented.
21 | }
22 |
23 | func KeepAlive(x interface{}) {
24 | // Unimplemented. Only required with SetFinalizer().
25 | }
26 |
27 | func SetFinalizer(obj interface{}, finalizer interface{}) {
28 | // Unimplemented.
29 | }
30 |
31 | func initHeap() {
32 | // Nothing to initialize.
33 | }
34 |
--------------------------------------------------------------------------------
/transform/transform.go:
--------------------------------------------------------------------------------
1 | // Package transform contains transformation passes for the TinyGo compiler.
2 | // These transformation passes may be optimization passes or lowering passes.
3 | //
4 | // Optimization passes transform the IR in such a way that they increase the
5 | // performance of the generated code and/or help the LLVM optimizer better do
6 | // its job by simplifying the IR. This usually means that certain
7 | // TinyGo-specific runtime calls are removed or replaced with something simpler
8 | // if that is a valid operation.
9 | //
10 | // Lowering passes are usually required to run. One example is the interface
11 | // lowering pass, which replaces stub runtime calls to get an interface method
12 | // with the method implementation (either a direct call or a thunk).
13 | package transform
14 |
--------------------------------------------------------------------------------
/src/machine/board_x9pro.go:
--------------------------------------------------------------------------------
1 | // +build x9pro
2 |
3 | package machine
4 |
5 | // https://hackaday.io/project/144350-hacking-wearables-for-mental-health-and-more/details
6 | const (
7 | LED Pin = 4 // HR LED pin
8 | UART_TX_PIN Pin = NoPin
9 | UART_RX_PIN Pin = NoPin
10 | SCL_PIN Pin = NoPin
11 | SDA_PIN Pin = NoPin
12 | SPI0_SCK_PIN Pin = 18
13 | SPI0_MISO_PIN Pin = 19
14 | SPI0_MOSI_PIN Pin = 20
15 | )
16 |
17 | // LCD pins.
18 | const (
19 | OLED_CS Pin = 15 // chip select
20 | OLED_RES Pin = 14 // reset pin
21 | OLED_DC Pin = 13 // data/command
22 | OLED_SCK Pin = 12 // SPI clock
23 | OLED_MOSI Pin = 11 // SPI MOSI (master-out, slave-in)
24 | OLED_LED_POW Pin = 16
25 | OLED_IC_POW Pin = 17
26 | )
27 |
28 | const HasLowFrequencyCrystal = true
29 |
--------------------------------------------------------------------------------
/src/runtime/poll.go:
--------------------------------------------------------------------------------
1 | package runtime
2 |
3 | // This file implements stub functions for internal/poll.
4 |
5 | //go:linkname poll_runtime_pollServerInit internal/poll.runtime_pollServerInit
6 | func poll_runtime_pollServerInit() {
7 | panic("todo: runtime_pollServerInit")
8 | }
9 |
10 | //go:linkname poll_runtime_pollOpen internal/poll.runtime_pollOpen
11 | func poll_runtime_pollOpen(fd uintptr) (uintptr, int) {
12 | panic("todo: runtime_pollOpen")
13 | }
14 |
15 | //go:linkname poll_runtime_pollClose internal/poll.runtime_pollClose
16 | func poll_runtime_pollClose(ctx uintptr) {
17 | panic("todo: runtime_pollClose")
18 | }
19 |
20 | //go:linkname poll_runtime_pollUnblock internal/poll.runtime_pollUnblock
21 | func poll_runtime_pollUnblock(ctx uintptr) {
22 | panic("todo: runtime_pollUnblock")
23 | }
24 |
--------------------------------------------------------------------------------
/src/machine/machine_attiny85.go:
--------------------------------------------------------------------------------
1 | // +build attiny85
2 |
3 | package machine
4 |
5 | import (
6 | "device/avr"
7 | "runtime/volatile"
8 | )
9 |
10 | const (
11 | PB0 Pin = iota
12 | PB1
13 | PB2
14 | PB3
15 | PB4
16 | PB5
17 | )
18 |
19 | // Configure sets the pin to input or output.
20 | func (p Pin) Configure(config PinConfig) {
21 | if config.Mode == PinOutput { // set output bit
22 | avr.DDRB.SetBits(1 << uint8(p))
23 | } else { // configure input: clear output bit
24 | avr.DDRB.ClearBits(1 << uint8(p))
25 | }
26 | }
27 |
28 | func (p Pin) getPortMask() (*volatile.Register8, uint8) {
29 | return avr.PORTB, 1 << uint8(p)
30 | }
31 |
32 | // Get returns the current value of a GPIO pin.
33 | func (p Pin) Get() bool {
34 | val := avr.PINB.Get() & (1 << uint8(p))
35 | return (val > 0)
36 | }
37 |
--------------------------------------------------------------------------------
/src/os/file_unix.go:
--------------------------------------------------------------------------------
1 | // +build darwin linux,!baremetal freebsd,!baremetal
2 |
3 | package os
4 |
5 | import (
6 | "syscall"
7 | )
8 |
9 | // Read reads up to len(b) bytes from the File. It returns the number of bytes
10 | // read and any error encountered. At end of file, Read returns 0, io.EOF.
11 | func (f *File) Read(b []byte) (n int, err error) {
12 | return syscall.Read(int(f.fd), b)
13 | }
14 |
15 | // Write writes len(b) bytes to the File. It returns the number of bytes written
16 | // and an error, if any. Write returns a non-nil error when n != len(b).
17 | func (f *File) Write(b []byte) (n int, err error) {
18 | return syscall.Write(int(f.fd), b)
19 | }
20 |
21 | // Close closes the File, rendering it unusable for I/O.
22 | func (f *File) Close() error {
23 | return syscall.Close(int(f.fd))
24 | }
25 |
--------------------------------------------------------------------------------
/src/os/file_other.go:
--------------------------------------------------------------------------------
1 | // +build baremetal wasm
2 |
3 | package os
4 |
5 | import (
6 | _ "unsafe"
7 | )
8 |
9 | // Read is unsupported on this system.
10 | func (f *File) Read(b []byte) (n int, err error) {
11 | return 0, errUnsupported
12 | }
13 |
14 | // Write writes len(b) bytes to the output. It returns the number of bytes
15 | // written or an error if this file is not stdout or stderr.
16 | func (f *File) Write(b []byte) (n int, err error) {
17 | switch f.fd {
18 | case Stdout.fd, Stderr.fd:
19 | for _, c := range b {
20 | putchar(c)
21 | }
22 | return len(b), nil
23 | default:
24 | return 0, errUnsupported
25 | }
26 | }
27 |
28 | // Close is unsupported on this system.
29 | func (f *File) Close() error {
30 | return errUnsupported
31 | }
32 |
33 | //go:linkname putchar runtime.putchar
34 | func putchar(c byte)
35 |
--------------------------------------------------------------------------------
/testdata/channel.txt:
--------------------------------------------------------------------------------
1 | len, cap of channel: 0 0 false
2 | recv from open channel: 1 true
3 | received num: 2
4 | received num: 3
5 | slept
6 | received num: 4
7 | received num: 5
8 | received num: 6
9 | received num: 7
10 | received num: 8
11 | recv from closed channel: 0 false
12 | complex128: (+7.000000e+000+1.050000e+001i)
13 | sum of n: 149
14 | sum: 25
15 | sum: 29
16 | sum: 33
17 | sum(100): 4950
18 | deadlocking
19 | select no-op
20 | after no-op
21 | sum: 5
22 | did send one
23 | select one n: 0
24 | select n from chan: 55
25 | select n from closed chan: 0
26 | select send
27 | sum: 235
28 | non-concurrent channel recieve: 1
29 | non-concurrent channel recieve: 2
30 | closed buffered channel recieve: 3
31 | closed buffered channel recieve: 4
32 | closed buffered channel recieve: 0
33 | hybrid buffered channel recieve: 2
34 | blocking select sum: 3
35 |
--------------------------------------------------------------------------------
/src/internal/task/task_none.go:
--------------------------------------------------------------------------------
1 | // +build scheduler.none
2 |
3 | package task
4 |
5 | import "unsafe"
6 |
7 | //go:linkname runtimePanic runtime.runtimePanic
8 | func runtimePanic(str string)
9 |
10 | func Pause() {
11 | runtimePanic("scheduler is disabled")
12 | }
13 |
14 | func Current() *Task {
15 | runtimePanic("scheduler is disabled")
16 | return nil
17 | }
18 |
19 | //go:noinline
20 | func start(fn uintptr, args unsafe.Pointer) {
21 | // The compiler will error if this is reachable.
22 | runtimePanic("scheduler is disabled")
23 | }
24 |
25 | type state struct{}
26 |
27 | func (t *Task) Resume() {
28 | runtimePanic("scheduler is disabled")
29 | }
30 |
31 | // OnSystemStack returns whether the caller is running on the system stack.
32 | func OnSystemStack() bool {
33 | // This scheduler does not do any stack switching.
34 | return true
35 | }
36 |
--------------------------------------------------------------------------------
/transform/testdata/panic.out.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
2 | target triple = "armv7m-none-eabi"
3 |
4 | @"runtime.lookupPanic$string" = constant [18 x i8] c"index out of range"
5 |
6 | declare void @runtime.runtimePanic(i8*, i32)
7 |
8 | declare void @runtime._panic(i32, i8*)
9 |
10 | define void @runtime.lookupPanic() {
11 | call void @llvm.trap()
12 | call void @runtime.runtimePanic(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @"runtime.lookupPanic$string", i64 0, i64 0), i32 18)
13 | ret void
14 | }
15 |
16 | define void @someFunc(i32 %typecode, i8* %value) {
17 | call void @llvm.trap()
18 | call void @runtime._panic(i32 %typecode, i8* %value)
19 | unreachable
20 | }
21 |
22 | ; Function Attrs: cold noreturn nounwind
23 | declare void @llvm.trap() #0
24 |
25 | attributes #0 = { cold noreturn nounwind }
26 |
--------------------------------------------------------------------------------
/cgo/testdata/flags.out.go:
--------------------------------------------------------------------------------
1 | // CGo errors:
2 | // testdata/flags.go:5:7: invalid #cgo line: NOFLAGS
3 | // testdata/flags.go:8:13: invalid flag: -fdoes-not-exist
4 | // testdata/flags.go:29:14: invalid flag: -does-not-exists
5 |
6 | package main
7 |
8 | import "unsafe"
9 |
10 | var _ unsafe.Pointer
11 |
12 | const C.BAR = 3
13 | const C.FOO_H = 1
14 |
15 | type C.int16_t = int16
16 | type C.int32_t = int32
17 | type C.int64_t = int64
18 | type C.int8_t = int8
19 | type C.uint16_t = uint16
20 | type C.uint32_t = uint32
21 | type C.uint64_t = uint64
22 | type C.uint8_t = uint8
23 | type C.uintptr_t = uintptr
24 | type C.char uint8
25 | type C.int int32
26 | type C.long int32
27 | type C.longlong int64
28 | type C.schar int8
29 | type C.short int16
30 | type C.uchar uint8
31 | type C.uint uint32
32 | type C.ulong uint32
33 | type C.ulonglong uint64
34 | type C.ushort uint16
35 |
--------------------------------------------------------------------------------
/transform/testdata/stringtobytes.out.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2 | target triple = "x86_64--linux"
3 |
4 | @str = constant [6 x i8] c"foobar"
5 |
6 | declare { i8*, i64, i64 } @runtime.stringToBytes(i8*, i64)
7 |
8 | declare void @printSlice(i8* nocapture readonly, i64, i64)
9 |
10 | declare void @writeToSlice(i8* nocapture, i64, i64)
11 |
12 | define void @testReadOnly() {
13 | entry:
14 | call fastcc void @printSlice(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @str, i32 0, i32 0), i64 6, i64 6)
15 | ret void
16 | }
17 |
18 | define void @testReadWrite() {
19 | entry:
20 | %0 = call fastcc { i8*, i64, i64 } @runtime.stringToBytes(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @str, i32 0, i32 0), i64 6)
21 | %1 = extractvalue { i8*, i64, i64 } %0, 0
22 | call fastcc void @writeToSlice(i8* %1, i64 6, i64 6)
23 | ret void
24 | }
25 |
--------------------------------------------------------------------------------
/src/machine/board_pca10031.go:
--------------------------------------------------------------------------------
1 | // +build pca10031
2 |
3 | // pca10031 is a nrf51 based dongle, intended for use in wireless applications.
4 | //
5 | // https://infocenter.nordicsemi.com/pdf/nRF51_Dongle_UG_v1.0.pdf
6 | package machine
7 |
8 | // The pca10031 has a 32kHz crystal on board.
9 | const HasLowFrequencyCrystal = true
10 |
11 | // LED on the pca10031
12 | const (
13 | LED Pin = LED_RED
14 | LED1 Pin = LED_RED
15 | LED2 Pin = LED_GREEN
16 | LED3 Pin = LED_BLUE
17 | LED_RED Pin = 21
18 | LED_GREEN Pin = 22
19 | LED_BLUE Pin = 23
20 | )
21 |
22 | // UART pins
23 | const (
24 | UART_TX_PIN Pin = 9
25 | UART_RX_PIN Pin = 11
26 | )
27 |
28 | // I2C pins (disabled)
29 | const (
30 | SDA_PIN = NoPin
31 | SCL_PIN = NoPin
32 | )
33 |
34 | // SPI pins (unused)
35 | const (
36 | SPI0_SCK_PIN = NoPin
37 | SPI0_MOSI_PIN = NoPin
38 | SPI0_MISO_PIN = NoPin
39 | )
40 |
--------------------------------------------------------------------------------
/targets/gameboy-advance.json:
--------------------------------------------------------------------------------
1 | {
2 | "llvm-target": "arm4-none-eabi",
3 | "cpu": "arm7tdmi",
4 | "build-tags": ["gameboyadvance", "arm7tdmi", "baremetal", "linux", "arm"],
5 | "goos": "linux",
6 | "goarch": "arm",
7 | "compiler": "clang",
8 | "linker": "ld.lld",
9 | "rtlib": "compiler-rt",
10 | "libc": "picolibc",
11 | "cflags": [
12 | "-g",
13 | "--target=arm4-none-eabi",
14 | "-mcpu=arm7tdmi",
15 | "-Oz",
16 | "-Werror",
17 | "-fshort-enums",
18 | "-fomit-frame-pointer",
19 | "-Qunused-arguments",
20 | "-fno-exceptions", "-fno-unwind-tables",
21 | "-ffunction-sections", "-fdata-sections"
22 | ],
23 | "ldflags": [
24 | "--gc-sections"
25 | ],
26 | "linkerscript": "targets/gameboy-advance.ld",
27 | "extra-files": [
28 | "targets/gameboy-advance.s",
29 | "src/runtime/scheduler_gba.S"
30 | ],
31 | "gdb": "gdb-multiarch",
32 | "emulator": ["mgba", "-3"]
33 | }
34 |
--------------------------------------------------------------------------------
/src/runtime/string_count.go:
--------------------------------------------------------------------------------
1 | // +build amd64 arm,go1.13 arm64 ppc64le ppc64 s390x
2 |
3 | package runtime
4 |
5 | // This file implements the string counting functions used by the strings
6 | // package, for example. It must be reimplemented here as a replacement for the
7 | // Go stdlib asm implementations, but only when the asm implementations are used
8 | // (this varies by Go version).
9 | // Track this file for updates:
10 | // https://github.com/golang/go/blob/master/src/internal/bytealg/count_native.go
11 |
12 | // countString copies the implementation from
13 | // https://github.com/golang/go/blob/67f181bfd84dfd5942fe9a29d8a20c9ce5eb2fea/src/internal/bytealg/count_generic.go#L1
14 | //go:linkname countString internal/bytealg.CountString
15 | func countString(s string, c byte) int {
16 | n := 0
17 | for i := 0; i < len(s); i++ {
18 | if s[i] == c {
19 | n++
20 | }
21 | }
22 | return n
23 | }
24 |
--------------------------------------------------------------------------------
/src/examples/wasm/export/wasm.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const WASM_URL = 'wasm.wasm';
4 |
5 | var wasm;
6 |
7 | function updateResult() {
8 | wasm.exports.update();
9 | }
10 |
11 | function init() {
12 | document.querySelector('#a').oninput = updateResult;
13 | document.querySelector('#b').oninput = updateResult;
14 |
15 | const go = new Go();
16 | if ('instantiateStreaming' in WebAssembly) {
17 | WebAssembly.instantiateStreaming(fetch(WASM_URL), go.importObject).then(function (obj) {
18 | wasm = obj.instance;
19 | go.run(wasm);
20 | updateResult();
21 | })
22 | } else {
23 | fetch(WASM_URL).then(resp =>
24 | resp.arrayBuffer()
25 | ).then(bytes =>
26 | WebAssembly.instantiate(bytes, go.importObject).then(function (obj) {
27 | wasm = obj.instance;
28 | go.run(wasm);
29 | updateResult();
30 | })
31 | )
32 | }
33 | }
34 |
35 | init();
36 |
--------------------------------------------------------------------------------
/src/runtime/runtime_tinygoriscv.go:
--------------------------------------------------------------------------------
1 | // +build tinygo.riscv
2 |
3 | package runtime
4 |
5 | import "unsafe"
6 |
7 | //go:extern _sbss
8 | var _sbss [0]byte
9 |
10 | //go:extern _ebss
11 | var _ebss [0]byte
12 |
13 | //go:extern _sdata
14 | var _sdata [0]byte
15 |
16 | //go:extern _sidata
17 | var _sidata [0]byte
18 |
19 | //go:extern _edata
20 | var _edata [0]byte
21 |
22 | func preinit() {
23 | // Initialize .bss: zero-initialized global variables.
24 | ptr := unsafe.Pointer(&_sbss)
25 | for ptr != unsafe.Pointer(&_ebss) {
26 | *(*uint32)(ptr) = 0
27 | ptr = unsafe.Pointer(uintptr(ptr) + 4)
28 | }
29 |
30 | // Initialize .data: global variables initialized from flash.
31 | src := unsafe.Pointer(&_sidata)
32 | dst := unsafe.Pointer(&_sdata)
33 | for dst != unsafe.Pointer(&_edata) {
34 | *(*uint32)(dst) = *(*uint32)(src)
35 | dst = unsafe.Pointer(uintptr(dst) + 4)
36 | src = unsafe.Pointer(uintptr(src) + 4)
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/machine/board_nrf52840-mdk.go:
--------------------------------------------------------------------------------
1 | // +build nrf52840_mdk
2 |
3 | package machine
4 |
5 | const HasLowFrequencyCrystal = true
6 |
7 | // LEDs on the nrf52840-mdk (nRF52840 dev board)
8 | const (
9 | LED Pin = LED_GREEN
10 | LED_GREEN Pin = 22
11 | LED_RED Pin = 23
12 | LED_BLUE Pin = 24
13 | )
14 |
15 | // UART pins
16 | const (
17 | UART_TX_PIN Pin = 20
18 | UART_RX_PIN Pin = 19
19 | )
20 |
21 | // UART0 is the USB device
22 | var (
23 | UART0 = USB
24 | )
25 |
26 | // I2C pins (unused)
27 | const (
28 | SDA_PIN = NoPin
29 | SCL_PIN = NoPin
30 | )
31 |
32 | // SPI pins (unused)
33 | const (
34 | SPI0_SCK_PIN = NoPin
35 | SPI0_MOSI_PIN = NoPin
36 | SPI0_MISO_PIN = NoPin
37 | )
38 |
39 | // USB CDC identifiers
40 | const (
41 | usb_STRING_PRODUCT = "Makerdiary nRF52840 MDK USB Dongle"
42 | usb_STRING_MANUFACTURER = "Makerdiary"
43 | )
44 |
45 | var (
46 | usb_VID uint16 = 0x1915
47 | usb_PID uint16 = 0xCAFE
48 | )
49 |
--------------------------------------------------------------------------------
/src/runtime/baremetal.go:
--------------------------------------------------------------------------------
1 | // +build baremetal
2 |
3 | package runtime
4 |
5 | import (
6 | "unsafe"
7 | )
8 |
9 | //go:extern _heap_start
10 | var heapStartSymbol [0]byte
11 |
12 | //go:extern _heap_end
13 | var heapEndSymbol [0]byte
14 |
15 | //go:extern _globals_start
16 | var globalsStartSymbol [0]byte
17 |
18 | //go:extern _globals_end
19 | var globalsEndSymbol [0]byte
20 |
21 | //go:extern _stack_top
22 | var stackTopSymbol [0]byte
23 |
24 | var (
25 | heapStart = uintptr(unsafe.Pointer(&heapStartSymbol))
26 | heapEnd = uintptr(unsafe.Pointer(&heapEndSymbol))
27 | globalsStart = uintptr(unsafe.Pointer(&globalsStartSymbol))
28 | globalsEnd = uintptr(unsafe.Pointer(&globalsEndSymbol))
29 | stackTop = uintptr(unsafe.Pointer(&stackTopSymbol))
30 | )
31 |
32 | //export malloc
33 | func libc_malloc(size uintptr) unsafe.Pointer {
34 | return alloc(size)
35 | }
36 |
37 | //export free
38 | func libc_free(ptr unsafe.Pointer) {
39 | free(ptr)
40 | }
41 |
--------------------------------------------------------------------------------
/src/machine/board_circuitplay_express_baremetal.go:
--------------------------------------------------------------------------------
1 | // +build sam,atsamd21,circuitplay_express
2 |
3 | package machine
4 |
5 | import (
6 | "device/sam"
7 | "runtime/interrupt"
8 | )
9 |
10 | // UART1 on the Circuit Playground Express.
11 | var (
12 | UART1 = UART{
13 | Buffer: NewRingBuffer(),
14 | Bus: sam.SERCOM4_USART,
15 | SERCOM: 4,
16 | }
17 | )
18 |
19 | func init() {
20 | UART1.Interrupt = interrupt.New(sam.IRQ_SERCOM4, UART1.handleInterrupt)
21 | }
22 |
23 | // I2C on the Circuit Playground Express.
24 | var (
25 | // external device
26 | I2C0 = I2C{
27 | Bus: sam.SERCOM5_I2CM,
28 | SERCOM: 5,
29 | }
30 | // internal device
31 | I2C1 = I2C{
32 | Bus: sam.SERCOM1_I2CM,
33 | SERCOM: 1,
34 | }
35 | )
36 |
37 | // SPI on the Circuit Playground Express.
38 | var (
39 | SPI0 = SPI{
40 | Bus: sam.SERCOM3_SPI,
41 | SERCOM: 3,
42 | }
43 | )
44 |
45 | // I2S on the Circuit Playground Express.
46 | var (
47 | I2S0 = I2S{Bus: sam.I2S}
48 | )
49 |
--------------------------------------------------------------------------------
/src/runtime/runtime_cortexm_qemu.go:
--------------------------------------------------------------------------------
1 | // +build cortexm,qemu
2 |
3 | package runtime
4 |
5 | // This file implements the Stellaris LM3S6965 Cortex-M3 chip as implemented by
6 | // QEMU.
7 |
8 | import (
9 | "device/arm"
10 | "runtime/volatile"
11 | "unsafe"
12 | )
13 |
14 | type timeUnit int64
15 |
16 | const tickMicros = 1
17 |
18 | var timestamp timeUnit
19 |
20 | func postinit() {}
21 |
22 | //export Reset_Handler
23 | func main() {
24 | preinit()
25 | run()
26 | arm.SemihostingCall(arm.SemihostingReportException, arm.SemihostingApplicationExit)
27 | abort()
28 | }
29 |
30 | const asyncScheduler = false
31 |
32 | func sleepTicks(d timeUnit) {
33 | // TODO: actually sleep here for the given time.
34 | timestamp += d
35 | }
36 |
37 | func ticks() timeUnit {
38 | return timestamp
39 | }
40 |
41 | // UART0 output register.
42 | var stdoutWrite = (*volatile.Register8)(unsafe.Pointer(uintptr(0x4000c000)))
43 |
44 | func putchar(c byte) {
45 | stdoutWrite.Set(uint8(c))
46 | }
47 |
--------------------------------------------------------------------------------
/src/examples/wasm/slices/wasm.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const WASM_URL = 'wasm.wasm';
4 |
5 | var wasm;
6 |
7 | function update() {
8 | const value = document.getElementById("a").value;
9 | document.getElementById("b").innerHTML = JSON.stringify(window.splitter(value));
10 | }
11 |
12 | function init() {
13 | document.querySelector('#a').oninput = update;
14 |
15 | const go = new Go();
16 | if ('instantiateStreaming' in WebAssembly) {
17 | WebAssembly.instantiateStreaming(fetch(WASM_URL), go.importObject).then(function (obj) {
18 | wasm = obj.instance;
19 | go.run(wasm);
20 | })
21 | } else {
22 | fetch(WASM_URL).then(resp =>
23 | resp.arrayBuffer()
24 | ).then(bytes =>
25 | WebAssembly.instantiate(bytes, go.importObject).then(function (obj) {
26 | wasm = obj.instance;
27 | go.run(wasm);
28 | })
29 | )
30 | }
31 | }
32 |
33 | init();
34 |
--------------------------------------------------------------------------------
/colorwriter.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "io"
5 | )
6 |
7 | // ANSI escape codes for terminal colors.
8 | const (
9 | TermColorReset = "\x1b[0m"
10 | TermColorYellow = "\x1b[93m"
11 | )
12 |
13 | // ColorWriter wraps an io.Writer but adds a prefix and a terminal color.
14 | type ColorWriter struct {
15 | Out io.Writer
16 | Color string
17 | Prefix string
18 | line []byte
19 | }
20 |
21 | // Write implements io.Writer, but with an added prefix and terminal color.
22 | func (w *ColorWriter) Write(p []byte) (n int, err error) {
23 | for _, c := range p {
24 | if c == '\n' {
25 | w.line = append(w.line, []byte(TermColorReset)...)
26 | w.line = append(w.line, '\n')
27 | // Write this line.
28 | _, err := w.Out.Write(w.line)
29 | w.line = w.line[:0]
30 | w.line = append(w.line, []byte(w.Color+w.Prefix)...)
31 | if err != nil {
32 | return 0, err
33 | }
34 | } else {
35 | w.line = append(w.line, c)
36 | }
37 | }
38 | return len(p), nil
39 | }
40 |
--------------------------------------------------------------------------------
/src/examples/wasm/Makefile:
--------------------------------------------------------------------------------
1 | invoke: clean wasm_exec
2 | tinygo build -o ./html/wasm.wasm -target wasm -no-debug ./invoke/wasm.go
3 | cp ./invoke/wasm.js ./html/
4 | cp ./invoke/index.html ./html/
5 |
6 | export: clean wasm_exec
7 | tinygo build -o ./html/wasm.wasm -target wasm -no-debug ./export/wasm.go
8 | cp ./export/wasm.js ./html/
9 | cp ./export/index.html ./html/
10 |
11 | callback: clean wasm_exec
12 | tinygo build -o ./html/wasm.wasm -target wasm ./callback/wasm.go
13 | cp ./callback/wasm.js ./html/
14 | cp ./callback/index.html ./html/
15 |
16 | slices: clean wasm_exec
17 | tinygo build -o ./html/wasm.wasm -target wasm -no-debug ./slices/wasm.go
18 | cp ./slices/wasm.js ./html/
19 | cp ./slices/index.html ./html/
20 |
21 |
22 | main: clean wasm_exec
23 | tinygo build -o ./html/wasm.wasm -target wasm -no-debug ./main/main.go
24 | cp ./main/index.html ./html/
25 |
26 | wasm_exec:
27 | cp ../../../targets/wasm_exec.js ./html/
28 |
29 | clean:
30 | rm -rf ./html
31 | mkdir ./html
32 |
--------------------------------------------------------------------------------
/src/machine/machine_nrf51.go:
--------------------------------------------------------------------------------
1 | // +build nrf51
2 |
3 | package machine
4 |
5 | import (
6 | "device/nrf"
7 | )
8 |
9 | var (
10 | UART0 = NRF_UART0
11 | )
12 |
13 | func CPUFrequency() uint32 {
14 | return 16000000
15 | }
16 |
17 | // Get peripheral and pin number for this GPIO pin.
18 | func (p Pin) getPortPin() (*nrf.GPIO_Type, uint32) {
19 | return nrf.GPIO, uint32(p)
20 | }
21 |
22 | func (uart UART) setPins(tx, rx Pin) {
23 | nrf.UART0.PSELTXD.Set(uint32(tx))
24 | nrf.UART0.PSELRXD.Set(uint32(rx))
25 | }
26 |
27 | func (i2c I2C) setPins(scl, sda Pin) {
28 | i2c.Bus.PSELSCL.Set(uint32(scl))
29 | i2c.Bus.PSELSDA.Set(uint32(sda))
30 | }
31 |
32 | // SPI
33 | func (spi SPI) setPins(sck, mosi, miso Pin) {
34 | if sck == 0 {
35 | sck = SPI0_SCK_PIN
36 | }
37 | if mosi == 0 {
38 | mosi = SPI0_MOSI_PIN
39 | }
40 | if miso == 0 {
41 | miso = SPI0_MISO_PIN
42 | }
43 | spi.Bus.PSELSCK.Set(uint32(sck))
44 | spi.Bus.PSELMOSI.Set(uint32(mosi))
45 | spi.Bus.PSELMISO.Set(uint32(miso))
46 | }
47 |
--------------------------------------------------------------------------------
/src/sync/mutex.go:
--------------------------------------------------------------------------------
1 | package sync
2 |
3 | // These mutexes assume there is only one thread of operation: no goroutines,
4 | // interrupts or anything else.
5 |
6 | type Mutex struct {
7 | locked bool
8 | }
9 |
10 | func (m *Mutex) Lock() {
11 | if m.locked {
12 | panic("todo: block on locked mutex")
13 | }
14 | m.locked = true
15 | }
16 |
17 | func (m *Mutex) Unlock() {
18 | if !m.locked {
19 | panic("sync: unlock of unlocked Mutex")
20 | }
21 | m.locked = false
22 | }
23 |
24 | type RWMutex struct {
25 | m Mutex
26 | readers uint32
27 | }
28 |
29 | func (rw *RWMutex) Lock() {
30 | rw.m.Lock()
31 | }
32 |
33 | func (rw *RWMutex) Unlock() {
34 | rw.m.Unlock()
35 | }
36 |
37 | func (rw *RWMutex) RLock() {
38 | if rw.readers == 0 {
39 | rw.m.Lock()
40 | }
41 | rw.readers++
42 | }
43 |
44 | func (rw *RWMutex) RUnlock() {
45 | if rw.readers == 0 {
46 | panic("sync: unlock of unlocked RWMutex")
47 | }
48 | rw.readers--
49 | if rw.readers == 0 {
50 | rw.m.Unlock()
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/examples/blinkm/blinkm.go:
--------------------------------------------------------------------------------
1 | // Connects to an BlinkM I2C RGB LED.
2 | // http://thingm.com/fileadmin/thingm/downloads/BlinkM_datasheet.pdf
3 | package main
4 |
5 | import (
6 | "machine"
7 | "time"
8 | )
9 |
10 | func main() {
11 | machine.I2C0.Configure(machine.I2CConfig{})
12 |
13 | // Init BlinkM
14 | machine.I2C0.WriteRegister(0x09, 'o', nil)
15 |
16 | version := []byte{0, 0}
17 | machine.I2C0.ReadRegister(0x09, 'Z', version)
18 | println("Firmware version:", string(version[0]), string(version[1]))
19 |
20 | count := 0
21 | for {
22 | switch count {
23 | case 0:
24 | // Crimson
25 | machine.I2C0.WriteRegister(0x09, 'n', []byte{0xdc, 0x14, 0x3c})
26 | count = 1
27 | case 1:
28 | // MediumPurple
29 | machine.I2C0.WriteRegister(0x09, 'n', []byte{0x93, 0x70, 0xdb})
30 | count = 2
31 | case 2:
32 | // MediumSeaGreen
33 | machine.I2C0.WriteRegister(0x09, 'n', []byte{0x3c, 0xb3, 0x71})
34 | count = 0
35 | }
36 |
37 | time.Sleep(100 * time.Millisecond)
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/device/stm32/stm32f407xx-altfunc-bitfields.go:
--------------------------------------------------------------------------------
1 | // These are the supported alternate function numberings on the stm32f407
2 | // +build stm32,stm32f407
3 |
4 | // Alternate function settings on the stm32f4xx series
5 |
6 | package stm32
7 |
8 | const (
9 | // Alternative peripheral pin functions
10 | // AF0_SYSTEM is defined im the common bitfields package
11 | AF1_TIM1_2 AltFunc = 1
12 | AF2_TIM3_4_5 = 2
13 | AF3_TIM8_9_10_11 = 3
14 | AF4_I2C1_2_3 = 4
15 | AF5_SPI1_SPI2 = 5
16 | AF6_SPI3 = 6
17 | AF7_USART1_2_3 = 7
18 | AF8_USART4_5_6 = 8
19 | AF9_CAN1_CAN2_TIM12_13_14 = 9
20 | AF10_OTG_FS_OTG_HS = 10
21 | AF11_ETH = 11
22 | AF12_FSMC_SDIO_OTG_HS_1 = 12
23 | AF13_DCMI = 13
24 | AF14 = 14
25 | AF15_EVENTOUT = 15
26 | )
27 |
--------------------------------------------------------------------------------
/src/examples/blinky2/blinky2.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // This blinky is a bit more advanced than blink1, with two goroutines running
4 | // at the same time and blinking a different LED. The delay of led2 is slightly
5 | // less than half of led1, which would be hard to do without some sort of
6 | // concurrency.
7 |
8 | import (
9 | "machine"
10 | "time"
11 | )
12 |
13 | func main() {
14 | go led1()
15 | led2()
16 | }
17 |
18 | func led1() {
19 | led := machine.LED1
20 | led.Configure(machine.PinConfig{Mode: machine.PinOutput})
21 | for {
22 | println("+")
23 | led.Low()
24 | time.Sleep(time.Millisecond * 1000)
25 |
26 | println("-")
27 | led.High()
28 | time.Sleep(time.Millisecond * 1000)
29 | }
30 | }
31 |
32 | func led2() {
33 | led := machine.LED2
34 | led.Configure(machine.PinConfig{Mode: machine.PinOutput})
35 | for {
36 | println(" +")
37 | led.Low()
38 | time.Sleep(time.Millisecond * 420)
39 |
40 | println(" -")
41 | led.High()
42 | time.Sleep(time.Millisecond * 420)
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/testdata/float.txt:
--------------------------------------------------------------------------------
1 | +3.141593e+000
2 | +6.666667e-001
3 | +1.666667e+000
4 | -3.333333e-001
5 | +1.333333e+000
6 | +3.333333e-001
7 | +6.666667e-001
8 | +1.666667e+000
9 | -3.333333e-001
10 | +1.333333e+000
11 | +3.333333e-001
12 | +6.666667e-001
13 | +6.666667e-001
14 | 3 5 -2 -11
15 | +5.300000e+001 -8.000000e+000 +2.000000e+001
16 | (+6.666667e-001+1.200000e+000i)
17 | +6.666667e-001
18 | +1.200000e+000
19 | (+6.666667e-001-2.000000e+000i)
20 | +6.666667e-001
21 | -2.000000e+000
22 | (+2.000000e+000+1.000000e+000i)
23 | (+2.000000e+000-2.000000e+000i)
24 | (+6.666667e-001-2.000000e+000i)
25 | (+6.666667e-001+1.200000e+000i)
26 | complex64 add: (+2.000000e+000+1.000000e+001i)
27 | complex64 sub: (+8.000000e+000+1.000000e+001i)
28 | complex64 mul: (-1.500000e+001+2.000000e+000i)
29 | complex64 div: (-1.666667e+000+7.333333e+000i)
30 | complex128 add: (-3.000000e+000+8.000000e+000i)
31 | complex128 sub: (-7.000000e+000+8.000000e+000i)
32 | complex128 mul: (-1.000000e+001+1.000000e+001i)
33 | complex128 div: (-2.500000e+000+7.000000e+000i)
34 |
--------------------------------------------------------------------------------
/interp/testdata/basic.out.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2 | target triple = "x86_64--linux"
3 |
4 | @main.nonConst1 = local_unnamed_addr global [4 x i64] zeroinitializer
5 | @main.nonConst2 = local_unnamed_addr global i64 0
6 |
7 | declare void @runtime.printint64(i64) unnamed_addr
8 |
9 | declare void @runtime.printnl() unnamed_addr
10 |
11 | define void @runtime.initAll() unnamed_addr {
12 | entry:
13 | call void @runtime.printint64(i64 5)
14 | call void @runtime.printnl()
15 | %value1 = call i64 @someValue()
16 | store i64 %value1, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @main.nonConst1, i32 0, i32 0)
17 | %value2 = load i64, i64* getelementptr inbounds ([4 x i64], [4 x i64]* @main.nonConst1, i32 0, i32 0)
18 | store i64 %value2, i64* @main.nonConst2
19 | ret void
20 | }
21 |
22 | define void @main() unnamed_addr {
23 | entry:
24 | call void @runtime.printint64(i64 3)
25 | call void @runtime.printnl()
26 | ret void
27 | }
28 |
29 | declare i64 @someValue() local_unnamed_addr
30 |
--------------------------------------------------------------------------------
/src/machine/board_pca10040.go:
--------------------------------------------------------------------------------
1 | // +build pca10040
2 |
3 | package machine
4 |
5 | // The PCA10040 has a low-frequency (32kHz) crystal oscillator on board.
6 | const HasLowFrequencyCrystal = true
7 |
8 | // LEDs on the PCA10040 (nRF52832 dev board)
9 | const (
10 | LED Pin = LED1
11 | LED1 Pin = 17
12 | LED2 Pin = 18
13 | LED3 Pin = 19
14 | LED4 Pin = 20
15 | )
16 |
17 | // Buttons on the PCA10040 (nRF52832 dev board)
18 | const (
19 | BUTTON Pin = BUTTON1
20 | BUTTON1 Pin = 13
21 | BUTTON2 Pin = 14
22 | BUTTON3 Pin = 15
23 | BUTTON4 Pin = 16
24 | )
25 |
26 | // UART pins for NRF52840-DK
27 | const (
28 | UART_TX_PIN Pin = 6
29 | UART_RX_PIN Pin = 8
30 | )
31 |
32 | // ADC pins
33 | const (
34 | ADC0 Pin = 3
35 | ADC1 Pin = 4
36 | ADC2 Pin = 28
37 | ADC3 Pin = 29
38 | ADC4 Pin = 30
39 | ADC5 Pin = 31
40 | )
41 |
42 | // I2C pins
43 | const (
44 | SDA_PIN Pin = 26
45 | SCL_PIN Pin = 27
46 | )
47 |
48 | // SPI pins
49 | const (
50 | SPI0_SCK_PIN Pin = 25
51 | SPI0_MOSI_PIN Pin = 23
52 | SPI0_MISO_PIN Pin = 24
53 | )
54 |
--------------------------------------------------------------------------------
/src/syscall/errno.go:
--------------------------------------------------------------------------------
1 | package syscall
2 |
3 | // Most code here has been copied from the Go sources:
4 | // https://github.com/golang/go/blob/go1.12/src/syscall/syscall_js.go
5 | // It has the following copyright note:
6 | //
7 | // Copyright 2018 The Go Authors. All rights reserved.
8 | // Use of this source code is governed by a BSD-style
9 | // license that can be found in the LICENSE file.
10 |
11 | // An Errno is an unsigned number describing an error condition.
12 | // It implements the error interface. The zero Errno is by convention
13 | // a non-error, so code to convert from Errno to error should use:
14 | // err = nil
15 | // if errno != 0 {
16 | // err = errno
17 | // }
18 | type Errno uintptr
19 |
20 | func (e Errno) Error() string {
21 | return "errno " + itoa(int(e))
22 | }
23 |
24 | func (e Errno) Temporary() bool {
25 | return e == EINTR || e == EMFILE || e.Timeout()
26 | }
27 |
28 | func (e Errno) Timeout() bool {
29 | return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
30 | }
31 |
--------------------------------------------------------------------------------
/testdata/print.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | func main() {
4 | // test basic printing
5 | println("hello world!")
6 | println(42)
7 | println(100000000)
8 |
9 | // check that this one doesn't print an extra space between args
10 | print("a", "b", "c")
11 | println()
12 | // ..but this one does
13 | println("a", "b", "c")
14 |
15 | // print integers
16 | println(uint8(123))
17 | println(int8(123))
18 | println(int8(-123))
19 | println(uint16(12345))
20 | println(int16(12345))
21 | println(int16(-12345))
22 | println(uint32(12345678))
23 | println(int32(12345678))
24 | println(int32(-12345678))
25 | println(uint64(123456789012))
26 | println(int64(123456789012))
27 | println(int64(-123456789012))
28 |
29 | // print float64
30 | println(3.14)
31 |
32 | // print complex128
33 | println(5 + 1.2345i)
34 |
35 | // print interface
36 | println(interface{}(nil))
37 |
38 | // print map
39 | println(map[string]int{"three": 3, "five": 5})
40 |
41 | // TODO: print pointer
42 |
43 | // print bool
44 | println(true, false)
45 | }
46 |
--------------------------------------------------------------------------------
/transform/panic.go:
--------------------------------------------------------------------------------
1 | package transform
2 |
3 | import (
4 | "tinygo.org/x/go-llvm"
5 | )
6 |
7 | // ReplacePanicsWithTrap replaces each call to panic (or similar functions) with
8 | // calls to llvm.trap, to reduce code size. This is the -panic=trap command-line
9 | // option.
10 | func ReplacePanicsWithTrap(mod llvm.Module) {
11 | ctx := mod.Context()
12 | builder := ctx.NewBuilder()
13 | defer builder.Dispose()
14 |
15 | trap := mod.NamedFunction("llvm.trap")
16 | if trap.IsNil() {
17 | trapType := llvm.FunctionType(ctx.VoidType(), nil, false)
18 | trap = llvm.AddFunction(mod, "llvm.trap", trapType)
19 | }
20 | for _, name := range []string{"runtime._panic", "runtime.runtimePanic"} {
21 | fn := mod.NamedFunction(name)
22 | if fn.IsNil() {
23 | continue
24 | }
25 | for _, use := range getUses(fn) {
26 | if use.IsACallInst().IsNil() || use.CalledValue() != fn {
27 | panic("expected use of a panic function to be a call")
28 | }
29 | builder.SetInsertPointBefore(use)
30 | builder.CreateCall(trap, nil, "")
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/compiler/volatile.go:
--------------------------------------------------------------------------------
1 | package compiler
2 |
3 | // This file implements volatile loads/stores in runtime/volatile.LoadT and
4 | // runtime/volatile.StoreT as compiler builtins.
5 |
6 | import (
7 | "golang.org/x/tools/go/ssa"
8 | "tinygo.org/x/go-llvm"
9 | )
10 |
11 | // createVolatileLoad is the implementation of the intrinsic function
12 | // runtime/volatile.LoadT().
13 | func (b *builder) createVolatileLoad(instr *ssa.CallCommon) (llvm.Value, error) {
14 | addr := b.getValue(instr.Args[0])
15 | b.createNilCheck(instr.Args[0], addr, "deref")
16 | val := b.CreateLoad(addr, "")
17 | val.SetVolatile(true)
18 | return val, nil
19 | }
20 |
21 | // createVolatileStore is the implementation of the intrinsic function
22 | // runtime/volatile.StoreT().
23 | func (b *builder) createVolatileStore(instr *ssa.CallCommon) (llvm.Value, error) {
24 | addr := b.getValue(instr.Args[0])
25 | val := b.getValue(instr.Args[1])
26 | b.createNilCheck(instr.Args[0], addr, "deref")
27 | store := b.CreateStore(val, addr)
28 | store.SetVolatile(true)
29 | return llvm.Value{}, nil
30 | }
31 |
--------------------------------------------------------------------------------
/loader/errors.go:
--------------------------------------------------------------------------------
1 | package loader
2 |
3 | import (
4 | "go/token"
5 | "strings"
6 | )
7 |
8 | // Errors contains a list of parser errors or a list of typechecker errors for
9 | // the given package.
10 | type Errors struct {
11 | Pkg *Package
12 | Errs []error
13 | }
14 |
15 | func (e Errors) Error() string {
16 | return "could not compile: " + e.Errs[0].Error()
17 | }
18 |
19 | // ImportCycleErrors is returned when encountering an import cycle. The list of
20 | // packages is a list from the root package to the leaf package that imports one
21 | // of the packages in the list.
22 | type ImportCycleError struct {
23 | Packages []string
24 | ImportPositions []token.Position
25 | }
26 |
27 | func (e *ImportCycleError) Error() string {
28 | var msg strings.Builder
29 | msg.WriteString("import cycle:\n\t")
30 | msg.WriteString(strings.Join(e.Packages, "\n\t"))
31 | msg.WriteString("\n at ")
32 | for i, pos := range e.ImportPositions {
33 | if i > 0 {
34 | msg.WriteString(", ")
35 | }
36 | msg.WriteString(pos.String())
37 | }
38 | return msg.String()
39 | }
40 |
--------------------------------------------------------------------------------
/src/device/arm/cortexm.s:
--------------------------------------------------------------------------------
1 | .syntax unified
2 |
3 | .section .text.HardFault_Handler
4 | .global HardFault_Handler
5 | .type HardFault_Handler, %function
6 | HardFault_Handler:
7 | // Put the old stack pointer in the first argument, for easy debugging. This
8 | // is especially useful on Cortex-M0, which supports far fewer debug
9 | // facilities.
10 | mov r0, sp
11 |
12 | // Load the default stack pointer from address 0 so that we can call normal
13 | // functions again that expect a working stack. However, it will corrupt the
14 | // old stack so the function below must not attempt to recover from this
15 | // fault.
16 | movs r3, #0
17 | ldr r3, [r3]
18 | mov sp, r3
19 |
20 | // Continue handling this error in Go.
21 | bl handleHardFault
22 |
23 | // This is a convenience function for semihosting support.
24 | // At some point, this should be replaced by inline assembly.
25 | .section .text.SemihostingCall
26 | .global SemihostingCall
27 | .type SemihostingCall, %function
28 | SemihostingCall:
29 | bkpt 0xab
30 | bx lr
31 |
--------------------------------------------------------------------------------
/interp/testdata/consteval.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2 | target triple = "x86_64--linux"
3 |
4 | @intToPtrResult = global i8 0
5 | @ptrToIntResult = global i8 0
6 |
7 | define void @runtime.initAll() {
8 | call void @main.init()
9 | ret void
10 | }
11 |
12 | define internal void @main.init() {
13 | call void @testIntToPtr()
14 | call void @testPtrToInt()
15 | ret void
16 | }
17 |
18 | define internal void @testIntToPtr() {
19 | %nil = icmp eq i8* inttoptr (i64 1024 to i8*), null
20 | br i1 %nil, label %a, label %b
21 | a:
22 | ; should not be reached
23 | store i8 1, i8* @intToPtrResult
24 | ret void
25 | b:
26 | ; should be reached
27 | store i8 2, i8* @intToPtrResult
28 | ret void
29 | }
30 |
31 | define internal void @testPtrToInt() {
32 | %zero = icmp eq i64 ptrtoint (i8* @ptrToIntResult to i64), 0
33 | br i1 %zero, label %a, label %b
34 | a:
35 | ; should not be reached
36 | store i8 1, i8* @ptrToIntResult
37 | ret void
38 | b:
39 | ; should be reached
40 | store i8 2, i8* @ptrToIntResult
41 | ret void
42 | }
43 |
--------------------------------------------------------------------------------
/src/sync/map.go:
--------------------------------------------------------------------------------
1 | package sync
2 |
3 | // This file implements just enough of sync.Map to get packages to compile. It
4 | // is no more efficient than a map with a lock.
5 |
6 | type Map struct {
7 | lock Mutex
8 | m map[interface{}]interface{}
9 | }
10 |
11 | func (m *Map) Delete(key interface{}) {
12 | m.lock.Lock()
13 | defer m.lock.Unlock()
14 | delete(m.m, key)
15 | }
16 |
17 | func (m *Map) Load(key interface{}) (value interface{}, ok bool) {
18 | m.lock.Lock()
19 | defer m.lock.Unlock()
20 | value, ok = m.m[key]
21 | return
22 | }
23 |
24 | func (m *Map) LoadOrStore(key, value interface{}) (actual interface{}, loaded bool) {
25 | m.lock.Lock()
26 | defer m.lock.Unlock()
27 | if m.m == nil {
28 | m.m = make(map[interface{}]interface{})
29 | }
30 | if existing, ok := m.m[key]; ok {
31 | return existing, true
32 | }
33 | m.m[key] = value
34 | return value, false
35 | }
36 |
37 | func (m *Map) Store(key, value interface{}) {
38 | m.lock.Lock()
39 | defer m.lock.Unlock()
40 | if m.m == nil {
41 | m.m = make(map[interface{}]interface{})
42 | }
43 | m.m[key] = value
44 | }
45 |
--------------------------------------------------------------------------------
/src/examples/echo/echo.go:
--------------------------------------------------------------------------------
1 | // This is a echo console running on the device UART.
2 | // Connect using default baudrate for this hardware, 8-N-1 with your terminal program.
3 | package main
4 |
5 | import (
6 | "machine"
7 | "time"
8 | )
9 |
10 | // change these to test a different UART or pins if available
11 | var (
12 | uart = machine.UART0
13 | tx = machine.UART_TX_PIN
14 | rx = machine.UART_RX_PIN
15 | )
16 |
17 | func main() {
18 | uart.Configure(machine.UARTConfig{TX: tx, RX: rx})
19 | uart.Write([]byte("Echo console enabled. Type something then press enter:\r\n"))
20 |
21 | input := make([]byte, 64)
22 | i := 0
23 | for {
24 | if uart.Buffered() > 0 {
25 | data, _ := uart.ReadByte()
26 |
27 | switch data {
28 | case 13:
29 | // return key
30 | uart.Write([]byte("\r\n"))
31 | uart.Write([]byte("You typed: "))
32 | uart.Write(input[:i])
33 | uart.Write([]byte("\r\n"))
34 | i = 0
35 | default:
36 | // just echo the character
37 | uart.WriteByte(data)
38 | input[i] = data
39 | i++
40 | }
41 | }
42 | time.Sleep(10 * time.Millisecond)
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/testdata/init.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | func init() {
4 | println("init")
5 | }
6 |
7 | func main() {
8 | println("main")
9 | println("v1:", v1)
10 | println("v2:", v2.x, v2.y)
11 | println("v3:", len(v3), cap(v3), v3[0], v3[3])
12 | println("v4:", len(v4), v4 == nil)
13 | println("v5:", len(v5), v5 == nil)
14 | println("v6:", v6)
15 | println("v7:", cap(v7), string(v7))
16 |
17 | println(uint8SliceSrc[0])
18 | println(uint8SliceDst[0])
19 | println(intSliceSrc[0])
20 | println(intSliceDst[0])
21 | }
22 |
23 | type (
24 | t2 struct {
25 | x int
26 | y int
27 | }
28 | )
29 |
30 | var (
31 | v1 = 3
32 | v2 = t2{2, 5}
33 | v3 = []int{2, 3, 5, 7}
34 | v4 map[string]int
35 | v5 = map[string]int{}
36 | v6 = float64(v1) < 2.6
37 | v7 = []byte("foo")
38 |
39 | uint8SliceSrc = []uint8{3, 100}
40 | uint8SliceDst []uint8
41 | intSliceSrc = []int16{5, 123, 1024}
42 | intSliceDst []int16
43 | )
44 |
45 | func init() {
46 | uint8SliceDst = make([]uint8, len(uint8SliceSrc))
47 | copy(uint8SliceDst, uint8SliceSrc)
48 |
49 | intSliceDst = make([]int16, len(intSliceSrc))
50 | copy(intSliceDst, intSliceSrc)
51 | }
52 |
--------------------------------------------------------------------------------
/src/runtime/gc_globals_precise.go:
--------------------------------------------------------------------------------
1 | // +build gc.conservative gc.extalloc
2 | // +build !baremetal
3 |
4 | package runtime
5 |
6 | import (
7 | "unsafe"
8 | )
9 |
10 | //go:extern runtime.trackedGlobalsStart
11 | var trackedGlobalsStart uintptr
12 |
13 | //go:extern runtime.trackedGlobalsLength
14 | var trackedGlobalsLength uintptr
15 |
16 | //go:extern runtime.trackedGlobalsBitmap
17 | var trackedGlobalsBitmap [0]uint8
18 |
19 | // markGlobals marks all globals, which are reachable by definition.
20 | //
21 | // This implementation relies on a compiler pass that stores all globals in a
22 | // single global (adjusting all uses of them accordingly) and creates a bit
23 | // vector with the locations of each pointer. This implementation then walks the
24 | // bit vector and for each pointer it indicates, it marks the root.
25 | //
26 | //go:nobounds
27 | func markGlobals() {
28 | for i := uintptr(0); i < trackedGlobalsLength; i++ {
29 | if trackedGlobalsBitmap[i/8]&(1<<(i%8)) != 0 {
30 | addr := trackedGlobalsStart + i*unsafe.Alignof(uintptr(0))
31 | root := *(*uintptr)(unsafe.Pointer(addr))
32 | markRoot(addr, root)
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/examples/pwm/pwm.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "machine"
5 | "time"
6 | )
7 |
8 | // This example assumes that an RGB LED is connected to pins 3, 5 and 6 on an Arduino.
9 | // Change the values below to use different pins.
10 | const (
11 | redPin = 3
12 | greenPin = 5
13 | bluePin = 6
14 | )
15 |
16 | // cycleColor is just a placeholder until math/rand or some equivalent is working.
17 | func cycleColor(color uint8) uint8 {
18 | if color < 10 {
19 | return color + 1
20 | } else if color < 200 {
21 | return color + 10
22 | } else {
23 | return 0
24 | }
25 | }
26 |
27 | func main() {
28 | machine.InitPWM()
29 |
30 | red := machine.PWM{redPin}
31 | red.Configure()
32 |
33 | green := machine.PWM{greenPin}
34 | green.Configure()
35 |
36 | blue := machine.PWM{bluePin}
37 | blue.Configure()
38 |
39 | var rc uint8
40 | var gc uint8 = 20
41 | var bc uint8 = 30
42 |
43 | for {
44 | rc = cycleColor(rc)
45 | gc = cycleColor(gc)
46 | bc = cycleColor(bc)
47 |
48 | red.Set(uint16(rc) << 8)
49 | green.Set(uint16(gc) << 8)
50 | blue.Set(uint16(bc) << 8)
51 |
52 | time.Sleep(time.Millisecond * 500)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/runtime/func.go:
--------------------------------------------------------------------------------
1 | package runtime
2 |
3 | // This file implements some data types that may be useful for some
4 | // implementations of func values.
5 |
6 | import (
7 | "unsafe"
8 | )
9 |
10 | // funcValue is the underlying type of func values, depending on which func
11 | // value representation was used.
12 | type funcValue struct {
13 | context unsafe.Pointer // function context, for closures and bound methods
14 | id uintptr // ptrtoint of *funcValueWithSignature before lowering, opaque index (non-0) after lowering
15 | }
16 |
17 | // funcValueWithSignature is used before the func lowering pass.
18 | type funcValueWithSignature struct {
19 | funcPtr uintptr // ptrtoint of the actual function pointer
20 | signature *typecodeID // pointer to identify this signature (the value is undef)
21 | }
22 |
23 | // getFuncPtr is a dummy function that may be used if the func lowering pass is
24 | // not used. It is generally too slow but may be a useful fallback to debug the
25 | // func lowering pass.
26 | func getFuncPtr(val funcValue, signature *typecodeID) uintptr {
27 | return (*funcValueWithSignature)(unsafe.Pointer(val.id)).funcPtr
28 | }
29 |
--------------------------------------------------------------------------------
/src/runtime/runtime_atmega.go:
--------------------------------------------------------------------------------
1 | // +build avr,atmega
2 |
3 | package runtime
4 |
5 | import (
6 | "device/avr"
7 | )
8 |
9 | // Sleep for a given period. The period is defined by the WDT peripheral, and is
10 | // on most chips (at least) 3 bits wide, in powers of two from 16ms to 2s
11 | // (0=16ms, 1=32ms, 2=64ms...). Note that the WDT is not very accurate: it can
12 | // be off by a large margin depending on temperature and supply voltage.
13 | //
14 | // TODO: disable more peripherals etc. to reduce sleep current.
15 | func sleepWDT(period uint8) {
16 | // Configure WDT
17 | avr.Asm("cli")
18 | avr.Asm("wdr")
19 | // Start timed sequence.
20 | avr.WDTCSR.SetBits(avr.WDTCSR_WDCE | avr.WDTCSR_WDE)
21 | // Enable WDT and set new timeout
22 | avr.WDTCSR.SetBits(avr.WDTCSR_WDIE | period)
23 | avr.Asm("sei")
24 |
25 | // Set sleep mode to idle and enable sleep mode.
26 | // Note: when using something other than idle, the UART won't work
27 | // correctly. This needs to be fixed, though, so we can truly sleep.
28 | avr.SMCR.Set((0 << 1) | avr.SMCR_SE)
29 |
30 | // go to sleep
31 | avr.Asm("sleep")
32 |
33 | // disable sleep
34 | avr.SMCR.Set(0)
35 | }
36 |
--------------------------------------------------------------------------------
/src/examples/button2/button2.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "machine"
5 | "time"
6 | )
7 |
8 | // This example assumes that you are using the pca10040 board
9 |
10 | func main() {
11 | led1 := machine.LED1
12 | led1.Configure(machine.PinConfig{Mode: machine.PinOutput})
13 |
14 | led2 := machine.LED2
15 | led2.Configure(machine.PinConfig{Mode: machine.PinOutput})
16 |
17 | led3 := machine.LED3
18 | led3.Configure(machine.PinConfig{Mode: machine.PinOutput})
19 |
20 | led4 := machine.LED4
21 | led4.Configure(machine.PinConfig{Mode: machine.PinOutput})
22 |
23 | button1 := machine.BUTTON1
24 | button1.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
25 |
26 | button2 := machine.BUTTON2
27 | button2.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
28 |
29 | button3 := machine.BUTTON3
30 | button3.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
31 |
32 | button4 := machine.BUTTON4
33 | button4.Configure(machine.PinConfig{Mode: machine.PinInputPullup})
34 |
35 | for {
36 | led1.Set(button1.Get())
37 | led2.Set(button2.Get())
38 | led3.Set(button3.Get())
39 | led4.Set(button4.Get())
40 |
41 | time.Sleep(time.Millisecond * 10)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/machine/board_pca10056.go:
--------------------------------------------------------------------------------
1 | // +build pca10056
2 |
3 | package machine
4 |
5 | const HasLowFrequencyCrystal = true
6 |
7 | // LEDs on the pca10056
8 | const (
9 | LED Pin = LED1
10 | LED1 Pin = 13
11 | LED2 Pin = 14
12 | LED3 Pin = 15
13 | LED4 Pin = 16
14 | )
15 |
16 | // Buttons on the pca10056
17 | const (
18 | BUTTON Pin = BUTTON1
19 | BUTTON1 Pin = 11
20 | BUTTON2 Pin = 12
21 | BUTTON3 Pin = 24
22 | BUTTON4 Pin = 25
23 | )
24 |
25 | // UART pins
26 | const (
27 | UART_TX_PIN Pin = 6
28 | UART_RX_PIN Pin = 8
29 | )
30 |
31 | // ADC pins
32 | const (
33 | ADC0 Pin = 3
34 | ADC1 Pin = 4
35 | ADC2 Pin = 28
36 | ADC3 Pin = 29
37 | ADC4 Pin = 30
38 | ADC5 Pin = 31
39 | )
40 |
41 | // I2C pins
42 | const (
43 | SDA_PIN Pin = 26 // P0.26
44 | SCL_PIN Pin = 27 // P0.27
45 | )
46 |
47 | // SPI pins
48 | const (
49 | SPI0_SCK_PIN Pin = 47 // P1.15
50 | SPI0_MOSI_PIN Pin = 45 // P1.13
51 | SPI0_MISO_PIN Pin = 46 // P1.14
52 | )
53 |
54 | // USB CDC identifiers
55 | const (
56 | usb_STRING_PRODUCT = "Nordic nRF52840DK (PCA10056)"
57 | usb_STRING_MANUFACTURER = "Nordic Semiconductor"
58 | )
59 |
60 | var (
61 | usb_VID uint16 = 0x239A
62 | usb_PID uint16 = 0x8029
63 | )
64 |
--------------------------------------------------------------------------------
/src/examples/mcp3008/mcp3008.go:
--------------------------------------------------------------------------------
1 | // Connects to an MCP3008 ADC via SPI.
2 | // Datasheet: https://www.microchip.com/wwwproducts/en/en010530
3 | package main
4 |
5 | import (
6 | "errors"
7 | "machine"
8 | "time"
9 | )
10 |
11 | // cs is the pin used for Chip Select (CS). Change to whatever is in use on your board.
12 | const cs = machine.Pin(3)
13 |
14 | var (
15 | tx []byte
16 | rx []byte
17 | val, result uint16
18 | )
19 |
20 | func main() {
21 | cs.Configure(machine.PinConfig{Mode: machine.PinOutput})
22 |
23 | machine.SPI0.Configure(machine.SPIConfig{
24 | Frequency: 4000000,
25 | Mode: 3})
26 |
27 | tx = make([]byte, 3)
28 | rx = make([]byte, 3)
29 |
30 | for {
31 | val, _ = Read(0)
32 | println(val)
33 | time.Sleep(50 * time.Millisecond)
34 | }
35 | }
36 |
37 | // Read analog data from channel
38 | func Read(channel int) (uint16, error) {
39 | if channel < 0 || channel > 7 {
40 | return 0, errors.New("Invalid channel for read")
41 | }
42 |
43 | tx[0] = 0x01
44 | tx[1] = byte(8+channel) << 4
45 | tx[2] = 0x00
46 |
47 | cs.Low()
48 | machine.SPI0.Tx(tx, rx)
49 | result = uint16((rx[1]&0x3))<<8 + uint16(rx[2])
50 | cs.High()
51 |
52 | return result, nil
53 | }
54 |
--------------------------------------------------------------------------------
/src/runtime/interrupt/interrupt_gameboyadvance.go:
--------------------------------------------------------------------------------
1 | // +build gameboyadvance
2 |
3 | package interrupt
4 |
5 | import (
6 | "runtime/volatile"
7 | "unsafe"
8 | )
9 |
10 | var (
11 | regInterruptEnable = (*volatile.Register16)(unsafe.Pointer(uintptr(0x4000200)))
12 | regInterruptRequestFlags = (*volatile.Register16)(unsafe.Pointer(uintptr(0x4000202)))
13 | regInterruptMasterEnable = (*volatile.Register16)(unsafe.Pointer(uintptr(0x4000208)))
14 | )
15 |
16 | // Enable enables this interrupt. Right after calling this function, the
17 | // interrupt may be invoked if it was already pending.
18 | func (irq Interrupt) Enable() {
19 | regInterruptEnable.SetBits(1 << uint(irq.num))
20 | }
21 |
22 | //export handleInterrupt
23 | func handleInterrupt() {
24 | flags := regInterruptRequestFlags.Get()
25 | for i := 0; i < 14; i++ {
26 | if flags&(1<RAM
25 |
26 | _sidata = LOADADDR(.data);
27 |
28 | .data :
29 | {
30 | _sdata = .; /* used by startup code */
31 | *(.data)
32 | *(.data*)
33 | _edata = .; /* used by startup code */
34 | } >RAM AT>FLASH_TEXT
35 |
36 | .bss :
37 | {
38 | _sbss = .; /* used by startup code */
39 | *(.bss)
40 | *(.bss*)
41 | *(COMMON)
42 | _ebss = .; /* used by startup code */
43 | } >RAM
44 | }
45 |
46 | /* For the memory allocator. */
47 | _heap_start = _ebss;
48 | _heap_end = ORIGIN(RAM) + LENGTH(RAM);
49 | _globals_start = _sdata;
50 | _globals_end = _ebss;
51 |
--------------------------------------------------------------------------------
/transform/globals.go:
--------------------------------------------------------------------------------
1 | package transform
2 |
3 | import "tinygo.org/x/go-llvm"
4 |
5 | // This file implements small transformations on globals (functions and global
6 | // variables) for specific ABIs/architectures.
7 |
8 | // ApplyFunctionSections puts every function in a separate section. This makes
9 | // it possible for the linker to remove dead code. It is the equivalent of
10 | // passing -ffunction-sections to a C compiler.
11 | func ApplyFunctionSections(mod llvm.Module) {
12 | llvmFn := mod.FirstFunction()
13 | for !llvmFn.IsNil() {
14 | if !llvmFn.IsDeclaration() {
15 | name := llvmFn.Name()
16 | llvmFn.SetSection(".text." + name)
17 | }
18 | llvmFn = llvm.NextFunction(llvmFn)
19 | }
20 | }
21 |
22 | // NonConstGlobals turns all global constants into global variables. This works
23 | // around a limitation on Harvard architectures (e.g. AVR), where constant and
24 | // non-constant pointers point to a different address space. Normal pointer
25 | // behavior is restored by using the data space only, at the cost of RAM for
26 | // constant global variables.
27 | func NonConstGlobals(mod llvm.Module) {
28 | global := mod.FirstGlobal()
29 | for !global.IsNil() {
30 | global.SetGlobalConstant(false)
31 | global = llvm.NextGlobal(global)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/cgo/sync.go:
--------------------------------------------------------------------------------
1 | package cgo
2 |
3 | import (
4 | "sync"
5 | "unsafe"
6 | )
7 |
8 | // #include
9 | import "C"
10 |
11 | // refMap is a convenient way to store opaque references that can be passed to
12 | // C. It is useful if an API uses function pointers and you cannot pass a Go
13 | // pointer but only a C pointer.
14 | type refMap struct {
15 | refs map[unsafe.Pointer]interface{}
16 | lock sync.Mutex
17 | }
18 |
19 | // Put stores a value in the map. It can later be retrieved using Get. It must
20 | // be removed using Remove to avoid memory leaks.
21 | func (m *refMap) Put(v interface{}) unsafe.Pointer {
22 | m.lock.Lock()
23 | defer m.lock.Unlock()
24 | if m.refs == nil {
25 | m.refs = make(map[unsafe.Pointer]interface{}, 1)
26 | }
27 | ref := C.malloc(1)
28 | m.refs[ref] = v
29 | return ref
30 | }
31 |
32 | // Get returns a stored value previously inserted with Put. Use the same
33 | // reference as you got from Put.
34 | func (m *refMap) Get(ref unsafe.Pointer) interface{} {
35 | m.lock.Lock()
36 | defer m.lock.Unlock()
37 | return m.refs[ref]
38 | }
39 |
40 | // Remove deletes a single reference from the map.
41 | func (m *refMap) Remove(ref unsafe.Pointer) {
42 | m.lock.Lock()
43 | defer m.lock.Unlock()
44 | delete(m.refs, ref)
45 | C.free(ref)
46 | }
47 |
--------------------------------------------------------------------------------
/cgo/testdata/errors.out.go:
--------------------------------------------------------------------------------
1 | // CGo errors:
2 | // testdata/errors.go:4:2: warning: some warning
3 | // testdata/errors.go:11:9: error: unknown type name 'someType'
4 | // testdata/errors.go:13:23: unexpected token )
5 |
6 | // Type checking errors after CGo processing:
7 | // testdata/errors.go:102: 2 << 10 (untyped int constant 2048) overflows uint8
8 | // testdata/errors.go:105: unknown field z in struct literal
9 | // testdata/errors.go:108: undeclared name: C.SOME_CONST_1
10 | // testdata/errors.go:110: C.SOME_CONST_3 (untyped int constant 1234) overflows byte
11 |
12 | package main
13 |
14 | import "unsafe"
15 |
16 | var _ unsafe.Pointer
17 |
18 | const C.SOME_CONST_3 = 1234
19 |
20 | type C.int16_t = int16
21 | type C.int32_t = int32
22 | type C.int64_t = int64
23 | type C.int8_t = int8
24 | type C.uint16_t = uint16
25 | type C.uint32_t = uint32
26 | type C.uint64_t = uint64
27 | type C.uint8_t = uint8
28 | type C.uintptr_t = uintptr
29 | type C.char uint8
30 | type C.int int32
31 | type C.long int32
32 | type C.longlong int64
33 | type C.schar int8
34 | type C.short int16
35 | type C.uchar uint8
36 | type C.uint uint32
37 | type C.ulong uint32
38 | type C.ulonglong uint64
39 | type C.ushort uint16
40 | type C.point_t = struct {
41 | x C.int
42 | y C.int
43 | }
44 |
--------------------------------------------------------------------------------
/src/examples/wasm/invoke/wasm.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const WASM_URL = 'wasm.wasm';
4 |
5 | var wasm;
6 |
7 | function updateRight() {
8 | const value = document.getElementById("a").value;
9 | window.runner(function (value) {
10 | document.getElementById("b").value = value;
11 | }, value);
12 | }
13 |
14 | function updateLeft() {
15 | const value = document.getElementById("b").value;
16 | window.runner(function (value) {
17 | document.getElementById("a").value = value;
18 | }, value);
19 | }
20 |
21 | function init() {
22 | document.querySelector('#a').oninput = updateRight;
23 | document.querySelector('#b').oninput = updateLeft;
24 |
25 | const go = new Go();
26 | if ('instantiateStreaming' in WebAssembly) {
27 | WebAssembly.instantiateStreaming(fetch(WASM_URL), go.importObject).then(function (obj) {
28 | wasm = obj.instance;
29 | go.run(wasm);
30 | })
31 | } else {
32 | fetch(WASM_URL).then(resp =>
33 | resp.arrayBuffer()
34 | ).then(bytes =>
35 | WebAssembly.instantiate(bytes, go.importObject).then(function (obj) {
36 | wasm = obj.instance;
37 | go.run(wasm);
38 | })
39 | )
40 | }
41 | }
42 |
43 | init();
44 |
--------------------------------------------------------------------------------
/src/machine/board_arduino_nano33_baremetal.go:
--------------------------------------------------------------------------------
1 | // +build sam,atsamd21,arduino_nano33
2 |
3 | package machine
4 |
5 | import (
6 | "device/sam"
7 | "runtime/interrupt"
8 | )
9 |
10 | // UART1 on the Arduino Nano 33 connects to the onboard NINA-W102 WiFi chip.
11 | var (
12 | UART1 = UART{
13 | Buffer: NewRingBuffer(),
14 | Bus: sam.SERCOM3_USART,
15 | SERCOM: 3,
16 | }
17 | )
18 |
19 | // UART2 on the Arduino Nano 33 connects to the normal TX/RX pins.
20 | var (
21 | UART2 = UART{
22 | Buffer: NewRingBuffer(),
23 | Bus: sam.SERCOM5_USART,
24 | SERCOM: 5,
25 | }
26 | )
27 |
28 | func init() {
29 | UART1.Interrupt = interrupt.New(sam.IRQ_SERCOM3, UART1.handleInterrupt)
30 | UART2.Interrupt = interrupt.New(sam.IRQ_SERCOM5, UART2.handleInterrupt)
31 | }
32 |
33 | // I2C on the Arduino Nano 33.
34 | var (
35 | I2C0 = I2C{
36 | Bus: sam.SERCOM4_I2CM,
37 | SERCOM: 4,
38 | }
39 | )
40 |
41 | // SPI on the Arduino Nano 33.
42 | var (
43 | SPI0 = SPI{
44 | Bus: sam.SERCOM1_SPI,
45 | SERCOM: 1,
46 | }
47 | )
48 |
49 | // SPI1 is connected to the NINA-W102 chip on the Arduino Nano 33.
50 | var (
51 | SPI1 = SPI{
52 | Bus: sam.SERCOM2_SPI,
53 | SERCOM: 2,
54 | }
55 | NINA_SPI = SPI1
56 | )
57 |
58 | // I2S on the Arduino Nano 33.
59 | var (
60 | I2S0 = I2S{Bus: sam.I2S}
61 | )
62 |
--------------------------------------------------------------------------------
/src/machine/board_hifive1b.go:
--------------------------------------------------------------------------------
1 | // +build hifive1b
2 |
3 | package machine
4 |
5 | const (
6 | D0 = P16
7 | D1 = P17
8 | D2 = P18
9 | D3 = P19 // Green LED/PWM (PWM1_PWM1)
10 | D4 = P20 // PWM (PWM1_PWM0)
11 | D5 = P21 // Blue LED/PWM (PWM1_PWM2)
12 | D6 = P22 // Red LED/PWM (PWM1_PWM3)
13 | D7 = P16
14 | D8 = NoPin // PWM?
15 | D9 = P01
16 | D10 = P02 // SPI1_CS0
17 | D11 = P03 // SPI1_DQ0
18 | D12 = P04 // SPI1_DQ1
19 | D13 = P05 // SPI1_SCK
20 | D14 = NoPin // not connected
21 | D15 = P09 // does not seem to work?
22 | D16 = P10 // PWM (PWM2_PWM0)
23 | D17 = P11 // PWM (PWM2_PWM1)
24 | D18 = P12 // SDA (I2C0_SDA)/PWM (PWM2_PWM2)
25 | D19 = P13 // SDL (I2C0_SCL)/PWM (PWM2_PWM3)
26 | )
27 |
28 | const (
29 | LED = LED1
30 | LED1 = LED_RED
31 | LED2 = LED_GREEN
32 | LED3 = LED_BLUE
33 | LED_RED = P22
34 | LED_GREEN = P19
35 | LED_BLUE = P21
36 | )
37 |
38 | const (
39 | // TODO: figure out the pin numbers for these.
40 | UART_TX_PIN = NoPin
41 | UART_RX_PIN = NoPin
42 | )
43 |
44 | // SPI pins
45 | const (
46 | SPI0_SCK_PIN = NoPin
47 | SPI0_MOSI_PIN = NoPin
48 | SPI0_MISO_PIN = NoPin
49 |
50 | SPI1_SCK_PIN = D13
51 | SPI1_MOSI_PIN = D11
52 | SPI1_MISO_PIN = D12
53 | )
54 |
55 | // I2C pins
56 | const (
57 | I2C0_SDA_PIN = D18
58 | I2C0_SCL_PIN = D19
59 | )
60 |
--------------------------------------------------------------------------------
/src/runtime/gc_leaking.go:
--------------------------------------------------------------------------------
1 | // +build gc.leaking
2 |
3 | package runtime
4 |
5 | // This GC implementation is the simplest useful memory allocator possible: it
6 | // only allocates memory and never frees it. For some constrained systems, it
7 | // may be the only memory allocator possible.
8 |
9 | import (
10 | "unsafe"
11 | )
12 |
13 | // Ever-incrementing pointer: no memory is freed.
14 | var heapptr = heapStart
15 |
16 | func alloc(size uintptr) unsafe.Pointer {
17 | // TODO: this can be optimized by not casting between pointers and ints so
18 | // much. And by using platform-native data types (e.g. *uint8 for 8-bit
19 | // systems).
20 | size = align(size)
21 | addr := heapptr
22 | heapptr += size
23 | if heapptr >= heapEnd {
24 | runtimePanic("out of memory")
25 | }
26 | for i := uintptr(0); i < uintptr(size); i += 4 {
27 | ptr := (*uint32)(unsafe.Pointer(addr + i))
28 | *ptr = 0
29 | }
30 | return unsafe.Pointer(addr)
31 | }
32 |
33 | func free(ptr unsafe.Pointer) {
34 | // Memory is never freed.
35 | }
36 |
37 | func GC() {
38 | // No-op.
39 | }
40 |
41 | func KeepAlive(x interface{}) {
42 | // Unimplemented. Only required with SetFinalizer().
43 | }
44 |
45 | func SetFinalizer(obj interface{}, finalizer interface{}) {
46 | // Unimplemented.
47 | }
48 |
49 | func initHeap() {
50 | // Nothing to initialize.
51 | }
52 |
--------------------------------------------------------------------------------
/src/syscall/syscall_libc.go:
--------------------------------------------------------------------------------
1 | // +build darwin
2 |
3 | package syscall
4 |
5 | import (
6 | "unsafe"
7 | )
8 |
9 | func Close(fd int) (err error) {
10 | return ENOSYS // TODO
11 | }
12 |
13 | func Write(fd int, p []byte) (n int, err error) {
14 | buf, count := splitSlice(p)
15 | n = libc_write(int32(fd), buf, uint(count))
16 | if n < 0 {
17 | err = getErrno()
18 | }
19 | return
20 | }
21 |
22 | func Read(fd int, p []byte) (n int, err error) {
23 | return 0, ENOSYS // TODO
24 | }
25 |
26 | func Seek(fd int, offset int64, whence int) (off int64, err error) {
27 | return 0, ENOSYS // TODO
28 | }
29 |
30 | func Open(path string, mode int, perm uint32) (fd int, err error) {
31 | return 0, ENOSYS // TODO
32 | }
33 |
34 | func Kill(pid int, sig Signal) (err error) {
35 | return ENOSYS // TODO
36 | }
37 |
38 | func Getpid() (pid int) {
39 | panic("unimplemented: getpid") // TODO
40 | }
41 |
42 | func Getenv(key string) (value string, found bool) {
43 | return "", false // TODO
44 | }
45 |
46 | func splitSlice(p []byte) (buf *byte, len uintptr) {
47 | slice := (*struct {
48 | buf *byte
49 | len uintptr
50 | cap uintptr
51 | })(unsafe.Pointer(&p))
52 | return slice.buf, slice.len
53 | }
54 |
55 | // ssize_t write(int fd, const void *buf, size_t count)
56 | //export write
57 | func libc_write(fd int32, buf *byte, count uint) int
58 |
--------------------------------------------------------------------------------
/transform/testdata/stringtobytes.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2 | target triple = "x86_64--linux"
3 |
4 | @str = constant [6 x i8] c"foobar"
5 |
6 | declare { i8*, i64, i64 } @runtime.stringToBytes(i8*, i64)
7 |
8 | declare void @printSlice(i8* nocapture readonly, i64, i64)
9 |
10 | declare void @writeToSlice(i8* nocapture, i64, i64)
11 |
12 | ; Test that runtime.stringToBytes can be fully optimized away.
13 | define void @testReadOnly() {
14 | entry:
15 | %0 = call fastcc { i8*, i64, i64 } @runtime.stringToBytes(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @str, i32 0, i32 0), i64 6)
16 | %1 = extractvalue { i8*, i64, i64 } %0, 0
17 | %2 = extractvalue { i8*, i64, i64 } %0, 1
18 | %3 = extractvalue { i8*, i64, i64 } %0, 2
19 | call fastcc void @printSlice(i8* %1, i64 %2, i64 %3)
20 | ret void
21 | }
22 |
23 | ; Test that even though the slice is written to, some values can be propagated.
24 | define void @testReadWrite() {
25 | entry:
26 | %0 = call fastcc { i8*, i64, i64 } @runtime.stringToBytes(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @str, i32 0, i32 0), i64 6)
27 | %1 = extractvalue { i8*, i64, i64 } %0, 0
28 | %2 = extractvalue { i8*, i64, i64 } %0, 1
29 | %3 = extractvalue { i8*, i64, i64 } %0, 2
30 | call fastcc void @writeToSlice(i8* %1, i64 %2, i64 %3)
31 | ret void
32 | }
33 |
--------------------------------------------------------------------------------
/interp/testdata/interface.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2 | target triple = "x86_64--linux"
3 |
4 | %runtime.typecodeID = type { %runtime.typecodeID*, i64 }
5 | %runtime.interfaceMethodInfo = type { i8*, i64 }
6 | %runtime.typeInInterface = type { %runtime.typecodeID*, %runtime.interfaceMethodInfo* }
7 |
8 | @main.v1 = global i1 0
9 | @"reflect/types.type:named:main.foo" = private constant %runtime.typecodeID { %runtime.typecodeID* @"reflect/types.type:basic:int", i64 0 }
10 | @"reflect/types.type:basic:int" = external constant %runtime.typecodeID
11 | @"typeInInterface:reflect/types.type:named:main.foo" = private constant %runtime.typeInInterface { %runtime.typecodeID* @"reflect/types.type:named:main.foo", %runtime.interfaceMethodInfo* null }
12 |
13 |
14 | declare i1 @runtime.typeAssert(i64, %runtime.typecodeID*, i8*, i8*)
15 |
16 | define void @runtime.initAll() unnamed_addr {
17 | entry:
18 | call void @main.init()
19 | ret void
20 | }
21 |
22 | define internal void @main.init() unnamed_addr {
23 | entry:
24 | ; Test type asserts.
25 | %typecode = call i1 @runtime.typeAssert(i64 ptrtoint (%runtime.typeInInterface* @"typeInInterface:reflect/types.type:named:main.foo" to i64), %runtime.typecodeID* @"reflect/types.type:named:main.foo", i8* undef, i8* null)
26 | store i1 %typecode, i1* @main.v1
27 | ret void
28 | }
29 |
--------------------------------------------------------------------------------
/src/runtime/gc_stack_raw.go:
--------------------------------------------------------------------------------
1 | // +build gc.conservative gc.extalloc
2 | // +build baremetal
3 |
4 | package runtime
5 |
6 | import "internal/task"
7 |
8 | // markStack marks all root pointers found on the stack.
9 | //
10 | // This implementation is conservative and relies on the stack top (provided by
11 | // the linker) and getting the current stack pointer from a register. Also, it
12 | // assumes a descending stack. Thus, it is not very portable.
13 | func markStack() {
14 | // Scan the current stack, and all current registers.
15 | scanCurrentStack()
16 |
17 | if !task.OnSystemStack() {
18 | // Mark system stack.
19 | markRoots(getSystemStackPointer(), stackTop)
20 | }
21 | }
22 |
23 | //go:export tinygo_scanCurrentStack
24 | func scanCurrentStack()
25 |
26 | //go:export tinygo_scanstack
27 | func scanstack(sp uintptr) {
28 | // Mark current stack.
29 | // This function is called by scanCurrentStack, after pushing all registers onto the stack.
30 | // Callee-saved registers have been pushed onto stack by tinygo_localscan, so this will scan them too.
31 | if task.OnSystemStack() {
32 | // This is the system stack.
33 | // Scan all words on the stack.
34 | markRoots(sp, stackTop)
35 | } else {
36 | // This is a goroutine stack.
37 | // It is an allocation, so scan it as if it were a value in a global.
38 | markRoot(0, sp)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/testdata/cgo/out.txt:
--------------------------------------------------------------------------------
1 | fortytwo: 42
2 | add: 8
3 | myint: 3 5
4 | myint size: 2
5 | longlong: -1099511627776
6 | global: 3
7 | defined ints: 5 5
8 | defined floats: +5.800000e+000 +5.800000e+000
9 | defined string: defined string
10 | defined char: 99
11 | 15: 15
12 | 25: 25
13 | callback 1: 50
14 | callback 2: 600
15 | bool: true true
16 | float: +3.100000e+000
17 | double: +3.200000e+000
18 | complex float: (+4.100000e+000+3.300000e+000i)
19 | complex double: (+4.200000e+000+3.400000e+000i)
20 | complex long double: (+4.300000e+000+3.500000e+000i)
21 | char match: true
22 | void* match: true true true
23 | int64_t match: true
24 | struct: true 256 -123456 +3.140000e+000
25 | array: 5 6 7
26 | union: true
27 | union s: 22
28 | union f: +3.140000e+000
29 | union global data: 5 8 1
30 | union local data: 5 8 1
31 | union s: true
32 | union f: +6.280000e+000
33 | union field: +6.280000e+000
34 | bitfield a: 15
35 | bitfield b: 1
36 | bitfield c: 2
37 | bitfield d: 47
38 | bitfield e: 5
39 | bitfield a: 7
40 | bitfield b: 0
41 | bitfield c: 3
42 | bitfield d: 47
43 | bitfield e: 5
44 | struct: 3 5
45 | n in chain: 3
46 | n in chain: 6
47 | n in chain: 7
48 | option: 12
49 | option A: 0
50 | option B: 1
51 | option C: -5
52 | option D: -4
53 | option E: 10
54 | option F: 11
55 | option G: 12
56 | option 2A: 20
57 | option 3A: 21
58 | enum width matches: true
59 | copied string: foobar
60 |
--------------------------------------------------------------------------------
/src/machine/buffer.go:
--------------------------------------------------------------------------------
1 | package machine
2 |
3 | import (
4 | "runtime/volatile"
5 | )
6 |
7 | const bufferSize = 128
8 |
9 | // RingBuffer is ring buffer implementation inspired by post at
10 | // https://www.embeddedrelated.com/showthread/comp.arch.embedded/77084-1.php
11 | type RingBuffer struct {
12 | rxbuffer [bufferSize]volatile.Register8
13 | head volatile.Register8
14 | tail volatile.Register8
15 | }
16 |
17 | // NewRingBuffer returns a new ring buffer.
18 | func NewRingBuffer() *RingBuffer {
19 | return &RingBuffer{}
20 | }
21 |
22 | // Used returns how many bytes in buffer have been used.
23 | func (rb *RingBuffer) Used() uint8 {
24 | return uint8(rb.head.Get() - rb.tail.Get())
25 | }
26 |
27 | // Put stores a byte in the buffer. If the buffer is already
28 | // full, the method will return false.
29 | func (rb *RingBuffer) Put(val byte) bool {
30 | if rb.Used() != bufferSize {
31 | rb.head.Set(rb.head.Get() + 1)
32 | rb.rxbuffer[rb.head.Get()%bufferSize].Set(val)
33 | return true
34 | }
35 | return false
36 | }
37 |
38 | // Get returns a byte from the buffer. If the buffer is empty,
39 | // the method will return a false as the second value.
40 | func (rb *RingBuffer) Get() (byte, bool) {
41 | if rb.Used() != 0 {
42 | rb.tail.Set(rb.tail.Get() + 1)
43 | return rb.rxbuffer[rb.tail.Get()%bufferSize].Get(), true
44 | }
45 | return 0, false
46 | }
47 |
--------------------------------------------------------------------------------
/src/syscall/syscall_darwin.go:
--------------------------------------------------------------------------------
1 | package syscall
2 |
3 | // This file defines errno and constants to match the darwin libsystem ABI.
4 | // Values have been determined experimentally by compiling some C code on macOS
5 | // with Clang and looking at the resulting LLVM IR.
6 |
7 | // This function returns the error location in the darwin ABI.
8 | // Discovered by compiling the following code using Clang:
9 | //
10 | // #include
11 | // int getErrno() {
12 | // return errno;
13 | // }
14 | //
15 | //export __error
16 | func libc___error() *int32
17 |
18 | // getErrno returns the current C errno. It may not have been caused by the last
19 | // call, so it should only be relied upon when the last call indicates an error
20 | // (for example, by returning -1).
21 | func getErrno() Errno {
22 | errptr := libc___error()
23 | return Errno(uintptr(*errptr))
24 | }
25 |
26 | const (
27 | ENOENT Errno = 2
28 | EINTR Errno = 4
29 | EMFILE Errno = 24
30 | EAGAIN Errno = 35
31 | ETIMEDOUT Errno = 60
32 | ENOSYS Errno = 78
33 | EWOULDBLOCK Errno = EAGAIN
34 | )
35 |
36 | type Signal int
37 |
38 | const (
39 | SIGCHLD Signal = 20
40 | SIGINT Signal = 2
41 | SIGKILL Signal = 9
42 | SIGTRAP Signal = 5
43 | SIGQUIT Signal = 3
44 | SIGTERM Signal = 15
45 | )
46 |
47 | const (
48 | O_RDONLY = 0
49 | O_WRONLY = 1
50 | O_RDWR = 2
51 | )
52 |
--------------------------------------------------------------------------------
/src/runtime/gc_stack_portable.go:
--------------------------------------------------------------------------------
1 | // +build gc.conservative gc.extalloc
2 | // +build !baremetal
3 |
4 | package runtime
5 |
6 | import (
7 | "unsafe"
8 | )
9 |
10 | //go:extern runtime.stackChainStart
11 | var stackChainStart *stackChainObject
12 |
13 | type stackChainObject struct {
14 | parent *stackChainObject
15 | numSlots uintptr
16 | }
17 |
18 | // markStack marks all root pointers found on the stack.
19 | //
20 | // This implementation is conservative and relies on the compiler inserting code
21 | // to manually push/pop stack objects that are stored in a linked list starting
22 | // with stackChainStart. Manually keeping track of stack values is _much_ more
23 | // expensive than letting the compiler do it and it inhibits a few important
24 | // optimizations, but it has the big advantage of being portable to basically
25 | // any ISA, including WebAssembly.
26 | func markStack() {
27 | stackObject := stackChainStart
28 | for stackObject != nil {
29 | start := uintptr(unsafe.Pointer(stackObject)) + unsafe.Sizeof(uintptr(0))*2
30 | end := start + stackObject.numSlots*unsafe.Alignof(uintptr(0))
31 | markRoots(start, end)
32 | stackObject = stackObject.parent
33 | }
34 | }
35 |
36 | // trackPointer is a stub function call inserted by the compiler during IR
37 | // construction. Calls to it are later replaced with regular stack bookkeeping
38 | // code.
39 | func trackPointer(ptr unsafe.Pointer)
40 |
--------------------------------------------------------------------------------
/testdata/cgo/main.c:
--------------------------------------------------------------------------------
1 | #include "main.h"
2 |
3 | int global = 3;
4 | bool globalBool = 1;
5 | bool globalBool2 = 10; // test narrowing
6 | float globalFloat = 3.1;
7 | double globalDouble = 3.2;
8 | _Complex float globalComplexFloat = 4.1+3.3i;
9 | _Complex double globalComplexDouble = 4.2+3.4i;
10 | _Complex double globalComplexLongDouble = 4.3+3.5i;
11 | char globalChar = 100;
12 | void *globalVoidPtrSet = &global;
13 | void *globalVoidPtrNull;
14 | int64_t globalInt64 = -(2LL << 40);
15 | collection_t globalStruct = {256, -123456, 3.14, 88};
16 | int globalStructSize = sizeof(globalStruct);
17 | short globalArray[3] = {5, 6, 7};
18 | joined_t globalUnion;
19 | int globalUnionSize = sizeof(globalUnion);
20 | option_t globalOption = optionG;
21 | bitfield_t globalBitfield = {244, 15, 1, 2, 47, 5};
22 |
23 | int smallEnumWidth = sizeof(option2_t);
24 |
25 | int fortytwo() {
26 | return 42;
27 | }
28 |
29 | int add(int a, int b) {
30 | return a + b;
31 | }
32 |
33 | int doCallback(int a, int b, binop_t callback) {
34 | return callback(a, b);
35 | }
36 |
37 | void store(int value, int *ptr) {
38 | *ptr = value;
39 | }
40 |
41 | void unionSetShort(short s) {
42 | globalUnion.s = s;
43 | }
44 |
45 | void unionSetFloat(float f) {
46 | globalUnion.f = f;
47 | }
48 |
49 | void unionSetData(short f0, short f1, short f2) {
50 | globalUnion.data[0] = 5;
51 | globalUnion.data[1] = 8;
52 | globalUnion.data[2] = 1;
53 | }
54 |
--------------------------------------------------------------------------------
/testdata/map.txt:
--------------------------------------------------------------------------------
1 | map length: 2
2 | map read: answer = 42
3 | answer = 42
4 | foo = 3
5 | map length: 1
6 | map read: data = 3
7 | data = 3
8 | map length: 12
9 | map read: three = 3
10 | one = 1
11 | two = 2
12 | three = 3
13 | four = 4
14 | five = 5
15 | six = 6
16 | seven = 7
17 | eight = 8
18 | nine = 9
19 | ten = 10
20 | eleven = 11
21 | twelve = 12
22 | map length: 12
23 | map read: ten = 10
24 | one = 1
25 | two = 2
26 | three = 3
27 | four = 4
28 | five = 5
29 | six = 6
30 | seven = 7
31 | eight = 8
32 | nine = 9
33 | ten = 10
34 | eleven = 11
35 | twelve = 12
36 | map length: 11
37 | map read: seven = 7
38 | one = 1
39 | two = 2
40 | three = 3
41 | four = 4
42 | five = 5
43 | seven = 7
44 | eight = 8
45 | nine = 9
46 | ten = 10
47 | eleven = 11
48 | twelve = 12
49 | lookup with comma-ok: eight 8 true
50 | lookup with comma-ok: nokey 0 false
51 | false true 2
52 | true false 0
53 | nilmap: 0
54 | 4
55 | 42
56 | 4321
57 | 5555
58 | itfMap[3]: 0
59 | itfMap[3.14]: 3
60 | itfMap[8]: 8
61 | itfMap[uint8(8)]: 80
62 | itfMap["eight"]: 800
63 | itfMap[[2]int{5, 2}]: 52
64 | itfMap[true]: 1
65 | itfMap[8]: 0
66 | floatMap[42]: 84
67 | floatMap[43]: 0
68 | floatMap[42]: 0
69 | structMap[{"tau", 6.28}]: 5
70 | structMap[{"Tau", 6.28}]: 0
71 | structMap[{"tau", 3.14}]: 0
72 | structMap[{"tau", 6.28}]: 0
73 | tested preallocated map
74 | tested growing of a map
75 |
--------------------------------------------------------------------------------
/compiler/ircheck/errors.go:
--------------------------------------------------------------------------------
1 | package ircheck
2 |
3 | import (
4 | "go/scanner"
5 | "go/token"
6 | "path/filepath"
7 |
8 | "tinygo.org/x/go-llvm"
9 | )
10 |
11 | // errorAt returns an error value at the location of the instruction.
12 | // The location information may not be complete as it depends on debug
13 | // information in the IR.
14 | func errorAt(inst llvm.Value, msg string) scanner.Error {
15 | return scanner.Error{
16 | Pos: getPosition(inst),
17 | Msg: msg,
18 | }
19 | }
20 |
21 | // getPosition returns the position information for the given value, as far as
22 | // it is available.
23 | func getPosition(val llvm.Value) token.Position {
24 | if !val.IsAInstruction().IsNil() {
25 | loc := val.InstructionDebugLoc()
26 | if loc.IsNil() {
27 | return token.Position{}
28 | }
29 | file := loc.LocationScope().ScopeFile()
30 | return token.Position{
31 | Filename: filepath.Join(file.FileDirectory(), file.FileFilename()),
32 | Line: int(loc.LocationLine()),
33 | Column: int(loc.LocationColumn()),
34 | }
35 | } else if !val.IsAFunction().IsNil() {
36 | loc := val.Subprogram()
37 | if loc.IsNil() {
38 | return token.Position{}
39 | }
40 | file := loc.ScopeFile()
41 | return token.Position{
42 | Filename: filepath.Join(file.FileDirectory(), file.FileFilename()),
43 | Line: int(loc.SubprogramLine()),
44 | }
45 | } else {
46 | return token.Position{}
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/machine/i2s.go:
--------------------------------------------------------------------------------
1 | // +build sam
2 |
3 | // This is the definition for I2S bus functions.
4 | // Actual implementations if available for any given hardware
5 | // are to be found in its the board definition.
6 | //
7 | // For more info about I2S, see: https://en.wikipedia.org/wiki/I%C2%B2S
8 | //
9 |
10 | package machine
11 |
12 | type I2SMode uint8
13 | type I2SStandard uint8
14 | type I2SClockSource uint8
15 | type I2SDataFormat uint8
16 |
17 | const (
18 | I2SModeMaster I2SMode = iota
19 | I2SModeSlave
20 | I2SModePDM
21 | )
22 |
23 | const (
24 | I2StandardPhilips I2SStandard = iota
25 | I2SStandardMSB
26 | I2SStandardLSB
27 | )
28 |
29 | const (
30 | I2SClockSourceInternal I2SClockSource = iota
31 | I2SClockSourceExternal
32 | )
33 |
34 | const (
35 | I2SDataFormatDefault I2SDataFormat = 0
36 | I2SDataFormat8bit = 8
37 | I2SDataFormat16bit = 16
38 | I2SDataFormat24bit = 24
39 | I2SDataFormat32bit = 32
40 | )
41 |
42 | // All fields are optional and may not be required or used on a particular platform.
43 | type I2SConfig struct {
44 | SCK Pin
45 | WS Pin
46 | SD Pin
47 | Mode I2SMode
48 | Standard I2SStandard
49 | ClockSource I2SClockSource
50 | DataFormat I2SDataFormat
51 | AudioFrequency uint32
52 | MasterClockOutput bool
53 | Stereo bool
54 | }
55 |
--------------------------------------------------------------------------------
/src/machine/machine_atmega328p.go:
--------------------------------------------------------------------------------
1 | // +build avr,atmega328p
2 |
3 | package machine
4 |
5 | import (
6 | "device/avr"
7 | "runtime/volatile"
8 | )
9 |
10 | const irq_USART0_RX = avr.IRQ_USART_RX
11 |
12 | // Configure sets the pin to input or output.
13 | func (p Pin) Configure(config PinConfig) {
14 | if config.Mode == PinOutput { // set output bit
15 | if p < 8 {
16 | avr.DDRD.SetBits(1 << uint8(p))
17 | } else if p < 14 {
18 | avr.DDRB.SetBits(1 << uint8(p-8))
19 | } else {
20 | avr.DDRC.SetBits(1 << uint8(p-14))
21 | }
22 | } else { // configure input: clear output bit
23 | if p < 8 {
24 | avr.DDRD.ClearBits(1 << uint8(p))
25 | } else if p < 14 {
26 | avr.DDRB.ClearBits(1 << uint8(p-8))
27 | } else {
28 | avr.DDRC.ClearBits(1 << uint8(p-14))
29 | }
30 | }
31 | }
32 |
33 | // Get returns the current value of a GPIO pin.
34 | func (p Pin) Get() bool {
35 | if p < 8 {
36 | val := avr.PIND.Get() & (1 << uint8(p))
37 | return (val > 0)
38 | } else if p < 14 {
39 | val := avr.PINB.Get() & (1 << uint8(p-8))
40 | return (val > 0)
41 | } else {
42 | val := avr.PINC.Get() & (1 << uint8(p-14))
43 | return (val > 0)
44 | }
45 | }
46 |
47 | func (p Pin) getPortMask() (*volatile.Register8, uint8) {
48 | if p < 8 {
49 | return avr.PORTD, 1 << uint8(p)
50 | } else if p < 14 {
51 | return avr.PORTB, 1 << uint8(p-8)
52 | } else {
53 | return avr.PORTC, 1 << uint8(p-14)
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/transform/maps.go:
--------------------------------------------------------------------------------
1 | package transform
2 |
3 | import (
4 | "tinygo.org/x/go-llvm"
5 | )
6 |
7 | // OptimizeMaps eliminates created but unused maps.
8 | //
9 | // In the future, this should statically allocate created but never modified
10 | // maps. This has not yet been implemented, however.
11 | func OptimizeMaps(mod llvm.Module) {
12 | hashmapMake := mod.NamedFunction("runtime.hashmapMake")
13 | if hashmapMake.IsNil() {
14 | // nothing to optimize
15 | return
16 | }
17 |
18 | hashmapBinarySet := mod.NamedFunction("runtime.hashmapBinarySet")
19 | hashmapStringSet := mod.NamedFunction("runtime.hashmapStringSet")
20 |
21 | for _, makeInst := range getUses(hashmapMake) {
22 | updateInsts := []llvm.Value{}
23 | unknownUses := false // are there any uses other than setting a value?
24 |
25 | for _, use := range getUses(makeInst) {
26 | if use := use.IsACallInst(); !use.IsNil() {
27 | switch use.CalledValue() {
28 | case hashmapBinarySet, hashmapStringSet:
29 | updateInsts = append(updateInsts, use)
30 | default:
31 | unknownUses = true
32 | }
33 | } else {
34 | unknownUses = true
35 | }
36 | }
37 |
38 | if !unknownUses {
39 | // This map can be entirely removed, as it is only created but never
40 | // used.
41 | for _, inst := range updateInsts {
42 | inst.EraseFromParentAsInstruction()
43 | }
44 | makeInst.EraseFromParentAsInstruction()
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/transform/testdata/wasm-abi.out.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
2 | target triple = "wasm32-unknown-unknown-wasm"
3 |
4 | declare i64 @"externalCall$i64wrap"(i8*, i32, i64)
5 |
6 | define internal i64 @testCall(i8* %ptr, i32 %len, i64 %foo) {
7 | %i64asptr = alloca i64
8 | %i64asptr1 = alloca i64
9 | store i64 %foo, i64* %i64asptr1
10 | call void @externalCall(i64* %i64asptr, i8* %ptr, i32 %len, i64* %i64asptr1)
11 | %retval = load i64, i64* %i64asptr
12 | ret i64 %retval
13 | }
14 |
15 | define internal i64 @testCallNonEntry(i8* %ptr, i32 %len) {
16 | entry:
17 | %i64asptr = alloca i64
18 | %i64asptr1 = alloca i64
19 | br label %bb1
20 |
21 | bb1: ; preds = %entry
22 | store i64 3, i64* %i64asptr1
23 | call void @externalCall(i64* %i64asptr, i8* %ptr, i32 %len, i64* %i64asptr1)
24 | %retval = load i64, i64* %i64asptr
25 | ret i64 %retval
26 | }
27 |
28 | define internal void @"exportedFunction$i64wrap"(i64 %foo) unnamed_addr {
29 | %unused = shl i64 %foo, 1
30 | ret void
31 | }
32 |
33 | define internal void @callExportedFunction(i64 %foo) {
34 | call void @"exportedFunction$i64wrap"(i64 %foo)
35 | ret void
36 | }
37 |
38 | declare void @externalCall(i64*, i8*, i32, i64*)
39 |
40 | define void @exportedFunction(i64* %0) {
41 | entry:
42 | %i64 = load i64, i64* %0
43 | call void @"exportedFunction$i64wrap"(i64 %i64)
44 | ret void
45 | }
46 |
--------------------------------------------------------------------------------
/src/machine/machine_atsamd51g19.go:
--------------------------------------------------------------------------------
1 | // +build sam,atsamd51,atsamd51g19
2 |
3 | // Peripheral abstraction layer for the atsamd51.
4 | //
5 | // Datasheet:
6 | // http://ww1.microchip.com/downloads/en/DeviceDoc/60001507C.pdf
7 | //
8 | package machine
9 |
10 | import "device/sam"
11 |
12 | const HSRAM_SIZE = 0x00030000
13 |
14 | // InitPWM initializes the PWM interface.
15 | func InitPWM() {
16 | // turn on timer clocks used for PWM
17 | sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_TCC0_ | sam.MCLK_APBBMASK_TCC1_)
18 | sam.MCLK.APBCMASK.SetBits(sam.MCLK_APBCMASK_TCC2_)
19 |
20 | //use clock generator 0
21 | sam.GCLK.PCHCTRL[25].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) |
22 | sam.GCLK_PCHCTRL_CHEN)
23 | sam.GCLK.PCHCTRL[29].Set((sam.GCLK_PCHCTRL_GEN_GCLK0 << sam.GCLK_PCHCTRL_GEN_Pos) |
24 | sam.GCLK_PCHCTRL_CHEN)
25 | }
26 |
27 | // getTimer returns the timer to be used for PWM on this pin
28 | func (pwm PWM) getTimer() *sam.TCC_Type {
29 | switch pwm.Pin {
30 | case PA16:
31 | return sam.TCC1
32 | case PA17:
33 | return sam.TCC1
34 | case PA14:
35 | return sam.TCC2
36 | case PA15:
37 | return sam.TCC2
38 | case PA18:
39 | return sam.TCC1
40 | case PA19:
41 | return sam.TCC1
42 | case PA20:
43 | return sam.TCC0
44 | case PA21:
45 | return sam.TCC0
46 | case PA23:
47 | return sam.TCC0
48 | case PA22:
49 | return sam.TCC0
50 | default:
51 | return nil // not supported on this pin
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/machine/machine_stm32.go:
--------------------------------------------------------------------------------
1 | // +build stm32
2 |
3 | package machine
4 |
5 | // Peripheral abstraction layer for the stm32.
6 |
7 | type PinMode uint8
8 |
9 | // Peripheral operations sequence:
10 | // 1. Enable the clock to the alternate function.
11 | // 2. Enable clock to corresponding GPIO
12 | // 3. Attach the alternate function.
13 | // 4. Configure the input-output port and pins (of the corresponding GPIOx) to match the AF .
14 | // 5. If desired enable the nested vector interrupt control to generate interrupts.
15 | // 6. Program the AF/peripheral for the required configuration (eg baud rate for a USART) .
16 |
17 | // Given that the stm32 family has the AF and GPIO on different registers based on the chip,
18 | // use the main function here for configuring, and use hooks in the more specific chip
19 | // definition files
20 | // Also, the stm32f1xx series handles things differently from the stm32f0/2/3/4
21 |
22 | // ---------- General pin operations ----------
23 |
24 | // Set the pin to high or low.
25 | // Warning: only use this on an output pin!
26 | func (p Pin) Set(high bool) {
27 | port := p.getPort()
28 | pin := uint8(p) % 16
29 | if high {
30 | port.BSRR.Set(1 << pin)
31 | } else {
32 | port.BSRR.Set(1 << (pin + 16))
33 | }
34 | }
35 |
36 | // Get returns the current value of a GPIO pin.
37 | func (p Pin) Get() bool {
38 | port := p.getPort()
39 | pin := uint8(p) % 16
40 | val := port.IDR.Get() & (1 << pin)
41 | return (val > 0)
42 | }
43 |
--------------------------------------------------------------------------------
/transform/testdata/gc-globals.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
2 | target triple = "wasm32-unknown-unknown-wasm"
3 |
4 | %runtime._string = type { i8*, i32 }
5 | %runtime._interface = type { i32, i8* }
6 |
7 | @globalInt = global i32 5
8 | @globalString = global %runtime._string zeroinitializer
9 | @globalInterface = global %runtime._interface zeroinitializer
10 | @constString = constant %runtime._string zeroinitializer
11 | @constInterface = constant %runtime._interface zeroinitializer
12 | @runtime.trackedGlobalsLength = external global i32
13 | @runtime.trackedGlobalsBitmap = external global [0 x i8]
14 | @runtime.trackedGlobalsStart = external global i32
15 |
16 | define void @main() {
17 | %1 = load i32, i32* @globalInt
18 | %2 = load %runtime._string, %runtime._string* @globalString
19 | %3 = load %runtime._interface, %runtime._interface* @globalInterface
20 | %4 = load %runtime._string, %runtime._string* @constString
21 | %5 = load %runtime._interface, %runtime._interface* @constInterface
22 | ret void
23 | }
24 |
25 | define void @runtime.markGlobals() {
26 | ; Very small subset of what runtime.markGlobals would really do.
27 | ; Just enough to make sure the transformation is correct.
28 | %1 = load i32, i32* @runtime.trackedGlobalsStart
29 | %2 = load i32, i32* @runtime.trackedGlobalsLength
30 | %3 = getelementptr inbounds [0 x i8], [0 x i8]* @runtime.trackedGlobalsBitmap, i32 0, i32 0
31 | %4 = load i8, i8* %3
32 | ret void
33 | }
34 |
--------------------------------------------------------------------------------
/src/machine/machine.go:
--------------------------------------------------------------------------------
1 | package machine
2 |
3 | import "errors"
4 |
5 | var (
6 | ErrInvalidInputPin = errors.New("machine: invalid input pin")
7 | ErrInvalidOutputPin = errors.New("machine: invalid output pin")
8 | ErrInvalidClockPin = errors.New("machine: invalid clock pin")
9 | ErrInvalidDataPin = errors.New("machine: invalid data pin")
10 | )
11 |
12 | type PinConfig struct {
13 | Mode PinMode
14 | }
15 |
16 | // Pin is a single pin on a chip, which may be connected to other hardware
17 | // devices. It can either be used directly as GPIO pin or it can be used in
18 | // other peripherals like ADC, I2C, etc.
19 | type Pin int8
20 |
21 | // NoPin explicitly indicates "not a pin". Use this pin if you want to leave one
22 | // of the pins in a peripheral unconfigured (if supported by the hardware).
23 | const NoPin = Pin(-1)
24 |
25 | // High sets this GPIO pin to high, assuming it has been configured as an output
26 | // pin. It is hardware dependent (and often undefined) what happens if you set a
27 | // pin to high that is not configured as an output pin.
28 | func (p Pin) High() {
29 | p.Set(true)
30 | }
31 |
32 | // Low sets this GPIO pin to low, assuming it has been configured as an output
33 | // pin. It is hardware dependent (and often undefined) what happens if you set a
34 | // pin to low that is not configured as an output pin.
35 | func (p Pin) Low() {
36 | p.Set(false)
37 | }
38 |
39 | type PWM struct {
40 | Pin Pin
41 | }
42 |
43 | type ADC struct {
44 | Pin Pin
45 | }
46 |
--------------------------------------------------------------------------------
/src/machine/usb_nrf52840_reset_uf2.go:
--------------------------------------------------------------------------------
1 | // +build nrf52840,nrf52840_reset_uf2
2 |
3 | package machine
4 |
5 | import (
6 | "device/arm"
7 | "device/nrf"
8 | )
9 |
10 | const (
11 | DFU_MAGIC_SERIAL_ONLY_RESET = 0x4e
12 | DFU_MAGIC_UF2_RESET = 0x57
13 | DFU_MAGIC_OTA_RESET = 0xA8
14 | )
15 |
16 | // checkShouldReset is called by the USB-CDC implementation to check whether to
17 | // reset into the bootloader/OTA and if so, resets the chip appropriately.
18 | func checkShouldReset() {
19 | if usbLineInfo.dwDTERate == 1200 && usbLineInfo.lineState&usb_CDC_LINESTATE_DTR == 0 {
20 | EnterUF2Bootloader()
21 | }
22 | }
23 |
24 | // EnterSerialBootloader resets the chip into the serial bootloader. After
25 | // reset, it can be flashed using serial/nrfutil.
26 | func EnterSerialBootloader() {
27 | arm.DisableInterrupts()
28 | nrf.POWER.GPREGRET.Set(DFU_MAGIC_SERIAL_ONLY_RESET)
29 | arm.SystemReset()
30 | }
31 |
32 | // EnterUF2Bootloader resets the chip into the UF2 bootloader. After reset, it
33 | // can be flashed via nrfutil or by copying a UF2 file to the mass storage device
34 | func EnterUF2Bootloader() {
35 | arm.DisableInterrupts()
36 | nrf.POWER.GPREGRET.Set(DFU_MAGIC_UF2_RESET)
37 | arm.SystemReset()
38 | }
39 |
40 | // EnterOTABootloader resets the chip into the bootloader so that it can be
41 | // flashed via an OTA update
42 | func EnterOTABootloader() {
43 | arm.DisableInterrupts()
44 | nrf.POWER.GPREGRET.Set(DFU_MAGIC_OTA_RESET)
45 | arm.SystemReset()
46 | }
47 |
--------------------------------------------------------------------------------
/src/machine/board_atsamd21.go:
--------------------------------------------------------------------------------
1 | // +build sam,atsamd21 arduino_nano33 circuitplay_express
2 |
3 | package machine
4 |
5 | // Return the current CPU frequency in hertz.
6 | func CPUFrequency() uint32 {
7 | return 48000000
8 | }
9 |
10 | // Hardware pins
11 | const (
12 | PA00 Pin = 0
13 | PA01 Pin = 1
14 | PA02 Pin = 2
15 | PA03 Pin = 3
16 | PA04 Pin = 4
17 | PA05 Pin = 5
18 | PA06 Pin = 6
19 | PA07 Pin = 7
20 | PA08 Pin = 8
21 | PA09 Pin = 9
22 | PA10 Pin = 10
23 | PA11 Pin = 11
24 | PA12 Pin = 12
25 | PA13 Pin = 13
26 | PA14 Pin = 14
27 | PA15 Pin = 15
28 | PA16 Pin = 16
29 | PA17 Pin = 17
30 | PA18 Pin = 18
31 | PA19 Pin = 19
32 | PA20 Pin = 20
33 | PA21 Pin = 21
34 | PA22 Pin = 22
35 | PA23 Pin = 23
36 | PA24 Pin = 24
37 | PA25 Pin = 25
38 | PA26 Pin = 26
39 | PA27 Pin = 27
40 | PA28 Pin = 28
41 | PA29 Pin = 29
42 | PA30 Pin = 30
43 | PA31 Pin = 31
44 | PB00 Pin = 32
45 | PB01 Pin = 33
46 | PB02 Pin = 34
47 | PB03 Pin = 35
48 | PB04 Pin = 36
49 | PB05 Pin = 37
50 | PB06 Pin = 38
51 | PB07 Pin = 39
52 | PB08 Pin = 40
53 | PB09 Pin = 41
54 | PB10 Pin = 42
55 | PB11 Pin = 43
56 | PB12 Pin = 44
57 | PB13 Pin = 45
58 | PB14 Pin = 46
59 | PB15 Pin = 47
60 | PB16 Pin = 48
61 | PB17 Pin = 49
62 | PB18 Pin = 50
63 | PB19 Pin = 51
64 | PB20 Pin = 52
65 | PB21 Pin = 53
66 | PB22 Pin = 54
67 | PB23 Pin = 55
68 | PB24 Pin = 56
69 | PB25 Pin = 57
70 | PB26 Pin = 58
71 | PB27 Pin = 59
72 | PB28 Pin = 60
73 | PB29 Pin = 61
74 | PB30 Pin = 62
75 | PB31 Pin = 63
76 | )
77 |
--------------------------------------------------------------------------------
/src/runtime/runtime_tinygoriscv_qemu.go:
--------------------------------------------------------------------------------
1 | // +build tinygo.riscv,virt,qemu
2 |
3 | package runtime
4 |
5 | import (
6 | "device/riscv"
7 | "runtime/volatile"
8 | "unsafe"
9 | )
10 |
11 | // This file implements the VirtIO RISC-V interface implemented in QEMU, which
12 | // is an interface designed for emulation.
13 |
14 | type timeUnit int64
15 |
16 | const tickMicros = 1
17 |
18 | var timestamp timeUnit
19 |
20 | func postinit() {}
21 |
22 | //export main
23 | func main() {
24 | preinit()
25 | run()
26 | abort()
27 | }
28 |
29 | const asyncScheduler = false
30 |
31 | func sleepTicks(d timeUnit) {
32 | // TODO: actually sleep here for the given time.
33 | timestamp += d
34 | }
35 |
36 | func ticks() timeUnit {
37 | return timestamp
38 | }
39 |
40 | // Memory-mapped I/O as defined by QEMU.
41 | // Source: https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c
42 | // Technically this is an implementation detail but hopefully they won't change
43 | // the memory-mapped I/O registers.
44 | var (
45 | // UART0 output register.
46 | stdoutWrite = (*volatile.Register8)(unsafe.Pointer(uintptr(0x10000000)))
47 | // SiFive test finisher
48 | testFinisher = (*volatile.Register16)(unsafe.Pointer(uintptr(0x100000)))
49 | )
50 |
51 | func putchar(c byte) {
52 | stdoutWrite.Set(uint8(c))
53 | }
54 |
55 | func abort() {
56 | // Make sure the QEMU process exits.
57 | testFinisher.Set(0x5555) // FINISHER_PASS
58 |
59 | // Lock up forever (as a fallback).
60 | for {
61 | riscv.Asm("wfi")
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/examples/wasm/main/index.html:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 | Go wasm
12 |
13 |
14 |
15 |
20 |
21 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/src/runtime/volatile/volatile.go:
--------------------------------------------------------------------------------
1 | // Package volatile provides definitions for volatile loads and stores. These
2 | // are implemented as compiler builtins.
3 | //
4 | // The load operations load a volatile value. The store operations store to a
5 | // volatile value. The compiler will emit exactly one load or store operation
6 | // when possible and will not reorder volatile operations. However, the compiler
7 | // may move other operations across load/store operations, so make sure that all
8 | // relevant loads/stores are done in a volatile way if this is a problem.
9 | //
10 | // These loads and stores are commonly used to read/write values from memory
11 | // mapped peripheral devices. They do not provide atomicity, use the sync/atomic
12 | // package for that.
13 | //
14 | // For more details: https://llvm.org/docs/LangRef.html#volatile-memory-accesses
15 | // and https://blog.regehr.org/archives/28.
16 | package volatile
17 |
18 | // LoadUint8 loads the volatile value *addr.
19 | func LoadUint8(addr *uint8) (val uint8)
20 |
21 | // LoadUint16 loads the volatile value *addr.
22 | func LoadUint16(addr *uint16) (val uint16)
23 |
24 | // LoadUint32 loads the volatile value *addr.
25 | func LoadUint32(addr *uint32) (val uint32)
26 |
27 | // StoreUint8 stores val to the volatile value *addr.
28 | func StoreUint8(addr *uint8, val uint8)
29 |
30 | // StoreUint16 stores val to the volatile value *addr.
31 | func StoreUint16(addr *uint16, val uint16)
32 |
33 | // StoreUint32 stores val to the volatile value *addr.
34 | func StoreUint32(addr *uint32, val uint32)
35 |
--------------------------------------------------------------------------------
/transform/testdata/maps.out.ll:
--------------------------------------------------------------------------------
1 | target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
2 | target triple = "armv7m-none-eabi"
3 |
4 | %runtime.hashmap = type { %runtime.hashmap*, i8*, i32, i8, i8, i8 }
5 |
6 | @answer = constant [6 x i8] c"answer"
7 |
8 | declare nonnull %runtime.hashmap* @runtime.hashmapMake(i8, i8, i32)
9 |
10 | declare void @runtime.hashmapStringSet(%runtime.hashmap* nocapture, i8*, i32, i8* nocapture readonly)
11 |
12 | declare i1 @runtime.hashmapStringGet(%runtime.hashmap* nocapture, i8*, i32, i8* nocapture)
13 |
14 | define void @testUnused() {
15 | ret void
16 | }
17 |
18 | define i32 @testReadonly() {
19 | %map = call %runtime.hashmap* @runtime.hashmapMake(i8 4, i8 4, i32 0)
20 | %hashmap.value = alloca i32
21 | store i32 42, i32* %hashmap.value
22 | %hashmap.value.bitcast = bitcast i32* %hashmap.value to i8*
23 | call void @runtime.hashmapStringSet(%runtime.hashmap* %map, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @answer, i32 0, i32 0), i32 6, i8* %hashmap.value.bitcast)
24 | %hashmap.value2 = alloca i32
25 | %hashmap.value2.bitcast = bitcast i32* %hashmap.value2 to i8*
26 | %commaOk = call i1 @runtime.hashmapStringGet(%runtime.hashmap* %map, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @answer, i32 0, i32 0), i32 6, i8* %hashmap.value2.bitcast)
27 | %loadedValue = load i32, i32* %hashmap.value2
28 | ret i32 %loadedValue
29 | }
30 |
31 | define %runtime.hashmap* @testUsed() {
32 | %1 = call %runtime.hashmap* @runtime.hashmapMake(i8 4, i8 4, i32 0)
33 | ret %runtime.hashmap* %1
34 | }
35 |
--------------------------------------------------------------------------------
/src/machine/board_microbit.go:
--------------------------------------------------------------------------------
1 | // +build microbit
2 |
3 | package machine
4 |
5 | // The micro:bit does not have a 32kHz crystal on board.
6 | const HasLowFrequencyCrystal = false
7 |
8 | // Buttons on the micro:bit (A and B)
9 | const (
10 | BUTTON Pin = BUTTONA
11 | BUTTONA Pin = 17
12 | BUTTONB Pin = 26
13 | )
14 |
15 | // UART pins
16 | const (
17 | UART_TX_PIN Pin = 24
18 | UART_RX_PIN Pin = 25
19 | )
20 |
21 | // ADC pins
22 | const (
23 | ADC0 Pin = 3 // P0 on the board
24 | ADC1 Pin = 2 // P1 on the board
25 | ADC2 Pin = 1 // P2 on the board
26 | )
27 |
28 | // I2C pins
29 | const (
30 | SDA_PIN Pin = 30 // P20 on the board
31 | SCL_PIN Pin = 0 // P19 on the board
32 | )
33 |
34 | // SPI pins
35 | const (
36 | SPI0_SCK_PIN Pin = 23 // P13 on the board
37 | SPI0_MOSI_PIN Pin = 21 // P15 on the board
38 | SPI0_MISO_PIN Pin = 22 // P14 on the board
39 | )
40 |
41 | // GPIO/Analog pins
42 | const (
43 | P0 Pin = 3
44 | P1 Pin = 2
45 | P2 Pin = 1
46 | P3 Pin = 4
47 | P4 Pin = 5
48 | P5 Pin = 17
49 | P6 Pin = 12
50 | P7 Pin = 11
51 | P8 Pin = 18
52 | P9 Pin = 10
53 | P10 Pin = 6
54 | P11 Pin = 26
55 | P12 Pin = 20
56 | P13 Pin = 23
57 | P14 Pin = 22
58 | P15 Pin = 21
59 | P16 Pin = 16
60 | )
61 |
62 | // LED matrix pins
63 | const (
64 | LED_COL_1 Pin = 4
65 | LED_COL_2 Pin = 5
66 | LED_COL_3 Pin = 6
67 | LED_COL_4 Pin = 7
68 | LED_COL_5 Pin = 8
69 | LED_COL_6 Pin = 9
70 | LED_COL_7 Pin = 10
71 | LED_COL_8 Pin = 11
72 | LED_COL_9 Pin = 12
73 | LED_ROW_1 Pin = 13
74 | LED_ROW_2 Pin = 14
75 | LED_ROW_3 Pin = 15
76 | )
77 |
--------------------------------------------------------------------------------
/src/runtime/runtime_atsamd21e18.go:
--------------------------------------------------------------------------------
1 | // +build sam,atsamd21,atsamd21e18
2 |
3 | package runtime
4 |
5 | import (
6 | "device/sam"
7 | )
8 |
9 | func initSERCOMClocks() {
10 | // Turn on clock to SERCOM0 for UART0
11 | sam.PM.APBCMASK.SetBits(sam.PM_APBCMASK_SERCOM0_)
12 |
13 | // Use GCLK0 for SERCOM0 aka UART0
14 | // GCLK_CLKCTRL_ID( clockId ) | // Generic Clock 0 (SERCOMx)
15 | // GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source
16 | // GCLK_CLKCTRL_CLKEN ;
17 | sam.GCLK.CLKCTRL.Set((sam.GCLK_CLKCTRL_ID_SERCOM0_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
18 | (sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
19 | sam.GCLK_CLKCTRL_CLKEN)
20 | waitForSync()
21 |
22 | // Turn on clock to SERCOM1
23 | sam.PM.APBCMASK.SetBits(sam.PM_APBCMASK_SERCOM1_)
24 | sam.GCLK.CLKCTRL.Set((sam.GCLK_CLKCTRL_ID_SERCOM1_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
25 | (sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
26 | sam.GCLK_CLKCTRL_CLKEN)
27 | waitForSync()
28 |
29 | // Turn on clock to SERCOM2
30 | sam.PM.APBCMASK.SetBits(sam.PM_APBCMASK_SERCOM2_)
31 | sam.GCLK.CLKCTRL.Set((sam.GCLK_CLKCTRL_ID_SERCOM2_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
32 | (sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
33 | sam.GCLK_CLKCTRL_CLKEN)
34 | waitForSync()
35 |
36 | // Turn on clock to SERCOM3
37 | sam.PM.APBCMASK.SetBits(sam.PM_APBCMASK_SERCOM3_)
38 | sam.GCLK.CLKCTRL.Set((sam.GCLK_CLKCTRL_ID_SERCOM3_CORE << sam.GCLK_CLKCTRL_ID_Pos) |
39 | (sam.GCLK_CLKCTRL_GEN_GCLK0 << sam.GCLK_CLKCTRL_GEN_Pos) |
40 | sam.GCLK_CLKCTRL_CLKEN)
41 | waitForSync()
42 | }
43 |
--------------------------------------------------------------------------------
/src/runtime/float.go:
--------------------------------------------------------------------------------
1 | // Copyright 2017 The Go Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style
3 | // license that can be found in the LICENSE file.
4 |
5 | package runtime
6 |
7 | import "unsafe"
8 |
9 | var inf = float64frombits(0x7FF0000000000000)
10 |
11 | // isNaN reports whether f is an IEEE 754 ``not-a-number'' value.
12 | func isNaN(f float64) (is bool) {
13 | // IEEE 754 says that only NaNs satisfy f != f.
14 | return f != f
15 | }
16 |
17 | // isFinite reports whether f is neither NaN nor an infinity.
18 | func isFinite(f float64) bool {
19 | return !isNaN(f - f)
20 | }
21 |
22 | // isInf reports whether f is an infinity.
23 | func isInf(f float64) bool {
24 | return !isNaN(f) && !isFinite(f)
25 | }
26 |
27 | // Abs returns the absolute value of x.
28 | //
29 | // Special cases are:
30 | // Abs(±Inf) = +Inf
31 | // Abs(NaN) = NaN
32 | func abs(x float64) float64 {
33 | const sign = 1 << 63
34 | return float64frombits(float64bits(x) &^ sign)
35 | }
36 |
37 | // copysign returns a value with the magnitude
38 | // of x and the sign of y.
39 | func copysign(x, y float64) float64 {
40 | const sign = 1 << 63
41 | return float64frombits(float64bits(x)&^sign | float64bits(y)&sign)
42 | }
43 |
44 | // Float64bits returns the IEEE 754 binary representation of f.
45 | func float64bits(f float64) uint64 {
46 | return *(*uint64)(unsafe.Pointer(&f))
47 | }
48 |
49 | // Float64frombits returns the floating point number corresponding
50 | // the IEEE 754 binary representation b.
51 | func float64frombits(b uint64) float64 {
52 | return *(*float64)(unsafe.Pointer(&b))
53 | }
54 |
--------------------------------------------------------------------------------
/src/runtime/runtime_arm7tdmi.go:
--------------------------------------------------------------------------------
1 | // +build arm7tdmi
2 |
3 | package runtime
4 |
5 | import (
6 | _ "runtime/interrupt" // make sure the interrupt handler is defined
7 | "unsafe"
8 | )
9 |
10 | type timeUnit int64
11 |
12 | const tickMicros = 1
13 |
14 | func putchar(c byte) {
15 | // dummy, TODO
16 | }
17 |
18 | //go:extern _sbss
19 | var _sbss [0]byte
20 |
21 | //go:extern _ebss
22 | var _ebss [0]byte
23 |
24 | //go:extern _sdata
25 | var _sdata [0]byte
26 |
27 | //go:extern _sidata
28 | var _sidata [0]byte
29 |
30 | //go:extern _edata
31 | var _edata [0]byte
32 |
33 | func postinit() {}
34 |
35 | // Entry point for Go. Initialize all packages and call main.main().
36 | //export main
37 | func main() {
38 | // Initialize .data and .bss sections.
39 | preinit()
40 |
41 | // Run program.
42 | run()
43 | }
44 |
45 | func preinit() {
46 | // Initialize .bss: zero-initialized global variables.
47 | ptr := unsafe.Pointer(&_sbss)
48 | for ptr != unsafe.Pointer(&_ebss) {
49 | *(*uint32)(ptr) = 0
50 | ptr = unsafe.Pointer(uintptr(ptr) + 4)
51 | }
52 |
53 | // Initialize .data: global variables initialized from flash.
54 | src := unsafe.Pointer(&_sidata)
55 | dst := unsafe.Pointer(&_sdata)
56 | for dst != unsafe.Pointer(&_edata) {
57 | *(*uint32)(dst) = *(*uint32)(src)
58 | dst = unsafe.Pointer(uintptr(dst) + 4)
59 | src = unsafe.Pointer(uintptr(src) + 4)
60 | }
61 | }
62 |
63 | func ticks() timeUnit {
64 | // TODO
65 | return 0
66 | }
67 |
68 | const asyncScheduler = false
69 |
70 | func sleepTicks(d timeUnit) {
71 | // TODO
72 | }
73 |
74 | func abort() {
75 | // TODO
76 | for {
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/internal/reflectlite/reflect.go:
--------------------------------------------------------------------------------
1 | package reflectlite
2 |
3 | import "reflect"
4 |
5 | func Swapper(slice interface{}) func(i, j int) {
6 | return reflect.Swapper(slice)
7 | }
8 |
9 | type Kind = reflect.Kind
10 | type Type = reflect.Type
11 | type Value = reflect.Value
12 |
13 | const (
14 | Invalid Kind = reflect.Invalid
15 | Bool Kind = reflect.Bool
16 | Int Kind = reflect.Int
17 | Int8 Kind = reflect.Int8
18 | Int16 Kind = reflect.Int16
19 | Int32 Kind = reflect.Int32
20 | Int64 Kind = reflect.Int64
21 | Uint Kind = reflect.Uint
22 | Uint8 Kind = reflect.Uint8
23 | Uint16 Kind = reflect.Uint16
24 | Uint32 Kind = reflect.Uint32
25 | Uint64 Kind = reflect.Uint64
26 | Uintptr Kind = reflect.Uintptr
27 | Float32 Kind = reflect.Float32
28 | Float64 Kind = reflect.Float64
29 | Complex64 Kind = reflect.Complex64
30 | Complex128 Kind = reflect.Complex128
31 | Array Kind = reflect.Array
32 | Chan Kind = reflect.Chan
33 | Func Kind = reflect.Func
34 | Interface Kind = reflect.Interface
35 | Map Kind = reflect.Map
36 | Ptr Kind = reflect.Ptr
37 | Slice Kind = reflect.Slice
38 | String Kind = reflect.String
39 | Struct Kind = reflect.Struct
40 | UnsafePointer Kind = reflect.UnsafePointer
41 | )
42 |
43 | func ValueOf(i interface{}) reflect.Value {
44 | return reflect.ValueOf(i)
45 | }
46 |
47 | func TypeOf(i interface{}) reflect.Type {
48 | return reflect.TypeOf(i)
49 | }
50 |
51 | type ValueError = reflect.ValueError
52 |
--------------------------------------------------------------------------------
/src/runtime/runtime_atsamd51g19.go:
--------------------------------------------------------------------------------
1 | // +build sam,atsamd51,atsamd51g19
2 |
3 | package runtime
4 |
5 | import (
6 | "device/sam"
7 | )
8 |
9 | func initSERCOMClocks() {
10 | // Turn on clock to SERCOM0 for UART0
11 | sam.MCLK.APBAMASK.SetBits(sam.MCLK_APBAMASK_SERCOM0_)
12 | sam.GCLK.PCHCTRL[7].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
13 | sam.GCLK_PCHCTRL_CHEN)
14 |
15 | // sets the "slow" clock shared by all SERCOM
16 | sam.GCLK.PCHCTRL[3].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
17 | sam.GCLK_PCHCTRL_CHEN)
18 |
19 | // Turn on clock to SERCOM1
20 | sam.MCLK.APBAMASK.SetBits(sam.MCLK_APBAMASK_SERCOM1_)
21 | sam.GCLK.PCHCTRL[8].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
22 | sam.GCLK_PCHCTRL_CHEN)
23 |
24 | // Turn on clock to SERCOM2
25 | sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_SERCOM2_)
26 | sam.GCLK.PCHCTRL[23].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
27 | sam.GCLK_PCHCTRL_CHEN)
28 |
29 | // Turn on clock to SERCOM3
30 | sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_SERCOM3_)
31 | sam.GCLK.PCHCTRL[24].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
32 | sam.GCLK_PCHCTRL_CHEN)
33 |
34 | // Turn on clock to SERCOM4
35 | sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_SERCOM4_)
36 | sam.GCLK.PCHCTRL[34].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
37 | sam.GCLK_PCHCTRL_CHEN)
38 |
39 | // Turn on clock to SERCOM5
40 | sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_SERCOM5_)
41 | sam.GCLK.PCHCTRL[35].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
42 | sam.GCLK_PCHCTRL_CHEN)
43 | }
44 |
--------------------------------------------------------------------------------
/src/runtime/runtime_atsamd51j19.go:
--------------------------------------------------------------------------------
1 | // +build sam,atsamd51,atsamd51j19
2 |
3 | package runtime
4 |
5 | import (
6 | "device/sam"
7 | )
8 |
9 | func initSERCOMClocks() {
10 | // Turn on clock to SERCOM0 for UART0
11 | sam.MCLK.APBAMASK.SetBits(sam.MCLK_APBAMASK_SERCOM0_)
12 | sam.GCLK.PCHCTRL[7].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
13 | sam.GCLK_PCHCTRL_CHEN)
14 |
15 | // sets the "slow" clock shared by all SERCOM
16 | sam.GCLK.PCHCTRL[3].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
17 | sam.GCLK_PCHCTRL_CHEN)
18 |
19 | // Turn on clock to SERCOM1
20 | sam.MCLK.APBAMASK.SetBits(sam.MCLK_APBAMASK_SERCOM1_)
21 | sam.GCLK.PCHCTRL[8].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
22 | sam.GCLK_PCHCTRL_CHEN)
23 |
24 | // Turn on clock to SERCOM2
25 | sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_SERCOM2_)
26 | sam.GCLK.PCHCTRL[23].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
27 | sam.GCLK_PCHCTRL_CHEN)
28 |
29 | // Turn on clock to SERCOM3
30 | sam.MCLK.APBBMASK.SetBits(sam.MCLK_APBBMASK_SERCOM3_)
31 | sam.GCLK.PCHCTRL[24].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
32 | sam.GCLK_PCHCTRL_CHEN)
33 |
34 | // Turn on clock to SERCOM4
35 | sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_SERCOM4_)
36 | sam.GCLK.PCHCTRL[34].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
37 | sam.GCLK_PCHCTRL_CHEN)
38 |
39 | // Turn on clock to SERCOM5
40 | sam.MCLK.APBDMASK.SetBits(sam.MCLK_APBDMASK_SERCOM5_)
41 | sam.GCLK.PCHCTRL[35].Set((sam.GCLK_PCHCTRL_GEN_GCLK1 << sam.GCLK_PCHCTRL_GEN_Pos) |
42 | sam.GCLK_PCHCTRL_CHEN)
43 | }
44 |
--------------------------------------------------------------------------------