llvm.org GIT mirror llvm / 7e3383c
Refactor ARM STR/STRB instruction patterns into STR{B}i12 and STR{B}rs, like the LDR instructions have. This makes the literal/register forms of the instructions explicit and allows us to assign scheduling itineraries appropriately. rdar://8477752 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117505 91177308-0d34-0410-b5e6-96231b3b80d8 Jim Grosbach 9 years ago
9 changed file(s) with 94 addition(s) and 101 deletion(s). Raw diff Collapse all Expand all
869869 switch (MI->getOpcode()) {
870870 default:
871871 llvm_unreachable("Unexpected opcode!");
872 case ARM::PICSTR: Opcode = ARM::STR; break;
873 case ARM::PICSTRB: Opcode = ARM::STRB; break;
872 case ARM::PICSTR: Opcode = ARM::STRrs; break;
873 case ARM::PICSTRB: Opcode = ARM::STRBrs; break;
874874 case ARM::PICSTRH: Opcode = ARM::STRH; break;
875875 case ARM::PICLDR: Opcode = ARM::LDRrs; break;
876876 case ARM::PICLDRB: Opcode = ARM::LDRBrs; break;
11601160 }
11611161 {
11621162 MCInst TmpInst;
1163 TmpInst.setOpcode(ARM::STR);
1163 TmpInst.setOpcode(ARM::STRi12);
11641164 TmpInst.addOperand(MCOperand::CreateReg(ValReg));
11651165 TmpInst.addOperand(MCOperand::CreateReg(SrcReg));
1166 TmpInst.addOperand(MCOperand::CreateReg(0));
11671166 TmpInst.addOperand(MCOperand::CreateImm(4));
11681167 // Predicate.
11691168 TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
675675
676676 switch (RC->getID()) {
677677 case ARM::GPRRegClassID:
678 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR))
678 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STRi12))
679679 .addReg(SrcReg, getKillRegState(isKill))
680 .addFrameIndex(FI).addReg(0).addImm(0).addMemOperand(MMO));
680 .addFrameIndex(FI).addImm(0).addMemOperand(MMO));
681681 break;
682682 case ARM::SPRRegClassID:
683683 AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRS))
754754 int &FrameIndex) const {
755755 switch (MI->getOpcode()) {
756756 default: break;
757 case ARM::STR:
757 case ARM::STRrs:
758758 case ARM::t2STRs: // FIXME: don't use t2STRs to access frame.
759759 if (MI->getOperand(1).isFI() &&
760760 MI->getOperand(2).isReg() &&
765765 return MI->getOperand(0).getReg();
766766 }
767767 break;
768 case ARM::STRi12:
768769 case ARM::t2STRi12:
769770 case ARM::tSpill:
770771 case ARM::VSTRD:
13761376 unsigned Opc = MI->getOpcode();
13771377 switch (Opc) {
13781378 case ARM::LDRi12: case ARM::LDRH: case ARM::LDRBi12:
1379 case ARM::STR: case ARM::STRH: case ARM::STRB:
1379 case ARM::STRi12: case ARM::STRH: case ARM::STRBi12:
13801380 case ARM::t2LDRi12: case ARM::t2LDRi8:
13811381 case ARM::t2STRi12: case ARM::t2STRi8:
13821382 case ARM::VLDRS: case ARM::VLDRD:
17101710
17111711 // Build the new SUBri to adjust SP for integer callee-save spill area.
17121712 emitSPUpdate(isARM, MBB, MBBI, dl, TII, -GPRCSSize);
1713 movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, ARM::t2STRi12, 1, STI);
1713 movePastCSLoadStoreOps(MBB, MBBI, ARM::STRi12, ARM::t2STRi12, 1, STI);
17141714
17151715 // Set FP to point to the stack slot that contains the previous FP.
17161716 bool HasFP = hasFP(MF);
965965 // Part of binary is determined by TableGn.
966966 unsigned Binary = getBinaryCodeForInstr(MI);
967967
968 // If this is an LDRi12 or LDRcp, nothing more needs be done.
969 if (MI.getOpcode() == ARM::LDRi12 || MI.getOpcode() == ARM::LDRcp) {
968 // If this is an LDRi12, STRi12 or LDRcp, nothing more needs be done.
969 if (MI.getOpcode() == ARM::LDRi12 || MI.getOpcode() == ARM::LDRcp ||
970 MI.getOpcode() == ARM::STRi12) {
970971 emitWordLE(Binary);
971972 return;
972973 }
804804 unsigned Base, int Offset) {
805805 unsigned StrOpc;
806806 bool isFloat = false;
807 bool needReg0Op = false;
807808 switch (VT.getSimpleVT().SimpleTy) {
808809 default: return false;
809810 case MVT::i1:
810811 case MVT::i8:
811 StrOpc = isThumb ? ARM::t2STRBi12 : ARM::STRB;
812 StrOpc = isThumb ? ARM::t2STRBi12 : ARM::STRBi12;
812813 break;
813814 case MVT::i16:
814815 StrOpc = isThumb ? ARM::t2STRHi12 : ARM::STRH;
816 needReg0Op = true;
815817 break;
816818 case MVT::i32:
817 StrOpc = isThumb ? ARM::t2STRi12 : ARM::STR;
819 StrOpc = isThumb ? ARM::t2STRi12 : ARM::STRi12;
818820 break;
819821 case MVT::f32:
820822 if (!Subtarget->hasVFP2()) return false;
835837 if (isFloat)
836838 Offset /= 4;
837839
838 // The thumb addressing mode has operands swapped from the arm addressing
839 // mode, the floating point one only has two operands.
840 if (isFloat || isThumb)
840
841 // FIXME: The 'needReg0Op' bit goes away once STRH is converted to
842 // not use the mega-addrmode stuff.
843 if (!needReg0Op)
841844 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL,
842845 TII.get(StrOpc))
843846 .addReg(SrcReg).addReg(Base).addImm(Offset));
400400
401401 // loads
402402
403 // LDR/LDRB
404 class AIldr1 op, bit opc22, dag oops, dag iops, AddrMode am, Format f,
405 InstrItinClass itin, string opc, string asm, list pattern>
403 // LDR/LDRB/STR/STRB
404 class AIldst1 op, bit opc22, bit isLd, dag oops, dag iops, AddrMode am,
405 Format f, InstrItinClass itin, string opc, string asm,
406 list pattern>
406407 : I
407408 "", pattern> {
408409 let Inst{27-25} = op;
410411 // 23 == U
411412 let Inst{22} = opc22;
412413 let Inst{21} = 0; // 21 == W
413 let Inst{20} = 1;
414 let Inst{20} = isLd;
414415 }
415416 // LDRH/LDRSB/LDRSH/LDRD
416417 class AIldr2 op, bit opc22, bit opc20, dag oops, dag iops, AddrMode am,
4747 return ARM::LDRSB;
4848 case ARM::STR_PRE:
4949 case ARM::STR_POST:
50 return ARM::STR;
50 return ARM::STRi12;
5151 case ARM::STRH_PRE:
5252 case ARM::STRH_POST:
5353 return ARM::STRH;
5454 case ARM::STRB_PRE:
5555 case ARM::STRB_POST:
56 return ARM::STRB;
56 return ARM::STRBi12;
5757 }
5858
5959 return 0;
812812 // Note: We use the complex addrmode_imm12 rather than just an input
813813 // GPR and a constrained immediate so that we can use this to match
814814 // frame index references and avoid matching constant pool references.
815 def i12 : AIldr1<0b010, opc22, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
815 def i12 : AIldst1<0b010, opc22, 1, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
816816 AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
817817 [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
818818 bits<4> Rt;
822822 let Inst{15-12} = Rt;
823823 let Inst{11-0} = addr{11-0}; // imm12
824824 }
825 def rs : AIldr1<0b011, opc22, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
825 def rs : AIldst1<0b011, opc22, 1, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
826826 AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
827827 [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
828828 bits<4> Rt;
834834 }
835835 }
836836
837 multiclass AI_str1
838 InstrItinClass iir, PatFrag opnode> {
839 // Note: We use the complex addrmode_imm12 rather than just an input
840 // GPR and a constrained immediate so that we can use this to match
841 // frame index references and avoid matching constant pool references.
842 def i12 : AIldst1<0b010, opc22, 0, (outs),
843 (ins GPR:$Rt, addrmode_imm12:$addr),
844 AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr",
845 [(opnode GPR:$Rt, addrmode_imm12:$addr)]> {
846 bits<4> Rt;
847 bits<17> addr;
848 let Inst{23} = addr{12}; // U (add = ('U' == 1))
849 let Inst{19-16} = addr{16-13}; // Rn
850 let Inst{15-12} = Rt;
851 let Inst{11-0} = addr{11-0}; // imm12
852 }
853 def rs : AIldst1<0b011, opc22, 0, (outs), (ins GPR:$Rt, ldst_so_reg:$shift),
854 AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift",
855 [(opnode GPR:$Rt, ldst_so_reg:$shift)]> {
856 bits<4> Rt;
857 bits<17> shift;
858 let Inst{23} = shift{12}; // U (add = ('U' == 1))
859 let Inst{19-16} = shift{16-13}; // Rn
860 let Inst{11-0} = shift{11-0};
861 }
862 }
837863 //===----------------------------------------------------------------------===//
838864 // Instructions
839865 //===----------------------------------------------------------------------===//
14081434 UnOpFrag<(load node:$Src)>>;
14091435 defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_i, IIC_iLoad_bh_r,
14101436 UnOpFrag<(zextloadi8 node:$Src)>>;
1437 defm STR : AI_str1<0, "str", IIC_iStore_i, IIC_iStore_r,
1438 BinOpFrag<(store node:$LHS, node:$RHS)>>;
1439 defm STRB : AI_str1<1, "strb", IIC_iStore_bh_i, IIC_iStore_bh_r,
1440 BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
14111441
14121442 // Special LDR for loads from non-pc-relative constpools.
14131443 let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
14141444 isReMaterializable = 1 in
1415 def LDRcp : AIldr1<0b010, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
1445 def LDRcp : AIldst1<0b010, 0, 1, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
14161446 AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr", []> {
14171447 bits<4> Rt;
14181448 bits<17> addr;
15301560 }
15311561
15321562 // Store
1533 def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStore_r,
1534 "str", "\t$src, $addr",
1535 [(store GPR:$src, addrmode2:$addr)]>;
15361563
15371564 // Stores with truncate
15381565 def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
15391566 IIC_iStore_bh_r, "strh", "\t$src, $addr",
15401567 [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
1541
1542 def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
1543 IIC_iStore_bh_r, "strb", "\t$src, $addr",
1544 [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
15451568
15461569 // Store doubleword
15471570 let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
132132 case ARM::LDRi12:
133133 ++NumLDMGened;
134134 return ARM::LDM;
135 case ARM::STR:
135 case ARM::STRi12:
136136 ++NumSTMGened;
137137 return ARM::STM;
138138 case ARM::t2LDRi8:
173173 }
174174
175175 static bool isi32Store(unsigned Opc) {
176 return Opc == ARM::STR || isT2i32Store(Opc);
176 return Opc == ARM::STRi12 || isT2i32Store(Opc);
177177 }
178178
179179 /// MergeOps - Create and insert a LDM or STM with Base as base register and
440440 switch (MI->getOpcode()) {
441441 default: return 0;
442442 case ARM::LDRi12:
443 case ARM::STR:
443 case ARM::STRi12:
444444 case ARM::t2LDRi8:
445445 case ARM::t2LDRi12:
446446 case ARM::t2STRi8:
578578 static unsigned getPreIndexedLoadStoreOpcode(unsigned Opc) {
579579 switch (Opc) {
580580 case ARM::LDRi12: return ARM::LDR_PRE;
581 case ARM::STR: return ARM::STR_PRE;
581 case ARM::STRi12: return ARM::STR_PRE;
582582 case ARM::VLDRS: return ARM::VLDMS_UPD;
583583 case ARM::VLDRD: return ARM::VLDMD_UPD;
584584 case ARM::VSTRS: return ARM::VSTMS_UPD;
597597 static unsigned getPostIndexedLoadStoreOpcode(unsigned Opc) {
598598 switch (Opc) {
599599 case ARM::LDRi12: return ARM::LDR_POST;
600 case ARM::STR: return ARM::STR_POST;
600 case ARM::STRi12: return ARM::STR_POST;
601601 case ARM::VLDRS: return ARM::VLDMS_UPD;
602602 case ARM::VLDRD: return ARM::VLDMD_UPD;
603603 case ARM::VSTRS: return ARM::VSTMS_UPD;
628628 DebugLoc dl = MI->getDebugLoc();
629629 bool isAM5 = (Opcode == ARM::VLDRD || Opcode == ARM::VLDRS ||
630630 Opcode == ARM::VSTRD || Opcode == ARM::VSTRS);
631 bool isAM2 = (Opcode == ARM::LDRi12 || Opcode == ARM::STR);
632 // FIXME: This special handling of LDRi12 is hackery until all of the ARM
633 // LDR/STR insns are moved away from the addrmode2 mega-instruction to
634 // the split (LDRi12/LDRrs) style instructions.
635 if (Opcode == ARM::LDRi12 || isT2i32Load(Opcode) || isT2i32Store(Opcode))
631 bool isAM2 = (Opcode == ARM::LDRi12 || Opcode == ARM::STRi12);
632 if (isi32Load(Opcode) || isi32Store(Opcode))
636633 if (MI->getOperand(2).getImm() != 0)
637634 return false;
638 if (isAM2 && Opcode != ARM::LDRi12
639 && ARM_AM::getAM2Offset(MI->getOperand(3).getImm()) != 0)
640 return false;
641635 if (isAM5 && ARM_AM::getAM5Offset(MI->getOperand(2).getImm()) != 0)
642636 return false;
643637
785779 int Opcode = MI->getOpcode();
786780 switch (Opcode) {
787781 default: break;
788 case ARM::STR:
789 return MI->getOperand(1).isReg() && MI->getOperand(2).getReg() == 0;
790782 case ARM::VLDRS:
791783 case ARM::VSTRS:
792784 return MI->getOperand(1).isReg();
794786 case ARM::VSTRD:
795787 return MI->getOperand(1).isReg();
796788 case ARM::LDRi12:
789 case ARM::STRi12:
797790 case ARM::t2LDRi8:
798791 case ARM::t2LDRi12:
799792 case ARM::t2STRi8:
821814
822815 static int getMemoryOpOffset(const MachineInstr *MI) {
823816 int Opcode = MI->getOpcode();
824 bool isAM2 = Opcode == ARM::STR;
825817 bool isAM3 = Opcode == ARM::LDRD || Opcode == ARM::STRD;
826818 unsigned NumOperands = MI->getDesc().getNumOperands();
827819 unsigned OffField = MI->getOperand(NumOperands-3).getImm();
829821 if (Opcode == ARM::t2LDRi12 || Opcode == ARM::t2LDRi8 ||
830822 Opcode == ARM::t2STRi12 || Opcode == ARM::t2STRi8 ||
831823 Opcode == ARM::t2LDRDi8 || Opcode == ARM::t2STRDi8 ||
832 Opcode == ARM::LDRi12)
824 Opcode == ARM::LDRi12 || Opcode == ARM::STRi12)
833825 return OffField;
834826
835 int Offset = isAM2
836 ? ARM_AM::getAM2Offset(OffField)
837 : (isAM3 ? ARM_AM::getAM3Offset(OffField)
838 : ARM_AM::getAM5Offset(OffField) * 4);
839 if (isAM2) {
840 if (ARM_AM::getAM2Op(OffField) == ARM_AM::sub)
841 Offset = -Offset;
842 } else if (isAM3) {
827 int Offset = isAM3 ? ARM_AM::getAM3Offset(OffField)
828 : ARM_AM::getAM5Offset(OffField) * 4;
829 if (isAM3) {
843830 if (ARM_AM::getAM3Op(OffField) == ARM_AM::sub)
844831 Offset = -Offset;
845832 } else {
851838
852839 static void InsertLDR_STR(MachineBasicBlock &MBB,
853840 MachineBasicBlock::iterator &MBBI,
854 int OffImm, bool isDef,
841 int Offset, bool isDef,
855842 DebugLoc dl, unsigned NewOpc,
856843 unsigned Reg, bool RegDeadKill, bool RegUndef,
857844 unsigned BaseReg, bool BaseKill, bool BaseUndef,
858 unsigned OffReg, bool OffKill, bool OffUndef,
845 bool OffKill, bool OffUndef,
859846 ARMCC::CondCodes Pred, unsigned PredReg,
860847 const TargetInstrInfo *TII, bool isT2) {
861 int Offset = OffImm;
862 // FIXME: This fancy offset encoding stuff goes away when we're done
863 // removing addrmode2.
864 if (!isT2 && !isDef) {
865 if (OffImm < 0)
866 Offset = ARM_AM::getAM2Opc(ARM_AM::sub, -OffImm, ARM_AM::no_shift);
867 else
868 Offset = ARM_AM::getAM2Opc(ARM_AM::add, OffImm, ARM_AM::no_shift);
869 }
870848 if (isDef) {
871849 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MBBI->getDebugLoc(),
872850 TII->get(NewOpc))
878856 TII->get(NewOpc))
879857 .addReg(Reg, getKillRegState(RegDeadKill) | getUndefRegState(RegUndef))
880858 .addReg(BaseReg, getKillRegState(BaseKill)|getUndefRegState(BaseUndef));
881 if (!isT2)
882 MIB.addReg(OffReg, getKillRegState(OffKill)|getUndefRegState(OffUndef));
883859 MIB.addImm(Offset).addImm(Pred).addReg(PredReg);
884860 }
885861 }
910886 unsigned BaseReg = BaseOp.getReg();
911887 bool BaseKill = BaseOp.isKill();
912888 bool BaseUndef = BaseOp.isUndef();
913 unsigned OffReg = isT2 ? 0 : MI->getOperand(3).getReg();
914889 bool OffKill = isT2 ? false : MI->getOperand(3).isKill();
915890 bool OffUndef = isT2 ? false : MI->getOperand(3).isUndef();
916891 int OffImm = getMemoryOpOffset(MI);
917892 unsigned PredReg = 0;
918893 ARMCC::CondCodes Pred = llvm::getInstrPredicate(MI, PredReg);
919894
920 if (OddRegNum > EvenRegNum && OffReg == 0 && OffImm == 0) {
895 if (OddRegNum > EvenRegNum && OffImm == 0) {
921896 // Ascending register numbers and no offset. It's safe to change it to a
922897 // ldm or stm.
923898 unsigned NewOpc = (isLd)
945920 NewBBI = llvm::prior(MBBI);
946921 } else {
947922 // Split into two instructions.
948 assert((!isT2 || !OffReg) &&
949 "Thumb2 ldrd / strd does not encode offset register!");
950923 unsigned NewOpc = (isLd)
951924 ? (isT2 ? (OffImm < 0 ? ARM::t2LDRi8 : ARM::t2LDRi12) : ARM::LDRi12)
952 : (isT2 ? (OffImm < 0 ? ARM::t2STRi8 : ARM::t2STRi12) : ARM::STR);
925 : (isT2 ? (OffImm < 0 ? ARM::t2STRi8 : ARM::t2STRi12) : ARM::STRi12);
953926 DebugLoc dl = MBBI->getDebugLoc();
954927 // If this is a load and base register is killed, it may have been
955928 // re-defed by the load, make sure the first load does not clobber it.
956929 if (isLd &&
957930 (BaseKill || OffKill) &&
958 (TRI->regsOverlap(EvenReg, BaseReg) ||
959 (OffReg && TRI->regsOverlap(EvenReg, OffReg)))) {
960 assert(!TRI->regsOverlap(OddReg, BaseReg) &&
961 (!OffReg || !TRI->regsOverlap(OddReg, OffReg)));
931 (TRI->regsOverlap(EvenReg, BaseReg))) {
932 assert(!TRI->regsOverlap(OddReg, BaseReg));
962933 InsertLDR_STR(MBB, MBBI, OffImm+4, isLd, dl, NewOpc,
963934 OddReg, OddDeadKill, false,
964 BaseReg, false, BaseUndef, OffReg, false, OffUndef,
935 BaseReg, false, BaseUndef, false, OffUndef,
965936 Pred, PredReg, TII, isT2);
966937 NewBBI = llvm::prior(MBBI);
967938 InsertLDR_STR(MBB, MBBI, OffImm, isLd, dl, NewOpc,
968939 EvenReg, EvenDeadKill, false,
969 BaseReg, BaseKill, BaseUndef, OffReg, OffKill, OffUndef,
940 BaseReg, BaseKill, BaseUndef, OffKill, OffUndef,
970941 Pred, PredReg, TII, isT2);
971942 } else {
972943 if (OddReg == EvenReg && EvenDeadKill) {
978949 }
979950 InsertLDR_STR(MBB, MBBI, OffImm, isLd, dl, NewOpc,
980951 EvenReg, EvenDeadKill, EvenUndef,
981 BaseReg, false, BaseUndef, OffReg, false, OffUndef,
952 BaseReg, false, BaseUndef, false, OffUndef,
982953 Pred, PredReg, TII, isT2);
983954 NewBBI = llvm::prior(MBBI);
984955 InsertLDR_STR(MBB, MBBI, OffImm+4, isLd, dl, NewOpc,
985956 OddReg, OddDeadKill, OddUndef,
986 BaseReg, BaseKill, BaseUndef, OffReg, OffKill, OffUndef,
957 BaseReg, BaseKill, BaseUndef, OffKill, OffUndef,
987958 Pred, PredReg, TII, isT2);
988959 }
989960 if (isLd)
12551226 bool CanFormLdStDWord(MachineInstr *Op0, MachineInstr *Op1, DebugLoc &dl,
12561227 unsigned &NewOpc, unsigned &EvenReg,
12571228 unsigned &OddReg, unsigned &BaseReg,
1258 unsigned &OffReg, int &Offset,
1229 int &Offset,
12591230 unsigned &PredReg, ARMCC::CondCodes &Pred,
12601231 bool &isT2);
12611232 bool RescheduleOps(MachineBasicBlock *MBB,
13351306 DebugLoc &dl,
13361307 unsigned &NewOpc, unsigned &EvenReg,
13371308 unsigned &OddReg, unsigned &BaseReg,
1338 unsigned &OffReg, int &Offset,
1339 unsigned &PredReg,
1309 int &Offset, unsigned &PredReg,
13401310 ARMCC::CondCodes &Pred,
13411311 bool &isT2) {
13421312 // Make sure we're allowed to generate LDRD/STRD.
13481318 unsigned Opcode = Op0->getOpcode();
13491319 if (Opcode == ARM::LDRi12)
13501320 NewOpc = ARM::LDRD;
1351 else if (Opcode == ARM::STR)
1321 else if (Opcode == ARM::STRi12)
13521322 NewOpc = ARM::STRD;
13531323 else if (Opcode == ARM::t2LDRi8 || Opcode == ARM::t2LDRi12) {
13541324 NewOpc = ARM::t2LDRDi8;
13611331 } else
13621332 return false;
13631333
1364 // Make sure the offset registers match.
1365 if (!isT2 && Opcode != ARM::LDRi12 &&
1366 (Op0->getOperand(2).getReg() != Op1->getOperand(2).getReg()))
1367 return false;
1368
13691334 // Make sure the base address satisfies i64 ld / st alignment requirement.
13701335 if (!Op0->hasOneMemOperand() ||
13711336 !(*Op0->memoperands_begin())->getValue() ||
13751340 unsigned Align = (*Op0->memoperands_begin())->getAlignment();
13761341 const Function *Func = MF->getFunction();
13771342 unsigned ReqAlign = STI->hasV6Ops()
1378 ? TD->getABITypeAlignment(Type::getInt64Ty(Func->getContext()))
1343 ? TD->getABITypeAlignment(Type::getInt64Ty(Func->getContext()))
13791344 : 8; // Pre-v6 need 8-byte align
13801345 if (Align < ReqAlign)
13811346 return false;
14091374 if (EvenReg == OddReg)
14101375 return false;
14111376 BaseReg = Op0->getOperand(1).getReg();
1412 if (!isT2 && Opcode != ARM::LDRi12)
1413 OffReg = Op0->getOperand(2).getReg();
14141377 Pred = llvm::getInstrPredicate(Op0, PredReg);
14151378 dl = Op0->getDebugLoc();
14161379 return true;
14981461 MachineInstr *Op0 = Ops.back();
14991462 MachineInstr *Op1 = Ops[Ops.size()-2];
15001463 unsigned EvenReg = 0, OddReg = 0;
1501 unsigned BaseReg = 0, OffReg = 0, PredReg = 0;
1464 unsigned BaseReg = 0, PredReg = 0;
15021465 ARMCC::CondCodes Pred = ARMCC::AL;
15031466 bool isT2 = false;
15041467 unsigned NewOpc = 0;
15051468 int Offset = 0;
15061469 DebugLoc dl;
15071470 if (NumMove == 2 && CanFormLdStDWord(Op0, Op1, dl, NewOpc,
1508 EvenReg, OddReg, BaseReg, OffReg,
1471 EvenReg, OddReg, BaseReg,
15091472 Offset, PredReg, Pred, isT2)) {
15101473 Ops.pop_back();
15111474 Ops.pop_back();
15171480 .addReg(EvenReg, RegState::Define)
15181481 .addReg(OddReg, RegState::Define)
15191482 .addReg(BaseReg);
1520 // For now, we're converting from LDRi12 to an insn that still
1483 // FIXME: We're converting from LDRi12 to an insn that still
15211484 // uses addrmode2, so we need an explicit offset reg. It should
1522 // always by reg0 since we're transforming LDRi12s. The old
1523 // was just being paranoid in allowing for anything else.
1485 // always by reg0 since we're transforming LDRi12s.
15241486 if (!isT2)
15251487 MIB.addReg(0);
15261488 MIB.addImm(Offset).addImm(Pred).addReg(PredReg);
15311493 .addReg(EvenReg)
15321494 .addReg(OddReg)
15331495 .addReg(BaseReg);
1496 // FIXME: We're converting from LDRi12 to an insn that still
1497 // uses addrmode2, so we need an explicit offset reg. It should
1498 // always by reg0 since we're transforming STRi12s.
15341499 if (!isT2)
1535 MIB.addReg(OffReg);
1500 MIB.addReg(0);
15361501 MIB.addImm(Offset).addImm(Pred).addReg(PredReg);
15371502 ++NumSTRDFormed;
15381503 }