|
614 | 614 | (MOVWLSX (ANDLconst [c] x)) && c & 0x8000 == 0 -> (ANDLconst [c & 0x7fff] x)
|
615 | 615 |
|
616 | 616 | // Don't extend before storing
|
617 |
| -(MOVWstore [off] {sym} ptr (MOVWLSX x) mem) -> (MOVWstore [off] {sym} ptr x mem) |
618 |
| -(MOVBstore [off] {sym} ptr (MOVBLSX x) mem) -> (MOVBstore [off] {sym} ptr x mem) |
619 |
| -(MOVWstore [off] {sym} ptr (MOVWLZX x) mem) -> (MOVWstore [off] {sym} ptr x mem) |
620 |
| -(MOVBstore [off] {sym} ptr (MOVBLZX x) mem) -> (MOVBstore [off] {sym} ptr x mem) |
| 617 | +(MOVWstore [off] {sym} ptr (MOVWL(S|Z)X x) mem) -> (MOVWstore [off] {sym} ptr x mem) |
| 618 | +(MOVBstore [off] {sym} ptr (MOVBL(S|Z)X x) mem) -> (MOVBstore [off] {sym} ptr x mem) |
621 | 619 |
|
622 | 620 | // fold constants into memory operations
|
623 | 621 | // Note that this is not always a good idea because if not all the uses of
|
624 | 622 | // the ADDQconst get eliminated, we still have to compute the ADDQconst and we now
|
625 | 623 | // have potentially two live values (ptr and (ADDQconst [off] ptr)) instead of one.
|
626 | 624 | // Nevertheless, let's do it!
|
627 |
| -(MOVLload [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(off1+off2) -> (MOVLload [off1+off2] {sym} ptr mem) |
628 |
| -(MOVWload [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(off1+off2) -> (MOVWload [off1+off2] {sym} ptr mem) |
629 |
| -(MOVBload [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(off1+off2) -> (MOVBload [off1+off2] {sym} ptr mem) |
630 |
| -(MOVSSload [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(off1+off2) -> (MOVSSload [off1+off2] {sym} ptr mem) |
631 |
| -(MOVSDload [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(off1+off2) -> (MOVSDload [off1+off2] {sym} ptr mem) |
632 |
| - |
633 |
| -(MOVLstore [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(off1+off2) -> (MOVLstore [off1+off2] {sym} ptr val mem) |
634 |
| -(MOVWstore [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(off1+off2) -> (MOVWstore [off1+off2] {sym} ptr val mem) |
635 |
| -(MOVBstore [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(off1+off2) -> (MOVBstore [off1+off2] {sym} ptr val mem) |
636 |
| -(MOVSSstore [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(off1+off2) -> (MOVSSstore [off1+off2] {sym} ptr val mem) |
637 |
| -(MOVSDstore [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(off1+off2) -> (MOVSDstore [off1+off2] {sym} ptr val mem) |
| 625 | +(MOV(L|W|B|SS|SD)load [off1] {sym} (ADDLconst [off2] ptr) mem) && is32Bit(off1+off2) -> (MOV(L|W|B|SS|SD)load [off1+off2] {sym} ptr mem) |
| 626 | +(MOV(L|W|B|SS|SD)store [off1] {sym} (ADDLconst [off2] ptr) val mem) && is32Bit(off1+off2) -> (MOV(L|W|B|SS|SD)store [off1+off2] {sym} ptr val mem) |
638 | 627 |
|
639 | 628 | ((ADD|SUB|MUL|AND|OR|XOR)Lload [off1] {sym} val (ADDLconst [off2] base) mem) && is32Bit(off1+off2) ->
|
640 | 629 | ((ADD|SUB|MUL|AND|OR|XOR)Lload [off1+off2] {sym} val base mem)
|
|
656 | 645 | (MOVBstoreconst [makeValAndOff(int64(int8(c)),off)] {sym} ptr mem)
|
657 | 646 |
|
658 | 647 | // Fold address offsets into constant stores.
|
659 |
| -(MOVLstoreconst [sc] {s} (ADDLconst [off] ptr) mem) && ValAndOff(sc).canAdd(off) -> |
660 |
| - (MOVLstoreconst [ValAndOff(sc).add(off)] {s} ptr mem) |
661 |
| -(MOVWstoreconst [sc] {s} (ADDLconst [off] ptr) mem) && ValAndOff(sc).canAdd(off) -> |
662 |
| - (MOVWstoreconst [ValAndOff(sc).add(off)] {s} ptr mem) |
663 |
| -(MOVBstoreconst [sc] {s} (ADDLconst [off] ptr) mem) && ValAndOff(sc).canAdd(off) -> |
664 |
| - (MOVBstoreconst [ValAndOff(sc).add(off)] {s} ptr mem) |
| 648 | +(MOV(L|W|B)storeconst [sc] {s} (ADDLconst [off] ptr) mem) && ValAndOff(sc).canAdd(off) -> |
| 649 | + (MOV(L|W|B)storeconst [ValAndOff(sc).add(off)] {s} ptr mem) |
665 | 650 |
|
666 | 651 | // We need to fold LEAQ into the MOVx ops so that the live variable analysis knows
|
667 | 652 | // what variables are being read/written by the ops.
|
|
671 | 656 | // a separate instruction gives us that register. Having the LEAL be
|
672 | 657 | // a separate instruction also allows it to be CSEd (which is good because
|
673 | 658 | // it compiles to a thunk call).
|
674 |
| -(MOVLload [off1] {sym1} (LEAL [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) |
| 659 | +(MOV(L|W|B|SS|SD|BLSX|WLSX)load [off1] {sym1} (LEAL [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) |
675 | 660 | && (base.Op != OpSB || !config.ctxt.Flag_shared) ->
|
676 |
| - (MOVLload [off1+off2] {mergeSym(sym1,sym2)} base mem) |
677 |
| -(MOVWload [off1] {sym1} (LEAL [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) |
678 |
| - && (base.Op != OpSB || !config.ctxt.Flag_shared) -> |
679 |
| - (MOVWload [off1+off2] {mergeSym(sym1,sym2)} base mem) |
680 |
| -(MOVBload [off1] {sym1} (LEAL [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) |
681 |
| - && (base.Op != OpSB || !config.ctxt.Flag_shared) -> |
682 |
| - (MOVBload [off1+off2] {mergeSym(sym1,sym2)} base mem) |
683 |
| -(MOVSSload [off1] {sym1} (LEAL [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) |
684 |
| - && (base.Op != OpSB || !config.ctxt.Flag_shared) -> |
685 |
| - (MOVSSload [off1+off2] {mergeSym(sym1,sym2)} base mem) |
686 |
| -(MOVSDload [off1] {sym1} (LEAL [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) |
687 |
| - && (base.Op != OpSB || !config.ctxt.Flag_shared) -> |
688 |
| - (MOVSDload [off1+off2] {mergeSym(sym1,sym2)} base mem) |
| 661 | + (MOV(L|W|B|SS|SD|BLSX|WLSX)load [off1+off2] {mergeSym(sym1,sym2)} base mem) |
689 | 662 |
|
690 |
| -(MOVBLSXload [off1] {sym1} (LEAL [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) |
| 663 | +(MOV(L|W|B|SS|SD)store [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) |
691 | 664 | && (base.Op != OpSB || !config.ctxt.Flag_shared) ->
|
692 |
| - (MOVBLSXload [off1+off2] {mergeSym(sym1,sym2)} base mem) |
693 |
| -(MOVWLSXload [off1] {sym1} (LEAL [off2] {sym2} base) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) |
694 |
| - && (base.Op != OpSB || !config.ctxt.Flag_shared) -> |
695 |
| - (MOVWLSXload [off1+off2] {mergeSym(sym1,sym2)} base mem) |
| 665 | + (MOV(L|W|B|SS|SD)store [off1+off2] {mergeSym(sym1,sym2)} base val mem) |
696 | 666 |
|
697 |
| -(MOVLstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) |
698 |
| - && (base.Op != OpSB || !config.ctxt.Flag_shared) -> |
699 |
| - (MOVLstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) |
700 |
| -(MOVWstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) |
701 |
| - && (base.Op != OpSB || !config.ctxt.Flag_shared) -> |
702 |
| - (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) |
703 |
| -(MOVBstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) |
704 |
| - && (base.Op != OpSB || !config.ctxt.Flag_shared) -> |
705 |
| - (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) |
706 |
| -(MOVSSstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) |
707 |
| - && (base.Op != OpSB || !config.ctxt.Flag_shared) -> |
708 |
| - (MOVSSstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) |
709 |
| -(MOVSDstore [off1] {sym1} (LEAL [off2] {sym2} base) val mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) |
710 |
| - && (base.Op != OpSB || !config.ctxt.Flag_shared) -> |
711 |
| - (MOVSDstore [off1+off2] {mergeSym(sym1,sym2)} base val mem) |
712 |
| - |
713 |
| -(MOVLstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) |
714 |
| - && (ptr.Op != OpSB || !config.ctxt.Flag_shared) -> |
715 |
| - (MOVLstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) |
716 |
| -(MOVWstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) |
717 |
| - && (ptr.Op != OpSB || !config.ctxt.Flag_shared) -> |
718 |
| - (MOVWstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) |
719 |
| -(MOVBstoreconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) |
| 667 | +(MOV(L|W|B)storeconst [sc] {sym1} (LEAL [off] {sym2} ptr) mem) && canMergeSym(sym1, sym2) && ValAndOff(sc).canAdd(off) |
720 | 668 | && (ptr.Op != OpSB || !config.ctxt.Flag_shared) ->
|
721 |
| - (MOVBstoreconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) |
| 669 | + (MOV(L|W|B)storeconst [ValAndOff(sc).add(off)] {mergeSym(sym1, sym2)} ptr mem) |
722 | 670 |
|
723 | 671 | // generating indexed loads and stores
|
724 | 672 | (MOV(B|W|L|SS|SD)load [off1] {sym1} (LEAL1 [off2] {sym2} ptr idx) mem) && is32Bit(off1+off2) && canMergeSym(sym1, sym2) ->
|
|
0 commit comments