|
624 | 624 | // Recognize bit setting (a |= 1<<b) and toggling (a ^= 1<<b) |
625 | 625 | (OR(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y) x) => (BTS(Q|L) x y) |
626 | 626 | (XOR(Q|L) (SHL(Q|L) (MOV(Q|L)const [1]) y) x) => (BTC(Q|L) x y) |
627 | | -(ORLmodify [off] {sym} ptr s:(SHLL (MOVLconst [1]) <t> x) mem) => |
628 | | - (BTSLmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem) |
629 | | -(ORQmodify [off] {sym} ptr s:(SHLQ (MOVQconst [1]) <t> x) mem) => |
630 | | - (BTSQmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem) |
631 | | -(XORLmodify [off] {sym} ptr s:(SHLL (MOVLconst [1]) <t> x) mem) => |
632 | | - (BTCLmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem) |
633 | | -(XORQmodify [off] {sym} ptr s:(SHLQ (MOVQconst [1]) <t> x) mem) => |
634 | | - (BTCQmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem) |
635 | 627 |
|
636 | 628 | // Convert ORconst into BTS, if the code gets smaller, with boundary being |
637 | 629 | // (ORL $40,AX is 3 bytes, ORL $80,AX is 6 bytes). |
|
654 | 646 | => (BTRQconst [int8(log64(^c))] x) |
655 | 647 | (ANDL (MOVLconst [c]) x) && isUint32PowerOfTwo(int64(^c)) && uint64(^c) >= 128 |
656 | 648 | => (BTRLconst [int8(log32(^c))] x) |
657 | | -(ANDLmodify [off] {sym} ptr (NOTL s:(SHLL (MOVLconst [1]) <t> x)) mem) => |
658 | | - (BTRLmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem) |
659 | | -(ANDQmodify [off] {sym} ptr (NOTQ s:(SHLQ (MOVQconst [1]) <t> x)) mem) => |
660 | | - (BTRQmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem) |
661 | 649 |
|
662 | 650 | // Special-case bit patterns on first/last bit. |
663 | 651 | // generic.rules changes ANDs of high-part/low-part masks into a couple of shifts, |
|
1126 | 1114 | ((ADD|SUB|MUL|DIV)SSload [off1+off2] {sym} val base mem) |
1127 | 1115 | ((ADD|SUB|MUL|DIV)SDload [off1] {sym} val (ADDQconst [off2] base) mem) && is32Bit(int64(off1)+int64(off2)) => |
1128 | 1116 | ((ADD|SUB|MUL|DIV)SDload [off1+off2] {sym} val base mem) |
1129 | | -((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) => |
1130 | | - ((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem) |
1131 | | -((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) => |
1132 | | - ((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem) |
1133 | | -((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Qmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) => |
1134 | | - ((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Qmodify [off1+off2] {sym} base val mem) |
1135 | | -((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Lmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) => |
1136 | | - ((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Lmodify [off1+off2] {sym} base val mem) |
| 1117 | +((ADD|AND|OR|XOR)Qconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) => |
| 1118 | + ((ADD|AND|OR|XOR)Qconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem) |
| 1119 | +((ADD|AND|OR|XOR)Lconstmodify [valoff1] {sym} (ADDQconst [off2] base) mem) && ValAndOff(valoff1).canAdd32(off2) => |
| 1120 | + ((ADD|AND|OR|XOR)Lconstmodify [ValAndOff(valoff1).addOffset32(off2)] {sym} base mem) |
| 1121 | +((ADD|SUB|AND|OR|XOR)Qmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) => |
| 1122 | + ((ADD|SUB|AND|OR|XOR)Qmodify [off1+off2] {sym} base val mem) |
| 1123 | +((ADD|SUB|AND|OR|XOR)Lmodify [off1] {sym} (ADDQconst [off2] base) val mem) && is32Bit(int64(off1)+int64(off2)) => |
| 1124 | + ((ADD|SUB|AND|OR|XOR)Lmodify [off1+off2] {sym} base val mem) |
1137 | 1125 |
|
1138 | 1126 | // Fold constants into stores. |
1139 | 1127 | (MOVQstore [off] {sym} ptr (MOVQconst [c]) mem) && validVal(c) => |
|
1181 | 1169 | ((ADD|SUB|MUL|DIV)SDload [off1] {sym1} val (LEAQ [off2] {sym2} base) mem) |
1182 | 1170 | && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => |
1183 | 1171 | ((ADD|SUB|MUL|DIV)SDload [off1+off2] {mergeSym(sym1,sym2)} val base mem) |
1184 | | -((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) |
| 1172 | +((ADD|AND|OR|XOR)Qconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) |
1185 | 1173 | && ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) => |
1186 | | - ((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) |
1187 | | -((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) |
| 1174 | + ((ADD|AND|OR|XOR)Qconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) |
| 1175 | +((ADD|AND|OR|XOR)Lconstmodify [valoff1] {sym1} (LEAQ [off2] {sym2} base) mem) |
1188 | 1176 | && ValAndOff(valoff1).canAdd32(off2) && canMergeSym(sym1, sym2) => |
1189 | | - ((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) |
1190 | | -((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Qmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) |
| 1177 | + ((ADD|AND|OR|XOR)Lconstmodify [ValAndOff(valoff1).addOffset32(off2)] {mergeSym(sym1,sym2)} base mem) |
| 1178 | +((ADD|SUB|AND|OR|XOR)Qmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) |
1191 | 1179 | && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => |
1192 | | - ((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Qmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) |
1193 | | -((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Lmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) |
| 1180 | + ((ADD|SUB|AND|OR|XOR)Qmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) |
| 1181 | +((ADD|SUB|AND|OR|XOR)Lmodify [off1] {sym1} (LEAQ [off2] {sym2} base) val mem) |
1194 | 1182 | && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => |
1195 | | - ((ADD|SUB|AND|OR|XOR|BTC|BTR|BTS)Lmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) |
| 1183 | + ((ADD|SUB|AND|OR|XOR)Lmodify [off1+off2] {mergeSym(sym1,sym2)} base val mem) |
1196 | 1184 |
|
1197 | 1185 | // fold LEAQs together |
1198 | 1186 | (LEAQ [off1] {sym1} (LEAQ [off2] {sym2} x)) && is32Bit(int64(off1)+int64(off2)) && canMergeSym(sym1, sym2) => |
|
2078 | 2066 | (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) |
2079 | 2067 | (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) => |
2080 | 2068 | ((ADD|SUB|AND|OR|XOR)Lmodify [off] {sym} ptr x mem) |
2081 | | -(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) => |
2082 | | - ((BTC|BTR|BTS)Lmodify [off] {sym} ptr (ANDLconst <t> [31] x) mem) |
2083 | 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) |
2084 | 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) => |
2085 | 2071 | ((ADD|SUB|AND|OR|XOR)Qmodify [off] {sym} ptr x mem) |
2086 | | -(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) => |
2087 | | - ((BTC|BTR|BTS)Qmodify [off] {sym} ptr (ANDQconst <t> [63] x) mem) |
2088 | 2072 |
|
2089 | 2073 | // Merge ADDQconst and LEAQ into atomic loads. |
2090 | 2074 | (MOV(Q|L|B)atomicload [off1] {sym} (ADDQconst [off2] ptr) mem) && is32Bit(int64(off1)+int64(off2)) => |
|
2138 | 2122 | (MOVWQZX (MOVBQZX x)) => (MOVBQZX x) |
2139 | 2123 | (MOVBQZX (MOVBQZX x)) => (MOVBQZX x) |
2140 | 2124 |
|
2141 | | -(MOVQstore [off] {sym} ptr a:((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem) |
| 2125 | +(MOVQstore [off] {sym} ptr a:((ADD|AND|OR|XOR)Qconst [c] l:(MOVQload [off] {sym} ptr2 mem)) mem) |
2142 | 2126 | && isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a) => |
2143 | | - ((ADD|AND|OR|XOR|BTC|BTR|BTS)Qconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem) |
2144 | | -(MOVLstore [off] {sym} ptr a:((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem) |
| 2127 | + ((ADD|AND|OR|XOR)Qconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem) |
| 2128 | +(MOVLstore [off] {sym} ptr a:((ADD|AND|OR|XOR)Lconst [c] l:(MOVLload [off] {sym} ptr2 mem)) mem) |
2145 | 2129 | && isSamePtr(ptr, ptr2) && a.Uses == 1 && l.Uses == 1 && clobber(l, a) => |
2146 | | - ((ADD|AND|OR|XOR|BTC|BTR|BTS)Lconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem) |
| 2130 | + ((ADD|AND|OR|XOR)Lconstmodify {sym} [makeValAndOff(int32(c),off)] ptr mem) |
2147 | 2131 |
|
2148 | 2132 | // float <-> int register moves, with no conversion. |
2149 | 2133 | // These come up when compiling math.{Float{32,64}bits,Float{32,64}frombits}. |
|
0 commit comments