[llvm-commits] [llvm] r117505 - in /llvm/trunk/lib/Target/ARM: ARMAsmPrinter.cpp ARMBaseInstrInfo.cpp ARMBaseRegisterInfo.cpp ARMCodeEmitter.cpp ARMFastISel.cpp ARMInstrFormats.td ARMInstrInfo.cpp ARMInstrInfo.td ARMLoadStoreOptimizer.cpp
Jim Grosbach
grosbach at apple.com
Wed Oct 27 16:12:14 PDT 2010
Author: grosbach
Date: Wed Oct 27 18:12:14 2010
New Revision: 117505
URL: http://llvm.org/viewvc/llvm-project?rev=117505&view=rev
Log:
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
Modified:
llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp
llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp
llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp
llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=117505&r1=117504&r2=117505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Wed Oct 27 18:12:14 2010
@@ -870,8 +870,8 @@
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 @@
}
{
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));
Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=117505&r1=117504&r2=117505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Wed Oct 27 18:12:14 2010
@@ -676,9 +676,9 @@
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 @@
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 @@
return MI->getOperand(0).getReg();
}
break;
+ case ARM::STRi12:
case ARM::t2STRi12:
case ARM::tSpill:
case ARM::VSTRD:
Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp?rev=117505&r1=117504&r2=117505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.cpp Wed Oct 27 18:12:14 2010
@@ -1377,7 +1377,7 @@
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 @@
// 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);
Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=117505&r1=117504&r2=117505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Wed Oct 27 18:12:14 2010
@@ -966,8 +966,9 @@
// 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;
}
Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=117505&r1=117504&r2=117505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Wed Oct 27 18:12:14 2010
@@ -805,17 +805,19 @@
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 @@
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));
Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=117505&r1=117504&r2=117505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Wed Oct 27 18:12:14 2010
@@ -401,9 +401,10 @@
// loads
-// LDR/LDRB
-class AIldr1<bits<3> op, bit opc22, dag oops, dag iops, AddrMode am, Format f,
- InstrItinClass itin, string opc, string asm, list<dag> pattern>
+// LDR/LDRB/STR/STRB
+class AIldst1<bits<3> op, bit opc22, bit isLd, dag oops, dag iops, AddrMode am,
+ Format f, InstrItinClass itin, string opc, string asm,
+ list<dag> pattern>
: I<oops, iops, am, Size4Bytes, IndexModeNone, f, itin, opc, asm,
"", pattern> {
let Inst{27-25} = op;
@@ -411,7 +412,7 @@
// 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<bits<4> op, bit opc22, bit opc20, dag oops, dag iops, AddrMode am,
Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp?rev=117505&r1=117504&r2=117505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.cpp Wed Oct 27 18:12:14 2010
@@ -48,13 +48,13 @@
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;
Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=117505&r1=117504&r2=117505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Wed Oct 27 18:12:14 2010
@@ -813,7 +813,7 @@
// 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 : AIldr1<0b010, opc22, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
+ def i12 : AIldst1<0b010, opc22, 1, (outs GPR:$Rt), (ins addrmode_imm12:$addr),
AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
[(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
bits<4> Rt;
@@ -823,7 +823,7 @@
let Inst{15-12} = Rt;
let Inst{11-0} = addr{11-0}; // imm12
}
- def rs : AIldr1<0b011, opc22, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
+ def rs : AIldst1<0b011, opc22, 1, (outs GPR:$Rt), (ins ldst_so_reg:$shift),
AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
[(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
bits<4> Rt;
@@ -835,6 +835,32 @@
}
}
+multiclass AI_str1<bit opc22, string opc, InstrItinClass iii,
+ InstrItinClass iir, PatFrag opnode> {
+ // 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 @@
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 @@
}
// 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),
Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=117505&r1=117504&r2=117505&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Wed Oct 27 18:12:14 2010
@@ -133,7 +133,7 @@
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 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 @@
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 @@
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 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 @@
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 @@
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 @@
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 @@
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 @@
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 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 @@
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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
} 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 @@
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 @@
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 @@
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 @@
.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 @@
.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;
}
More information about the llvm-commits
mailing list