(Mul32uhilo x y) -> (MULLU x y)
 
-(Div32 x y) -> (DIV x y)
-(Div32u x y) -> (DIVU x y)
-(Div16 x y) -> (DIV (SignExt16to32 x) (SignExt16to32 y))
-(Div16u x y) -> (DIVU (ZeroExt16to32 x) (ZeroExt16to32 y))
-(Div8 x y) -> (DIV (SignExt8to32 x) (SignExt8to32 y))
-(Div8u x y) -> (DIVU (ZeroExt8to32 x) (ZeroExt8to32 y))
+(Div32 x y) ->
+       (SUB (XOR <config.fe.TypeUInt32()>                                                                  // negate the result if one operand is negative
+               (Select0 <config.fe.TypeUInt32()> (UDIVrtcall
+                       (SUB <config.fe.TypeUInt32()> (XOR x <config.fe.TypeUInt32()> (Signmask x)) (Signmask x))   // negate x if negative
+                       (SUB <config.fe.TypeUInt32()> (XOR y <config.fe.TypeUInt32()> (Signmask y)) (Signmask y)))) // negate y if negative
+               (Signmask (XOR <config.fe.TypeUInt32()> x y))) (Signmask (XOR <config.fe.TypeUInt32()> x y)))
+(Div32u x y) -> (Select0 <config.fe.TypeUInt32()> (UDIVrtcall x y))
+(Div16 x y) -> (Div32 (SignExt16to32 x) (SignExt16to32 y))
+(Div16u x y) -> (Div32u (ZeroExt16to32 x) (ZeroExt16to32 y))
+(Div8 x y) -> (Div32 (SignExt8to32 x) (SignExt8to32 y))
+(Div8u x y) -> (Div32u (ZeroExt8to32 x) (ZeroExt8to32 y))
 (Div32F x y) -> (DIVF x y)
 (Div64F x y) -> (DIVD x y)
 
-(Mod32 x y) -> (MOD x y)
-(Mod32u x y) -> (MODU x y)
-(Mod16 x y) -> (MOD (SignExt16to32 x) (SignExt16to32 y))
-(Mod16u x y) -> (MODU (ZeroExt16to32 x) (ZeroExt16to32 y))
-(Mod8 x y) -> (MOD (SignExt8to32 x) (SignExt8to32 y))
-(Mod8u x y) -> (MODU (ZeroExt8to32 x) (ZeroExt8to32 y))
+(Mod32 x y) ->
+       (SUB (XOR <config.fe.TypeUInt32()>                                                                  // negate the result if x is negative
+               (Select1 <config.fe.TypeUInt32()> (UDIVrtcall
+                       (SUB <config.fe.TypeUInt32()> (XOR <config.fe.TypeUInt32()> x (Signmask x)) (Signmask x))   // negate x if negative
+                       (SUB <config.fe.TypeUInt32()> (XOR <config.fe.TypeUInt32()> y (Signmask y)) (Signmask y)))) // negate y if negative
+               (Signmask x)) (Signmask x))
+(Mod32u x y) -> (Select1 <config.fe.TypeUInt32()> (UDIVrtcall x y))
+(Mod16 x y) -> (Mod32 (SignExt16to32 x) (SignExt16to32 y))
+(Mod16u x y) -> (Mod32u (ZeroExt16to32 x) (ZeroExt16to32 y))
+(Mod8 x y) -> (Mod32 (SignExt8to32 x) (SignExt8to32 y))
+(Mod8u x y) -> (Mod32u (ZeroExt8to32 x) (ZeroExt8to32 y))
 
 (And32 x y) -> (AND x y)
 (And16 x y) -> (AND x y)
 (MULA (MOVWconst [c]) x a) && c%9 == 0 && isPowerOfTwo(c/9) && is32Bit(c) -> (ADD (SLLconst <x.Type> [log2(c/9)] (ADDshiftLL <x.Type> x x [3])) a)
 
 // div by constant
-(DIVU x (MOVWconst [1])) -> x
-(DIVU x (MOVWconst [c])) && isPowerOfTwo(c) -> (SRLconst [log2(c)] x)
+(Select0 (UDIVrtcall x (MOVWconst [1]))) -> x
+(Select1 (UDIVrtcall _ (MOVWconst [1]))) -> (MOVWconst [0])
+(Select0 (UDIVrtcall x (MOVWconst [c]))) && isPowerOfTwo(c) -> (SRLconst [log2(c)] x)
+(Select1 (UDIVrtcall x (MOVWconst [c]))) && isPowerOfTwo(c) -> (ANDconst [c-1] x)
 
 // constant comparisons
 (CMPconst (MOVWconst [x]) [y]) && int32(x)==int32(y) -> (FlagEQ)
 (SRAconst [c] (MOVWconst [d])) -> (MOVWconst [int64(int32(d)>>uint64(c))])
 (MUL (MOVWconst [c]) (MOVWconst [d])) -> (MOVWconst [int64(int32(c*d))])
 (MULA (MOVWconst [c]) (MOVWconst [d]) a) -> (ADDconst [int64(int32(c*d))] a)
-(DIV (MOVWconst [c]) (MOVWconst [d])) -> (MOVWconst [int64(int32(c)/int32(d))])
-(DIVU (MOVWconst [c]) (MOVWconst [d])) -> (MOVWconst [int64(uint32(c)/uint32(d))])
+(Select0 (UDIVrtcall (MOVWconst [c]) (MOVWconst [d]))) -> (MOVWconst [int64(uint32(c)/uint32(d))])
+(Select1 (UDIVrtcall (MOVWconst [c]) (MOVWconst [d]))) -> (MOVWconst [int64(uint32(c)%uint32(d))])
 (ANDconst [c] (MOVWconst [d])) -> (MOVWconst [c&d])
 (ANDconst [c] (ANDconst [d] x)) -> (ANDconst [c&d] x)
 (ORconst [c] (MOVWconst [d])) -> (MOVWconst [c|d])
 
                {name: "MUL", argLength: 2, reg: gp21, asm: "MUL", commutative: true},     // arg0 * arg1
                {name: "HMUL", argLength: 2, reg: gp21, asm: "MULL", commutative: true},   // (arg0 * arg1) >> 32, signed
                {name: "HMULU", argLength: 2, reg: gp21, asm: "MULLU", commutative: true}, // (arg0 * arg1) >> 32, unsigned
-               {name: "DIV", argLength: 2, reg: gp21, asm: "DIV", clobberFlags: true},    // arg0 / arg1, signed, soft div clobbers flags
-               {name: "DIVU", argLength: 2, reg: gp21, asm: "DIVU", clobberFlags: true},  // arg0 / arg1, unsighed
-               {name: "MOD", argLength: 2, reg: gp21, asm: "MOD", clobberFlags: true},    // arg0 % arg1, signed
-               {name: "MODU", argLength: 2, reg: gp21, asm: "MODU", clobberFlags: true},  // arg0 % arg1, unsigned
+
+               // udiv runtime call for soft division
+               // output0 = arg0/arg1, output1 = arg0%arg1
+               // see ../../../../../runtime/vlop_arm.s
+               {
+                       name:      "UDIVrtcall",
+                       argLength: 2,
+                       reg: regInfo{
+                               inputs:   []regMask{buildReg("R1"), buildReg("R0")},
+                               outputs:  []regMask{buildReg("R0"), buildReg("R1")},
+                               clobbers: buildReg("R2 R3"), // also clobbers R12 on NaCl (modified in ../config.go)
+                       },
+                       clobberFlags: true,
+                       typ:          "(UInt32,UInt32)",
+               },
 
                {name: "ADDS", argLength: 2, reg: gp21carry, asm: "ADD", commutative: true}, // arg0 + arg1, set carry flag
                {name: "ADDSconst", argLength: 1, reg: gp11carry, asm: "ADD", aux: "Int32"}, // arg0 + auxInt, set carry flag
 
                return rewriteValueARM_OpARMCMPshiftRL(v, config)
        case OpARMCMPshiftRLreg:
                return rewriteValueARM_OpARMCMPshiftRLreg(v, config)
-       case OpARMDIV:
-               return rewriteValueARM_OpARMDIV(v, config)
-       case OpARMDIVU:
-               return rewriteValueARM_OpARMDIVU(v, config)
        case OpARMEqual:
                return rewriteValueARM_OpARMEqual(v, config)
        case OpARMGreaterEqual:
                return rewriteValueARM_OpRsh8x64(v, config)
        case OpRsh8x8:
                return rewriteValueARM_OpRsh8x8(v, config)
+       case OpSelect0:
+               return rewriteValueARM_OpSelect0(v, config)
+       case OpSelect1:
+               return rewriteValueARM_OpSelect1(v, config)
        case OpSignExt16to32:
                return rewriteValueARM_OpSignExt16to32(v, config)
        case OpSignExt8to16:
        }
        return false
 }
-func rewriteValueARM_OpARMDIV(v *Value, config *Config) bool {
-       b := v.Block
-       _ = b
-       // match: (DIV (MOVWconst [c]) (MOVWconst [d]))
-       // cond:
-       // result: (MOVWconst [int64(int32(c)/int32(d))])
-       for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
-                       break
-               }
-               c := v_0.AuxInt
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVWconst {
-                       break
-               }
-               d := v_1.AuxInt
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = int64(int32(c) / int32(d))
-               return true
-       }
-       return false
-}
-func rewriteValueARM_OpARMDIVU(v *Value, config *Config) bool {
-       b := v.Block
-       _ = b
-       // match: (DIVU x (MOVWconst [1]))
-       // cond:
-       // result: x
-       for {
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVWconst {
-                       break
-               }
-               if v_1.AuxInt != 1 {
-                       break
-               }
-               v.reset(OpCopy)
-               v.Type = x.Type
-               v.AddArg(x)
-               return true
-       }
-       // match: (DIVU x (MOVWconst [c]))
-       // cond: isPowerOfTwo(c)
-       // result: (SRLconst [log2(c)] x)
-       for {
-               x := v.Args[0]
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVWconst {
-                       break
-               }
-               c := v_1.AuxInt
-               if !(isPowerOfTwo(c)) {
-                       break
-               }
-               v.reset(OpARMSRLconst)
-               v.AuxInt = log2(c)
-               v.AddArg(x)
-               return true
-       }
-       // match: (DIVU (MOVWconst [c]) (MOVWconst [d]))
-       // cond:
-       // result: (MOVWconst [int64(uint32(c)/uint32(d))])
-       for {
-               v_0 := v.Args[0]
-               if v_0.Op != OpARMMOVWconst {
-                       break
-               }
-               c := v_0.AuxInt
-               v_1 := v.Args[1]
-               if v_1.Op != OpARMMOVWconst {
-                       break
-               }
-               d := v_1.AuxInt
-               v.reset(OpARMMOVWconst)
-               v.AuxInt = int64(uint32(c) / uint32(d))
-               return true
-       }
-       return false
-}
 func rewriteValueARM_OpARMEqual(v *Value, config *Config) bool {
        b := v.Block
        _ = b
        _ = b
        // match: (Div16 x y)
        // cond:
-       // result: (DIV (SignExt16to32 x) (SignExt16to32 y))
+       // result: (Div32 (SignExt16to32 x) (SignExt16to32 y))
        for {
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMDIV)
+               v.reset(OpDiv32)
                v0 := b.NewValue0(v.Line, OpSignExt16to32, config.fe.TypeInt32())
                v0.AddArg(x)
                v.AddArg(v0)
        _ = b
        // match: (Div16u x y)
        // cond:
-       // result: (DIVU (ZeroExt16to32 x) (ZeroExt16to32 y))
+       // result: (Div32u (ZeroExt16to32 x) (ZeroExt16to32 y))
        for {
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMDIVU)
+               v.reset(OpDiv32u)
                v0 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32())
                v0.AddArg(x)
                v.AddArg(v0)
        _ = b
        // match: (Div32 x y)
        // cond:
-       // result: (DIV x y)
+       // result: (SUB (XOR <config.fe.TypeUInt32()>           (Select0 <config.fe.TypeUInt32()> (UDIVrtcall                   (SUB <config.fe.TypeUInt32()> (XOR x <config.fe.TypeUInt32()> (Signmask x)) (Signmask x))                       (SUB <config.fe.TypeUInt32()> (XOR y <config.fe.TypeUInt32()> (Signmask y)) (Signmask y))))             (Signmask (XOR <config.fe.TypeUInt32()> x y))) (Signmask (XOR <config.fe.TypeUInt32()> x y)))
        for {
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMDIV)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMSUB)
+               v0 := b.NewValue0(v.Line, OpARMXOR, config.fe.TypeUInt32())
+               v1 := b.NewValue0(v.Line, OpSelect0, config.fe.TypeUInt32())
+               v2 := b.NewValue0(v.Line, OpARMUDIVrtcall, MakeTuple(config.fe.TypeUInt32(), config.fe.TypeUInt32()))
+               v3 := b.NewValue0(v.Line, OpARMSUB, config.fe.TypeUInt32())
+               v4 := b.NewValue0(v.Line, OpARMXOR, config.fe.TypeUInt32())
+               v4.AddArg(x)
+               v5 := b.NewValue0(v.Line, OpSignmask, config.fe.TypeInt32())
+               v5.AddArg(x)
+               v4.AddArg(v5)
+               v3.AddArg(v4)
+               v6 := b.NewValue0(v.Line, OpSignmask, config.fe.TypeInt32())
+               v6.AddArg(x)
+               v3.AddArg(v6)
+               v2.AddArg(v3)
+               v7 := b.NewValue0(v.Line, OpARMSUB, config.fe.TypeUInt32())
+               v8 := b.NewValue0(v.Line, OpARMXOR, config.fe.TypeUInt32())
+               v8.AddArg(y)
+               v9 := b.NewValue0(v.Line, OpSignmask, config.fe.TypeInt32())
+               v9.AddArg(y)
+               v8.AddArg(v9)
+               v7.AddArg(v8)
+               v10 := b.NewValue0(v.Line, OpSignmask, config.fe.TypeInt32())
+               v10.AddArg(y)
+               v7.AddArg(v10)
+               v2.AddArg(v7)
+               v1.AddArg(v2)
+               v0.AddArg(v1)
+               v11 := b.NewValue0(v.Line, OpSignmask, config.fe.TypeInt32())
+               v12 := b.NewValue0(v.Line, OpARMXOR, config.fe.TypeUInt32())
+               v12.AddArg(x)
+               v12.AddArg(y)
+               v11.AddArg(v12)
+               v0.AddArg(v11)
+               v.AddArg(v0)
+               v13 := b.NewValue0(v.Line, OpSignmask, config.fe.TypeInt32())
+               v14 := b.NewValue0(v.Line, OpARMXOR, config.fe.TypeUInt32())
+               v14.AddArg(x)
+               v14.AddArg(y)
+               v13.AddArg(v14)
+               v.AddArg(v13)
                return true
        }
 }
        _ = b
        // match: (Div32u x y)
        // cond:
-       // result: (DIVU x y)
+       // result: (Select0 <config.fe.TypeUInt32()> (UDIVrtcall x y))
        for {
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMDIVU)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpSelect0)
+               v.Type = config.fe.TypeUInt32()
+               v0 := b.NewValue0(v.Line, OpARMUDIVrtcall, MakeTuple(config.fe.TypeUInt32(), config.fe.TypeUInt32()))
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
 }
        _ = b
        // match: (Div8 x y)
        // cond:
-       // result: (DIV (SignExt8to32 x) (SignExt8to32 y))
+       // result: (Div32 (SignExt8to32 x) (SignExt8to32 y))
        for {
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMDIV)
+               v.reset(OpDiv32)
                v0 := b.NewValue0(v.Line, OpSignExt8to32, config.fe.TypeInt32())
                v0.AddArg(x)
                v.AddArg(v0)
        _ = b
        // match: (Div8u x y)
        // cond:
-       // result: (DIVU (ZeroExt8to32 x) (ZeroExt8to32 y))
+       // result: (Div32u (ZeroExt8to32 x) (ZeroExt8to32 y))
        for {
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMDIVU)
+               v.reset(OpDiv32u)
                v0 := b.NewValue0(v.Line, OpZeroExt8to32, config.fe.TypeUInt32())
                v0.AddArg(x)
                v.AddArg(v0)
        _ = b
        // match: (Mod16 x y)
        // cond:
-       // result: (MOD (SignExt16to32 x) (SignExt16to32 y))
+       // result: (Mod32 (SignExt16to32 x) (SignExt16to32 y))
        for {
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMMOD)
+               v.reset(OpMod32)
                v0 := b.NewValue0(v.Line, OpSignExt16to32, config.fe.TypeInt32())
                v0.AddArg(x)
                v.AddArg(v0)
        _ = b
        // match: (Mod16u x y)
        // cond:
-       // result: (MODU (ZeroExt16to32 x) (ZeroExt16to32 y))
+       // result: (Mod32u (ZeroExt16to32 x) (ZeroExt16to32 y))
        for {
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMMODU)
+               v.reset(OpMod32u)
                v0 := b.NewValue0(v.Line, OpZeroExt16to32, config.fe.TypeUInt32())
                v0.AddArg(x)
                v.AddArg(v0)
        _ = b
        // match: (Mod32 x y)
        // cond:
-       // result: (MOD x y)
+       // result: (SUB (XOR <config.fe.TypeUInt32()>           (Select1 <config.fe.TypeUInt32()> (UDIVrtcall                   (SUB <config.fe.TypeUInt32()> (XOR <config.fe.TypeUInt32()> x (Signmask x)) (Signmask x))                       (SUB <config.fe.TypeUInt32()> (XOR <config.fe.TypeUInt32()> y (Signmask y)) (Signmask y))))             (Signmask x)) (Signmask x))
        for {
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMMOD)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpARMSUB)
+               v0 := b.NewValue0(v.Line, OpARMXOR, config.fe.TypeUInt32())
+               v1 := b.NewValue0(v.Line, OpSelect1, config.fe.TypeUInt32())
+               v2 := b.NewValue0(v.Line, OpARMUDIVrtcall, MakeTuple(config.fe.TypeUInt32(), config.fe.TypeUInt32()))
+               v3 := b.NewValue0(v.Line, OpARMSUB, config.fe.TypeUInt32())
+               v4 := b.NewValue0(v.Line, OpARMXOR, config.fe.TypeUInt32())
+               v4.AddArg(x)
+               v5 := b.NewValue0(v.Line, OpSignmask, config.fe.TypeInt32())
+               v5.AddArg(x)
+               v4.AddArg(v5)
+               v3.AddArg(v4)
+               v6 := b.NewValue0(v.Line, OpSignmask, config.fe.TypeInt32())
+               v6.AddArg(x)
+               v3.AddArg(v6)
+               v2.AddArg(v3)
+               v7 := b.NewValue0(v.Line, OpARMSUB, config.fe.TypeUInt32())
+               v8 := b.NewValue0(v.Line, OpARMXOR, config.fe.TypeUInt32())
+               v8.AddArg(y)
+               v9 := b.NewValue0(v.Line, OpSignmask, config.fe.TypeInt32())
+               v9.AddArg(y)
+               v8.AddArg(v9)
+               v7.AddArg(v8)
+               v10 := b.NewValue0(v.Line, OpSignmask, config.fe.TypeInt32())
+               v10.AddArg(y)
+               v7.AddArg(v10)
+               v2.AddArg(v7)
+               v1.AddArg(v2)
+               v0.AddArg(v1)
+               v11 := b.NewValue0(v.Line, OpSignmask, config.fe.TypeInt32())
+               v11.AddArg(x)
+               v0.AddArg(v11)
+               v.AddArg(v0)
+               v12 := b.NewValue0(v.Line, OpSignmask, config.fe.TypeInt32())
+               v12.AddArg(x)
+               v.AddArg(v12)
                return true
        }
 }
        _ = b
        // match: (Mod32u x y)
        // cond:
-       // result: (MODU x y)
+       // result: (Select1 <config.fe.TypeUInt32()> (UDIVrtcall x y))
        for {
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMMODU)
-               v.AddArg(x)
-               v.AddArg(y)
+               v.reset(OpSelect1)
+               v.Type = config.fe.TypeUInt32()
+               v0 := b.NewValue0(v.Line, OpARMUDIVrtcall, MakeTuple(config.fe.TypeUInt32(), config.fe.TypeUInt32()))
+               v0.AddArg(x)
+               v0.AddArg(y)
+               v.AddArg(v0)
                return true
        }
 }
        _ = b
        // match: (Mod8 x y)
        // cond:
-       // result: (MOD (SignExt8to32 x) (SignExt8to32 y))
+       // result: (Mod32 (SignExt8to32 x) (SignExt8to32 y))
        for {
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMMOD)
+               v.reset(OpMod32)
                v0 := b.NewValue0(v.Line, OpSignExt8to32, config.fe.TypeInt32())
                v0.AddArg(x)
                v.AddArg(v0)
        _ = b
        // match: (Mod8u x y)
        // cond:
-       // result: (MODU (ZeroExt8to32 x) (ZeroExt8to32 y))
+       // result: (Mod32u (ZeroExt8to32 x) (ZeroExt8to32 y))
        for {
                x := v.Args[0]
                y := v.Args[1]
-               v.reset(OpARMMODU)
+               v.reset(OpMod32u)
                v0 := b.NewValue0(v.Line, OpZeroExt8to32, config.fe.TypeUInt32())
                v0.AddArg(x)
                v.AddArg(v0)
                return true
        }
 }
+func rewriteValueARM_OpSelect0(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Select0 (UDIVrtcall x (MOVWconst [1])))
+       // cond:
+       // result: x
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMUDIVrtcall {
+                       break
+               }
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpARMMOVWconst {
+                       break
+               }
+               if v_0_1.AuxInt != 1 {
+                       break
+               }
+               v.reset(OpCopy)
+               v.Type = x.Type
+               v.AddArg(x)
+               return true
+       }
+       // match: (Select0 (UDIVrtcall x (MOVWconst [c])))
+       // cond: isPowerOfTwo(c)
+       // result: (SRLconst [log2(c)] x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMUDIVrtcall {
+                       break
+               }
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0_1.AuxInt
+               if !(isPowerOfTwo(c)) {
+                       break
+               }
+               v.reset(OpARMSRLconst)
+               v.AuxInt = log2(c)
+               v.AddArg(x)
+               return true
+       }
+       // match: (Select0 (UDIVrtcall (MOVWconst [c]) (MOVWconst [d])))
+       // cond:
+       // result: (MOVWconst [int64(uint32(c)/uint32(d))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMUDIVrtcall {
+                       break
+               }
+               v_0_0 := v_0.Args[0]
+               if v_0_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0_0.AuxInt
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpARMMOVWconst {
+                       break
+               }
+               d := v_0_1.AuxInt
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = int64(uint32(c) / uint32(d))
+               return true
+       }
+       return false
+}
+func rewriteValueARM_OpSelect1(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (Select1 (UDIVrtcall _ (MOVWconst [1])))
+       // cond:
+       // result: (MOVWconst [0])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMUDIVrtcall {
+                       break
+               }
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpARMMOVWconst {
+                       break
+               }
+               if v_0_1.AuxInt != 1 {
+                       break
+               }
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = 0
+               return true
+       }
+       // match: (Select1 (UDIVrtcall x (MOVWconst [c])))
+       // cond: isPowerOfTwo(c)
+       // result: (ANDconst [c-1] x)
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMUDIVrtcall {
+                       break
+               }
+               x := v_0.Args[0]
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0_1.AuxInt
+               if !(isPowerOfTwo(c)) {
+                       break
+               }
+               v.reset(OpARMANDconst)
+               v.AuxInt = c - 1
+               v.AddArg(x)
+               return true
+       }
+       // match: (Select1 (UDIVrtcall (MOVWconst [c]) (MOVWconst [d])))
+       // cond:
+       // result: (MOVWconst [int64(uint32(c)%uint32(d))])
+       for {
+               v_0 := v.Args[0]
+               if v_0.Op != OpARMUDIVrtcall {
+                       break
+               }
+               v_0_0 := v_0.Args[0]
+               if v_0_0.Op != OpARMMOVWconst {
+                       break
+               }
+               c := v_0_0.AuxInt
+               v_0_1 := v_0.Args[1]
+               if v_0_1.Op != OpARMMOVWconst {
+                       break
+               }
+               d := v_0_1.AuxInt
+               v.reset(OpARMMOVWconst)
+               v.AuxInt = int64(uint32(c) % uint32(d))
+               return true
+       }
+       return false
+}
 func rewriteValueARM_OpSignExt16to32(v *Value, config *Config) bool {
        b := v.Block
        _ = b