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 7package codegen 8 9import "math/bits" 10 11// ----------------------- // 12// bits.LeadingZeros // 13// ----------------------- // 14 15func 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 24func 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 33func 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 42func 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 51func 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 64func 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 73func 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 84func SubFromLen64(n uint64) int { 85 // ppc64le:"CNTLZD",-"SUBC" 86 // ppc64:"CNTLZD",-"SUBC" 87 return 64 - bits.Len64(n) 88} 89 90func 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 101func 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 110func 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. 124func 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 135func 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 146func 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 157func 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 168func 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 180func ReverseBytes(n uint) uint { 181 // amd64:"BSWAPQ" 182 // s390x:"MOVDBR" 183 // arm64:"REV" 184 return bits.ReverseBytes(n) 185} 186 187func ReverseBytes64(n uint64) uint64 { 188 // amd64:"BSWAPQ" 189 // s390x:"MOVDBR" 190 // arm64:"REV" 191 return bits.ReverseBytes64(n) 192} 193 194func ReverseBytes32(n uint32) uint32 { 195 // amd64:"BSWAPL" 196 // s390x:"MOVWBR" 197 // arm64:"REVW" 198 return bits.ReverseBytes32(n) 199} 200 201func 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 214func 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 224func 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 235func RotateLeft16(n uint16) uint16 { 236 // amd64:"ROLW" 386:"ROLW" 237 return bits.RotateLeft16(n, 5) 238} 239 240func RotateLeft8(n uint8) uint8 { 241 // amd64:"ROLB" 386:"ROLB" 242 return bits.RotateLeft8(n, 5) 243} 244 245func 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 255func 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 265func 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 280func 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 294func 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 307func TrailingZeros64Subtract(n uint64) int { 308 // ppc64le/power8:"NEG","SUBC","ANDN","POPCNTD" 309 // ppc64le/power9:"SUBC","CNTTZD" 310 return bits.TrailingZeros64(1 - n) 311} 312 313func 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 327func 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 341func 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 352func 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 363func 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 374func 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 385func 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 397func 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 413func 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 420func 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 427func 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 434func 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 442func 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 452func 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 461func 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 470func 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 479func 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} 488func 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 500func 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 509func 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 518func 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 527func 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 539func 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 551func 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 567func 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 574func 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 581func 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 588func 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} 595func 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 605func 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 612func 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 619func 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 626func 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} 633func 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 643func 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 652func 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 661func 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 670func 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 682func 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 694func 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 710func 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 720func 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 735func Div(hi, lo, x uint) (q, r uint) { 736 // amd64:"DIVQ" 737 return bits.Div(hi, lo, x) 738} 739 740func Div32(hi, lo, x uint32) (q, r uint32) { 741 // arm64:"ORR","UDIV","MSUB",-"UREM" 742 return bits.Div32(hi, lo, x) 743} 744 745func Div64(hi, lo, x uint64) (q, r uint64) { 746 // amd64:"DIVQ" 747 return bits.Div64(hi, lo, x) 748} 749 750func Div64degenerate(x uint64) (q, r uint64) { 751 // amd64:-"DIVQ" 752 return bits.Div64(0, x, 5) 753} 754