|
606 | 606 | // mutandis, for UGE and SETAE, and CC and SETCC.
|
607 | 607 | ((NE|EQ) (TESTL (SHLL (MOVLconst [1]) x) y)) => ((ULT|UGE) (BTL x y))
|
608 | 608 | ((NE|EQ) (TESTQ (SHLQ (MOVQconst [1]) x) y)) => ((ULT|UGE) (BTQ x y))
|
609 |
| -((NE|EQ) (TESTLconst [c] x)) && isUint32PowerOfTwo(int64(c)) |
610 |
| - => ((ULT|UGE) (BTLconst [int8(log32(c))] x)) |
611 |
| -((NE|EQ) (TESTQconst [c] x)) && isUint64PowerOfTwo(int64(c)) |
612 |
| - => ((ULT|UGE) (BTQconst [int8(log32(c))] x)) |
613 |
| -((NE|EQ) (TESTQ (MOVQconst [c]) x)) && isUint64PowerOfTwo(c) |
614 |
| - => ((ULT|UGE) (BTQconst [int8(log64(c))] x)) |
| 609 | +((NE|EQ) (TESTLconst [c] x)) && isUnsignedPowerOfTwo(uint32(c)) |
| 610 | + => ((ULT|UGE) (BTLconst [int8(log32u(uint32(c)))] x)) |
| 611 | +((NE|EQ) (TESTQconst [c] x)) && isUnsignedPowerOfTwo(uint64(c)) |
| 612 | + => ((ULT|UGE) (BTQconst [int8(log32u(uint32(c)))] x)) |
| 613 | +((NE|EQ) (TESTQ (MOVQconst [c]) x)) && isUnsignedPowerOfTwo(uint64(c)) |
| 614 | + => ((ULT|UGE) (BTQconst [int8(log64u(uint64(c)))] x)) |
615 | 615 | (SET(NE|EQ) (TESTL (SHLL (MOVLconst [1]) x) y)) => (SET(B|AE) (BTL x y))
|
616 | 616 | (SET(NE|EQ) (TESTQ (SHLQ (MOVQconst [1]) x) y)) => (SET(B|AE) (BTQ x y))
|
617 |
| -(SET(NE|EQ) (TESTLconst [c] x)) && isUint32PowerOfTwo(int64(c)) |
618 |
| - => (SET(B|AE) (BTLconst [int8(log32(c))] x)) |
619 |
| -(SET(NE|EQ) (TESTQconst [c] x)) && isUint64PowerOfTwo(int64(c)) |
620 |
| - => (SET(B|AE) (BTQconst [int8(log32(c))] x)) |
621 |
| -(SET(NE|EQ) (TESTQ (MOVQconst [c]) x)) && isUint64PowerOfTwo(c) |
622 |
| - => (SET(B|AE) (BTQconst [int8(log64(c))] x)) |
| 617 | +(SET(NE|EQ) (TESTLconst [c] x)) && isUnsignedPowerOfTwo(uint32(c)) |
| 618 | + => (SET(B|AE) (BTLconst [int8(log32u(uint32(c)))] x)) |
| 619 | +(SET(NE|EQ) (TESTQconst [c] x)) && isUnsignedPowerOfTwo(uint64(c)) |
| 620 | + => (SET(B|AE) (BTQconst [int8(log32u(uint32(c)))] x)) |
| 621 | +(SET(NE|EQ) (TESTQ (MOVQconst [c]) x)) && isUnsignedPowerOfTwo(uint64(c)) |
| 622 | + => (SET(B|AE) (BTQconst [int8(log64u(uint64(c)))] x)) |
623 | 623 | // SET..store variant
|
624 | 624 | (SET(NE|EQ)store [off] {sym} ptr (TESTL (SHLL (MOVLconst [1]) x) y) mem)
|
625 | 625 | => (SET(B|AE)store [off] {sym} ptr (BTL x y) mem)
|
626 | 626 | (SET(NE|EQ)store [off] {sym} ptr (TESTQ (SHLQ (MOVQconst [1]) x) y) mem)
|
627 | 627 | => (SET(B|AE)store [off] {sym} ptr (BTQ x y) mem)
|
628 |
| -(SET(NE|EQ)store [off] {sym} ptr (TESTLconst [c] x) mem) && isUint32PowerOfTwo(int64(c)) |
629 |
| - => (SET(B|AE)store [off] {sym} ptr (BTLconst [int8(log32(c))] x) mem) |
630 |
| -(SET(NE|EQ)store [off] {sym} ptr (TESTQconst [c] x) mem) && isUint64PowerOfTwo(int64(c)) |
631 |
| - => (SET(B|AE)store [off] {sym} ptr (BTQconst [int8(log32(c))] x) mem) |
632 |
| -(SET(NE|EQ)store [off] {sym} ptr (TESTQ (MOVQconst [c]) x) mem) && isUint64PowerOfTwo(c) |
633 |
| - => (SET(B|AE)store [off] {sym} ptr (BTQconst [int8(log64(c))] x) mem) |
| 628 | +(SET(NE|EQ)store [off] {sym} ptr (TESTLconst [c] x) mem) && isUnsignedPowerOfTwo(uint32(c)) |
| 629 | + => (SET(B|AE)store [off] {sym} ptr (BTLconst [int8(log32u(uint32(c)))] x) mem) |
| 630 | +(SET(NE|EQ)store [off] {sym} ptr (TESTQconst [c] x) mem) && isUnsignedPowerOfTwo(uint64(c)) |
| 631 | + => (SET(B|AE)store [off] {sym} ptr (BTQconst [int8(log32u(uint32(c)))] x) mem) |
| 632 | +(SET(NE|EQ)store [off] {sym} ptr (TESTQ (MOVQconst [c]) x) mem) && isUnsignedPowerOfTwo(uint64(c)) |
| 633 | + => (SET(B|AE)store [off] {sym} ptr (BTQconst [int8(log64u(uint64(c)))] x) mem) |
634 | 634 |
|
635 | 635 | // Handle bit-testing in the form (a>>b)&1 != 0 by building the above rules
|
636 | 636 | // and further combining shifts.
|
|
655 | 655 | (XOR(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y) x) => (BTC(Q|L) x y)
|
656 | 656 | // Note: only convert OR/XOR to BTS/BTC if the constant wouldn't fit in
|
657 | 657 | // the constant field of the OR/XOR instruction. See issue 61694.
|
658 |
| -((OR|XOR)Q (MOVQconst [c]) x) && isUint64PowerOfTwo(c) && uint64(c) >= 1<<31 => (BT(S|C)Qconst [int8(log64(c))] x) |
| 658 | +((OR|XOR)Q (MOVQconst [c]) x) && isUnsignedPowerOfTwo(uint64(c)) && uint64(c) >= 1<<31 => (BT(S|C)Qconst [int8(log64u(uint64(c)))] x) |
659 | 659 |
|
660 | 660 | // Recognize bit clearing: a &^= 1<<b
|
661 | 661 | (AND(Q|L) (NOT(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y)) x) => (BTR(Q|L) x y)
|
662 | 662 | (ANDN(Q|L) x (SHL(Q|L) (MOV(Q|L)const [1]) y)) => (BTR(Q|L) x y)
|
663 | 663 | // Note: only convert AND to BTR if the constant wouldn't fit in
|
664 | 664 | // the constant field of the AND instruction. See issue 61694.
|
665 |
| -(ANDQ (MOVQconst [c]) x) && isUint64PowerOfTwo(^c) && uint64(^c) >= 1<<31 => (BTRQconst [int8(log64(^c))] x) |
| 665 | +(ANDQ (MOVQconst [c]) x) && isUnsignedPowerOfTwo(uint64(^c)) && uint64(^c) >= 1<<31 => (BTRQconst [int8(log64u(uint64(^c)))] x) |
666 | 666 |
|
667 | 667 | // Special-case bit patterns on first/last bit.
|
668 | 668 | // generic.rules changes ANDs of high-part/low-part masks into a couple of shifts,
|
|
0 commit comments