Source file src/cmd/compile/internal/ssarewrite/rewritedivmod/rewritedivmod.go

     1  // Code generated from _gen/divmod.rules using 'go generate'; DO NOT EDIT.
     2  
     3  package rewritedivmod
     4  
     5  import "cmd/compile/internal/ssa/ssaop"
     6  import "cmd/compile/internal/ssa"
     7  
     8  func RewriteValue(v *ssa.Value) bool {
     9  	switch v.Op {
    10  	case ssaop.OpDiv16:
    11  		return rewriteValue_OpDiv16(v)
    12  	case ssaop.OpDiv16u:
    13  		return rewriteValue_OpDiv16u(v)
    14  	case ssaop.OpDiv32:
    15  		return rewriteValue_OpDiv32(v)
    16  	case ssaop.OpDiv32u:
    17  		return rewriteValue_OpDiv32u(v)
    18  	case ssaop.OpDiv64:
    19  		return rewriteValue_OpDiv64(v)
    20  	case ssaop.OpDiv64u:
    21  		return rewriteValue_OpDiv64u(v)
    22  	case ssaop.OpDiv8:
    23  		return rewriteValue_OpDiv8(v)
    24  	case ssaop.OpDiv8u:
    25  		return rewriteValue_OpDiv8u(v)
    26  	}
    27  	return false
    28  }
    29  func rewriteValue_OpDiv16(v *ssa.Value) bool {
    30  	v_1 := v.Args[1]
    31  	v_0 := v.Args[0]
    32  	b := v.Block
    33  	typ := &b.Func.Config.Types
    34  	// match: (Div16 <t> n (Const16 [c]))
    35  	// cond: ssa.IsPowerOfTwo(c)
    36  	// result: (Rsh16x64 (Add16 <t> n (Rsh16Ux64 <t> (Rsh16x64 <t> n (Const64 <typ.UInt64> [15])) (Const64 <typ.UInt64> [int64(16-ssa.Log16(c))]))) (Const64 <typ.UInt64> [int64(ssa.Log16(c))]))
    37  	for {
    38  		t := v.Type
    39  		n := v_0
    40  		if v_1.Op != ssaop.OpConst16 {
    41  			break
    42  		}
    43  		c := ssa.AuxIntToInt16(v_1.AuxInt)
    44  		if !(ssa.IsPowerOfTwo(c)) {
    45  			break
    46  		}
    47  		v.Reset(ssaop.OpRsh16x64)
    48  		v0 := b.NewValue0(v.Pos, ssaop.OpAdd16, t)
    49  		v1 := b.NewValue0(v.Pos, ssaop.OpRsh16Ux64, t)
    50  		v2 := b.NewValue0(v.Pos, ssaop.OpRsh16x64, t)
    51  		v3 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
    52  		v3.AuxInt = ssa.Int64ToAuxInt(15)
    53  		v2.AddArg2(n, v3)
    54  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
    55  		v4.AuxInt = ssa.Int64ToAuxInt(int64(16 - ssa.Log16(c)))
    56  		v1.AddArg2(v2, v4)
    57  		v0.AddArg2(n, v1)
    58  		v5 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
    59  		v5.AuxInt = ssa.Int64ToAuxInt(int64(ssa.Log16(c)))
    60  		v.AddArg2(v0, v5)
    61  		return true
    62  	}
    63  	// match: (Div16 <t> x (Const16 [c]))
    64  	// cond: smagicOK16(c)
    65  	// result: (Sub16 <t> (Rsh32x64 <t> (Mul32 <typ.UInt32> (SignExt16to32 x) (Const32 <typ.UInt32> [int32(smagic16(c).M)])) (Const64 <typ.UInt64> [16 + smagic16(c).S])) (Rsh32x64 <t> (SignExt16to32 x) (Const64 <typ.UInt64> [31])))
    66  	for {
    67  		t := v.Type
    68  		x := v_0
    69  		if v_1.Op != ssaop.OpConst16 {
    70  			break
    71  		}
    72  		c := ssa.AuxIntToInt16(v_1.AuxInt)
    73  		if !(smagicOK16(c)) {
    74  			break
    75  		}
    76  		v.Reset(ssaop.OpSub16)
    77  		v.Type = t
    78  		v0 := b.NewValue0(v.Pos, ssaop.OpRsh32x64, t)
    79  		v1 := b.NewValue0(v.Pos, ssaop.OpMul32, typ.UInt32)
    80  		v2 := b.NewValue0(v.Pos, ssaop.OpSignExt16to32, typ.Int32)
    81  		v2.AddArg(x)
    82  		v3 := b.NewValue0(v.Pos, ssaop.OpConst32, typ.UInt32)
    83  		v3.AuxInt = ssa.Int32ToAuxInt(int32(smagic16(c).M))
    84  		v1.AddArg2(v2, v3)
    85  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
    86  		v4.AuxInt = ssa.Int64ToAuxInt(16 + smagic16(c).S)
    87  		v0.AddArg2(v1, v4)
    88  		v5 := b.NewValue0(v.Pos, ssaop.OpRsh32x64, t)
    89  		v6 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
    90  		v6.AuxInt = ssa.Int64ToAuxInt(31)
    91  		v5.AddArg2(v2, v6)
    92  		v.AddArg2(v0, v5)
    93  		return true
    94  	}
    95  	return false
    96  }
    97  func rewriteValue_OpDiv16u(v *ssa.Value) bool {
    98  	v_1 := v.Args[1]
    99  	v_0 := v.Args[0]
   100  	b := v.Block
   101  	config := b.Func.Config
   102  	typ := &b.Func.Config.Types
   103  	// match: (Div16u <t> x (Const16 [c]))
   104  	// cond: t.IsSigned() && smagicOK16(c)
   105  	// result: (Rsh32Ux64 <t> (Mul32 <typ.UInt32> (SignExt16to32 x) (Const32 <typ.UInt32> [int32(smagic16(c).M)])) (Const64 <typ.UInt64> [16 + smagic16(c).S]))
   106  	for {
   107  		t := v.Type
   108  		x := v_0
   109  		if v_1.Op != ssaop.OpConst16 {
   110  			break
   111  		}
   112  		c := ssa.AuxIntToInt16(v_1.AuxInt)
   113  		if !(t.IsSigned() && smagicOK16(c)) {
   114  			break
   115  		}
   116  		v.Reset(ssaop.OpRsh32Ux64)
   117  		v.Type = t
   118  		v0 := b.NewValue0(v.Pos, ssaop.OpMul32, typ.UInt32)
   119  		v1 := b.NewValue0(v.Pos, ssaop.OpSignExt16to32, typ.Int32)
   120  		v1.AddArg(x)
   121  		v2 := b.NewValue0(v.Pos, ssaop.OpConst32, typ.UInt32)
   122  		v2.AuxInt = ssa.Int32ToAuxInt(int32(smagic16(c).M))
   123  		v0.AddArg2(v1, v2)
   124  		v3 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   125  		v3.AuxInt = ssa.Int64ToAuxInt(16 + smagic16(c).S)
   126  		v.AddArg2(v0, v3)
   127  		return true
   128  	}
   129  	// match: (Div16u <t> x (Const16 [c]))
   130  	// cond: umagicOK16(c) && config.RegSize == 8
   131  	// result: (Trunc64to16 <t> (Rsh64Ux64 <typ.UInt64> (Mul64 <typ.UInt64> (ZeroExt16to64 x) (Const64 <typ.UInt64> [int64(1<<16 + umagic16(c).M)])) (Const64 <typ.UInt64> [16 + umagic16(c).S])))
   132  	for {
   133  		t := v.Type
   134  		x := v_0
   135  		if v_1.Op != ssaop.OpConst16 {
   136  			break
   137  		}
   138  		c := ssa.AuxIntToInt16(v_1.AuxInt)
   139  		if !(umagicOK16(c) && config.RegSize == 8) {
   140  			break
   141  		}
   142  		v.Reset(ssaop.OpTrunc64to16)
   143  		v.Type = t
   144  		v0 := b.NewValue0(v.Pos, ssaop.OpRsh64Ux64, typ.UInt64)
   145  		v1 := b.NewValue0(v.Pos, ssaop.OpMul64, typ.UInt64)
   146  		v2 := b.NewValue0(v.Pos, ssaop.OpZeroExt16to64, typ.UInt64)
   147  		v2.AddArg(x)
   148  		v3 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   149  		v3.AuxInt = ssa.Int64ToAuxInt(int64(1<<16 + umagic16(c).M))
   150  		v1.AddArg2(v2, v3)
   151  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   152  		v4.AuxInt = ssa.Int64ToAuxInt(16 + umagic16(c).S)
   153  		v0.AddArg2(v1, v4)
   154  		v.AddArg(v0)
   155  		return true
   156  	}
   157  	// match: (Div16u <t> x (Const16 [c]))
   158  	// cond: umagicOK16(c) && umagic16(c).M&1 == 0
   159  	// result: (Trunc32to16 <t> (Rsh32Ux64 <typ.UInt32> (Mul32 <typ.UInt32> (ZeroExt16to32 x) (Const32 <typ.UInt32> [int32(1<<15 + umagic16(c).M/2)])) (Const64 <typ.UInt64> [16 + umagic16(c).S - 1])))
   160  	for {
   161  		t := v.Type
   162  		x := v_0
   163  		if v_1.Op != ssaop.OpConst16 {
   164  			break
   165  		}
   166  		c := ssa.AuxIntToInt16(v_1.AuxInt)
   167  		if !(umagicOK16(c) && umagic16(c).M&1 == 0) {
   168  			break
   169  		}
   170  		v.Reset(ssaop.OpTrunc32to16)
   171  		v.Type = t
   172  		v0 := b.NewValue0(v.Pos, ssaop.OpRsh32Ux64, typ.UInt32)
   173  		v1 := b.NewValue0(v.Pos, ssaop.OpMul32, typ.UInt32)
   174  		v2 := b.NewValue0(v.Pos, ssaop.OpZeroExt16to32, typ.UInt32)
   175  		v2.AddArg(x)
   176  		v3 := b.NewValue0(v.Pos, ssaop.OpConst32, typ.UInt32)
   177  		v3.AuxInt = ssa.Int32ToAuxInt(int32(1<<15 + umagic16(c).M/2))
   178  		v1.AddArg2(v2, v3)
   179  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   180  		v4.AuxInt = ssa.Int64ToAuxInt(16 + umagic16(c).S - 1)
   181  		v0.AddArg2(v1, v4)
   182  		v.AddArg(v0)
   183  		return true
   184  	}
   185  	// match: (Div16u <t> x (Const16 [c]))
   186  	// cond: umagicOK16(c) && config.RegSize == 4 && c&1 == 0
   187  	// result: (Trunc32to16 <t> (Rsh32Ux64 <typ.UInt32> (Mul32 <typ.UInt32> (Rsh32Ux64 <typ.UInt32> (ZeroExt16to32 x) (Const64 <typ.UInt64> [1])) (Const32 <typ.UInt32> [int32(1<<15 + (umagic16(c).M+1)/2)])) (Const64 <typ.UInt64> [16 + umagic16(c).S - 2])))
   188  	for {
   189  		t := v.Type
   190  		x := v_0
   191  		if v_1.Op != ssaop.OpConst16 {
   192  			break
   193  		}
   194  		c := ssa.AuxIntToInt16(v_1.AuxInt)
   195  		if !(umagicOK16(c) && config.RegSize == 4 && c&1 == 0) {
   196  			break
   197  		}
   198  		v.Reset(ssaop.OpTrunc32to16)
   199  		v.Type = t
   200  		v0 := b.NewValue0(v.Pos, ssaop.OpRsh32Ux64, typ.UInt32)
   201  		v1 := b.NewValue0(v.Pos, ssaop.OpMul32, typ.UInt32)
   202  		v2 := b.NewValue0(v.Pos, ssaop.OpRsh32Ux64, typ.UInt32)
   203  		v3 := b.NewValue0(v.Pos, ssaop.OpZeroExt16to32, typ.UInt32)
   204  		v3.AddArg(x)
   205  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   206  		v4.AuxInt = ssa.Int64ToAuxInt(1)
   207  		v2.AddArg2(v3, v4)
   208  		v5 := b.NewValue0(v.Pos, ssaop.OpConst32, typ.UInt32)
   209  		v5.AuxInt = ssa.Int32ToAuxInt(int32(1<<15 + (umagic16(c).M+1)/2))
   210  		v1.AddArg2(v2, v5)
   211  		v6 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   212  		v6.AuxInt = ssa.Int64ToAuxInt(16 + umagic16(c).S - 2)
   213  		v0.AddArg2(v1, v6)
   214  		v.AddArg(v0)
   215  		return true
   216  	}
   217  	// match: (Div16u <t> x (Const16 [c]))
   218  	// cond: umagicOK16(c) && config.RegSize == 4
   219  	// result: (Trunc32to16 <t> (Rsh32Ux64 <typ.UInt32> (Avg32u (Lsh32x64 <typ.UInt32> (ZeroExt16to32 x) (Const64 <typ.UInt64> [16])) (Mul32 <typ.UInt32> (ZeroExt16to32 x) (Const32 <typ.UInt32> [int32(umagic16(c).M)]))) (Const64 <typ.UInt64> [16 + umagic16(c).S - 1])))
   220  	for {
   221  		t := v.Type
   222  		x := v_0
   223  		if v_1.Op != ssaop.OpConst16 {
   224  			break
   225  		}
   226  		c := ssa.AuxIntToInt16(v_1.AuxInt)
   227  		if !(umagicOK16(c) && config.RegSize == 4) {
   228  			break
   229  		}
   230  		v.Reset(ssaop.OpTrunc32to16)
   231  		v.Type = t
   232  		v0 := b.NewValue0(v.Pos, ssaop.OpRsh32Ux64, typ.UInt32)
   233  		v1 := b.NewValue0(v.Pos, ssaop.OpAvg32u, typ.UInt32)
   234  		v2 := b.NewValue0(v.Pos, ssaop.OpLsh32x64, typ.UInt32)
   235  		v3 := b.NewValue0(v.Pos, ssaop.OpZeroExt16to32, typ.UInt32)
   236  		v3.AddArg(x)
   237  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   238  		v4.AuxInt = ssa.Int64ToAuxInt(16)
   239  		v2.AddArg2(v3, v4)
   240  		v5 := b.NewValue0(v.Pos, ssaop.OpMul32, typ.UInt32)
   241  		v6 := b.NewValue0(v.Pos, ssaop.OpConst32, typ.UInt32)
   242  		v6.AuxInt = ssa.Int32ToAuxInt(int32(umagic16(c).M))
   243  		v5.AddArg2(v3, v6)
   244  		v1.AddArg2(v2, v5)
   245  		v7 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   246  		v7.AuxInt = ssa.Int64ToAuxInt(16 + umagic16(c).S - 1)
   247  		v0.AddArg2(v1, v7)
   248  		v.AddArg(v0)
   249  		return true
   250  	}
   251  	return false
   252  }
   253  func rewriteValue_OpDiv32(v *ssa.Value) bool {
   254  	v_1 := v.Args[1]
   255  	v_0 := v.Args[0]
   256  	b := v.Block
   257  	config := b.Func.Config
   258  	typ := &b.Func.Config.Types
   259  	// match: (Div32 <t> n (Const32 [c]))
   260  	// cond: ssa.IsPowerOfTwo(c)
   261  	// result: (Rsh32x64 (Add32 <t> n (Rsh32Ux64 <t> (Rsh32x64 <t> n (Const64 <typ.UInt64> [31])) (Const64 <typ.UInt64> [int64(32-ssa.Log32(c))]))) (Const64 <typ.UInt64> [int64(ssa.Log32(c))]))
   262  	for {
   263  		t := v.Type
   264  		n := v_0
   265  		if v_1.Op != ssaop.OpConst32 {
   266  			break
   267  		}
   268  		c := ssa.AuxIntToInt32(v_1.AuxInt)
   269  		if !(ssa.IsPowerOfTwo(c)) {
   270  			break
   271  		}
   272  		v.Reset(ssaop.OpRsh32x64)
   273  		v0 := b.NewValue0(v.Pos, ssaop.OpAdd32, t)
   274  		v1 := b.NewValue0(v.Pos, ssaop.OpRsh32Ux64, t)
   275  		v2 := b.NewValue0(v.Pos, ssaop.OpRsh32x64, t)
   276  		v3 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   277  		v3.AuxInt = ssa.Int64ToAuxInt(31)
   278  		v2.AddArg2(n, v3)
   279  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   280  		v4.AuxInt = ssa.Int64ToAuxInt(int64(32 - ssa.Log32(c)))
   281  		v1.AddArg2(v2, v4)
   282  		v0.AddArg2(n, v1)
   283  		v5 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   284  		v5.AuxInt = ssa.Int64ToAuxInt(int64(ssa.Log32(c)))
   285  		v.AddArg2(v0, v5)
   286  		return true
   287  	}
   288  	// match: (Div32 <t> x (Const32 [c]))
   289  	// cond: smagicOK32(c) && config.RegSize == 8
   290  	// result: (Sub32 <t> (Rsh64x64 <t> (Mul64 <typ.UInt64> (SignExt32to64 x) (Const64 <typ.UInt64> [int64(smagic32(c).M)])) (Const64 <typ.UInt64> [32 + smagic32(c).S])) (Rsh64x64 <t> (SignExt32to64 x) (Const64 <typ.UInt64> [63])))
   291  	for {
   292  		t := v.Type
   293  		x := v_0
   294  		if v_1.Op != ssaop.OpConst32 {
   295  			break
   296  		}
   297  		c := ssa.AuxIntToInt32(v_1.AuxInt)
   298  		if !(smagicOK32(c) && config.RegSize == 8) {
   299  			break
   300  		}
   301  		v.Reset(ssaop.OpSub32)
   302  		v.Type = t
   303  		v0 := b.NewValue0(v.Pos, ssaop.OpRsh64x64, t)
   304  		v1 := b.NewValue0(v.Pos, ssaop.OpMul64, typ.UInt64)
   305  		v2 := b.NewValue0(v.Pos, ssaop.OpSignExt32to64, typ.Int64)
   306  		v2.AddArg(x)
   307  		v3 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   308  		v3.AuxInt = ssa.Int64ToAuxInt(int64(smagic32(c).M))
   309  		v1.AddArg2(v2, v3)
   310  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   311  		v4.AuxInt = ssa.Int64ToAuxInt(32 + smagic32(c).S)
   312  		v0.AddArg2(v1, v4)
   313  		v5 := b.NewValue0(v.Pos, ssaop.OpRsh64x64, t)
   314  		v6 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   315  		v6.AuxInt = ssa.Int64ToAuxInt(63)
   316  		v5.AddArg2(v2, v6)
   317  		v.AddArg2(v0, v5)
   318  		return true
   319  	}
   320  	// match: (Div32 <t> x (Const32 [c]))
   321  	// cond: smagicOK32(c) && config.RegSize == 4 && smagic32(c).M&1 == 0
   322  	// result: (Sub32 <t> (Rsh32x64 <t> (Hmul32 <t> x (Const32 <typ.UInt32> [int32(smagic32(c).M/2)])) (Const64 <typ.UInt64> [smagic32(c).S - 1])) (Rsh32x64 <t> x (Const64 <typ.UInt64> [31])))
   323  	for {
   324  		t := v.Type
   325  		x := v_0
   326  		if v_1.Op != ssaop.OpConst32 {
   327  			break
   328  		}
   329  		c := ssa.AuxIntToInt32(v_1.AuxInt)
   330  		if !(smagicOK32(c) && config.RegSize == 4 && smagic32(c).M&1 == 0) {
   331  			break
   332  		}
   333  		v.Reset(ssaop.OpSub32)
   334  		v.Type = t
   335  		v0 := b.NewValue0(v.Pos, ssaop.OpRsh32x64, t)
   336  		v1 := b.NewValue0(v.Pos, ssaop.OpHmul32, t)
   337  		v2 := b.NewValue0(v.Pos, ssaop.OpConst32, typ.UInt32)
   338  		v2.AuxInt = ssa.Int32ToAuxInt(int32(smagic32(c).M / 2))
   339  		v1.AddArg2(x, v2)
   340  		v3 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   341  		v3.AuxInt = ssa.Int64ToAuxInt(smagic32(c).S - 1)
   342  		v0.AddArg2(v1, v3)
   343  		v4 := b.NewValue0(v.Pos, ssaop.OpRsh32x64, t)
   344  		v5 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   345  		v5.AuxInt = ssa.Int64ToAuxInt(31)
   346  		v4.AddArg2(x, v5)
   347  		v.AddArg2(v0, v4)
   348  		return true
   349  	}
   350  	// match: (Div32 <t> x (Const32 [c]))
   351  	// cond: smagicOK32(c) && config.RegSize == 4 && smagic32(c).M&1 != 0
   352  	// result: (Sub32 <t> (Rsh32x64 <t> (Add32 <t> x (Hmul32 <t> x (Const32 <typ.UInt32> [int32(smagic32(c).M)]))) (Const64 <typ.UInt64> [smagic32(c).S])) (Rsh32x64 <t> x (Const64 <typ.UInt64> [31])))
   353  	for {
   354  		t := v.Type
   355  		x := v_0
   356  		if v_1.Op != ssaop.OpConst32 {
   357  			break
   358  		}
   359  		c := ssa.AuxIntToInt32(v_1.AuxInt)
   360  		if !(smagicOK32(c) && config.RegSize == 4 && smagic32(c).M&1 != 0) {
   361  			break
   362  		}
   363  		v.Reset(ssaop.OpSub32)
   364  		v.Type = t
   365  		v0 := b.NewValue0(v.Pos, ssaop.OpRsh32x64, t)
   366  		v1 := b.NewValue0(v.Pos, ssaop.OpAdd32, t)
   367  		v2 := b.NewValue0(v.Pos, ssaop.OpHmul32, t)
   368  		v3 := b.NewValue0(v.Pos, ssaop.OpConst32, typ.UInt32)
   369  		v3.AuxInt = ssa.Int32ToAuxInt(int32(smagic32(c).M))
   370  		v2.AddArg2(x, v3)
   371  		v1.AddArg2(x, v2)
   372  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   373  		v4.AuxInt = ssa.Int64ToAuxInt(smagic32(c).S)
   374  		v0.AddArg2(v1, v4)
   375  		v5 := b.NewValue0(v.Pos, ssaop.OpRsh32x64, t)
   376  		v6 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   377  		v6.AuxInt = ssa.Int64ToAuxInt(31)
   378  		v5.AddArg2(x, v6)
   379  		v.AddArg2(v0, v5)
   380  		return true
   381  	}
   382  	return false
   383  }
   384  func rewriteValue_OpDiv32u(v *ssa.Value) bool {
   385  	v_1 := v.Args[1]
   386  	v_0 := v.Args[0]
   387  	b := v.Block
   388  	config := b.Func.Config
   389  	typ := &b.Func.Config.Types
   390  	// match: (Div32u <t> x (Const32 [c]))
   391  	// cond: t.IsSigned() && smagicOK32(c) && config.RegSize == 8
   392  	// result: (Rsh64Ux64 <t> (Mul64 <typ.UInt64> (SignExt32to64 x) (Const64 <typ.UInt64> [int64(smagic32(c).M)])) (Const64 <typ.UInt64> [32 + smagic32(c).S]))
   393  	for {
   394  		t := v.Type
   395  		x := v_0
   396  		if v_1.Op != ssaop.OpConst32 {
   397  			break
   398  		}
   399  		c := ssa.AuxIntToInt32(v_1.AuxInt)
   400  		if !(t.IsSigned() && smagicOK32(c) && config.RegSize == 8) {
   401  			break
   402  		}
   403  		v.Reset(ssaop.OpRsh64Ux64)
   404  		v.Type = t
   405  		v0 := b.NewValue0(v.Pos, ssaop.OpMul64, typ.UInt64)
   406  		v1 := b.NewValue0(v.Pos, ssaop.OpSignExt32to64, typ.Int64)
   407  		v1.AddArg(x)
   408  		v2 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   409  		v2.AuxInt = ssa.Int64ToAuxInt(int64(smagic32(c).M))
   410  		v0.AddArg2(v1, v2)
   411  		v3 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   412  		v3.AuxInt = ssa.Int64ToAuxInt(32 + smagic32(c).S)
   413  		v.AddArg2(v0, v3)
   414  		return true
   415  	}
   416  	// match: (Div32u <t> x (Const32 [c]))
   417  	// cond: t.IsSigned() && smagicOK32(c) && config.RegSize == 4
   418  	// result: (Rsh32Ux64 <t> (Hmul32u <typ.UInt32> x (Const32 <typ.UInt32> [int32(smagic32(c).M)])) (Const64 <typ.UInt64> [smagic32(c).S]))
   419  	for {
   420  		t := v.Type
   421  		x := v_0
   422  		if v_1.Op != ssaop.OpConst32 {
   423  			break
   424  		}
   425  		c := ssa.AuxIntToInt32(v_1.AuxInt)
   426  		if !(t.IsSigned() && smagicOK32(c) && config.RegSize == 4) {
   427  			break
   428  		}
   429  		v.Reset(ssaop.OpRsh32Ux64)
   430  		v.Type = t
   431  		v0 := b.NewValue0(v.Pos, ssaop.OpHmul32u, typ.UInt32)
   432  		v1 := b.NewValue0(v.Pos, ssaop.OpConst32, typ.UInt32)
   433  		v1.AuxInt = ssa.Int32ToAuxInt(int32(smagic32(c).M))
   434  		v0.AddArg2(x, v1)
   435  		v2 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   436  		v2.AuxInt = ssa.Int64ToAuxInt(smagic32(c).S)
   437  		v.AddArg2(v0, v2)
   438  		return true
   439  	}
   440  	// match: (Div32u <t> x (Const32 [c]))
   441  	// cond: umagicOK32(c) && umagic32(c).M&1 == 0 && config.RegSize == 8
   442  	// result: (Trunc64to32 <t> (Rsh64Ux64 <typ.UInt64> (Mul64 <typ.UInt64> (ZeroExt32to64 x) (Const64 <typ.UInt64> [int64(1<<31 + umagic32(c).M/2)])) (Const64 <typ.UInt64> [32 + umagic32(c).S - 1])))
   443  	for {
   444  		t := v.Type
   445  		x := v_0
   446  		if v_1.Op != ssaop.OpConst32 {
   447  			break
   448  		}
   449  		c := ssa.AuxIntToInt32(v_1.AuxInt)
   450  		if !(umagicOK32(c) && umagic32(c).M&1 == 0 && config.RegSize == 8) {
   451  			break
   452  		}
   453  		v.Reset(ssaop.OpTrunc64to32)
   454  		v.Type = t
   455  		v0 := b.NewValue0(v.Pos, ssaop.OpRsh64Ux64, typ.UInt64)
   456  		v1 := b.NewValue0(v.Pos, ssaop.OpMul64, typ.UInt64)
   457  		v2 := b.NewValue0(v.Pos, ssaop.OpZeroExt32to64, typ.UInt64)
   458  		v2.AddArg(x)
   459  		v3 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   460  		v3.AuxInt = ssa.Int64ToAuxInt(int64(1<<31 + umagic32(c).M/2))
   461  		v1.AddArg2(v2, v3)
   462  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   463  		v4.AuxInt = ssa.Int64ToAuxInt(32 + umagic32(c).S - 1)
   464  		v0.AddArg2(v1, v4)
   465  		v.AddArg(v0)
   466  		return true
   467  	}
   468  	// match: (Div32u <t> x (Const32 [c]))
   469  	// cond: umagicOK32(c) && umagic32(c).M&1 == 0 && config.RegSize == 4
   470  	// result: (Rsh32Ux64 <t> (Hmul32u <typ.UInt32> x (Const32 <typ.UInt32> [int32(1<<31 + umagic32(c).M/2)])) (Const64 <typ.UInt64> [umagic32(c).S - 1]))
   471  	for {
   472  		t := v.Type
   473  		x := v_0
   474  		if v_1.Op != ssaop.OpConst32 {
   475  			break
   476  		}
   477  		c := ssa.AuxIntToInt32(v_1.AuxInt)
   478  		if !(umagicOK32(c) && umagic32(c).M&1 == 0 && config.RegSize == 4) {
   479  			break
   480  		}
   481  		v.Reset(ssaop.OpRsh32Ux64)
   482  		v.Type = t
   483  		v0 := b.NewValue0(v.Pos, ssaop.OpHmul32u, typ.UInt32)
   484  		v1 := b.NewValue0(v.Pos, ssaop.OpConst32, typ.UInt32)
   485  		v1.AuxInt = ssa.Int32ToAuxInt(int32(1<<31 + umagic32(c).M/2))
   486  		v0.AddArg2(x, v1)
   487  		v2 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   488  		v2.AuxInt = ssa.Int64ToAuxInt(umagic32(c).S - 1)
   489  		v.AddArg2(v0, v2)
   490  		return true
   491  	}
   492  	// match: (Div32u <t> x (Const32 [c]))
   493  	// cond: umagicOK32(c) && config.RegSize == 8 && config.Ctxt.Arch.Name != "wasm" && umagic32(c).M&1 != 0
   494  	// result: (Trunc64to32 <t> (Hmul64u <typ.UInt64> (ZeroExt32to64 x) (Const64 <typ.UInt64> [int64(umagic32PreShifted(c))])))
   495  	for {
   496  		t := v.Type
   497  		x := v_0
   498  		if v_1.Op != ssaop.OpConst32 {
   499  			break
   500  		}
   501  		c := ssa.AuxIntToInt32(v_1.AuxInt)
   502  		if !(umagicOK32(c) && config.RegSize == 8 && config.Ctxt.Arch.Name != "wasm" && umagic32(c).M&1 != 0) {
   503  			break
   504  		}
   505  		v.Reset(ssaop.OpTrunc64to32)
   506  		v.Type = t
   507  		v0 := b.NewValue0(v.Pos, ssaop.OpHmul64u, typ.UInt64)
   508  		v1 := b.NewValue0(v.Pos, ssaop.OpZeroExt32to64, typ.UInt64)
   509  		v1.AddArg(x)
   510  		v2 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   511  		v2.AuxInt = ssa.Int64ToAuxInt(int64(umagic32PreShifted(c)))
   512  		v0.AddArg2(v1, v2)
   513  		v.AddArg(v0)
   514  		return true
   515  	}
   516  	// match: (Div32u <t> x (Const32 [c]))
   517  	// cond: umagicOK32(c) && config.RegSize == 8 && c&1 == 0
   518  	// result: (Trunc64to32 <t> (Rsh64Ux64 <typ.UInt64> (Mul64 <typ.UInt64> (Rsh64Ux64 <typ.UInt64> (ZeroExt32to64 x) (Const64 <typ.UInt64> [1])) (Const64 <typ.UInt64> [int64(1<<31 + (umagic32(c).M+1)/2)])) (Const64 <typ.UInt64> [32 + umagic32(c).S - 2])))
   519  	for {
   520  		t := v.Type
   521  		x := v_0
   522  		if v_1.Op != ssaop.OpConst32 {
   523  			break
   524  		}
   525  		c := ssa.AuxIntToInt32(v_1.AuxInt)
   526  		if !(umagicOK32(c) && config.RegSize == 8 && c&1 == 0) {
   527  			break
   528  		}
   529  		v.Reset(ssaop.OpTrunc64to32)
   530  		v.Type = t
   531  		v0 := b.NewValue0(v.Pos, ssaop.OpRsh64Ux64, typ.UInt64)
   532  		v1 := b.NewValue0(v.Pos, ssaop.OpMul64, typ.UInt64)
   533  		v2 := b.NewValue0(v.Pos, ssaop.OpRsh64Ux64, typ.UInt64)
   534  		v3 := b.NewValue0(v.Pos, ssaop.OpZeroExt32to64, typ.UInt64)
   535  		v3.AddArg(x)
   536  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   537  		v4.AuxInt = ssa.Int64ToAuxInt(1)
   538  		v2.AddArg2(v3, v4)
   539  		v5 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   540  		v5.AuxInt = ssa.Int64ToAuxInt(int64(1<<31 + (umagic32(c).M+1)/2))
   541  		v1.AddArg2(v2, v5)
   542  		v6 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   543  		v6.AuxInt = ssa.Int64ToAuxInt(32 + umagic32(c).S - 2)
   544  		v0.AddArg2(v1, v6)
   545  		v.AddArg(v0)
   546  		return true
   547  	}
   548  	// match: (Div32u <t> x (Const32 [c]))
   549  	// cond: umagicOK32(c) && config.RegSize == 4 && c&1 == 0
   550  	// result: (Rsh32Ux64 <t> (Hmul32u <typ.UInt32> (Rsh32Ux64 <typ.UInt32> x (Const64 <typ.UInt64> [1])) (Const32 <typ.UInt32> [int32(1<<31 + (umagic32(c).M+1)/2)])) (Const64 <typ.UInt64> [umagic32(c).S - 2]))
   551  	for {
   552  		t := v.Type
   553  		x := v_0
   554  		if v_1.Op != ssaop.OpConst32 {
   555  			break
   556  		}
   557  		c := ssa.AuxIntToInt32(v_1.AuxInt)
   558  		if !(umagicOK32(c) && config.RegSize == 4 && c&1 == 0) {
   559  			break
   560  		}
   561  		v.Reset(ssaop.OpRsh32Ux64)
   562  		v.Type = t
   563  		v0 := b.NewValue0(v.Pos, ssaop.OpHmul32u, typ.UInt32)
   564  		v1 := b.NewValue0(v.Pos, ssaop.OpRsh32Ux64, typ.UInt32)
   565  		v2 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   566  		v2.AuxInt = ssa.Int64ToAuxInt(1)
   567  		v1.AddArg2(x, v2)
   568  		v3 := b.NewValue0(v.Pos, ssaop.OpConst32, typ.UInt32)
   569  		v3.AuxInt = ssa.Int32ToAuxInt(int32(1<<31 + (umagic32(c).M+1)/2))
   570  		v0.AddArg2(v1, v3)
   571  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   572  		v4.AuxInt = ssa.Int64ToAuxInt(umagic32(c).S - 2)
   573  		v.AddArg2(v0, v4)
   574  		return true
   575  	}
   576  	// match: (Div32u <t> x (Const32 [c]))
   577  	// cond: umagicOK32(c) && config.RegSize == 8 && config.Ctxt.Arch.Name == "wasm"
   578  	// result: (Trunc64to32 <t> (Rsh64Ux64 <typ.UInt64> (Avg64u (Lsh64x64 <typ.UInt64> (ZeroExt32to64 x) (Const64 <typ.UInt64> [32])) (Mul64 <typ.UInt64> (ZeroExt32to64 x) (Const64 <typ.UInt64> [int64(umagic32(c).M)]))) (Const64 <typ.UInt64> [32 + umagic32(c).S - 1])))
   579  	for {
   580  		t := v.Type
   581  		x := v_0
   582  		if v_1.Op != ssaop.OpConst32 {
   583  			break
   584  		}
   585  		c := ssa.AuxIntToInt32(v_1.AuxInt)
   586  		if !(umagicOK32(c) && config.RegSize == 8 && config.Ctxt.Arch.Name == "wasm") {
   587  			break
   588  		}
   589  		v.Reset(ssaop.OpTrunc64to32)
   590  		v.Type = t
   591  		v0 := b.NewValue0(v.Pos, ssaop.OpRsh64Ux64, typ.UInt64)
   592  		v1 := b.NewValue0(v.Pos, ssaop.OpAvg64u, typ.UInt64)
   593  		v2 := b.NewValue0(v.Pos, ssaop.OpLsh64x64, typ.UInt64)
   594  		v3 := b.NewValue0(v.Pos, ssaop.OpZeroExt32to64, typ.UInt64)
   595  		v3.AddArg(x)
   596  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   597  		v4.AuxInt = ssa.Int64ToAuxInt(32)
   598  		v2.AddArg2(v3, v4)
   599  		v5 := b.NewValue0(v.Pos, ssaop.OpMul64, typ.UInt64)
   600  		v6 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   601  		v6.AuxInt = ssa.Int64ToAuxInt(int64(umagic32(c).M))
   602  		v5.AddArg2(v3, v6)
   603  		v1.AddArg2(v2, v5)
   604  		v7 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   605  		v7.AuxInt = ssa.Int64ToAuxInt(32 + umagic32(c).S - 1)
   606  		v0.AddArg2(v1, v7)
   607  		v.AddArg(v0)
   608  		return true
   609  	}
   610  	// match: (Div32u <t> x (Const32 [c]))
   611  	// cond: umagicOK32(c) && config.RegSize == 4
   612  	// result: (Rsh32Ux64 <t> (Avg32u x (Hmul32u <typ.UInt32> x (Const32 <typ.UInt32> [int32(umagic32(c).M)]))) (Const64 <typ.UInt64> [umagic32(c).S - 1]))
   613  	for {
   614  		t := v.Type
   615  		x := v_0
   616  		if v_1.Op != ssaop.OpConst32 {
   617  			break
   618  		}
   619  		c := ssa.AuxIntToInt32(v_1.AuxInt)
   620  		if !(umagicOK32(c) && config.RegSize == 4) {
   621  			break
   622  		}
   623  		v.Reset(ssaop.OpRsh32Ux64)
   624  		v.Type = t
   625  		v0 := b.NewValue0(v.Pos, ssaop.OpAvg32u, typ.UInt32)
   626  		v1 := b.NewValue0(v.Pos, ssaop.OpHmul32u, typ.UInt32)
   627  		v2 := b.NewValue0(v.Pos, ssaop.OpConst32, typ.UInt32)
   628  		v2.AuxInt = ssa.Int32ToAuxInt(int32(umagic32(c).M))
   629  		v1.AddArg2(x, v2)
   630  		v0.AddArg2(x, v1)
   631  		v3 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   632  		v3.AuxInt = ssa.Int64ToAuxInt(umagic32(c).S - 1)
   633  		v.AddArg2(v0, v3)
   634  		return true
   635  	}
   636  	return false
   637  }
   638  func rewriteValue_OpDiv64(v *ssa.Value) bool {
   639  	v_1 := v.Args[1]
   640  	v_0 := v.Args[0]
   641  	b := v.Block
   642  	typ := &b.Func.Config.Types
   643  	// match: (Div64 <t> n (Const64 [c]))
   644  	// cond: ssa.IsPowerOfTwo(c)
   645  	// result: (Rsh64x64 (Add64 <t> n (Rsh64Ux64 <t> (Rsh64x64 <t> n (Const64 <typ.UInt64> [63])) (Const64 <typ.UInt64> [int64(64-ssa.Log64(c))]))) (Const64 <typ.UInt64> [int64(ssa.Log64(c))]))
   646  	for {
   647  		t := v.Type
   648  		n := v_0
   649  		if v_1.Op != ssaop.OpConst64 {
   650  			break
   651  		}
   652  		c := ssa.AuxIntToInt64(v_1.AuxInt)
   653  		if !(ssa.IsPowerOfTwo(c)) {
   654  			break
   655  		}
   656  		v.Reset(ssaop.OpRsh64x64)
   657  		v0 := b.NewValue0(v.Pos, ssaop.OpAdd64, t)
   658  		v1 := b.NewValue0(v.Pos, ssaop.OpRsh64Ux64, t)
   659  		v2 := b.NewValue0(v.Pos, ssaop.OpRsh64x64, t)
   660  		v3 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   661  		v3.AuxInt = ssa.Int64ToAuxInt(63)
   662  		v2.AddArg2(n, v3)
   663  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   664  		v4.AuxInt = ssa.Int64ToAuxInt(int64(64 - ssa.Log64(c)))
   665  		v1.AddArg2(v2, v4)
   666  		v0.AddArg2(n, v1)
   667  		v5 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   668  		v5.AuxInt = ssa.Int64ToAuxInt(int64(ssa.Log64(c)))
   669  		v.AddArg2(v0, v5)
   670  		return true
   671  	}
   672  	// match: (Div64 <t> x (Const64 [c]))
   673  	// cond: smagicOK64(c) && smagic64(c).M&1 == 0
   674  	// result: (Sub64 <t> (Rsh64x64 <t> (Hmul64 <t> x (Const64 <typ.UInt64> [int64(smagic64(c).M/2)])) (Const64 <typ.UInt64> [smagic64(c).S - 1])) (Rsh64x64 <t> x (Const64 <typ.UInt64> [63])))
   675  	for {
   676  		t := v.Type
   677  		x := v_0
   678  		if v_1.Op != ssaop.OpConst64 {
   679  			break
   680  		}
   681  		c := ssa.AuxIntToInt64(v_1.AuxInt)
   682  		if !(smagicOK64(c) && smagic64(c).M&1 == 0) {
   683  			break
   684  		}
   685  		v.Reset(ssaop.OpSub64)
   686  		v.Type = t
   687  		v0 := b.NewValue0(v.Pos, ssaop.OpRsh64x64, t)
   688  		v1 := b.NewValue0(v.Pos, ssaop.OpHmul64, t)
   689  		v2 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   690  		v2.AuxInt = ssa.Int64ToAuxInt(int64(smagic64(c).M / 2))
   691  		v1.AddArg2(x, v2)
   692  		v3 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   693  		v3.AuxInt = ssa.Int64ToAuxInt(smagic64(c).S - 1)
   694  		v0.AddArg2(v1, v3)
   695  		v4 := b.NewValue0(v.Pos, ssaop.OpRsh64x64, t)
   696  		v5 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   697  		v5.AuxInt = ssa.Int64ToAuxInt(63)
   698  		v4.AddArg2(x, v5)
   699  		v.AddArg2(v0, v4)
   700  		return true
   701  	}
   702  	// match: (Div64 <t> x (Const64 [c]))
   703  	// cond: smagicOK64(c) && smagic64(c).M&1 != 0
   704  	// result: (Sub64 <t> (Rsh64x64 <t> (Add64 <t> x (Hmul64 <t> x (Const64 <typ.UInt64> [int64(smagic64(c).M)]))) (Const64 <typ.UInt64> [smagic64(c).S])) (Rsh64x64 <t> x (Const64 <typ.UInt64> [63])))
   705  	for {
   706  		t := v.Type
   707  		x := v_0
   708  		if v_1.Op != ssaop.OpConst64 {
   709  			break
   710  		}
   711  		c := ssa.AuxIntToInt64(v_1.AuxInt)
   712  		if !(smagicOK64(c) && smagic64(c).M&1 != 0) {
   713  			break
   714  		}
   715  		v.Reset(ssaop.OpSub64)
   716  		v.Type = t
   717  		v0 := b.NewValue0(v.Pos, ssaop.OpRsh64x64, t)
   718  		v1 := b.NewValue0(v.Pos, ssaop.OpAdd64, t)
   719  		v2 := b.NewValue0(v.Pos, ssaop.OpHmul64, t)
   720  		v3 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   721  		v3.AuxInt = ssa.Int64ToAuxInt(int64(smagic64(c).M))
   722  		v2.AddArg2(x, v3)
   723  		v1.AddArg2(x, v2)
   724  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   725  		v4.AuxInt = ssa.Int64ToAuxInt(smagic64(c).S)
   726  		v0.AddArg2(v1, v4)
   727  		v5 := b.NewValue0(v.Pos, ssaop.OpRsh64x64, t)
   728  		v6 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   729  		v6.AuxInt = ssa.Int64ToAuxInt(63)
   730  		v5.AddArg2(x, v6)
   731  		v.AddArg2(v0, v5)
   732  		return true
   733  	}
   734  	return false
   735  }
   736  func rewriteValue_OpDiv64u(v *ssa.Value) bool {
   737  	v_1 := v.Args[1]
   738  	v_0 := v.Args[0]
   739  	b := v.Block
   740  	typ := &b.Func.Config.Types
   741  	// match: (Div64u <t> x (Const64 [c]))
   742  	// cond: t.IsSigned() && smagicOK64(c)
   743  	// result: (Rsh64Ux64 <t> (Hmul64u <typ.UInt64> x (Const64 <typ.UInt64> [int64(smagic64(c).M)])) (Const64 <typ.UInt64> [smagic64(c).S]))
   744  	for {
   745  		t := v.Type
   746  		x := v_0
   747  		if v_1.Op != ssaop.OpConst64 {
   748  			break
   749  		}
   750  		c := ssa.AuxIntToInt64(v_1.AuxInt)
   751  		if !(t.IsSigned() && smagicOK64(c)) {
   752  			break
   753  		}
   754  		v.Reset(ssaop.OpRsh64Ux64)
   755  		v.Type = t
   756  		v0 := b.NewValue0(v.Pos, ssaop.OpHmul64u, typ.UInt64)
   757  		v1 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   758  		v1.AuxInt = ssa.Int64ToAuxInt(int64(smagic64(c).M))
   759  		v0.AddArg2(x, v1)
   760  		v2 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   761  		v2.AuxInt = ssa.Int64ToAuxInt(smagic64(c).S)
   762  		v.AddArg2(v0, v2)
   763  		return true
   764  	}
   765  	// match: (Div64u <t> x (Const64 [c]))
   766  	// cond: umagicOK64(c) && umagic64(c).M&1 == 0
   767  	// result: (Rsh64Ux64 <t> (Hmul64u <typ.UInt64> x (Const64 <typ.UInt64> [int64(1<<63 + umagic64(c).M/2)])) (Const64 <typ.UInt64> [umagic64(c).S - 1]))
   768  	for {
   769  		t := v.Type
   770  		x := v_0
   771  		if v_1.Op != ssaop.OpConst64 {
   772  			break
   773  		}
   774  		c := ssa.AuxIntToInt64(v_1.AuxInt)
   775  		if !(umagicOK64(c) && umagic64(c).M&1 == 0) {
   776  			break
   777  		}
   778  		v.Reset(ssaop.OpRsh64Ux64)
   779  		v.Type = t
   780  		v0 := b.NewValue0(v.Pos, ssaop.OpHmul64u, typ.UInt64)
   781  		v1 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   782  		v1.AuxInt = ssa.Int64ToAuxInt(int64(1<<63 + umagic64(c).M/2))
   783  		v0.AddArg2(x, v1)
   784  		v2 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   785  		v2.AuxInt = ssa.Int64ToAuxInt(umagic64(c).S - 1)
   786  		v.AddArg2(v0, v2)
   787  		return true
   788  	}
   789  	// match: (Div64u <t> x (Const64 [c]))
   790  	// cond: umagicOK64(c) && c&1 == 0
   791  	// result: (Rsh64Ux64 <t> (Hmul64u <typ.UInt64> (Rsh64Ux64 <typ.UInt64> x (Const64 <typ.UInt64> [1])) (Const64 <typ.UInt64> [int64(1<<63 + (umagic64(c).M+1)/2)])) (Const64 <typ.UInt64> [umagic64(c).S - 2]))
   792  	for {
   793  		t := v.Type
   794  		x := v_0
   795  		if v_1.Op != ssaop.OpConst64 {
   796  			break
   797  		}
   798  		c := ssa.AuxIntToInt64(v_1.AuxInt)
   799  		if !(umagicOK64(c) && c&1 == 0) {
   800  			break
   801  		}
   802  		v.Reset(ssaop.OpRsh64Ux64)
   803  		v.Type = t
   804  		v0 := b.NewValue0(v.Pos, ssaop.OpHmul64u, typ.UInt64)
   805  		v1 := b.NewValue0(v.Pos, ssaop.OpRsh64Ux64, typ.UInt64)
   806  		v2 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   807  		v2.AuxInt = ssa.Int64ToAuxInt(1)
   808  		v1.AddArg2(x, v2)
   809  		v3 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   810  		v3.AuxInt = ssa.Int64ToAuxInt(int64(1<<63 + (umagic64(c).M+1)/2))
   811  		v0.AddArg2(v1, v3)
   812  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   813  		v4.AuxInt = ssa.Int64ToAuxInt(umagic64(c).S - 2)
   814  		v.AddArg2(v0, v4)
   815  		return true
   816  	}
   817  	// match: (Div64u <t> x (Const64 [c]))
   818  	// cond: umagicOK64(c)
   819  	// result: (Rsh64Ux64 <t> (Avg64u x (Hmul64u <typ.UInt64> x (Const64 <typ.UInt64> [int64(umagic64(c).M)]))) (Const64 <typ.UInt64> [umagic64(c).S - 1]))
   820  	for {
   821  		t := v.Type
   822  		x := v_0
   823  		if v_1.Op != ssaop.OpConst64 {
   824  			break
   825  		}
   826  		c := ssa.AuxIntToInt64(v_1.AuxInt)
   827  		if !(umagicOK64(c)) {
   828  			break
   829  		}
   830  		v.Reset(ssaop.OpRsh64Ux64)
   831  		v.Type = t
   832  		v0 := b.NewValue0(v.Pos, ssaop.OpAvg64u, typ.UInt64)
   833  		v1 := b.NewValue0(v.Pos, ssaop.OpHmul64u, typ.UInt64)
   834  		v2 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   835  		v2.AuxInt = ssa.Int64ToAuxInt(int64(umagic64(c).M))
   836  		v1.AddArg2(x, v2)
   837  		v0.AddArg2(x, v1)
   838  		v3 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   839  		v3.AuxInt = ssa.Int64ToAuxInt(umagic64(c).S - 1)
   840  		v.AddArg2(v0, v3)
   841  		return true
   842  	}
   843  	return false
   844  }
   845  func rewriteValue_OpDiv8(v *ssa.Value) bool {
   846  	v_1 := v.Args[1]
   847  	v_0 := v.Args[0]
   848  	b := v.Block
   849  	typ := &b.Func.Config.Types
   850  	// match: (Div8 <t> n (Const8 [c]))
   851  	// cond: ssa.IsPowerOfTwo(c)
   852  	// result: (Rsh8x64 (Add8 <t> n (Rsh8Ux64 <t> (Rsh8x64 <t> n (Const64 <typ.UInt64> [ 7])) (Const64 <typ.UInt64> [int64( 8-log8(c))]))) (Const64 <typ.UInt64> [int64(log8(c))]))
   853  	for {
   854  		t := v.Type
   855  		n := v_0
   856  		if v_1.Op != ssaop.OpConst8 {
   857  			break
   858  		}
   859  		c := ssa.AuxIntToInt8(v_1.AuxInt)
   860  		if !(ssa.IsPowerOfTwo(c)) {
   861  			break
   862  		}
   863  		v.Reset(ssaop.OpRsh8x64)
   864  		v0 := b.NewValue0(v.Pos, ssaop.OpAdd8, t)
   865  		v1 := b.NewValue0(v.Pos, ssaop.OpRsh8Ux64, t)
   866  		v2 := b.NewValue0(v.Pos, ssaop.OpRsh8x64, t)
   867  		v3 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   868  		v3.AuxInt = ssa.Int64ToAuxInt(7)
   869  		v2.AddArg2(n, v3)
   870  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   871  		v4.AuxInt = ssa.Int64ToAuxInt(int64(8 - log8(c)))
   872  		v1.AddArg2(v2, v4)
   873  		v0.AddArg2(n, v1)
   874  		v5 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   875  		v5.AuxInt = ssa.Int64ToAuxInt(int64(log8(c)))
   876  		v.AddArg2(v0, v5)
   877  		return true
   878  	}
   879  	// match: (Div8 <t> x (Const8 [c]))
   880  	// cond: smagicOK8(c)
   881  	// result: (Sub8 <t> (Rsh32x64 <t> (Mul32 <typ.UInt32> (SignExt8to32 x) (Const32 <typ.UInt32> [int32(smagic8(c).M)])) (Const64 <typ.UInt64> [8 + smagic8(c).S])) (Rsh32x64 <t> (SignExt8to32 x) (Const64 <typ.UInt64> [31])))
   882  	for {
   883  		t := v.Type
   884  		x := v_0
   885  		if v_1.Op != ssaop.OpConst8 {
   886  			break
   887  		}
   888  		c := ssa.AuxIntToInt8(v_1.AuxInt)
   889  		if !(smagicOK8(c)) {
   890  			break
   891  		}
   892  		v.Reset(ssaop.OpSub8)
   893  		v.Type = t
   894  		v0 := b.NewValue0(v.Pos, ssaop.OpRsh32x64, t)
   895  		v1 := b.NewValue0(v.Pos, ssaop.OpMul32, typ.UInt32)
   896  		v2 := b.NewValue0(v.Pos, ssaop.OpSignExt8to32, typ.Int32)
   897  		v2.AddArg(x)
   898  		v3 := b.NewValue0(v.Pos, ssaop.OpConst32, typ.UInt32)
   899  		v3.AuxInt = ssa.Int32ToAuxInt(int32(smagic8(c).M))
   900  		v1.AddArg2(v2, v3)
   901  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   902  		v4.AuxInt = ssa.Int64ToAuxInt(8 + smagic8(c).S)
   903  		v0.AddArg2(v1, v4)
   904  		v5 := b.NewValue0(v.Pos, ssaop.OpRsh32x64, t)
   905  		v6 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   906  		v6.AuxInt = ssa.Int64ToAuxInt(31)
   907  		v5.AddArg2(v2, v6)
   908  		v.AddArg2(v0, v5)
   909  		return true
   910  	}
   911  	return false
   912  }
   913  func rewriteValue_OpDiv8u(v *ssa.Value) bool {
   914  	v_1 := v.Args[1]
   915  	v_0 := v.Args[0]
   916  	b := v.Block
   917  	typ := &b.Func.Config.Types
   918  	// match: (Div8u <t> x (Const8 [c]))
   919  	// cond: umagicOK8(c)
   920  	// result: (Trunc32to8 <t> (Rsh32Ux64 <typ.UInt32> (Mul32 <typ.UInt32> (ZeroExt8to32 x) (Const32 <typ.UInt32> [int32(1<<8 + umagic8(c).M)])) (Const64 <typ.UInt64> [8 + umagic8(c).S])))
   921  	for {
   922  		t := v.Type
   923  		x := v_0
   924  		if v_1.Op != ssaop.OpConst8 {
   925  			break
   926  		}
   927  		c := ssa.AuxIntToInt8(v_1.AuxInt)
   928  		if !(umagicOK8(c)) {
   929  			break
   930  		}
   931  		v.Reset(ssaop.OpTrunc32to8)
   932  		v.Type = t
   933  		v0 := b.NewValue0(v.Pos, ssaop.OpRsh32Ux64, typ.UInt32)
   934  		v1 := b.NewValue0(v.Pos, ssaop.OpMul32, typ.UInt32)
   935  		v2 := b.NewValue0(v.Pos, ssaop.OpZeroExt8to32, typ.UInt32)
   936  		v2.AddArg(x)
   937  		v3 := b.NewValue0(v.Pos, ssaop.OpConst32, typ.UInt32)
   938  		v3.AuxInt = ssa.Int32ToAuxInt(int32(1<<8 + umagic8(c).M))
   939  		v1.AddArg2(v2, v3)
   940  		v4 := b.NewValue0(v.Pos, ssaop.OpConst64, typ.UInt64)
   941  		v4.AuxInt = ssa.Int64ToAuxInt(8 + umagic8(c).S)
   942  		v0.AddArg2(v1, v4)
   943  		v.AddArg(v0)
   944  		return true
   945  	}
   946  	return false
   947  }
   948  func RewriteBlock(b *ssa.Block) bool {
   949  	return false
   950  }
   951  

View as plain text