diff --git a/chore/llvmtargets/llvm_targets.go b/chore/llvmtargets/llvm_targets.go new file mode 100644 index 00000000..936ae7e9 --- /dev/null +++ b/chore/llvmtargets/llvm_targets.go @@ -0,0 +1,18 @@ +package main + +import ( + "fmt" + + "github.com/goplus/llvm" +) + +func main() { + llvm.InitializeAllTargetInfos() + llvm.InitializeAllTargets() + llvm.InitializeAllTargetMCs() + llvm.InitializeNativeTarget() + fmt.Println("targets:") + for it := llvm.FirstTarget(); it.C != nil; it = it.NextTarget() { + fmt.Printf("- %s: %s\n", it.Name(), it.Description()) + } +} diff --git a/cl/cltest/cltest.go b/cl/cltest/cltest.go index 3b8c60b2..a0d0b750 100644 --- a/cl/cltest/cltest.go +++ b/cl/cltest/cltest.go @@ -32,6 +32,7 @@ import ( "github.com/goplus/gogen/packages" "github.com/goplus/llgo/cl" "github.com/goplus/llgo/internal/llgen" + "github.com/goplus/llgo/ssa/ssatest" "golang.org/x/tools/go/ssa" "golang.org/x/tools/go/ssa/ssautil" @@ -139,21 +140,7 @@ func TestCompileEx(t *testing.T, src any, fname, expected string) { t.Fatal("BuildPackage failed:", err) } foo.WriteTo(os.Stderr) - prog := llssa.NewProgram(nil) - prog.SetRuntime(func() *types.Package { - rt, err := imp.Import(llssa.PkgRuntime) - if err != nil { - t.Fatal("load runtime failed:", err) - } - return rt - }) - prog.SetPython(func() *types.Package { - rt, err := imp.Import(llssa.PkgPython) - if err != nil { - t.Fatal("load python failed:", err) - } - return rt - }) + prog := ssatest.NewProgramEx(t, nil, imp) ret, err := cl.NewPackage(prog, foo, files) if err != nil { diff --git a/ssa/cl_test.go b/ssa/cl_test.go index 21c8bf85..c89a0958 100644 --- a/ssa/cl_test.go +++ b/ssa/cl_test.go @@ -17,9 +17,12 @@ package ssa_test import ( + "go/types" "testing" "github.com/goplus/llgo/cl/cltest" + "github.com/goplus/llgo/ssa" + "github.com/goplus/llgo/ssa/ssatest" ) func TestFromTestpy(t *testing.T) { @@ -42,6 +45,40 @@ func TestAbi(t *testing.T) { cltest.Pkg(t, "github.com/goplus/llgo/internal/abi", "../internal/abi/llgo_autogen.ll") } +func TestMakeInterface(t *testing.T) { + prog := ssatest.NewProgram(t, &ssa.Target{GOARCH: "x86"}) + pkg := prog.NewPackage("foo", "foo") + fn := pkg.NewFunc("main", types.NewSignatureType(nil, nil, nil, nil, nil, false), ssa.InC) + b := fn.MakeBody(1) + b.MakeInterface(prog.Any(), prog.IntVal(100, prog.Int64())) + b.MakeInterface(prog.Any(), prog.FloatVal(100, prog.Float64())) + b.Return() + ssatest.Assert(t, pkg, `; ModuleID = 'foo' +source_filename = "foo" + +%"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr } + +define void @main() { +_llgo_0: + %0 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8) + store i64 100, ptr %0, align 4 + %1 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 6) + %2 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAny"(ptr %1, ptr %0) + %3 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 8) + store double 1.000000e+02, ptr %3, align 8 + %4 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 14) + %5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAny"(ptr %4, ptr %3) + ret void +} + +declare ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64) + +declare %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAny"(ptr, ptr) + +declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64) +`) +} + /* func TestCallback(t *testing.T) { ctx := llvm.NewContext() diff --git a/ssa/package.go b/ssa/package.go index ca8ec18c..9e9356bb 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -182,7 +182,7 @@ func NewProgram(target *Target) Program { // TODO(xsw): Finalize may cause panic, so comment it. ctx.Finalize() */ - is32Bits := (td.PointerSize() == 4) + is32Bits := (td.PointerSize() == 4 || target.GOARCH == "x86") // TODO(xsw): remove temp code return &aProgram{ ctx: ctx, gocvt: newGoTypes(), // abi: abi.New(), target: target, td: td, is32Bits: is32Bits, diff --git a/ssa/ssa_test.go b/ssa/ssa_test.go index 05496769..103ee79e 100644 --- a/ssa/ssa_test.go +++ b/ssa/ssa_test.go @@ -21,10 +21,18 @@ import ( "go/token" "go/types" "testing" + "unsafe" "github.com/goplus/llvm" ) +func TestPointerSize(t *testing.T) { + expected := unsafe.Sizeof(uintptr(0)) + if size := NewProgram(nil).PointerSize(); size != int(expected) { + t.Fatal("bad PointerSize:", size) + } +} + func TestSetBlock(t *testing.T) { defer func() { if r := recover(); r == nil { diff --git a/ssa/ssatest/ssautil.go b/ssa/ssatest/ssautil.go new file mode 100644 index 00000000..bbb8ae9a --- /dev/null +++ b/ssa/ssatest/ssautil.go @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ssatest + +import ( + "go/token" + "go/types" + "testing" + + "github.com/goplus/gogen/packages" + "github.com/goplus/llgo/ssa" +) + +func NewProgram(t *testing.T, target *ssa.Target) ssa.Program { + fset := token.NewFileSet() + imp := packages.NewImporter(fset) + return NewProgramEx(t, target, imp) +} + +func NewProgramEx(t *testing.T, target *ssa.Target, imp types.Importer) ssa.Program { + prog := ssa.NewProgram(target) + prog.SetRuntime(func() *types.Package { + rt, err := imp.Import(ssa.PkgRuntime) + if err != nil { + t.Fatal("load runtime failed:", err) + } + return rt + }) + prog.SetPython(func() *types.Package { + rt, err := imp.Import(ssa.PkgPython) + if err != nil { + t.Fatal("load python failed:", err) + } + return rt + }) + return prog +} + +func Assert(t *testing.T, p ssa.Package, expected string) { + t.Helper() + if v := p.String(); v != expected { + t.Fatalf("\n==> got:\n%s\n==> expected:\n%s\n", v, expected) + } +}