// as the original load. If not, we end up making a value with
// memory type live in two different blocks, which can lead to
// multiple memory values alive simultaneously.
-// TODO: somehow have this rewrite rule put the new MOVBQSXload in
-// v.Args[0].Block instead of in v.Block?
-(MOVBQSX (MOVBload [off] {sym} ptr mem)) && b == v.Args[0].Block -> (MOVBQSXload [off] {sym} ptr mem)
-(MOVBQZX (MOVBload [off] {sym} ptr mem)) && b == v.Args[0].Block -> (MOVBQZXload [off] {sym} ptr mem)
+(MOVBQSX (MOVBload [off] {sym} ptr mem)) -> @v.Args[0].Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
+(MOVBQZX (MOVBload [off] {sym} ptr mem)) -> @v.Args[0].Block (MOVBQZXload <v.Type> [off] {sym} ptr mem)
// TODO: more
// Don't extend before storing
// Note: bounds check has already been done
(ArrayIndex (Load ptr mem) idx) && b == v.Args[0].Block -> (Load (PtrIndex <v.Type.PtrTo()> ptr idx) mem)
(PtrIndex <t> ptr idx) -> (AddPtr ptr (MulPtr idx (ConstPtr [t.Elem().Size()])))
-(StructSelect [idx] (Load ptr mem)) && b == v.Args[0].Block -> (Load (OffPtr <v.Type.PtrTo()> [idx] ptr) mem)
+(StructSelect [idx] (Load ptr mem)) -> @v.Args[0].Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [idx] ptr) mem)
// complex ops
(ComplexReal (ComplexMake real _ )) -> real
)
// rule syntax:
-// sexpr [&& extra conditions] -> sexpr
+// sexpr [&& extra conditions] -> [@block] sexpr
//
// sexpr are s-expressions (lisp-like parenthesized groupings)
// sexpr ::= (opcode sexpr*)
if t[1] == "nil" {
fmt.Fprintf(w, "b.Control = nil\n")
} else {
- fmt.Fprintf(w, "b.Control = %s\n", genResult0(w, arch, t[1], new(int), false))
+ fmt.Fprintf(w, "b.Control = %s\n", genResult0(w, arch, t[1], new(int), false, "b"))
}
if len(newsuccs) < len(succs) {
fmt.Fprintf(w, "b.Succs = b.Succs[:%d]\n", len(newsuccs))
}
func genResult(w io.Writer, arch arch, result string) {
- genResult0(w, arch, result, new(int), true)
+ loc := "b"
+ if result[0] == '@' {
+ // parse @block directive
+ s := strings.SplitN(result[1:], " ", 2)
+ loc = s[0]
+ result = s[1]
+ }
+ genResult0(w, arch, result, new(int), true, loc)
}
-func genResult0(w io.Writer, arch arch, result string, alloc *int, top bool) string {
+func genResult0(w io.Writer, arch arch, result string, alloc *int, top bool, loc string) string {
if result[0] != '(' {
// variable
if top {
s := split(result[1 : len(result)-1]) // remove parens, then split
var v string
var hasType bool
- if top {
+ if top && loc == "b" {
v = "v"
fmt.Fprintf(w, "v.Op = %s\n", opName(s[0], arch))
fmt.Fprintf(w, "v.AuxInt = 0\n")
} else {
v = fmt.Sprintf("v%d", *alloc)
*alloc++
- fmt.Fprintf(w, "%s := b.NewValue0(v.Line, %s, TypeInvalid)\n", v, opName(s[0], arch))
+ fmt.Fprintf(w, "%s := %s.NewValue0(v.Line, %s, TypeInvalid)\n", v, loc, opName(s[0], arch))
+ if top {
+ // Rewrite original into a copy
+ fmt.Fprintf(w, "v.Op = OpCopy\n")
+ fmt.Fprintf(w, "v.AuxInt = 0\n")
+ fmt.Fprintf(w, "v.Aux = nil\n")
+ fmt.Fprintf(w, "v.resetArgs()\n")
+ fmt.Fprintf(w, "v.AddArg(%s)\n", v)
+ }
}
for _, a := range s[1:] {
if a[0] == '<' {
fmt.Fprintf(w, "%s.Aux = %s\n", v, x)
} else {
// regular argument (sexpr or variable)
- x := genResult0(w, arch, a, alloc, false)
+ x := genResult0(w, arch, a, alloc, false, loc)
fmt.Fprintf(w, "%s.AddArg(%s)\n", v, x)
}
}
;
case OpAMD64MOVBQSX:
// match: (MOVBQSX (MOVBload [off] {sym} ptr mem))
- // cond: b == v.Args[0].Block
- // result: (MOVBQSXload [off] {sym} ptr mem)
+ // cond:
+ // result: @v.Args[0].Block (MOVBQSXload <v.Type> [off] {sym} ptr mem)
{
if v.Args[0].Op != OpAMD64MOVBload {
- goto end4fcdab76af223d4a6b942b532ebf860b
+ goto end19c38f3a1a37dca50637c917fa26e4f7
}
off := v.Args[0].AuxInt
sym := v.Args[0].Aux
ptr := v.Args[0].Args[0]
mem := v.Args[0].Args[1]
- if !(b == v.Args[0].Block) {
- goto end4fcdab76af223d4a6b942b532ebf860b
- }
- v.Op = OpAMD64MOVBQSXload
+ v0 := v.Args[0].Block.NewValue0(v.Line, OpAMD64MOVBQSXload, TypeInvalid)
+ v.Op = OpCopy
v.AuxInt = 0
v.Aux = nil
v.resetArgs()
- v.AuxInt = off
- v.Aux = sym
- v.AddArg(ptr)
- v.AddArg(mem)
+ v.AddArg(v0)
+ v0.Type = v.Type
+ v0.AuxInt = off
+ v0.Aux = sym
+ v0.AddArg(ptr)
+ v0.AddArg(mem)
return true
}
- goto end4fcdab76af223d4a6b942b532ebf860b
- end4fcdab76af223d4a6b942b532ebf860b:
+ goto end19c38f3a1a37dca50637c917fa26e4f7
+ end19c38f3a1a37dca50637c917fa26e4f7:
;
case OpAMD64MOVBQZX:
// match: (MOVBQZX (MOVBload [off] {sym} ptr mem))
- // cond: b == v.Args[0].Block
- // result: (MOVBQZXload [off] {sym} ptr mem)
+ // cond:
+ // result: @v.Args[0].Block (MOVBQZXload <v.Type> [off] {sym} ptr mem)
{
if v.Args[0].Op != OpAMD64MOVBload {
- goto endce35c966b0a38aa124a610e5616a220c
+ goto end1169bcf3d56fa24321b002eaebd5a62d
}
off := v.Args[0].AuxInt
sym := v.Args[0].Aux
ptr := v.Args[0].Args[0]
mem := v.Args[0].Args[1]
- if !(b == v.Args[0].Block) {
- goto endce35c966b0a38aa124a610e5616a220c
- }
- v.Op = OpAMD64MOVBQZXload
+ v0 := v.Args[0].Block.NewValue0(v.Line, OpAMD64MOVBQZXload, TypeInvalid)
+ v.Op = OpCopy
v.AuxInt = 0
v.Aux = nil
v.resetArgs()
- v.AuxInt = off
- v.Aux = sym
- v.AddArg(ptr)
- v.AddArg(mem)
+ v.AddArg(v0)
+ v0.Type = v.Type
+ v0.AuxInt = off
+ v0.Aux = sym
+ v0.AddArg(ptr)
+ v0.AddArg(mem)
return true
}
- goto endce35c966b0a38aa124a610e5616a220c
- endce35c966b0a38aa124a610e5616a220c:
+ goto end1169bcf3d56fa24321b002eaebd5a62d
+ end1169bcf3d56fa24321b002eaebd5a62d:
;
case OpAMD64MOVBload:
// match: (MOVBload [off1] {sym} (ADDQconst [off2] ptr) mem)
;
case OpStructSelect:
// match: (StructSelect [idx] (Load ptr mem))
- // cond: b == v.Args[0].Block
- // result: (Load (OffPtr <v.Type.PtrTo()> [idx] ptr) mem)
+ // cond:
+ // result: @v.Args[0].Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [idx] ptr) mem)
{
idx := v.AuxInt
if v.Args[0].Op != OpLoad {
- goto endd1a92da3e00c16a8f5bd3bd30deca298
+ goto end27abc5bf0299ce1bd5457af6ce8e3fba
}
ptr := v.Args[0].Args[0]
mem := v.Args[0].Args[1]
- if !(b == v.Args[0].Block) {
- goto endd1a92da3e00c16a8f5bd3bd30deca298
- }
- v.Op = OpLoad
+ v0 := v.Args[0].Block.NewValue0(v.Line, OpLoad, TypeInvalid)
+ v.Op = OpCopy
v.AuxInt = 0
v.Aux = nil
v.resetArgs()
- v0 := b.NewValue0(v.Line, OpOffPtr, TypeInvalid)
- v0.Type = v.Type.PtrTo()
- v0.AuxInt = idx
- v0.AddArg(ptr)
v.AddArg(v0)
- v.AddArg(mem)
+ v0.Type = v.Type
+ v1 := v.Args[0].Block.NewValue0(v.Line, OpOffPtr, TypeInvalid)
+ v1.Type = v.Type.PtrTo()
+ v1.AuxInt = idx
+ v1.AddArg(ptr)
+ v0.AddArg(v1)
+ v0.AddArg(mem)
return true
}
- goto endd1a92da3e00c16a8f5bd3bd30deca298
- endd1a92da3e00c16a8f5bd3bd30deca298:
+ goto end27abc5bf0299ce1bd5457af6ce8e3fba
+ end27abc5bf0299ce1bd5457af6ce8e3fba:
;
case OpSub16:
// match: (Sub16 x x)