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)