Source file test/codegen/divmod.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 // Div and mod rewrites, testing cmd/compile/internal/ssa/_gen/divmod.rules. 10 // See comments there for "Case 1" etc. 11 12 // Convert multiplication by a power of two to a shift. 13 14 func mul32_uint8(i uint8) uint8 { 15 // 386: "SHLL [$]5," 16 // arm64: "LSL [$]5," 17 return i * 32 18 } 19 20 func mul32_uint16(i uint16) uint16 { 21 // 386: "SHLL [$]5," 22 // arm64: "LSL [$]5," 23 return i * 32 24 } 25 26 func mul32_uint32(i uint32) uint32 { 27 // 386: "SHLL [$]5," 28 // arm64: "LSL [$]5," 29 return i * 32 30 } 31 32 func mul32_uint64(i uint64) uint64 { 33 // 386: "SHLL [$]5," 34 // 386: "SHRL [$]27," 35 // arm64: "LSL [$]5," 36 return i * 32 37 } 38 39 func mulNeg32_int8(i int8) int8 { 40 // 386: "SHLL [$]5," 41 // 386: "NEGL" 42 // arm64: "NEG R[0-9]+<<5," 43 return i * -32 44 } 45 46 func mulNeg32_int16(i int16) int16 { 47 // 386: "SHLL [$]5," 48 // 386: "NEGL" 49 // arm64: "NEG R[0-9]+<<5," 50 return i * -32 51 } 52 53 func mulNeg32_int32(i int32) int32 { 54 // 386: "SHLL [$]5," 55 // 386: "NEGL" 56 // arm64: "NEG R[0-9]+<<5," 57 return i * -32 58 } 59 60 func mulNeg32_int64(i int64) int64 { 61 // 386: "SHLL [$]5," 62 // 386: "SHRL [$]27," 63 // 386: "SBBL" 64 // arm64: "NEG R[0-9]+<<5," 65 return i * -32 66 } 67 68 // Signed divide by power of 2. 69 70 func div32_int8(i int8) int8 { 71 // 386: "SARB [$]7," 72 // 386: "SHRB [$]3," 73 // 386: "ADDL" 74 // 386: "SARB [$]5," 75 // arm64: "SBFX [$]7, R[0-9]+, [$]1," 76 // arm64: "ADD R[0-9]+>>3," 77 // arm64: "SBFX [$]5, R[0-9]+, [$]3," 78 return i / 32 79 } 80 81 func div32_int16(i int16) int16 { 82 // 386: "SARW [$]15," 83 // 386: "SHRW [$]11," 84 // 386: "ADDL" 85 // 386: "SARW [$]5," 86 // arm64: "SBFX [$]15, R[0-9]+, [$]1," 87 // arm64: "ADD R[0-9]+>>11," 88 // arm64: "SBFX [$]5, R[0-9]+, [$]11," 89 return i / 32 90 } 91 92 func div32_int32(i int32) int32 { 93 // 386: "SARL [$]31," 94 // 386: "SHRL [$]27," 95 // 386: "ADDL" 96 // 386: "SARL [$]5," 97 // arm64: "SBFX [$]31, R[0-9]+, [$]1," 98 // arm64: "ADD R[0-9]+>>27," 99 // arm64: "SBFX [$]5, R[0-9]+, [$]27," 100 return i / 32 101 } 102 103 func div32_int64(i int64) int64 { 104 // 386: "SARL [$]31," 105 // 386: "SHRL [$]27," 106 // 386: "ADDL" 107 // 386: "SARL [$]5," 108 // 386: "SHRL [$]5," 109 // 386: "SHLL [$]27," 110 // arm64: "ASR [$]63," 111 // arm64: "ADD R[0-9]+>>59," 112 // arm64: "ASR [$]5," 113 return i / 32 114 } 115 116 // Case 1. Signed divides where 2N ≤ register size. 117 118 func div7_int8(i int8) int8 { 119 // 386: "SARL [$]31," 120 // 386: "IMUL3L [$]147," 121 // 386: "SARL [$]10," 122 // 386: "SUBL" 123 // arm64: "MOVD [$]147," 124 // arm64: "MULW" 125 // arm64: "SBFX [$]10, R[0-9]+, [$]22," 126 // arm64: "SUB R[0-9]+->31," 127 return i / 7 128 } 129 130 func div7_int16(i int16) int16 { 131 // 386: "SARL [$]31," 132 // 386: "IMUL3L [$]37450," 133 // 386: "SARL [$]18," 134 // 386: "SUBL" 135 // arm64: "MOVD [$]37450," 136 // arm64: "MULW" 137 // arm64: "SBFX [$]18, R[0-9]+, [$]14," 138 // arm64: "SUB R[0-9]+->31," 139 return i / 7 140 } 141 142 func div7_int32(i int32) int32 { 143 // 64-bit only 144 // arm64: "MOVD [$]2454267027," 145 // arm64: "MUL " 146 // arm64: "ASR [$]34," 147 // arm64: "SUB R[0-9]+->63," 148 return i / 7 149 } 150 151 // Case 2. Signed divides where m is even. 152 153 func div9_int32(i int32) int32 { 154 // 386: "SARL [$]31," 155 // 386: "MOVL [$]1908874354," 156 // 386: "IMULL" 157 // 386: "SARL [$]2," 158 // 386: "SUBL" 159 // arm64: "MOVD [$]3817748708," 160 // arm64: "MUL " 161 // arm64: "ASR [$]35," 162 // arm64: "SUB R[0-9]+->63," 163 return i / 9 164 } 165 166 func div7_int64(i int64) int64 { 167 // 64-bit only 168 // arm64 MOVD $5270498306774157605, SMULH, ASR $1, SUB ->63 169 // arm64: "MOVD [$]5270498306774157605," 170 // arm64: "SMULH" 171 // arm64: "ASR [$]1," 172 // arm64: "SUB R[0-9]+->63," 173 return i / 7 174 } 175 176 // Case 3. Signed divides where m is odd. 177 178 func div3_int32(i int32) int32 { 179 // 386: "SARL [$]31," 180 // 386: "MOVL [$]-1431655765," 181 // 386: "IMULL" 182 // 386: "SARL [$]1," 183 // 386: "SUBL" 184 // arm64: "MOVD [$]2863311531," 185 // arm64: "MUL" 186 // arm64: "ASR [$]33," 187 // arm64: "SUB R[0-9]+->63," 188 return i / 3 189 } 190 191 func div3_int64(i int64) int64 { 192 // 64-bit only 193 // arm64: "MOVD [$]-6148914691236517205," 194 // arm64: "SMULH" 195 // arm64: "ADD" 196 // arm64: "ASR [$]1," 197 // arm64: "SUB R[0-9]+->63," 198 return i / 3 199 } 200 201 // Case 4. Unsigned divide where x < 1<<(N-1). 202 203 func div7_int16u(i int16) int16 { 204 if i < 0 { 205 return 0 206 } 207 // 386: "IMUL3L [$]37450," 208 // 386: "SHRL [$]18," 209 // 386: -"SUBL" 210 // arm64: "MOVD [$]37450," 211 // arm64: "MULW" 212 // arm64: "UBFX [$]18, R[0-9]+, [$]14," 213 // arm64: -"SUB" 214 return i / 7 215 } 216 217 func div7_int32u(i int32) int32 { 218 if i < 0 { 219 return 0 220 } 221 // 386: "MOVL [$]-1840700269," 222 // 386: "MULL" 223 // 386: "SHRL [$]2" 224 // 386: -"SUBL" 225 // arm64: "MOVD [$]2454267027," 226 // arm64: "MUL" 227 // arm64: "LSR [$]34," 228 // arm64: -"SUB" 229 return i / 7 230 } 231 232 func div7_int64u(i int64) int64 { 233 // 64-bit only 234 if i < 0 { 235 return 0 236 } 237 // arm64: "MOVD [$]-7905747460161236406," 238 // arm64: "UMULH" 239 // arm64: "LSR [$]2," 240 // arm64: -"SUB" 241 return i / 7 242 } 243 244 // Case 5. Unsigned divide where 2N+1 ≤ register size. 245 246 func div7_uint8(i uint8) uint8 { 247 // 386: "IMUL3L [$]293," 248 // 386: "SHRL [$]11," 249 // arm64: "MOVD [$]293," 250 // arm64: "MULW" 251 // arm64: "UBFX [$]11, R[0-9]+, [$]21," 252 return i / 7 253 } 254 255 func div7_uint16(i uint16) uint16 { 256 // only 64-bit 257 // arm64: "MOVD [$]74899," 258 // arm64: "MUL" 259 // arm64: "LSR [$]19," 260 return i / 7 261 } 262 263 // Case 6. Unsigned divide where m is even. 264 265 func div3_uint16(i uint16) uint16 { 266 // 386: "IMUL3L [$]43691," "SHRL [$]17," 267 // arm64: "MOVD [$]87382," 268 // arm64: "MUL" 269 // arm64: "LSR [$]18," 270 return i / 3 271 } 272 273 func div3_uint32(i uint32) uint32 { 274 // 386: "MOVL [$]-1431655765," "MULL", "SHRL [$]1," 275 // arm64: "MOVD [$]2863311531," 276 // arm64: "MUL" 277 // arm64: "LSR [$]33," 278 return i / 3 279 } 280 281 func div3_uint64(i uint64) uint64 { 282 // 386: "MOVL [$]-1431655766" 283 // 386: "MULL" 284 // 386: "SHRL [$]1" 285 // 386 -".*CALL" 286 // arm64: "MOVD [$]-6148914691236517205," 287 // arm64: "UMULH" 288 // arm64: "LSR [$]1," 289 return i / 3 290 } 291 292 // Case 7. Unsigned divide where c is even. 293 294 func div14_uint16(i uint16) uint16 { 295 // 32-bit only 296 // 386: "SHRL [$]1," 297 // 386: "IMUL3L [$]37450," 298 // 386: "SHRL [$]18," 299 return i / 14 300 } 301 302 func div14_uint32(i uint32) uint32 { 303 // 386: "SHRL [$]1," 304 // 386: "MOVL [$]-1840700269," 305 // 386: "SHRL [$]2," 306 // arm64: "UBFX [$]1, R[0-9]+, [$]31," 307 // arm64: "MOVD [$]2454267027," 308 // arm64: "MUL" 309 // arm64: "LSR [$]34," 310 return i / 14 311 } 312 313 func div14_uint64(i uint64) uint64 { 314 // 386: "MOVL [$]-1840700270," 315 // 386: "MULL" 316 // 386: "SHRL [$]2," 317 // 386: -".*CALL" 318 // arm64: "MOVD [$]-7905747460161236406," 319 // arm64: "UMULH" 320 // arm64: "LSR [$]2," 321 return i / 14 322 } 323 324 // Case 8. Unsigned divide on systems with avg. 325 326 func div7_uint16a(i uint16) uint16 { 327 // only 32-bit 328 // 386: "SHLL [$]16," 329 // 386: "IMUL3L [$]9363," 330 // 386: "ADDL" 331 // 386: "RCRL [$]1," 332 // 386: "SHRL [$]18," 333 return i / 7 334 } 335 336 func div7_uint32(i uint32) uint32 { 337 // 386: "MOVL [$]613566757," 338 // 386: "MULL" 339 // 386: "ADDL" 340 // 386: "RCRL [$]1," 341 // 386: "SHRL [$]2," 342 // arm64: "UBFIZ [$]32, R[0-9]+, [$]32," 343 // arm64: "MOVD [$]613566757," 344 // arm64: "MUL" 345 // arm64: "SUB" 346 // arm64: "ADD R[0-9]+>>1," 347 // arm64: "LSR [$]34," 348 return i / 7 349 } 350 351 func div7_uint64(i uint64) uint64 { 352 // 386: "MOVL [$]-1840700269," 353 // 386: "MULL" 354 // 386: "SHRL [$]2," 355 // 386: -".*CALL" 356 // arm64: "MOVD [$]2635249153387078803," 357 // arm64: "UMULH" 358 // arm64: "SUB", 359 // arm64: "ADD R[0-9]+>>1," 360 // arm64: "LSR [$]2," 361 return i / 7 362 } 363 364 func div12345_uint64(i uint64) uint64 { 365 // 386: "MOVL [$]-1444876402," 366 // 386: "MOVL [$]835683390," 367 // 386: "MULL" 368 // 386: "SHRL [$]13," 369 // 386: "SHLL [$]19," 370 // arm64: "MOVD [$]-6205696892516465602," 371 // arm64: "UMULH" 372 // arm64: "LSR [$]13," 373 return i / 12345 374 } 375 376 // Divisibility and non-divisibility by power of two. 377 378 func divis32_uint8(i uint8) bool { 379 // 386: "TESTB [$]31," 380 // arm64: "TSTW [$]31," 381 return i%32 == 0 382 } 383 384 func ndivis32_uint8(i uint8) bool { 385 // 386: "TESTB [$]31," 386 // arm64: "TSTW [$]31," 387 return i%32 != 0 388 } 389 390 func divis32_uint16(i uint16) bool { 391 // 386: "TESTW [$]31," 392 // arm64: "TSTW [$]31," 393 return i%32 == 0 394 } 395 396 func ndivis32_uint16(i uint16) bool { 397 // 386: "TESTW [$]31," 398 // arm64: "TSTW [$]31," 399 return i%32 != 0 400 } 401 402 func divis32_uint32(i uint32) bool { 403 // 386: "TESTL [$]31," 404 // arm64: "TSTW [$]31," 405 return i%32 == 0 406 } 407 408 func ndivis32_uint32(i uint32) bool { 409 // 386: "TESTL [$]31," 410 // arm64: "TSTW [$]31," 411 return i%32 != 0 412 } 413 414 func divis32_uint64(i uint64) bool { 415 // 386: "TESTL [$]31," 416 // arm64: "TST [$]31," 417 return i%32 == 0 418 } 419 420 func ndivis32_uint64(i uint64) bool { 421 // 386: "TESTL [$]31," 422 // arm64: "TST [$]31," 423 return i%32 != 0 424 } 425 426 func divis32_int8(i int8) bool { 427 // 386: "TESTB [$]31," 428 // arm64: "TSTW [$]31," 429 return i%32 == 0 430 } 431 432 func ndivis32_int8(i int8) bool { 433 // 386: "TESTB [$]31," 434 // arm64: "TSTW [$]31," 435 return i%32 != 0 436 } 437 438 func divis32_int16(i int16) bool { 439 // 386: "TESTW [$]31," 440 // arm64: "TSTW [$]31," 441 return i%32 == 0 442 } 443 444 func ndivis32_int16(i int16) bool { 445 // 386: "TESTW [$]31," 446 // arm64: "TSTW [$]31," 447 return i%32 != 0 448 } 449 450 func divis32_int32(i int32) bool { 451 // 386: "TESTL [$]31," 452 // arm64: "TSTW [$]31," 453 return i%32 == 0 454 } 455 456 func ndivis32_int32(i int32) bool { 457 // 386: "TESTL [$]31," 458 // arm64: "TSTW [$]31," 459 return i%32 != 0 460 } 461 462 func divis32_int64(i int64) bool { 463 // 386: "TESTL [$]31," 464 // arm64: "TST [$]31," 465 return i%32 == 0 466 } 467 468 func ndivis32_int64(i int64) bool { 469 // 386: "TESTL [$]31," 470 // arm64: "TST [$]31," 471 return i%32 != 0 472 } 473 474 // Divide with divisibility check; reuse divide intermediate mod. 475 476 func div_divis32_uint8(i uint8) (uint8, bool) { 477 // 386: "SHRB [$]5," 478 // 386: "TESTB [$]31,", 479 // 386: "SETEQ" 480 // arm64: "UBFX [$]5, R[0-9]+, [$]3" 481 // arm64: "TSTW [$]31," 482 // arm64: "CSET EQ" 483 return i/32, i%32 == 0 484 } 485 486 func div_ndivis32_uint8(i uint8) (uint8, bool) { 487 // 386: "SHRB [$]5," 488 // 386: "TESTB [$]31,", 489 // 386: "SETNE" 490 // arm64: "UBFX [$]5, R[0-9]+, [$]3" 491 // arm64: "TSTW [$]31," 492 // arm64: "CSET NE" 493 return i/32, i%32 != 0 494 } 495 496 func div_divis32_uint16(i uint16) (uint16, bool) { 497 // 386: "SHRW [$]5," 498 // 386: "TESTW [$]31,", 499 // 386: "SETEQ" 500 // arm64: "UBFX [$]5, R[0-9]+, [$]11" 501 // arm64: "TSTW [$]31," 502 // arm64: "CSET EQ" 503 return i/32, i%32 == 0 504 } 505 506 func div_ndivis32_uint16(i uint16) (uint16, bool) { 507 // 386: "SHRW [$]5," 508 // 386: "TESTW [$]31,", 509 // 386: "SETNE" 510 // arm64: "UBFX [$]5, R[0-9]+, [$]11," 511 // arm64: "TSTW [$]31," 512 // arm64: "CSET NE" 513 return i/32, i%32 != 0 514 } 515 516 func div_divis32_uint32(i uint32) (uint32, bool) { 517 // 386: "SHRL [$]5," 518 // 386: "TESTL [$]31,", 519 // 386: "SETEQ" 520 // arm64: "UBFX [$]5, R[0-9]+, [$]27," 521 // arm64: "TSTW [$]31," 522 // arm64: "CSET EQ" 523 return i/32, i%32 == 0 524 } 525 526 func div_ndivis32_uint32(i uint32) (uint32, bool) { 527 // 386: "SHRL [$]5," 528 // 386: "TESTL [$]31,", 529 // 386: "SETNE" 530 // arm64: "UBFX [$]5, R[0-9]+, [$]27," 531 // arm64: "TSTW [$]31," 532 // arm64: "CSET NE" 533 return i/32, i%32 != 0 534 } 535 536 func div_divis32_uint64(i uint64) (uint64, bool) { 537 // 386: "SHRL [$]5," 538 // 386: "SHLL [$]27," 539 // 386: "TESTL [$]31,", 540 // 386: "SETEQ" 541 // arm64: "LSR [$]5," 542 // arm64: "TST [$]31," 543 // arm64: "CSET EQ" 544 return i/32, i%32 == 0 545 } 546 547 func div_ndivis32_uint64(i uint64) (uint64, bool) { 548 // 386: "SHRL [$]5," 549 // 386: "SHLL [$]27," 550 // 386: "TESTL [$]31,", 551 // 386: "SETNE" 552 // arm64: "LSR [$]5," 553 // arm64: "TST [$]31," 554 // arm64: "CSET NE" 555 return i/32, i%32 != 0 556 } 557 558 func div_divis32_int8(i int8) (int8, bool) { 559 // 386: "SARB [$]7," 560 // 386: "SHRB [$]3," 561 // 386: "SARB [$]5," 562 // 386: "TESTB [$]31,", 563 // 386: "SETEQ" 564 // arm64: "SBFX [$]7, R[0-9]+, [$]1," 565 // arm64: "ADD R[0-9]+>>3," 566 // arm64: "SBFX [$]5, R[0-9]+, [$]3," 567 // arm64: "TSTW [$]31," 568 // arm64: "CSET EQ" 569 return i/32, i%32 == 0 570 } 571 572 func div_ndivis32_int8(i int8) (int8, bool) { 573 // 386: "SARB [$]7," 574 // 386: "SHRB [$]3," 575 // 386: "SARB [$]5," 576 // 386: "TESTB [$]31,", 577 // 386: "SETNE" 578 // arm64: "SBFX [$]7, R[0-9]+, [$]1," 579 // arm64: "ADD R[0-9]+>>3," 580 // arm64: "SBFX [$]5, R[0-9]+, [$]3," 581 // arm64: "TSTW [$]31," 582 // arm64: "CSET NE" 583 return i/32, i%32 != 0 584 } 585 586 func div_divis32_int16(i int16) (int16, bool) { 587 // 386: "SARW [$]15," 588 // 386: "SHRW [$]11," 589 // 386: "SARW [$]5," 590 // 386: "TESTW [$]31,", 591 // 386: "SETEQ" 592 // arm64: "SBFX [$]15, R[0-9]+, [$]1," 593 // arm64: "ADD R[0-9]+>>11," 594 // arm64: "SBFX [$]5, R[0-9]+, [$]11," 595 // arm64: "TSTW [$]31," 596 // arm64: "CSET EQ" 597 return i/32, i%32 == 0 598 } 599 600 func div_ndivis32_int16(i int16) (int16, bool) { 601 // 386: "SARW [$]15," 602 // 386: "SHRW [$]11," 603 // 386: "SARW [$]5," 604 // 386: "TESTW [$]31,", 605 // 386: "SETNE" 606 // arm64: "SBFX [$]15, R[0-9]+, [$]1," 607 // arm64: "ADD R[0-9]+>>11," 608 // arm64: "SBFX [$]5, R[0-9]+, [$]11," 609 // arm64: "TSTW [$]31," 610 // arm64: "CSET NE" 611 return i/32, i%32 != 0 612 } 613 614 func div_divis32_int32(i int32) (int32, bool) { 615 // 386: "SARL [$]31," 616 // 386: "SHRL [$]27," 617 // 386: "SARL [$]5," 618 // 386: "TESTL [$]31,", 619 // 386: "SETEQ" 620 // arm64: "SBFX [$]31, R[0-9]+, [$]1," 621 // arm64: "ADD R[0-9]+>>27," 622 // arm64: "SBFX [$]5, R[0-9]+, [$]27," 623 // arm64: "TSTW [$]31," 624 // arm64: "CSET EQ" 625 return i/32, i%32 == 0 626 } 627 628 func div_ndivis32_int32(i int32) (int32, bool) { 629 // 386: "SARL [$]31," 630 // 386: "SHRL [$]27," 631 // 386: "SARL [$]5," 632 // 386: "TESTL [$]31,", 633 // 386: "SETNE" 634 // arm64: "SBFX [$]31, R[0-9]+, [$]1," 635 // arm64: "ADD R[0-9]+>>27," 636 // arm64: "SBFX [$]5, R[0-9]+, [$]27," 637 // arm64: "TSTW [$]31," 638 // arm64: "CSET NE" 639 return i/32, i%32 != 0 640 } 641 642 func div_divis32_int64(i int64) (int64, bool) { 643 // 386: "SARL [$]31," 644 // 386: "SHRL [$]27," 645 // 386: "SARL [$]5," 646 // 386: "SHLL [$]27," 647 // 386: "TESTL [$]31,", 648 // 386: "SETEQ" 649 // arm64: "ASR [$]63," 650 // arm64: "ADD R[0-9]+>>59," 651 // arm64: "ASR [$]5," 652 // arm64: "TST [$]31," 653 // arm64: "CSET EQ" 654 return i/32, i%32 == 0 655 } 656 657 func div_ndivis32_int64(i int64) (int64, bool) { 658 // 386: "SARL [$]31," 659 // 386: "SHRL [$]27," 660 // 386: "SARL [$]5," 661 // 386: "SHLL [$]27," 662 // 386: "TESTL [$]31,", 663 // 386: "SETNE" 664 // arm64: "ASR [$]63," 665 // arm64: "ADD R[0-9]+>>59," 666 // arm64: "ASR [$]5," 667 // arm64: "TST [$]31," 668 // arm64: "CSET NE" 669 return i/32, i%32 != 0 670 } 671 672 // Divisibility and non-divisibility by non-power-of-two. 673 674 func divis6_uint8(i uint8) bool { 675 // 386: "IMUL3L [$]-85," 676 // 386: "ROLB [$]7," 677 // 386: "CMPB .*, [$]42" 678 // 386: "SETLS" 679 // arm64: "MOVD [$]-85," 680 // arm64: "MULW" 681 // arm64: "UBFX [$]1, R[0-9]+, [$]7," 682 // arm64: "ORR R[0-9]+<<7" 683 // arm64: "CMPW [$]42," 684 // arm64: "CSET LS" 685 return i%6 == 0 686 } 687 688 func ndivis6_uint8(i uint8) bool { 689 // 386: "IMUL3L [$]-85," 690 // 386: "ROLB [$]7," 691 // 386: "CMPB .*, [$]42" 692 // 386: "SETHI" 693 // arm64: "MOVD [$]-85," 694 // arm64: "MULW" 695 // arm64: "UBFX [$]1, R[0-9]+, [$]7," 696 // arm64: "ORR R[0-9]+<<7" 697 // arm64: "CMPW [$]42," 698 // arm64: "CSET HI" 699 return i%6 != 0 700 } 701 702 func divis6_uint16(i uint16) bool { 703 // 386: "IMUL3L [$]-21845," 704 // 386: "ROLW [$]15," 705 // 386: "CMPW .*, [$]10922" 706 // 386: "SETLS" 707 // arm64: "MOVD [$]-21845," 708 // arm64: "MULW" 709 // arm64: "ORR R[0-9]+<<16" 710 // arm64: "RORW [$]17," 711 // arm64: "MOVD [$]10922," 712 // arm64: "CSET LS" 713 return i%6 == 0 714 } 715 716 func ndivis6_uint16(i uint16) bool { 717 // 386: "IMUL3L [$]-21845," 718 // 386: "ROLW [$]15," 719 // 386: "CMPW .*, [$]10922" 720 // 386: "SETHI" 721 // arm64: "MOVD [$]-21845," 722 // arm64: "MULW" 723 // arm64: "ORR R[0-9]+<<16" 724 // arm64: "RORW [$]17," 725 // arm64: "MOVD [$]10922," 726 // arm64: "CSET HI" 727 return i%6 != 0 728 } 729 730 func divis6_uint32(i uint32) bool { 731 // 386: "IMUL3L [$]-1431655765," 732 // 386: "ROLL [$]31," 733 // 386: "CMPL .*, [$]715827882" 734 // 386: "SETLS" 735 // arm64: "MOVD [$]-1431655765," 736 // arm64: "MULW" 737 // arm64: "RORW [$]1," 738 // arm64: "MOVD [$]715827882," 739 // arm64: "CSET LS" 740 return i%6 == 0 741 } 742 743 func ndivis6_uint32(i uint32) bool { 744 // 386: "IMUL3L [$]-1431655765," 745 // 386: "ROLL [$]31," 746 // 386: "CMPL .*, [$]715827882" 747 // 386: "SETHI" 748 // arm64: "MOVD [$]-1431655765," 749 // arm64: "MULW" 750 // arm64: "RORW [$]1," 751 // arm64: "MOVD [$]715827882," 752 // arm64: "CSET HI" 753 return i%6 != 0 754 } 755 756 func divis6_uint64(i uint64) bool { 757 // 386: "IMUL3L [$]-1431655766," 758 // 386: "IMUL3L [$]-1431655765," 759 // 386: "MULL" 760 // 386: "SHRL [$]1," 761 // 386: "SHLL [$]31," 762 // 386: "CMPL .*, [$]715827882" 763 // 386: "SETLS" 764 // arm64: "MOVD [$]-6148914691236517205," 765 // arm64: "MUL " 766 // arm64: "ROR [$]1," 767 // arm64: "MOVD [$]3074457345618258602," 768 // arm64: "CSET LS" 769 return i%6 == 0 770 } 771 772 func ndivis6_uint64(i uint64) bool { 773 // 386: "IMUL3L [$]-1431655766," 774 // 386: "IMUL3L [$]-1431655765," 775 // 386: "MULL" 776 // 386: "SHRL [$]1," 777 // 386: "SHLL [$]31," 778 // 386: "CMPL .*, [$]715827882" 779 // 386: "SETHI" 780 // arm64: "MOVD [$]-6148914691236517205," 781 // arm64: "MUL " 782 // arm64: "ROR [$]1," 783 // arm64: "MOVD [$]3074457345618258602," 784 // arm64: "CSET HI" 785 return i%6 != 0 786 } 787 788 func divis6_int8(i int8) bool { 789 // 386: "IMUL3L [$]-85," 790 // 386: "ADDL [$]42," 791 // 386: "ROLB [$]7," 792 // 386: "CMPB .*, [$]42" 793 // 386: "SETLS" 794 // arm64: "MOVD [$]-85," 795 // arm64: "MULW" 796 // arm64: "ADD [$]42," 797 // arm64: "UBFX [$]1, R[0-9]+, [$]7," 798 // arm64: "ORR R[0-9]+<<7" 799 // arm64: "CMPW [$]42," 800 // arm64: "CSET LS" 801 return i%6 == 0 802 } 803 804 func ndivis6_int8(i int8) bool { 805 // 386: "IMUL3L [$]-85," 806 // 386: "ADDL [$]42," 807 // 386: "ROLB [$]7," 808 // 386: "CMPB .*, [$]42" 809 // 386: "SETHI" 810 // arm64: "MOVD [$]-85," 811 // arm64: "MULW" 812 // arm64: "ADD [$]42," 813 // arm64: "UBFX [$]1, R[0-9]+, [$]7," 814 // arm64: "ORR R[0-9]+<<7" 815 // arm64: "CMPW [$]42," 816 // arm64: "CSET HI" 817 return i%6 != 0 818 } 819 820 func divis6_int16(i int16) bool { 821 // 386: "IMUL3L [$]-21845," 822 // 386: "ADDL [$]10922," 823 // 386: "ROLW [$]15," 824 // 386: "CMPW .*, [$]10922" 825 // 386: "SETLS" 826 // arm64: "MOVD [$]-21845," 827 // arm64: "MULW" 828 // arm64: "MOVD [$]10922," 829 // arm64: "ADD " 830 // arm64: "ORR R[0-9]+<<16" 831 // arm64: "RORW [$]17," 832 // arm64: "MOVD [$]10922," 833 // arm64: "CSET LS" 834 return i%6 == 0 835 } 836 837 func ndivis6_int16(i int16) bool { 838 // 386: "IMUL3L [$]-21845," 839 // 386: "ADDL [$]10922," 840 // 386: "ROLW [$]15," 841 // 386: "CMPW .*, [$]10922" 842 // 386: "SETHI" 843 // arm64: "MOVD [$]-21845," 844 // arm64: "MULW" 845 // arm64: "MOVD [$]10922," 846 // arm64: "ADD " 847 // arm64: "ORR R[0-9]+<<16" 848 // arm64: "RORW [$]17," 849 // arm64: "MOVD [$]10922," 850 // arm64: "CSET HI" 851 return i%6 != 0 852 } 853 854 func divis6_int32(i int32) bool { 855 // 386: "IMUL3L [$]-1431655765," 856 // 386: "ADDL [$]715827882," 857 // 386: "ROLL [$]31," 858 // 386: "CMPL .*, [$]715827882" 859 // 386: "SETLS" 860 // arm64: "MOVD [$]-1431655765," 861 // arm64: "MULW" 862 // arm64: "MOVD [$]715827882," 863 // arm64: "ADD " 864 // arm64: "RORW [$]1," 865 // arm64: "CSET LS" 866 return i%6 == 0 867 } 868 869 func ndivis6_int32(i int32) bool { 870 // 386: "IMUL3L [$]-1431655765," 871 // 386: "ADDL [$]715827882," 872 // 386: "ROLL [$]31," 873 // 386: "CMPL .*, [$]715827882" 874 // 386: "SETHI" 875 // arm64: "MOVD [$]-1431655765," 876 // arm64: "MULW" 877 // arm64: "MOVD [$]715827882," 878 // arm64: "ADD " 879 // arm64: "RORW [$]1," 880 // arm64: "CSET HI" 881 return i%6 != 0 882 } 883 884 func divis6_int64(i int64) bool { 885 // 386: "IMUL3L [$]-1431655766," 886 // 386: "IMUL3L [$]-1431655765," 887 // 386: "ADCL [$]715827882," 888 // 386: "CMPL .*, [$]715827882" 889 // 386: "CMPL .*, [$]-1431655766" 890 // 386: "SETLS" 891 // arm64: "MOVD [$]-6148914691236517205," 892 // arm64: "MUL " 893 // arm64: "MOVD [$]3074457345618258602," 894 // arm64: "ADD " 895 // arm64: "ROR [$]1," 896 // arm64: "CSET LS" 897 return i%6 == 0 898 } 899 900 func ndivis6_int64(i int64) bool { 901 // 386: "IMUL3L [$]-1431655766," 902 // 386: "IMUL3L [$]-1431655765," 903 // 386: "ADCL [$]715827882," 904 // 386: "CMPL .*, [$]715827882" 905 // 386: "CMPL .*, [$]-1431655766" 906 // 386: "SETHI" 907 // arm64: "MOVD [$]-6148914691236517205," 908 // arm64: "MUL " 909 // arm64: "MOVD [$]3074457345618258602," 910 // arm64: "ADD " 911 // arm64: "ROR [$]1," 912 // arm64: "CSET HI" 913 return i%6 != 0 914 } 915 916 func div_divis6_uint8(i uint8) (uint8, bool) { 917 // 386: "IMUL3L [$]342," 918 // 386: "SHRL [$]11," 919 // 386: "SETEQ" 920 // 386: -"RO[RL]" 921 // arm64: "MOVD [$]342," 922 // arm64: "MULW" 923 // arm64: "UBFX [$]11, R[0-9]+, [$]21," 924 // arm64: "CSET EQ" 925 // arm64: -"RO[RL]" 926 return i/6, i%6 == 0 927 } 928 929 func div_ndivis6_uint8(i uint8) (uint8, bool) { 930 // 386: "IMUL3L [$]342," 931 // 386: "SHRL [$]11," 932 // 386: "SETNE" 933 // 386: -"RO[RL]" 934 // arm64: "MOVD [$]342," 935 // arm64: "MULW" 936 // arm64: "UBFX [$]11, R[0-9]+, [$]21," 937 // arm64: "CSET NE" 938 // arm64: -"RO[RL]" 939 return i/6, i%6 != 0 940 } 941 942 func div_divis6_uint16(i uint16) (uint16, bool) { 943 // 386: "IMUL3L [$]43691," 944 // 386: "SHRL [$]18," 945 // 386: "SHLL [$]1," 946 // 386: "SETEQ" 947 // 386: -"RO[RL]" 948 // arm64: "MOVD [$]87382," 949 // arm64: "MUL " 950 // arm64: "LSR [$]19," 951 // arm64: "CSET EQ" 952 // arm64: -"RO[RL]" 953 return i/6, i%6 == 0 954 } 955 956 func div_ndivis6_uint16(i uint16) (uint16, bool) { 957 // 386: "IMUL3L [$]43691," 958 // 386: "SHRL [$]18," 959 // 386: "SHLL [$]1," 960 // 386: "SETNE" 961 // 386: -"RO[RL]" 962 // arm64: "MOVD [$]87382," 963 // arm64: "MUL " 964 // arm64: "LSR [$]19," 965 // arm64: "CSET NE" 966 // arm64: -"RO[RL]" 967 return i/6, i%6 != 0 968 } 969 970 func div_divis6_uint32(i uint32) (uint32, bool) { 971 // 386: "MOVL [$]-1431655765," 972 // 386: "SHRL [$]2," 973 // 386: "SHLL [$]1," 974 // 386: "SETEQ" 975 // 386: -"RO[RL]" 976 // arm64: "MOVD [$]2863311531," 977 // arm64: "MUL " 978 // arm64: "LSR [$]34," 979 // arm64: "CSET EQ" 980 // arm64: -"RO[RL]" 981 return i/6, i%6 == 0 982 } 983 984 func div_ndivis6_uint32(i uint32) (uint32, bool) { 985 // 386: "MOVL [$]-1431655765," 986 // 386: "SHRL [$]2," 987 // 386: "SHLL [$]1," 988 // 386: "SETNE" 989 // 386: -"RO[RL]" 990 // arm64: "MOVD [$]2863311531," 991 // arm64: "MUL " 992 // arm64: "LSR [$]34," 993 // arm64: "CSET NE" 994 // arm64: -"RO[RL]" 995 return i/6, i%6 != 0 996 } 997 998 func div_divis6_uint64(i uint64) (uint64, bool) { 999 // 386: "MOVL [$]-1431655766," 1000 // 386: "MOVL [$]-1431655765," 1001 // 386: "MULL" 1002 // 386: "SHRL [$]2," 1003 // 386: "SHLL [$]30," 1004 // 386: "SETEQ" 1005 // 386: -".*CALL" 1006 // 386: -"RO[RL]" 1007 // arm64: "MOVD [$]-6148914691236517205," 1008 // arm64: "UMULH" 1009 // arm64: "LSR [$]2," 1010 // arm64: "CSET EQ" 1011 // arm64: -"RO[RL]" 1012 return i/6, i%6 == 0 1013 } 1014 1015 func div_ndivis6_uint64(i uint64) (uint64, bool) { 1016 // 386: "MOVL [$]-1431655766," 1017 // 386: "MOVL [$]-1431655765," 1018 // 386: "MULL" 1019 // 386: "SHRL [$]2," 1020 // 386: "SHLL [$]30," 1021 // 386: "SETNE" 1022 // 386: -".*CALL" 1023 // 386: -"RO[RL]" 1024 // arm64: "MOVD [$]-6148914691236517205," 1025 // arm64: "UMULH" 1026 // arm64: "LSR [$]2," 1027 // arm64: "CSET NE" 1028 // arm64: -"RO[RL]" 1029 return i/6, i%6 != 0 1030 } 1031 1032 func div_divis6_int8(i int8) (int8, bool) { 1033 // 386: "SARL [$]31," 1034 // 386: "IMUL3L [$]171," 1035 // 386: "SARL [$]10," 1036 // 386: "SHLL [$]1," 1037 // 386: "SETEQ" 1038 // 386: -"RO[RL]" 1039 // arm64: "MOVD [$]171," 1040 // arm64: "MULW" 1041 // arm64: "SBFX [$]10, R[0-9]+, [$]22," 1042 // arm64: "SUB R[0-9]+->31," 1043 // arm64: "CSET EQ" 1044 // arm64: -"RO[RL]" 1045 return i/6, i%6 == 0 1046 } 1047 1048 func div_ndivis6_int8(i int8) (int8, bool) { 1049 // 386: "SARL [$]31," 1050 // 386: "IMUL3L [$]171," 1051 // 386: "SARL [$]10," 1052 // 386: "SHLL [$]1," 1053 // 386: "SETNE" 1054 // 386: -"RO[RL]" 1055 // arm64: "MOVD [$]171," 1056 // arm64: "MULW" 1057 // arm64: "SBFX [$]10, R[0-9]+, [$]22," 1058 // arm64: "SUB R[0-9]+->31," 1059 // arm64: "CSET NE" 1060 // arm64: -"RO[RL]" 1061 return i/6, i%6 != 0 1062 } 1063 1064 func div_divis6_int16(i int16) (int16, bool) { 1065 // 386: "SARL [$]31," 1066 // 386: "IMUL3L [$]43691," 1067 // 386: "SARL [$]18," 1068 // 386: "SHLL [$]1," 1069 // 386: "SETEQ" 1070 // 386: -"RO[RL]" 1071 // arm64: "MOVD [$]43691," 1072 // arm64: "MULW" 1073 // arm64: "SBFX [$]18, R[0-9]+, [$]14," 1074 // arm64: "SUB R[0-9]+->31," 1075 // arm64: "CSET EQ" 1076 // arm64: -"RO[RL]" 1077 return i/6, i%6 == 0 1078 } 1079 1080 func div_ndivis6_int16(i int16) (int16, bool) { 1081 // 386: "SARL [$]31," 1082 // 386: "IMUL3L [$]43691," 1083 // 386: "SARL [$]18," 1084 // 386: "SHLL [$]1," 1085 // 386: "SETNE" 1086 // 386: -"RO[RL]" 1087 // arm64: "MOVD [$]43691," 1088 // arm64: "MULW" 1089 // arm64: "SBFX [$]18, R[0-9]+, [$]14," 1090 // arm64: "SUB R[0-9]+->31," 1091 // arm64: "CSET NE" 1092 // arm64: -"RO[RL]" 1093 return i/6, i%6 != 0 1094 } 1095 1096 func div_divis6_int32(i int32) (int32, bool) { 1097 // 386: "SARL [$]31," 1098 // 386: "MOVL [$]-1431655765," 1099 // 386: "IMULL" 1100 // 386: "SARL [$]2," 1101 // 386: "SHLL [$]1," 1102 // 386: "SETEQ" 1103 // 386: -"RO[RL]" 1104 // arm64: "MOVD [$]2863311531," 1105 // arm64: "MUL " 1106 // arm64: "ASR [$]34," 1107 // arm64: "SUB R[0-9]+->63," 1108 // arm64: "CSET EQ" 1109 // arm64: -"RO[RL]" 1110 return i/6, i%6 == 0 1111 } 1112 1113 func div_ndivis6_int32(i int32) (int32, bool) { 1114 // 386: "SARL [$]31," 1115 // 386: "MOVL [$]-1431655765," 1116 // 386: "IMULL" 1117 // 386: "SARL [$]2," 1118 // 386: "SHLL [$]1," 1119 // 386: "SETNE" 1120 // 386: -"RO[RL]" 1121 // arm64: "MOVD [$]2863311531," 1122 // arm64: "MUL " 1123 // arm64: "ASR [$]34," 1124 // arm64: "SUB R[0-9]+->63," 1125 // arm64: "CSET NE" 1126 // arm64: -"RO[RL]" 1127 return i/6, i%6 != 0 1128 } 1129 1130 func div_divis6_int64(i int64) (int64, bool) { 1131 // 386: "ANDL [$]-1431655766," 1132 // 386: "ANDL [$]-1431655765," 1133 // 386: "MOVL [$]-1431655766," 1134 // 386: "MOVL [$]-1431655765," 1135 // 386: "SUBL" "SBBL" 1136 // 386: "MULL" 1137 // 386: "SETEQ" 1138 // 386: -"SET(LS|HI)" 1139 // 386: -".*CALL" 1140 // 386: -"RO[RL]" 1141 // arm64: "MOVD [$]-6148914691236517205," 1142 // arm64: "SMULH" 1143 // arm64: "ADD" 1144 // arm64: "ASR [$]2," 1145 // arm64: "SUB R[0-9]+->63," 1146 // arm64: "CSET EQ" 1147 // arm64: -"RO[RL]" 1148 return i/6, i%6 == 0 1149 } 1150 1151 func div_ndivis6_int64(i int64) (int64, bool) { 1152 // 386: "ANDL [$]-1431655766," 1153 // 386: "ANDL [$]-1431655765," 1154 // 386: "MOVL [$]-1431655766," 1155 // 386: "MOVL [$]-1431655765," 1156 // 386: "SUBL" "SBBL" 1157 // 386: "MULL" 1158 // 386: "SETNE" 1159 // 386: -"SET(LS|HI)" 1160 // 386: -".*CALL" 1161 // 386: -"RO[RL]" 1162 // arm64: "MOVD [$]-6148914691236517205," 1163 // arm64: "SMULH" 1164 // arm64: "ADD" 1165 // arm64: "ASR [$]2," 1166 // arm64: "SUB R[0-9]+->63," 1167 // arm64: "CSET NE" 1168 // arm64: -"RO[RL]" 1169 return i/6, i%6 != 0 1170 } 1171