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