From 7ed6d62a3c99cd82c8df9e8c887b0c87f764025a Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Tue, 14 Jan 2020 16:59:51 +0100 Subject: [PATCH 1/2] riscv: add support for CGo This commit makes the following command work correctly: tinygo run -target=hifive1-qemu ./testdata/cgo/ --- targets/riscv.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/targets/riscv.json b/targets/riscv.json index f96354008d..a84e2b0189 100644 --- a/targets/riscv.json +++ b/targets/riscv.json @@ -3,6 +3,7 @@ "goos": "linux", "goarch": "arm", "build-tags": ["tinygo.riscv", "baremetal", "linux", "arm"], + "compiler": "clang", "gc": "conservative", "compiler": "clang", "linker": "ld.lld", @@ -13,7 +14,8 @@ "-mabi=ilp32", "-Os", "-Werror", - "-nostdinc", + "-nostdlibinc", + "-Wno-macro-redefined", "-fno-exceptions", "-fno-unwind-tables", "-ffunction-sections", "-fdata-sections" ], From fedc36ef5d4c9a8bde4a6ba60adf4eddc89a5835 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sat, 30 Nov 2019 13:26:58 +0100 Subject: [PATCH 2/2] riscv: run tests in QEMU These tests should make sure that things that work now won't break in the future. --- .circleci/config.yml | 4 +++- azure-pipelines.yml | 1 + main_test.go | 16 +++++++++++++++- src/runtime/runtime_fe310_qemu.go | 10 ++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index dcd33dd5c9..152d5efb0b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -246,7 +246,9 @@ commands: llvm-build - run: name: "Test TinyGo" - command: make test + command: | + make gen-device-sifive # needed for testing + make test - run: name: "Build TinyGo release" command: | diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5b6a5c0429..c27e50cc3c 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -52,6 +52,7 @@ jobs: script: | export PATH="/c/Go1.13/bin:$PATH:./llvm-build/bin:/c/Program Files/qemu" unset GOROOT + make gen-device-sifive # needed for testing make test - task: Bash@3 displayName: Build TinyGo release tarball diff --git a/main_test.go b/main_test.go index 188f318e8d..f11af75b31 100644 --- a/main_test.go +++ b/main_test.go @@ -55,6 +55,14 @@ func TestCompiler(t *testing.T) { runPlatTests("cortex-m-qemu", matches, t) }) + if runtime.GOOS == "windows" || runtime.GOOS == "darwin" { + // Note: running only on Windows and macOS because Linux usually has an + // outdated QEMU version that doesn't support RISC-V yet. + t.Run("EmulatedHiFive1", func(t *testing.T) { + runPlatTests("hifive1-qemu", matches, t) + }) + } + if runtime.GOOS == "linux" { t.Run("ARMLinux", func(t *testing.T) { runPlatTests("arm--linux-gnueabihf", matches, t) @@ -84,6 +92,8 @@ func runPlatTests(target string, matches []string, t *testing.T) { // run all tests on host case target == "cortex-m-qemu": // all tests are supported + case target == "hifive1-qemu": + // all tests are supported default: // cross-compilation of cgo is not yet supported if path == filepath.Join("testdata", "cgo")+string(filepath.Separator) { @@ -204,7 +214,11 @@ func runTest(path, target string, t *testing.T) { } close(runComplete) - if ranTooLong { + if ranTooLong && target != "hifive1-qemu" { + // Note: the hifive1-qemu exception is here because QEMU does + // not yet include the SiFive test finisher used to exit tests. + // https://github.com/sifive/riscv-qemu/commit/0eec372a36b7237caf16ec7c7646a202faba5fdb + // It's a crude hack, but it makes RISC-V testable. stdout.WriteString("--- test ran too long, terminating...\n") } diff --git a/src/runtime/runtime_fe310_qemu.go b/src/runtime/runtime_fe310_qemu.go index 132515e795..3270aa3deb 100644 --- a/src/runtime/runtime_fe310_qemu.go +++ b/src/runtime/runtime_fe310_qemu.go @@ -3,6 +3,7 @@ package runtime import ( + "device/riscv" "runtime/volatile" "unsafe" ) @@ -17,4 +18,13 @@ var timestamp timeUnit func abort() { // Signal a successful exit. testExit.Set(0x5555) + + // Note: the SiFive test finisher does not seem to be implemented in QEMU + // 4.2 (but is included in the SiFive build of QEMU). And while the above + // write somehow results in exiting the process on Windows, that's not the + // case on macOS. Therefore, make sure to halt the process with an endless + // loop. + for { + riscv.Asm("wfi") + } }