1
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
35
36
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
64
65
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
104
105
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
130
131
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
158
159
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
186
187
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
218
219
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
260
261
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
289
290
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
321
322
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
351
352
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
391
392
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
417
418
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
441
442
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
469
470
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
493
494
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
517
518
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
549
550
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
577
578
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
611
612
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
644
645
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
673
674
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
703
704
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
742
743
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
766
767
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
790
791
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
818
819
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
851
852
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
880
881
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
919
920
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