diff --git a/internal/runtime/z_type.go b/internal/runtime/z_type.go index f0ad7723..02b31b2d 100644 --- a/internal/runtime/z_type.go +++ b/internal/runtime/z_type.go @@ -17,15 +17,15 @@ package runtime import ( - "go/types" "unsafe" "github.com/goplus/llgo/internal/abi" ) +type Kind = abi.Kind type Type = abi.Type -func Basic(kind types.BasicKind) *Type { +func Basic(kind Kind) *Type { return basicTypes[kind] } diff --git a/ssa/expr.go b/ssa/expr.go index bbc76f57..eda2c4dc 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -23,6 +23,7 @@ import ( "go/token" "go/types" "log" + "unsafe" "github.com/goplus/llvm" ) @@ -76,10 +77,12 @@ func llvmValues(vals []Expr) []llvm.Value { // ----------------------------------------------------------------------------- +// Null returns a null constant expression. func (p Program) Null(t Type) Expr { return Expr{llvm.ConstNull(t.ll), t} } +// BoolVal returns a boolean constant expression. func (p Program) BoolVal(v bool) Expr { t := p.Bool() var bv uint64 @@ -90,15 +93,19 @@ func (p Program) BoolVal(v bool) Expr { return Expr{ret, t} } +// IntVal returns an integer constant expression. func (p Program) IntVal(v uint64, t Type) Expr { ret := llvm.ConstInt(t.ll, v, false) return Expr{ret, t} } +// Val returns a constant expression. func (p Program) Val(v interface{}) Expr { switch v := v.(type) { case int: return p.IntVal(uint64(v), p.Int()) + case uintptr: + return p.IntVal(uint64(v), p.Uintptr()) case bool: return p.BoolVal(v) case float64: @@ -109,6 +116,7 @@ func (p Program) Val(v interface{}) Expr { panic("todo") } +// Const returns a constant expression. func (b Builder) Const(v constant.Value, typ Type) Expr { if v == nil { return b.prog.Null(typ) @@ -258,7 +266,7 @@ func (b Builder) BinOp(op token.Token, x, y Expr) Expr { case vkSigned: pred := intPredOpToLLVM[op-predOpBase] return Expr{llvm.CreateICmp(b.impl, pred, x.impl, y.impl), tret} - case vkUnsigned: + case vkUnsigned, vkPtr: pred := uintPredOpToLLVM[op-predOpBase] return Expr{llvm.CreateICmp(b.impl, pred, x.impl, y.impl), tret} case vkFloat: @@ -386,9 +394,11 @@ func (b Builder) Alloc(t Type, heap bool) (ret Expr) { if heap { ret.impl = llvm.CreateAlloca(b.impl, telem.ll) } else { - panic("todo") + pkg := b.fn.pkg + size := unsafe.Sizeof(t.t) + ret = b.Call(pkg.rtFunc("Alloc"), b.prog.Val(size)) } - // TODO: zero-initialize + // TODO(xsw): zero-initialize ret.Type = t return } diff --git a/ssa/package.go b/ssa/package.go index 23af1d23..cd63b986 100644 --- a/ssa/package.go +++ b/ssa/package.go @@ -113,11 +113,12 @@ type aProgram struct { rtIfaceTy llvm.Type rtSliceTy llvm.Type - anyTy Type - voidTy Type - boolTy Type - intTy Type - f64Ty Type + anyTy Type + voidTy Type + boolTy Type + uintptrTy Type + intTy Type + f64Ty Type } // A Program presents a program. @@ -211,6 +212,14 @@ func (p Program) Int() Type { return p.intTy } +// Uintptr returns uintptr type. +func (p Program) Uintptr() Type { + if p.uintptrTy == nil { + p.uintptrTy = p.Type(types.Typ[types.Uintptr]) + } + return p.uintptrTy +} + // Float64 returns float64 type. func (p Program) Float64() Type { if p.f64Ty == nil { diff --git a/ssa/type.go b/ssa/type.go index ffec59b9..dc5d20aa 100644 --- a/ssa/type.go +++ b/ssa/type.go @@ -39,6 +39,7 @@ const ( vkComplex vkString vkBool + vkPtr vkFunc vkTuple vkDelayExpr = -1 @@ -237,11 +238,11 @@ func (p Program) toLLVMType(typ types.Type) Type { case types.Complex128: case types.String: case types.UnsafePointer: - return &aType{p.tyVoidPtr(), typ, vkInvalid} + return &aType{p.tyVoidPtr(), typ, vkPtr} } case *types.Pointer: elem := p.Type(t.Elem()) - return &aType{llvm.PointerType(elem.ll, 0), typ, vkInvalid} + return &aType{llvm.PointerType(elem.ll, 0), typ, vkPtr} case *types.Interface: return &aType{p.rtIface(), typ, vkInvalid} case *types.Slice: