From 68949c28c83159b046e585caef151fb3e46ca21f Mon Sep 17 00:00:00 2001 From: visualfc Date: Tue, 7 May 2024 09:55:51 +0800 Subject: [PATCH] ssa.UnOp: sub/not/xor --- cl/_testdata/print/in.go | 37 +++++++++++++++++++----- cl/_testdata/print/out.ll | 60 ++++++++++++++++++++++++++++++++++++--- ssa/expr.go | 34 ++++++++++++++++++---- 3 files changed, 114 insertions(+), 17 deletions(-) diff --git a/cl/_testdata/print/in.go b/cl/_testdata/print/in.go index 8ab1f11c..f6edcf5c 100644 --- a/cl/_testdata/print/in.go +++ b/cl/_testdata/print/in.go @@ -100,13 +100,13 @@ func printuint(v uint64) { gwrite(buf[i:]) } -// func printint(v int64) { -// if v < 0 { -// printstring("-") -// v = -v -// } -// printuint(uint64(v)) -// } +func printint(v int64) { + if v < 0 { + printstring("-") + v = -v + } + printuint(uint64(v)) +} var minhexdigits = 0 @@ -171,4 +171,27 @@ func main() { printnl() printhex(0x1234abcf) printnl() + prinxor(1) + printnl() + prinsub(100) + printnl() + prinusub(1<<64 - 1) + printnl() + prinfsub(100.1) +} + +func prinxor(n int64) { + printint(^n) +} + +func prinsub(n int64) { + printint(-n) +} + +func prinusub(n uint64) { + printuint(-n) +} + +func prinfsub(n float64) { + _ = -n } diff --git a/cl/_testdata/print/out.ll b/cl/_testdata/print/out.ll index b8256d6e..0f2972ff 100644 --- a/cl/_testdata/print/out.ll +++ b/cl/_testdata/print/out.ll @@ -11,8 +11,9 @@ source_filename = "main" @0 = private unnamed_addr constant [3 x i8] c"%c\00", align 1 @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"\0A\00", align 1 -@4 = private unnamed_addr constant [2 x i8] c" \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 define %"github.com/goplus/llgo/internal/runtime.Slice" @main.bytes(%"github.com/goplus/llgo/internal/runtime.String" %0) { _llgo_0: @@ -91,6 +92,26 @@ _llgo_0: call void @main.printnl() call void @main.printhex(i64 305441743) call void @main.printnl() + call void @main.prinxor(i64 1) + call void @main.printnl() + call void @main.prinsub(i64 100) + call void @main.printnl() + call void @main.prinusub(i64 -1) + call void @main.printnl() + call void @main.prinfsub(double 1.001000e+02) + ret void +} + +define void @main.prinfsub(double %0) { +_llgo_0: + %1 = fneg double %0 + ret void +} + +define void @main.prinsub(i64 %0) { +_llgo_0: + %1 = sub i64 0, %0 + call void @main.printint(i64 %1) ret void } @@ -139,16 +160,33 @@ _llgo_5: ; preds = %_llgo_1 br i1 %21, label %_llgo_2, label %_llgo_4 } +define void @main.printint(i64 %0) { +_llgo_0: + %1 = icmp slt i64 %0, 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) + call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %2) + %3 = sub i64 0, %0 + br label %_llgo_2 + +_llgo_2: ; preds = %_llgo_1, %_llgo_0 + %4 = phi i64 [ %0, %_llgo_0 ], [ %3, %_llgo_1 ] + call void @main.printuint(i64 %4) + ret void +} + define void @main.printnl() { _llgo_0: - %0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @3, i64 1) + %0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @4, 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 @4, i64 1) + %0 = call %"github.com/goplus/llgo/internal/runtime.String" @"github.com/goplus/llgo/internal/runtime.NewString"(ptr @5, i64 1) call void @main.printstring(%"github.com/goplus/llgo/internal/runtime.String" %0) ret void } @@ -191,6 +229,20 @@ _llgo_4: ; preds = %_llgo_1 br label %_llgo_3 } +define void @main.prinusub(i64 %0) { +_llgo_0: + %1 = sub i64 0, %0 + call void @main.printuint(i64 %1) + ret void +} + +define void @main.prinxor(i64 %0) { +_llgo_0: + %1 = xor i64 %0, -1 + call void @main.printint(i64 %1) + ret void +} + define ptr @main.stringStructOf(ptr %0) { _llgo_0: ret ptr %0 diff --git a/ssa/expr.go b/ssa/expr.go index 80c69830..a8e4a0a4 100644 --- a/ssa/expr.go +++ b/ssa/expr.go @@ -342,15 +342,37 @@ func (b Builder) BinOp(op token.Token, x, y Expr) Expr { // XOR is bitwise complement. // SUB is negation. // NOT is logical negation. -func (b Builder) UnOp(op token.Token, x Expr) Expr { - switch op { - case token.MUL: - return b.Load(x) - } +func (b Builder) UnOp(op token.Token, x Expr) (ret Expr) { if debugInstr { log.Printf("UnOp %v, %v\n", op, x.impl) } - panic("todo") + switch op { + case token.MUL: + return b.Load(x) + case token.SUB: + switch t := x.Type.raw.Underlying().(type) { + case *types.Basic: + ret.Type = x.Type + if t.Info()&types.IsInteger != 0 { + ret.impl = b.impl.CreateNeg(x.impl, "") + } else if t.Info()&types.IsFloat != 0 { + ret.impl = b.impl.CreateFNeg(x.impl, "") + } else { + panic("todo") + } + default: + panic("unreachable") + } + case token.NOT: + ret.Type = x.Type + ret.impl = b.impl.CreateNot(x.impl, "") + case token.XOR: + ret.Type = x.Type + ret.impl = b.impl.CreateXor(x.impl, llvm.ConstInt(x.Type.ll, ^uint64(0), false), "") + case token.ARROW: + panic("todo") + } + return } // -----------------------------------------------------------------------------