Pārlūkot izejas kodu

закончил операции

kpmy 9 gadi atpakaļ
vecāks
revīzija
7cab2da480
4 mainītis faili ar 190 papildinājumiem un 3 dzēšanām
  1. BIN
      TODO.odc
  2. 84 0
      ir/code.go
  3. 100 2
      ir/ops/op.go
  4. 6 1
      tiss_test.go

BIN
TODO.odc


+ 84 - 0
ir/code.go

@@ -1,6 +1,7 @@
 package ir
 package ir
 
 
 import (
 import (
+	"github.com/kpmy/tiss/ir/ops"
 	"github.com/kpmy/tiss/ir/types"
 	"github.com/kpmy/tiss/ir/types"
 	"github.com/kpmy/ypk/fn"
 	"github.com/kpmy/ypk/fn"
 	. "github.com/kpmy/ypk/tc"
 	. "github.com/kpmy/ypk/tc"
@@ -152,3 +153,86 @@ func (s *SetLocalExpr) Children() (ret []interface{}) {
 }
 }
 
 
 func (*SetLocalExpr) Eval() {}
 func (*SetLocalExpr) Eval() {}
+
+type MonadicOp struct {
+	Op   *ops.MonadicOpCode
+	Expr CodeExpr
+}
+
+func (m *MonadicOp) Name() string {
+	return m.Op.String()
+}
+
+func (m *MonadicOp) Validate() (err error) {
+	if fn.IsNil(m.Expr) {
+		err = Error("no expression for monadic op")
+	}
+
+	if fn.IsNil(m.Op) {
+		err = Error("no operation for monadic op")
+	}
+	return
+}
+
+func (m *MonadicOp) Children() (ret []interface{}) {
+	return append(ret, m.Expr)
+}
+
+func (*MonadicOp) Eval() {}
+
+type DyadicOp struct {
+	Op          *ops.DyadicOpCode
+	Left, Right CodeExpr
+}
+
+func (d *DyadicOp) Name() string {
+	return d.Op.String()
+}
+
+func (d *DyadicOp) Validate() (err error) {
+	if fn.IsNil(d.Left) {
+		err = Error("no left expression for dyadic op")
+	}
+
+	if fn.IsNil(d.Op) {
+		err = Error("no operation for dyadic op")
+	}
+
+	if fn.IsNil(d.Right) {
+		err = Error("no right expression for dyadic op")
+	}
+	return
+}
+
+func (d *DyadicOp) Children() (ret []interface{}) {
+	return append(ret, d.Left, d.Right)
+}
+
+func (*DyadicOp) Eval() {}
+
+type ConvertOp struct {
+	Op   *ops.ConvertOpCode
+	Expr CodeExpr
+}
+
+func (c *ConvertOp) Name() string {
+	return c.Op.String()
+}
+
+func (c *ConvertOp) Validate() (err error) {
+	if fn.IsNil(c.Expr) {
+		err = Error("no expression for convert op")
+	}
+
+	if fn.IsNil(c.Op) {
+		err = Error("no operation for convert op")
+	}
+
+	return
+}
+
+func (c *ConvertOp) Children() (ret []interface{}) {
+	return append(ret, c.Expr)
+}
+
+func (*ConvertOp) Eval() {}

+ 100 - 2
ir/ops/op.go

@@ -83,7 +83,7 @@ const Ge Op = "ge"
 //const Ge Op = "ge"
 //const Ge Op = "ge"
 
 
 //conversion
 //conversion
-const Wrap Op = "wrap" // i32_ /i64
+const Wrap Op = "wrap" // i32_ /i64 +
 //const Trunc Op = "trunc"             // i32_, i64_ * _s, _u * /f32, /f64
 //const Trunc Op = "trunc"             // i32_, i64_ * _s, _u * /f32, /f64
 const Extend Op = "extend"           // i64_ * _s, _u * /i32
 const Extend Op = "extend"           // i64_ * _s, _u * /i32
 const Convert Op = "convert"         // f32_, f64_ * _s, _u * /i32, /i64
 const Convert Op = "convert"         // f32_, f64_ * _s, _u * /i32, /i64
@@ -125,6 +125,7 @@ type DyadicOpCode struct {
 
 
 var ii_ops = fmt.Sprint(Add, Sub, Mul, Div, Rem, And, Or, Xor, Shl, Shr, RotL, RotR, Eq, Ne, Le, Lt, Ge, Gt)
 var ii_ops = fmt.Sprint(Add, Sub, Mul, Div, Rem, And, Or, Xor, Shl, Shr, RotL, RotR, Eq, Ne, Le, Lt, Ge, Gt)
 var ii_sign = fmt.Sprint(Div, Rem, Shr, Le, Lt, Ge, Gt)
 var ii_sign = fmt.Sprint(Div, Rem, Shr, Le, Lt, Ge, Gt)
+var ff_ops = fmt.Sprint(Add, Sub, Mul, Div, Min, Max, CopySign, Eq, Ne, Le, Lt, Ge, Gt)
 
 
 func (d DyadicOpCode) String() (ret string) {
 func (d DyadicOpCode) String() (ret string) {
 	if d.l == d.r {
 	if d.l == d.r {
@@ -148,8 +149,13 @@ func Dyadic(l, r types.Type, op Op, signed ...bool) (ret DyadicOpCode) {
 		case types.I32, types.I64:
 		case types.I32, types.I64:
 			Assert(strings.Contains(ii_ops, string(op)), 21)
 			Assert(strings.Contains(ii_ops, string(op)), 21)
 			if strings.Contains(ii_sign, string(op)) {
 			if strings.Contains(ii_sign, string(op)) {
-				Assert(len(signed) > 0, 21)
+				Assert(len(signed) > 0, 22)
+			} else {
+				Assert(len(signed) == 0, 24)
 			}
 			}
+		case types.F32, types.F64:
+			Assert(strings.Contains(ff_ops, string(op)), 23)
+			Assert(len(signed) == 0, 24)
 		default:
 		default:
 			Halt(100)
 			Halt(100)
 		}
 		}
@@ -164,3 +170,95 @@ func Dyadic(l, r types.Type, op Op, signed ...bool) (ret DyadicOpCode) {
 	}
 	}
 	return
 	return
 }
 }
+
+type ConvertOpCode struct {
+	to, from types.Type
+	op       Op
+	signed   bool
+	sign     bool
+}
+
+func (c ConvertOpCode) String() (ret string) {
+	ret = fmt.Sprint(c.to, ".", c.op)
+	if c.sign {
+		if c.signed {
+			ret = fmt.Sprint(ret, "_s")
+		} else {
+			ret = fmt.Sprint(ret, "_u")
+		}
+	}
+	ret = fmt.Sprint(ret, "/", c.from)
+	return
+}
+
+func Conv(from, to types.Type, op Op, signed ...bool) (ret ConvertOpCode) {
+	Assert(from != to, 20)
+	switch to {
+	case types.I32:
+		Assert(strings.Contains(fmt.Sprint(Wrap, Trunc, Reinterpret), string(op)), 21)
+		if strings.Contains(fmt.Sprint(Trunc), string(op)) {
+			ret.sign = true
+			Assert(len(signed) > 0, 23)
+		} else {
+			Assert(len(signed) == 0, 24)
+		}
+		switch op {
+		case Wrap:
+			Assert(from == types.I64, 25)
+		case Trunc, Reinterpret:
+			Assert(from == types.F32, 26)
+		}
+	case types.I64:
+		Assert(strings.Contains(fmt.Sprint(Extend, Trunc, Reinterpret), string(op)), 21)
+		if strings.Contains(fmt.Sprint(Trunc, Extend), string(op)) {
+			ret.sign = true
+			Assert(len(signed) > 0, 23)
+		} else {
+			Assert(len(signed) == 0, 24)
+		}
+		switch op {
+		case Extend:
+			Assert(from == types.I32, 25)
+		case Trunc, Reinterpret:
+			Assert(from == types.F64, 26)
+		}
+	case types.F32:
+		Assert(strings.Contains(fmt.Sprint(Convert, Demote, Reinterpret), string(op)), 21)
+		switch op {
+		case Convert:
+			Assert(from == types.I32 || from == types.I64, 22)
+			Assert(len(signed) > 0, 23)
+			ret.sign = true
+		case Demote:
+			Assert(from == types.F64, 22)
+			Assert(len(signed) == 0, 24)
+		case Reinterpret:
+			Assert(from == types.I32, 23)
+			Assert(len(signed) == 0, 24)
+		}
+	case types.F64:
+		Assert(strings.Contains(fmt.Sprint(Convert, Promote, Reinterpret), string(op)), 21)
+		switch op {
+		case Convert:
+			Assert(from == types.I32 || from == types.I64, 22)
+			Assert(len(signed) > 0, 23)
+			ret.sign = true
+		case Promote:
+			Assert(from == types.F32, 22)
+			Assert(len(signed) == 0, 24)
+		case Reinterpret:
+			Assert(from == types.I64, 23)
+			Assert(len(signed) == 0, 24)
+		}
+	default:
+		Halt(100, "unsupported")
+
+	}
+	ret.to = to
+	ret.from = from
+	ret.op = op
+	if len(signed) > 0 {
+		ret.signed = signed[0]
+	}
+	return
+}

+ 6 - 1
tiss_test.go

@@ -63,6 +63,11 @@ func TestOp(t *testing.T) {
 	t.Log(ops.Monadic(types.I32, ops.Clz))
 	t.Log(ops.Monadic(types.I32, ops.Clz))
 	t.Log(ops.Monadic(types.F32, ops.Nearest))
 	t.Log(ops.Monadic(types.F32, ops.Nearest))
 
 
-	t.Log(ops.Dyadic(types.I64, types.I64, ops.Add, true))
+	t.Log(ops.Dyadic(types.I64, types.I64, ops.Add))
 	t.Log(ops.Dyadic(types.I32, types.I32, ops.Ge, true))
 	t.Log(ops.Dyadic(types.I32, types.I32, ops.Ge, true))
+
+	t.Log(ops.Dyadic(types.F32, types.F32, ops.Min))
+
+	t.Log(ops.Conv(types.I64, types.F32, ops.Convert, true))
+	t.Log(ops.Conv(types.I64, types.F64, ops.Reinterpret))
 }
 }