// autogenerated from gen/ARM.rules: do not edit!
// generated with: cd gen; go run *.go

package ssa

import "math"

var _ = math.MinInt8 // in case not otherwise used
func rewriteValueARM(v *Value, config *Config) bool {
	switch v.Op {
	case OpARMADD:
		return rewriteValueARM_OpARMADD(v, config)
	case OpAdd32:
		return rewriteValueARM_OpAdd32(v, config)
	case OpAddr:
		return rewriteValueARM_OpAddr(v, config)
	case OpConst32:
		return rewriteValueARM_OpConst32(v, config)
	case OpLess32:
		return rewriteValueARM_OpLess32(v, config)
	case OpLoad:
		return rewriteValueARM_OpLoad(v, config)
	case OpARMMOVWload:
		return rewriteValueARM_OpARMMOVWload(v, config)
	case OpARMMOVWstore:
		return rewriteValueARM_OpARMMOVWstore(v, config)
	case OpOffPtr:
		return rewriteValueARM_OpOffPtr(v, config)
	case OpStaticCall:
		return rewriteValueARM_OpStaticCall(v, config)
	case OpStore:
		return rewriteValueARM_OpStore(v, config)
	}
	return false
}
func rewriteValueARM_OpARMADD(v *Value, config *Config) bool {
	b := v.Block
	_ = b
	// match: (ADD (MOVWconst [c]) x)
	// cond:
	// result: (ADDconst [c] x)
	for {
		v_0 := v.Args[0]
		if v_0.Op != OpARMMOVWconst {
			break
		}
		c := v_0.AuxInt
		x := v.Args[1]
		v.reset(OpARMADDconst)
		v.AuxInt = c
		v.AddArg(x)
		return true
	}
	// match: (ADD x (MOVWconst [c]))
	// cond:
	// result: (ADDconst [c] x)
	for {
		x := v.Args[0]
		v_1 := v.Args[1]
		if v_1.Op != OpARMMOVWconst {
			break
		}
		c := v_1.AuxInt
		v.reset(OpARMADDconst)
		v.AuxInt = c
		v.AddArg(x)
		return true
	}
	return false
}
func rewriteValueARM_OpAdd32(v *Value, config *Config) bool {
	b := v.Block
	_ = b
	// match: (Add32 x y)
	// cond:
	// result: (ADD x y)
	for {
		x := v.Args[0]
		y := v.Args[1]
		v.reset(OpARMADD)
		v.AddArg(x)
		v.AddArg(y)
		return true
	}
}
func rewriteValueARM_OpAddr(v *Value, config *Config) bool {
	b := v.Block
	_ = b
	// match: (Addr {sym} base)
	// cond:
	// result: (ADDconst {sym} base)
	for {
		sym := v.Aux
		base := v.Args[0]
		v.reset(OpARMADDconst)
		v.Aux = sym
		v.AddArg(base)
		return true
	}
}
func rewriteValueARM_OpConst32(v *Value, config *Config) bool {
	b := v.Block
	_ = b
	// match: (Const32 [val])
	// cond:
	// result: (MOVWconst [val])
	for {
		val := v.AuxInt
		v.reset(OpARMMOVWconst)
		v.AuxInt = val
		return true
	}
}
func rewriteValueARM_OpLess32(v *Value, config *Config) bool {
	b := v.Block
	_ = b
	// match: (Less32 x y)
	// cond:
	// result: (LessThan (CMP x y))
	for {
		x := v.Args[0]
		y := v.Args[1]
		v.reset(OpARMLessThan)
		v0 := b.NewValue0(v.Line, OpARMCMP, TypeFlags)
		v0.AddArg(x)
		v0.AddArg(y)
		v.AddArg(v0)
		return true
	}
}
func rewriteValueARM_OpLoad(v *Value, config *Config) bool {
	b := v.Block
	_ = b
	// match: (Load <t> ptr mem)
	// cond: is32BitInt(t)
	// result: (MOVWload ptr mem)
	for {
		t := v.Type
		ptr := v.Args[0]
		mem := v.Args[1]
		if !(is32BitInt(t)) {
			break
		}
		v.reset(OpARMMOVWload)
		v.AddArg(ptr)
		v.AddArg(mem)
		return true
	}
	return false
}
func rewriteValueARM_OpARMMOVWload(v *Value, config *Config) bool {
	b := v.Block
	_ = b
	// match: (MOVWload [off1] {sym1} (ADDconst [off2] {sym2} ptr) mem)
	// cond: canMergeSym(sym1,sym2)
	// result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
	for {
		off1 := v.AuxInt
		sym1 := v.Aux
		v_0 := v.Args[0]
		if v_0.Op != OpARMADDconst {
			break
		}
		off2 := v_0.AuxInt
		sym2 := v_0.Aux
		ptr := v_0.Args[0]
		mem := v.Args[1]
		if !(canMergeSym(sym1, sym2)) {
			break
		}
		v.reset(OpARMMOVWload)
		v.AuxInt = off1 + off2
		v.Aux = mergeSym(sym1, sym2)
		v.AddArg(ptr)
		v.AddArg(mem)
		return true
	}
	return false
}
func rewriteValueARM_OpARMMOVWstore(v *Value, config *Config) bool {
	b := v.Block
	_ = b
	// match: (MOVWstore [off1] {sym1} (ADDconst [off2] {sym2} ptr) val mem)
	// cond: canMergeSym(sym1,sym2)
	// result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
	for {
		off1 := v.AuxInt
		sym1 := v.Aux
		v_0 := v.Args[0]
		if v_0.Op != OpARMADDconst {
			break
		}
		off2 := v_0.AuxInt
		sym2 := v_0.Aux
		ptr := v_0.Args[0]
		val := v.Args[1]
		mem := v.Args[2]
		if !(canMergeSym(sym1, sym2)) {
			break
		}
		v.reset(OpARMMOVWstore)
		v.AuxInt = off1 + off2
		v.Aux = mergeSym(sym1, sym2)
		v.AddArg(ptr)
		v.AddArg(val)
		v.AddArg(mem)
		return true
	}
	return false
}
func rewriteValueARM_OpOffPtr(v *Value, config *Config) bool {
	b := v.Block
	_ = b
	// match: (OffPtr [off] ptr)
	// cond:
	// result: (ADD (MOVWconst <config.Frontend().TypeInt32()> [off]) ptr)
	for {
		off := v.AuxInt
		ptr := v.Args[0]
		v.reset(OpARMADD)
		v0 := b.NewValue0(v.Line, OpARMMOVWconst, config.Frontend().TypeInt32())
		v0.AuxInt = off
		v.AddArg(v0)
		v.AddArg(ptr)
		return true
	}
}
func rewriteValueARM_OpStaticCall(v *Value, config *Config) bool {
	b := v.Block
	_ = b
	// match: (StaticCall [argwid] {target} mem)
	// cond:
	// result: (CALLstatic [argwid] {target} mem)
	for {
		argwid := v.AuxInt
		target := v.Aux
		mem := v.Args[0]
		v.reset(OpARMCALLstatic)
		v.AuxInt = argwid
		v.Aux = target
		v.AddArg(mem)
		return true
	}
}
func rewriteValueARM_OpStore(v *Value, config *Config) bool {
	b := v.Block
	_ = b
	// match: (Store [4] ptr val mem)
	// cond:
	// result: (MOVWstore ptr val mem)
	for {
		if v.AuxInt != 4 {
			break
		}
		ptr := v.Args[0]
		val := v.Args[1]
		mem := v.Args[2]
		v.reset(OpARMMOVWstore)
		v.AddArg(ptr)
		v.AddArg(val)
		v.AddArg(mem)
		return true
	}
	return false
}
func rewriteBlockARM(b *Block) bool {
	switch b.Kind {
	case BlockIf:
		// match: (If (LessThan cc) yes no)
		// cond:
		// result: (LT cc yes no)
		for {
			v := b.Control
			if v.Op != OpARMLessThan {
				break
			}
			cc := v.Args[0]
			yes := b.Succs[0]
			no := b.Succs[1]
			b.Kind = BlockARMLT
			b.SetControl(cc)
			_ = yes
			_ = no
			return true
		}
	}
	return false
}
