Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions _demo/asmcall/asmcall.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

import (
"fmt"
"time"
)

//llgo:link asm llgo.asm
func asm(instruction string) {}

func main() {
start := time.Now()
for i := 0; i < 100000; i++ {
asm("nop")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE:single asm call seems hardly to make a directive function verification

}
duration := time.Since(start)
fmt.Println("Duration:", duration)
}
10 changes: 10 additions & 0 deletions cl/_testrt/asm/in.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package main

import _ "unsafe"

//go:linkname asm llgo.asm
func asm(instruction string)

func main() {
asm("nop")
}
23 changes: 23 additions & 0 deletions cl/_testrt/asm/out.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
; ModuleID = 'github.com/goplus/llgo/cl/_testrt/asm'
source_filename = "github.com/goplus/llgo/cl/_testrt/asm"

@"github.com/goplus/llgo/cl/_testrt/asm.init$guard" = global i1 false, align 1

define void @"github.com/goplus/llgo/cl/_testrt/asm.init"() {
_llgo_0:
%0 = load i1, ptr @"github.com/goplus/llgo/cl/_testrt/asm.init$guard", align 1
br i1 %0, label %_llgo_2, label %_llgo_1

_llgo_1: ; preds = %_llgo_0
store i1 true, ptr @"github.com/goplus/llgo/cl/_testrt/asm.init$guard", align 1
br label %_llgo_2

_llgo_2: ; preds = %_llgo_1, %_llgo_0
ret void
}

define void @"github.com/goplus/llgo/cl/_testrt/asm.main"() {
_llgo_0:
call void asm sideeffect "nop", ""()
ret void
}
2 changes: 2 additions & 0 deletions cl/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,8 @@ const (
llgoCgoCheckPointer = llgoCgoBase + 0x6
llgoCgoCgocall = llgoCgoBase + 0x7

llgoAsm = llgoInstrBase + 0x40

llgoAtomicOpLast = llgoAtomicOpBase + int(llssa.OpUMin)
)

Expand Down
15 changes: 15 additions & 0 deletions cl/instr.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ func cstr(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) {
panic("cstr(<string-literal>): invalid arguments")
}

// func asm(string)
func asm(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) {
if len(args) == 1 {
if sv, ok := constStr(args[0]); ok {
b.InlineAsm(sv)
return llssa.Expr{Type: b.Prog.Void()}
}
}
panic("asm(<string-literal>): invalid arguments")
}

// -----------------------------------------------------------------------------

// func _Cfunc_CString(s string) *int8
Expand Down Expand Up @@ -329,6 +340,8 @@ var llgoInstrs = map[string]int{
"_Cfunc__CMalloc": llgoCgoCMalloc,
"_cgoCheckPointer": llgoCgoCheckPointer,
"_cgo_runtime_cgocall": llgoCgoCgocall,

"asm": llgoAsm,
}

// funcOf returns a function by name and set ftype = goFunc, cFunc, etc.
Expand Down Expand Up @@ -456,6 +469,8 @@ func (p *context) call(b llssa.Builder, act llssa.DoAction, call *ssa.CallCommon
ret = pystr(b, args)
case llgoCstr:
ret = cstr(b, args)
case llgoAsm:
ret = asm(b, args)
case llgoCgoCString:
ret = p.cgoCString(b, args)
case llgoCgoCBytes:
Expand Down
11 changes: 11 additions & 0 deletions ssa/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,17 @@ func (b Builder) CBytes(v Expr) Expr {
return b.Call(fn, v)
}

// InlineAsm generates inline assembly instruction
func (b Builder) InlineAsm(instruction string) {
if debugInstr {
log.Printf("InlineAsm %s\n", instruction)
}

typ := llvm.FunctionType(b.Prog.tyVoid(), nil, false)
asm := llvm.InlineAsm(typ, instruction, "", true, false, llvm.InlineAsmDialectATT, false)
b.impl.CreateCall(typ, asm, nil, "")
}

// GoString returns a Go string
func (b Builder) GoString(v Expr) Expr {
fn := b.Pkg.rtFunc("GoString")
Expand Down
Loading