cl: instr llgo.index/advance
This commit is contained in:
2
c/c.go
2
c/c.go
@@ -41,7 +41,7 @@ type integer interface {
|
|||||||
func Str(string) *Char
|
func Str(string) *Char
|
||||||
|
|
||||||
//go:linkname Advance llgo.advance
|
//go:linkname Advance llgo.advance
|
||||||
func Advance(ptr Pointer, offset int) Pointer
|
func Advance[PtrT any](ptr PtrT, offset int) PtrT { return ptr }
|
||||||
|
|
||||||
// llgo:link Index llgo.index
|
// llgo:link Index llgo.index
|
||||||
func Index[T any, I integer](ptr *T, offset I) T { return *ptr }
|
func Index[T any, I integer](ptr *T, offset I) T { return *ptr }
|
||||||
|
|||||||
11
cl/_testlibc/argv/in.go
Normal file
11
cl/_testlibc/argv/in.go
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/goplus/llgo/c"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
for i := c.Int(0); i < c.Argc; i++ {
|
||||||
|
c.Printf(c.Str("%s\n"), c.Index(c.Argv, i))
|
||||||
|
}
|
||||||
|
}
|
||||||
50
cl/_testlibc/argv/out.ll
Normal file
50
cl/_testlibc/argv/out.ll
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
; ModuleID = 'main'
|
||||||
|
source_filename = "main"
|
||||||
|
|
||||||
|
@"main.init$guard" = global ptr null
|
||||||
|
@__llgo_argc = global ptr null
|
||||||
|
@__llgo_argv = global ptr null
|
||||||
|
@0 = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1
|
||||||
|
|
||||||
|
define void @main.init() {
|
||||||
|
_llgo_0:
|
||||||
|
%0 = load i1, ptr @"main.init$guard", align 1
|
||||||
|
br i1 %0, label %_llgo_2, label %_llgo_1
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_0
|
||||||
|
store i1 true, ptr @"main.init$guard", align 1
|
||||||
|
br label %_llgo_2
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_1, %_llgo_0
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @main(i32 %0, ptr %1) {
|
||||||
|
_llgo_0:
|
||||||
|
store i32 %0, ptr @__llgo_argc, align 4
|
||||||
|
store ptr %1, ptr @__llgo_argv, align 8
|
||||||
|
call void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
call void @main.init()
|
||||||
|
br label %_llgo_3
|
||||||
|
|
||||||
|
_llgo_1: ; preds = %_llgo_3
|
||||||
|
%2 = load ptr, ptr @__llgo_argv, align 8
|
||||||
|
%3 = getelementptr ptr, ptr %2, i32 %7
|
||||||
|
%4 = load ptr, ptr %3, align 8
|
||||||
|
%5 = call i32 (ptr, ...) @printf(ptr @0, ptr %4)
|
||||||
|
%6 = add i32 %7, 1
|
||||||
|
br label %_llgo_3
|
||||||
|
|
||||||
|
_llgo_2: ; preds = %_llgo_3
|
||||||
|
ret void
|
||||||
|
|
||||||
|
_llgo_3: ; preds = %_llgo_1, %_llgo_0
|
||||||
|
%7 = phi i32 [ 0, %_llgo_0 ], [ %6, %_llgo_1 ]
|
||||||
|
%8 = load i32, ptr @__llgo_argc, align 4
|
||||||
|
%9 = icmp slt i32 %7, %8
|
||||||
|
br i1 %9, label %_llgo_1, label %_llgo_2
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @"github.com/goplus/llgo/internal/runtime.init"()
|
||||||
|
|
||||||
|
declare i32 @printf(ptr, ...)
|
||||||
@@ -278,6 +278,8 @@ func (p *context) funcOf(fn *ssa.Function) (ret llssa.Function, ftype int) {
|
|||||||
ftype = llgoCstr
|
ftype = llgoCstr
|
||||||
case "advance":
|
case "advance":
|
||||||
ftype = llgoAdvance
|
ftype = llgoAdvance
|
||||||
|
case "index":
|
||||||
|
ftype = llgoIndex
|
||||||
case "alloca":
|
case "alloca":
|
||||||
ftype = llgoAlloca
|
ftype = llgoAlloca
|
||||||
case "allocaCStr":
|
case "allocaCStr":
|
||||||
@@ -377,6 +379,12 @@ func cstr(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) {
|
|||||||
panic("cstr(<string-literal>): invalid arguments")
|
panic("cstr(<string-literal>): invalid arguments")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func index(arr *T, idx int) T
|
||||||
|
func (p *context) index(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) {
|
||||||
|
return b.Load(p.advance(b, args))
|
||||||
|
}
|
||||||
|
|
||||||
|
// func advance(ptr *T, offset int) *T
|
||||||
func (p *context) advance(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) {
|
func (p *context) advance(b llssa.Builder, args []ssa.Value) (ret llssa.Expr) {
|
||||||
if len(args) == 2 {
|
if len(args) == 2 {
|
||||||
ptr := p.compileValue(b, args[0])
|
ptr := p.compileValue(b, args[0])
|
||||||
@@ -489,6 +497,8 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
|
|||||||
ret = cstr(b, call.Args)
|
ret = cstr(b, call.Args)
|
||||||
case llgoAdvance:
|
case llgoAdvance:
|
||||||
ret = p.advance(b, call.Args)
|
ret = p.advance(b, call.Args)
|
||||||
|
case llgoIndex:
|
||||||
|
ret = p.index(b, call.Args)
|
||||||
case llgoAlloca:
|
case llgoAlloca:
|
||||||
ret = p.alloca(b, call.Args)
|
ret = p.alloca(b, call.Args)
|
||||||
case llgoAllocaCStr:
|
case llgoAllocaCStr:
|
||||||
|
|||||||
@@ -28,11 +28,9 @@ func testCompile(t *testing.T, src, expected string) {
|
|||||||
cltest.TestCompileEx(t, src, "foo.go", expected)
|
cltest.TestCompileEx(t, src, "foo.go", expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
func TestFromTestlibc(t *testing.T) {
|
func TestFromTestlibc(t *testing.T) {
|
||||||
cltest.FromDir(t, "argv", "./_testlibc", false)
|
cltest.FromDir(t, "", "./_testlibc", false)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
func TestFromTestrt(t *testing.T) {
|
func TestFromTestrt(t *testing.T) {
|
||||||
cltest.FromDir(t, "", "./_testrt", true)
|
cltest.FromDir(t, "", "./_testrt", true)
|
||||||
|
|||||||
@@ -213,6 +213,7 @@ const (
|
|||||||
llgoAlloca = llgoInstrBase + 2
|
llgoAlloca = llgoInstrBase + 2
|
||||||
llgoAllocaCStr = llgoInstrBase + 3
|
llgoAllocaCStr = llgoInstrBase + 3
|
||||||
llgoAdvance = llgoInstrBase + 4
|
llgoAdvance = llgoInstrBase + 4
|
||||||
|
llgoIndex = llgoInstrBase + 5
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *context) funcName(fn *ssa.Function, ignore bool) (*types.Package, string, int) {
|
func (p *context) funcName(fn *ssa.Function, ignore bool) (*types.Package, string, int) {
|
||||||
|
|||||||
12
ssa/expr.go
12
ssa/expr.go
@@ -496,12 +496,20 @@ func (b Builder) Phi(t Type) Phi {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Advance returns the pointer ptr advanced by offset bytes.
|
// Advance returns the pointer ptr advanced by offset.
|
||||||
func (b Builder) Advance(ptr Expr, offset Expr) Expr {
|
func (b Builder) Advance(ptr Expr, offset Expr) Expr {
|
||||||
if debugInstr {
|
if debugInstr {
|
||||||
log.Printf("Advance %v, %v\n", ptr.impl, offset.impl)
|
log.Printf("Advance %v, %v\n", ptr.impl, offset.impl)
|
||||||
}
|
}
|
||||||
ret := llvm.CreateGEP(b.impl, b.Prog.tyInt8(), ptr.impl, []llvm.Value{offset.impl})
|
var elem llvm.Type
|
||||||
|
var prog = b.Prog
|
||||||
|
var telem = ptr.raw.Type.(*types.Pointer).Elem()
|
||||||
|
if telem == types.Typ[types.Invalid] { // void
|
||||||
|
elem = prog.tyInt8()
|
||||||
|
} else {
|
||||||
|
elem = prog.rawType(telem).ll
|
||||||
|
}
|
||||||
|
ret := llvm.CreateGEP(b.impl, elem, ptr.impl, []llvm.Value{offset.impl})
|
||||||
return Expr{ret, ptr.Type}
|
return Expr{ret, ptr.Type}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user