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