|
514 | 514 | (Arg <t.FieldType(1)> {n} [off+t.FieldOff(1)]) |
515 | 515 | (Arg <t.FieldType(2)> {n} [off+t.FieldOff(2)]) |
516 | 516 | (Arg <t.FieldType(3)> {n} [off+t.FieldOff(3)])) |
| 517 | + |
| 518 | +// strength reduction of divide by a constant. |
| 519 | +// Note: frontend does <=32 bits. We only need to do 64 bits here. |
| 520 | +// TODO: Do them all here? |
| 521 | + |
| 522 | +// Div/mod by 1. Currently handled by frontend. |
| 523 | +//(Div64 n (Const64 [1])) -> n |
| 524 | +//(Div64u n (Const64 [1])) -> n |
| 525 | +//(Mod64 n (Const64 [1])) -> (Const64 [0]) |
| 526 | +//(Mod64u n (Const64 [1])) -> (Const64 [0]) |
| 527 | + |
| 528 | +// Unsigned divide by power of 2. Currently handled by frontend. |
| 529 | +//(Div64u <t> n (Const64 [c])) && isPowerOfTwo(c) -> (Rsh64Ux64 n (Const64 <t> [log2(c)])) |
| 530 | +//(Mod64u <t> n (Const64 [c])) && isPowerOfTwo(c) -> (And64 n (Const64 <t> [c-1])) |
| 531 | + |
| 532 | +// Signed divide by power of 2. Currently handled by frontend. |
| 533 | +// n / c = n >> log(c) if n >= 0 |
| 534 | +// = (n+c-1) >> log(c) if n < 0 |
| 535 | +// We conditionally add c-1 by adding n>>63>>(64-log(c)) (first shift signed, second shift unsigned). |
| 536 | +//(Div64 <t> n (Const64 [c])) && isPowerOfTwo(c) -> |
| 537 | +// (Rsh64x64 |
| 538 | +// (Add64 <t> |
| 539 | +// n |
| 540 | +// (Rsh64Ux64 <t> |
| 541 | +// (Rsh64x64 <t> n (Const64 <t> [63])) |
| 542 | +// (Const64 <t> [64-log2(c)]))) |
| 543 | +// (Const64 <t> [log2(c)])) |
| 544 | + |
| 545 | +// Unsigned divide, not a power of 2. Strength reduce to a multiply. |
| 546 | +(Div64u <t> x (Const64 [c])) && umagic64ok(c) && !umagic64a(c) -> |
| 547 | + (Rsh64Ux64 |
| 548 | + (Hmul64u <t> |
| 549 | + (Const64 <t> [umagic64m(c)]) |
| 550 | + x) |
| 551 | + (Const64 <t> [umagic64s(c)])) |
| 552 | +(Div64u <t> x (Const64 [c])) && umagic64ok(c) && umagic64a(c) -> |
| 553 | + (Rsh64Ux64 |
| 554 | + (Avg64u <t> |
| 555 | + (Hmul64u <t> |
| 556 | + x |
| 557 | + (Const64 <t> [umagic64m(c)])) |
| 558 | + x) |
| 559 | + (Const64 <t> [umagic64s(c)-1])) |
| 560 | + |
| 561 | +// Signed divide, not a power of 2. Strength reduce to a multiply. |
| 562 | +(Div64 <t> x (Const64 [c])) && c > 0 && smagic64ok(c) && smagic64m(c) > 0 -> |
| 563 | + (Sub64 <t> |
| 564 | + (Rsh64x64 <t> |
| 565 | + (Hmul64 <t> |
| 566 | + (Const64 <t> [smagic64m(c)]) |
| 567 | + x) |
| 568 | + (Const64 <t> [smagic64s(c)])) |
| 569 | + (Rsh64x64 <t> |
| 570 | + x |
| 571 | + (Const64 <t> [63]))) |
| 572 | +(Div64 <t> x (Const64 [c])) && c > 0 && smagic64ok(c) && smagic64m(c) < 0 -> |
| 573 | + (Sub64 <t> |
| 574 | + (Rsh64x64 <t> |
| 575 | + (Add64 <t> |
| 576 | + (Hmul64 <t> |
| 577 | + (Const64 <t> [smagic64m(c)]) |
| 578 | + x) |
| 579 | + x) |
| 580 | + (Const64 <t> [smagic64s(c)])) |
| 581 | + (Rsh64x64 <t> |
| 582 | + x |
| 583 | + (Const64 <t> [63]))) |
| 584 | +(Div64 <t> x (Const64 [c])) && c < 0 && smagic64ok(c) && smagic64m(c) > 0 -> |
| 585 | + (Neg64 <t> |
| 586 | + (Sub64 <t> |
| 587 | + (Rsh64x64 <t> |
| 588 | + (Hmul64 <t> |
| 589 | + (Const64 <t> [smagic64m(c)]) |
| 590 | + x) |
| 591 | + (Const64 <t> [smagic64s(c)])) |
| 592 | + (Rsh64x64 <t> |
| 593 | + x |
| 594 | + (Const64 <t> [63])))) |
| 595 | +(Div64 <t> x (Const64 [c])) && c < 0 && smagic64ok(c) && smagic64m(c) < 0 -> |
| 596 | + (Neg64 <t> |
| 597 | + (Sub64 <t> |
| 598 | + (Rsh64x64 <t> |
| 599 | + (Add64 <t> |
| 600 | + (Hmul64 <t> |
| 601 | + (Const64 <t> [smagic64m(c)]) |
| 602 | + x) |
| 603 | + x) |
| 604 | + (Const64 <t> [smagic64s(c)])) |
| 605 | + (Rsh64x64 <t> |
| 606 | + x |
| 607 | + (Const64 <t> [63])))) |
| 608 | + |
| 609 | +// A%B = A-(A/B*B). |
| 610 | +// This implements % with two * and a bunch of ancillary ops. |
| 611 | +// One of the * is free if the user's code also computes A/B. |
| 612 | +(Mod64 <t> x (Const64 [c])) && smagic64ok(c) -> (Sub64 x (Mul64 <t> (Div64 <t> x (Const64 <t> [c])) (Const64 <t> [c]))) |
| 613 | +(Mod64u <t> x (Const64 [c])) && umagic64ok(c) -> (Sub64 x (Mul64 <t> (Div64u <t> x (Const64 <t> [c])) (Const64 <t> [c]))) |
0 commit comments