|
88 | 88 | (Com32 x) -> (NOTW x) |
89 | 89 | (Com16 x) -> (NOTW x) |
90 | 90 | (Com8 x) -> (NOTW x) |
91 | | -(NOT x) && true -> (XORconst [-1] x) |
| 91 | +(NOT x) && true -> (XOR (MOVDconst [-1]) x) |
92 | 92 | (NOTW x) && true -> (XORWconst [-1] x) |
93 | 93 |
|
94 | 94 | // Lowering boolean ops |
|
480 | 480 | (MULLW x (MOVDconst [c])) -> (MULLWconst [c] x) |
481 | 481 | (MULLW (MOVDconst [c]) x) -> (MULLWconst [c] x) |
482 | 482 |
|
483 | | -(AND x (MOVDconst [c])) && is32Bit(c) -> (ANDconst [c] x) |
484 | | -(AND (MOVDconst [c]) x) && is32Bit(c) -> (ANDconst [c] x) |
| 483 | +// NILF instructions leave the high 32 bits unchanged which is |
| 484 | +// equivalent to the leftmost 32 bits being set. |
| 485 | +// TODO(mundaym): modify the assembler to accept 64-bit values |
| 486 | +// and use isU32Bit(^c). |
| 487 | +(AND x (MOVDconst [c])) && is32Bit(c) && c < 0 -> (ANDconst [c] x) |
| 488 | +(AND (MOVDconst [c]) x) && is32Bit(c) && c < 0 -> (ANDconst [c] x) |
485 | 489 | (ANDW x (MOVDconst [c])) -> (ANDWconst [c] x) |
486 | 490 | (ANDW (MOVDconst [c]) x) -> (ANDWconst [c] x) |
487 | 491 |
|
488 | 492 | (ANDWconst [c] (ANDWconst [d] x)) -> (ANDWconst [c & d] x) |
489 | 493 | (ANDconst [c] (ANDconst [d] x)) -> (ANDconst [c & d] x) |
490 | 494 |
|
491 | | -(OR x (MOVDconst [c])) && is32Bit(c) -> (ORconst [c] x) |
492 | | -(OR (MOVDconst [c]) x) && is32Bit(c) -> (ORconst [c] x) |
| 495 | +(OR x (MOVDconst [c])) && isU32Bit(c) -> (ORconst [c] x) |
| 496 | +(OR (MOVDconst [c]) x) && isU32Bit(c) -> (ORconst [c] x) |
493 | 497 | (ORW x (MOVDconst [c])) -> (ORWconst [c] x) |
494 | 498 | (ORW (MOVDconst [c]) x) -> (ORWconst [c] x) |
495 | 499 |
|
496 | | -(XOR x (MOVDconst [c])) && is32Bit(c) -> (XORconst [c] x) |
497 | | -(XOR (MOVDconst [c]) x) && is32Bit(c) -> (XORconst [c] x) |
| 500 | +(XOR x (MOVDconst [c])) && isU32Bit(c) -> (XORconst [c] x) |
| 501 | +(XOR (MOVDconst [c]) x) && isU32Bit(c) -> (XORconst [c] x) |
498 | 502 | (XORW x (MOVDconst [c])) -> (XORWconst [c] x) |
499 | 503 | (XORW (MOVDconst [c]) x) -> (XORWconst [c] x) |
500 | 504 |
|
|
521 | 525 | (CMPWU x (MOVDconst [c])) -> (CMPWUconst x [int64(uint32(c))]) |
522 | 526 | (CMPWU (MOVDconst [c]) x) -> (InvertFlags (CMPWUconst x [int64(uint32(c))])) |
523 | 527 |
|
524 | | -// Using MOVBZreg instead of AND is cheaper. |
525 | | -(ANDconst [0xFF] x) -> (MOVBZreg x) |
526 | | -(ANDconst [0xFFFF] x) -> (MOVHZreg x) |
527 | | -(ANDconst [0xFFFFFFFF] x) -> (MOVWZreg x) |
| 528 | +// Using MOV{W,H,B}Zreg instead of AND is cheaper. |
| 529 | +(AND (MOVDconst [0xFF]) x) -> (MOVBZreg x) |
| 530 | +(AND x (MOVDconst [0xFF])) -> (MOVBZreg x) |
| 531 | +(AND (MOVDconst [0xFFFF]) x) -> (MOVHZreg x) |
| 532 | +(AND x (MOVDconst [0xFFFF])) -> (MOVHZreg x) |
| 533 | +(AND (MOVDconst [0xFFFFFFFF]) x) -> (MOVWZreg x) |
| 534 | +(AND x (MOVDconst [0xFFFFFFFF])) -> (MOVWZreg x) |
| 535 | +(ANDWconst [0xFF] x) -> (MOVBZreg x) |
| 536 | +(ANDWconst [0xFFFF] x) -> (MOVHZreg x) |
528 | 537 |
|
529 | 538 | // strength reduction |
530 | 539 | (MULLDconst [-1] x) -> (NEG x) |
|
638 | 647 | (MOVWZload [off] {sym} ptr (MOVWstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x |
639 | 648 | (MOVDload [off] {sym} ptr (MOVDstore [off2] {sym2} ptr2 x _)) && sym == sym2 && off == off2 && isSamePtr(ptr, ptr2) -> x |
640 | 649 |
|
641 | | -// Fold extensions and ANDs together. |
642 | | -(MOVBZreg (ANDWconst [c] x)) -> (ANDconst [c & 0xff] x) |
643 | | -(MOVHZreg (ANDWconst [c] x)) -> (ANDconst [c & 0xffff] x) |
644 | | -(MOVWZreg (ANDWconst [c] x)) -> (ANDconst [c & 0xffffffff] x) |
645 | | -(MOVBreg (ANDWconst [c] x)) && c & 0x80 == 0 -> (ANDconst [c & 0x7f] x) |
646 | | -(MOVHreg (ANDWconst [c] x)) && c & 0x8000 == 0 -> (ANDconst [c & 0x7fff] x) |
647 | | -(MOVWreg (ANDWconst [c] x)) && c & 0x80000000 == 0 -> (ANDconst [c & 0x7fffffff] x) |
648 | | - |
649 | | -(MOVBZreg (ANDconst [c] x)) -> (ANDconst [c & 0xff] x) |
650 | | -(MOVHZreg (ANDconst [c] x)) -> (ANDconst [c & 0xffff] x) |
651 | | -(MOVWZreg (ANDconst [c] x)) -> (ANDconst [c & 0xffffffff] x) |
652 | | -(MOVBreg (ANDconst [c] x)) && c & 0x80 == 0 -> (ANDconst [c & 0x7f] x) |
653 | | -(MOVHreg (ANDconst [c] x)) && c & 0x8000 == 0 -> (ANDconst [c & 0x7fff] x) |
654 | | -(MOVWreg (ANDconst [c] x)) && c & 0x80000000 == 0 -> (ANDconst [c & 0x7fffffff] x) |
655 | | - |
656 | 650 | // Don't extend before storing |
657 | 651 | (MOVWstore [off] {sym} ptr (MOVWreg x) mem) -> (MOVWstore [off] {sym} ptr x mem) |
658 | 652 | (MOVHstore [off] {sym} ptr (MOVHreg x) mem) -> (MOVHstore [off] {sym} ptr x mem) |
|
951 | 945 | (NEGW (MOVDconst [c])) -> (MOVDconst [int64(int32(-c))]) |
952 | 946 | (MULLDconst [c] (MOVDconst [d])) -> (MOVDconst [c*d]) |
953 | 947 | (MULLWconst [c] (MOVDconst [d])) -> (MOVDconst [int64(int32(c*d))]) |
| 948 | +(AND (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [c&d]) |
954 | 949 | (ANDconst [c] (MOVDconst [d])) -> (MOVDconst [c&d]) |
955 | 950 | (ANDWconst [c] (MOVDconst [d])) -> (MOVDconst [c&d]) |
| 951 | +(OR (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [c|d]) |
956 | 952 | (ORconst [c] (MOVDconst [d])) -> (MOVDconst [c|d]) |
957 | 953 | (ORWconst [c] (MOVDconst [d])) -> (MOVDconst [c|d]) |
| 954 | +(XOR (MOVDconst [c]) (MOVDconst [d])) -> (MOVDconst [c^d]) |
958 | 955 | (XORconst [c] (MOVDconst [d])) -> (MOVDconst [c^d]) |
959 | 956 | (XORWconst [c] (MOVDconst [d])) -> (MOVDconst [c^d]) |
960 | | -(NOT (MOVDconst [c])) -> (MOVDconst [^c]) |
961 | | -(NOTW (MOVDconst [c])) -> (MOVDconst [^c]) |
962 | 957 |
|
963 | 958 | // generic simplifications |
964 | 959 | // TODO: more of this |
|
0 commit comments