]> 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         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 // amd64:".*x86HasPOPCNT"
114 func OnesCount(n uint) int {
115         // amd64:"POPCNTQ"
116         // arm64:"VCNT","VUADDLV"
117         // s390x:"POPCNT"
118         // ppc64:"POPCNTD"
119         // ppc64le:"POPCNTD"
120         // wasm:"I64Popcnt"
121         return bits.OnesCount(n)
122 }
123
124 // amd64:".*x86HasPOPCNT"
125 func OnesCount64(n uint64) int {
126         // amd64:"POPCNTQ"
127         // arm64:"VCNT","VUADDLV"
128         // s390x:"POPCNT"
129         // ppc64:"POPCNTD"
130         // ppc64le:"POPCNTD"
131         // wasm:"I64Popcnt"
132         return bits.OnesCount64(n)
133 }
134
135 // amd64:".*x86HasPOPCNT"
136 func OnesCount32(n uint32) int {
137         // amd64:"POPCNTL"
138         // arm64:"VCNT","VUADDLV"
139         // s390x:"POPCNT"
140         // ppc64:"POPCNTW"
141         // ppc64le:"POPCNTW"
142         // wasm:"I64Popcnt"
143         return bits.OnesCount32(n)
144 }
145
146 // amd64:".*x86HasPOPCNT"
147 func OnesCount16(n uint16) int {
148         // amd64:"POPCNTL"
149         // arm64:"VCNT","VUADDLV"
150         // s390x:"POPCNT"
151         // ppc64:"POPCNTW"
152         // ppc64le:"POPCNTW"
153         // wasm:"I64Popcnt"
154         return bits.OnesCount16(n)
155 }
156
157 func OnesCount8(n uint8) int {
158         // s390x:"POPCNT"
159         // ppc64:"POPCNTB"
160         // ppc64le:"POPCNTB"
161         // wasm:"I64Popcnt"
162         return bits.OnesCount8(n)
163 }
164
165 // ----------------------- //
166 //    bits.ReverseBytes    //
167 // ----------------------- //
168
169 func ReverseBytes(n uint) uint {
170         // amd64:"BSWAPQ"
171         // s390x:"MOVDBR"
172         // arm64:"REV"
173         return bits.ReverseBytes(n)
174 }
175
176 func ReverseBytes64(n uint64) uint64 {
177         // amd64:"BSWAPQ"
178         // s390x:"MOVDBR"
179         // arm64:"REV"
180         return bits.ReverseBytes64(n)
181 }
182
183 func ReverseBytes32(n uint32) uint32 {
184         // amd64:"BSWAPL"
185         // s390x:"MOVWBR"
186         // arm64:"REVW"
187         return bits.ReverseBytes32(n)
188 }
189
190 func ReverseBytes16(n uint16) uint16 {
191         // amd64:"ROLW"
192         // arm64:"REV16W",-"UBFX",-"ORR"
193         // arm/5:"SLL","SRL","ORR"
194         // arm/6:"REV16"
195         // arm/7:"REV16"
196         return bits.ReverseBytes16(n)
197 }
198
199 // --------------------- //
200 //    bits.RotateLeft    //
201 // --------------------- //
202
203 func RotateLeft64(n uint64) uint64 {
204         // amd64:"ROLQ"
205         // arm64:"ROR"
206         // ppc64:"ROTL"
207         // ppc64le:"ROTL"
208         // s390x:"RLLG"
209         // wasm:"I64Rotl"
210         return bits.RotateLeft64(n, 37)
211 }
212
213 func RotateLeft32(n uint32) uint32 {
214         // amd64:"ROLL" 386:"ROLL"
215         // arm:`MOVW\tR[0-9]+@>23`
216         // arm64:"RORW"
217         // ppc64:"ROTLW"
218         // ppc64le:"ROTLW"
219         // s390x:"RLL"
220         // wasm:"I32Rotl"
221         return bits.RotateLeft32(n, 9)
222 }
223
224 func RotateLeft16(n uint16) uint16 {
225         // amd64:"ROLW" 386:"ROLW"
226         return bits.RotateLeft16(n, 5)
227 }
228
229 func RotateLeft8(n uint8) uint8 {
230         // amd64:"ROLB" 386:"ROLB"
231         return bits.RotateLeft8(n, 5)
232 }
233
234 func RotateLeftVariable(n uint, m int) uint {
235         // amd64:"ROLQ"
236         // arm64:"ROR"
237         // ppc64:"ROTL"
238         // ppc64le:"ROTL"
239         // s390x:"RLLG"
240         // wasm:"I64Rotl"
241         return bits.RotateLeft(n, m)
242 }
243
244 func RotateLeftVariable64(n uint64, m int) uint64 {
245         // amd64:"ROLQ"
246         // arm64:"ROR"
247         // ppc64:"ROTL"
248         // ppc64le:"ROTL"
249         // s390x:"RLLG"
250         // wasm:"I64Rotl"
251         return bits.RotateLeft64(n, m)
252 }
253
254 func RotateLeftVariable32(n uint32, m int) uint32 {
255         // arm:`MOVW\tR[0-9]+@>R[0-9]+`
256         // amd64:"ROLL"
257         // arm64:"RORW"
258         // ppc64:"ROTLW"
259         // ppc64le:"ROTLW"
260         // s390x:"RLL"
261         // wasm:"I32Rotl"
262         return bits.RotateLeft32(n, m)
263 }
264
265 // ------------------------ //
266 //    bits.TrailingZeros    //
267 // ------------------------ //
268
269 func TrailingZeros(n uint) int {
270         // amd64:"BSFQ","MOVL\t\\$64","CMOVQEQ"
271         // arm:"CLZ"
272         // arm64:"RBIT","CLZ"
273         // s390x:"FLOGR"
274         // ppc64/power8:"ANDN","POPCNTD"
275         // ppc64le/power8:"ANDN","POPCNTD"
276         // ppc64/power9: "CNTTZD"
277         // ppc64le/power9: "CNTTZD"
278         // wasm:"I64Ctz"
279         return bits.TrailingZeros(n)
280 }
281
282 func TrailingZeros64(n uint64) int {
283         // amd64:"BSFQ","MOVL\t\\$64","CMOVQEQ"
284         // arm64:"RBIT","CLZ"
285         // s390x:"FLOGR"
286         // ppc64/power8:"ANDN","POPCNTD"
287         // ppc64le/power8:"ANDN","POPCNTD"
288         // ppc64/power9: "CNTTZD"
289         // ppc64le/power9: "CNTTZD"
290         // wasm:"I64Ctz"
291         return bits.TrailingZeros64(n)
292 }
293
294 func TrailingZeros32(n uint32) int {
295         // amd64:"BTSQ\\t\\$32","BSFQ"
296         // arm:"CLZ"
297         // arm64:"RBITW","CLZW"
298         // s390x:"FLOGR","MOVWZ"
299         // ppc64/power8:"ANDN","POPCNTW"
300         // ppc64le/power8:"ANDN","POPCNTW"
301         // ppc64/power9: "CNTTZW"
302         // ppc64le/power9: "CNTTZW"
303         // wasm:"I64Ctz"
304         return bits.TrailingZeros32(n)
305 }
306
307 func TrailingZeros16(n uint16) int {
308         // amd64:"BSFL","BTSL\\t\\$16"
309         // 386:"BSFL\t"
310         // arm:"ORR\t\\$65536","CLZ",-"MOVHU\tR"
311         // arm64:"ORR\t\\$65536","RBITW","CLZW",-"MOVHU\tR",-"RBIT\t",-"CLZ\t"
312         // s390x:"FLOGR","OR\t\\$65536"
313         // ppc64/power8:"POPCNTD","OR\\t\\$65536"
314         // ppc64le/power8:"POPCNTD","OR\\t\\$65536"
315         // ppc64/power9:"CNTTZD","OR\\t\\$65536"
316         // ppc64le/power9:"CNTTZD","OR\\t\\$65536"
317         // wasm:"I64Ctz"
318         return bits.TrailingZeros16(n)
319 }
320
321 func TrailingZeros8(n uint8) int {
322         // amd64:"BSFL","BTSL\\t\\$8"
323         // arm:"ORR\t\\$256","CLZ",-"MOVBU\tR"
324         // arm64:"ORR\t\\$256","RBITW","CLZW",-"MOVBU\tR",-"RBIT\t",-"CLZ\t"
325         // s390x:"FLOGR","OR\t\\$256"
326         // wasm:"I64Ctz"
327         return bits.TrailingZeros8(n)
328 }
329
330 // IterateBitsNN checks special handling of TrailingZerosNN when the input is known to be non-zero.
331
332 func IterateBits(n uint) int {
333         i := 0
334         for n != 0 {
335                 // amd64:"BSFQ",-"CMOVEQ"
336                 i += bits.TrailingZeros(n)
337                 n &= n - 1
338         }
339         return i
340 }
341
342 func IterateBits64(n uint64) int {
343         i := 0
344         for n != 0 {
345                 // amd64:"BSFQ",-"CMOVEQ"
346                 i += bits.TrailingZeros64(n)
347                 n &= n - 1
348         }
349         return i
350 }
351
352 func IterateBits32(n uint32) int {
353         i := 0
354         for n != 0 {
355                 // amd64:"BSFL",-"BTSQ"
356                 i += bits.TrailingZeros32(n)
357                 n &= n - 1
358         }
359         return i
360 }
361
362 func IterateBits16(n uint16) int {
363         i := 0
364         for n != 0 {
365                 // amd64:"BSFL",-"BTSL"
366                 // arm64:"RBITW","CLZW",-"ORR"
367                 i += bits.TrailingZeros16(n)
368                 n &= n - 1
369         }
370         return i
371 }
372
373 func IterateBits8(n uint8) int {
374         i := 0
375         for n != 0 {
376                 // amd64:"BSFL",-"BTSL"
377                 // arm64:"RBITW","CLZW",-"ORR"
378                 i += bits.TrailingZeros8(n)
379                 n &= n - 1
380         }
381         return i
382 }
383
384 // --------------- //
385 //    bits.Add*    //
386 // --------------- //
387
388 func Add(x, y, ci uint) (r, co uint) {
389         // arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
390         // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
391         // s390x:"ADDE","ADDC\t[$]-1,"
392         return bits.Add(x, y, ci)
393 }
394
395 func AddC(x, ci uint) (r, co uint) {
396         // arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
397         // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
398         // s390x:"ADDE","ADDC\t[$]-1,"
399         return bits.Add(x, 7, ci)
400 }
401
402 func AddZ(x, y uint) (r, co uint) {
403         // arm64:"ADDS","ADC",-"ADCS",-"ADD\t",-"CMP"
404         // amd64:"ADDQ","SBBQ","NEGQ",-"NEGL",-"ADCQ"
405         // s390x:"ADDC",-"ADDC\t[$]-1,"
406         return bits.Add(x, y, 0)
407 }
408
409 func AddR(x, y, ci uint) uint {
410         // arm64:"ADDS","ADCS",-"ADD\t",-"CMP"
411         // amd64:"NEGL","ADCQ",-"SBBQ",-"NEGQ"
412         // s390x:"ADDE","ADDC\t[$]-1,"
413         r, _ := bits.Add(x, y, ci)
414         return r
415 }
416
417 func AddM(p, q, r *[3]uint) {
418         var c uint
419         r[0], c = bits.Add(p[0], q[0], c)
420         // arm64:"ADCS",-"ADD\t",-"CMP"
421         // amd64:"ADCQ",-"NEGL",-"SBBQ",-"NEGQ"
422         // s390x:"ADDE",-"ADDC\t[$]-1,"
423         r[1], c = bits.Add(p[1], q[1], c)
424         r[2], c = bits.Add(p[2], q[2], c)
425 }
426
427 func Add64(x, y, ci uint64) (r, co uint64) {
428         // arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
429         // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
430         // ppc64: "ADDC", "ADDE", "ADDZE"
431         // ppc64le: "ADDC", "ADDE", "ADDZE"
432         // s390x:"ADDE","ADDC\t[$]-1,"
433         return bits.Add64(x, y, ci)
434 }
435
436 func Add64C(x, ci uint64) (r, co uint64) {
437         // arm64:"ADDS","ADCS","ADC",-"ADD\t",-"CMP"
438         // amd64:"NEGL","ADCQ","SBBQ","NEGQ"
439         // ppc64: "ADDC", "ADDE", "ADDZE"
440         // ppc64le: "ADDC", "ADDE", "ADDZE"
441         // s390x:"ADDE","ADDC\t[$]-1,"
442         return bits.Add64(x, 7, ci)
443 }
444
445 func Add64Z(x, y uint64) (r, co uint64) {
446         // arm64:"ADDS","ADC",-"ADCS",-"ADD\t",-"CMP"
447         // amd64:"ADDQ","SBBQ","NEGQ",-"NEGL",-"ADCQ"
448         // ppc64: "ADDC", "ADDE", "ADDZE"
449         // ppc64le: "ADDC", "ADDE", "ADDZE"
450         // s390x:"ADDC",-"ADDC\t[$]-1,"
451         return bits.Add64(x, y, 0)
452 }
453
454 func Add64R(x, y, ci uint64) uint64 {
455         // arm64:"ADDS","ADCS",-"ADD\t",-"CMP"
456         // amd64:"NEGL","ADCQ",-"SBBQ",-"NEGQ"
457         // ppc64: "ADDC", "ADDE", "ADDZE"
458         // ppc64le: "ADDC", "ADDE", "ADDZE"
459         // s390x:"ADDE","ADDC\t[$]-1,"
460         r, _ := bits.Add64(x, y, ci)
461         return r
462 }
463 func Add64M(p, q, r *[3]uint64) {
464         var c uint64
465         r[0], c = bits.Add64(p[0], q[0], c)
466         // arm64:"ADCS",-"ADD\t",-"CMP"
467         // amd64:"ADCQ",-"NEGL",-"SBBQ",-"NEGQ"
468         // ppc64: "ADDC", "ADDE", "ADDZE"
469         // ppc64le: "ADDC", "ADDE", "ADDZE"
470         // s390x:"ADDE",-"ADDC\t[$]-1,"
471         r[1], c = bits.Add64(p[1], q[1], c)
472         r[2], c = bits.Add64(p[2], q[2], c)
473 }
474
475 func Add64PanicOnOverflowEQ(a, b uint64) uint64 {
476         r, c := bits.Add64(a, b, 0)
477         // s390x:"BRC\t[$]3,",-"ADDE"
478         if c == 1 {
479                 panic("overflow")
480         }
481         return r
482 }
483
484 func Add64PanicOnOverflowNE(a, b uint64) uint64 {
485         r, c := bits.Add64(a, b, 0)
486         // s390x:"BRC\t[$]3,",-"ADDE"
487         if c != 0 {
488                 panic("overflow")
489         }
490         return r
491 }
492
493 func Add64PanicOnOverflowGT(a, b uint64) uint64 {
494         r, c := bits.Add64(a, b, 0)
495         // s390x:"BRC\t[$]3,",-"ADDE"
496         if c > 0 {
497                 panic("overflow")
498         }
499         return r
500 }
501
502 func Add64MPanicOnOverflowEQ(a, b [2]uint64) [2]uint64 {
503         var r [2]uint64
504         var c uint64
505         r[0], c = bits.Add64(a[0], b[0], c)
506         r[1], c = bits.Add64(a[1], b[1], c)
507         // s390x:"BRC\t[$]3,"
508         if c == 1 {
509                 panic("overflow")
510         }
511         return r
512 }
513
514 func Add64MPanicOnOverflowNE(a, b [2]uint64) [2]uint64 {
515         var r [2]uint64
516         var c uint64
517         r[0], c = bits.Add64(a[0], b[0], c)
518         r[1], c = bits.Add64(a[1], b[1], c)
519         // s390x:"BRC\t[$]3,"
520         if c != 0 {
521                 panic("overflow")
522         }
523         return r
524 }
525
526 func Add64MPanicOnOverflowGT(a, b [2]uint64) [2]uint64 {
527         var r [2]uint64
528         var c uint64
529         r[0], c = bits.Add64(a[0], b[0], c)
530         r[1], c = bits.Add64(a[1], b[1], c)
531         // s390x:"BRC\t[$]3,"
532         if c > 0 {
533                 panic("overflow")
534         }
535         return r
536 }
537
538 // --------------- //
539 //    bits.Sub*    //
540 // --------------- //
541
542 func Sub(x, y, ci uint) (r, co uint) {
543         // amd64:"NEGL","SBBQ","NEGQ"
544         // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
545         // s390x:"SUBE"
546         return bits.Sub(x, y, ci)
547 }
548
549 func SubC(x, ci uint) (r, co uint) {
550         // amd64:"NEGL","SBBQ","NEGQ"
551         // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
552         // s390x:"SUBE"
553         return bits.Sub(x, 7, ci)
554 }
555
556 func SubZ(x, y uint) (r, co uint) {
557         // amd64:"SUBQ","SBBQ","NEGQ",-"NEGL"
558         // arm64:"SUBS","NGC","NEG",-"SBCS",-"ADD",-"SUB\t",-"CMP"
559         // s390x:"SUBC"
560         return bits.Sub(x, y, 0)
561 }
562
563 func SubR(x, y, ci uint) uint {
564         // amd64:"NEGL","SBBQ",-"NEGQ"
565         // arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP"
566         // s390x:"SUBE"
567         r, _ := bits.Sub(x, y, ci)
568         return r
569 }
570 func SubM(p, q, r *[3]uint) {
571         var c uint
572         r[0], c = bits.Sub(p[0], q[0], c)
573         // amd64:"SBBQ",-"NEGL",-"NEGQ"
574         // arm64:"SBCS",-"NEGS",-"NGC",-"NEG",-"ADD",-"SUB",-"CMP"
575         // s390x:"SUBE"
576         r[1], c = bits.Sub(p[1], q[1], c)
577         r[2], c = bits.Sub(p[2], q[2], c)
578 }
579
580 func Sub64(x, y, ci uint64) (r, co uint64) {
581         // amd64:"NEGL","SBBQ","NEGQ"
582         // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
583         // s390x:"SUBE"
584         return bits.Sub64(x, y, ci)
585 }
586
587 func Sub64C(x, ci uint64) (r, co uint64) {
588         // amd64:"NEGL","SBBQ","NEGQ"
589         // arm64:"NEGS","SBCS","NGC","NEG",-"ADD",-"SUB",-"CMP"
590         // s390x:"SUBE"
591         return bits.Sub64(x, 7, ci)
592 }
593
594 func Sub64Z(x, y uint64) (r, co uint64) {
595         // amd64:"SUBQ","SBBQ","NEGQ",-"NEGL"
596         // arm64:"SUBS","NGC","NEG",-"SBCS",-"ADD",-"SUB\t",-"CMP"
597         // s390x:"SUBC"
598         return bits.Sub64(x, y, 0)
599 }
600
601 func Sub64R(x, y, ci uint64) uint64 {
602         // amd64:"NEGL","SBBQ",-"NEGQ"
603         // arm64:"NEGS","SBCS",-"NGC",-"NEG\t",-"ADD",-"SUB",-"CMP"
604         // s390x:"SUBE"
605         r, _ := bits.Sub64(x, y, ci)
606         return r
607 }
608 func Sub64M(p, q, r *[3]uint64) {
609         var c uint64
610         r[0], c = bits.Sub64(p[0], q[0], c)
611         // amd64:"SBBQ",-"NEGL",-"NEGQ"
612         // arm64:"SBCS",-"NEGS",-"NGC",-"NEG",-"ADD",-"SUB",-"CMP"
613         // s390x:"SUBE"
614         r[1], c = bits.Sub64(p[1], q[1], c)
615         r[2], c = bits.Sub64(p[2], q[2], c)
616 }
617
618 func Sub64PanicOnOverflowEQ(a, b uint64) uint64 {
619         r, b := bits.Sub64(a, b, 0)
620         // s390x:"BRC\t[$]12,",-"ADDE",-"SUBE"
621         if b == 1 {
622                 panic("overflow")
623         }
624         return r
625 }
626
627 func Sub64PanicOnOverflowNE(a, b uint64) uint64 {
628         r, b := bits.Sub64(a, b, 0)
629         // s390x:"BRC\t[$]12,",-"ADDE",-"SUBE"
630         if b != 0 {
631                 panic("overflow")
632         }
633         return r
634 }
635
636 func Sub64PanicOnOverflowGT(a, b uint64) uint64 {
637         r, b := bits.Sub64(a, b, 0)
638         // s390x:"BRC\t[$]12,",-"ADDE",-"SUBE"
639         if b > 0 {
640                 panic("overflow")
641         }
642         return r
643 }
644
645 func Sub64MPanicOnOverflowEQ(a, b [2]uint64) [2]uint64 {
646         var r [2]uint64
647         var c uint64
648         r[0], c = bits.Sub64(a[0], b[0], c)
649         r[1], c = bits.Sub64(a[1], b[1], c)
650         // s390x:"BRC\t[$]12,"
651         if c == 1 {
652                 panic("overflow")
653         }
654         return r
655 }
656
657 func Sub64MPanicOnOverflowNE(a, b [2]uint64) [2]uint64 {
658         var r [2]uint64
659         var c uint64
660         r[0], c = bits.Sub64(a[0], b[0], c)
661         r[1], c = bits.Sub64(a[1], b[1], c)
662         // s390x:"BRC\t[$]12,"
663         if c != 0 {
664                 panic("overflow")
665         }
666         return r
667 }
668
669 func Sub64MPanicOnOverflowGT(a, b [2]uint64) [2]uint64 {
670         var r [2]uint64
671         var c uint64
672         r[0], c = bits.Sub64(a[0], b[0], c)
673         r[1], c = bits.Sub64(a[1], b[1], c)
674         // s390x:"BRC\t[$]12,"
675         if c > 0 {
676                 panic("overflow")
677         }
678         return r
679 }
680
681 // --------------- //
682 //    bits.Mul*    //
683 // --------------- //
684
685 func Mul(x, y uint) (hi, lo uint) {
686         // amd64:"MULQ"
687         // arm64:"UMULH","MUL"
688         // ppc64:"MULHDU","MULLD"
689         // ppc64le:"MULHDU","MULLD"
690         // s390x:"MLGR"
691         // mips64: "MULVU"
692         return bits.Mul(x, y)
693 }
694
695 func Mul64(x, y uint64) (hi, lo uint64) {
696         // amd64:"MULQ"
697         // arm64:"UMULH","MUL"
698         // ppc64:"MULHDU","MULLD"
699         // ppc64le:"MULHDU","MULLD"
700         // s390x:"MLGR"
701         // mips64: "MULVU"
702         return bits.Mul64(x, y)
703 }
704
705 // --------------- //
706 //    bits.Div*    //
707 // --------------- //
708
709 func Div(hi, lo, x uint) (q, r uint) {
710         // amd64:"DIVQ"
711         return bits.Div(hi, lo, x)
712 }
713
714 func Div32(hi, lo, x uint32) (q, r uint32) {
715         // arm64:"ORR","UDIV","MSUB",-"UREM"
716         return bits.Div32(hi, lo, x)
717 }
718
719 func Div64(hi, lo, x uint64) (q, r uint64) {
720         // amd64:"DIVQ"
721         return bits.Div64(hi, lo, x)
722 }
723
724 func Div64degenerate(x uint64) (q, r uint64) {
725         // amd64:-"DIVQ"
726         return bits.Div64(0, x, 5)
727 }