]> Cypherpunks.ru repositories - gostls13.git/blob - test/codegen/mathbits.go
math, math/bits: add intrinsics for wasm
[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         // arm64:"RORW"
212         // ppc64:"ROTLW"
213         // ppc64le:"ROTLW"
214         // s390x:"RLL"
215         return bits.RotateLeft32(n, 9)
216 }
217
218 func RotateLeft16(n uint16) uint16 {
219         // amd64:"ROLW" 386:"ROLW"
220         return bits.RotateLeft16(n, 5)
221 }
222
223 func RotateLeft8(n uint8) uint8 {
224         // amd64:"ROLB" 386:"ROLB"
225         return bits.RotateLeft8(n, 5)
226 }
227
228 func RotateLeftVariable(n uint, m int) uint {
229         // amd64:"ROLQ"
230         // arm64:"ROR"
231         // ppc64:"ROTL"
232         // ppc64le:"ROTL"
233         // s390x:"RLLG"
234         return bits.RotateLeft(n, m)
235 }
236
237 func RotateLeftVariable64(n uint64, m int) uint64 {
238         // amd64:"ROLQ"
239         // arm64:"ROR"
240         // ppc64:"ROTL"
241         // ppc64le:"ROTL"
242         // s390x:"RLLG"
243         return bits.RotateLeft64(n, m)
244 }
245
246 func RotateLeftVariable32(n uint32, m int) uint32 {
247         // amd64:"ROLL"
248         // arm64:"RORW"
249         // ppc64:"ROTLW"
250         // ppc64le:"ROTLW"
251         // s390x:"RLL"
252         return bits.RotateLeft32(n, m)
253 }
254
255 // ------------------------ //
256 //    bits.TrailingZeros    //
257 // ------------------------ //
258
259 func TrailingZeros(n uint) int {
260         // amd64:"BSFQ","MOVL\t\\$64","CMOVQEQ"
261         // arm64:"RBIT","CLZ"
262         // s390x:"FLOGR"
263         // ppc64:"ANDN","POPCNTD"
264         // ppc64le:"ANDN","POPCNTD"
265         // wasm:"I64Ctz"
266         return bits.TrailingZeros(n)
267 }
268
269 func TrailingZeros64(n uint64) int {
270         // amd64:"BSFQ","MOVL\t\\$64","CMOVQEQ"
271         // arm64:"RBIT","CLZ"
272         // s390x:"FLOGR"
273         // ppc64:"ANDN","POPCNTD"
274         // ppc64le:"ANDN","POPCNTD"
275         // wasm:"I64Ctz"
276         return bits.TrailingZeros64(n)
277 }
278
279 func TrailingZeros32(n uint32) int {
280         // amd64:"BTSQ\\t\\$32","BSFQ"
281         // arm64:"RBITW","CLZW"
282         // s390x:"FLOGR","MOVWZ"
283         // ppc64:"ANDN","POPCNTW"
284         // ppc64le:"ANDN","POPCNTW"
285         // wasm:"I64Ctz"
286         return bits.TrailingZeros32(n)
287 }
288
289 func TrailingZeros16(n uint16) int {
290         // amd64:"BSFL","BTSL\\t\\$16"
291         // arm64:"ORR\t\\$65536","RBITW","CLZW",-"MOVHU\tR",-"RBIT\t",-"CLZ\t"
292         // s390x:"FLOGR","OR\t\\$65536"
293         // ppc64:"POPCNTD","OR\\t\\$65536"
294         // ppc64le:"POPCNTD","OR\\t\\$65536"
295         // wasm:"I64Ctz"
296         return bits.TrailingZeros16(n)
297 }
298
299 func TrailingZeros8(n uint8) int {
300         // amd64:"BSFL","BTSL\\t\\$8"
301         // arm64:"ORR\t\\$256","RBITW","CLZW",-"MOVBU\tR",-"RBIT\t",-"CLZ\t"
302         // s390x:"FLOGR","OR\t\\$256"
303         // wasm:"I64Ctz"
304         return bits.TrailingZeros8(n)
305 }
306
307 // IterateBitsNN checks special handling of TrailingZerosNN when the input is known to be non-zero.
308
309 func IterateBits(n uint) int {
310         i := 0
311         for n != 0 {
312                 // amd64:"BSFQ",-"CMOVEQ"
313                 i += bits.TrailingZeros(n)
314                 n &= n - 1
315         }
316         return i
317 }
318
319 func IterateBits64(n uint64) int {
320         i := 0
321         for n != 0 {
322                 // amd64:"BSFQ",-"CMOVEQ"
323                 i += bits.TrailingZeros64(n)
324                 n &= n - 1
325         }
326         return i
327 }
328
329 func IterateBits32(n uint32) int {
330         i := 0
331         for n != 0 {
332                 // amd64:"BSFL",-"BTSQ"
333                 i += bits.TrailingZeros32(n)
334                 n &= n - 1
335         }
336         return i
337 }
338
339 func IterateBits16(n uint16) int {
340         i := 0
341         for n != 0 {
342                 // amd64:"BSFL",-"BTSL"
343                 // arm64:"RBITW","CLZW",-"ORR"
344                 i += bits.TrailingZeros16(n)
345                 n &= n - 1
346         }
347         return i
348 }
349
350 func IterateBits8(n uint8) int {
351         i := 0
352         for n != 0 {
353                 // amd64:"BSFL",-"BTSL"
354                 // arm64:"RBITW","CLZW",-"ORR"
355                 i += bits.TrailingZeros8(n)
356                 n &= n - 1
357         }
358         return i
359 }
360
361 // --------------- //
362 //    bits.Add*    //
363 // --------------- //
364
365 func Add(x, y, ci uint) (r, co uint) {
366         // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
367         return bits.Add(x, y, ci)
368 }
369
370 func AddC(x, ci uint) (r, co uint) {
371         // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
372         return bits.Add(x, 7, ci)
373 }
374
375 func AddZ(x, y uint) (r, co uint) {
376         // amd64:"ADDQ","SBBQ","NEGQ",-"NEGL",-"ADCQ"
377         return bits.Add(x, y, 0)
378 }
379
380 func AddR(x, y, ci uint) uint {
381         // amd64:"NEGL","ADCQ",-"SBBQ",-"NEGQ"
382         r, _ := bits.Add(x, y, ci)
383         return r
384 }
385 func AddM(p, q, r *[3]uint) {
386         var c uint
387         r[0], c = bits.Add(p[0], q[0], c)
388         // amd64:"ADCQ",-"NEGL",-"SBBQ",-"NEGQ"
389         r[1], c = bits.Add(p[1], q[1], c)
390         r[2], c = bits.Add(p[2], q[2], c)
391 }
392
393 func Add64(x, y, ci uint64) (r, co uint64) {
394         // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
395         return bits.Add64(x, y, ci)
396 }
397
398 func Add64C(x, ci uint64) (r, co uint64) {
399         // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
400         return bits.Add64(x, 7, ci)
401 }
402
403 func Add64Z(x, y uint64) (r, co uint64) {
404         // amd64:"ADDQ","SBBQ","NEGQ",-"NEGL",-"ADCQ"
405         return bits.Add64(x, y, 0)
406 }
407
408 func Add64R(x, y, ci uint64) uint64 {
409         // amd64:"NEGL","ADCQ",-"SBBQ",-"NEGQ"
410         r, _ := bits.Add64(x, y, ci)
411         return r
412 }
413 func Add64M(p, q, r *[3]uint64) {
414         var c uint64
415         r[0], c = bits.Add64(p[0], q[0], c)
416         // amd64:"ADCQ",-"NEGL",-"SBBQ",-"NEGQ"
417         r[1], c = bits.Add64(p[1], q[1], c)
418         r[2], c = bits.Add64(p[2], q[2], c)
419 }
420
421 // --------------- //
422 //    bits.Sub*    //
423 // --------------- //
424
425 func Sub(x, y, ci uint) (r, co uint) {
426         // amd64:"NEGL","SBBQ","NEGQ"
427         return bits.Sub(x, y, ci)
428 }
429
430 func SubC(x, ci uint) (r, co uint) {
431         // amd64:"NEGL","SBBQ","NEGQ"
432         return bits.Sub(x, 7, ci)
433 }
434
435 func SubZ(x, y uint) (r, co uint) {
436         // amd64:"SUBQ","SBBQ","NEGQ",-"NEGL"
437         return bits.Sub(x, y, 0)
438 }
439
440 func SubR(x, y, ci uint) uint {
441         // amd64:"NEGL","SBBQ",-"NEGQ"
442         r, _ := bits.Sub(x, y, ci)
443         return r
444 }
445 func SubM(p, q, r *[3]uint) {
446         var c uint
447         r[0], c = bits.Sub(p[0], q[0], c)
448         // amd64:"SBBQ",-"NEGL",-"NEGQ"
449         r[1], c = bits.Sub(p[1], q[1], c)
450         r[2], c = bits.Sub(p[2], q[2], c)
451 }
452
453 func Sub64(x, y, ci uint64) (r, co uint64) {
454         // amd64:"NEGL","SBBQ","NEGQ"
455         return bits.Sub64(x, y, ci)
456 }
457
458 func Sub64C(x, ci uint64) (r, co uint64) {
459         // amd64:"NEGL","SBBQ","NEGQ"
460         return bits.Sub64(x, 7, ci)
461 }
462
463 func Sub64Z(x, y uint64) (r, co uint64) {
464         // amd64:"SUBQ","SBBQ","NEGQ",-"NEGL"
465         return bits.Sub64(x, y, 0)
466 }
467
468 func Sub64R(x, y, ci uint64) uint64 {
469         // amd64:"NEGL","SBBQ",-"NEGQ"
470         r, _ := bits.Sub64(x, y, ci)
471         return r
472 }
473 func Sub64M(p, q, r *[3]uint64) {
474         var c uint64
475         r[0], c = bits.Sub64(p[0], q[0], c)
476         // amd64:"SBBQ",-"NEGL",-"NEGQ"
477         r[1], c = bits.Sub64(p[1], q[1], c)
478         r[2], c = bits.Sub64(p[2], q[2], c)
479 }
480
481 // --------------- //
482 //    bits.Mul*    //
483 // --------------- //
484
485 func Mul(x, y uint) (hi, lo uint) {
486         // amd64:"MULQ"
487         // arm64:"UMULH","MUL"
488         // ppc64:"MULHDU","MULLD"
489         // ppc64le:"MULHDU","MULLD"
490         return bits.Mul(x, y)
491 }
492
493 func Mul64(x, y uint64) (hi, lo uint64) {
494         // amd64:"MULQ"
495         // arm64:"UMULH","MUL"
496         // ppc64:"MULHDU","MULLD"
497         // ppc64le:"MULHDU","MULLD"
498         return bits.Mul64(x, y)
499 }
500
501 // --------------- //
502 //    bits.Div*    //
503 // --------------- //
504
505 func Div(hi, lo, x uint) (q, r uint) {
506         // amd64:"DIVQ"
507         return bits.Div(hi, lo, x)
508 }
509
510 func Div32(hi, lo, x uint32) (q, r uint32) {
511         // arm64:"ORR","UDIV","MSUB",-"UREM"
512         return bits.Div32(hi, lo, x)
513 }
514
515 func Div64(hi, lo, x uint64) (q, r uint64) {
516         // amd64:"DIVQ"
517         return bits.Div64(hi, lo, x)
518 }