OLD | NEW |
1 //===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===// | 1 //===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file defines an instruction selector for the ARM target. | 10 // This file defines an instruction selector for the ARM target. |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 } | 105 } |
106 bool SelectShiftImmShifterOperand(SDValue N, SDValue &A, | 106 bool SelectShiftImmShifterOperand(SDValue N, SDValue &A, |
107 SDValue &B) { | 107 SDValue &B) { |
108 // Don't apply the profitability check | 108 // Don't apply the profitability check |
109 return SelectImmShifterOperand(N, A, B, false); | 109 return SelectImmShifterOperand(N, A, B, false); |
110 } | 110 } |
111 | 111 |
112 bool SelectAddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm); | 112 bool SelectAddrModeImm12(SDValue N, SDValue &Base, SDValue &OffImm); |
113 bool SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc); | 113 bool SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc); |
114 | 114 |
115 AddrMode2Type SelectAddrMode2Worker(SDValue N, SDValue &Base, | 115 AddrMode2Type SelectAddrMode2Worker(SDNode *Op, SDValue N, SDValue &Base, |
116 SDValue &Offset, SDValue &Opc); | 116 SDValue &Offset, SDValue &Opc); |
117 bool SelectAddrMode2Base(SDValue N, SDValue &Base, SDValue &Offset, | 117 bool SelectAddrMode2Base(SDNode *Op, |
| 118 SDValue N, SDValue &Base, SDValue &Offset, |
118 SDValue &Opc) { | 119 SDValue &Opc) { |
119 return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_BASE; | 120 return SelectAddrMode2Worker(Op, N, Base, Offset, Opc) == AM2_BASE; |
120 } | 121 } |
121 | 122 |
122 bool SelectAddrMode2ShOp(SDValue N, SDValue &Base, SDValue &Offset, | 123 bool SelectAddrMode2ShOp(SDNode *Op, |
| 124 SDValue N, SDValue &Base, SDValue &Offset, |
123 SDValue &Opc) { | 125 SDValue &Opc) { |
124 return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_SHOP; | 126 return SelectAddrMode2Worker(Op, N, Base, Offset, Opc) == AM2_SHOP; |
125 } | 127 } |
126 | 128 |
127 bool SelectAddrMode2(SDValue N, SDValue &Base, SDValue &Offset, | 129 bool SelectAddrMode2(SDNode *Op, |
| 130 SDValue N, SDValue &Base, SDValue &Offset, |
128 SDValue &Opc) { | 131 SDValue &Opc) { |
129 SelectAddrMode2Worker(N, Base, Offset, Opc); | 132 SelectAddrMode2Worker(Op, N, Base, Offset, Opc); |
130 // return SelectAddrMode2ShOp(N, Base, Offset, Opc); | 133 // return SelectAddrMode2ShOp(N, Base, Offset, Opc); |
131 // This always matches one way or another. | 134 // This always matches one way or another. |
132 return true; | 135 return true; |
133 } | 136 } |
134 | 137 |
135 bool SelectCMOVPred(SDValue N, SDValue &Pred, SDValue &Reg) { | 138 bool SelectCMOVPred(SDValue N, SDValue &Pred, SDValue &Reg) { |
136 const ConstantSDNode *CN = cast<ConstantSDNode>(N); | 139 const ConstantSDNode *CN = cast<ConstantSDNode>(N); |
137 Pred = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32); | 140 Pred = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32); |
138 Reg = CurDAG->getRegister(ARM::CPSR, MVT::i32); | 141 Reg = CurDAG->getRegister(ARM::CPSR, MVT::i32); |
139 return true; | 142 return true; |
140 } | 143 } |
141 | 144 |
142 bool SelectAddrMode2OffsetReg(SDNode *Op, SDValue N, | 145 bool SelectAddrMode2OffsetReg(SDNode *Op, SDValue N, |
143 SDValue &Offset, SDValue &Opc); | 146 SDValue &Offset, SDValue &Opc); |
144 bool SelectAddrMode2OffsetImm(SDNode *Op, SDValue N, | 147 bool SelectAddrMode2OffsetImm(SDNode *Op, SDValue N, |
145 SDValue &Offset, SDValue &Opc); | 148 SDValue &Offset, SDValue &Opc); |
146 bool SelectAddrMode2OffsetImmPre(SDNode *Op, SDValue N, | 149 bool SelectAddrMode2OffsetImmPre(SDNode *Op, SDValue N, |
147 SDValue &Offset, SDValue &Opc); | 150 SDValue &Offset, SDValue &Opc); |
148 bool SelectAddrOffsetNone(SDValue N, SDValue &Base); | 151 bool SelectAddrOffsetNone(SDValue N, SDValue &Base); |
149 bool SelectAddrMode3(SDValue N, SDValue &Base, | 152 bool SelectAddrMode3(SDNode *Op, SDValue N, SDValue &Base, |
150 SDValue &Offset, SDValue &Opc); | 153 SDValue &Offset, SDValue &Opc); |
151 bool SelectAddrMode3Offset(SDNode *Op, SDValue N, | 154 bool SelectAddrMode3Offset(SDNode *Op, SDValue N, |
152 SDValue &Offset, SDValue &Opc); | 155 SDValue &Offset, SDValue &Opc); |
153 bool SelectAddrMode5(SDValue N, SDValue &Base, | 156 bool SelectAddrMode5(SDValue N, SDValue &Base, |
154 SDValue &Offset); | 157 SDValue &Offset); |
155 bool SelectAddrMode6(SDNode *Parent, SDValue N, SDValue &Addr,SDValue &Align); | 158 bool SelectAddrMode6(SDNode *Parent, SDValue N, SDValue &Addr,SDValue &Align); |
156 bool SelectAddrMode6Offset(SDNode *Op, SDValue N, SDValue &Offset); | 159 bool SelectAddrMode6Offset(SDNode *Op, SDValue N, SDValue &Offset); |
157 | 160 |
158 bool SelectAddrModePC(SDValue N, SDValue &Offset, SDValue &Label); | 161 bool SelectAddrModePC(SDValue N, SDValue &Offset, SDValue &Label); |
159 | 162 |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 if (RHS) return false; | 510 if (RHS) return false; |
508 | 511 |
509 ShReg = N.getOperand(1); | 512 ShReg = N.getOperand(1); |
510 if (CheckProfitability && !isShifterOpProfitable(N, ShOpcVal, ShImmVal)) | 513 if (CheckProfitability && !isShifterOpProfitable(N, ShOpcVal, ShImmVal)) |
511 return false; | 514 return false; |
512 Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal), | 515 Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal), |
513 MVT::i32); | 516 MVT::i32); |
514 return true; | 517 return true; |
515 } | 518 } |
516 | 519 |
| 520 // @LOCALMOD-START |
| 521 static bool ShouldOperandBeUnwrappedForUseAsBaseAddress( |
| 522 SDValue& N, const ARMSubtarget* Subtarget) { |
| 523 assert (N.getOpcode() == ARMISD::Wrapper); |
| 524 // Never use this transformation if constant island pools are disallowed |
| 525 if (!Subtarget->useConstIslands()) return false; |
| 526 |
| 527 // explain why we do not want to use this for TargetGlobalAddress |
| 528 if (N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress) return true; |
| 529 return false; |
| 530 } |
| 531 // @LOCALMOD-END |
517 | 532 |
518 bool ARMDAGToDAGISel::SelectAddrModeImm12(SDValue N, | 533 bool ARMDAGToDAGISel::SelectAddrModeImm12(SDValue N, |
519 SDValue &Base, | 534 SDValue &Base, |
520 SDValue &OffImm) { | 535 SDValue &OffImm) { |
521 // Match simple R + imm12 operands. | 536 // Match simple R + imm12 operands. |
522 | 537 |
523 // Base only. | 538 // Base only. |
524 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB && | 539 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB && |
525 !CurDAG->isBaseWithConstantOffset(N)) { | 540 !CurDAG->isBaseWithConstantOffset(N)) { |
526 if (N.getOpcode() == ISD::FrameIndex) { | 541 if (N.getOpcode() == ISD::FrameIndex) { |
527 // Match frame index. | 542 // Match frame index. |
528 int FI = cast<FrameIndexSDNode>(N)->getIndex(); | 543 int FI = cast<FrameIndexSDNode>(N)->getIndex(); |
529 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy()); | 544 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy()); |
530 OffImm = CurDAG->getTargetConstant(0, MVT::i32); | 545 OffImm = CurDAG->getTargetConstant(0, MVT::i32); |
531 return true; | 546 return true; |
532 } | 547 } |
533 | 548 |
534 if (N.getOpcode() == ARMISD::Wrapper && | 549 if (N.getOpcode() == ARMISD::Wrapper && |
535 N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress) { | 550 // @LOCALMOD |
| 551 ShouldOperandBeUnwrappedForUseAsBaseAddress(N, Subtarget)) { |
536 Base = N.getOperand(0); | 552 Base = N.getOperand(0); |
537 } else | 553 } else |
538 Base = N; | 554 Base = N; |
539 OffImm = CurDAG->getTargetConstant(0, MVT::i32); | 555 OffImm = CurDAG->getTargetConstant(0, MVT::i32); |
540 return true; | 556 return true; |
541 } | 557 } |
542 | 558 |
543 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { | 559 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { |
544 int RHSC = (int)RHS->getSExtValue(); | 560 int RHSC = (int)RHS->getSExtValue(); |
545 if (N.getOpcode() == ISD::SUB) | 561 if (N.getOpcode() == ISD::SUB) |
(...skipping 13 matching lines...) Expand all Loading... |
559 // Base only. | 575 // Base only. |
560 Base = N; | 576 Base = N; |
561 OffImm = CurDAG->getTargetConstant(0, MVT::i32); | 577 OffImm = CurDAG->getTargetConstant(0, MVT::i32); |
562 return true; | 578 return true; |
563 } | 579 } |
564 | 580 |
565 | 581 |
566 | 582 |
567 bool ARMDAGToDAGISel::SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, | 583 bool ARMDAGToDAGISel::SelectLdStSOReg(SDValue N, SDValue &Base, SDValue &Offset, |
568 SDValue &Opc) { | 584 SDValue &Opc) { |
| 585 // @LOCALMOD-BEGIN |
| 586 // Disallow offsets of Reg + Reg (which may escape sandbox). |
| 587 if (Subtarget->isTargetNaCl()) |
| 588 return false; |
| 589 // @LOCALMOD-END |
569 if (N.getOpcode() == ISD::MUL && | 590 if (N.getOpcode() == ISD::MUL && |
570 ((!Subtarget->isLikeA9() && !Subtarget->isSwift()) || N.hasOneUse())) { | 591 ((!Subtarget->isLikeA9() && !Subtarget->isSwift()) || N.hasOneUse())) { |
571 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { | 592 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { |
572 // X * [3,5,9] -> X + X * [2,4,8] etc. | 593 // X * [3,5,9] -> X + X * [2,4,8] etc. |
573 int RHSC = (int)RHS->getZExtValue(); | 594 int RHSC = (int)RHS->getZExtValue(); |
574 if (RHSC & 1) { | 595 if (RHSC & 1) { |
575 RHSC = RHSC & ~1; | 596 RHSC = RHSC & ~1; |
576 ARM_AM::AddrOpc AddSub = ARM_AM::add; | 597 ARM_AM::AddrOpc AddSub = ARM_AM::add; |
577 if (RHSC < 0) { | 598 if (RHSC < 0) { |
578 AddSub = ARM_AM::sub; | 599 AddSub = ARM_AM::sub; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 } | 675 } |
655 | 676 |
656 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), | 677 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal), |
657 MVT::i32); | 678 MVT::i32); |
658 return true; | 679 return true; |
659 } | 680 } |
660 | 681 |
661 | 682 |
662 //----- | 683 //----- |
663 | 684 |
664 AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDValue N, | 685 AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDNode *Op, |
| 686 SDValue N, |
665 SDValue &Base, | 687 SDValue &Base, |
666 SDValue &Offset, | 688 SDValue &Offset, |
667 SDValue &Opc) { | 689 SDValue &Opc) { |
| 690 // @LOCALMOD-START |
| 691 // Avoid two reg addressing mode for loads and stores |
| 692 const bool restrict_addressing_modes_for_nacl = Subtarget->isTargetNaCl() && |
| 693 (Op->getOpcode() == ISD::LOAD || Op->getOpcode() == ISD::STORE); |
| 694 // This is neither a sandboxable load nor a sandboxable store. |
| 695 if (!restrict_addressing_modes_for_nacl) { |
| 696 // @LOCALMOD-END |
| 697 |
668 if (N.getOpcode() == ISD::MUL && | 698 if (N.getOpcode() == ISD::MUL && |
669 (!(Subtarget->isLikeA9() || Subtarget->isSwift()) || N.hasOneUse())) { | 699 (!(Subtarget->isLikeA9() || Subtarget->isSwift()) || N.hasOneUse())) { |
670 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { | 700 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { |
671 // X * [3,5,9] -> X + X * [2,4,8] etc. | 701 // X * [3,5,9] -> X + X * [2,4,8] etc. |
672 int RHSC = (int)RHS->getZExtValue(); | 702 int RHSC = (int)RHS->getZExtValue(); |
673 if (RHSC & 1) { | 703 if (RHSC & 1) { |
674 RHSC = RHSC & ~1; | 704 RHSC = RHSC & ~1; |
675 ARM_AM::AddrOpc AddSub = ARM_AM::add; | 705 ARM_AM::AddrOpc AddSub = ARM_AM::add; |
676 if (RHSC < 0) { | 706 if (RHSC < 0) { |
677 AddSub = ARM_AM::sub; | 707 AddSub = ARM_AM::sub; |
678 RHSC = - RHSC; | 708 RHSC = - RHSC; |
679 } | 709 } |
680 if (isPowerOf2_32(RHSC)) { | 710 if (isPowerOf2_32(RHSC)) { |
681 unsigned ShAmt = Log2_32(RHSC); | 711 unsigned ShAmt = Log2_32(RHSC); |
682 Base = Offset = N.getOperand(0); | 712 Base = Offset = N.getOperand(0); |
683 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, | 713 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, |
684 ARM_AM::lsl), | 714 ARM_AM::lsl), |
685 MVT::i32); | 715 MVT::i32); |
686 return AM2_SHOP; | 716 return AM2_SHOP; |
687 } | 717 } |
688 } | 718 } |
689 } | 719 } |
690 } | 720 } |
| 721 } // @LOCALMOD |
691 | 722 |
692 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB && | 723 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB && |
693 // ISD::OR that is equivalent to an ADD. | 724 // ISD::OR that is equivalent to an ADD. |
694 !CurDAG->isBaseWithConstantOffset(N)) { | 725 !CurDAG->isBaseWithConstantOffset(N)) { |
695 Base = N; | 726 Base = N; |
696 if (N.getOpcode() == ISD::FrameIndex) { | 727 if (N.getOpcode() == ISD::FrameIndex) { |
697 int FI = cast<FrameIndexSDNode>(N)->getIndex(); | 728 int FI = cast<FrameIndexSDNode>(N)->getIndex(); |
698 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy()); | 729 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy()); |
699 } else if (N.getOpcode() == ARMISD::Wrapper && | 730 } else if (N.getOpcode() == ARMISD::Wrapper && |
700 N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress) { | 731 // @LOCALMOD |
| 732 ShouldOperandBeUnwrappedForUseAsBaseAddress(N, Subtarget)) { |
701 Base = N.getOperand(0); | 733 Base = N.getOperand(0); |
702 } | 734 } |
703 Offset = CurDAG->getRegister(0, MVT::i32); | 735 Offset = CurDAG->getRegister(0, MVT::i32); |
704 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0, | 736 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0, |
705 ARM_AM::no_shift), | 737 ARM_AM::no_shift), |
706 MVT::i32); | 738 MVT::i32); |
707 return AM2_BASE; | 739 return AM2_BASE; |
708 } | 740 } |
709 | 741 |
710 // Match simple R +/- imm12 operands. | 742 // Match simple R +/- imm12 operands. |
(...skipping 22 matching lines...) Expand all Loading... |
733 | 765 |
734 if ((Subtarget->isLikeA9() || Subtarget->isSwift()) && !N.hasOneUse()) { | 766 if ((Subtarget->isLikeA9() || Subtarget->isSwift()) && !N.hasOneUse()) { |
735 // Compute R +/- (R << N) and reuse it. | 767 // Compute R +/- (R << N) and reuse it. |
736 Base = N; | 768 Base = N; |
737 Offset = CurDAG->getRegister(0, MVT::i32); | 769 Offset = CurDAG->getRegister(0, MVT::i32); |
738 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0, | 770 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0, |
739 ARM_AM::no_shift), | 771 ARM_AM::no_shift), |
740 MVT::i32); | 772 MVT::i32); |
741 return AM2_BASE; | 773 return AM2_BASE; |
742 } | 774 } |
| 775 |
| 776 // @LOCALMOD-START |
| 777 // Keep load and store addressing modes simple |
| 778 if (restrict_addressing_modes_for_nacl) { |
| 779 Base = N; |
| 780 if (N.getOpcode() == ISD::FrameIndex) { |
| 781 int FI = cast<FrameIndexSDNode>(N)->getIndex(); |
| 782 Base = CurDAG->getTargetFrameIndex(FI, |
| 783 getTargetLowering()->getPointerTy()); |
| 784 } else if (N.getOpcode() == ARMISD::Wrapper) { |
| 785 Base = N.getOperand(0); |
| 786 } |
| 787 Offset = CurDAG->getRegister(0, MVT::i32); |
| 788 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0, |
| 789 ARM_AM::no_shift), |
| 790 MVT::i32); |
| 791 return AM2_BASE; |
| 792 } |
| 793 // @LOCALMOD-END |
743 | 794 |
744 // Otherwise this is R +/- [possibly shifted] R. | 795 // Otherwise this is R +/- [possibly shifted] R. |
745 ARM_AM::AddrOpc AddSub = N.getOpcode() != ISD::SUB ? ARM_AM::add:ARM_AM::sub; | 796 ARM_AM::AddrOpc AddSub = N.getOpcode() != ISD::SUB ? ARM_AM::add:ARM_AM::sub; |
746 ARM_AM::ShiftOpc ShOpcVal = | 797 ARM_AM::ShiftOpc ShOpcVal = |
747 ARM_AM::getShiftOpcForNode(N.getOperand(1).getOpcode()); | 798 ARM_AM::getShiftOpcForNode(N.getOperand(1).getOpcode()); |
748 unsigned ShAmt = 0; | 799 unsigned ShAmt = 0; |
749 | 800 |
750 Base = N.getOperand(0); | 801 Base = N.getOperand(0); |
751 Offset = N.getOperand(1); | 802 Offset = N.getOperand(1); |
752 | 803 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 unsigned Opcode = Op->getOpcode(); | 852 unsigned Opcode = Op->getOpcode(); |
802 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) | 853 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) |
803 ? cast<LoadSDNode>(Op)->getAddressingMode() | 854 ? cast<LoadSDNode>(Op)->getAddressingMode() |
804 : cast<StoreSDNode>(Op)->getAddressingMode(); | 855 : cast<StoreSDNode>(Op)->getAddressingMode(); |
805 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) | 856 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC) |
806 ? ARM_AM::add : ARM_AM::sub; | 857 ? ARM_AM::add : ARM_AM::sub; |
807 int Val; | 858 int Val; |
808 if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) | 859 if (isScaledConstantInRange(N, /*Scale=*/1, 0, 0x1000, Val)) |
809 return false; | 860 return false; |
810 | 861 |
| 862 // @LOCALMOD-BEGIN |
| 863 // Avoid two reg addressing mode for loads and stores |
| 864 const bool restrict_addressing_modes_for_nacl = Subtarget->isTargetNaCl() && |
| 865 (Op->getOpcode() == ISD::LOAD || Op->getOpcode() == ISD::STORE); |
| 866 // @LOCALMOD-END |
| 867 |
811 Offset = N; | 868 Offset = N; |
812 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode()); | 869 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOpcode()); |
813 unsigned ShAmt = 0; | 870 unsigned ShAmt = 0; |
814 if (ShOpcVal != ARM_AM::no_shift) { | 871 if (ShOpcVal != ARM_AM::no_shift) { |
815 // Check to see if the RHS of the shift is a constant, if not, we can't fold | 872 // Check to see if the RHS of the shift is a constant, if not, we can't fold |
816 // it. | 873 // it. |
817 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) { | 874 |
| 875 //if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) { |
| 876 ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1)); |
| 877 // @LOCALMOD-BEGIN |
| 878 // Neither a sandboxable load nor a sandboxable store. |
| 879 if (!restrict_addressing_modes_for_nacl && Sh ) { |
| 880 // @LOCALMOD-END |
818 ShAmt = Sh->getZExtValue(); | 881 ShAmt = Sh->getZExtValue(); |
819 if (isShifterOpProfitable(N, ShOpcVal, ShAmt)) | 882 if (isShifterOpProfitable(N, ShOpcVal, ShAmt)) |
820 Offset = N.getOperand(0); | 883 Offset = N.getOperand(0); |
821 else { | 884 else { |
822 ShAmt = 0; | 885 ShAmt = 0; |
823 ShOpcVal = ARM_AM::no_shift; | 886 ShOpcVal = ARM_AM::no_shift; |
824 } | 887 } |
825 } else { | 888 } else { |
826 ShOpcVal = ARM_AM::no_shift; | 889 ShOpcVal = ARM_AM::no_shift; |
827 } | 890 } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 } | 933 } |
871 | 934 |
872 return false; | 935 return false; |
873 } | 936 } |
874 | 937 |
875 bool ARMDAGToDAGISel::SelectAddrOffsetNone(SDValue N, SDValue &Base) { | 938 bool ARMDAGToDAGISel::SelectAddrOffsetNone(SDValue N, SDValue &Base) { |
876 Base = N; | 939 Base = N; |
877 return true; | 940 return true; |
878 } | 941 } |
879 | 942 |
880 bool ARMDAGToDAGISel::SelectAddrMode3(SDValue N, | 943 bool ARMDAGToDAGISel::SelectAddrMode3(SDNode *Op, SDValue N, |
881 SDValue &Base, SDValue &Offset, | 944 SDValue &Base, SDValue &Offset, |
882 SDValue &Opc) { | 945 SDValue &Opc) { |
| 946 // @LOCALMOD-START |
| 947 // Avoid two reg addressing mode for loads and stores |
| 948 const bool restrict_addressing_modes_for_nacl = Subtarget->isTargetNaCl() && |
| 949 (Op->getOpcode() == ISD::LOAD || Op->getOpcode() == ISD::STORE); |
| 950 if (!restrict_addressing_modes_for_nacl) { |
| 951 // @LOCALMOD-END |
883 if (N.getOpcode() == ISD::SUB) { | 952 if (N.getOpcode() == ISD::SUB) { |
884 // X - C is canonicalize to X + -C, no need to handle it here. | 953 // X - C is canonicalize to X + -C, no need to handle it here. |
885 Base = N.getOperand(0); | 954 Base = N.getOperand(0); |
886 Offset = N.getOperand(1); | 955 Offset = N.getOperand(1); |
887 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0),MVT::i32); | 956 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0),MVT::i32); |
888 return true; | 957 return true; |
889 } | 958 } |
| 959 } // @LOCALMOD-END |
890 | 960 |
891 if (!CurDAG->isBaseWithConstantOffset(N)) { | 961 if (!CurDAG->isBaseWithConstantOffset(N)) { |
892 Base = N; | 962 Base = N; |
893 if (N.getOpcode() == ISD::FrameIndex) { | 963 if (N.getOpcode() == ISD::FrameIndex) { |
894 int FI = cast<FrameIndexSDNode>(N)->getIndex(); | 964 int FI = cast<FrameIndexSDNode>(N)->getIndex(); |
895 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy()); | 965 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy()); |
896 } | 966 } |
897 Offset = CurDAG->getRegister(0, MVT::i32); | 967 Offset = CurDAG->getRegister(0, MVT::i32); |
898 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0),MVT::i32); | 968 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0),MVT::i32); |
899 return true; | 969 return true; |
(...skipping 12 matching lines...) Expand all Loading... |
912 | 982 |
913 ARM_AM::AddrOpc AddSub = ARM_AM::add; | 983 ARM_AM::AddrOpc AddSub = ARM_AM::add; |
914 if (RHSC < 0) { | 984 if (RHSC < 0) { |
915 AddSub = ARM_AM::sub; | 985 AddSub = ARM_AM::sub; |
916 RHSC = -RHSC; | 986 RHSC = -RHSC; |
917 } | 987 } |
918 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, RHSC),MVT::i32); | 988 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, RHSC),MVT::i32); |
919 return true; | 989 return true; |
920 } | 990 } |
921 | 991 |
| 992 // @LOCALMOD-START |
| 993 // A sandboxable load or a sandboxable store. |
| 994 if (restrict_addressing_modes_for_nacl) { |
| 995 Base = N; |
| 996 Offset = CurDAG->getRegister(0, MVT::i32); |
| 997 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0),MVT::i32); |
| 998 return true; |
| 999 } |
| 1000 // @LOCALMOD-END |
| 1001 |
922 Base = N.getOperand(0); | 1002 Base = N.getOperand(0); |
923 Offset = N.getOperand(1); | 1003 Offset = N.getOperand(1); |
924 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), MVT::i32); | 1004 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), MVT::i32); |
925 return true; | 1005 return true; |
926 } | 1006 } |
927 | 1007 |
928 bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDNode *Op, SDValue N, | 1008 bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDNode *Op, SDValue N, |
929 SDValue &Offset, SDValue &Opc) { | 1009 SDValue &Offset, SDValue &Opc) { |
930 unsigned Opcode = Op->getOpcode(); | 1010 unsigned Opcode = Op->getOpcode(); |
931 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) | 1011 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD) |
(...skipping 14 matching lines...) Expand all Loading... |
946 } | 1026 } |
947 | 1027 |
948 bool ARMDAGToDAGISel::SelectAddrMode5(SDValue N, | 1028 bool ARMDAGToDAGISel::SelectAddrMode5(SDValue N, |
949 SDValue &Base, SDValue &Offset) { | 1029 SDValue &Base, SDValue &Offset) { |
950 if (!CurDAG->isBaseWithConstantOffset(N)) { | 1030 if (!CurDAG->isBaseWithConstantOffset(N)) { |
951 Base = N; | 1031 Base = N; |
952 if (N.getOpcode() == ISD::FrameIndex) { | 1032 if (N.getOpcode() == ISD::FrameIndex) { |
953 int FI = cast<FrameIndexSDNode>(N)->getIndex(); | 1033 int FI = cast<FrameIndexSDNode>(N)->getIndex(); |
954 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy()); | 1034 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy()); |
955 } else if (N.getOpcode() == ARMISD::Wrapper && | 1035 } else if (N.getOpcode() == ARMISD::Wrapper && |
956 N.getOperand(0).getOpcode() != ISD::TargetGlobalAddress) { | 1036 // @LOCALMOD |
| 1037 ShouldOperandBeUnwrappedForUseAsBaseAddress(N, Subtarget)) { |
957 Base = N.getOperand(0); | 1038 Base = N.getOperand(0); |
958 } | 1039 } |
959 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), | 1040 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0), |
960 MVT::i32); | 1041 MVT::i32); |
961 return true; | 1042 return true; |
962 } | 1043 } |
963 | 1044 |
964 // If the RHS is +/- imm8, fold into addr mode. | 1045 // If the RHS is +/- imm8, fold into addr mode. |
965 int RHSC; | 1046 int RHSC; |
966 if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/4, | 1047 if (isScaledConstantInRange(N.getOperand(1), /*Scale=*/4, |
(...skipping 1485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2452 ~Val > 255 && // MOV + MVN | 2533 ~Val > 255 && // MOV + MVN |
2453 !ARM_AM::isThumbImmShiftedVal(Val) && // MOV + LSL | 2534 !ARM_AM::isThumbImmShiftedVal(Val) && // MOV + LSL |
2454 !(Subtarget->hasV6T2Ops() && Val <= 0xffff)); // MOVW | 2535 !(Subtarget->hasV6T2Ops() && Val <= 0xffff)); // MOVW |
2455 } else | 2536 } else |
2456 UseCP = (ARM_AM::getSOImmVal(Val) == -1 && // MOV | 2537 UseCP = (ARM_AM::getSOImmVal(Val) == -1 && // MOV |
2457 ARM_AM::getSOImmVal(~Val) == -1 && // MVN | 2538 ARM_AM::getSOImmVal(~Val) == -1 && // MVN |
2458 !ARM_AM::isSOImmTwoPartVal(Val) && // two instrs. | 2539 !ARM_AM::isSOImmTwoPartVal(Val) && // two instrs. |
2459 !(Subtarget->hasV6T2Ops() && Val <= 0xffff)); // MOVW | 2540 !(Subtarget->hasV6T2Ops() && Val <= 0xffff)); // MOVW |
2460 } | 2541 } |
2461 | 2542 |
| 2543 if (!Subtarget->useConstIslands()) UseCP = false; // @LOCALMOD |
| 2544 |
2462 if (UseCP) { | 2545 if (UseCP) { |
2463 SDValue CPIdx = CurDAG->getTargetConstantPool( | 2546 SDValue CPIdx = CurDAG->getTargetConstantPool( |
2464 ConstantInt::get(Type::getInt32Ty(*CurDAG->getContext()), Val), | 2547 ConstantInt::get(Type::getInt32Ty(*CurDAG->getContext()), Val), |
2465 TLI->getPointerTy()); | 2548 TLI->getPointerTy()); |
2466 | 2549 |
2467 SDNode *ResNode; | 2550 SDNode *ResNode; |
2468 if (Subtarget->isThumb()) { | 2551 if (Subtarget->isThumb()) { |
2469 SDValue Pred = getAL(CurDAG); | 2552 SDValue Pred = getAL(CurDAG); |
2470 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); | 2553 SDValue PredReg = CurDAG->getRegister(0, MVT::i32); |
2471 SDValue Ops[] = { CPIdx, Pred, PredReg, CurDAG->getEntryNode() }; | 2554 SDValue Ops[] = { CPIdx, Pred, PredReg, CurDAG->getEntryNode() }; |
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3459 return false; | 3542 return false; |
3460 } | 3543 } |
3461 | 3544 |
3462 /// createARMISelDag - This pass converts a legalized DAG into a | 3545 /// createARMISelDag - This pass converts a legalized DAG into a |
3463 /// ARM-specific DAG, ready for instruction scheduling. | 3546 /// ARM-specific DAG, ready for instruction scheduling. |
3464 /// | 3547 /// |
3465 FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM, | 3548 FunctionPass *llvm::createARMISelDag(ARMBaseTargetMachine &TM, |
3466 CodeGenOpt::Level OptLevel) { | 3549 CodeGenOpt::Level OptLevel) { |
3467 return new ARMDAGToDAGISel(TM, OptLevel); | 3550 return new ARMDAGToDAGISel(TM, OptLevel); |
3468 } | 3551 } |
OLD | NEW |