From 212ae937bb9b52bb1f27f02cb0c28496c4d1e2b9 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Thu, 21 Oct 2010 19:40:30 +0000 Subject: [PATCH] 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 --- lib/Target/ARM/ARMFastISel.cpp | 64 ++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index 4f0411d19a4..92ead77d193 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; -- 2.11.0