(CMPLconst (ANDLconst [c] x) [0]) -> (TESTLconst [c] x)
(CMPWconst (ANDWconst [c] x) [0]) -> (TESTWconst [c] x)
(CMPBconst (ANDBconst [c] x) [0]) -> (TESTBconst [c] x)
+
+// Combining byte loads into larger (unaligned) loads.
+// There are many ways these combinations could occur. This is
+// designed to match the way encoding/binary.LittleEndian does it.
+(ORW (MOVBQZXload [i] {s} p mem)
+ (SHLWconst [8] (MOVBQZXload [i+1] {s} p mem))) -> (MOVWload p mem)
+
+(ORL (ORL (ORL
+ (MOVBQZXload [i] {s} p mem)
+ (SHLLconst [8] (MOVBQZXload [i+1] {s} p mem)))
+ (SHLLconst [16] (MOVBQZXload [i+2] {s} p mem)))
+ (SHLLconst [24] (MOVBQZXload [i+3] {s} p mem))) -> (MOVLload p mem)
+
+(ORQ (ORQ (ORQ (ORQ (ORQ (ORQ (ORQ
+ (MOVBQZXload [i] {s} p mem)
+ (SHLQconst [8] (MOVBQZXload [i+1] {s} p mem)))
+ (SHLQconst [16] (MOVBQZXload [i+2] {s} p mem)))
+ (SHLQconst [24] (MOVBQZXload [i+3] {s} p mem)))
+ (SHLQconst [32] (MOVBQZXload [i+4] {s} p mem)))
+ (SHLQconst [40] (MOVBQZXload [i+5] {s} p mem)))
+ (SHLQconst [48] (MOVBQZXload [i+6] {s} p mem)))
+ (SHLQconst [56] (MOVBQZXload [i+7] {s} p mem))) -> (MOVQload p mem)
// auxint+aux == add auxint and the offset of the symbol in aux (if any) to the effective address
{name: "MOVBload", argLength: 2, reg: gpload, asm: "MOVBLZX", aux: "SymOff", typ: "UInt8"}, // load byte from arg0+auxint+aux. arg1=mem
{name: "MOVBQSXload", argLength: 2, reg: gpload, asm: "MOVBQSX", aux: "SymOff"}, // ditto, extend to int64
- {name: "MOVBQZXload", argLength: 2, reg: gpload, asm: "MOVBQZX", aux: "SymOff"}, // ditto, extend to uint64
+ {name: "MOVBQZXload", argLength: 2, reg: gpload, asm: "MOVBLZX", aux: "SymOff"}, // ditto, extend to uint64
{name: "MOVWload", argLength: 2, reg: gpload, asm: "MOVWLZX", aux: "SymOff", typ: "UInt16"}, // load 2 bytes from arg0+auxint+aux. arg1=mem
{name: "MOVWQSXload", argLength: 2, reg: gpload, asm: "MOVWQSX", aux: "SymOff"}, // ditto, extend to int64
- {name: "MOVWQZXload", argLength: 2, reg: gpload, asm: "MOVWQZX", aux: "SymOff"}, // ditto, extend to uint64
+ {name: "MOVWQZXload", argLength: 2, reg: gpload, asm: "MOVWLZX", aux: "SymOff"}, // ditto, extend to uint64
{name: "MOVLload", argLength: 2, reg: gpload, asm: "MOVL", aux: "SymOff", typ: "UInt32"}, // load 4 bytes from arg0+auxint+aux. arg1=mem
{name: "MOVLQSXload", argLength: 2, reg: gpload, asm: "MOVLQSX", aux: "SymOff"}, // ditto, extend to int64
- {name: "MOVLQZXload", argLength: 2, reg: gpload, asm: "MOVLQZX", aux: "SymOff"}, // ditto, extend to uint64
+ {name: "MOVLQZXload", argLength: 2, reg: gpload, asm: "MOVL", aux: "SymOff"}, // ditto, extend to uint64
{name: "MOVQload", argLength: 2, reg: gpload, asm: "MOVQ", aux: "SymOff", typ: "UInt64"}, // load 8 bytes from arg0+auxint+aux. arg1=mem
{name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem"}, // store byte in arg1 to arg0+auxint+aux. arg2=mem
{name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem"}, // store 2 bytes in arg1 to arg0+auxint+aux. arg2=mem
fmt.Fprintf(w, "if %s.Type != %s {\nbreak\n}\n", v, t)
} else {
// variable
- if u, ok := m[t]; ok {
+ if _, ok := m[t]; ok {
// must match previous variable
- fmt.Fprintf(w, "if %s.Type != %s {\nbreak\n}\n", v, u)
+ fmt.Fprintf(w, "if %s.Type != %s {\nbreak\n}\n", v, t)
} else {
m[t] = v + ".Type"
fmt.Fprintf(w, "%s := %s.Type\n", t, v)
fmt.Fprintf(w, "if %s.AuxInt != %s {\nbreak\n}\n", v, x)
} else {
// variable
- if y, ok := m[x]; ok {
- fmt.Fprintf(w, "if %s.AuxInt != %s {\nbreak\n}\n", v, y)
+ if _, ok := m[x]; ok {
+ fmt.Fprintf(w, "if %s.AuxInt != %s {\nbreak\n}\n", v, x)
} else {
m[x] = v + ".AuxInt"
fmt.Fprintf(w, "%s := %s.AuxInt\n", x, v)
fmt.Fprintf(w, "if %s.Aux != %s {\nbreak\n}\n", v, x)
} else {
// variable
- if y, ok := m[x]; ok {
- fmt.Fprintf(w, "if %s.Aux != %s {\nbreak\n}\n", v, y)
+ if _, ok := m[x]; ok {
+ fmt.Fprintf(w, "if %s.Aux != %s {\nbreak\n}\n", v, x)
} else {
m[x] = v + ".Aux"
fmt.Fprintf(w, "%s := %s.Aux\n", x, v)
name: "MOVBQZXload",
auxType: auxSymOff,
argLen: 2,
- asm: x86.AMOVBQZX,
+ asm: x86.AMOVBLZX,
reg: regInfo{
inputs: []inputInfo{
{0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
name: "MOVWQZXload",
auxType: auxSymOff,
argLen: 2,
- asm: x86.AMOVWQZX,
+ asm: x86.AMOVWLZX,
reg: regInfo{
inputs: []inputInfo{
{0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
name: "MOVLQZXload",
auxType: auxSymOff,
argLen: 2,
- asm: x86.AMOVLQZX,
+ asm: x86.AMOVL,
reg: regInfo{
inputs: []inputInfo{
{0, 4295032831}, // .AX .CX .DX .BX .SP .BP .SI .DI .R8 .R9 .R10 .R11 .R12 .R13 .R14 .R15 .SB
v.AddArg(x)
return true
}
+ // match: (ORL (ORL (ORL (MOVBQZXload [i] {s} p mem) (SHLLconst [8] (MOVBQZXload [i+1] {s} p mem))) (SHLLconst [16] (MOVBQZXload [i+2] {s} p mem))) (SHLLconst [24] (MOVBQZXload [i+3] {s} p mem)))
+ // cond:
+ // result: (MOVLload p mem)
+ for {
+ if v.Args[0].Op != OpAMD64ORL {
+ break
+ }
+ if v.Args[0].Args[0].Op != OpAMD64ORL {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Op != OpAMD64MOVBQZXload {
+ break
+ }
+ i := v.Args[0].Args[0].Args[0].AuxInt
+ s := v.Args[0].Args[0].Args[0].Aux
+ p := v.Args[0].Args[0].Args[0].Args[0]
+ mem := v.Args[0].Args[0].Args[0].Args[1]
+ if v.Args[0].Args[0].Args[1].Op != OpAMD64SHLLconst {
+ break
+ }
+ if v.Args[0].Args[0].Args[1].AuxInt != 8 {
+ break
+ }
+ if v.Args[0].Args[0].Args[1].Args[0].Op != OpAMD64MOVBQZXload {
+ break
+ }
+ if v.Args[0].Args[0].Args[1].Args[0].AuxInt != i+1 {
+ break
+ }
+ if v.Args[0].Args[0].Args[1].Args[0].Aux != s {
+ break
+ }
+ if v.Args[0].Args[0].Args[1].Args[0].Args[0] != p {
+ break
+ }
+ if v.Args[0].Args[0].Args[1].Args[0].Args[1] != mem {
+ break
+ }
+ if v.Args[0].Args[1].Op != OpAMD64SHLLconst {
+ break
+ }
+ if v.Args[0].Args[1].AuxInt != 16 {
+ break
+ }
+ if v.Args[0].Args[1].Args[0].Op != OpAMD64MOVBQZXload {
+ break
+ }
+ if v.Args[0].Args[1].Args[0].AuxInt != i+2 {
+ break
+ }
+ if v.Args[0].Args[1].Args[0].Aux != s {
+ break
+ }
+ if v.Args[0].Args[1].Args[0].Args[0] != p {
+ break
+ }
+ if v.Args[0].Args[1].Args[0].Args[1] != mem {
+ break
+ }
+ if v.Args[1].Op != OpAMD64SHLLconst {
+ break
+ }
+ if v.Args[1].AuxInt != 24 {
+ break
+ }
+ if v.Args[1].Args[0].Op != OpAMD64MOVBQZXload {
+ break
+ }
+ if v.Args[1].Args[0].AuxInt != i+3 {
+ break
+ }
+ if v.Args[1].Args[0].Aux != s {
+ break
+ }
+ if v.Args[1].Args[0].Args[0] != p {
+ break
+ }
+ if v.Args[1].Args[0].Args[1] != mem {
+ break
+ }
+ v.reset(OpAMD64MOVLload)
+ v.AddArg(p)
+ v.AddArg(mem)
+ return true
+ }
return false
}
func rewriteValueAMD64_OpAMD64ORLconst(v *Value, config *Config) bool {
v.AddArg(x)
return true
}
+ // match: (ORQ (ORQ (ORQ (ORQ (ORQ (ORQ (ORQ (MOVBQZXload [i] {s} p mem) (SHLQconst [8] (MOVBQZXload [i+1] {s} p mem))) (SHLQconst [16] (MOVBQZXload [i+2] {s} p mem))) (SHLQconst [24] (MOVBQZXload [i+3] {s} p mem))) (SHLQconst [32] (MOVBQZXload [i+4] {s} p mem))) (SHLQconst [40] (MOVBQZXload [i+5] {s} p mem))) (SHLQconst [48] (MOVBQZXload [i+6] {s} p mem))) (SHLQconst [56] (MOVBQZXload [i+7] {s} p mem)))
+ // cond:
+ // result: (MOVQload p mem)
+ for {
+ if v.Args[0].Op != OpAMD64ORQ {
+ break
+ }
+ if v.Args[0].Args[0].Op != OpAMD64ORQ {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Op != OpAMD64ORQ {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Op != OpAMD64ORQ {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Op != OpAMD64ORQ {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Op != OpAMD64ORQ {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Op != OpAMD64MOVBQZXload {
+ break
+ }
+ i := v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].AuxInt
+ s := v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Aux
+ p := v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Args[0]
+ mem := v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Args[1]
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Args[1].Op != OpAMD64SHLQconst {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Args[1].AuxInt != 8 {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Args[1].Args[0].Op != OpAMD64MOVBQZXload {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Args[1].Args[0].AuxInt != i+1 {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Args[1].Args[0].Aux != s {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Args[1].Args[0].Args[0] != p {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[0].Args[1].Args[0].Args[1] != mem {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[1].Op != OpAMD64SHLQconst {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[1].AuxInt != 16 {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[1].Args[0].Op != OpAMD64MOVBQZXload {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[1].Args[0].AuxInt != i+2 {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[1].Args[0].Aux != s {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[1].Args[0].Args[0] != p {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[0].Args[1].Args[0].Args[1] != mem {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[1].Op != OpAMD64SHLQconst {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[1].AuxInt != 24 {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[1].Args[0].Op != OpAMD64MOVBQZXload {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[1].Args[0].AuxInt != i+3 {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[1].Args[0].Aux != s {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[1].Args[0].Args[0] != p {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[0].Args[1].Args[0].Args[1] != mem {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[1].Op != OpAMD64SHLQconst {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[1].AuxInt != 32 {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[1].Args[0].Op != OpAMD64MOVBQZXload {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[1].Args[0].AuxInt != i+4 {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[1].Args[0].Aux != s {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[1].Args[0].Args[0] != p {
+ break
+ }
+ if v.Args[0].Args[0].Args[0].Args[1].Args[0].Args[1] != mem {
+ break
+ }
+ if v.Args[0].Args[0].Args[1].Op != OpAMD64SHLQconst {
+ break
+ }
+ if v.Args[0].Args[0].Args[1].AuxInt != 40 {
+ break
+ }
+ if v.Args[0].Args[0].Args[1].Args[0].Op != OpAMD64MOVBQZXload {
+ break
+ }
+ if v.Args[0].Args[0].Args[1].Args[0].AuxInt != i+5 {
+ break
+ }
+ if v.Args[0].Args[0].Args[1].Args[0].Aux != s {
+ break
+ }
+ if v.Args[0].Args[0].Args[1].Args[0].Args[0] != p {
+ break
+ }
+ if v.Args[0].Args[0].Args[1].Args[0].Args[1] != mem {
+ break
+ }
+ if v.Args[0].Args[1].Op != OpAMD64SHLQconst {
+ break
+ }
+ if v.Args[0].Args[1].AuxInt != 48 {
+ break
+ }
+ if v.Args[0].Args[1].Args[0].Op != OpAMD64MOVBQZXload {
+ break
+ }
+ if v.Args[0].Args[1].Args[0].AuxInt != i+6 {
+ break
+ }
+ if v.Args[0].Args[1].Args[0].Aux != s {
+ break
+ }
+ if v.Args[0].Args[1].Args[0].Args[0] != p {
+ break
+ }
+ if v.Args[0].Args[1].Args[0].Args[1] != mem {
+ break
+ }
+ if v.Args[1].Op != OpAMD64SHLQconst {
+ break
+ }
+ if v.Args[1].AuxInt != 56 {
+ break
+ }
+ if v.Args[1].Args[0].Op != OpAMD64MOVBQZXload {
+ break
+ }
+ if v.Args[1].Args[0].AuxInt != i+7 {
+ break
+ }
+ if v.Args[1].Args[0].Aux != s {
+ break
+ }
+ if v.Args[1].Args[0].Args[0] != p {
+ break
+ }
+ if v.Args[1].Args[0].Args[1] != mem {
+ break
+ }
+ v.reset(OpAMD64MOVQload)
+ v.AddArg(p)
+ v.AddArg(mem)
+ return true
+ }
return false
}
func rewriteValueAMD64_OpAMD64ORQconst(v *Value, config *Config) bool {
v.AddArg(x)
return true
}
+ // match: (ORW (MOVBQZXload [i] {s} p mem) (SHLWconst [8] (MOVBQZXload [i+1] {s} p mem)))
+ // cond:
+ // result: (MOVWload p mem)
+ for {
+ if v.Args[0].Op != OpAMD64MOVBQZXload {
+ break
+ }
+ i := v.Args[0].AuxInt
+ s := v.Args[0].Aux
+ p := v.Args[0].Args[0]
+ mem := v.Args[0].Args[1]
+ if v.Args[1].Op != OpAMD64SHLWconst {
+ break
+ }
+ if v.Args[1].AuxInt != 8 {
+ break
+ }
+ if v.Args[1].Args[0].Op != OpAMD64MOVBQZXload {
+ break
+ }
+ if v.Args[1].Args[0].AuxInt != i+1 {
+ break
+ }
+ if v.Args[1].Args[0].Aux != s {
+ break
+ }
+ if v.Args[1].Args[0].Args[0] != p {
+ break
+ }
+ if v.Args[1].Args[0].Args[1] != mem {
+ break
+ }
+ v.reset(OpAMD64MOVWload)
+ v.AddArg(p)
+ v.AddArg(mem)
+ return true
+ }
return false
}
func rewriteValueAMD64_OpAMD64ORWconst(v *Value, config *Config) bool {
if v.Args[1].Args[0].Op != OpConst16 {
break
}
- if v.Args[1].Args[0].Type != v.Args[0].Type {
+ if v.Args[1].Args[0].Type != t {
break
}
d := v.Args[1].Args[0].AuxInt
if v.Args[1].Args[0].Op != OpConst32 {
break
}
- if v.Args[1].Args[0].Type != v.Args[0].Type {
+ if v.Args[1].Args[0].Type != t {
break
}
d := v.Args[1].Args[0].AuxInt
if v.Args[1].Args[0].Op != OpConst64 {
break
}
- if v.Args[1].Args[0].Type != v.Args[0].Type {
+ if v.Args[1].Args[0].Type != t {
break
}
d := v.Args[1].Args[0].AuxInt
if v.Args[1].Args[0].Op != OpConst8 {
break
}
- if v.Args[1].Args[0].Type != v.Args[0].Type {
+ if v.Args[1].Args[0].Type != t {
break
}
d := v.Args[1].Args[0].AuxInt
if v.Args[1].Op != OpAdd32 {
break
}
- if v.Args[1].Type != v.Args[0].Type {
+ if v.Args[1].Type != t {
break
}
if v.Args[1].Args[0].Op != OpConst32 {
break
}
- if v.Args[1].Args[0].Type != v.Args[0].Type {
+ if v.Args[1].Args[0].Type != t {
break
}
d := v.Args[1].Args[0].AuxInt
if v.Args[1].Op != OpAdd64 {
break
}
- if v.Args[1].Type != v.Args[0].Type {
+ if v.Args[1].Type != t {
break
}
if v.Args[1].Args[0].Op != OpConst64 {
break
}
- if v.Args[1].Args[0].Type != v.Args[0].Type {
+ if v.Args[1].Args[0].Type != t {
break
}
d := v.Args[1].Args[0].AuxInt
if v.Args[1].Args[0].Op != OpConst16 {
break
}
- if v.Args[1].Args[0].Type != v.Args[0].Type {
+ if v.Args[1].Args[0].Type != t {
break
}
d := v.Args[1].Args[0].AuxInt
if v.Args[1].Args[0].Op != OpConst32 {
break
}
- if v.Args[1].Args[0].Type != v.Args[0].Type {
+ if v.Args[1].Args[0].Type != t {
break
}
d := v.Args[1].Args[0].AuxInt
if v.Args[1].Args[0].Op != OpConst64 {
break
}
- if v.Args[1].Args[0].Type != v.Args[0].Type {
+ if v.Args[1].Args[0].Type != t {
break
}
d := v.Args[1].Args[0].AuxInt
if v.Args[1].Args[0].Op != OpConst8 {
break
}
- if v.Args[1].Args[0].Type != v.Args[0].Type {
+ if v.Args[1].Args[0].Type != t {
break
}
d := v.Args[1].Args[0].AuxInt
if v.Args[1].Op != OpConst64 {
break
}
- if v.Args[1].AuxInt != v.Args[0].AuxInt {
+ if v.Args[1].AuxInt != c {
break
}
if len(v.Args) != 2 {