]> Cypherpunks.ru repositories - gostls13.git/blob - test/codegen/mathbits.go
cmd/compile: optimize 386's math.bits.TrailingZeros16
[gostls13.git] / test / codegen / mathbits.go
1 // asmcheck
2
3 // Copyright 2018 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 package codegen
8
9 import "math/bits"
10
11 // ----------------------- //
12 //    bits.LeadingZeros    //
13 // ----------------------- //
14
15 func LeadingZeros(n uint) int {
16         // amd64:"BSRQ"
17         // s390x:"FLOGR"
18         // arm:"CLZ" arm64:"CLZ"
19         // mips:"CLZ"
20         // wasm:"I64Clz"
21         return bits.LeadingZeros(n)
22 }
23
24 func LeadingZeros64(n uint64) int {
25         // amd64:"BSRQ"
26         // s390x:"FLOGR"
27         // arm:"CLZ" arm64:"CLZ"
28         // mips:"CLZ"
29         // wasm:"I64Clz"
30         return bits.LeadingZeros64(n)
31 }
32
33 func LeadingZeros32(n uint32) int {
34         // amd64:"BSRQ","LEAQ",-"CMOVQEQ"
35         // s390x:"FLOGR"
36         // arm:"CLZ" arm64:"CLZW"
37         // mips:"CLZ"
38         // wasm:"I64Clz"
39         return bits.LeadingZeros32(n)
40 }
41
42 func LeadingZeros16(n uint16) int {
43         // amd64:"BSRL","LEAL",-"CMOVQEQ"
44         // s390x:"FLOGR"
45         // arm:"CLZ" arm64:"CLZ"
46         // mips:"CLZ"
47         // wasm:"I64Clz"
48         return bits.LeadingZeros16(n)
49 }
50
51 func LeadingZeros8(n uint8) int {
52         // amd64:"BSRL","LEAL",-"CMOVQEQ"
53         // s390x:"FLOGR"
54         // arm:"CLZ" arm64:"CLZ"
55         // mips:"CLZ"
56         // wasm:"I64Clz"
57         return bits.LeadingZeros8(n)
58 }
59
60 // --------------- //
61 //    bits.Len*    //
62 // --------------- //
63
64 func Len(n uint) int {
65         // amd64:"BSRQ"
66         // s390x:"FLOGR"
67         // arm:"CLZ" arm64:"CLZ"
68         // mips:"CLZ"
69         // wasm:"I64Clz"
70         return bits.Len(n)
71 }
72
73 func Len64(n uint64) int {
74         // amd64:"BSRQ"
75         // s390x:"FLOGR"
76         // arm:"CLZ" arm64:"CLZ"
77         // mips:"CLZ"
78         // wasm:"I64Clz"
79         return bits.Len64(n)
80 }
81
82 func Len32(n uint32) int {
83         // amd64:"BSRQ","LEAQ",-"CMOVQEQ"
84         // s390x:"FLOGR"
85         // arm:"CLZ" arm64:"CLZ"
86         // mips:"CLZ"
87         // wasm:"I64Clz"
88         return bits.Len32(n)
89 }
90
91 func Len16(n uint16) int {
92         // amd64:"BSRL","LEAL",-"CMOVQEQ"
93         // s390x:"FLOGR"
94         // arm:"CLZ" arm64:"CLZ"
95         // mips:"CLZ"
96         // wasm:"I64Clz"
97         return bits.Len16(n)
98 }
99
100 func Len8(n uint8) int {
101         // amd64:"BSRL","LEAL",-"CMOVQEQ"
102         // s390x:"FLOGR"
103         // arm:"CLZ" arm64:"CLZ"
104         // mips:"CLZ"
105         // wasm:"I64Clz"
106         return bits.Len8(n)
107 }
108
109 // -------------------- //
110 //    bits.OnesCount    //
111 // -------------------- //
112
113 func OnesCount(n uint) int {
114         // amd64:"POPCNTQ",".*x86HasPOPCNT"
115         // arm64:"VCNT","VUADDLV"
116         // s390x:"POPCNT"
117         // ppc64:"POPCNTD"
118         // ppc64le:"POPCNTD"
119         // wasm:"I64Popcnt"
120         return bits.OnesCount(n)
121 }
122
123 func OnesCount64(n uint64) int {
124         // amd64:"POPCNTQ",".*x86HasPOPCNT"
125         // arm64:"VCNT","VUADDLV"
126         // s390x:"POPCNT"
127         // ppc64:"POPCNTD"
128         // ppc64le:"POPCNTD"
129         // wasm:"I64Popcnt"
130         return bits.OnesCount64(n)
131 }
132
133 func OnesCount32(n uint32) int {
134         // amd64:"POPCNTL",".*x86HasPOPCNT"
135         // arm64:"VCNT","VUADDLV"
136         // s390x:"POPCNT"
137         // ppc64:"POPCNTW"
138         // ppc64le:"POPCNTW"
139         // wasm:"I64Popcnt"
140         return bits.OnesCount32(n)
141 }
142
143 func OnesCount16(n uint16) int {
144         // amd64:"POPCNTL",".*x86HasPOPCNT"
145         // arm64:"VCNT","VUADDLV"
146         // s390x:"POPCNT"
147         // ppc64:"POPCNTW"
148         // ppc64le:"POPCNTW"
149         // wasm:"I64Popcnt"
150         return bits.OnesCount16(n)
151 }
152
153 func OnesCount8(n uint8) int {
154         // s390x:"POPCNT"
155         // ppc64:"POPCNTB"
156         // ppc64le:"POPCNTB"
157         // wasm:"I64Popcnt"
158         return bits.OnesCount8(n)
159 }
160
161 // ----------------------- //
162 //    bits.ReverseBytes    //
163 // ----------------------- //
164
165 func ReverseBytes(n uint) uint {
166         // amd64:"BSWAPQ"
167         // s390x:"MOVDBR"
168         // arm64:"REV"
169         return bits.ReverseBytes(n)
170 }
171
172 func ReverseBytes64(n uint64) uint64 {
173         // amd64:"BSWAPQ"
174         // s390x:"MOVDBR"
175         // arm64:"REV"
176         return bits.ReverseBytes64(n)
177 }
178
179 func ReverseBytes32(n uint32) uint32 {
180         // amd64:"BSWAPL"
181         // s390x:"MOVWBR"
182         // arm64:"REVW"
183         return bits.ReverseBytes32(n)
184 }
185
186 func ReverseBytes16(n uint16) uint16 {
187         // amd64:"ROLW"
188         // arm64:"REV16W",-"UBFX",-"ORR"
189         // arm/5:"SLL","SRL","ORR"
190         // arm/6:"REV16"
191         // arm/7:"REV16"
192         return bits.ReverseBytes16(n)
193 }
194
195 // --------------------- //
196 //    bits.RotateLeft    //
197 // --------------------- //
198
199 func RotateLeft64(n uint64) uint64 {
200         // amd64:"ROLQ"
201         // arm64:"ROR"
202         // ppc64:"ROTL"
203         // ppc64le:"ROTL"
204         // s390x:"RLLG"
205         // wasm:"I64Rotl"
206         return bits.RotateLeft64(n, 37)
207 }
208
209 func RotateLeft32(n uint32) uint32 {
210         // amd64:"ROLL" 386:"ROLL"
211         // arm:`MOVW\tR[0-9]+@>23`
212         // arm64:"RORW"
213         // ppc64:"ROTLW"
214         // ppc64le:"ROTLW"
215         // s390x:"RLL"
216         return bits.RotateLeft32(n, 9)
217 }
218
219 func RotateLeft16(n uint16) uint16 {
220         // amd64:"ROLW" 386:"ROLW"
221         return bits.RotateLeft16(n, 5)
222 }
223
224 func RotateLeft8(n uint8) uint8 {
225         // amd64:"ROLB" 386:"ROLB"
226         return bits.RotateLeft8(n, 5)
227 }
228
229 func RotateLeftVariable(n uint, m int) uint {
230         // amd64:"ROLQ"
231         // arm64:"ROR"
232         // ppc64:"ROTL"
233         // ppc64le:"ROTL"
234         // s390x:"RLLG"
235         return bits.RotateLeft(n, m)
236 }
237
238 func RotateLeftVariable64(n uint64, m int) uint64 {
239         // amd64:"ROLQ"
240         // arm64:"ROR"
241         // ppc64:"ROTL"
242         // ppc64le:"ROTL"
243         // s390x:"RLLG"
244         return bits.RotateLeft64(n, m)
245 }
246
247 func RotateLeftVariable32(n uint32, m int) uint32 {
248         // arm:`MOVW\tR[0-9]+@>R[0-9]+`
249         // amd64:"ROLL"
250         // arm64:"RORW"
251         // ppc64:"ROTLW"
252         // ppc64le:"ROTLW"
253         // s390x:"RLL"
254         return bits.RotateLeft32(n, m)
255 }
256
257 // ------------------------ //
258 //    bits.TrailingZeros    //
259 // ------------------------ //
260
261 func TrailingZeros(n uint) int {
262         // amd64:"BSFQ","MOVL\t\\$64","CMOVQEQ"
263         // arm:"CLZ"
264         // arm64:"RBIT","CLZ"
265         // s390x:"FLOGR"
266         // ppc64/power8:"ANDN","POPCNTD"
267         // ppc64le/power8:"ANDN","POPCNTD"
268         // ppc64/power9: "CNTTZD"
269         // ppc64le/power9: "CNTTZD"
270         // wasm:"I64Ctz"
271         return bits.TrailingZeros(n)
272 }
273
274 func TrailingZeros64(n uint64) int {
275         // amd64:"BSFQ","MOVL\t\\$64","CMOVQEQ"
276         // arm64:"RBIT","CLZ"
277         // s390x:"FLOGR"
278         // ppc64/power8:"ANDN","POPCNTD"
279         // ppc64le/power8:"ANDN","POPCNTD"
280         // ppc64/power9: "CNTTZD"
281         // ppc64le/power9: "CNTTZD"
282         // wasm:"I64Ctz"
283         return bits.TrailingZeros64(n)
284 }
285
286 func TrailingZeros32(n uint32) int {
287         // amd64:"BTSQ\\t\\$32","BSFQ"
288         // arm:"CLZ"
289         // arm64:"RBITW","CLZW"
290         // s390x:"FLOGR","MOVWZ"
291         // ppc64/power8:"ANDN","POPCNTW"
292         // ppc64le/power8:"ANDN","POPCNTW"
293         // ppc64/power9: "CNTTZW"
294         // ppc64le/power9: "CNTTZW"
295         // wasm:"I64Ctz"
296         return bits.TrailingZeros32(n)
297 }
298
299 func TrailingZeros16(n uint16) int {
300         // amd64:"BSFL","BTSL\\t\\$16"
301         // 386:"BSFL\t"
302         // arm:"ORR\t\\$65536","CLZ",-"MOVHU\tR"
303         // arm64:"ORR\t\\$65536","RBITW","CLZW",-"MOVHU\tR",-"RBIT\t",-"CLZ\t"
304         // s390x:"FLOGR","OR\t\\$65536"
305         // ppc64/power8:"POPCNTD","OR\\t\\$65536"
306         // ppc64le/power8:"POPCNTD","OR\\t\\$65536"
307         // ppc64/power9:"CNTTZD","OR\\t\\$65536"
308         // ppc64le/power9:"CNTTZD","OR\\t\\$65536"
309         // wasm:"I64Ctz"
310         return bits.TrailingZeros16(n)
311 }
312
313 func TrailingZeros8(n uint8) int {
314         // amd64:"BSFL","BTSL\\t\\$8"
315         // arm:"ORR\t\\$256","CLZ",-"MOVBU\tR"
316         // arm64:"ORR\t\\$256","RBITW","CLZW",-"MOVBU\tR",-"RBIT\t",-"CLZ\t"
317         // s390x:"FLOGR","OR\t\\$256"
318         // wasm:"I64Ctz"
319         return bits.TrailingZeros8(n)
320 }
321
322 // IterateBitsNN checks special handling of TrailingZerosNN when the input is known to be non-zero.
323
324 func IterateBits(n uint) int {
325         i := 0
326         for n != 0 {
327                 // amd64:"BSFQ",-"CMOVEQ"
328                 i += bits.TrailingZeros(n)
329                 n &= n - 1
330         }
331         return i
332 }
333
334 func IterateBits64(n uint64) int {
335         i := 0
336         for n != 0 {
337                 // amd64:"BSFQ",-"CMOVEQ"
338                 i += bits.TrailingZeros64(n)
339                 n &= n - 1
340         }
341         return i
342 }
343
344 func IterateBits32(n uint32) int {
345         i := 0
346         for n != 0 {
347                 // amd64:"BSFL",-"BTSQ"
348                 i += bits.TrailingZeros32(n)
349                 n &= n - 1
350         }
351         return i
352 }
353
354 func IterateBits16(n uint16) int {
355         i := 0
356         for n != 0 {
357                 // amd64:"BSFL",-"BTSL"
358                 // arm64:"RBITW","CLZW",-"ORR"
359                 i += bits.TrailingZeros16(n)
360                 n &= n - 1
361         }
362         return i
363 }
364
365 func IterateBits8(n uint8) int {
366         i := 0
367         for n != 0 {
368                 // amd64:"BSFL",-"BTSL"
369                 // arm64:"RBITW","CLZW",-"ORR"
370                 i += bits.TrailingZeros8(n)
371                 n &= n - 1
372         }
373         return i
374 }
375
376 // --------------- //
377 //    bits.Add*    //
378 // --------------- //
379
380 func Add(x, y, ci uint) (r, co uint) {
381         // arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
382         // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
383         // s390x:"ADDE","ADDC\t[$]-1,"
384         return bits.Add(x, y, ci)
385 }
386
387 func AddC(x, ci uint) (r, co uint) {
388         // arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
389         // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
390         // s390x:"ADDE","ADDC\t[$]-1,"
391         return bits.Add(x, 7, ci)
392 }
393
394 func AddZ(x, y uint) (r, co uint) {
395         // arm64:"ADDS","ADC",-"ADCS",-"ADD\t",-"CMP"
396         // amd64:"ADDQ","SBBQ","NEGQ",-"NEGL",-"ADCQ"
397         // s390x:"ADDC",-"ADDC\t[$]-1,"
398         return bits.Add(x, y, 0)
399 }
400
401 func AddR(x, y, ci uint) uint {
402         // arm64:"ADDS","ADCS",-"ADD\t",-"CMP"
403         // amd64:"NEGL","ADCQ",-"SBBQ",-"NEGQ"
404         // s390x:"ADDE","ADDC\t[$]-1,"
405         r, _ := bits.Add(x, y, ci)
406         return r
407 }
408
409 func AddM(p, q, r *[3]uint) {
410         var c uint
411         r[0], c = bits.Add(p[0], q[0], c)
412         // arm64:"ADCS",-"ADD\t",-"CMP"
413         // amd64:"ADCQ",-"NEGL",-"SBBQ",-"NEGQ"
414         // s390x:"ADDE",-"ADDC\t[$]-1,"
415         r[1], c = bits.Add(p[1], q[1], c)
416         r[2], c = bits.Add(p[2], q[2], c)
417 }
418
419 func Add64(x, y, ci uint64) (r, co uint64) {
420         // arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
421         // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
422         // ppc64: "ADDC", "ADDE", "ADDZE"
423         // ppc64le: "ADDC", "ADDE", "ADDZE"
424         // s390x:"ADDE","ADDC\t[$]-1,"
425         return bits.Add64(x, y, ci)
426 }
427
428 func Add64C(x, ci uint64) (r, co uint64) {
429         // arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
430         // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
431         // ppc64: "ADDC", "ADDE", "ADDZE"
432         // ppc64le: "ADDC", "ADDE", "ADDZE"
433         // s390x:"ADDE","ADDC\t[$]-1,"
434         return bits.Add64(x, 7, ci)
435 }
436
437 func Add64Z(x, y uint64) (r, co uint64) {
438         // arm64:"ADDS","ADC",-"ADCS",-"ADD\t",-"CMP"
439         // amd64:"ADDQ","SBBQ","NEGQ",-"NEGL",-"ADCQ"
440         // ppc64: "ADDC", "ADDE", "ADDZE"
441         // ppc64le: "ADDC", "ADDE", "ADDZE"
442         // s390x:"ADDC",-"ADDC\t[$]-1,"
443         return bits.Add64(x, y, 0)
444 }
445
446 func Add64R(x, y, ci uint64) uint64 {
447         // arm64:"ADDS","ADCS",-"ADD\t",-"CMP"
448         // amd64:"NEGL","ADCQ",-"SBBQ",-"NEGQ"
449         // ppc64: "ADDC", "ADDE", "ADDZE"
450         // ppc64le: "ADDC", "ADDE", "ADDZE"
451         // s390x:"ADDE","ADDC\t[$]-1,"
452         r, _ := bits.Add64(x, y, ci)
453         return r
454 }
455 func Add64M(p, q, r *[3]uint64) {
456         var c uint64
457         r[0], c = bits.Add64(p[0], q[0], c)
458         // arm64:"ADCS",-"ADD\t",-"CMP"
459         // amd64:"ADCQ",-"NEGL",-"SBBQ",-"NEGQ"
460         // ppc64: "ADDC", "ADDE", "ADDZE"
461         // ppc64le: "ADDC", "ADDE", "ADDZE"
462         // s390x:"ADDE",-"ADDC\t[$]-1,"
463         r[1], c = bits.Add64(p[1], q[1], c)
464         r[2], c = bits.Add64(p[2], q[2], c)
465 }
466
467 // --------------- //
468 //    bits.Sub*    //
469 // --------------- //
470
471 func Sub(x, y, ci uint) (r, co uint) {
472         // amd64:"NEGL","SBBQ","NEGQ"
473         // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
474         // s390x:"SUBE"
475         return bits.Sub(x, y, ci)
476 }
477
478 func SubC(x, ci uint) (r, co uint) {
479         // amd64:"NEGL","SBBQ","NEGQ"
480         // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
481         // s390x:"SUBE"
482         return bits.Sub(x, 7, ci)
483 }
484
485 func SubZ(x, y uint) (r, co uint) {
486         // amd64:"SUBQ","SBBQ","NEGQ",-"NEGL"
487         // arm64:"SUBS","NGC","NEG",-"SBCS",-"ADD",-"SUB\t",-"CMP"
488         // s390x:"SUBC"
489         return bits.Sub(x, y, 0)
490 }
491
492 func SubR(x, y, ci uint) uint {
493         // amd64:"NEGL","SBBQ",-"NEGQ"
494         // arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP"
495         // s390x:"SUBE"
496         r, _ := bits.Sub(x, y, ci)
497         return r
498 }
499 func SubM(p, q, r *[3]uint) {
500         var c uint
501         r[0], c = bits.Sub(p[0], q[0], c)
502         // amd64:"SBBQ",-"NEGL",-"NEGQ"
503         // arm64:"SBCS",-"NEGS",-"NGC",-"NEG",-"ADD",-"SUB",-"CMP"
504         // s390x:"SUBE"
505         r[1], c = bits.Sub(p[1], q[1], c)
506         r[2], c = bits.Sub(p[2], q[2], c)
507 }
508
509 func Sub64(x, y, ci uint64) (r, co uint64) {
510         // amd64:"NEGL","SBBQ","NEGQ"
511         // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
512         // s390x:"SUBE"
513         return bits.Sub64(x, y, ci)
514 }
515
516 func Sub64C(x, ci uint64) (r, co uint64) {
517         // amd64:"NEGL","SBBQ","NEGQ"
518         // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
519         // s390x:"SUBE"
520         return bits.Sub64(x, 7, ci)
521 }
522
523 func Sub64Z(x, y uint64) (r, co uint64) {
524         // amd64:"SUBQ","SBBQ","NEGQ",-"NEGL"
525         // arm64:"SUBS","NGC","NEG",-"SBCS",-"ADD",-"SUB\t",-"CMP"
526         // s390x:"SUBC"
527         return bits.Sub64(x, y, 0)
528 }
529
530 func Sub64R(x, y, ci uint64) uint64 {
531         // amd64:"NEGL","SBBQ",-"NEGQ"
532         // arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP"
533         // s390x:"SUBE"
534         r, _ := bits.Sub64(x, y, ci)
535         return r
536 }
537 func Sub64M(p, q, r *[3]uint64) {
538         var c uint64
539         r[0], c = bits.Sub64(p[0], q[0], c)
540         // amd64:"SBBQ",-"NEGL",-"NEGQ"
541         // arm64:"SBCS",-"NEGS",-"NGC",-"NEG",-"ADD",-"SUB",-"CMP"
542         // s390x:"SUBE"
543         r[1], c = bits.Sub64(p[1], q[1], c)
544         r[2], c = bits.Sub64(p[2], q[2], c)
545 }
546
547 // --------------- //
548 //    bits.Mul*    //
549 // --------------- //
550
551 func Mul(x, y uint) (hi, lo uint) {
552         // amd64:"MULQ"
553         // arm64:"UMULH","MUL"
554         // ppc64:"MULHDU","MULLD"
555         // ppc64le:"MULHDU","MULLD"
556         return bits.Mul(x, y)
557 }
558
559 func Mul64(x, y uint64) (hi, lo uint64) {
560         // amd64:"MULQ"
561         // arm64:"UMULH","MUL"
562         // ppc64:"MULHDU","MULLD"
563         // ppc64le:"MULHDU","MULLD"
564         return bits.Mul64(x, y)
565 }
566
567 // --------------- //
568 //    bits.Div*    //
569 // --------------- //
570
571 func Div(hi, lo, x uint) (q, r uint) {
572         // amd64:"DIVQ"
573         return bits.Div(hi, lo, x)
574 }
575
576 func Div32(hi, lo, x uint32) (q, r uint32) {
577         // arm64:"ORR","UDIV","MSUB",-"UREM"
578         return bits.Div32(hi, lo, x)
579 }
580
581 func Div64(hi, lo, x uint64) (q, r uint64) {
582         // amd64:"DIVQ"
583         return bits.Div64(hi, lo, x)
584 }
585
586 func Div64degenerate(x uint64) (q, r uint64) {
587         // amd64:-"DIVQ"
588         return bits.Div64(0, x, 5)
589 }