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) {
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) {
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) {
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) {
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) {
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) {
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) {
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) {
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 typ := &b.Func.Config.Types
616
617
618
619 for {
620 t := v.Type
621 n := v_0
622 if v_1.Op != OpConst64 {
623 break
624 }
625 c := auxIntToInt64(v_1.AuxInt)
626 if !(isPowerOfTwo(c)) {
627 break
628 }
629 v.reset(OpRsh64x64)
630 v0 := b.NewValue0(v.Pos, OpAdd64, t)
631 v1 := b.NewValue0(v.Pos, OpRsh64Ux64, t)
632 v2 := b.NewValue0(v.Pos, OpRsh64x64, t)
633 v3 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
634 v3.AuxInt = int64ToAuxInt(63)
635 v2.AddArg2(n, v3)
636 v4 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
637 v4.AuxInt = int64ToAuxInt(int64(64 - log64(c)))
638 v1.AddArg2(v2, v4)
639 v0.AddArg2(n, v1)
640 v5 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
641 v5.AuxInt = int64ToAuxInt(int64(log64(c)))
642 v.AddArg2(v0, v5)
643 return true
644 }
645
646
647
648 for {
649 t := v.Type
650 x := v_0
651 if v_1.Op != OpConst64 {
652 break
653 }
654 c := auxIntToInt64(v_1.AuxInt)
655 if !(smagicOK64(c) && smagic64(c).m&1 == 0) {
656 break
657 }
658 v.reset(OpSub64)
659 v.Type = t
660 v0 := b.NewValue0(v.Pos, OpRsh64x64, t)
661 v1 := b.NewValue0(v.Pos, OpHmul64, t)
662 v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
663 v2.AuxInt = int64ToAuxInt(int64(smagic64(c).m / 2))
664 v1.AddArg2(x, v2)
665 v3 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
666 v3.AuxInt = int64ToAuxInt(smagic64(c).s - 1)
667 v0.AddArg2(v1, v3)
668 v4 := b.NewValue0(v.Pos, OpRsh64x64, t)
669 v5 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
670 v5.AuxInt = int64ToAuxInt(63)
671 v4.AddArg2(x, v5)
672 v.AddArg2(v0, v4)
673 return true
674 }
675
676
677
678 for {
679 t := v.Type
680 x := v_0
681 if v_1.Op != OpConst64 {
682 break
683 }
684 c := auxIntToInt64(v_1.AuxInt)
685 if !(smagicOK64(c) && smagic64(c).m&1 != 0) {
686 break
687 }
688 v.reset(OpSub64)
689 v.Type = t
690 v0 := b.NewValue0(v.Pos, OpRsh64x64, t)
691 v1 := b.NewValue0(v.Pos, OpAdd64, t)
692 v2 := b.NewValue0(v.Pos, OpHmul64, t)
693 v3 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
694 v3.AuxInt = int64ToAuxInt(int64(smagic64(c).m))
695 v2.AddArg2(x, v3)
696 v1.AddArg2(x, v2)
697 v4 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
698 v4.AuxInt = int64ToAuxInt(smagic64(c).s)
699 v0.AddArg2(v1, v4)
700 v5 := b.NewValue0(v.Pos, OpRsh64x64, t)
701 v6 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
702 v6.AuxInt = int64ToAuxInt(63)
703 v5.AddArg2(x, v6)
704 v.AddArg2(v0, v5)
705 return true
706 }
707 return false
708 }
709 func rewriteValuedivmod_OpDiv64u(v *Value) bool {
710 v_1 := v.Args[1]
711 v_0 := v.Args[0]
712 b := v.Block
713 typ := &b.Func.Config.Types
714
715
716
717 for {
718 t := v.Type
719 x := v_0
720 if v_1.Op != OpConst64 {
721 break
722 }
723 c := auxIntToInt64(v_1.AuxInt)
724 if !(t.IsSigned() && smagicOK64(c)) {
725 break
726 }
727 v.reset(OpRsh64Ux64)
728 v.Type = t
729 v0 := b.NewValue0(v.Pos, OpHmul64u, typ.UInt64)
730 v1 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
731 v1.AuxInt = int64ToAuxInt(int64(smagic64(c).m))
732 v0.AddArg2(x, v1)
733 v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
734 v2.AuxInt = int64ToAuxInt(smagic64(c).s)
735 v.AddArg2(v0, v2)
736 return true
737 }
738
739
740
741 for {
742 t := v.Type
743 x := v_0
744 if v_1.Op != OpConst64 {
745 break
746 }
747 c := auxIntToInt64(v_1.AuxInt)
748 if !(umagicOK64(c) && umagic64(c).m&1 == 0) {
749 break
750 }
751 v.reset(OpRsh64Ux64)
752 v.Type = t
753 v0 := b.NewValue0(v.Pos, OpHmul64u, typ.UInt64)
754 v1 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
755 v1.AuxInt = int64ToAuxInt(int64(1<<63 + umagic64(c).m/2))
756 v0.AddArg2(x, v1)
757 v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
758 v2.AuxInt = int64ToAuxInt(umagic64(c).s - 1)
759 v.AddArg2(v0, v2)
760 return true
761 }
762
763
764
765 for {
766 t := v.Type
767 x := v_0
768 if v_1.Op != OpConst64 {
769 break
770 }
771 c := auxIntToInt64(v_1.AuxInt)
772 if !(umagicOK64(c) && c&1 == 0) {
773 break
774 }
775 v.reset(OpRsh64Ux64)
776 v.Type = t
777 v0 := b.NewValue0(v.Pos, OpHmul64u, typ.UInt64)
778 v1 := b.NewValue0(v.Pos, OpRsh64Ux64, typ.UInt64)
779 v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
780 v2.AuxInt = int64ToAuxInt(1)
781 v1.AddArg2(x, v2)
782 v3 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
783 v3.AuxInt = int64ToAuxInt(int64(1<<63 + (umagic64(c).m+1)/2))
784 v0.AddArg2(v1, v3)
785 v4 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
786 v4.AuxInt = int64ToAuxInt(umagic64(c).s - 2)
787 v.AddArg2(v0, v4)
788 return true
789 }
790
791
792
793 for {
794 t := v.Type
795 x := v_0
796 if v_1.Op != OpConst64 {
797 break
798 }
799 c := auxIntToInt64(v_1.AuxInt)
800 if !(umagicOK64(c)) {
801 break
802 }
803 v.reset(OpRsh64Ux64)
804 v.Type = t
805 v0 := b.NewValue0(v.Pos, OpAvg64u, typ.UInt64)
806 v1 := b.NewValue0(v.Pos, OpHmul64u, typ.UInt64)
807 v2 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
808 v2.AuxInt = int64ToAuxInt(int64(umagic64(c).m))
809 v1.AddArg2(x, v2)
810 v0.AddArg2(x, v1)
811 v3 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
812 v3.AuxInt = int64ToAuxInt(umagic64(c).s - 1)
813 v.AddArg2(v0, v3)
814 return true
815 }
816 return false
817 }
818 func rewriteValuedivmod_OpDiv8(v *Value) bool {
819 v_1 := v.Args[1]
820 v_0 := v.Args[0]
821 b := v.Block
822 typ := &b.Func.Config.Types
823
824
825
826 for {
827 t := v.Type
828 n := v_0
829 if v_1.Op != OpConst8 {
830 break
831 }
832 c := auxIntToInt8(v_1.AuxInt)
833 if !(isPowerOfTwo(c)) {
834 break
835 }
836 v.reset(OpRsh8x64)
837 v0 := b.NewValue0(v.Pos, OpAdd8, t)
838 v1 := b.NewValue0(v.Pos, OpRsh8Ux64, t)
839 v2 := b.NewValue0(v.Pos, OpRsh8x64, t)
840 v3 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
841 v3.AuxInt = int64ToAuxInt(7)
842 v2.AddArg2(n, v3)
843 v4 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
844 v4.AuxInt = int64ToAuxInt(int64(8 - log8(c)))
845 v1.AddArg2(v2, v4)
846 v0.AddArg2(n, v1)
847 v5 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
848 v5.AuxInt = int64ToAuxInt(int64(log8(c)))
849 v.AddArg2(v0, v5)
850 return true
851 }
852
853
854
855 for {
856 t := v.Type
857 x := v_0
858 if v_1.Op != OpConst8 {
859 break
860 }
861 c := auxIntToInt8(v_1.AuxInt)
862 if !(smagicOK8(c)) {
863 break
864 }
865 v.reset(OpSub8)
866 v.Type = t
867 v0 := b.NewValue0(v.Pos, OpRsh32x64, t)
868 v1 := b.NewValue0(v.Pos, OpMul32, typ.UInt32)
869 v2 := b.NewValue0(v.Pos, OpSignExt8to32, typ.Int32)
870 v2.AddArg(x)
871 v3 := b.NewValue0(v.Pos, OpConst32, typ.UInt32)
872 v3.AuxInt = int32ToAuxInt(int32(smagic8(c).m))
873 v1.AddArg2(v2, v3)
874 v4 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
875 v4.AuxInt = int64ToAuxInt(8 + smagic8(c).s)
876 v0.AddArg2(v1, v4)
877 v5 := b.NewValue0(v.Pos, OpRsh32x64, t)
878 v6 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
879 v6.AuxInt = int64ToAuxInt(31)
880 v5.AddArg2(v2, v6)
881 v.AddArg2(v0, v5)
882 return true
883 }
884 return false
885 }
886 func rewriteValuedivmod_OpDiv8u(v *Value) bool {
887 v_1 := v.Args[1]
888 v_0 := v.Args[0]
889 b := v.Block
890 typ := &b.Func.Config.Types
891
892
893
894 for {
895 t := v.Type
896 x := v_0
897 if v_1.Op != OpConst8 {
898 break
899 }
900 c := auxIntToInt8(v_1.AuxInt)
901 if !(umagicOK8(c)) {
902 break
903 }
904 v.reset(OpTrunc32to8)
905 v.Type = t
906 v0 := b.NewValue0(v.Pos, OpRsh32Ux64, typ.UInt32)
907 v1 := b.NewValue0(v.Pos, OpMul32, typ.UInt32)
908 v2 := b.NewValue0(v.Pos, OpZeroExt8to32, typ.UInt32)
909 v2.AddArg(x)
910 v3 := b.NewValue0(v.Pos, OpConst32, typ.UInt32)
911 v3.AuxInt = int32ToAuxInt(int32(1<<8 + umagic8(c).m))
912 v1.AddArg2(v2, v3)
913 v4 := b.NewValue0(v.Pos, OpConst64, typ.UInt64)
914 v4.AuxInt = int64ToAuxInt(8 + umagic8(c).s)
915 v0.AddArg2(v1, v4)
916 v.AddArg(v0)
917 return true
918 }
919 return false
920 }
921 func rewriteBlockdivmod(b *Block) bool {
922 return false
923 }
924
View as plain text