Merge pull request #136 from visualfc/vkfloat

ssa: bitcast float => iface.data
This commit is contained in:
xushiwei
2024-05-09 17:45:57 +08:00
committed by GitHub
7 changed files with 292 additions and 8 deletions

View File

@@ -177,6 +177,41 @@ func main() {
printnl() printnl()
prinfsub(100.1) prinfsub(100.1)
printnl() printnl()
printnum(float32(1e9))
printnl()
printnum(float64(2e9))
printnl()
}
func printnum(v any) {
switch v := v.(type) {
case int:
printint(int64(v))
case int8:
printint(int64(v))
case int16:
printint(int64(v))
case int32:
printint(int64(v))
case int64:
printint(int64(v))
case uint:
printuint(uint64(v))
case uint8:
printuint(uint64(v))
case uint16:
printuint(uint64(v))
case uint32:
printuint(uint64(v))
case uint64:
printuint(uint64(v))
case uintptr:
printuint(uint64(v))
case float32:
printfloat(float64(v))
case float64:
printfloat(float64(v))
}
} }
func prinxor(n int64) { func prinxor(n int64) {

View File

@@ -5,6 +5,7 @@ source_filename = "main"
%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } %"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 }
%main.stringStruct = type { ptr, i64 } %main.stringStruct = type { ptr, i64 }
%main.slice = type { ptr, i64, i64 } %main.slice = type { ptr, i64, i64 }
%"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr }
@"main.init$guard" = global ptr null @"main.init$guard" = global ptr null
@main.minhexdigits = global ptr null @main.minhexdigits = global ptr null
@@ -91,6 +92,14 @@ _llgo_0:
call void @main.printnl() call void @main.printnl()
call void @main.prinfsub(double 1.001000e+02) call void @main.prinfsub(double 1.001000e+02)
call void @main.printnl() call void @main.printnl()
%3 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 13)
%4 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %3, i64 1315859240)
call void @main.printnum(%"github.com/goplus/llgo/internal/runtime.iface" %4)
call void @main.printnl()
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 14)
%6 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr %5, i64 4746175415993761792)
call void @main.printnum(%"github.com/goplus/llgo/internal/runtime.iface" %6)
call void @main.printnl()
ret void ret void
} }
@@ -363,6 +372,155 @@ _llgo_0:
ret void ret void
} }
define void @main.printnum(%"github.com/goplus/llgo/internal/runtime.iface" %0) {
_llgo_0:
%1 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 2)
%2 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %1)
%3 = extractvalue { i64, i1 } %2, 0
%4 = extractvalue { i64, i1 } %2, 1
br i1 %4, label %_llgo_2, label %_llgo_3
_llgo_1: ; preds = %_llgo_26, %_llgo_25, %_llgo_24, %_llgo_22, %_llgo_20, %_llgo_18, %_llgo_16, %_llgo_14, %_llgo_12, %_llgo_10, %_llgo_8, %_llgo_6, %_llgo_4, %_llgo_2
ret void
_llgo_2: ; preds = %_llgo_0
call void @main.printint(i64 %3)
br label %_llgo_1
_llgo_3: ; preds = %_llgo_0
%5 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 3)
%6 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %5)
%7 = extractvalue { i64, i1 } %6, 0
%8 = extractvalue { i64, i1 } %6, 1
br i1 %8, label %_llgo_4, label %_llgo_5
_llgo_4: ; preds = %_llgo_3
call void @main.printint(i64 %7)
br label %_llgo_1
_llgo_5: ; preds = %_llgo_3
%9 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 4)
%10 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %9)
%11 = extractvalue { i64, i1 } %10, 0
%12 = extractvalue { i64, i1 } %10, 1
br i1 %12, label %_llgo_6, label %_llgo_7
_llgo_6: ; preds = %_llgo_5
call void @main.printint(i64 %11)
br label %_llgo_1
_llgo_7: ; preds = %_llgo_5
%13 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 5)
%14 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %13)
%15 = extractvalue { i64, i1 } %14, 0
%16 = extractvalue { i64, i1 } %14, 1
br i1 %16, label %_llgo_8, label %_llgo_9
_llgo_8: ; preds = %_llgo_7
call void @main.printint(i64 %15)
br label %_llgo_1
_llgo_9: ; preds = %_llgo_7
%17 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 6)
%18 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %17)
%19 = extractvalue { i64, i1 } %18, 0
%20 = extractvalue { i64, i1 } %18, 1
br i1 %20, label %_llgo_10, label %_llgo_11
_llgo_10: ; preds = %_llgo_9
call void @main.printint(i64 %19)
br label %_llgo_1
_llgo_11: ; preds = %_llgo_9
%21 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 7)
%22 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %21)
%23 = extractvalue { i64, i1 } %22, 0
%24 = extractvalue { i64, i1 } %22, 1
br i1 %24, label %_llgo_12, label %_llgo_13
_llgo_12: ; preds = %_llgo_11
call void @main.printuint(i64 %23)
br label %_llgo_1
_llgo_13: ; preds = %_llgo_11
%25 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 8)
%26 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %25)
%27 = extractvalue { i64, i1 } %26, 0
%28 = extractvalue { i64, i1 } %26, 1
br i1 %28, label %_llgo_14, label %_llgo_15
_llgo_14: ; preds = %_llgo_13
call void @main.printuint(i64 %27)
br label %_llgo_1
_llgo_15: ; preds = %_llgo_13
%29 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 9)
%30 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %29)
%31 = extractvalue { i64, i1 } %30, 0
%32 = extractvalue { i64, i1 } %30, 1
br i1 %32, label %_llgo_16, label %_llgo_17
_llgo_16: ; preds = %_llgo_15
call void @main.printuint(i64 %31)
br label %_llgo_1
_llgo_17: ; preds = %_llgo_15
%33 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 10)
%34 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %33)
%35 = extractvalue { i64, i1 } %34, 0
%36 = extractvalue { i64, i1 } %34, 1
br i1 %36, label %_llgo_18, label %_llgo_19
_llgo_18: ; preds = %_llgo_17
call void @main.printuint(i64 %35)
br label %_llgo_1
_llgo_19: ; preds = %_llgo_17
%37 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 11)
%38 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %37)
%39 = extractvalue { i64, i1 } %38, 0
%40 = extractvalue { i64, i1 } %38, 1
br i1 %40, label %_llgo_20, label %_llgo_21
_llgo_20: ; preds = %_llgo_19
call void @main.printuint(i64 %39)
br label %_llgo_1
_llgo_21: ; preds = %_llgo_19
%41 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 12)
%42 = call { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %41)
%43 = extractvalue { i64, i1 } %42, 0
%44 = extractvalue { i64, i1 } %42, 1
br i1 %44, label %_llgo_22, label %_llgo_23
_llgo_22: ; preds = %_llgo_21
call void @main.printuint(i64 %43)
br label %_llgo_1
_llgo_23: ; preds = %_llgo_21
%45 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 13)
%46 = call { float, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Float32"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %45)
%47 = extractvalue { float, i1 } %46, 0
%48 = extractvalue { float, i1 } %46, 1
br i1 %48, label %_llgo_24, label %_llgo_25
_llgo_24: ; preds = %_llgo_23
%49 = fpext float %47 to double
call void @main.printfloat(double %49)
br label %_llgo_1
_llgo_25: ; preds = %_llgo_23
%50 = call ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64 14)
%51 = call { double, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Float64"(%"github.com/goplus/llgo/internal/runtime.iface" %0, ptr %50)
%52 = extractvalue { double, i1 } %51, 0
%53 = extractvalue { double, i1 } %51, 1
br i1 %53, label %_llgo_26, label %_llgo_1
_llgo_26: ; preds = %_llgo_25
call void @main.printfloat(double %52)
br label %_llgo_1
}
define void @main.printsp() { define void @main.printsp() {
_llgo_0: _llgo_0:
%0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @8, i64 1) %0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @8, i64 1)
@@ -437,6 +595,16 @@ declare void @"github.com/goplus/llgo/internal/runtime.init"()
declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64) declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64)
declare ptr @"github.com/goplus/llgo/internal/runtime.Basic"(i64)
declare %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyInt"(ptr, i64)
declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64) declare %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr, i64, i64, i64, i64, i64)
declare ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String") declare ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String")
declare { i64, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Int"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
declare { float, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Float32"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)
declare { double, i1 } @"github.com/goplus/llgo/internal/runtime.CheckI2Float64"(%"github.com/goplus/llgo/internal/runtime.iface", ptr)

View File

@@ -290,6 +290,10 @@ func (p *context) funcOf(fn *ssa.Function) (ret llssa.Function, ftype int) {
ftype = llgoAllocaCStr ftype = llgoAllocaCStr
case "unreachable": case "unreachable":
ftype = llgoUnreachable ftype = llgoUnreachable
case "bitCastTo64F":
ftype = llgoBitCastTo64F
case "bitCastTo32F":
ftype = llgoBitCastTo32F
default: default:
panic("unknown llgo instruction: " + name) panic("unknown llgo instruction: " + name)
} }
@@ -523,6 +527,10 @@ func (p *context) compileInstrOrValue(b llssa.Builder, iv instrOrValue, asValue
ret = p.allocaCStr(b, args) ret = p.allocaCStr(b, args)
case llgoUnreachable: // func unreachable() case llgoUnreachable: // func unreachable()
b.Unreachable() b.Unreachable()
case llgoBitCastTo32F:
ret = b.BitCast(p.compileValue(b, args[0]), b.Prog.Type(types.Typ[types.Float32], llssa.InGo))
case llgoBitCastTo64F:
ret = b.BitCast(p.compileValue(b, args[0]), b.Prog.Float64())
default: default:
panic("todo") panic("todo")
} }

View File

@@ -312,6 +312,8 @@ const (
llgoAllocaCStr = llgoInstrBase + 3 llgoAllocaCStr = llgoInstrBase + 3
llgoAdvance = llgoInstrBase + 4 llgoAdvance = llgoInstrBase + 4
llgoIndex = llgoInstrBase + 5 llgoIndex = llgoInstrBase + 5
llgoBitCastTo32F = llgoInstrBase + 6
llgoBitCastTo64F = llgoInstrBase + 7
) )
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) {

Binary file not shown.

View File

@@ -77,4 +77,38 @@ func CheckI2Int(v Interface, t *Type) (uintptr, bool) {
return 0, false return 0, false
} }
func I2Float64(v Interface, t *Type) float64 {
if v.tab._type == t {
return bitCastTo64F(uint64(uintptr(v.data)))
}
panic("I2Float64: type mismatch")
}
func CheckI2Float64(v Interface, t *Type) (float64, bool) {
if v.tab._type == t {
return bitCastTo64F(uint64(uintptr(v.data))), true
}
return 0, false
}
func I2Float32(v Interface, t *Type) float32 {
if v.tab._type == t {
return bitCastTo32F(uint32(uintptr(v.data)))
}
panic("I2Float32: type mismatch")
}
func CheckI2Float32(v Interface, t *Type) (float32, bool) {
if v.tab._type == t {
return bitCastTo32F(uint32(uintptr(v.data))), true
}
return 0, false
}
//go:linkname bitCastTo64F llgo.bitCastTo64F
func bitCastTo64F(uint64) float64
//go:linkname bitCastTo32F llgo.bitCastTo32F
func bitCastTo32F(uint32) float32
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@@ -1056,6 +1056,17 @@ func (b Builder) MakeInterface(tinter Type, x Expr) (ret Expr) {
tptr := prog.Uintptr() tptr := prog.Uintptr()
vptr := Expr{llvm.CreateIntCast(b.impl, x.impl, tptr.ll), tptr} vptr := Expr{llvm.CreateIntCast(b.impl, x.impl, tptr.ll), tptr}
return Expr{b.InlineCall(pkg.rtFunc("MakeAnyInt"), t, vptr).impl, tinter} return Expr{b.InlineCall(pkg.rtFunc("MakeAnyInt"), t, vptr).impl, tinter}
case kind == types.Float32:
t := b.InlineCall(pkg.rtFunc("Basic"), prog.Val(int(kind)))
tptr := prog.Uintptr()
i32 := b.impl.CreateBitCast(x.impl, prog.tyInt32(), "")
vptr := Expr{llvm.CreateIntCast(b.impl, i32, tptr.ll), tptr}
return Expr{b.InlineCall(pkg.rtFunc("MakeAnyInt"), t, vptr).impl, tinter}
case kind == types.Float64:
t := b.InlineCall(pkg.rtFunc("Basic"), prog.Val(int(kind)))
tptr := prog.Uintptr()
vptr := Expr{b.impl.CreateBitCast(x.impl, tptr.ll, ""), tptr}
return Expr{b.InlineCall(pkg.rtFunc("MakeAnyInt"), t, vptr).impl, tinter}
case kind == types.String: case kind == types.String:
return Expr{b.InlineCall(pkg.rtFunc("MakeAnyString"), x).impl, tinter} return Expr{b.InlineCall(pkg.rtFunc("MakeAnyString"), x).impl, tinter}
} }
@@ -1107,7 +1118,7 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) (ret Expr) {
log.Printf("TypeAssert %v, %v, %v\n", x.impl, assertedTyp.raw.Type, commaOk) log.Printf("TypeAssert %v, %v, %v\n", x.impl, assertedTyp.raw.Type, commaOk)
} }
switch assertedTyp.kind { switch assertedTyp.kind {
case vkSigned, vkUnsigned, vkFloat: case vkSigned, vkUnsigned:
pkg := b.Func.Pkg pkg := b.Func.Pkg
fnName := "I2Int" fnName := "I2Int"
if commaOk { if commaOk {
@@ -1123,6 +1134,25 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) (ret Expr) {
} }
typ := b.InlineCall(pkg.rtFunc("Basic"), b.Prog.Val(int(kind))) typ := b.InlineCall(pkg.rtFunc("Basic"), b.Prog.Val(int(kind)))
return b.InlineCall(fn, x, typ) return b.InlineCall(fn, x, typ)
case vkFloat:
var fnName string
kind := assertedTyp.raw.Underlying().(*types.Basic).Kind()
switch kind {
case types.Float32:
fnName = "I2Float32"
if commaOk {
fnName = "CheckI2Float32"
}
case types.Float64:
fnName = "I2Float64"
if commaOk {
fnName = "CheckI2Float64"
}
}
pkg := b.Func.Pkg
fn := pkg.rtFunc(fnName)
typ := b.InlineCall(pkg.rtFunc("Basic"), b.Prog.Val(int(kind)))
return b.InlineCall(fn, x, typ)
} }
panic("todo") panic("todo")
} }
@@ -1232,4 +1262,11 @@ func (b Builder) BuiltinCall(fn string, args ...Expr) (ret Expr) {
panic("todo") panic("todo")
} }
// BitCast bit cast expr to type
func (b Builder) BitCast(val Expr, typ Type) (ret Expr) {
ret.Type = typ
ret.impl = b.impl.CreateBitCast(val.impl, typ.ll, "")
return
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------