From 7e3383c007f53b3a00675af225e428cb66ddf404 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 27 Oct 2010 23:12:14 +0000 Subject: [PATCH] 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 --- lib/Target/ARM/ARMAsmPrinter.cpp | 7 +- lib/Target/ARM/ARMBaseInstrInfo.cpp | 7 +- lib/Target/ARM/ARMBaseRegisterInfo.cpp | 4 +- lib/Target/ARM/ARMCodeEmitter.cpp | 5 +- lib/Target/ARM/ARMFastISel.cpp | 13 +-- lib/Target/ARM/ARMInstrFormats.td | 9 +- lib/Target/ARM/ARMInstrInfo.cpp | 4 +- lib/Target/ARM/ARMInstrInfo.td | 43 +++++++--- lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 103 ++++++++--------------- 9 files changed, 94 insertions(+), 101 deletions(-) diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 79b35ad4b97..8e215921998 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -870,8 +870,8 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { switch (MI->getOpcode()) { default: llvm_unreachable("Unexpected opcode!"); - case ARM::PICSTR: Opcode = ARM::STR; break; - case ARM::PICSTRB: Opcode = ARM::STRB; break; + case ARM::PICSTR: Opcode = ARM::STRrs; break; + case ARM::PICSTRB: Opcode = ARM::STRBrs; break; case ARM::PICSTRH: Opcode = ARM::STRH; break; case ARM::PICLDR: Opcode = ARM::LDRrs; break; case ARM::PICLDRB: Opcode = ARM::LDRBrs; break; @@ -1161,10 +1161,9 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { } { MCInst TmpInst; - TmpInst.setOpcode(ARM::STR); + TmpInst.setOpcode(ARM::STRi12); TmpInst.addOperand(MCOperand::CreateReg(ValReg)); TmpInst.addOperand(MCOperand::CreateReg(SrcReg)); - TmpInst.addOperand(MCOperand::CreateReg(0)); TmpInst.addOperand(MCOperand::CreateImm(4)); // Predicate. TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 223cbe75e0b..1c89b97b817 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -676,9 +676,9 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, switch (RC->getID()) { case ARM::GPRRegClassID: - AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STR)) + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::STRi12)) .addReg(SrcReg, getKillRegState(isKill)) - .addFrameIndex(FI).addReg(0).addImm(0).addMemOperand(MMO)); + .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); break; case ARM::SPRRegClassID: AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRS)) @@ -755,7 +755,7 @@ ARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const { switch (MI->getOpcode()) { default: break; - case ARM::STR: + case ARM::STRrs: case ARM::t2STRs: // FIXME: don't use t2STRs to access frame. if (MI->getOperand(1).isFI() && MI->getOperand(2).isReg() && @@ -766,6 +766,7 @@ ARMBaseInstrInfo::isStoreToStackSlot(const MachineInstr *MI, return MI->getOperand(0).getReg(); } break; + case ARM::STRi12: case ARM::t2STRi12: case ARM::tSpill: case ARM::VSTRD: diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 1686124b825..27a0e7b560d 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -1377,7 +1377,7 @@ needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const { unsigned Opc = MI->getOpcode(); switch (Opc) { case ARM::LDRi12: case ARM::LDRH: case ARM::LDRBi12: - case ARM::STR: case ARM::STRH: case ARM::STRB: + case ARM::STRi12: case ARM::STRH: case ARM::STRBi12: case ARM::t2LDRi12: case ARM::t2LDRi8: case ARM::t2STRi12: case ARM::t2STRi8: case ARM::VLDRS: case ARM::VLDRD: @@ -1711,7 +1711,7 @@ emitPrologue(MachineFunction &MF) const { // Build the new SUBri to adjust SP for integer callee-save spill area. emitSPUpdate(isARM, MBB, MBBI, dl, TII, -GPRCSSize); - movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, ARM::t2STRi12, 1, STI); + movePastCSLoadStoreOps(MBB, MBBI, ARM::STRi12, ARM::t2STRi12, 1, STI); // Set FP to point to the stack slot that contains the previous FP. bool HasFP = hasFP(MF); diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 1fb99fe5b0d..fa11a483221 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -966,8 +966,9 @@ void ARMCodeEmitter::emitLoadStoreInstruction(const MachineInstr &MI, // Part of binary is determined by TableGn. unsigned Binary = getBinaryCodeForInstr(MI); - // If this is an LDRi12 or LDRcp, nothing more needs be done. - if (MI.getOpcode() == ARM::LDRi12 || MI.getOpcode() == ARM::LDRcp) { + // If this is an LDRi12, STRi12 or LDRcp, nothing more needs be done. + if (MI.getOpcode() == ARM::LDRi12 || MI.getOpcode() == ARM::LDRcp || + MI.getOpcode() == ARM::STRi12) { emitWordLE(Binary); return; } diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index 3eac44bc8d7..675e7e5d25c 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -805,17 +805,19 @@ bool ARMFastISel::ARMEmitStore(EVT VT, unsigned SrcReg, unsigned Base, int Offset) { unsigned StrOpc; bool isFloat = false; + bool needReg0Op = false; switch (VT.getSimpleVT().SimpleTy) { default: return false; case MVT::i1: case MVT::i8: - StrOpc = isThumb ? ARM::t2STRBi12 : ARM::STRB; + StrOpc = isThumb ? ARM::t2STRBi12 : ARM::STRBi12; break; case MVT::i16: StrOpc = isThumb ? ARM::t2STRHi12 : ARM::STRH; + needReg0Op = true; break; case MVT::i32: - StrOpc = isThumb ? ARM::t2STRi12 : ARM::STR; + StrOpc = isThumb ? ARM::t2STRi12 : ARM::STRi12; break; case MVT::f32: if (!Subtarget->hasVFP2()) return false; @@ -836,9 +838,10 @@ bool ARMFastISel::ARMEmitStore(EVT VT, unsigned SrcReg, if (isFloat) Offset /= 4; - // The thumb addressing mode has operands swapped from the arm addressing - // mode, the floating point one only has two operands. - if (isFloat || isThumb) + + // FIXME: The 'needReg0Op' bit goes away once STRH is converted to + // not use the mega-addrmode stuff. + if (!needReg0Op) AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(StrOpc)) .addReg(SrcReg).addReg(Base).addImm(Offset)); diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index 891c2976f5f..2bfc0652d0e 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -401,9 +401,10 @@ class AI2 op, bit opc22, dag oops, dag iops, AddrMode am, Format f, - InstrItinClass itin, string opc, string asm, list pattern> +// LDR/LDRB/STR/STRB +class AIldst1 op, bit opc22, bit isLd, dag oops, dag iops, AddrMode am, + Format f, InstrItinClass itin, string opc, string asm, + list pattern> : I { let Inst{27-25} = op; @@ -411,7 +412,7 @@ class AIldr1 op, bit opc22, dag oops, dag iops, AddrMode am, Format f, // 23 == U let Inst{22} = opc22; let Inst{21} = 0; // 21 == W - let Inst{20} = 1; + let Inst{20} = isLd; } // LDRH/LDRSB/LDRSH/LDRD class AIldr2 op, bit opc22, bit opc20, dag oops, dag iops, AddrMode am, diff --git a/lib/Target/ARM/ARMInstrInfo.cpp b/lib/Target/ARM/ARMInstrInfo.cpp index d62b93e1b1e..7b40fad0e31 100644 --- a/lib/Target/ARM/ARMInstrInfo.cpp +++ b/lib/Target/ARM/ARMInstrInfo.cpp @@ -48,13 +48,13 @@ unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const { return ARM::LDRSB; case ARM::STR_PRE: case ARM::STR_POST: - return ARM::STR; + return ARM::STRi12; case ARM::STRH_PRE: case ARM::STRH_POST: return ARM::STRH; case ARM::STRB_PRE: case ARM::STRB_POST: - return ARM::STRB; + return ARM::STRBi12; } return 0; diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 7e8f4fff0fd..5e49cf1807e 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -813,7 +813,7 @@ multiclass AI_ldr1 { bits<4> Rt; @@ -823,7 +823,7 @@ multiclass AI_ldr1 { bits<4> Rt; @@ -835,6 +835,32 @@ multiclass AI_ldr1 { + // Note: We use the complex addrmode_imm12 rather than just an input + // GPR and a constrained immediate so that we can use this to match + // frame index references and avoid matching constant pool references. + def i12 : AIldst1<0b010, opc22, 0, (outs), + (ins GPR:$Rt, addrmode_imm12:$addr), + AddrMode_i12, StFrm, iii, opc, "\t$Rt, $addr", + [(opnode GPR:$Rt, addrmode_imm12:$addr)]> { + bits<4> Rt; + bits<17> addr; + let Inst{23} = addr{12}; // U (add = ('U' == 1)) + let Inst{19-16} = addr{16-13}; // Rn + let Inst{15-12} = Rt; + let Inst{11-0} = addr{11-0}; // imm12 + } + def rs : AIldst1<0b011, opc22, 0, (outs), (ins GPR:$Rt, ldst_so_reg:$shift), + AddrModeNone, StFrm, iir, opc, "\t$Rt, $shift", + [(opnode GPR:$Rt, ldst_so_reg:$shift)]> { + bits<4> Rt; + bits<17> shift; + let Inst{23} = shift{12}; // U (add = ('U' == 1)) + let Inst{19-16} = shift{16-13}; // Rn + let Inst{11-0} = shift{11-0}; + } +} //===----------------------------------------------------------------------===// // Instructions //===----------------------------------------------------------------------===// @@ -1409,11 +1435,15 @@ defm LDR : AI_ldr1<0, "ldr", IIC_iLoad_i, IIC_iLoad_r, UnOpFrag<(load node:$Src)>>; defm LDRB : AI_ldr1<1, "ldrb", IIC_iLoad_bh_i, IIC_iLoad_bh_r, UnOpFrag<(zextloadi8 node:$Src)>>; +defm STR : AI_str1<0, "str", IIC_iStore_i, IIC_iStore_r, + BinOpFrag<(store node:$LHS, node:$RHS)>>; +defm STRB : AI_str1<1, "strb", IIC_iStore_bh_i, IIC_iStore_bh_r, + BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>; // Special LDR for loads from non-pc-relative constpools. let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1, isReMaterializable = 1 in -def LDRcp : AIldr1<0b010, 0, (outs GPR:$Rt), (ins addrmode_imm12:$addr), +def LDRcp : AIldst1<0b010, 0, 1, (outs GPR:$Rt), (ins addrmode_imm12:$addr), AddrMode_i12, LdFrm, IIC_iLoad_r, "ldr", "\t$Rt, $addr", []> { bits<4> Rt; bits<17> addr; @@ -1531,19 +1561,12 @@ def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb), } // Store -def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStore_r, - "str", "\t$src, $addr", - [(store GPR:$src, addrmode2:$addr)]>; // Stores with truncate def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, IIC_iStore_bh_r, "strh", "\t$src, $addr", [(truncstorei16 GPR:$src, addrmode3:$addr)]>; -def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, - IIC_iStore_bh_r, "strb", "\t$src, $addr", - [(truncstorei8 GPR:$src, addrmode2:$addr)]>; - // Store doubleword let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr), diff --git a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp index 3715ec002c5..b1367883338 100644 --- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp +++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp @@ -133,7 +133,7 @@ static int getLoadStoreMultipleOpcode(int Opcode) { case ARM::LDRi12: ++NumLDMGened; return ARM::LDM; - case ARM::STR: + case ARM::STRi12: ++NumSTMGened; return ARM::STM; case ARM::t2LDRi8: @@ -174,7 +174,7 @@ static bool isT2i32Store(unsigned Opc) { } static bool isi32Store(unsigned Opc) { - return Opc == ARM::STR || isT2i32Store(Opc); + return Opc == ARM::STRi12 || isT2i32Store(Opc); } /// MergeOps - Create and insert a LDM or STM with Base as base register and @@ -441,7 +441,7 @@ static inline unsigned getLSMultipleTransferSize(MachineInstr *MI) { switch (MI->getOpcode()) { default: return 0; case ARM::LDRi12: - case ARM::STR: + case ARM::STRi12: case ARM::t2LDRi8: case ARM::t2LDRi12: case ARM::t2STRi8: @@ -579,7 +579,7 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLSMultiple(MachineBasicBlock &MBB, static unsigned getPreIndexedLoadStoreOpcode(unsigned Opc) { switch (Opc) { case ARM::LDRi12: return ARM::LDR_PRE; - case ARM::STR: return ARM::STR_PRE; + case ARM::STRi12: return ARM::STR_PRE; case ARM::VLDRS: return ARM::VLDMS_UPD; case ARM::VLDRD: return ARM::VLDMD_UPD; case ARM::VSTRS: return ARM::VSTMS_UPD; @@ -598,7 +598,7 @@ static unsigned getPreIndexedLoadStoreOpcode(unsigned Opc) { static unsigned getPostIndexedLoadStoreOpcode(unsigned Opc) { switch (Opc) { case ARM::LDRi12: return ARM::LDR_POST; - case ARM::STR: return ARM::STR_POST; + case ARM::STRi12: return ARM::STR_POST; case ARM::VLDRS: return ARM::VLDMS_UPD; case ARM::VLDRD: return ARM::VLDMD_UPD; case ARM::VSTRS: return ARM::VSTMS_UPD; @@ -629,16 +629,10 @@ bool ARMLoadStoreOpt::MergeBaseUpdateLoadStore(MachineBasicBlock &MBB, DebugLoc dl = MI->getDebugLoc(); bool isAM5 = (Opcode == ARM::VLDRD || Opcode == ARM::VLDRS || Opcode == ARM::VSTRD || Opcode == ARM::VSTRS); - bool isAM2 = (Opcode == ARM::LDRi12 || Opcode == ARM::STR); - // FIXME: This special handling of LDRi12 is hackery until all of the ARM - // LDR/STR insns are moved away from the addrmode2 mega-instruction to - // the split (LDRi12/LDRrs) style instructions. - if (Opcode == ARM::LDRi12 || isT2i32Load(Opcode) || isT2i32Store(Opcode)) + bool isAM2 = (Opcode == ARM::LDRi12 || Opcode == ARM::STRi12); + if (isi32Load(Opcode) || isi32Store(Opcode)) if (MI->getOperand(2).getImm() != 0) return false; - if (isAM2 && Opcode != ARM::LDRi12 - && ARM_AM::getAM2Offset(MI->getOperand(3).getImm()) != 0) - return false; if (isAM5 && ARM_AM::getAM5Offset(MI->getOperand(2).getImm()) != 0) return false; @@ -786,8 +780,6 @@ static bool isMemoryOp(const MachineInstr *MI) { int Opcode = MI->getOpcode(); switch (Opcode) { default: break; - case ARM::STR: - return MI->getOperand(1).isReg() && MI->getOperand(2).getReg() == 0; case ARM::VLDRS: case ARM::VSTRS: return MI->getOperand(1).isReg(); @@ -795,6 +787,7 @@ static bool isMemoryOp(const MachineInstr *MI) { case ARM::VSTRD: return MI->getOperand(1).isReg(); case ARM::LDRi12: + case ARM::STRi12: case ARM::t2LDRi8: case ARM::t2LDRi12: case ARM::t2STRi8: @@ -822,7 +815,6 @@ void ARMLoadStoreOpt::AdvanceRS(MachineBasicBlock &MBB, MemOpQueue &MemOps) { static int getMemoryOpOffset(const MachineInstr *MI) { int Opcode = MI->getOpcode(); - bool isAM2 = Opcode == ARM::STR; bool isAM3 = Opcode == ARM::LDRD || Opcode == ARM::STRD; unsigned NumOperands = MI->getDesc().getNumOperands(); unsigned OffField = MI->getOperand(NumOperands-3).getImm(); @@ -830,17 +822,12 @@ static int getMemoryOpOffset(const MachineInstr *MI) { if (Opcode == ARM::t2LDRi12 || Opcode == ARM::t2LDRi8 || Opcode == ARM::t2STRi12 || Opcode == ARM::t2STRi8 || Opcode == ARM::t2LDRDi8 || Opcode == ARM::t2STRDi8 || - Opcode == ARM::LDRi12) + Opcode == ARM::LDRi12 || Opcode == ARM::STRi12) return OffField; - int Offset = isAM2 - ? ARM_AM::getAM2Offset(OffField) - : (isAM3 ? ARM_AM::getAM3Offset(OffField) - : ARM_AM::getAM5Offset(OffField) * 4); - if (isAM2) { - if (ARM_AM::getAM2Op(OffField) == ARM_AM::sub) - Offset = -Offset; - } else if (isAM3) { + int Offset = isAM3 ? ARM_AM::getAM3Offset(OffField) + : ARM_AM::getAM5Offset(OffField) * 4; + if (isAM3) { if (ARM_AM::getAM3Op(OffField) == ARM_AM::sub) Offset = -Offset; } else { @@ -852,22 +839,13 @@ static int getMemoryOpOffset(const MachineInstr *MI) { static void InsertLDR_STR(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, - int OffImm, bool isDef, + int Offset, bool isDef, DebugLoc dl, unsigned NewOpc, unsigned Reg, bool RegDeadKill, bool RegUndef, unsigned BaseReg, bool BaseKill, bool BaseUndef, - unsigned OffReg, bool OffKill, bool OffUndef, + bool OffKill, bool OffUndef, ARMCC::CondCodes Pred, unsigned PredReg, const TargetInstrInfo *TII, bool isT2) { - int Offset = OffImm; - // FIXME: This fancy offset encoding stuff goes away when we're done - // removing addrmode2. - if (!isT2 && !isDef) { - if (OffImm < 0) - Offset = ARM_AM::getAM2Opc(ARM_AM::sub, -OffImm, ARM_AM::no_shift); - else - Offset = ARM_AM::getAM2Opc(ARM_AM::add, OffImm, ARM_AM::no_shift); - } if (isDef) { MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(NewOpc)) @@ -879,8 +857,6 @@ static void InsertLDR_STR(MachineBasicBlock &MBB, TII->get(NewOpc)) .addReg(Reg, getKillRegState(RegDeadKill) | getUndefRegState(RegUndef)) .addReg(BaseReg, getKillRegState(BaseKill)|getUndefRegState(BaseUndef)); - if (!isT2) - MIB.addReg(OffReg, getKillRegState(OffKill)|getUndefRegState(OffUndef)); MIB.addImm(Offset).addImm(Pred).addReg(PredReg); } } @@ -911,14 +887,13 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB, unsigned BaseReg = BaseOp.getReg(); bool BaseKill = BaseOp.isKill(); bool BaseUndef = BaseOp.isUndef(); - unsigned OffReg = isT2 ? 0 : MI->getOperand(3).getReg(); bool OffKill = isT2 ? false : MI->getOperand(3).isKill(); bool OffUndef = isT2 ? false : MI->getOperand(3).isUndef(); int OffImm = getMemoryOpOffset(MI); unsigned PredReg = 0; ARMCC::CondCodes Pred = llvm::getInstrPredicate(MI, PredReg); - if (OddRegNum > EvenRegNum && OffReg == 0 && OffImm == 0) { + if (OddRegNum > EvenRegNum && OffImm == 0) { // Ascending register numbers and no offset. It's safe to change it to a // ldm or stm. unsigned NewOpc = (isLd) @@ -946,28 +921,24 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB, NewBBI = llvm::prior(MBBI); } else { // Split into two instructions. - assert((!isT2 || !OffReg) && - "Thumb2 ldrd / strd does not encode offset register!"); unsigned NewOpc = (isLd) ? (isT2 ? (OffImm < 0 ? ARM::t2LDRi8 : ARM::t2LDRi12) : ARM::LDRi12) - : (isT2 ? (OffImm < 0 ? ARM::t2STRi8 : ARM::t2STRi12) : ARM::STR); + : (isT2 ? (OffImm < 0 ? ARM::t2STRi8 : ARM::t2STRi12) : ARM::STRi12); DebugLoc dl = MBBI->getDebugLoc(); // If this is a load and base register is killed, it may have been // re-defed by the load, make sure the first load does not clobber it. if (isLd && (BaseKill || OffKill) && - (TRI->regsOverlap(EvenReg, BaseReg) || - (OffReg && TRI->regsOverlap(EvenReg, OffReg)))) { - assert(!TRI->regsOverlap(OddReg, BaseReg) && - (!OffReg || !TRI->regsOverlap(OddReg, OffReg))); + (TRI->regsOverlap(EvenReg, BaseReg))) { + assert(!TRI->regsOverlap(OddReg, BaseReg)); InsertLDR_STR(MBB, MBBI, OffImm+4, isLd, dl, NewOpc, OddReg, OddDeadKill, false, - BaseReg, false, BaseUndef, OffReg, false, OffUndef, + BaseReg, false, BaseUndef, false, OffUndef, Pred, PredReg, TII, isT2); NewBBI = llvm::prior(MBBI); InsertLDR_STR(MBB, MBBI, OffImm, isLd, dl, NewOpc, EvenReg, EvenDeadKill, false, - BaseReg, BaseKill, BaseUndef, OffReg, OffKill, OffUndef, + BaseReg, BaseKill, BaseUndef, OffKill, OffUndef, Pred, PredReg, TII, isT2); } else { if (OddReg == EvenReg && EvenDeadKill) { @@ -979,12 +950,12 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB, } InsertLDR_STR(MBB, MBBI, OffImm, isLd, dl, NewOpc, EvenReg, EvenDeadKill, EvenUndef, - BaseReg, false, BaseUndef, OffReg, false, OffUndef, + BaseReg, false, BaseUndef, false, OffUndef, Pred, PredReg, TII, isT2); NewBBI = llvm::prior(MBBI); InsertLDR_STR(MBB, MBBI, OffImm+4, isLd, dl, NewOpc, OddReg, OddDeadKill, OddUndef, - BaseReg, BaseKill, BaseUndef, OffReg, OffKill, OffUndef, + BaseReg, BaseKill, BaseUndef, OffKill, OffUndef, Pred, PredReg, TII, isT2); } if (isLd) @@ -1256,7 +1227,7 @@ namespace { bool CanFormLdStDWord(MachineInstr *Op0, MachineInstr *Op1, DebugLoc &dl, unsigned &NewOpc, unsigned &EvenReg, unsigned &OddReg, unsigned &BaseReg, - unsigned &OffReg, int &Offset, + int &Offset, unsigned &PredReg, ARMCC::CondCodes &Pred, bool &isT2); bool RescheduleOps(MachineBasicBlock *MBB, @@ -1336,8 +1307,7 @@ ARMPreAllocLoadStoreOpt::CanFormLdStDWord(MachineInstr *Op0, MachineInstr *Op1, DebugLoc &dl, unsigned &NewOpc, unsigned &EvenReg, unsigned &OddReg, unsigned &BaseReg, - unsigned &OffReg, int &Offset, - unsigned &PredReg, + int &Offset, unsigned &PredReg, ARMCC::CondCodes &Pred, bool &isT2) { // Make sure we're allowed to generate LDRD/STRD. @@ -1349,7 +1319,7 @@ ARMPreAllocLoadStoreOpt::CanFormLdStDWord(MachineInstr *Op0, MachineInstr *Op1, unsigned Opcode = Op0->getOpcode(); if (Opcode == ARM::LDRi12) NewOpc = ARM::LDRD; - else if (Opcode == ARM::STR) + else if (Opcode == ARM::STRi12) NewOpc = ARM::STRD; else if (Opcode == ARM::t2LDRi8 || Opcode == ARM::t2LDRi12) { NewOpc = ARM::t2LDRDi8; @@ -1362,11 +1332,6 @@ ARMPreAllocLoadStoreOpt::CanFormLdStDWord(MachineInstr *Op0, MachineInstr *Op1, } else return false; - // Make sure the offset registers match. - if (!isT2 && Opcode != ARM::LDRi12 && - (Op0->getOperand(2).getReg() != Op1->getOperand(2).getReg())) - return false; - // Make sure the base address satisfies i64 ld / st alignment requirement. if (!Op0->hasOneMemOperand() || !(*Op0->memoperands_begin())->getValue() || @@ -1376,7 +1341,7 @@ ARMPreAllocLoadStoreOpt::CanFormLdStDWord(MachineInstr *Op0, MachineInstr *Op1, unsigned Align = (*Op0->memoperands_begin())->getAlignment(); const Function *Func = MF->getFunction(); unsigned ReqAlign = STI->hasV6Ops() - ? TD->getABITypeAlignment(Type::getInt64Ty(Func->getContext())) + ? TD->getABITypeAlignment(Type::getInt64Ty(Func->getContext())) : 8; // Pre-v6 need 8-byte align if (Align < ReqAlign) return false; @@ -1410,8 +1375,6 @@ ARMPreAllocLoadStoreOpt::CanFormLdStDWord(MachineInstr *Op0, MachineInstr *Op1, if (EvenReg == OddReg) return false; BaseReg = Op0->getOperand(1).getReg(); - if (!isT2 && Opcode != ARM::LDRi12) - OffReg = Op0->getOperand(2).getReg(); Pred = llvm::getInstrPredicate(Op0, PredReg); dl = Op0->getDebugLoc(); return true; @@ -1499,14 +1462,14 @@ bool ARMPreAllocLoadStoreOpt::RescheduleOps(MachineBasicBlock *MBB, MachineInstr *Op0 = Ops.back(); MachineInstr *Op1 = Ops[Ops.size()-2]; unsigned EvenReg = 0, OddReg = 0; - unsigned BaseReg = 0, OffReg = 0, PredReg = 0; + unsigned BaseReg = 0, PredReg = 0; ARMCC::CondCodes Pred = ARMCC::AL; bool isT2 = false; unsigned NewOpc = 0; int Offset = 0; DebugLoc dl; if (NumMove == 2 && CanFormLdStDWord(Op0, Op1, dl, NewOpc, - EvenReg, OddReg, BaseReg, OffReg, + EvenReg, OddReg, BaseReg, Offset, PredReg, Pred, isT2)) { Ops.pop_back(); Ops.pop_back(); @@ -1518,10 +1481,9 @@ bool ARMPreAllocLoadStoreOpt::RescheduleOps(MachineBasicBlock *MBB, .addReg(EvenReg, RegState::Define) .addReg(OddReg, RegState::Define) .addReg(BaseReg); - // For now, we're converting from LDRi12 to an insn that still + // FIXME: We're converting from LDRi12 to an insn that still // uses addrmode2, so we need an explicit offset reg. It should - // always by reg0 since we're transforming LDRi12s. The old - // was just being paranoid in allowing for anything else. + // always by reg0 since we're transforming LDRi12s. if (!isT2) MIB.addReg(0); MIB.addImm(Offset).addImm(Pred).addReg(PredReg); @@ -1532,8 +1494,11 @@ bool ARMPreAllocLoadStoreOpt::RescheduleOps(MachineBasicBlock *MBB, .addReg(EvenReg) .addReg(OddReg) .addReg(BaseReg); + // FIXME: We're converting from LDRi12 to an insn that still + // uses addrmode2, so we need an explicit offset reg. It should + // always by reg0 since we're transforming STRi12s. if (!isT2) - MIB.addReg(OffReg); + MIB.addReg(0); MIB.addImm(Offset).addImm(Pred).addReg(PredReg); ++NumSTRDFormed; }