(Select0 (MULTU (MOVWconst [1]) _ )) => (MOVWconst [0])
(Select1 (MULTU (MOVWconst [-1]) x )) => (NEG <x.Type> x)
(Select0 (MULTU (MOVWconst [-1]) x )) => (CMOVZ (ADDconst <x.Type> [-1] x) (MOVWconst [0]) x)
-(Select1 (MULTU (MOVWconst [c]) x )) && isPowerOfTwo(int64(uint32(c))) => (SLLconst [int32(log2uint32(int64(c)))] x)
-(Select0 (MULTU (MOVWconst [c]) x )) && isPowerOfTwo(int64(uint32(c))) => (SRLconst [int32(32-log2uint32(int64(c)))] x)
+(Select1 (MULTU (MOVWconst [c]) x )) && isUnsignedPowerOfTwo(uint32(c)) => (SLLconst [int32(log32u(uint32(c)))] x)
+(Select0 (MULTU (MOVWconst [c]) x )) && isUnsignedPowerOfTwo(uint32(c)) => (SRLconst [int32(32-log32u(uint32(c)))] x)
(MUL (MOVWconst [0]) _ ) => (MOVWconst [0])
(MUL (MOVWconst [1]) x ) => x
(MUL (MOVWconst [-1]) x ) => (NEG x)
-(MUL (MOVWconst [c]) x ) && isPowerOfTwo(int64(uint32(c))) => (SLLconst [int32(log2uint32(int64(c)))] x)
+(MUL (MOVWconst [c]) x ) && isUnsignedPowerOfTwo(uint32(c)) => (SLLconst [int32(log32u(uint32(c)))] x)
// generic simplifications
(ADD x (NEG y)) => (SUB x y)
func log32u(n uint32) int64 { return int64(bits.Len32(n)) - 1 }
func log64u(n uint64) int64 { return int64(bits.Len64(n)) - 1 }
-// log2uint32 returns logarithm in base 2 of uint32(n), with log2(0) = -1.
-// Rounds down.
-func log2uint32(n int64) int64 {
- return int64(bits.Len32(uint32(n))) - 1
-}
-
// isPowerOfTwoX functions report whether n is a power of 2.
func isPowerOfTwo[T int8 | int16 | int32 | int64](n T) bool {
return n > 0 && n&(n-1) == 0
break
}
// match: (MUL (MOVWconst [c]) x )
- // cond: isPowerOfTwo(int64(uint32(c)))
- // result: (SLLconst [int32(log2uint32(int64(c)))] x)
+ // cond: isUnsignedPowerOfTwo(uint32(c))
+ // result: (SLLconst [int32(log32u(uint32(c)))] x)
for {
for _i0 := 0; _i0 <= 1; _i0, v_0, v_1 = _i0+1, v_1, v_0 {
if v_0.Op != OpMIPSMOVWconst {
}
c := auxIntToInt32(v_0.AuxInt)
x := v_1
- if !(isPowerOfTwo(int64(uint32(c)))) {
+ if !(isUnsignedPowerOfTwo(uint32(c))) {
continue
}
v.reset(OpMIPSSLLconst)
- v.AuxInt = int32ToAuxInt(int32(log2uint32(int64(c))))
+ v.AuxInt = int32ToAuxInt(int32(log32u(uint32(c))))
v.AddArg(x)
return true
}
break
}
// match: (Select0 (MULTU (MOVWconst [c]) x ))
- // cond: isPowerOfTwo(int64(uint32(c)))
- // result: (SRLconst [int32(32-log2uint32(int64(c)))] x)
+ // cond: isUnsignedPowerOfTwo(uint32(c))
+ // result: (SRLconst [int32(32-log32u(uint32(c)))] x)
for {
if v_0.Op != OpMIPSMULTU {
break
}
c := auxIntToInt32(v_0_0.AuxInt)
x := v_0_1
- if !(isPowerOfTwo(int64(uint32(c)))) {
+ if !(isUnsignedPowerOfTwo(uint32(c))) {
continue
}
v.reset(OpMIPSSRLconst)
- v.AuxInt = int32ToAuxInt(int32(32 - log2uint32(int64(c))))
+ v.AuxInt = int32ToAuxInt(int32(32 - log32u(uint32(c))))
v.AddArg(x)
return true
}
break
}
// match: (Select1 (MULTU (MOVWconst [c]) x ))
- // cond: isPowerOfTwo(int64(uint32(c)))
- // result: (SLLconst [int32(log2uint32(int64(c)))] x)
+ // cond: isUnsignedPowerOfTwo(uint32(c))
+ // result: (SLLconst [int32(log32u(uint32(c)))] x)
for {
if v_0.Op != OpMIPSMULTU {
break
}
c := auxIntToInt32(v_0_0.AuxInt)
x := v_0_1
- if !(isPowerOfTwo(int64(uint32(c)))) {
+ if !(isUnsignedPowerOfTwo(uint32(c))) {
continue
}
v.reset(OpMIPSSLLconst)
- v.AuxInt = int32ToAuxInt(int32(log2uint32(int64(c))))
+ v.AuxInt = int32ToAuxInt(int32(log32u(uint32(c))))
v.AddArg(x)
return true
}