arm64.ASTLXR & obj.AMask: {Flags: gc.SizeQ | gc.LeftRead | gc.RightWrite | gc.Move},
// Jumps
- arm64.AB & obj.AMask: {Flags: gc.Jump | gc.Break},
- arm64.ABL & obj.AMask: {Flags: gc.Call},
- arm64.ABEQ & obj.AMask: {Flags: gc.Cjmp},
- arm64.ABNE & obj.AMask: {Flags: gc.Cjmp},
- arm64.ABGE & obj.AMask: {Flags: gc.Cjmp},
- arm64.ABLT & obj.AMask: {Flags: gc.Cjmp},
- arm64.ABGT & obj.AMask: {Flags: gc.Cjmp},
- arm64.ABLE & obj.AMask: {Flags: gc.Cjmp},
- arm64.ABLO & obj.AMask: {Flags: gc.Cjmp},
- arm64.ABLS & obj.AMask: {Flags: gc.Cjmp},
- arm64.ABHI & obj.AMask: {Flags: gc.Cjmp},
- arm64.ABHS & obj.AMask: {Flags: gc.Cjmp},
- arm64.ACBZ & obj.AMask: {Flags: gc.Cjmp},
- arm64.ACBNZ & obj.AMask: {Flags: gc.Cjmp},
- obj.ARET: {Flags: gc.Break},
- obj.ADUFFZERO: {Flags: gc.Call},
- obj.ADUFFCOPY: {Flags: gc.Call},
+ arm64.AB & obj.AMask: {Flags: gc.Jump | gc.Break},
+ arm64.ABL & obj.AMask: {Flags: gc.Call},
+ arm64.ABEQ & obj.AMask: {Flags: gc.Cjmp},
+ arm64.ABNE & obj.AMask: {Flags: gc.Cjmp},
+ arm64.ABGE & obj.AMask: {Flags: gc.Cjmp},
+ arm64.ABLT & obj.AMask: {Flags: gc.Cjmp},
+ arm64.ABGT & obj.AMask: {Flags: gc.Cjmp},
+ arm64.ABLE & obj.AMask: {Flags: gc.Cjmp},
+ arm64.ABLO & obj.AMask: {Flags: gc.Cjmp},
+ arm64.ABLS & obj.AMask: {Flags: gc.Cjmp},
+ arm64.ABHI & obj.AMask: {Flags: gc.Cjmp},
+ arm64.ABHS & obj.AMask: {Flags: gc.Cjmp},
+ arm64.ACBZ & obj.AMask: {Flags: gc.Cjmp},
+ arm64.ACBNZ & obj.AMask: {Flags: gc.Cjmp},
+ arm64.ACBZW & obj.AMask: {Flags: gc.Cjmp},
+ arm64.ACBNZW & obj.AMask: {Flags: gc.Cjmp},
+ obj.ARET: {Flags: gc.Break},
+ obj.ADUFFZERO: {Flags: gc.Call},
+ obj.ADUFFCOPY: {Flags: gc.Call},
}
func proginfo(p *obj.Prog) gc.ProgInfo {
ssa.BlockARM64UGE: {arm64.ABHS, arm64.ABLO},
ssa.BlockARM64UGT: {arm64.ABHI, arm64.ABLS},
ssa.BlockARM64ULE: {arm64.ABLS, arm64.ABHI},
+ ssa.BlockARM64Z: {arm64.ACBZ, arm64.ACBNZ},
+ ssa.BlockARM64NZ: {arm64.ACBNZ, arm64.ACBZ},
+ ssa.BlockARM64ZW: {arm64.ACBZW, arm64.ACBNZW},
+ ssa.BlockARM64NZW: {arm64.ACBNZW, arm64.ACBZW},
}
func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
ssa.BlockARM64LT, ssa.BlockARM64GE,
ssa.BlockARM64LE, ssa.BlockARM64GT,
ssa.BlockARM64ULT, ssa.BlockARM64UGT,
- ssa.BlockARM64ULE, ssa.BlockARM64UGE:
+ ssa.BlockARM64ULE, ssa.BlockARM64UGE,
+ ssa.BlockARM64Z, ssa.BlockARM64NZ,
+ ssa.BlockARM64ZW, ssa.BlockARM64NZW:
jmp := blockJump[b.Kind]
var p *obj.Prog
switch next {
q.To.Type = obj.TYPE_BRANCH
s.Branches = append(s.Branches, gc.Branch{P: q, B: b.Succs[1].Block()})
}
+ if !b.Control.Type.IsFlags() {
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = b.Control.Reg()
+ }
default:
b.Fatalf("branch not implemented: %s. Control: %s", b.LongString(), b.Control.LongString())
(If (GreaterEqual cc) yes no) -> (GE cc yes no)
(If (GreaterEqualU cc) yes no) -> (UGE cc yes no)
-(If cond yes no) -> (NE (CMPconst [0] cond) yes no)
+(If cond yes no) -> (NZ cond yes no)
// atomic intrinsics
// Note: these ops do not accept offset.
// Optimizations
// Absorb boolean tests into block
-(NE (CMPconst [0] (Equal cc)) yes no) -> (EQ cc yes no)
-(NE (CMPconst [0] (NotEqual cc)) yes no) -> (NE cc yes no)
-(NE (CMPconst [0] (LessThan cc)) yes no) -> (LT cc yes no)
-(NE (CMPconst [0] (LessThanU cc)) yes no) -> (ULT cc yes no)
-(NE (CMPconst [0] (LessEqual cc)) yes no) -> (LE cc yes no)
-(NE (CMPconst [0] (LessEqualU cc)) yes no) -> (ULE cc yes no)
-(NE (CMPconst [0] (GreaterThan cc)) yes no) -> (GT cc yes no)
-(NE (CMPconst [0] (GreaterThanU cc)) yes no) -> (UGT cc yes no)
-(NE (CMPconst [0] (GreaterEqual cc)) yes no) -> (GE cc yes no)
-(NE (CMPconst [0] (GreaterEqualU cc)) yes no) -> (UGE cc yes no)
+(NZ (Equal cc) yes no) -> (EQ cc yes no)
+(NZ (NotEqual cc) yes no) -> (NE cc yes no)
+(NZ (LessThan cc) yes no) -> (LT cc yes no)
+(NZ (LessThanU cc) yes no) -> (ULT cc yes no)
+(NZ (LessEqual cc) yes no) -> (LE cc yes no)
+(NZ (LessEqualU cc) yes no) -> (ULE cc yes no)
+(NZ (GreaterThan cc) yes no) -> (GT cc yes no)
+(NZ (GreaterThanU cc) yes no) -> (UGT cc yes no)
+(NZ (GreaterEqual cc) yes no) -> (GE cc yes no)
+(NZ (GreaterEqualU cc) yes no) -> (UGE cc yes no)
+
+(EQ (CMPconst [0] x) yes no) -> (Z x yes no)
+(NE (CMPconst [0] x) yes no) -> (NZ x yes no)
+(EQ (CMPWconst [0] x) yes no) -> (ZW x yes no)
+(NE (CMPWconst [0] x) yes no) -> (NZW x yes no)
// fold offset into address
(ADDconst [off1] (MOVDaddr [off2] {sym} ptr)) -> (MOVDaddr [off1+off2] {sym} ptr)
(UGE (FlagGT_ULT) yes no) -> (First nil no yes)
(UGE (FlagGT_UGT) yes no) -> (First nil yes no)
+(Z (MOVDconst [0]) yes no) -> (First nil yes no)
+(Z (MOVDconst [c]) yes no) && c != 0 -> (First nil no yes)
+(NZ (MOVDconst [0]) yes no) -> (First nil no yes)
+(NZ (MOVDconst [c]) yes no) && c != 0 -> (First nil yes no)
+(ZW (MOVDconst [c]) yes no) && int32(c) == 0 -> (First nil yes no)
+(ZW (MOVDconst [c]) yes no) && int32(c) != 0 -> (First nil no yes)
+(NZW (MOVDconst [c]) yes no) && int32(c) == 0 -> (First nil no yes)
+(NZW (MOVDconst [c]) yes no) && int32(c) != 0 -> (First nil yes no)
+
// absorb InvertFlags into branches
(LT (InvertFlags cmp) yes no) -> (GT cmp yes no)
(GT (InvertFlags cmp) yes no) -> (LT cmp yes no)
{name: "ULE"},
{name: "UGT"},
{name: "UGE"},
+ {name: "Z"}, // Control == 0 (take a register instead of flags)
+ {name: "NZ"}, // Control != 0
+ {name: "ZW"}, // Control == 0, 32-bit
+ {name: "NZW"}, // Control != 0, 32-bit
}
archs = append(archs, arch{
BlockARM64ULE
BlockARM64UGT
BlockARM64UGE
+ BlockARM64Z
+ BlockARM64NZ
+ BlockARM64ZW
+ BlockARM64NZW
BlockMIPS64EQ
BlockMIPS64NE
BlockARM64ULE: "ULE",
BlockARM64UGT: "UGT",
BlockARM64UGE: "UGE",
+ BlockARM64Z: "Z",
+ BlockARM64NZ: "NZ",
+ BlockARM64ZW: "ZW",
+ BlockARM64NZW: "NZW",
BlockMIPS64EQ: "EQ",
BlockMIPS64NE: "NE",
func rewriteBlockARM64(b *Block, config *Config) bool {
switch b.Kind {
case BlockARM64EQ:
+ // match: (EQ (CMPconst [0] x) yes no)
+ // cond:
+ // result: (Z x yes no)
+ for {
+ v := b.Control
+ if v.Op != OpARM64CMPconst {
+ break
+ }
+ if v.AuxInt != 0 {
+ break
+ }
+ x := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockARM64Z
+ b.SetControl(x)
+ _ = yes
+ _ = no
+ return true
+ }
+ // match: (EQ (CMPWconst [0] x) yes no)
+ // cond:
+ // result: (ZW x yes no)
+ for {
+ v := b.Control
+ if v.Op != OpARM64CMPWconst {
+ break
+ }
+ if v.AuxInt != 0 {
+ break
+ }
+ x := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockARM64ZW
+ b.SetControl(x)
+ _ = yes
+ _ = no
+ return true
+ }
// match: (EQ (FlagEQ) yes no)
// cond:
// result: (First nil yes no)
}
// match: (If cond yes no)
// cond:
- // result: (NE (CMPconst [0] cond) yes no)
+ // result: (NZ cond yes no)
for {
v := b.Control
_ = v
cond := b.Control
yes := b.Succs[0]
no := b.Succs[1]
- b.Kind = BlockARM64NE
- v0 := b.NewValue0(v.Line, OpARM64CMPconst, TypeFlags)
- v0.AuxInt = 0
- v0.AddArg(cond)
- b.SetControl(v0)
+ b.Kind = BlockARM64NZ
+ b.SetControl(cond)
_ = yes
_ = no
return true
return true
}
case BlockARM64NE:
- // match: (NE (CMPconst [0] (Equal cc)) yes no)
+ // match: (NE (CMPconst [0] x) yes no)
// cond:
- // result: (EQ cc yes no)
+ // result: (NZ x yes no)
for {
v := b.Control
if v.Op != OpARM64CMPconst {
if v.AuxInt != 0 {
break
}
- v_0 := v.Args[0]
- if v_0.Op != OpARM64Equal {
- break
- }
- cc := v_0.Args[0]
+ x := v.Args[0]
yes := b.Succs[0]
no := b.Succs[1]
- b.Kind = BlockARM64EQ
- b.SetControl(cc)
+ b.Kind = BlockARM64NZ
+ b.SetControl(x)
_ = yes
_ = no
return true
}
- // match: (NE (CMPconst [0] (NotEqual cc)) yes no)
+ // match: (NE (CMPWconst [0] x) yes no)
// cond:
- // result: (NE cc yes no)
+ // result: (NZW x yes no)
for {
v := b.Control
- if v.Op != OpARM64CMPconst {
+ if v.Op != OpARM64CMPWconst {
break
}
if v.AuxInt != 0 {
break
}
- v_0 := v.Args[0]
- if v_0.Op != OpARM64NotEqual {
+ x := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockARM64NZW
+ b.SetControl(x)
+ _ = yes
+ _ = no
+ return true
+ }
+ // match: (NE (FlagEQ) yes no)
+ // cond:
+ // result: (First nil no yes)
+ for {
+ v := b.Control
+ if v.Op != OpARM64FlagEQ {
break
}
- cc := v_0.Args[0]
yes := b.Succs[0]
no := b.Succs[1]
- b.Kind = BlockARM64NE
- b.SetControl(cc)
+ b.Kind = BlockFirst
+ b.SetControl(nil)
+ b.swapSuccessors()
+ _ = no
+ _ = yes
+ return true
+ }
+ // match: (NE (FlagLT_ULT) yes no)
+ // cond:
+ // result: (First nil yes no)
+ for {
+ v := b.Control
+ if v.Op != OpARM64FlagLT_ULT {
+ break
+ }
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockFirst
+ b.SetControl(nil)
_ = yes
_ = no
return true
}
- // match: (NE (CMPconst [0] (LessThan cc)) yes no)
+ // match: (NE (FlagLT_UGT) yes no)
// cond:
- // result: (LT cc yes no)
+ // result: (First nil yes no)
for {
v := b.Control
- if v.Op != OpARM64CMPconst {
+ if v.Op != OpARM64FlagLT_UGT {
break
}
- if v.AuxInt != 0 {
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockFirst
+ b.SetControl(nil)
+ _ = yes
+ _ = no
+ return true
+ }
+ // match: (NE (FlagGT_ULT) yes no)
+ // cond:
+ // result: (First nil yes no)
+ for {
+ v := b.Control
+ if v.Op != OpARM64FlagGT_ULT {
break
}
- v_0 := v.Args[0]
- if v_0.Op != OpARM64LessThan {
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockFirst
+ b.SetControl(nil)
+ _ = yes
+ _ = no
+ return true
+ }
+ // match: (NE (FlagGT_UGT) yes no)
+ // cond:
+ // result: (First nil yes no)
+ for {
+ v := b.Control
+ if v.Op != OpARM64FlagGT_UGT {
break
}
- cc := v_0.Args[0]
yes := b.Succs[0]
no := b.Succs[1]
- b.Kind = BlockARM64LT
- b.SetControl(cc)
+ b.Kind = BlockFirst
+ b.SetControl(nil)
_ = yes
_ = no
return true
}
- // match: (NE (CMPconst [0] (LessThanU cc)) yes no)
+ // match: (NE (InvertFlags cmp) yes no)
// cond:
- // result: (ULT cc yes no)
+ // result: (NE cmp yes no)
for {
v := b.Control
- if v.Op != OpARM64CMPconst {
+ if v.Op != OpARM64InvertFlags {
break
}
- if v.AuxInt != 0 {
+ cmp := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockARM64NE
+ b.SetControl(cmp)
+ _ = yes
+ _ = no
+ return true
+ }
+ case BlockARM64NZ:
+ // match: (NZ (Equal cc) yes no)
+ // cond:
+ // result: (EQ cc yes no)
+ for {
+ v := b.Control
+ if v.Op != OpARM64Equal {
break
}
- v_0 := v.Args[0]
- if v_0.Op != OpARM64LessThanU {
+ cc := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockARM64EQ
+ b.SetControl(cc)
+ _ = yes
+ _ = no
+ return true
+ }
+ // match: (NZ (NotEqual cc) yes no)
+ // cond:
+ // result: (NE cc yes no)
+ for {
+ v := b.Control
+ if v.Op != OpARM64NotEqual {
break
}
- cc := v_0.Args[0]
+ cc := v.Args[0]
yes := b.Succs[0]
no := b.Succs[1]
- b.Kind = BlockARM64ULT
+ b.Kind = BlockARM64NE
b.SetControl(cc)
_ = yes
_ = no
return true
}
- // match: (NE (CMPconst [0] (LessEqual cc)) yes no)
+ // match: (NZ (LessThan cc) yes no)
// cond:
- // result: (LE cc yes no)
+ // result: (LT cc yes no)
for {
v := b.Control
- if v.Op != OpARM64CMPconst {
+ if v.Op != OpARM64LessThan {
break
}
- if v.AuxInt != 0 {
+ cc := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockARM64LT
+ b.SetControl(cc)
+ _ = yes
+ _ = no
+ return true
+ }
+ // match: (NZ (LessThanU cc) yes no)
+ // cond:
+ // result: (ULT cc yes no)
+ for {
+ v := b.Control
+ if v.Op != OpARM64LessThanU {
break
}
- v_0 := v.Args[0]
- if v_0.Op != OpARM64LessEqual {
+ cc := v.Args[0]
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockARM64ULT
+ b.SetControl(cc)
+ _ = yes
+ _ = no
+ return true
+ }
+ // match: (NZ (LessEqual cc) yes no)
+ // cond:
+ // result: (LE cc yes no)
+ for {
+ v := b.Control
+ if v.Op != OpARM64LessEqual {
break
}
- cc := v_0.Args[0]
+ cc := v.Args[0]
yes := b.Succs[0]
no := b.Succs[1]
b.Kind = BlockARM64LE
_ = no
return true
}
- // match: (NE (CMPconst [0] (LessEqualU cc)) yes no)
+ // match: (NZ (LessEqualU cc) yes no)
// cond:
// result: (ULE cc yes no)
for {
v := b.Control
- if v.Op != OpARM64CMPconst {
- break
- }
- if v.AuxInt != 0 {
- break
- }
- v_0 := v.Args[0]
- if v_0.Op != OpARM64LessEqualU {
+ if v.Op != OpARM64LessEqualU {
break
}
- cc := v_0.Args[0]
+ cc := v.Args[0]
yes := b.Succs[0]
no := b.Succs[1]
b.Kind = BlockARM64ULE
_ = no
return true
}
- // match: (NE (CMPconst [0] (GreaterThan cc)) yes no)
+ // match: (NZ (GreaterThan cc) yes no)
// cond:
// result: (GT cc yes no)
for {
v := b.Control
- if v.Op != OpARM64CMPconst {
- break
- }
- if v.AuxInt != 0 {
- break
- }
- v_0 := v.Args[0]
- if v_0.Op != OpARM64GreaterThan {
+ if v.Op != OpARM64GreaterThan {
break
}
- cc := v_0.Args[0]
+ cc := v.Args[0]
yes := b.Succs[0]
no := b.Succs[1]
b.Kind = BlockARM64GT
_ = no
return true
}
- // match: (NE (CMPconst [0] (GreaterThanU cc)) yes no)
+ // match: (NZ (GreaterThanU cc) yes no)
// cond:
// result: (UGT cc yes no)
for {
v := b.Control
- if v.Op != OpARM64CMPconst {
- break
- }
- if v.AuxInt != 0 {
- break
- }
- v_0 := v.Args[0]
- if v_0.Op != OpARM64GreaterThanU {
+ if v.Op != OpARM64GreaterThanU {
break
}
- cc := v_0.Args[0]
+ cc := v.Args[0]
yes := b.Succs[0]
no := b.Succs[1]
b.Kind = BlockARM64UGT
_ = no
return true
}
- // match: (NE (CMPconst [0] (GreaterEqual cc)) yes no)
+ // match: (NZ (GreaterEqual cc) yes no)
// cond:
// result: (GE cc yes no)
for {
v := b.Control
- if v.Op != OpARM64CMPconst {
- break
- }
- if v.AuxInt != 0 {
- break
- }
- v_0 := v.Args[0]
- if v_0.Op != OpARM64GreaterEqual {
+ if v.Op != OpARM64GreaterEqual {
break
}
- cc := v_0.Args[0]
+ cc := v.Args[0]
yes := b.Succs[0]
no := b.Succs[1]
b.Kind = BlockARM64GE
_ = no
return true
}
- // match: (NE (CMPconst [0] (GreaterEqualU cc)) yes no)
+ // match: (NZ (GreaterEqualU cc) yes no)
// cond:
// result: (UGE cc yes no)
for {
v := b.Control
- if v.Op != OpARM64CMPconst {
- break
- }
- if v.AuxInt != 0 {
- break
- }
- v_0 := v.Args[0]
- if v_0.Op != OpARM64GreaterEqualU {
+ if v.Op != OpARM64GreaterEqualU {
break
}
- cc := v_0.Args[0]
+ cc := v.Args[0]
yes := b.Succs[0]
no := b.Succs[1]
b.Kind = BlockARM64UGE
_ = no
return true
}
- // match: (NE (FlagEQ) yes no)
+ // match: (NZ (MOVDconst [0]) yes no)
// cond:
// result: (First nil no yes)
for {
v := b.Control
- if v.Op != OpARM64FlagEQ {
+ if v.Op != OpARM64MOVDconst {
+ break
+ }
+ if v.AuxInt != 0 {
break
}
yes := b.Succs[0]
_ = yes
return true
}
- // match: (NE (FlagLT_ULT) yes no)
- // cond:
+ // match: (NZ (MOVDconst [c]) yes no)
+ // cond: c != 0
// result: (First nil yes no)
for {
v := b.Control
- if v.Op != OpARM64FlagLT_ULT {
+ if v.Op != OpARM64MOVDconst {
break
}
+ c := v.AuxInt
yes := b.Succs[0]
no := b.Succs[1]
- b.Kind = BlockFirst
- b.SetControl(nil)
- _ = yes
- _ = no
- return true
- }
- // match: (NE (FlagLT_UGT) yes no)
- // cond:
- // result: (First nil yes no)
- for {
- v := b.Control
- if v.Op != OpARM64FlagLT_UGT {
+ if !(c != 0) {
break
}
- yes := b.Succs[0]
- no := b.Succs[1]
b.Kind = BlockFirst
b.SetControl(nil)
_ = yes
_ = no
return true
}
- // match: (NE (FlagGT_ULT) yes no)
- // cond:
- // result: (First nil yes no)
+ case BlockARM64NZW:
+ // match: (NZW (MOVDconst [c]) yes no)
+ // cond: int32(c) == 0
+ // result: (First nil no yes)
for {
v := b.Control
- if v.Op != OpARM64FlagGT_ULT {
+ if v.Op != OpARM64MOVDconst {
break
}
+ c := v.AuxInt
yes := b.Succs[0]
no := b.Succs[1]
+ if !(int32(c) == 0) {
+ break
+ }
b.Kind = BlockFirst
b.SetControl(nil)
- _ = yes
+ b.swapSuccessors()
_ = no
+ _ = yes
return true
}
- // match: (NE (FlagGT_UGT) yes no)
- // cond:
+ // match: (NZW (MOVDconst [c]) yes no)
+ // cond: int32(c) != 0
// result: (First nil yes no)
for {
v := b.Control
- if v.Op != OpARM64FlagGT_UGT {
+ if v.Op != OpARM64MOVDconst {
break
}
+ c := v.AuxInt
yes := b.Succs[0]
no := b.Succs[1]
- b.Kind = BlockFirst
- b.SetControl(nil)
- _ = yes
- _ = no
- return true
- }
- // match: (NE (InvertFlags cmp) yes no)
- // cond:
- // result: (NE cmp yes no)
- for {
- v := b.Control
- if v.Op != OpARM64InvertFlags {
+ if !(int32(c) != 0) {
break
}
- cmp := v.Args[0]
- yes := b.Succs[0]
- no := b.Succs[1]
- b.Kind = BlockARM64NE
- b.SetControl(cmp)
+ b.Kind = BlockFirst
+ b.SetControl(nil)
_ = yes
_ = no
return true
_ = no
return true
}
+ case BlockARM64Z:
+ // match: (Z (MOVDconst [0]) yes no)
+ // cond:
+ // result: (First nil yes no)
+ for {
+ v := b.Control
+ if v.Op != OpARM64MOVDconst {
+ break
+ }
+ if v.AuxInt != 0 {
+ break
+ }
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ b.Kind = BlockFirst
+ b.SetControl(nil)
+ _ = yes
+ _ = no
+ return true
+ }
+ // match: (Z (MOVDconst [c]) yes no)
+ // cond: c != 0
+ // result: (First nil no yes)
+ for {
+ v := b.Control
+ if v.Op != OpARM64MOVDconst {
+ break
+ }
+ c := v.AuxInt
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ if !(c != 0) {
+ break
+ }
+ b.Kind = BlockFirst
+ b.SetControl(nil)
+ b.swapSuccessors()
+ _ = no
+ _ = yes
+ return true
+ }
+ case BlockARM64ZW:
+ // match: (ZW (MOVDconst [c]) yes no)
+ // cond: int32(c) == 0
+ // result: (First nil yes no)
+ for {
+ v := b.Control
+ if v.Op != OpARM64MOVDconst {
+ break
+ }
+ c := v.AuxInt
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ if !(int32(c) == 0) {
+ break
+ }
+ b.Kind = BlockFirst
+ b.SetControl(nil)
+ _ = yes
+ _ = no
+ return true
+ }
+ // match: (ZW (MOVDconst [c]) yes no)
+ // cond: int32(c) != 0
+ // result: (First nil no yes)
+ for {
+ v := b.Control
+ if v.Op != OpARM64MOVDconst {
+ break
+ }
+ c := v.AuxInt
+ yes := b.Succs[0]
+ no := b.Succs[1]
+ if !(int32(c) != 0) {
+ break
+ }
+ b.Kind = BlockFirst
+ b.SetControl(nil)
+ b.swapSuccessors()
+ _ = no
+ _ = yes
+ return true
+ }
}
return false
}
return ACBNZ
case ACBNZ:
return ACBZ
+ case ACBZW:
+ return ACBNZW
+ case ACBNZW:
+ return ACBZW
}
log.Fatalf("unknown relation: %s", Anames[a-obj.ABaseARM64])