2015-03-23 17:02:11 -07:00
|
|
|
// Copyright 2015 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
2015-05-28 16:45:33 -07:00
|
|
|
// values are specified using the following format:
|
2015-06-11 21:29:25 -07:00
|
|
|
// (op <type> [auxint] {aux} arg0 arg1 ...)
|
2015-05-28 16:45:33 -07:00
|
|
|
// the type and aux fields are optional
|
|
|
|
|
// on the matching side
|
2015-06-11 21:29:25 -07:00
|
|
|
// - the type, aux, and auxint fields must match if they are specified.
|
2015-05-28 16:45:33 -07:00
|
|
|
// on the generated side
|
|
|
|
|
// - the type of the top-level expression is the same as the one on the left-hand side.
|
|
|
|
|
// - the type of any subexpressions must be specified explicitly.
|
2015-06-11 21:29:25 -07:00
|
|
|
// - auxint will be 0 if not specified.
|
2015-05-28 16:45:33 -07:00
|
|
|
// - aux will be nil if not specified.
|
|
|
|
|
|
|
|
|
|
// blocks are specified using the following format:
|
|
|
|
|
// (kind controlvalue succ0 succ1 ...)
|
|
|
|
|
// controlvalue must be "nil" or a value expression
|
|
|
|
|
// succ* fields must be variables
|
|
|
|
|
// For now, the generated successors must be a permutation of the matched successors.
|
|
|
|
|
|
2015-03-23 17:02:11 -07:00
|
|
|
// constant folding
|
2015-07-28 14:19:20 -07:00
|
|
|
(Add64 (Const64 [c]) (Const64 [d])) -> (Const64 [c+d])
|
|
|
|
|
(AddPtr (ConstPtr [c]) (ConstPtr [d])) -> (ConstPtr [c+d])
|
|
|
|
|
(Mul64 (Const64 [c]) (Const64 [d])) -> (Const64 [c*d])
|
|
|
|
|
(MulPtr (ConstPtr [c]) (ConstPtr [d])) -> (ConstPtr [c*d])
|
|
|
|
|
(IsInBounds (ConstPtr [c]) (ConstPtr [d])) -> (ConstPtr {inBounds(c,d)})
|
2015-07-31 12:32:22 +02:00
|
|
|
(Eq64 x x) -> (ConstBool {true})
|
|
|
|
|
(Eq32 x x) -> (ConstBool {true})
|
|
|
|
|
(Eq16 x x) -> (ConstBool {true})
|
|
|
|
|
(Eq8 x x) -> (ConstBool {true})
|
|
|
|
|
(Neq64 x x) -> (ConstBool {false})
|
|
|
|
|
(Neq32 x x) -> (ConstBool {false})
|
|
|
|
|
(Neq16 x x) -> (ConstBool {false})
|
|
|
|
|
(Neq8 x x) -> (ConstBool {false})
|
2015-03-23 17:02:11 -07:00
|
|
|
|
2015-08-05 10:33:09 -07:00
|
|
|
(Com8 (Com8 x)) -> x
|
|
|
|
|
(Com16 (Com16 x)) -> x
|
|
|
|
|
(Com32 (Com32 x)) -> x
|
|
|
|
|
(Com64 (Com64 x)) -> x
|
2015-07-30 16:02:24 -04:00
|
|
|
|
2015-04-15 15:51:25 -07:00
|
|
|
// tear apart slices
|
|
|
|
|
// TODO: anything that generates a slice needs to go in here.
|
|
|
|
|
(SlicePtr (Load ptr mem)) -> (Load ptr mem)
|
2015-07-30 11:03:05 -07:00
|
|
|
(SliceLen (Load ptr mem)) -> (Load (AddPtr <ptr.Type> ptr (ConstPtr <config.Frontend().TypeUintptr()> [config.PtrSize])) mem)
|
|
|
|
|
(SliceCap (Load ptr mem)) -> (Load (AddPtr <ptr.Type> ptr (ConstPtr <config.Frontend().TypeUintptr()> [config.PtrSize*2])) mem)
|
2015-04-15 15:51:25 -07:00
|
|
|
|
2015-07-27 13:17:45 -07:00
|
|
|
// slice and interface comparisons
|
|
|
|
|
// the frontend ensures that we can only compare against nil
|
|
|
|
|
// start by putting nil on the right to simplify the other rules
|
2015-07-28 14:19:20 -07:00
|
|
|
(EqFat x y) && x.Op == OpConstNil && y.Op != OpConstNil -> (EqFat y x)
|
|
|
|
|
(NeqFat x y) && x.Op == OpConstNil && y.Op != OpConstNil -> (NeqFat y x)
|
2015-07-27 13:17:45 -07:00
|
|
|
// it suffices to check the first word (backing array for slices, dynamic type for interfaces)
|
2015-07-30 11:03:05 -07:00
|
|
|
(EqFat (Load ptr mem) (ConstNil)) -> (EqPtr (Load <config.Frontend().TypeUintptr()> ptr mem) (ConstPtr <config.Frontend().TypeUintptr()> [0]))
|
|
|
|
|
(NeqFat (Load ptr mem) (ConstNil)) -> (NeqPtr (Load <config.Frontend().TypeUintptr()> ptr mem) (ConstPtr <config.Frontend().TypeUintptr()> [0]))
|
2015-07-27 13:17:45 -07:00
|
|
|
|
2015-05-18 16:44:20 -07:00
|
|
|
// indexing operations
|
2015-04-15 15:51:25 -07:00
|
|
|
// Note: bounds check has already been done
|
2015-06-12 11:01:13 -07:00
|
|
|
(ArrayIndex (Load ptr mem) idx) -> (Load (PtrIndex <v.Type.PtrTo()> ptr idx) mem)
|
2015-07-30 11:03:05 -07:00
|
|
|
(PtrIndex <t> ptr idx) -> (AddPtr ptr (MulPtr <config.Frontend().TypeUintptr()> idx (ConstPtr <config.Frontend().TypeUintptr()> [t.Elem().Size()])))
|
2015-07-15 21:33:49 -07:00
|
|
|
(StructSelect [idx] (Load ptr mem)) -> (Load (OffPtr <v.Type.PtrTo()> [idx] ptr) mem)
|
2015-05-18 16:44:20 -07:00
|
|
|
|
|
|
|
|
// big-object moves
|
|
|
|
|
// TODO: fix size
|
|
|
|
|
(Store dst (Load <t> src mem) mem) && t.Size() > 8 -> (Move [t.Size()] dst src mem)
|
2015-05-28 16:45:33 -07:00
|
|
|
|
2015-05-27 14:52:22 -07:00
|
|
|
// string ops
|
2015-07-30 11:03:05 -07:00
|
|
|
(ConstString {s}) -> (StringMake (Addr <config.Frontend().TypeBytePtr()> {config.fe.StringData(s.(string))} (SB <config.Frontend().TypeUintptr()>)) (ConstPtr <config.Frontend().TypeUintptr()> [int64(len(s.(string)))]))
|
|
|
|
|
(Load <t> ptr mem) && t.IsString() -> (StringMake (Load <config.Frontend().TypeBytePtr()> ptr mem) (Load <config.Frontend().TypeUintptr()> (OffPtr <config.Frontend().TypeBytePtr()> [config.PtrSize] ptr) mem))
|
2015-05-27 14:52:22 -07:00
|
|
|
(StringPtr (StringMake ptr _)) -> ptr
|
|
|
|
|
(StringLen (StringMake _ len)) -> len
|
2015-07-30 11:03:05 -07:00
|
|
|
(Store dst str mem) && str.Type.IsString() -> (Store (OffPtr <config.Frontend().TypeBytePtr()> [config.PtrSize] dst) (StringLen <config.Frontend().TypeUintptr()> str) (Store <TypeMem> dst (StringPtr <config.Frontend().TypeBytePtr()> str) mem))
|
2015-06-06 16:03:33 -07:00
|
|
|
|
2015-08-12 11:22:16 -07:00
|
|
|
(If (IsNonNil (GetG)) yes no) -> (Plain nil yes)
|
|
|
|
|
|
2015-07-23 18:44:09 -05:00
|
|
|
(If (Not cond) yes no) -> (If cond no yes)
|
2015-07-28 14:19:20 -07:00
|
|
|
(If (ConstBool {c}) yes no) && c.(bool) -> (Plain nil yes)
|
|
|
|
|
(If (ConstBool {c}) yes no) && !c.(bool) -> (Plain nil no)
|