diff options
author | Eric Christopher <echristo@apple.com> | 2010-10-21 19:40:30 +0000 |
---|---|---|
committer | Eric Christopher <echristo@apple.com> | 2010-10-21 19:40:30 +0000 |
commit | 212ae937bb9b52bb1f27f02cb0c28496c4d1e2b9 (patch) | |
tree | b03bd50e42b55117b33e36b3223142ed78301972 /lib/Target/ARM/ARMFastISel.cpp | |
parent | 3ab5658a127d78c4bcf2b4a69fb838f14f833f0a (diff) |
More load/store refactoring, call reg+offset simplification from within
the emitter to handle the addresses. Only simplify the offset if we need
to - also fix bug where in addrmode 5 we weren't dividing the offset by
4, which showed up due to not always lowering.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117051 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMFastISel.cpp')
-rw-r--r-- | lib/Target/ARM/ARMFastISel.cpp | 64 |
1 files changed, 36 insertions, 28 deletions
diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index 4f0411d19a..92ead77d19 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -683,12 +683,30 @@ bool ARMFastISel::ARMComputeRegOffset(const Value *Obj, unsigned &Base, } void ARMFastISel::ARMSimplifyRegOffset(unsigned &Base, int &Offset, EVT VT) { - - assert (Base != ARM::SP && "How'd we get a stack pointer here?"); - // Since the offset may be too large for the load instruction + assert(VT.isSimple() && "Non-simple types are invalid here!"); + + bool needsLowering = false; + switch (VT.getSimpleVT().SimpleTy) { + default: + assert(false && "Unhandled load/store type!"); + case MVT::i1: + case MVT::i8: + case MVT::i16: + case MVT::i32: + // Integer loads/stores handle 12-bit offsets. + needsLowering = ((Offset & 0xfff) != Offset); + break; + case MVT::f32: + case MVT::f64: + // Floating point operands handle 8-bit offsets. + needsLowering = ((Offset & 0xff) != Offset); + break; + } + + // Since the offset is too large for the load/store instruction // get the reg+offset into a register. - if (Offset != 0) { + if (needsLowering) { ARMCC::CondCodes Pred = ARMCC::AL; unsigned PredReg = 0; @@ -725,12 +743,10 @@ bool ARMFastISel::ARMEmitLoad(EVT VT, unsigned &ResultReg, case MVT::i16: Opc = isThumb ? ARM::t2LDRHi12 : ARM::LDRH; RC = ARM::GPRRegisterClass; - VT = MVT::i32; break; case MVT::i8: Opc = isThumb ? ARM::t2LDRBi12 : ARM::LDRB; RC = ARM::GPRRegisterClass; - VT = MVT::i32; break; case MVT::i32: Opc = isThumb ? ARM::t2LDRi12 : ARM::LDR; @@ -750,13 +766,13 @@ bool ARMFastISel::ARMEmitLoad(EVT VT, unsigned &ResultReg, ResultReg = createResultReg(RC); - // All SP loads should already have been lowered to another reg. - assert(Base != ARM::SP && "No stack stores this late!"); - - // For now with the additions above the offset should be zero - thus we - // can always fit into an i12. - assert(Offset == 0 && "Offset should be zero at this point!"); - + ARMSimplifyRegOffset(Base, Offset, VT); + + // addrmode5 output depends on the selection dag addressing dividing the + // offset by 4 that it then later multiplies. Do this here as well. + if (isFloat) + Offset /= 4; + // The thumb and floating point instructions both take 2 operands, ARM takes // another register. if (isFloat || isThumb) @@ -784,8 +800,6 @@ bool ARMFastISel::SelectLoad(const Instruction *I) { if (!ARMComputeRegOffset(I->getOperand(0), Base, Offset)) return false; - ARMSimplifyRegOffset(Base, Offset, VT); - unsigned ResultReg; if (!ARMEmitLoad(VT, ResultReg, Base, Offset)) return false; @@ -797,17 +811,13 @@ bool ARMFastISel::ARMEmitStore(EVT VT, unsigned SrcReg, unsigned Base, int Offset) { unsigned StrOpc; bool isFloat = false; - // VT is set here only for use in the alloca stores below - those are promoted - // to reg size always. switch (VT.getSimpleVT().SimpleTy) { default: return false; case MVT::i1: case MVT::i8: - VT = MVT::i32; StrOpc = isThumb ? ARM::t2STRBi12 : ARM::STRB; break; case MVT::i16: - VT = MVT::i32; StrOpc = isThumb ? ARM::t2STRHi12 : ARM::STRH; break; case MVT::i32: @@ -825,13 +835,13 @@ bool ARMFastISel::ARMEmitStore(EVT VT, unsigned SrcReg, break; } - // All SP stores should already have been lowered to another reg. - assert(Base != ARM::SP && "No stack stores this late!"); - - // For now with the additions above the offset should be zero - thus we - // can always fit into an i12. - assert(Offset == 0 && "Offset should be zero at this point!"); - + ARMSimplifyRegOffset(Base, Offset, VT); + + // addrmode5 output depends on the selection dag addressing dividing the + // offset by 4 that it then later multiplies. Do this here as well. + 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) @@ -868,8 +878,6 @@ bool ARMFastISel::SelectStore(const Instruction *I) { if (!ARMComputeRegOffset(I->getOperand(1), Base, Offset)) return false; - ARMSimplifyRegOffset(Base, Offset, VT); - if (!ARMEmitStore(VT, SrcReg, Base, Offset)) return false; return true; |