]> Cypherpunks.ru repositories - gostls13.git/blob - test/codegen/mathbits.go
[dev.link] all: merge branch 'master' into dev.link
[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         // ppc64le:"SUBC","CNTLZD"
80         // ppc64:"SUBC","CNTLZD"
81         return bits.Len64(n)
82 }
83
84 func SubFromLen64(n uint64) int {
85         // ppc64le:"CNTLZD",-"SUBC"
86         // ppc64:"CNTLZD",-"SUBC"
87         return 64 - bits.Len64(n)
88 }
89
90 func Len32(n uint32) int {
91         // amd64:"BSRQ","LEAQ",-"CMOVQEQ"
92         // s390x:"FLOGR"
93         // arm:"CLZ" arm64:"CLZ"
94         // mips:"CLZ"
95         // wasm:"I64Clz"
96         return bits.Len32(n)
97 }
98
99 func Len16(n uint16) int {
100         // amd64:"BSRL","LEAL",-"CMOVQEQ"
101         // s390x:"FLOGR"
102         // arm:"CLZ" arm64:"CLZ"
103         // mips:"CLZ"
104         // wasm:"I64Clz"
105         return bits.Len16(n)
106 }
107
108 func Len8(n uint8) int {
109         // amd64:"BSRL","LEAL",-"CMOVQEQ"
110         // s390x:"FLOGR"
111         // arm:"CLZ" arm64:"CLZ"
112         // mips:"CLZ"
113         // wasm:"I64Clz"
114         return bits.Len8(n)
115 }
116
117 // -------------------- //
118 //    bits.OnesCount    //
119 // -------------------- //
120
121 // amd64:".*x86HasPOPCNT"
122 func OnesCount(n uint) int {
123         // amd64:"POPCNTQ"
124         // arm64:"VCNT","VUADDLV"
125         // s390x:"POPCNT"
126         // ppc64:"POPCNTD"
127         // ppc64le:"POPCNTD"
128         // wasm:"I64Popcnt"
129         return bits.OnesCount(n)
130 }
131
132 // amd64:".*x86HasPOPCNT"
133 func OnesCount64(n uint64) int {
134         // amd64:"POPCNTQ"
135         // arm64:"VCNT","VUADDLV"
136         // s390x:"POPCNT"
137         // ppc64:"POPCNTD"
138         // ppc64le:"POPCNTD"
139         // wasm:"I64Popcnt"
140         return bits.OnesCount64(n)
141 }
142
143 // amd64:".*x86HasPOPCNT"
144 func OnesCount32(n uint32) int {
145         // amd64:"POPCNTL"
146         // arm64:"VCNT","VUADDLV"
147         // s390x:"POPCNT"
148         // ppc64:"POPCNTW"
149         // ppc64le:"POPCNTW"
150         // wasm:"I64Popcnt"
151         return bits.OnesCount32(n)
152 }
153
154 // amd64:".*x86HasPOPCNT"
155 func OnesCount16(n uint16) int {
156         // amd64:"POPCNTL"
157         // arm64:"VCNT","VUADDLV"
158         // s390x:"POPCNT"
159         // ppc64:"POPCNTW"
160         // ppc64le:"POPCNTW"
161         // wasm:"I64Popcnt"
162         return bits.OnesCount16(n)
163 }
164
165 func OnesCount8(n uint8) int {
166         // s390x:"POPCNT"
167         // ppc64:"POPCNTB"
168         // ppc64le:"POPCNTB"
169         // wasm:"I64Popcnt"
170         return bits.OnesCount8(n)
171 }
172
173 // ----------------------- //
174 //    bits.ReverseBytes    //
175 // ----------------------- //
176
177 func ReverseBytes(n uint) uint {
178         // amd64:"BSWAPQ"
179         // s390x:"MOVDBR"
180         // arm64:"REV"
181         return bits.ReverseBytes(n)
182 }
183
184 func ReverseBytes64(n uint64) uint64 {
185         // amd64:"BSWAPQ"
186         // s390x:"MOVDBR"
187         // arm64:"REV"
188         return bits.ReverseBytes64(n)
189 }
190
191 func ReverseBytes32(n uint32) uint32 {
192         // amd64:"BSWAPL"
193         // s390x:"MOVWBR"
194         // arm64:"REVW"
195         return bits.ReverseBytes32(n)
196 }
197
198 func ReverseBytes16(n uint16) uint16 {
199         // amd64:"ROLW"
200         // arm64:"REV16W",-"UBFX",-"ORR"
201         // arm/5:"SLL","SRL","ORR"
202         // arm/6:"REV16"
203         // arm/7:"REV16"
204         return bits.ReverseBytes16(n)
205 }
206
207 // --------------------- //
208 //    bits.RotateLeft    //
209 // --------------------- //
210
211 func RotateLeft64(n uint64) uint64 {
212         // amd64:"ROLQ"
213         // arm64:"ROR"
214         // ppc64:"ROTL"
215         // ppc64le:"ROTL"
216         // s390x:"RLLG"
217         // wasm:"I64Rotl"
218         return bits.RotateLeft64(n, 37)
219 }
220
221 func RotateLeft32(n uint32) uint32 {
222         // amd64:"ROLL" 386:"ROLL"
223         // arm:`MOVW\tR[0-9]+@>23`
224         // arm64:"RORW"
225         // ppc64:"ROTLW"
226         // ppc64le:"ROTLW"
227         // s390x:"RLL"
228         // wasm:"I32Rotl"
229         return bits.RotateLeft32(n, 9)
230 }
231
232 func RotateLeft16(n uint16) uint16 {
233         // amd64:"ROLW" 386:"ROLW"
234         return bits.RotateLeft16(n, 5)
235 }
236
237 func RotateLeft8(n uint8) uint8 {
238         // amd64:"ROLB" 386:"ROLB"
239         return bits.RotateLeft8(n, 5)
240 }
241
242 func RotateLeftVariable(n uint, m int) uint {
243         // amd64:"ROLQ"
244         // arm64:"ROR"
245         // ppc64:"ROTL"
246         // ppc64le:"ROTL"
247         // s390x:"RLLG"
248         // wasm:"I64Rotl"
249         return bits.RotateLeft(n, m)
250 }
251
252 func RotateLeftVariable64(n uint64, m int) uint64 {
253         // amd64:"ROLQ"
254         // arm64:"ROR"
255         // ppc64:"ROTL"
256         // ppc64le:"ROTL"
257         // s390x:"RLLG"
258         // wasm:"I64Rotl"
259         return bits.RotateLeft64(n, m)
260 }
261
262 func RotateLeftVariable32(n uint32, m int) uint32 {
263         // arm:`MOVW\tR[0-9]+@>R[0-9]+`
264         // amd64:"ROLL"
265         // arm64:"RORW"
266         // ppc64:"ROTLW"
267         // ppc64le:"ROTLW"
268         // s390x:"RLL"
269         // wasm:"I32Rotl"
270         return bits.RotateLeft32(n, m)
271 }
272
273 // ------------------------ //
274 //    bits.TrailingZeros    //
275 // ------------------------ //
276
277 func TrailingZeros(n uint) int {
278         // amd64:"BSFQ","MOVL\t\\$64","CMOVQEQ"
279         // arm:"CLZ"
280         // arm64:"RBIT","CLZ"
281         // s390x:"FLOGR"
282         // ppc64/power8:"ANDN","POPCNTD"
283         // ppc64le/power8:"ANDN","POPCNTD"
284         // ppc64/power9: "CNTTZD"
285         // ppc64le/power9: "CNTTZD"
286         // wasm:"I64Ctz"
287         return bits.TrailingZeros(n)
288 }
289
290 func TrailingZeros64(n uint64) int {
291         // amd64:"BSFQ","MOVL\t\\$64","CMOVQEQ"
292         // arm64:"RBIT","CLZ"
293         // s390x:"FLOGR"
294         // ppc64/power8:"ANDN","POPCNTD"
295         // ppc64le/power8:"ANDN","POPCNTD"
296         // ppc64/power9: "CNTTZD"
297         // ppc64le/power9: "CNTTZD"
298         // wasm:"I64Ctz"
299         return bits.TrailingZeros64(n)
300 }
301
302 func TrailingZeros64Subtract(n uint64) int {
303         // ppc64le/power8:"NEG","SUBC","ANDN","POPCNTD"
304         // ppc64le/power9:"SUBC","CNTTZD"
305         return bits.TrailingZeros64(1 - n)
306 }
307
308 func TrailingZeros32(n uint32) int {
309         // amd64:"BTSQ\\t\\$32","BSFQ"
310         // arm:"CLZ"
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"
317         // wasm:"I64Ctz"
318         return bits.TrailingZeros32(n)
319 }
320
321 func TrailingZeros16(n uint16) int {
322         // amd64:"BSFL","BTSL\\t\\$16"
323         // 386:"BSFL\t"
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"
331         // wasm:"I64Ctz"
332         return bits.TrailingZeros16(n)
333 }
334
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"
340         // wasm:"I64Ctz"
341         return bits.TrailingZeros8(n)
342 }
343
344 // IterateBitsNN checks special handling of TrailingZerosNN when the input is known to be non-zero.
345
346 func IterateBits(n uint) int {
347         i := 0
348         for n != 0 {
349                 // amd64:"BSFQ",-"CMOVEQ"
350                 i += bits.TrailingZeros(n)
351                 n &= n - 1
352         }
353         return i
354 }
355
356 func IterateBits64(n uint64) int {
357         i := 0
358         for n != 0 {
359                 // amd64:"BSFQ",-"CMOVEQ"
360                 i += bits.TrailingZeros64(n)
361                 n &= n - 1
362         }
363         return i
364 }
365
366 func IterateBits32(n uint32) int {
367         i := 0
368         for n != 0 {
369                 // amd64:"BSFL",-"BTSQ"
370                 i += bits.TrailingZeros32(n)
371                 n &= n - 1
372         }
373         return i
374 }
375
376 func IterateBits16(n uint16) int {
377         i := 0
378         for n != 0 {
379                 // amd64:"BSFL",-"BTSL"
380                 // arm64:"RBITW","CLZW",-"ORR"
381                 i += bits.TrailingZeros16(n)
382                 n &= n - 1
383         }
384         return i
385 }
386
387 func IterateBits8(n uint8) int {
388         i := 0
389         for n != 0 {
390                 // amd64:"BSFL",-"BTSL"
391                 // arm64:"RBITW","CLZW",-"ORR"
392                 i += bits.TrailingZeros8(n)
393                 n &= n - 1
394         }
395         return i
396 }
397
398 // --------------- //
399 //    bits.Add*    //
400 // --------------- //
401
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)
407 }
408
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)
414 }
415
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)
421 }
422
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)
428         return r
429 }
430
431 func AddM(p, q, r *[3]uint) {
432         var c 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)
439 }
440
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)
448 }
449
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)
457 }
458
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)
466 }
467
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)
475         return r
476 }
477 func Add64M(p, q, r *[3]uint64) {
478         var c 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)
487 }
488
489 func Add64PanicOnOverflowEQ(a, b uint64) uint64 {
490         r, c := bits.Add64(a, b, 0)
491         // s390x:"BRC\t[$]3,",-"ADDE"
492         if c == 1 {
493                 panic("overflow")
494         }
495         return r
496 }
497
498 func Add64PanicOnOverflowNE(a, b uint64) uint64 {
499         r, c := bits.Add64(a, b, 0)
500         // s390x:"BRC\t[$]3,",-"ADDE"
501         if c != 0 {
502                 panic("overflow")
503         }
504         return r
505 }
506
507 func Add64PanicOnOverflowGT(a, b uint64) uint64 {
508         r, c := bits.Add64(a, b, 0)
509         // s390x:"BRC\t[$]3,",-"ADDE"
510         if c > 0 {
511                 panic("overflow")
512         }
513         return r
514 }
515
516 func Add64MPanicOnOverflowEQ(a, b [2]uint64) [2]uint64 {
517         var r [2]uint64
518         var c 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,"
522         if c == 1 {
523                 panic("overflow")
524         }
525         return r
526 }
527
528 func Add64MPanicOnOverflowNE(a, b [2]uint64) [2]uint64 {
529         var r [2]uint64
530         var c 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,"
534         if c != 0 {
535                 panic("overflow")
536         }
537         return r
538 }
539
540 func Add64MPanicOnOverflowGT(a, b [2]uint64) [2]uint64 {
541         var r [2]uint64
542         var c 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,"
546         if c > 0 {
547                 panic("overflow")
548         }
549         return r
550 }
551
552 // --------------- //
553 //    bits.Sub*    //
554 // --------------- //
555
556 func Sub(x, y, ci uint) (r, co uint) {
557         // amd64:"NEGL","SBBQ","NEGQ"
558         // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
559         // s390x:"SUBE"
560         return bits.Sub(x, y, ci)
561 }
562
563 func SubC(x, ci uint) (r, co uint) {
564         // amd64:"NEGL","SBBQ","NEGQ"
565         // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
566         // s390x:"SUBE"
567         return bits.Sub(x, 7, ci)
568 }
569
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"
573         // s390x:"SUBC"
574         return bits.Sub(x, y, 0)
575 }
576
577 func SubR(x, y, ci uint) uint {
578         // amd64:"NEGL","SBBQ",-"NEGQ"
579         // arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP"
580         // s390x:"SUBE"
581         r, _ := bits.Sub(x, y, ci)
582         return r
583 }
584 func SubM(p, q, r *[3]uint) {
585         var c 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"
589         // s390x:"SUBE"
590         r[1], c = bits.Sub(p[1], q[1], c)
591         r[2], c = bits.Sub(p[2], q[2], c)
592 }
593
594 func Sub64(x, y, ci uint64) (r, co uint64) {
595         // amd64:"NEGL","SBBQ","NEGQ"
596         // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
597         // s390x:"SUBE"
598         return bits.Sub64(x, y, ci)
599 }
600
601 func Sub64C(x, ci uint64) (r, co uint64) {
602         // amd64:"NEGL","SBBQ","NEGQ"
603         // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
604         // s390x:"SUBE"
605         return bits.Sub64(x, 7, ci)
606 }
607
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"
611         // s390x:"SUBC"
612         return bits.Sub64(x, y, 0)
613 }
614
615 func Sub64R(x, y, ci uint64) uint64 {
616         // amd64:"NEGL","SBBQ",-"NEGQ"
617         // arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP"
618         // s390x:"SUBE"
619         r, _ := bits.Sub64(x, y, ci)
620         return r
621 }
622 func Sub64M(p, q, r *[3]uint64) {
623         var c 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"
627         // s390x:"SUBE"
628         r[1], c = bits.Sub64(p[1], q[1], c)
629         r[2], c = bits.Sub64(p[2], q[2], c)
630 }
631
632 func Sub64PanicOnOverflowEQ(a, b uint64) uint64 {
633         r, b := bits.Sub64(a, b, 0)
634         // s390x:"BRC\t[$]12,",-"ADDE",-"SUBE"
635         if b == 1 {
636                 panic("overflow")
637         }
638         return r
639 }
640
641 func Sub64PanicOnOverflowNE(a, b uint64) uint64 {
642         r, b := bits.Sub64(a, b, 0)
643         // s390x:"BRC\t[$]12,",-"ADDE",-"SUBE"
644         if b != 0 {
645                 panic("overflow")
646         }
647         return r
648 }
649
650 func Sub64PanicOnOverflowGT(a, b uint64) uint64 {
651         r, b := bits.Sub64(a, b, 0)
652         // s390x:"BRC\t[$]12,",-"ADDE",-"SUBE"
653         if b > 0 {
654                 panic("overflow")
655         }
656         return r
657 }
658
659 func Sub64MPanicOnOverflowEQ(a, b [2]uint64) [2]uint64 {
660         var r [2]uint64
661         var c 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,"
665         if c == 1 {
666                 panic("overflow")
667         }
668         return r
669 }
670
671 func Sub64MPanicOnOverflowNE(a, b [2]uint64) [2]uint64 {
672         var r [2]uint64
673         var c 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,"
677         if c != 0 {
678                 panic("overflow")
679         }
680         return r
681 }
682
683 func Sub64MPanicOnOverflowGT(a, b [2]uint64) [2]uint64 {
684         var r [2]uint64
685         var c 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,"
689         if c > 0 {
690                 panic("overflow")
691         }
692         return r
693 }
694
695 // --------------- //
696 //    bits.Mul*    //
697 // --------------- //
698
699 func Mul(x, y uint) (hi, lo uint) {
700         // amd64:"MULQ"
701         // arm64:"UMULH","MUL"
702         // ppc64:"MULHDU","MULLD"
703         // ppc64le:"MULHDU","MULLD"
704         // s390x:"MLGR"
705         // mips64: "MULVU"
706         return bits.Mul(x, y)
707 }
708
709 func Mul64(x, y uint64) (hi, lo uint64) {
710         // amd64:"MULQ"
711         // arm64:"UMULH","MUL"
712         // ppc64:"MULHDU","MULLD"
713         // ppc64le:"MULHDU","MULLD"
714         // s390x:"MLGR"
715         // mips64: "MULVU"
716         return bits.Mul64(x, y)
717 }
718
719 // --------------- //
720 //    bits.Div*    //
721 // --------------- //
722
723 func Div(hi, lo, x uint) (q, r uint) {
724         // amd64:"DIVQ"
725         return bits.Div(hi, lo, x)
726 }
727
728 func Div32(hi, lo, x uint32) (q, r uint32) {
729         // arm64:"ORR","UDIV","MSUB",-"UREM"
730         return bits.Div32(hi, lo, x)
731 }
732
733 func Div64(hi, lo, x uint64) (q, r uint64) {
734         // amd64:"DIVQ"
735         return bits.Div64(hi, lo, x)
736 }
737
738 func Div64degenerate(x uint64) (q, r uint64) {
739         // amd64:-"DIVQ"
740         return bits.Div64(0, x, 5)
741 }