|
623 | 623 | // Recognize bit setting (a |= 1<<b) and toggling (a ^= 1<<b) |
624 | 624 | (OR(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y) x) => (BTS(Q|L) x y) |
625 | 625 | (XOR(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y) x) => (BTC(Q|L) x y) |
| 626 | +(ORLmodify [off] {sym} ptr s:(SHLL (MOVLconst [1]) <t> x) mem) => |
| 627 | + (BTSLmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem) |
| 628 | +(ORQmodify [off] {sym} ptr s:(SHLQ (MOVQconst [1]) <t> x) mem) => |
| 629 | + (BTSQmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem) |
| 630 | +(XORLmodify [off] {sym} ptr s:(SHLL (MOVLconst [1]) <t> x) mem) => |
| 631 | + (BTCLmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem) |
| 632 | +(XORQmodify [off] {sym} ptr s:(SHLQ (MOVQconst [1]) <t> x) mem) => |
| 633 | + (BTCQmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem) |
626 | 634 |
|
627 | 635 | // Convert ORconst into BTS, if the code gets smaller, with boundary being |
628 | 636 | // (ORL $40,AX is 3 bytes, ORL $80,AX is 6 bytes). |
|
645 | 653 | => (BTRQconst [int8(log64(^c))] x) |
646 | 654 | (ANDL (MOVLconst [c]) x) && isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128 |
647 | 655 | => (BTRLconst [int8(log32(^c))] x) |
| 656 | +(ANDLmodify [off] {sym} ptr (NOTL s:(SHLL (MOVLconst [1]) <t> x)) mem) => |
| 657 | + (BTRLmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem) |
| 658 | +(ANDQmodify [off] {sym} ptr (NOTQ s:(SHLQ (MOVQconst [1]) <t> x)) mem) => |
| 659 | + (BTRQmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem) |
648 | 660 |
|
649 | 661 | // Special-case bit patterns on first/last bit. |
650 | 662 | // generic.rules changes ANDs of high-part/low-part masks into a couple of shifts, |
|
2050 | 2062 | ((ADD|SUB|MUL|DIV)SD x l:(MOVSDload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|MUL|DIV)SDload x [off] {sym} ptr mem) |
2051 | 2063 | ((ADD|SUB|MUL|DIV)SS x l:(MOVSSload [off] {sym} ptr mem)) && canMergeLoadClobber(v, l, x) && clobber(l) => ((ADD|SUB|MUL|DIV)SSload x [off] {sym} ptr mem) |
2052 | 2064 | (MOVLstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Lload x [off] {sym} ptr mem) mem) && y.Uses==1 && clobber(y) => ((ADD|AND|OR|XOR)Lmodify [off] {sym} ptr x mem) |
2053 | | -(MOVLstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)L l:(MOVLload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) => |
2054 | | - ((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Lmodify [off] {sym} ptr x mem) |
| 2065 | +(MOVLstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR)L l:(MOVLload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) => |
| 2066 | + ((ADD|SUB|AND|OR|XOR)Lmodify [off] {sym} ptr x mem) |
| 2067 | +(MOVLstore {sym} [off] ptr y:((BTC|BTR|BTS)L l:(MOVLload [off] {sym} ptr mem) <t> x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) => |
| 2068 | + ((BTC|BTR|BTS)Lmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem) |
2055 | 2069 | (MOVQstore {sym} [off] ptr y:((ADD|AND|OR|XOR)Qload x [off] {sym} ptr mem) mem) && y.Uses==1 && clobber(y) => ((ADD|AND|OR|XOR)Qmodify [off] {sym} ptr x mem) |
2056 | | -(MOVQstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Q l:(MOVQload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) => |
2057 | | - ((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Qmodify [off] {sym} ptr x mem) |
| 2070 | +(MOVQstore {sym} [off] ptr y:((ADD|SUB|AND|OR|XOR)Q l:(MOVQload [off] {sym} ptr mem) x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) => |
| 2071 | + ((ADD|SUB|AND|OR|XOR)Qmodify [off] {sym} ptr x mem) |
| 2072 | +(MOVQstore {sym} [off] ptr y:((BTC|BTR|BTS)Q l:(MOVQload [off] {sym} ptr mem) <t> x) mem) && y.Uses==1 && l.Uses==1 && clobber(y, l) => |
| 2073 | + ((BTC|BTR|BTS)Qmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem) |
2058 | 2074 |
|
2059 | 2075 | // Merge ADDQconst and LEAQ into atomic loads. |
2060 | 2076 | (MOV(Q|L|B)atomicload [off1] {sym} (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) => |
|
0 commit comments