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