ARMFastISel.cpp revision bd6bf0848ee651a3cf4ea868b7a7605e37b4e028
1//===-- ARMFastISel.cpp - ARM FastISel implementation ---------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the ARM-specific support for the FastISel class. Some 11// of the target-specific code is generated by tablegen in the file 12// ARMGenFastISel.inc, which is #included here. 13// 14//===----------------------------------------------------------------------===// 15 16#include "ARM.h" 17#include "ARMBaseInstrInfo.h" 18#include "ARMRegisterInfo.h" 19#include "ARMTargetMachine.h" 20#include "ARMSubtarget.h" 21#include "llvm/CallingConv.h" 22#include "llvm/DerivedTypes.h" 23#include "llvm/GlobalVariable.h" 24#include "llvm/Instructions.h" 25#include "llvm/IntrinsicInst.h" 26#include "llvm/CodeGen/Analysis.h" 27#include "llvm/CodeGen/FastISel.h" 28#include "llvm/CodeGen/FunctionLoweringInfo.h" 29#include "llvm/CodeGen/MachineInstrBuilder.h" 30#include "llvm/CodeGen/MachineModuleInfo.h" 31#include "llvm/CodeGen/MachineConstantPool.h" 32#include "llvm/CodeGen/MachineFrameInfo.h" 33#include "llvm/CodeGen/MachineRegisterInfo.h" 34#include "llvm/Support/CallSite.h" 35#include "llvm/Support/CommandLine.h" 36#include "llvm/Support/ErrorHandling.h" 37#include "llvm/Support/GetElementPtrTypeIterator.h" 38#include "llvm/Target/TargetData.h" 39#include "llvm/Target/TargetInstrInfo.h" 40#include "llvm/Target/TargetLowering.h" 41#include "llvm/Target/TargetMachine.h" 42#include "llvm/Target/TargetOptions.h" 43using namespace llvm; 44 45static cl::opt<bool> 46EnableARMFastISel("arm-fast-isel", 47 cl::desc("Turn on experimental ARM fast-isel support"), 48 cl::init(false), cl::Hidden); 49 50namespace { 51 52class ARMFastISel : public FastISel { 53 54 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can 55 /// make the right decision when generating code for different targets. 56 const ARMSubtarget *Subtarget; 57 const TargetMachine &TM; 58 const TargetInstrInfo &TII; 59 const TargetLowering &TLI; 60 const ARMFunctionInfo *AFI; 61 62 // Convenience variable to avoid checking all the time. 63 bool isThumb; 64 65 public: 66 explicit ARMFastISel(FunctionLoweringInfo &funcInfo) 67 : FastISel(funcInfo), 68 TM(funcInfo.MF->getTarget()), 69 TII(*TM.getInstrInfo()), 70 TLI(*TM.getTargetLowering()) { 71 Subtarget = &TM.getSubtarget<ARMSubtarget>(); 72 AFI = funcInfo.MF->getInfo<ARMFunctionInfo>(); 73 isThumb = AFI->isThumbFunction(); 74 } 75 76 // Code from FastISel.cpp. 77 virtual unsigned FastEmitInst_(unsigned MachineInstOpcode, 78 const TargetRegisterClass *RC); 79 virtual unsigned FastEmitInst_r(unsigned MachineInstOpcode, 80 const TargetRegisterClass *RC, 81 unsigned Op0, bool Op0IsKill); 82 virtual unsigned FastEmitInst_rr(unsigned MachineInstOpcode, 83 const TargetRegisterClass *RC, 84 unsigned Op0, bool Op0IsKill, 85 unsigned Op1, bool Op1IsKill); 86 virtual unsigned FastEmitInst_ri(unsigned MachineInstOpcode, 87 const TargetRegisterClass *RC, 88 unsigned Op0, bool Op0IsKill, 89 uint64_t Imm); 90 virtual unsigned FastEmitInst_rf(unsigned MachineInstOpcode, 91 const TargetRegisterClass *RC, 92 unsigned Op0, bool Op0IsKill, 93 const ConstantFP *FPImm); 94 virtual unsigned FastEmitInst_i(unsigned MachineInstOpcode, 95 const TargetRegisterClass *RC, 96 uint64_t Imm); 97 virtual unsigned FastEmitInst_rri(unsigned MachineInstOpcode, 98 const TargetRegisterClass *RC, 99 unsigned Op0, bool Op0IsKill, 100 unsigned Op1, bool Op1IsKill, 101 uint64_t Imm); 102 virtual unsigned FastEmitInst_extractsubreg(MVT RetVT, 103 unsigned Op0, bool Op0IsKill, 104 uint32_t Idx); 105 106 // Backend specific FastISel code. 107 virtual bool TargetSelectInstruction(const Instruction *I); 108 virtual unsigned TargetMaterializeConstant(const Constant *C); 109 110 #include "ARMGenFastISel.inc" 111 112 // Instruction selection routines. 113 virtual bool ARMSelectLoad(const Instruction *I); 114 virtual bool ARMSelectStore(const Instruction *I); 115 virtual bool ARMSelectBranch(const Instruction *I); 116 virtual bool ARMSelectCmp(const Instruction *I); 117 virtual bool ARMSelectFPExt(const Instruction *I); 118 virtual bool ARMSelectBinaryOp(const Instruction *I, unsigned ISDOpcode); 119 120 // Utility routines. 121 private: 122 bool isTypeLegal(const Type *Ty, EVT &VT); 123 bool isLoadTypeLegal(const Type *Ty, EVT &VT); 124 bool ARMEmitLoad(EVT VT, unsigned &ResultReg, unsigned Reg, int Offset); 125 bool ARMEmitStore(EVT VT, unsigned SrcReg, unsigned Reg, int Offset); 126 bool ARMLoadAlloca(const Instruction *I, EVT VT); 127 bool ARMStoreAlloca(const Instruction *I, unsigned SrcReg, EVT VT); 128 bool ARMComputeRegOffset(const Value *Obj, unsigned &Reg, int &Offset); 129 unsigned ARMMaterializeFP(const ConstantFP *CFP, EVT VT); 130 unsigned ARMMaterializeInt(const Constant *C); 131 132 bool DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR); 133 const MachineInstrBuilder &AddOptionalDefs(const MachineInstrBuilder &MIB); 134}; 135 136} // end anonymous namespace 137 138// #include "ARMGenCallingConv.inc" 139 140// DefinesOptionalPredicate - This is different from DefinesPredicate in that 141// we don't care about implicit defs here, just places we'll need to add a 142// default CCReg argument. Sets CPSR if we're setting CPSR instead of CCR. 143bool ARMFastISel::DefinesOptionalPredicate(MachineInstr *MI, bool *CPSR) { 144 const TargetInstrDesc &TID = MI->getDesc(); 145 if (!TID.hasOptionalDef()) 146 return false; 147 148 // Look to see if our OptionalDef is defining CPSR or CCR. 149 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { 150 const MachineOperand &MO = MI->getOperand(i); 151 if (!MO.isReg() || !MO.isDef()) continue; 152 if (MO.getReg() == ARM::CPSR) 153 *CPSR = true; 154 } 155 return true; 156} 157 158// If the machine is predicable go ahead and add the predicate operands, if 159// it needs default CC operands add those. 160const MachineInstrBuilder & 161ARMFastISel::AddOptionalDefs(const MachineInstrBuilder &MIB) { 162 MachineInstr *MI = &*MIB; 163 164 // Do we use a predicate? 165 if (TII.isPredicable(MI)) 166 AddDefaultPred(MIB); 167 168 // Do we optionally set a predicate? Preds is size > 0 iff the predicate 169 // defines CPSR. All other OptionalDefines in ARM are the CCR register. 170 bool CPSR = false; 171 if (DefinesOptionalPredicate(MI, &CPSR)) { 172 if (CPSR) 173 AddDefaultT1CC(MIB); 174 else 175 AddDefaultCC(MIB); 176 } 177 return MIB; 178} 179 180unsigned ARMFastISel::FastEmitInst_(unsigned MachineInstOpcode, 181 const TargetRegisterClass* RC) { 182 unsigned ResultReg = createResultReg(RC); 183 const TargetInstrDesc &II = TII.get(MachineInstOpcode); 184 185 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg)); 186 return ResultReg; 187} 188 189unsigned ARMFastISel::FastEmitInst_r(unsigned MachineInstOpcode, 190 const TargetRegisterClass *RC, 191 unsigned Op0, bool Op0IsKill) { 192 unsigned ResultReg = createResultReg(RC); 193 const TargetInstrDesc &II = TII.get(MachineInstOpcode); 194 195 if (II.getNumDefs() >= 1) 196 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) 197 .addReg(Op0, Op0IsKill * RegState::Kill)); 198 else { 199 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 200 .addReg(Op0, Op0IsKill * RegState::Kill)); 201 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 202 TII.get(TargetOpcode::COPY), ResultReg) 203 .addReg(II.ImplicitDefs[0])); 204 } 205 return ResultReg; 206} 207 208unsigned ARMFastISel::FastEmitInst_rr(unsigned MachineInstOpcode, 209 const TargetRegisterClass *RC, 210 unsigned Op0, bool Op0IsKill, 211 unsigned Op1, bool Op1IsKill) { 212 unsigned ResultReg = createResultReg(RC); 213 const TargetInstrDesc &II = TII.get(MachineInstOpcode); 214 215 if (II.getNumDefs() >= 1) 216 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) 217 .addReg(Op0, Op0IsKill * RegState::Kill) 218 .addReg(Op1, Op1IsKill * RegState::Kill)); 219 else { 220 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 221 .addReg(Op0, Op0IsKill * RegState::Kill) 222 .addReg(Op1, Op1IsKill * RegState::Kill)); 223 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 224 TII.get(TargetOpcode::COPY), ResultReg) 225 .addReg(II.ImplicitDefs[0])); 226 } 227 return ResultReg; 228} 229 230unsigned ARMFastISel::FastEmitInst_ri(unsigned MachineInstOpcode, 231 const TargetRegisterClass *RC, 232 unsigned Op0, bool Op0IsKill, 233 uint64_t Imm) { 234 unsigned ResultReg = createResultReg(RC); 235 const TargetInstrDesc &II = TII.get(MachineInstOpcode); 236 237 if (II.getNumDefs() >= 1) 238 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) 239 .addReg(Op0, Op0IsKill * RegState::Kill) 240 .addImm(Imm)); 241 else { 242 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 243 .addReg(Op0, Op0IsKill * RegState::Kill) 244 .addImm(Imm)); 245 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 246 TII.get(TargetOpcode::COPY), ResultReg) 247 .addReg(II.ImplicitDefs[0])); 248 } 249 return ResultReg; 250} 251 252unsigned ARMFastISel::FastEmitInst_rf(unsigned MachineInstOpcode, 253 const TargetRegisterClass *RC, 254 unsigned Op0, bool Op0IsKill, 255 const ConstantFP *FPImm) { 256 unsigned ResultReg = createResultReg(RC); 257 const TargetInstrDesc &II = TII.get(MachineInstOpcode); 258 259 if (II.getNumDefs() >= 1) 260 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) 261 .addReg(Op0, Op0IsKill * RegState::Kill) 262 .addFPImm(FPImm)); 263 else { 264 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 265 .addReg(Op0, Op0IsKill * RegState::Kill) 266 .addFPImm(FPImm)); 267 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 268 TII.get(TargetOpcode::COPY), ResultReg) 269 .addReg(II.ImplicitDefs[0])); 270 } 271 return ResultReg; 272} 273 274unsigned ARMFastISel::FastEmitInst_rri(unsigned MachineInstOpcode, 275 const TargetRegisterClass *RC, 276 unsigned Op0, bool Op0IsKill, 277 unsigned Op1, bool Op1IsKill, 278 uint64_t Imm) { 279 unsigned ResultReg = createResultReg(RC); 280 const TargetInstrDesc &II = TII.get(MachineInstOpcode); 281 282 if (II.getNumDefs() >= 1) 283 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) 284 .addReg(Op0, Op0IsKill * RegState::Kill) 285 .addReg(Op1, Op1IsKill * RegState::Kill) 286 .addImm(Imm)); 287 else { 288 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 289 .addReg(Op0, Op0IsKill * RegState::Kill) 290 .addReg(Op1, Op1IsKill * RegState::Kill) 291 .addImm(Imm)); 292 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 293 TII.get(TargetOpcode::COPY), ResultReg) 294 .addReg(II.ImplicitDefs[0])); 295 } 296 return ResultReg; 297} 298 299unsigned ARMFastISel::FastEmitInst_i(unsigned MachineInstOpcode, 300 const TargetRegisterClass *RC, 301 uint64_t Imm) { 302 unsigned ResultReg = createResultReg(RC); 303 const TargetInstrDesc &II = TII.get(MachineInstOpcode); 304 305 if (II.getNumDefs() >= 1) 306 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II, ResultReg) 307 .addImm(Imm)); 308 else { 309 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, II) 310 .addImm(Imm)); 311 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 312 TII.get(TargetOpcode::COPY), ResultReg) 313 .addReg(II.ImplicitDefs[0])); 314 } 315 return ResultReg; 316} 317 318unsigned ARMFastISel::FastEmitInst_extractsubreg(MVT RetVT, 319 unsigned Op0, bool Op0IsKill, 320 uint32_t Idx) { 321 unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT)); 322 assert(TargetRegisterInfo::isVirtualRegister(Op0) && 323 "Cannot yet extract from physregs"); 324 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, 325 DL, TII.get(TargetOpcode::COPY), ResultReg) 326 .addReg(Op0, getKillRegState(Op0IsKill), Idx)); 327 return ResultReg; 328} 329 330// For double width floating point we need to materialize two constants 331// (the high and the low) into integer registers then use a move to get 332// the combined constant into an FP reg. 333unsigned ARMFastISel::ARMMaterializeFP(const ConstantFP *CFP, EVT VT) { 334 const APFloat Val = CFP->getValueAPF(); 335 bool is64bit = VT.getSimpleVT().SimpleTy == MVT::f64; 336 337 // This checks to see if we can use VFP3 instructions to materialize 338 // a constant, otherwise we have to go through the constant pool. 339 if (TLI.isFPImmLegal(Val, VT)) { 340 unsigned Opc = is64bit ? ARM::FCONSTD : ARM::FCONSTS; 341 unsigned DestReg = createResultReg(TLI.getRegClassFor(VT)); 342 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), 343 DestReg) 344 .addFPImm(CFP)); 345 return DestReg; 346 } 347 348 // No 64-bit at the moment. 349 if (is64bit) return 0; 350 351 // Load this from the constant pool. 352 unsigned DestReg = ARMMaterializeInt(cast<Constant>(CFP)); 353 354 // If we have a floating point constant we expect it in a floating point 355 // register. 356 unsigned MoveReg = createResultReg(TLI.getRegClassFor(VT)); 357 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 358 TII.get(ARM::VMOVRS), MoveReg) 359 .addReg(DestReg)); 360 return MoveReg; 361} 362 363unsigned ARMFastISel::ARMMaterializeInt(const Constant *C) { 364 // MachineConstantPool wants an explicit alignment. 365 unsigned Align = TD.getPrefTypeAlignment(C->getType()); 366 if (Align == 0) { 367 // TODO: Figure out if this is correct. 368 Align = TD.getTypeAllocSize(C->getType()); 369 } 370 unsigned Idx = MCP.getConstantPoolIndex(C, Align); 371 372 unsigned DestReg = createResultReg(TLI.getRegClassFor(MVT::i32)); 373 if (isThumb) 374 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 375 TII.get(ARM::t2LDRpci)) 376 .addReg(DestReg).addConstantPoolIndex(Idx)); 377 else 378 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 379 TII.get(ARM::LDRcp)) 380 .addReg(DestReg).addConstantPoolIndex(Idx) 381 .addReg(0).addImm(0)); 382 383 return DestReg; 384} 385 386unsigned ARMFastISel::TargetMaterializeConstant(const Constant *C) { 387 EVT VT = TLI.getValueType(C->getType(), true); 388 389 // Only handle simple types. 390 if (!VT.isSimple()) return 0; 391 392 if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) 393 return ARMMaterializeFP(CFP, VT); 394 return ARMMaterializeInt(C); 395} 396 397bool ARMFastISel::isTypeLegal(const Type *Ty, EVT &VT) { 398 VT = TLI.getValueType(Ty, true); 399 400 // Only handle simple types. 401 if (VT == MVT::Other || !VT.isSimple()) return false; 402 403 // Handle all legal types, i.e. a register that will directly hold this 404 // value. 405 return TLI.isTypeLegal(VT); 406} 407 408bool ARMFastISel::isLoadTypeLegal(const Type *Ty, EVT &VT) { 409 if (isTypeLegal(Ty, VT)) return true; 410 411 // If this is a type than can be sign or zero-extended to a basic operation 412 // go ahead and accept it now. 413 if (VT == MVT::i8 || VT == MVT::i16) 414 return true; 415 416 return false; 417} 418 419// Computes the Reg+Offset to get to an object. 420bool ARMFastISel::ARMComputeRegOffset(const Value *Obj, unsigned &Reg, 421 int &Offset) { 422 // Some boilerplate from the X86 FastISel. 423 const User *U = NULL; 424 unsigned Opcode = Instruction::UserOp1; 425 if (const Instruction *I = dyn_cast<Instruction>(Obj)) { 426 // Don't walk into other basic blocks; it's possible we haven't 427 // visited them yet, so the instructions may not yet be assigned 428 // virtual registers. 429 if (FuncInfo.MBBMap[I->getParent()] != FuncInfo.MBB) 430 return false; 431 432 Opcode = I->getOpcode(); 433 U = I; 434 } else if (const ConstantExpr *C = dyn_cast<ConstantExpr>(Obj)) { 435 Opcode = C->getOpcode(); 436 U = C; 437 } 438 439 if (const PointerType *Ty = dyn_cast<PointerType>(Obj->getType())) 440 if (Ty->getAddressSpace() > 255) 441 // Fast instruction selection doesn't support the special 442 // address spaces. 443 return false; 444 445 switch (Opcode) { 446 default: 447 //errs() << "Failing Opcode is: " << *Op1 << "\n"; 448 break; 449 case Instruction::Alloca: { 450 assert(false && "Alloca should have been handled earlier!"); 451 return false; 452 } 453 } 454 455 if (const GlobalValue *GV = dyn_cast<GlobalValue>(Obj)) { 456 //errs() << "Failing GV is: " << GV << "\n"; 457 (void)GV; 458 return false; 459 } 460 461 // Try to get this in a register if nothing else has worked. 462 Reg = getRegForValue(Obj); 463 if (Reg == 0) return false; 464 465 // Since the offset may be too large for the load instruction 466 // get the reg+offset into a register. 467 // TODO: Verify the additions work, otherwise we'll need to add the 468 // offset instead of 0 to the instructions and do all sorts of operand 469 // munging. 470 // TODO: Optimize this somewhat. 471 if (Offset != 0) { 472 ARMCC::CondCodes Pred = ARMCC::AL; 473 unsigned PredReg = 0; 474 475 if (!isThumb) 476 emitARMRegPlusImmediate(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 477 Reg, Reg, Offset, Pred, PredReg, 478 static_cast<const ARMBaseInstrInfo&>(TII)); 479 else { 480 assert(AFI->isThumb2Function()); 481 emitT2RegPlusImmediate(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 482 Reg, Reg, Offset, Pred, PredReg, 483 static_cast<const ARMBaseInstrInfo&>(TII)); 484 } 485 } 486 487 return true; 488} 489 490bool ARMFastISel::ARMLoadAlloca(const Instruction *I, EVT VT) { 491 Value *Op0 = I->getOperand(0); 492 493 // Verify it's an alloca. 494 if (const AllocaInst *AI = dyn_cast<AllocaInst>(Op0)) { 495 DenseMap<const AllocaInst*, int>::iterator SI = 496 FuncInfo.StaticAllocaMap.find(AI); 497 498 if (SI != FuncInfo.StaticAllocaMap.end()) { 499 TargetRegisterClass* RC = TLI.getRegClassFor(VT); 500 unsigned ResultReg = createResultReg(RC); 501 TII.loadRegFromStackSlot(*FuncInfo.MBB, *FuncInfo.InsertPt, 502 ResultReg, SI->second, RC, 503 TM.getRegisterInfo()); 504 UpdateValueMap(I, ResultReg); 505 return true; 506 } 507 } 508 return false; 509} 510 511bool ARMFastISel::ARMEmitLoad(EVT VT, unsigned &ResultReg, 512 unsigned Reg, int Offset) { 513 514 assert(VT.isSimple() && "Non-simple types are invalid here!"); 515 unsigned Opc; 516 517 switch (VT.getSimpleVT().SimpleTy) { 518 default: 519 assert(false && "Trying to emit for an unhandled type!"); 520 return false; 521 case MVT::i16: 522 Opc = isThumb ? ARM::tLDRH : ARM::LDRH; 523 VT = MVT::i32; 524 break; 525 case MVT::i8: 526 Opc = isThumb ? ARM::tLDRB : ARM::LDRB; 527 VT = MVT::i32; 528 break; 529 case MVT::i32: 530 Opc = isThumb ? ARM::tLDR : ARM::LDR; 531 break; 532 } 533 534 ResultReg = createResultReg(TLI.getRegClassFor(VT)); 535 536 // TODO: Fix the Addressing modes so that these can share some code. 537 // Since this is a Thumb1 load this will work in Thumb1 or 2 mode. 538 if (isThumb) 539 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 540 TII.get(Opc), ResultReg) 541 .addReg(Reg).addImm(Offset).addReg(0)); 542 else 543 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 544 TII.get(Opc), ResultReg) 545 .addReg(Reg).addReg(0).addImm(Offset)); 546 547 return true; 548} 549 550bool ARMFastISel::ARMStoreAlloca(const Instruction *I, unsigned SrcReg, EVT VT){ 551 Value *Op1 = I->getOperand(1); 552 553 // Verify it's an alloca. 554 if (const AllocaInst *AI = dyn_cast<AllocaInst>(Op1)) { 555 DenseMap<const AllocaInst*, int>::iterator SI = 556 FuncInfo.StaticAllocaMap.find(AI); 557 558 if (SI != FuncInfo.StaticAllocaMap.end()) { 559 TargetRegisterClass* RC = TLI.getRegClassFor(VT); 560 assert(SrcReg != 0 && "Nothing to store!"); 561 TII.storeRegToStackSlot(*FuncInfo.MBB, *FuncInfo.InsertPt, 562 SrcReg, true /*isKill*/, SI->second, RC, 563 TM.getRegisterInfo()); 564 return true; 565 } 566 } 567 return false; 568} 569 570bool ARMFastISel::ARMEmitStore(EVT VT, unsigned SrcReg, 571 unsigned DstReg, int Offset) { 572 unsigned StrOpc; 573 switch (VT.getSimpleVT().SimpleTy) { 574 default: return false; 575 case MVT::i1: 576 case MVT::i8: StrOpc = isThumb ? ARM::tSTRB : ARM::STRB; break; 577 case MVT::i16: StrOpc = isThumb ? ARM::tSTRH : ARM::STRH; break; 578 case MVT::i32: StrOpc = isThumb ? ARM::tSTR : ARM::STR; break; 579 case MVT::f32: 580 if (!Subtarget->hasVFP2()) return false; 581 StrOpc = ARM::VSTRS; 582 break; 583 case MVT::f64: 584 if (!Subtarget->hasVFP2()) return false; 585 StrOpc = ARM::VSTRD; 586 break; 587 } 588 589 if (isThumb) 590 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 591 TII.get(StrOpc), SrcReg) 592 .addReg(DstReg).addImm(Offset).addReg(0)); 593 else 594 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 595 TII.get(StrOpc), SrcReg) 596 .addReg(DstReg).addReg(0).addImm(Offset)); 597 598 return true; 599} 600 601bool ARMFastISel::ARMSelectStore(const Instruction *I) { 602 Value *Op0 = I->getOperand(0); 603 unsigned SrcReg = 0; 604 605 // Yay type legalization 606 EVT VT; 607 if (!isLoadTypeLegal(I->getOperand(0)->getType(), VT)) 608 return false; 609 610 // Get the value to be stored into a register. 611 SrcReg = getRegForValue(Op0); 612 if (SrcReg == 0) 613 return false; 614 615 // If we're an alloca we know we have a frame index and can emit the store 616 // quickly. 617 if (ARMStoreAlloca(I, SrcReg, VT)) 618 return true; 619 620 // Our register and offset with innocuous defaults. 621 unsigned Reg = 0; 622 int Offset = 0; 623 624 // See if we can handle this as Reg + Offset 625 if (!ARMComputeRegOffset(I->getOperand(1), Reg, Offset)) 626 return false; 627 628 if (!ARMEmitStore(VT, SrcReg, Reg, Offset /* 0 */)) return false; 629 630 return false; 631 632} 633 634bool ARMFastISel::ARMSelectLoad(const Instruction *I) { 635 // Verify we have a legal type before going any further. 636 EVT VT; 637 if (!isLoadTypeLegal(I->getType(), VT)) 638 return false; 639 640 // If we're an alloca we know we have a frame index and can emit the load 641 // directly in short order. 642 if (ARMLoadAlloca(I, VT)) 643 return true; 644 645 // Our register and offset with innocuous defaults. 646 unsigned Reg = 0; 647 int Offset = 0; 648 649 // See if we can handle this as Reg + Offset 650 if (!ARMComputeRegOffset(I->getOperand(0), Reg, Offset)) 651 return false; 652 653 unsigned ResultReg; 654 if (!ARMEmitLoad(VT, ResultReg, Reg, Offset /* 0 */)) return false; 655 656 UpdateValueMap(I, ResultReg); 657 return true; 658} 659 660bool ARMFastISel::ARMSelectBranch(const Instruction *I) { 661 const BranchInst *BI = cast<BranchInst>(I); 662 MachineBasicBlock *TBB = FuncInfo.MBBMap[BI->getSuccessor(0)]; 663 MachineBasicBlock *FBB = FuncInfo.MBBMap[BI->getSuccessor(1)]; 664 665 // Simple branch support. 666 unsigned CondReg = getRegForValue(BI->getCondition()); 667 if (CondReg == 0) return false; 668 669 unsigned CmpOpc = isThumb ? ARM::t2CMPrr : ARM::CMPrr; 670 unsigned BrOpc = isThumb ? ARM::t2Bcc : ARM::Bcc; 671 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc)) 672 .addReg(CondReg).addReg(CondReg)); 673 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(BrOpc)) 674 .addMBB(TBB).addImm(ARMCC::NE).addReg(ARM::CPSR); 675 FastEmitBranch(FBB, DL); 676 FuncInfo.MBB->addSuccessor(TBB); 677 return true; 678} 679 680bool ARMFastISel::ARMSelectCmp(const Instruction *I) { 681 const CmpInst *CI = cast<CmpInst>(I); 682 683 EVT VT; 684 const Type *Ty = CI->getOperand(0)->getType(); 685 if (!isTypeLegal(Ty, VT)) 686 return false; 687 688 bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy()); 689 if (isFloat && !Subtarget->hasVFP2()) 690 return false; 691 692 unsigned CmpOpc; 693 switch (VT.getSimpleVT().SimpleTy) { 694 default: return false; 695 // TODO: Verify compares. 696 case MVT::f32: 697 CmpOpc = ARM::VCMPES; 698 break; 699 case MVT::f64: 700 CmpOpc = ARM::VCMPED; 701 break; 702 case MVT::i32: 703 CmpOpc = isThumb ? ARM::t2CMPrr : ARM::CMPrr; 704 break; 705 } 706 707 unsigned Arg1 = getRegForValue(CI->getOperand(0)); 708 if (Arg1 == 0) return false; 709 710 unsigned Arg2 = getRegForValue(CI->getOperand(1)); 711 if (Arg2 == 0) return false; 712 713 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(CmpOpc)) 714 .addReg(Arg1).addReg(Arg2)); 715 716 // For floating point we need to move the result to a register we can 717 // actually do something with. 718 if (isFloat) 719 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 720 TII.get(ARM::FMSTAT))); 721 return true; 722} 723 724bool ARMFastISel::ARMSelectFPExt(const Instruction *I) { 725 // Make sure we have VFP and that we're extending float to double. 726 if (!Subtarget->hasVFP2()) return false; 727 728 Value *V = I->getOperand(0); 729 if (!I->getType()->isDoubleTy() || 730 !V->getType()->isFloatTy()) return false; 731 732 unsigned Op = getRegForValue(V); 733 if (Op == 0) return false; 734 735 unsigned Result = createResultReg(ARM::DPRRegisterClass); 736 737 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 738 TII.get(ARM::VCVTDS), Result) 739 .addReg(Op)); 740 UpdateValueMap(I, Result); 741 return true; 742} 743 744bool ARMFastISel::ARMSelectBinaryOp(const Instruction *I, unsigned ISDOpcode) { 745 EVT VT = TLI.getValueType(I->getType(), true); 746 747 // We can get here in the case when we want to use NEON for our fp 748 // operations, but can't figure out how to. Just use the vfp instructions 749 // if we have them. 750 // FIXME: It'd be nice to use NEON instructions. 751 const Type *Ty = I->getType(); 752 bool isFloat = (Ty->isDoubleTy() || Ty->isFloatTy()); 753 if (isFloat && !Subtarget->hasVFP2()) 754 return false; 755 756 unsigned Op1 = getRegForValue(I->getOperand(0)); 757 if (Op1 == 0) return false; 758 759 unsigned Op2 = getRegForValue(I->getOperand(1)); 760 if (Op2 == 0) return false; 761 762 unsigned Opc; 763 bool is64bit = VT.getSimpleVT().SimpleTy == MVT::f64 || 764 VT.getSimpleVT().SimpleTy == MVT::i64; 765 switch (ISDOpcode) { 766 default: return false; 767 case ISD::FADD: 768 Opc = is64bit ? ARM::VADDD : ARM::VADDS; 769 break; 770 case ISD::FSUB: 771 Opc = is64bit ? ARM::VSUBD : ARM::VSUBS; 772 break; 773 case ISD::FMUL: 774 Opc = is64bit ? ARM::VMULD : ARM::VMULS; 775 break; 776 } 777 unsigned ResultReg = createResultReg(TLI.getRegClassFor(VT)); 778 AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, 779 TII.get(Opc), ResultReg) 780 .addReg(Op1).addReg(Op2)); 781 return true; 782} 783 784// TODO: SoftFP support. 785bool ARMFastISel::TargetSelectInstruction(const Instruction *I) { 786 // No Thumb-1 for now. 787 if (isThumb && !AFI->isThumb2Function()) return false; 788 789 switch (I->getOpcode()) { 790 case Instruction::Load: 791 return ARMSelectLoad(I); 792 case Instruction::Store: 793 return ARMSelectStore(I); 794 case Instruction::Br: 795 return ARMSelectBranch(I); 796 case Instruction::ICmp: 797 case Instruction::FCmp: 798 return ARMSelectCmp(I); 799 case Instruction::FPExt: 800 return ARMSelectFPExt(I); 801 case Instruction::FAdd: 802 return ARMSelectBinaryOp(I, ISD::FADD); 803 case Instruction::FSub: 804 return ARMSelectBinaryOp(I, ISD::FSUB); 805 case Instruction::FMul: 806 return ARMSelectBinaryOp(I, ISD::FMUL); 807 default: break; 808 } 809 return false; 810} 811 812namespace llvm { 813 llvm::FastISel *ARM::createFastISel(FunctionLoweringInfo &funcInfo) { 814 if (EnableARMFastISel) return new ARMFastISel(funcInfo); 815 return 0; 816 } 817} 818