aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.cpp21
-rw-r--r--lib/Target/ARM/ARMBaseInstrInfo.h19
-rw-r--r--lib/Target/ARM/ARMBaseRegisterInfo.cpp32
-rw-r--r--lib/Target/ARM/Thumb2InstrInfo.cpp36
4 files changed, 66 insertions, 42 deletions
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp
index d5ceedb1e8..142c3f1a41 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -893,9 +893,9 @@ void llvm::emitARMRegPlusImmediate(MachineBasicBlock &MBB,
}
}
-int llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
- unsigned FrameReg, int Offset,
- const ARMBaseInstrInfo &TII) {
+bool llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
+ unsigned FrameReg, int &Offset,
+ const ARMBaseInstrInfo &TII) {
unsigned Opcode = MI.getOpcode();
const TargetInstrDesc &Desc = MI.getDesc();
unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
@@ -912,7 +912,8 @@ int llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
MI.setDesc(TII.get(ARM::MOVr));
MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
MI.RemoveOperand(FrameRegIdx+1);
- return 0;
+ Offset = 0;
+ return true;
} else if (Offset < 0) {
Offset = -Offset;
isSub = true;
@@ -924,7 +925,8 @@ int llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
// Replace the FrameIndex with sp / fp
MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
- return 0;
+ Offset = 0;
+ return true;
}
// Otherwise, pull as much of the immedidate into this ADDri/SUBri
@@ -962,7 +964,8 @@ int llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
break;
}
case ARMII::AddrMode4:
- break;
+ // Can't fold any offset even if it's zero.
+ return false;
case ARMII::AddrMode5: {
ImmIdx = FrameRegIdx+1;
InstrOffs = ARM_AM::getAM5Offset(MI.getOperand(ImmIdx).getImm());
@@ -996,7 +999,8 @@ int llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
if (isSub)
ImmedOffset |= 1 << NumBits;
ImmOp.ChangeToImmediate(ImmedOffset);
- return 0;
+ Offset = 0;
+ return true;
}
// Otherwise, it didn't fit. Pull in what we can to simplify the immed.
@@ -1008,5 +1012,6 @@ int llvm::rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
}
}
- return (isSub) ? -Offset : Offset;
+ Offset = (isSub) ? -Offset : Offset;
+ return Offset == 0;
}
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.h b/lib/Target/ARM/ARMBaseInstrInfo.h
index f4d1ef373d..3632450ede 100644
--- a/lib/Target/ARM/ARMBaseInstrInfo.h
+++ b/lib/Target/ARM/ARMBaseInstrInfo.h
@@ -317,15 +317,16 @@ void emitT2RegPlusImmediate(MachineBasicBlock &MBB,
/// rewriteARMFrameIndex / rewriteT2FrameIndex -
-/// Rewrite MI to access 'Offset' bytes from the FP. Return the offset that
-/// could not be handled directly in MI.
-int rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
- unsigned FrameReg, int Offset,
- const ARMBaseInstrInfo &TII);
-
-int rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
- unsigned FrameReg, int Offset,
- const ARMBaseInstrInfo &TII);
+/// Rewrite MI to access 'Offset' bytes from the FP. Return false if the
+/// offset could not be handled directly in MI, and return the left-over
+/// portion by reference.
+bool rewriteARMFrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
+ unsigned FrameReg, int &Offset,
+ const ARMBaseInstrInfo &TII);
+
+bool rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
+ unsigned FrameReg, int &Offset,
+ const ARMBaseInstrInfo &TII);
} // End llvm namespace
diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index 07164ff6f5..b0108f2306 100644
--- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -1047,19 +1047,24 @@ ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
}
// modify MI as necessary to handle as much of 'Offset' as possible
+ bool Done = false;
if (!AFI->isThumbFunction())
- Offset = rewriteARMFrameIndex(MI, i, FrameReg, Offset, TII);
+ Done = rewriteARMFrameIndex(MI, i, FrameReg, Offset, TII);
else {
assert(AFI->isThumb2Function());
- Offset = rewriteT2FrameIndex(MI, i, FrameReg, Offset, TII);
+ Done = rewriteT2FrameIndex(MI, i, FrameReg, Offset, TII);
}
- if (Offset == 0)
+ if (Done)
return;
+ const TargetInstrDesc &Desc = MI.getDesc();
+ unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
+
// If we get here, the immediate doesn't fit into the instruction. We folded
// as much as possible above, handle the rest, providing a register that is
// SP+LargeImm.
- assert(Offset && "This code isn't needed if offset already handled!");
+ assert((Offset || AddrMode == ARMII::AddrMode4) &&
+ "This code isn't needed if offset already handled!");
// Insert a set of r12 with the full address: r12 = sp + offset
// If the offset we have is too large to fit into the instruction, we need
@@ -1073,15 +1078,20 @@ ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
ARMCC::CondCodes Pred = (PIdx == -1)
? ARMCC::AL : (ARMCC::CondCodes)MI.getOperand(PIdx).getImm();
unsigned PredReg = (PIdx == -1) ? 0 : MI.getOperand(PIdx+1).getReg();
- if (!AFI->isThumbFunction())
- emitARMRegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
- Offset, Pred, PredReg, TII);
+ if (Offset == 0)
+ // Must be addrmode4.
+ MI.getOperand(i).ChangeToRegister(FrameReg, false, false, false);
else {
- assert(AFI->isThumb2Function());
- emitT2RegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
- Offset, Pred, PredReg, TII);
+ if (!AFI->isThumbFunction())
+ emitARMRegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
+ Offset, Pred, PredReg, TII);
+ else {
+ assert(AFI->isThumb2Function());
+ emitT2RegPlusImmediate(MBB, II, MI.getDebugLoc(), ScratchReg, FrameReg,
+ Offset, Pred, PredReg, TII);
+ }
+ MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
}
- MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
}
/// Move iterator pass the next bunch of callee save load / store ops for
diff --git a/lib/Target/ARM/Thumb2InstrInfo.cpp b/lib/Target/ARM/Thumb2InstrInfo.cpp
index d37f61e490..8c09ebd3e0 100644
--- a/lib/Target/ARM/Thumb2InstrInfo.cpp
+++ b/lib/Target/ARM/Thumb2InstrInfo.cpp
@@ -319,9 +319,9 @@ immediateOffsetOpcode(unsigned opcode)
return 0;
}
-int llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
- unsigned FrameReg, int Offset,
- const ARMBaseInstrInfo &TII) {
+bool llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
+ unsigned FrameReg, int &Offset,
+ const ARMBaseInstrInfo &TII) {
unsigned Opcode = MI.getOpcode();
const TargetInstrDesc &Desc = MI.getDesc();
unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
@@ -340,7 +340,8 @@ int llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
MI.setDesc(TII.get(ARM::tMOVgpr2gpr));
MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
MI.RemoveOperand(FrameRegIdx+1);
- return 0;
+ Offset = 0;
+ return true;
}
if (Offset < 0) {
@@ -355,7 +356,8 @@ int llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
if (ARM_AM::getT2SOImmVal(Offset) != -1) {
MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
- return 0;
+ Offset = 0;
+ return true;
}
// Another common case: imm12.
if (Offset < 4096) {
@@ -365,7 +367,8 @@ int llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
MI.setDesc(TII.get(NewOpc));
MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
MI.getOperand(FrameRegIdx+1).ChangeToImmediate(Offset);
- return 0;
+ Offset = 0;
+ return true;
}
// Otherwise, extract 8 adjacent bits from the immediate into this
@@ -387,7 +390,7 @@ int llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
unsigned OffsetReg = MI.getOperand(FrameRegIdx+1).getReg();
if (OffsetReg != 0) {
MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false);
- return Offset;
+ return Offset == 0;
}
MI.RemoveOperand(FrameRegIdx+1);
@@ -413,11 +416,14 @@ int llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
NumBits = 12;
}
} else {
- // VFP address modes.
- assert(AddrMode == ARMII::AddrMode5);
- int InstrOffs=ARM_AM::getAM5Offset(MI.getOperand(FrameRegIdx+1).getImm());
- if (ARM_AM::getAM5Op(MI.getOperand(FrameRegIdx+1).getImm()) ==ARM_AM::sub)
- InstrOffs *= -1;
+ // VFP and NEON address modes.
+ int InstrOffs = 0;
+ if (AddrMode == ARMII::AddrMode5) {
+ const MachineOperand &OffOp = MI.getOperand(FrameRegIdx+1);
+ InstrOffs = ARM_AM::getAM5Offset(OffOp.getImm());
+ if (ARM_AM::getAM5Op(OffOp.getImm()) == ARM_AM::sub)
+ InstrOffs *= -1;
+ }
NumBits = 8;
Scale = 4;
Offset += InstrOffs * 4;
@@ -448,7 +454,8 @@ int llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
ImmedOffset = -ImmedOffset;
}
ImmOp.ChangeToImmediate(ImmedOffset);
- return 0;
+ Offset = 0;
+ return true;
}
// Otherwise, offset doesn't fit. Pull in what we can to simplify
@@ -468,5 +475,6 @@ int llvm::rewriteT2FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
Offset &= ~(Mask*Scale);
}
- return (isSub) ? -Offset : Offset;
+ Offset = (isSub) ? -Offset : Offset;
+ return Offset == 0;
}