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.
11 // ----------------------- //
12 // bits.LeadingZeros //
13 // ----------------------- //
15 func LeadingZeros(n uint) int {
18 // arm:"CLZ" arm64:"CLZ"
21 return bits.LeadingZeros(n)
24 func LeadingZeros64(n uint64) int {
27 // arm:"CLZ" arm64:"CLZ"
30 return bits.LeadingZeros64(n)
33 func LeadingZeros32(n uint32) int {
34 // amd64:"BSRQ","LEAQ",-"CMOVQEQ"
36 // arm:"CLZ" arm64:"CLZW"
39 return bits.LeadingZeros32(n)
42 func LeadingZeros16(n uint16) int {
43 // amd64:"BSRL","LEAL",-"CMOVQEQ"
45 // arm:"CLZ" arm64:"CLZ"
48 return bits.LeadingZeros16(n)
51 func LeadingZeros8(n uint8) int {
52 // amd64:"BSRL","LEAL",-"CMOVQEQ"
54 // arm:"CLZ" arm64:"CLZ"
57 return bits.LeadingZeros8(n)
64 func Len(n uint) int {
67 // arm:"CLZ" arm64:"CLZ"
73 func Len64(n uint64) int {
76 // arm:"CLZ" arm64:"CLZ"
79 // ppc64le:"SUBC","CNTLZD"
80 // ppc64:"SUBC","CNTLZD"
84 func SubFromLen64(n uint64) int {
85 // ppc64le:"CNTLZD",-"SUBC"
86 // ppc64:"CNTLZD",-"SUBC"
87 return 64 - bits.Len64(n)
90 func Len32(n uint32) int {
91 // amd64:"BSRQ","LEAQ",-"CMOVQEQ"
93 // arm:"CLZ" arm64:"CLZ"
99 func Len16(n uint16) int {
100 // amd64:"BSRL","LEAL",-"CMOVQEQ"
102 // arm:"CLZ" arm64:"CLZ"
108 func Len8(n uint8) int {
109 // amd64:"BSRL","LEAL",-"CMOVQEQ"
111 // arm:"CLZ" arm64:"CLZ"
117 // -------------------- //
119 // -------------------- //
121 // amd64:".*x86HasPOPCNT"
122 func OnesCount(n uint) int {
124 // arm64:"VCNT","VUADDLV"
129 return bits.OnesCount(n)
132 // amd64:".*x86HasPOPCNT"
133 func OnesCount64(n uint64) int {
135 // arm64:"VCNT","VUADDLV"
140 return bits.OnesCount64(n)
143 // amd64:".*x86HasPOPCNT"
144 func OnesCount32(n uint32) int {
146 // arm64:"VCNT","VUADDLV"
151 return bits.OnesCount32(n)
154 // amd64:".*x86HasPOPCNT"
155 func OnesCount16(n uint16) int {
157 // arm64:"VCNT","VUADDLV"
162 return bits.OnesCount16(n)
165 func OnesCount8(n uint8) int {
170 return bits.OnesCount8(n)
173 // ----------------------- //
174 // bits.ReverseBytes //
175 // ----------------------- //
177 func ReverseBytes(n uint) uint {
181 return bits.ReverseBytes(n)
184 func ReverseBytes64(n uint64) uint64 {
188 return bits.ReverseBytes64(n)
191 func ReverseBytes32(n uint32) uint32 {
195 return bits.ReverseBytes32(n)
198 func ReverseBytes16(n uint16) uint16 {
200 // arm64:"REV16W",-"UBFX",-"ORR"
201 // arm/5:"SLL","SRL","ORR"
204 return bits.ReverseBytes16(n)
207 // --------------------- //
208 // bits.RotateLeft //
209 // --------------------- //
211 func RotateLeft64(n uint64) uint64 {
218 return bits.RotateLeft64(n, 37)
221 func RotateLeft32(n uint32) uint32 {
222 // amd64:"ROLL" 386:"ROLL"
223 // arm:`MOVW\tR[0-9]+@>23`
229 return bits.RotateLeft32(n, 9)
232 func RotateLeft16(n uint16) uint16 {
233 // amd64:"ROLW" 386:"ROLW"
234 return bits.RotateLeft16(n, 5)
237 func RotateLeft8(n uint8) uint8 {
238 // amd64:"ROLB" 386:"ROLB"
239 return bits.RotateLeft8(n, 5)
242 func RotateLeftVariable(n uint, m int) uint {
249 return bits.RotateLeft(n, m)
252 func RotateLeftVariable64(n uint64, m int) uint64 {
259 return bits.RotateLeft64(n, m)
262 func RotateLeftVariable32(n uint32, m int) uint32 {
263 // arm:`MOVW\tR[0-9]+@>R[0-9]+`
270 return bits.RotateLeft32(n, m)
273 // ------------------------ //
274 // bits.TrailingZeros //
275 // ------------------------ //
277 func TrailingZeros(n uint) int {
278 // amd64:"BSFQ","MOVL\t\\$64","CMOVQEQ"
280 // arm64:"RBIT","CLZ"
282 // ppc64/power8:"ANDN","POPCNTD"
283 // ppc64le/power8:"ANDN","POPCNTD"
284 // ppc64/power9: "CNTTZD"
285 // ppc64le/power9: "CNTTZD"
287 return bits.TrailingZeros(n)
290 func TrailingZeros64(n uint64) int {
291 // amd64:"BSFQ","MOVL\t\\$64","CMOVQEQ"
292 // arm64:"RBIT","CLZ"
294 // ppc64/power8:"ANDN","POPCNTD"
295 // ppc64le/power8:"ANDN","POPCNTD"
296 // ppc64/power9: "CNTTZD"
297 // ppc64le/power9: "CNTTZD"
299 return bits.TrailingZeros64(n)
302 func TrailingZeros64Subtract(n uint64) int {
303 // ppc64le/power8:"NEG","SUBC","ANDN","POPCNTD"
304 // ppc64le/power9:"SUBC","CNTTZD"
305 return bits.TrailingZeros64(1 - n)
308 func TrailingZeros32(n uint32) int {
309 // amd64:"BTSQ\\t\\$32","BSFQ"
311 // arm64:"RBITW","CLZW"
312 // s390x:"FLOGR","MOVWZ"
313 // ppc64/power8:"ANDN","POPCNTW"
314 // ppc64le/power8:"ANDN","POPCNTW"
315 // ppc64/power9: "CNTTZW"
316 // ppc64le/power9: "CNTTZW"
318 return bits.TrailingZeros32(n)
321 func TrailingZeros16(n uint16) int {
322 // amd64:"BSFL","BTSL\\t\\$16"
324 // arm:"ORR\t\\$65536","CLZ",-"MOVHU\tR"
325 // arm64:"ORR\t\\$65536","RBITW","CLZW",-"MOVHU\tR",-"RBIT\t",-"CLZ\t"
326 // s390x:"FLOGR","OR\t\\$65536"
327 // ppc64/power8:"POPCNTD","OR\\t\\$65536"
328 // ppc64le/power8:"POPCNTD","OR\\t\\$65536"
329 // ppc64/power9:"CNTTZD","OR\\t\\$65536"
330 // ppc64le/power9:"CNTTZD","OR\\t\\$65536"
332 return bits.TrailingZeros16(n)
335 func TrailingZeros8(n uint8) int {
336 // amd64:"BSFL","BTSL\\t\\$8"
337 // arm:"ORR\t\\$256","CLZ",-"MOVBU\tR"
338 // arm64:"ORR\t\\$256","RBITW","CLZW",-"MOVBU\tR",-"RBIT\t",-"CLZ\t"
339 // s390x:"FLOGR","OR\t\\$256"
341 return bits.TrailingZeros8(n)
344 // IterateBitsNN checks special handling of TrailingZerosNN when the input is known to be non-zero.
346 func IterateBits(n uint) int {
349 // amd64:"BSFQ",-"CMOVEQ"
350 i += bits.TrailingZeros(n)
356 func IterateBits64(n uint64) int {
359 // amd64:"BSFQ",-"CMOVEQ"
360 i += bits.TrailingZeros64(n)
366 func IterateBits32(n uint32) int {
369 // amd64:"BSFL",-"BTSQ"
370 i += bits.TrailingZeros32(n)
376 func IterateBits16(n uint16) int {
379 // amd64:"BSFL",-"BTSL"
380 // arm64:"RBITW","CLZW",-"ORR"
381 i += bits.TrailingZeros16(n)
387 func IterateBits8(n uint8) int {
390 // amd64:"BSFL",-"BTSL"
391 // arm64:"RBITW","CLZW",-"ORR"
392 i += bits.TrailingZeros8(n)
398 // --------------- //
400 // --------------- //
402 func Add(x, y, ci uint) (r, co uint) {
403 // arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
404 // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
405 // s390x:"ADDE","ADDC\t[$]-1,"
406 return bits.Add(x, y, ci)
409 func AddC(x, ci uint) (r, co uint) {
410 // arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
411 // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
412 // s390x:"ADDE","ADDC\t[$]-1,"
413 return bits.Add(x, 7, ci)
416 func AddZ(x, y uint) (r, co uint) {
417 // arm64:"ADDS","ADC",-"ADCS",-"ADD\t",-"CMP"
418 // amd64:"ADDQ","SBBQ","NEGQ",-"NEGL",-"ADCQ"
419 // s390x:"ADDC",-"ADDC\t[$]-1,"
420 return bits.Add(x, y, 0)
423 func AddR(x, y, ci uint) uint {
424 // arm64:"ADDS","ADCS",-"ADD\t",-"CMP"
425 // amd64:"NEGL","ADCQ",-"SBBQ",-"NEGQ"
426 // s390x:"ADDE","ADDC\t[$]-1,"
427 r, _ := bits.Add(x, y, ci)
431 func AddM(p, q, r *[3]uint) {
433 r[0], c = bits.Add(p[0], q[0], c)
434 // arm64:"ADCS",-"ADD\t",-"CMP"
435 // amd64:"ADCQ",-"NEGL",-"SBBQ",-"NEGQ"
436 // s390x:"ADDE",-"ADDC\t[$]-1,"
437 r[1], c = bits.Add(p[1], q[1], c)
438 r[2], c = bits.Add(p[2], q[2], c)
441 func Add64(x, y, ci uint64) (r, co uint64) {
442 // arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
443 // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
444 // ppc64: "ADDC", "ADDE", "ADDZE"
445 // ppc64le: "ADDC", "ADDE", "ADDZE"
446 // s390x:"ADDE","ADDC\t[$]-1,"
447 return bits.Add64(x, y, ci)
450 func Add64C(x, ci uint64) (r, co uint64) {
451 // arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
452 // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
453 // ppc64: "ADDC", "ADDE", "ADDZE"
454 // ppc64le: "ADDC", "ADDE", "ADDZE"
455 // s390x:"ADDE","ADDC\t[$]-1,"
456 return bits.Add64(x, 7, ci)
459 func Add64Z(x, y uint64) (r, co uint64) {
460 // arm64:"ADDS","ADC",-"ADCS",-"ADD\t",-"CMP"
461 // amd64:"ADDQ","SBBQ","NEGQ",-"NEGL",-"ADCQ"
462 // ppc64: "ADDC", "ADDE", "ADDZE"
463 // ppc64le: "ADDC", "ADDE", "ADDZE"
464 // s390x:"ADDC",-"ADDC\t[$]-1,"
465 return bits.Add64(x, y, 0)
468 func Add64R(x, y, ci uint64) uint64 {
469 // arm64:"ADDS","ADCS",-"ADD\t",-"CMP"
470 // amd64:"NEGL","ADCQ",-"SBBQ",-"NEGQ"
471 // ppc64: "ADDC", "ADDE", "ADDZE"
472 // ppc64le: "ADDC", "ADDE", "ADDZE"
473 // s390x:"ADDE","ADDC\t[$]-1,"
474 r, _ := bits.Add64(x, y, ci)
477 func Add64M(p, q, r *[3]uint64) {
479 r[0], c = bits.Add64(p[0], q[0], c)
480 // arm64:"ADCS",-"ADD\t",-"CMP"
481 // amd64:"ADCQ",-"NEGL",-"SBBQ",-"NEGQ"
482 // ppc64: "ADDC", "ADDE", "ADDZE"
483 // ppc64le: "ADDC", "ADDE", "ADDZE"
484 // s390x:"ADDE",-"ADDC\t[$]-1,"
485 r[1], c = bits.Add64(p[1], q[1], c)
486 r[2], c = bits.Add64(p[2], q[2], c)
489 func Add64PanicOnOverflowEQ(a, b uint64) uint64 {
490 r, c := bits.Add64(a, b, 0)
491 // s390x:"BRC\t[$]3,",-"ADDE"
498 func Add64PanicOnOverflowNE(a, b uint64) uint64 {
499 r, c := bits.Add64(a, b, 0)
500 // s390x:"BRC\t[$]3,",-"ADDE"
507 func Add64PanicOnOverflowGT(a, b uint64) uint64 {
508 r, c := bits.Add64(a, b, 0)
509 // s390x:"BRC\t[$]3,",-"ADDE"
516 func Add64MPanicOnOverflowEQ(a, b [2]uint64) [2]uint64 {
519 r[0], c = bits.Add64(a[0], b[0], c)
520 r[1], c = bits.Add64(a[1], b[1], c)
521 // s390x:"BRC\t[$]3,"
528 func Add64MPanicOnOverflowNE(a, b [2]uint64) [2]uint64 {
531 r[0], c = bits.Add64(a[0], b[0], c)
532 r[1], c = bits.Add64(a[1], b[1], c)
533 // s390x:"BRC\t[$]3,"
540 func Add64MPanicOnOverflowGT(a, b [2]uint64) [2]uint64 {
543 r[0], c = bits.Add64(a[0], b[0], c)
544 r[1], c = bits.Add64(a[1], b[1], c)
545 // s390x:"BRC\t[$]3,"
552 // --------------- //
554 // --------------- //
556 func Sub(x, y, ci uint) (r, co uint) {
557 // amd64:"NEGL","SBBQ","NEGQ"
558 // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
560 return bits.Sub(x, y, ci)
563 func SubC(x, ci uint) (r, co uint) {
564 // amd64:"NEGL","SBBQ","NEGQ"
565 // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
567 return bits.Sub(x, 7, ci)
570 func SubZ(x, y uint) (r, co uint) {
571 // amd64:"SUBQ","SBBQ","NEGQ",-"NEGL"
572 // arm64:"SUBS","NGC","NEG",-"SBCS",-"ADD",-"SUB\t",-"CMP"
574 return bits.Sub(x, y, 0)
577 func SubR(x, y, ci uint) uint {
578 // amd64:"NEGL","SBBQ",-"NEGQ"
579 // arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP"
581 r, _ := bits.Sub(x, y, ci)
584 func SubM(p, q, r *[3]uint) {
586 r[0], c = bits.Sub(p[0], q[0], c)
587 // amd64:"SBBQ",-"NEGL",-"NEGQ"
588 // arm64:"SBCS",-"NEGS",-"NGC",-"NEG",-"ADD",-"SUB",-"CMP"
590 r[1], c = bits.Sub(p[1], q[1], c)
591 r[2], c = bits.Sub(p[2], q[2], c)
594 func Sub64(x, y, ci uint64) (r, co uint64) {
595 // amd64:"NEGL","SBBQ","NEGQ"
596 // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
598 return bits.Sub64(x, y, ci)
601 func Sub64C(x, ci uint64) (r, co uint64) {
602 // amd64:"NEGL","SBBQ","NEGQ"
603 // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
605 return bits.Sub64(x, 7, ci)
608 func Sub64Z(x, y uint64) (r, co uint64) {
609 // amd64:"SUBQ","SBBQ","NEGQ",-"NEGL"
610 // arm64:"SUBS","NGC","NEG",-"SBCS",-"ADD",-"SUB\t",-"CMP"
612 return bits.Sub64(x, y, 0)
615 func Sub64R(x, y, ci uint64) uint64 {
616 // amd64:"NEGL","SBBQ",-"NEGQ"
617 // arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP"
619 r, _ := bits.Sub64(x, y, ci)
622 func Sub64M(p, q, r *[3]uint64) {
624 r[0], c = bits.Sub64(p[0], q[0], c)
625 // amd64:"SBBQ",-"NEGL",-"NEGQ"
626 // arm64:"SBCS",-"NEGS",-"NGC",-"NEG",-"ADD",-"SUB",-"CMP"
628 r[1], c = bits.Sub64(p[1], q[1], c)
629 r[2], c = bits.Sub64(p[2], q[2], c)
632 func Sub64PanicOnOverflowEQ(a, b uint64) uint64 {
633 r, b := bits.Sub64(a, b, 0)
634 // s390x:"BRC\t[$]12,",-"ADDE",-"SUBE"
641 func Sub64PanicOnOverflowNE(a, b uint64) uint64 {
642 r, b := bits.Sub64(a, b, 0)
643 // s390x:"BRC\t[$]12,",-"ADDE",-"SUBE"
650 func Sub64PanicOnOverflowGT(a, b uint64) uint64 {
651 r, b := bits.Sub64(a, b, 0)
652 // s390x:"BRC\t[$]12,",-"ADDE",-"SUBE"
659 func Sub64MPanicOnOverflowEQ(a, b [2]uint64) [2]uint64 {
662 r[0], c = bits.Sub64(a[0], b[0], c)
663 r[1], c = bits.Sub64(a[1], b[1], c)
664 // s390x:"BRC\t[$]12,"
671 func Sub64MPanicOnOverflowNE(a, b [2]uint64) [2]uint64 {
674 r[0], c = bits.Sub64(a[0], b[0], c)
675 r[1], c = bits.Sub64(a[1], b[1], c)
676 // s390x:"BRC\t[$]12,"
683 func Sub64MPanicOnOverflowGT(a, b [2]uint64) [2]uint64 {
686 r[0], c = bits.Sub64(a[0], b[0], c)
687 r[1], c = bits.Sub64(a[1], b[1], c)
688 // s390x:"BRC\t[$]12,"
695 // --------------- //
697 // --------------- //
699 func Mul(x, y uint) (hi, lo uint) {
701 // arm64:"UMULH","MUL"
702 // ppc64:"MULHDU","MULLD"
703 // ppc64le:"MULHDU","MULLD"
706 return bits.Mul(x, y)
709 func Mul64(x, y uint64) (hi, lo uint64) {
711 // arm64:"UMULH","MUL"
712 // ppc64:"MULHDU","MULLD"
713 // ppc64le:"MULHDU","MULLD"
716 return bits.Mul64(x, y)
719 // --------------- //
721 // --------------- //
723 func Div(hi, lo, x uint) (q, r uint) {
725 return bits.Div(hi, lo, x)
728 func Div32(hi, lo, x uint32) (q, r uint32) {
729 // arm64:"ORR","UDIV","MSUB",-"UREM"
730 return bits.Div32(hi, lo, x)
733 func Div64(hi, lo, x uint64) (q, r uint64) {
735 return bits.Div64(hi, lo, x)
738 func Div64degenerate(x uint64) (q, r uint64) {
740 return bits.Div64(0, x, 5)