From: Eric Christopher Date: Mon, 23 Aug 2010 21:44:12 +0000 (+0000) Subject: Start getting ARM loads/address computation going. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8300712c1e73dc106242f0007e0e0e4dd9ea38ce;p=oota-llvm.git Start getting ARM loads/address computation going. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111850 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMFastISel.cpp b/lib/Target/ARM/ARMFastISel.cpp index 6281c3a3b0b..c2a05512103 100644 --- a/lib/Target/ARM/ARMFastISel.cpp +++ b/lib/Target/ARM/ARMFastISel.cpp @@ -101,8 +101,14 @@ class ARMFastISel : public FastISel { virtual bool TargetSelectInstruction(const Instruction *I); #include "ARMGenFastISel.inc" + + // Instruction selection routines. + virtual bool ARMSelectLoad(const Instruction *I); + // Utility routines. private: + bool ARMComputeRegOffset(const Instruction *I, unsigned &Reg, int &Offset); + bool DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR); const MachineInstrBuilder &AddOptionalDefs(const MachineInstrBuilder &MIB); }; @@ -301,8 +307,75 @@ unsigned ARMFastISel::FastEmitInst_extractsubreg(MVT RetVT, return ResultReg; } +bool ARMFastISel::ARMComputeRegOffset(const Instruction *I, unsigned &Reg, + int &Offset) { + // Some boilerplate from the X86 FastISel. + const User *U = NULL; + Value *Op1 = I->getOperand(0); + unsigned Opcode = Instruction::UserOp1; + if (const Instruction *I = dyn_cast(Op1)) { + // Don't walk into other basic blocks; it's possible we haven't + // visited them yet, so the instructions may not yet be assigned + // virtual registers. + if (FuncInfo.MBBMap[I->getParent()] != FuncInfo.MBB) + return false; + + Opcode = I->getOpcode(); + U = I; + } else if (const ConstantExpr *C = dyn_cast(Op1)) { + Opcode = C->getOpcode(); + U = C; + } + + if (const PointerType *Ty = dyn_cast(Op1->getType())) + if (Ty->getAddressSpace() > 255) + // Fast instruction selection doesn't support the special + // address spaces. + return false; + + switch (Opcode) { + default: + //errs() << "Failing Opcode is: " << *Op1 << "\n"; + break; + case Instruction::Alloca: { + // Do static allocas. + const AllocaInst *A = cast(Op1); + DenseMap::iterator SI = + FuncInfo.StaticAllocaMap.find(A); + if (SI != FuncInfo.StaticAllocaMap.end()) + Offset = + TM.getRegisterInfo()->getFrameIndexReference(*FuncInfo.MF, + SI->second, Reg); + else + return false; + return true; + } + } + return false; +} + +bool ARMFastISel::ARMSelectLoad(const Instruction *I) { + + unsigned Reg; + int Offset; + + // See if we can handle this as Reg + Offset + if (!ARMComputeRegOffset(I, Reg, Offset)) + return false; + + + unsigned ResultReg = createResultReg(ARM::GPRRegisterClass); + AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, + TII.get(ARM::LDR), ResultReg) + .addImm(0).addReg(Reg).addImm(Offset)); + + return true; +} + bool ARMFastISel::TargetSelectInstruction(const Instruction *I) { switch (I->getOpcode()) { + case Instruction::Load: + return ARMSelectLoad(I); default: break; } return false;