From 802302a1aafcac4ad46110b95727f68df72aca4c Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Thu, 7 Jun 2018 18:29:35 +0200 Subject: [PATCH] Add support for inline assembly This depends on support in LLVM, which hasn't been merged yet. See: https://reviews.llvm.org/D46437 --- src/device/arm/arm.go | 3 +++ src/runtime/runtime_nrf.go | 2 +- tgo.go | 9 +++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/device/arm/arm.go b/src/device/arm/arm.go index 5374a5d3..ff6f4c53 100644 --- a/src/device/arm/arm.go +++ b/src/device/arm/arm.go @@ -32,6 +32,9 @@ package arm type __reg uint32 type RegValue = __reg +type __asm string +func Asm(s __asm) + const ( SCS_BASE = 0xE000E000 NVIC_BASE = SCS_BASE + 0x0100 diff --git a/src/runtime/runtime_nrf.go b/src/runtime/runtime_nrf.go index da740adf..0b62b498 100644 --- a/src/runtime/runtime_nrf.go +++ b/src/runtime/runtime_nrf.go @@ -74,8 +74,8 @@ func monotime() uint64 { } func abort() { - // TODO: wfi for { + arm.Asm("wfi") } } diff --git a/tgo.go b/tgo.go index c2f38cc2..71d2e00f 100644 --- a/tgo.go +++ b/tgo.go @@ -1038,6 +1038,15 @@ func (c *Compiler) parseCall(frame *Frame, instr *ssa.CallCommon, parentHandle l case *ssa.Builtin: return c.parseBuiltin(frame, instr.Args, call.Name()) case *ssa.Function: + if call.Name() == "Asm" && len(instr.Args) == 1 { + // Magic function: insert inline assembly instead of calling it. + if named, ok := instr.Args[0].Type().(*types.Named); ok && named.Obj().Name() == "__asm" { + fnType := llvm.FunctionType(llvm.VoidType(), []llvm.Type{}, false) + asm := constant.StringVal(instr.Args[0].(*ssa.Const).Value) + target := llvm.InlineAsm(fnType, asm, "", true, false, 0) + return c.builder.CreateCall(target, nil, ""), nil + } + } targetBlocks := false name := getFunctionName(call, targetBlocks) llvmFn := c.mod.NamedFunction(name)