diff --git a/cl/_testdata/print/in.go b/cl/_testdata/print/in.go index f6edcf5c..aa623c27 100644 --- a/cl/_testdata/print/in.go +++ b/cl/_testdata/print/in.go @@ -10,82 +10,80 @@ func gwrite(b []byte) { if len(b) == 0 { return } - for _, v := range b { - c.Printf(c.Str("%c"), v) - } + c.Printf(c.Str("%s"), b) } -// func printfloat(v float64) { -// switch { -// case v != v: -// printstring("NaN") -// return -// case v+v == v && v > 0: -// printstring("+Inf") -// return -// case v+v == v && v < 0: -// printstring("-Inf") -// return -// } +func printfloat(v float64) { + switch { + case v != v: + printstring("NaN") + return + case v+v == v && v > 0: + printstring("+Inf") + return + case v+v == v && v < 0: + printstring("-Inf") + return + } -// const n = 7 // digits printed -// var buf [n + 7]byte -// buf[0] = '+' -// e := 0 // exp -// if v == 0 { -// if 1/v < 0 { -// buf[0] = '-' -// } -// } else { -// if v < 0 { -// v = -v -// buf[0] = '-' -// } + const n = 7 // digits printed + var buf [n + 7]byte + buf[0] = '+' + e := 0 // exp + if v == 0 { + if 1/v < 0 { + buf[0] = '-' + } + } else { + if v < 0 { + v = -v + buf[0] = '-' + } -// // normalize -// for v >= 10 { -// e++ -// v /= 10 -// } -// for v < 1 { -// e-- -// v *= 10 -// } + // normalize + for v >= 10 { + e++ + v /= 10 + } + for v < 1 { + e-- + v *= 10 + } -// // round -// h := 5.0 -// for i := 0; i < n; i++ { -// h /= 10 -// } -// v += h -// if v >= 10 { -// e++ -// v /= 10 -// } -// } + // round + h := 5.0 + for i := 0; i < n; i++ { + h /= 10 + } + v += h + if v >= 10 { + e++ + v /= 10 + } + } -// // format +d.dddd+edd -// for i := 0; i < n; i++ { -// s := int(v) -// buf[i+2] = byte(s + '0') -// v -= float64(s) -// v *= 10 -// } -// buf[1] = buf[2] -// buf[2] = '.' + // format +d.dddd+edd + for i := 0; i < n; i++ { + s := int(v) + buf[i+2] = byte(s + '0') + v -= float64(s) + v *= 10 + } + buf[1] = buf[2] + buf[2] = '.' -// buf[n+2] = 'e' -// buf[n+3] = '+' -// if e < 0 { -// e = -e -// buf[n+3] = '-' -// } + buf[n+2] = 'e' + buf[n+3] = '+' + if e < 0 { + e = -e + buf[n+3] = '-' + } -// buf[n+4] = byte(e/100) + '0' -// buf[n+5] = byte(e/10)%10 + '0' -// buf[n+6] = byte(e%10) + '0' -// gwrite(buf[:]) -// } + buf[n+4] = byte(e/100) + '0' + buf[n+5] = byte(e/10)%10 + '0' + buf[n+6] = byte(e%10) + '0' + gwrite(buf[:]) +} func printuint(v uint64) { var buf [100]byte @@ -178,6 +176,7 @@ func main() { prinusub(1<<64 - 1) printnl() prinfsub(100.1) + printnl() } func prinxor(n int64) { @@ -193,5 +192,5 @@ func prinusub(n uint64) { } func prinfsub(n float64) { - _ = -n + printfloat(-n) } diff --git a/cl/_testdata/print/out.ll b/cl/_testdata/print/out.ll index e26910fd..d47b639f 100644 --- a/cl/_testdata/print/out.ll +++ b/cl/_testdata/print/out.ll @@ -8,14 +8,17 @@ source_filename = "main" @"main.init$guard" = global ptr null @main.minhexdigits = global ptr null -@0 = private unnamed_addr constant [3 x i8] c"%c\00", align 1 +@0 = private unnamed_addr constant [3 x i8] c"%s\00", align 1 @__llgo_argc = global ptr null @__llgo_argv = global ptr null @1 = private unnamed_addr constant [5 x i8] c"llgo\00", align 1 -@2 = private unnamed_addr constant [17 x i8] c"0123456789abcdef\00", align 1 -@3 = private unnamed_addr constant [2 x i8] c"-\00", align 1 -@4 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 -@5 = private unnamed_addr constant [2 x i8] c" \00", align 1 +@2 = private unnamed_addr constant [4 x i8] c"NaN\00", align 1 +@3 = private unnamed_addr constant [5 x i8] c"+Inf\00", align 1 +@4 = private unnamed_addr constant [5 x i8] c"-Inf\00", align 1 +@5 = private unnamed_addr constant [17 x i8] c"0123456789abcdef\00", align 1 +@6 = private unnamed_addr constant [2 x i8] c"-\00", align 1 +@7 = private unnamed_addr constant [2 x i8] c"\0A\00", align 1 +@8 = private unnamed_addr constant [2 x i8] c" \00", align 1 define %"github.com/goplus/llgo/internal/runtime.Slice" @main.bytes(%"github.com/goplus/llgo/internal/runtime.String" %0) { _llgo_0: @@ -49,23 +52,7 @@ _llgo_1: ; preds = %_llgo_0 ret void _llgo_2: ; preds = %_llgo_0 - %3 = call i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) - br label %_llgo_3 - -_llgo_3: ; preds = %_llgo_4, %_llgo_2 - %4 = phi i64 [ -1, %_llgo_2 ], [ %5, %_llgo_4 ] - %5 = add i64 %4, 1 - %6 = icmp slt i64 %5, %3 - br i1 %6, label %_llgo_4, label %_llgo_5 - -_llgo_4: ; preds = %_llgo_3 - %7 = call ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice" %0) - %8 = getelementptr inbounds i8, ptr %7, i64 %5 - %9 = load i8, ptr %8, align 1 - %10 = call i32 (ptr, ...) @printf(ptr @0, i8 %9) - br label %_llgo_3 - -_llgo_5: ; preds = %_llgo_3 + %3 = call i32 (ptr, ...) @printf(ptr @0, %"github.com/goplus/llgo/internal/runtime.Slice" %0) ret void } @@ -103,12 +90,14 @@ _llgo_0: call void @main.prinusub(i64 -1) call void @main.printnl() call void @main.prinfsub(double 1.001000e+02) + call void @main.printnl() ret void } define void @main.prinfsub(double %0) { _llgo_0: %1 = fneg double %0 + call void @main.printfloat(double %1) ret void } @@ -119,6 +108,192 @@ _llgo_0: ret void } +define void @main.printfloat(double %0) { +_llgo_0: + %1 = fcmp one double %0, %0 + br i1 %1, label %_llgo_1, label %_llgo_3 + +_llgo_1: ; preds = %_llgo_0 + %2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 3) + call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %2) + ret void + +_llgo_2: ; preds = %_llgo_7 + %3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 4) + call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %3) + ret void + +_llgo_3: ; preds = %_llgo_0 + %4 = fadd double %0, %0 + %5 = fcmp oeq double %4, %0 + br i1 %5, label %_llgo_6, label %_llgo_7 + +_llgo_4: ; preds = %_llgo_10 + %6 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 4) + call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %6) + ret void + +_llgo_5: ; preds = %_llgo_7 + %7 = fadd double %0, %0 + %8 = fcmp oeq double %7, %0 + br i1 %8, label %_llgo_9, label %_llgo_10 + +_llgo_6: ; preds = %_llgo_3 + %9 = fcmp ogt double %0, 0.000000e+00 + br label %_llgo_7 + +_llgo_7: ; preds = %_llgo_6, %_llgo_3 + %10 = phi i1 [ false, %_llgo_3 ], [ %9, %_llgo_6 ] + br i1 %10, label %_llgo_2, label %_llgo_5 + +_llgo_8: ; preds = %_llgo_10 + %11 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 14) + %12 = getelementptr inbounds i8, ptr %11, i64 0 + store i8 43, ptr %12, align 1 + %13 = fcmp oeq double %0, 0.000000e+00 + br i1 %13, label %_llgo_11, label %_llgo_13 + +_llgo_9: ; preds = %_llgo_5 + %14 = fcmp olt double %0, 0.000000e+00 + br label %_llgo_10 + +_llgo_10: ; preds = %_llgo_9, %_llgo_5 + %15 = phi i1 [ false, %_llgo_5 ], [ %14, %_llgo_9 ] + br i1 %15, label %_llgo_4, label %_llgo_8 + +_llgo_11: ; preds = %_llgo_8 + %16 = fdiv double 1.000000e+00, %0 + %17 = fcmp olt double %16, 0.000000e+00 + br i1 %17, label %_llgo_14, label %_llgo_12 + +_llgo_12: ; preds = %_llgo_24, %_llgo_22, %_llgo_14, %_llgo_11 + %18 = phi double [ %0, %_llgo_11 ], [ %36, %_llgo_22 ], [ %0, %_llgo_14 ], [ %42, %_llgo_24 ] + %19 = phi i64 [ 0, %_llgo_11 ], [ %32, %_llgo_22 ], [ 0, %_llgo_14 ], [ %41, %_llgo_24 ] + br label %_llgo_27 + +_llgo_13: ; preds = %_llgo_8 + %20 = fcmp olt double %0, 0.000000e+00 + br i1 %20, label %_llgo_15, label %_llgo_17 + +_llgo_14: ; preds = %_llgo_11 + %21 = getelementptr inbounds i8, ptr %11, i64 0 + store i8 45, ptr %21, align 1 + br label %_llgo_12 + +_llgo_15: ; preds = %_llgo_13 + %22 = fneg double %0 + %23 = getelementptr inbounds i8, ptr %11, i64 0 + store i8 45, ptr %23, align 1 + br label %_llgo_17 + +_llgo_16: ; preds = %_llgo_17 + %24 = add i64 %27, 1 + %25 = fdiv double %26, 1.000000e+01 + br label %_llgo_17 + +_llgo_17: ; preds = %_llgo_16, %_llgo_15, %_llgo_13 + %26 = phi double [ %0, %_llgo_13 ], [ %25, %_llgo_16 ], [ %22, %_llgo_15 ] + %27 = phi i64 [ 0, %_llgo_13 ], [ %24, %_llgo_16 ], [ 0, %_llgo_15 ] + %28 = fcmp oge double %26, 1.000000e+01 + br i1 %28, label %_llgo_16, label %_llgo_20 + +_llgo_18: ; preds = %_llgo_20 + %29 = sub i64 %32, 1 + %30 = fmul double %31, 1.000000e+01 + br label %_llgo_20 + +_llgo_19: ; preds = %_llgo_20 + br label %_llgo_23 + +_llgo_20: ; preds = %_llgo_18, %_llgo_17 + %31 = phi double [ %26, %_llgo_17 ], [ %30, %_llgo_18 ] + %32 = phi i64 [ %27, %_llgo_17 ], [ %29, %_llgo_18 ] + %33 = fcmp olt double %31, 1.000000e+00 + br i1 %33, label %_llgo_18, label %_llgo_19 + +_llgo_21: ; preds = %_llgo_23 + %34 = fdiv double %38, 1.000000e+01 + %35 = add i64 %39, 1 + br label %_llgo_23 + +_llgo_22: ; preds = %_llgo_23 + %36 = fadd double %31, %38 + %37 = fcmp oge double %36, 1.000000e+01 + br i1 %37, label %_llgo_24, label %_llgo_12 + +_llgo_23: ; preds = %_llgo_21, %_llgo_19 + %38 = phi double [ 5.000000e+00, %_llgo_19 ], [ %34, %_llgo_21 ] + %39 = phi i64 [ 0, %_llgo_19 ], [ %35, %_llgo_21 ] + %40 = icmp slt i64 %39, 7 + br i1 %40, label %_llgo_21, label %_llgo_22 + +_llgo_24: ; preds = %_llgo_22 + %41 = add i64 %32, 1 + %42 = fdiv double %36, 1.000000e+01 + br label %_llgo_12 + +_llgo_25: ; preds = %_llgo_27 + %43 = fptosi double %59 to i64 + %44 = add i64 %60, 2 + %45 = add i64 %43, 48 + %46 = trunc i64 %45 to i8 + %47 = getelementptr inbounds i8, ptr %11, i64 %44 + store i8 %46, ptr %47, align 1 + %48 = sitofp i64 %43 to double + %49 = fsub double %59, %48 + %50 = fmul double %49, 1.000000e+01 + %51 = add i64 %60, 1 + br label %_llgo_27 + +_llgo_26: ; preds = %_llgo_27 + %52 = getelementptr inbounds i8, ptr %11, i64 2 + %53 = load i8, ptr %52, align 1 + %54 = getelementptr inbounds i8, ptr %11, i64 1 + store i8 %53, ptr %54, align 1 + %55 = getelementptr inbounds i8, ptr %11, i64 2 + store i8 46, ptr %55, align 1 + %56 = getelementptr inbounds i8, ptr %11, i64 9 + store i8 101, ptr %56, align 1 + %57 = getelementptr inbounds i8, ptr %11, i64 10 + store i8 43, ptr %57, align 1 + %58 = icmp slt i64 %19, 0 + br i1 %58, label %_llgo_28, label %_llgo_29 + +_llgo_27: ; preds = %_llgo_25, %_llgo_12 + %59 = phi double [ %18, %_llgo_12 ], [ %50, %_llgo_25 ] + %60 = phi i64 [ 0, %_llgo_12 ], [ %51, %_llgo_25 ] + %61 = icmp slt i64 %60, 7 + br i1 %61, label %_llgo_25, label %_llgo_26 + +_llgo_28: ; preds = %_llgo_26 + %62 = sub i64 0, %19 + %63 = getelementptr inbounds i8, ptr %11, i64 10 + store i8 45, ptr %63, align 1 + br label %_llgo_29 + +_llgo_29: ; preds = %_llgo_28, %_llgo_26 + %64 = phi i64 [ %19, %_llgo_26 ], [ %62, %_llgo_28 ] + %65 = sdiv i64 %64, 100 + %66 = trunc i64 %65 to i8 + %67 = add i8 %66, 48 + %68 = getelementptr inbounds i8, ptr %11, i64 11 + store i8 %67, ptr %68, align 1 + %69 = sdiv i64 %64, 10 + %70 = trunc i64 %69 to i8 + %71 = urem i8 %70, 10 + %72 = add i8 %71, 48 + %73 = getelementptr inbounds i8, ptr %11, i64 12 + store i8 %72, ptr %73, align 1 + %74 = srem i64 %64, 10 + %75 = trunc i64 %74 to i8 + %76 = add i8 %75, 48 + %77 = getelementptr inbounds i8, ptr %11, i64 13 + store i8 %76, ptr %77, align 1 + %78 = call %"github.com/goplus/llgo/internal/runtime.Slice" @"github.com/goplus/llgo/internal/runtime.NewSlice3"(ptr %11, i64 1, i64 14, i64 0, i64 14, i64 14) + call void @main.gwrite(%"github.com/goplus/llgo/internal/runtime.Slice" %78) + ret void +} + define void @main.printhex(i64 %0) { _llgo_0: %1 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 100) @@ -126,7 +301,7 @@ _llgo_0: _llgo_1: ; preds = %_llgo_3 %2 = urem i64 %14, 16 - %3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 16) + %3 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 16) %4 = call ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String" %3) %5 = getelementptr inbounds i8, ptr %4, i64 %2 %6 = load i8, ptr %5, align 1 @@ -170,7 +345,7 @@ _llgo_0: br i1 %1, label %_llgo_1, label %_llgo_2 _llgo_1: ; preds = %_llgo_0 - %2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 1) + %2 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @6, i64 1) call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %2) %3 = sub i64 0, %0 br label %_llgo_2 @@ -183,14 +358,14 @@ _llgo_2: ; preds = %_llgo_1, %_llgo_0 define void @main.printnl() { _llgo_0: - %0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 1) + %0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @7, i64 1) call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %0) ret void } define void @main.printsp() { _llgo_0: - %0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 1) + %0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @8, i64 1) call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %0) ret void } @@ -256,14 +431,12 @@ declare ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64) declare i64 @"github.com/goplus/llgo/internal/runtime.SliceLen"(%"github.com/goplus/llgo/internal/runtime.Slice") -declare ptr @"github.com/goplus/llgo/internal/runtime.SliceData"(%"github.com/goplus/llgo/internal/runtime.Slice") - declare i32 @printf(ptr, ...) 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 ptr @"github.com/goplus/llgo/internal/runtime.StringData"(%"github.com/goplus/llgo/internal/runtime.String") - 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") diff --git a/cl/_testrt/cast/in.go b/cl/_testrt/cast/in.go new file mode 100644 index 00000000..8c2927e3 --- /dev/null +++ b/cl/_testrt/cast/in.go @@ -0,0 +1,158 @@ +package main + +//"github.com/goplus/llgo/internal/runtime/c" + +func main() { + cvt64to8(0, 0) + cvt64to8(127, 127) + cvt64to8(128, -128) + cvt64to8(-128, -128) + cvt64to8(-129, 127) + cvt64to8(256, 0) + + cvt64to8U(0, 0) + cvt64to8U(255, 255) + cvt64to8U(256, 0) + cvt64to8U(257, 1) + cvt64to8U(-1, 255) + + cvt32Fto8(0.1, 0) + cvt32Fto8(127.1, 127) + cvt32Fto8(128.1, -128) + cvt32Fto8(-128.1, -128) + cvt32Fto8(-129.1, 127) + cvt32Fto8(256.1, 0) + + cvt32Fto8U(0, 0) + cvt32Fto8U(255, 255) + cvt32Fto8U(256, 0) + cvt32Fto8U(257, 1) + cvt32Fto8U(-1, 255) + + // MaxInt32 = 1<<31 - 1 // 2147483647 + // MinInt32 = -1 << 31 // -2147483648 + cvt32Fto32(0, 0) + cvt32Fto32(1.5, 1) + cvt32Fto32(1147483647.1, 1147483648) + cvt32Fto32(2147483647.1, -2147483648) + cvt32Fto32(4147483647.1, -2147483648) + cvt32Fto32(-2147483648.1, -2147483648) + cvt32Fto32(-2147482648.1, -2147482624) + + // MaxUint32 = 1<<32 - 1 // 4294967295 + cvt32Fto32U(0, 0) + cvt32Fto32U(1.5, 1) + cvt32Fto32U(4294967295.1, 0) + cvt32Fto32U(5294967295.1, 1000000000) + cvt32Fto32U(-4294967295.1, 0) + cvt32Fto32U(-1294967295.1, 3000000000) + cvt32Fto32U(-1.1, 4294967295) + + // MaxFloat32 = 0x1p127 * (1 + (1 - 0x1p-23)) // 3.40282346638528859811704183484516925440e+38 + // SmallestNonzeroFloat32 = 0x1p-126 * 0x1p-23 // 1.401298464324817070923729583289916131280e-45 + // MaxFloat64 = 0x1p1023 * (1 + (1 - 0x1p-52)) // 1.79769313486231570814527423731704356798070e+308 + // SmallestNonzeroFloat64 = 0x1p-1022 * 0x1p-52 // 4.9406564584124654417656879286822137236505980e-324 + + cvt32Fto64F(0, 0) + cvt32Fto64F(1.5, 1.5) + cvt32Fto64F(1e10, 1e10) + cvt32Fto64F(-1e10, -1e10) + + cvt64Fto32F(0, 0) + cvt64Fto32F(1.5, 1.5) + cvt64Fto32F(1e10, 1e10) + cvt64Fto32F(-1e10, -1e10) + + // MaxInt64 = 1<<63 - 1 // 9223372036854775807 + // MinInt64 = -1 << 63 // -9223372036854775808 + cvt64to64F(0, 0) + cvt64to64F(1e10, 1e10) + cvt64to64F(9223372036854775807, 9223372036854775807) + cvt64to64F(-9223372036854775807, -9223372036854775807) + + // MaxUint64 = 1<<64 - 1 // 18446744073709551615 + cvt64Uto64F(0, 0) + cvt64Uto64F(1e10, 1e10) + cvt64Uto64F(9223372036854775807, 9223372036854775807) + cvt64Uto64F(18446744073709551615, 18446744073709551615) + + cvt32to64(0, 0) + cvt32to64(2147483647, 2147483647) + + cvtUinptr(1024, 1024) +} + +func cvtUinptr(a int32, b uintptr) { + if uintptr(a) != b { + panic("error") + } + if int32(b) != a { + panic("error") + } +} + +func cvt32to64(a int32, b int64) { + if int64(a) != b { + panic("error") + } +} + +func cvt64to64F(a int64, b float64) { + if float64(a) != b { + panic("error") + } +} + +func cvt64Uto64F(a uint64, b float64) { + if float64(a) != b { + panic("error") + } +} + +func cvt64Fto32F(a float64, b float32) { + if float32(a) != b { + panic("error") + } +} + +func cvt32Fto64F(a float32, b float64) { + if float64(a) != b { + panic("error") + } +} + +func cvt32Fto32(a float32, b int32) { + if int32(a) != b { + panic("error") + } +} + +func cvt32Fto32U(a float32, b uint32) { + if uint32(a) != b { + panic("error") + } +} + +func cvt32Fto8(a float32, b int8) { + if int8(a) != b { + panic("error") + } +} + +func cvt32Fto8U(a float32, b uint8) { + if uint8(a) != b { + panic("error") + } +} + +func cvt64to8(a int64, b int8) { + if int8(a) != b { + panic("error") + } +} + +func cvt64to8U(a int, b uint8) { + if uint8(a) != b { + panic("error") + } +} diff --git a/cl/_testrt/cast/out.ll b/cl/_testrt/cast/out.ll new file mode 100644 index 00000000..65c7100b --- /dev/null +++ b/cl/_testrt/cast/out.ll @@ -0,0 +1,310 @@ +; ModuleID = 'main' +source_filename = "main" + +%"github.com/goplus/llgo/internal/runtime.String" = type { ptr, i64 } +%"github.com/goplus/llgo/internal/runtime.iface" = type { ptr, ptr } + +@"main.init$guard" = global ptr null +@0 = private unnamed_addr constant [6 x i8] c"error\00", align 1 +@1 = private unnamed_addr constant [6 x i8] c"error\00", align 1 +@2 = private unnamed_addr constant [6 x i8] c"error\00", align 1 +@3 = private unnamed_addr constant [6 x i8] c"error\00", align 1 +@4 = private unnamed_addr constant [6 x i8] c"error\00", align 1 +@5 = private unnamed_addr constant [6 x i8] c"error\00", align 1 +@6 = private unnamed_addr constant [6 x i8] c"error\00", align 1 +@7 = private unnamed_addr constant [6 x i8] c"error\00", align 1 +@8 = private unnamed_addr constant [6 x i8] c"error\00", align 1 +@9 = private unnamed_addr constant [6 x i8] c"error\00", align 1 +@10 = private unnamed_addr constant [6 x i8] c"error\00", align 1 +@11 = private unnamed_addr constant [6 x i8] c"error\00", align 1 +@12 = private unnamed_addr constant [6 x i8] c"error\00", align 1 +@__llgo_argc = global ptr null +@__llgo_argv = global ptr null + +define void @main.cvt32Fto32(float %0, i32 %1) { +_llgo_0: + %2 = fptosi float %0 to i32 + %3 = icmp ne i32 %2, %1 + br i1 %3, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @0, i64 5) + %5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4) + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5) + unreachable + +_llgo_2: ; preds = %_llgo_0 + ret void +} + +define void @main.cvt32Fto32U(float %0, i32 %1) { +_llgo_0: + %2 = fptoui float %0 to i32 + %3 = icmp ne i32 %2, %1 + br i1 %3, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @1, i64 5) + %5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4) + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5) + unreachable + +_llgo_2: ; preds = %_llgo_0 + ret void +} + +define void @main.cvt32Fto64F(float %0, double %1) { +_llgo_0: + %2 = fpext float %0 to double + %3 = fcmp one double %2, %1 + br i1 %3, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @2, i64 5) + %5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4) + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5) + unreachable + +_llgo_2: ; preds = %_llgo_0 + ret void +} + +define void @main.cvt32Fto8(float %0, i8 %1) { +_llgo_0: + %2 = fptosi float %0 to i8 + %3 = icmp ne i8 %2, %1 + br i1 %3, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 5) + %5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4) + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5) + unreachable + +_llgo_2: ; preds = %_llgo_0 + ret void +} + +define void @main.cvt32Fto8U(float %0, i8 %1) { +_llgo_0: + %2 = fptoui float %0 to i8 + %3 = icmp ne i8 %2, %1 + br i1 %3, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, i64 5) + %5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4) + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5) + unreachable + +_llgo_2: ; preds = %_llgo_0 + ret void +} + +define void @main.cvt32to64(i32 %0, i64 %1) { +_llgo_0: + %2 = sext i32 %0 to i64 + %3 = icmp ne i64 %2, %1 + br i1 %3, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 5) + %5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4) + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5) + unreachable + +_llgo_2: ; preds = %_llgo_0 + ret void +} + +define void @main.cvt64Fto32F(double %0, float %1) { +_llgo_0: + %2 = fptrunc double %0 to float + %3 = fcmp one float %2, %1 + br i1 %3, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @6, i64 5) + %5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4) + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5) + unreachable + +_llgo_2: ; preds = %_llgo_0 + ret void +} + +define void @main.cvt64Uto64F(i64 %0, double %1) { +_llgo_0: + %2 = uitofp i64 %0 to double + %3 = fcmp one double %2, %1 + br i1 %3, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @7, i64 5) + %5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4) + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5) + unreachable + +_llgo_2: ; preds = %_llgo_0 + ret void +} + +define void @main.cvt64to64F(i64 %0, double %1) { +_llgo_0: + %2 = sitofp i64 %0 to double + %3 = fcmp one double %2, %1 + br i1 %3, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @8, i64 5) + %5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4) + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5) + unreachable + +_llgo_2: ; preds = %_llgo_0 + ret void +} + +define void @main.cvt64to8(i64 %0, i8 %1) { +_llgo_0: + %2 = trunc i64 %0 to i8 + %3 = icmp ne i8 %2, %1 + br i1 %3, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @9, i64 5) + %5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4) + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5) + unreachable + +_llgo_2: ; preds = %_llgo_0 + ret void +} + +define void @main.cvt64to8U(i64 %0, i8 %1) { +_llgo_0: + %2 = trunc i64 %0 to i8 + %3 = icmp ne i8 %2, %1 + br i1 %3, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @10, i64 5) + %5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4) + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5) + unreachable + +_llgo_2: ; preds = %_llgo_0 + ret void +} + +define void @main.cvtUinptr(i32 %0, i64 %1) { +_llgo_0: + %2 = sext i32 %0 to i64 + %3 = icmp ne i64 %2, %1 + br i1 %3, label %_llgo_1, label %_llgo_2 + +_llgo_1: ; preds = %_llgo_0 + %4 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @11, i64 5) + %5 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %4) + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %5) + unreachable + +_llgo_2: ; preds = %_llgo_0 + %6 = trunc i64 %1 to i32 + %7 = icmp ne i32 %6, %0 + br i1 %7, label %_llgo_3, label %_llgo_4 + +_llgo_3: ; preds = %_llgo_2 + %8 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @12, i64 5) + %9 = call %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String" %8) + call void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface" %9) + unreachable + +_llgo_4: ; preds = %_llgo_2 + ret void +} + +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() + call void @main.cvt64to8(i64 0, i8 0) + call void @main.cvt64to8(i64 127, i8 127) + call void @main.cvt64to8(i64 128, i8 -128) + call void @main.cvt64to8(i64 -128, i8 -128) + call void @main.cvt64to8(i64 -129, i8 127) + call void @main.cvt64to8(i64 256, i8 0) + call void @main.cvt64to8U(i64 0, i8 0) + call void @main.cvt64to8U(i64 255, i8 -1) + call void @main.cvt64to8U(i64 256, i8 0) + call void @main.cvt64to8U(i64 257, i8 1) + call void @main.cvt64to8U(i64 -1, i8 -1) + call void @main.cvt32Fto8(float 0x3FB99999A0000000, i8 0) + call void @main.cvt32Fto8(float 0x405FC66660000000, i8 127) + call void @main.cvt32Fto8(float 0x4060033340000000, i8 -128) + call void @main.cvt32Fto8(float 0xC060033340000000, i8 -128) + call void @main.cvt32Fto8(float 0xC060233340000000, i8 127) + call void @main.cvt32Fto8(float 0x40700199A0000000, i8 0) + call void @main.cvt32Fto8U(float 0.000000e+00, i8 0) + call void @main.cvt32Fto8U(float 2.550000e+02, i8 -1) + call void @main.cvt32Fto8U(float 2.560000e+02, i8 0) + call void @main.cvt32Fto8U(float 2.570000e+02, i8 1) + call void @main.cvt32Fto8U(float -1.000000e+00, i8 -1) + call void @main.cvt32Fto32(float 0.000000e+00, i32 0) + call void @main.cvt32Fto32(float 1.500000e+00, i32 1) + call void @main.cvt32Fto32(float 0x41D1194D80000000, i32 1147483648) + call void @main.cvt32Fto32(float 0x41E0000000000000, i32 -2147483648) + call void @main.cvt32Fto32(float 0x41EEE6B280000000, i32 -2147483648) + call void @main.cvt32Fto32(float 0xC1E0000000000000, i32 -2147483648) + call void @main.cvt32Fto32(float 0xC1DFFFFF00000000, i32 -2147482624) + call void @main.cvt32Fto32U(float 0.000000e+00, i32 0) + call void @main.cvt32Fto32U(float 1.500000e+00, i32 1) + call void @main.cvt32Fto32U(float 0x41F0000000000000, i32 0) + call void @main.cvt32Fto32U(float 0x41F3B9ACA0000000, i32 1000000000) + call void @main.cvt32Fto32U(float 0xC1F0000000000000, i32 0) + call void @main.cvt32Fto32U(float 0xC1D34BE880000000, i32 -1294967296) + call void @main.cvt32Fto32U(float 0xBFF19999A0000000, i32 -1) + call void @main.cvt32Fto64F(float 0.000000e+00, double 0.000000e+00) + call void @main.cvt32Fto64F(float 1.500000e+00, double 1.500000e+00) + call void @main.cvt32Fto64F(float 1.000000e+10, double 1.000000e+10) + call void @main.cvt32Fto64F(float -1.000000e+10, double -1.000000e+10) + call void @main.cvt64Fto32F(double 0.000000e+00, float 0.000000e+00) + call void @main.cvt64Fto32F(double 1.500000e+00, float 1.500000e+00) + call void @main.cvt64Fto32F(double 1.000000e+10, float 1.000000e+10) + call void @main.cvt64Fto32F(double -1.000000e+10, float -1.000000e+10) + call void @main.cvt64to64F(i64 0, double 0.000000e+00) + call void @main.cvt64to64F(i64 10000000000, double 1.000000e+10) + call void @main.cvt64to64F(i64 9223372036854775807, double 0x43E0000000000000) + call void @main.cvt64to64F(i64 -9223372036854775807, double 0xC3E0000000000000) + call void @main.cvt64Uto64F(i64 0, double 0.000000e+00) + call void @main.cvt64Uto64F(i64 10000000000, double 1.000000e+10) + call void @main.cvt64Uto64F(i64 9223372036854775807, double 0x43E0000000000000) + call void @main.cvt64Uto64F(i64 -1, double 0x43F0000000000000) + call void @main.cvt32to64(i32 0, i64 0) + call void @main.cvt32to64(i32 2147483647, i64 2147483647) + call void @main.cvtUinptr(i32 1024, i64 1024) + ret void +} + +declare %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr, i64) + +declare %"github.com/goplus/llgo/internal/runtime.iface" @"github.com/goplus/llgo/internal/runtime.MakeAnyString"(%"github.com/goplus/llgo/internal/runtime.String") + +declare void @"github.com/goplus/llgo/internal/runtime.TracePanic"(%"github.com/goplus/llgo/internal/runtime.iface") + +declare void @"github.com/goplus/llgo/internal/runtime.init"() diff --git a/ssa/expr.go b/ssa/expr.go index 4dfa3b62..5a6bbb57 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -962,19 +962,64 @@ func (b Builder) ChangeType(t Type, x Expr) (ret Expr) { // // t1 = convert []byte <- string (t0) func (b Builder) Convert(t Type, x Expr) (ret Expr) { + if debugInstr { + log.Printf("Convert %v <- %v\n", t.RawType(), x.RawType()) + } typ := t.raw.Type ret.Type = b.Prog.rawType(typ) - switch und := typ.Underlying().(type) { + switch typ := typ.Underlying().(type) { case *types.Basic: - kind := und.Kind() - switch { - case kind >= types.Int && kind <= types.Uintptr: + switch typ.Kind() { + case types.Uintptr: ret.impl = castInt(b.impl, x.impl, t.ll) return - case kind == types.UnsafePointer: + case types.UnsafePointer: ret.impl = castPtr(b.impl, x.impl, t.ll) return } + switch xtyp := x.RawType().Underlying().(type) { + case *types.Basic: + size := b.Prog.SizeOf(t) + xsize := b.Prog.SizeOf(x.Type) + if typ.Info()&types.IsInteger != 0 { + // int <- int/float + if xtyp.Info()&types.IsInteger != 0 { + // if xsize > size { + // ret.impl = b.impl.CreateTrunc(x.impl, t.ll, "") + // } else if typ.Info()&types.IsUnsigned != 0 { + // ret.impl = b.impl.CreateZExt(x.impl, t.ll, "") + // } else { + // ret.impl = b.impl.CreateSExt(x.impl, t.ll, "") + // } + ret.impl = castInt(b.impl, x.impl, t.ll) + return + } else if xtyp.Info()&types.IsFloat != 0 { + if typ.Info()&types.IsUnsigned != 0 { + ret.impl = b.impl.CreateFPToUI(x.impl, t.ll, "") + } else { + ret.impl = b.impl.CreateFPToSI(x.impl, t.ll, "") + } + return + } + } else if typ.Info()&types.IsFloat != 0 { + // float <- int/float + if xtyp.Info()&types.IsInteger != 0 { + if xtyp.Info()&types.IsUnsigned != 0 { + ret.impl = b.impl.CreateUIToFP(x.impl, t.ll, "") + } else { + ret.impl = b.impl.CreateSIToFP(x.impl, t.ll, "") + } + return + } else if xtyp.Info()&types.IsFloat != 0 { + if xsize > size { + ret.impl = b.impl.CreateFPTrunc(x.impl, t.ll, "") + } else { + ret.impl = b.impl.CreateFPExt(x.impl, t.ll, "") + } + return + } + } + } case *types.Pointer: ret.impl = castPtr(b.impl, x.impl, t.ll) return