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