1 //===- ARMInstructionSelector.cpp ----------------------------*- C++ -*-==// 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 /// \file 10 /// This file implements the targeting of the InstructionSelector class for ARM. 11 /// \todo This should be generated by TableGen. 12 //===----------------------------------------------------------------------===// 13 14 #include "ARMInstructionSelector.h" 15 #include "ARMRegisterBankInfo.h" 16 #include "ARMSubtarget.h" 17 #include "ARMTargetMachine.h" 18 #include "llvm/CodeGen/MachineRegisterInfo.h" 19 #include "llvm/Support/Debug.h" 20 21 #define DEBUG_TYPE "arm-isel" 22 23 using namespace llvm; 24 25 #ifndef LLVM_BUILD_GLOBAL_ISEL 26 #error "You shouldn't build this" 27 #endif 28 29 ARMInstructionSelector::ARMInstructionSelector(const ARMSubtarget &STI, 30 const ARMRegisterBankInfo &RBI) 31 : InstructionSelector(), TII(*STI.getInstrInfo()), 32 TRI(*STI.getRegisterInfo()), RBI(RBI) {} 33 34 static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, 35 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, 36 const RegisterBankInfo &RBI) { 37 unsigned DstReg = I.getOperand(0).getReg(); 38 if (TargetRegisterInfo::isPhysicalRegister(DstReg)) 39 return true; 40 41 const RegisterBank *RegBank = RBI.getRegBank(DstReg, MRI, TRI); 42 (void)RegBank; 43 assert(RegBank && "Can't get reg bank for virtual register"); 44 45 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits(); 46 (void)DstSize; 47 unsigned SrcReg = I.getOperand(1).getReg(); 48 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI); 49 (void)SrcSize; 50 // We use copies for trunc, so it's ok for the size of the destination to be 51 // smaller (the higher bits will just be undefined). 52 assert(DstSize <= SrcSize && "Copy with different width?!"); 53 54 assert((RegBank->getID() == ARM::GPRRegBankID || 55 RegBank->getID() == ARM::FPRRegBankID) && 56 "Unsupported reg bank"); 57 58 const TargetRegisterClass *RC = &ARM::GPRRegClass; 59 60 if (RegBank->getID() == ARM::FPRRegBankID) { 61 if (DstSize == 32) 62 RC = &ARM::SPRRegClass; 63 else if (DstSize == 64) 64 RC = &ARM::DPRRegClass; 65 else 66 llvm_unreachable("Unsupported destination size"); 67 } 68 69 // No need to constrain SrcReg. It will get constrained when 70 // we hit another of its uses or its defs. 71 // Copies do not have constraints. 72 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) { 73 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) 74 << " operand\n"); 75 return false; 76 } 77 return true; 78 } 79 80 static bool selectFAdd(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, 81 MachineRegisterInfo &MRI) { 82 assert(TII.getSubtarget().hasVFP2() && "Can't select fp add without vfp"); 83 84 LLT Ty = MRI.getType(MIB->getOperand(0).getReg()); 85 unsigned ValSize = Ty.getSizeInBits(); 86 87 if (ValSize == 32) { 88 if (TII.getSubtarget().useNEONForSinglePrecisionFP()) 89 return false; 90 MIB->setDesc(TII.get(ARM::VADDS)); 91 } else { 92 assert(ValSize == 64 && "Unsupported size for floating point value"); 93 if (TII.getSubtarget().isFPOnlySP()) 94 return false; 95 MIB->setDesc(TII.get(ARM::VADDD)); 96 } 97 MIB.add(predOps(ARMCC::AL)); 98 99 return true; 100 } 101 102 static bool selectSequence(MachineInstrBuilder &MIB, 103 const ARMBaseInstrInfo &TII, 104 MachineRegisterInfo &MRI, 105 const TargetRegisterInfo &TRI, 106 const RegisterBankInfo &RBI) { 107 assert(TII.getSubtarget().hasVFP2() && "Can't select sequence without VFP"); 108 109 // We only support G_SEQUENCE as a way to stick together two scalar GPRs 110 // into one DPR. 111 unsigned VReg0 = MIB->getOperand(0).getReg(); 112 (void)VReg0; 113 assert(MRI.getType(VReg0).getSizeInBits() == 64 && 114 RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::FPRRegBankID && 115 "Unsupported operand for G_SEQUENCE"); 116 unsigned VReg1 = MIB->getOperand(1).getReg(); 117 (void)VReg1; 118 assert(MRI.getType(VReg1).getSizeInBits() == 32 && 119 RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::GPRRegBankID && 120 "Unsupported operand for G_SEQUENCE"); 121 unsigned VReg2 = MIB->getOperand(3).getReg(); 122 (void)VReg2; 123 assert(MRI.getType(VReg2).getSizeInBits() == 32 && 124 RBI.getRegBank(VReg2, MRI, TRI)->getID() == ARM::GPRRegBankID && 125 "Unsupported operand for G_SEQUENCE"); 126 127 // Remove the operands corresponding to the offsets. 128 MIB->RemoveOperand(4); 129 MIB->RemoveOperand(2); 130 131 MIB->setDesc(TII.get(ARM::VMOVDRR)); 132 MIB.add(predOps(ARMCC::AL)); 133 134 return true; 135 } 136 137 static bool selectExtract(MachineInstrBuilder &MIB, const ARMBaseInstrInfo &TII, 138 MachineRegisterInfo &MRI, 139 const TargetRegisterInfo &TRI, 140 const RegisterBankInfo &RBI) { 141 assert(TII.getSubtarget().hasVFP2() && "Can't select extract without VFP"); 142 143 // We only support G_EXTRACT as a way to break up one DPR into two GPRs. 144 unsigned VReg0 = MIB->getOperand(0).getReg(); 145 (void)VReg0; 146 assert(MRI.getType(VReg0).getSizeInBits() == 32 && 147 RBI.getRegBank(VReg0, MRI, TRI)->getID() == ARM::GPRRegBankID && 148 "Unsupported operand for G_EXTRACT"); 149 unsigned VReg1 = MIB->getOperand(1).getReg(); 150 (void)VReg1; 151 assert(MRI.getType(VReg1).getSizeInBits() == 64 && 152 RBI.getRegBank(VReg1, MRI, TRI)->getID() == ARM::FPRRegBankID && 153 "Unsupported operand for G_EXTRACT"); 154 assert(MIB->getOperand(2).getImm() % 32 == 0 && 155 "Unsupported operand for G_EXTRACT"); 156 157 // Remove the operands corresponding to the offsets. 158 MIB->getOperand(2).setImm(MIB->getOperand(2).getImm() / 32); 159 160 MIB->setDesc(TII.get(ARM::VGETLNi32)); 161 MIB.add(predOps(ARMCC::AL)); 162 163 return true; 164 } 165 166 /// Select the opcode for simple extensions (that translate to a single SXT/UXT 167 /// instruction). Extension operations more complicated than that should not 168 /// invoke this. Returns the original opcode if it doesn't know how to select a 169 /// better one. 170 static unsigned selectSimpleExtOpc(unsigned Opc, unsigned Size) { 171 using namespace TargetOpcode; 172 173 if (Size != 8 && Size != 16) 174 return Opc; 175 176 if (Opc == G_SEXT) 177 return Size == 8 ? ARM::SXTB : ARM::SXTH; 178 179 if (Opc == G_ZEXT) 180 return Size == 8 ? ARM::UXTB : ARM::UXTH; 181 182 return Opc; 183 } 184 185 /// Select the opcode for simple loads and stores. For types smaller than 32 186 /// bits, the value will be zero extended. Returns the original opcode if it 187 /// doesn't know how to select a better one. 188 static unsigned selectLoadStoreOpCode(unsigned Opc, unsigned RegBank, 189 unsigned Size) { 190 bool isStore = Opc == TargetOpcode::G_STORE; 191 192 if (RegBank == ARM::GPRRegBankID) { 193 switch (Size) { 194 case 1: 195 case 8: 196 return isStore ? ARM::STRBi12 : ARM::LDRBi12; 197 case 16: 198 return isStore ? ARM::STRH : ARM::LDRH; 199 case 32: 200 return isStore ? ARM::STRi12 : ARM::LDRi12; 201 default: 202 return Opc; 203 } 204 } 205 206 if (RegBank == ARM::FPRRegBankID) { 207 switch (Size) { 208 case 32: 209 return isStore ? ARM::VSTRS : ARM::VLDRS; 210 case 64: 211 return isStore ? ARM::VSTRD : ARM::VLDRD; 212 default: 213 return Opc; 214 } 215 } 216 217 return Opc; 218 } 219 220 bool ARMInstructionSelector::select(MachineInstr &I) const { 221 assert(I.getParent() && "Instruction should be in a basic block!"); 222 assert(I.getParent()->getParent() && "Instruction should be in a function!"); 223 224 auto &MBB = *I.getParent(); 225 auto &MF = *MBB.getParent(); 226 auto &MRI = MF.getRegInfo(); 227 228 if (!isPreISelGenericOpcode(I.getOpcode())) { 229 if (I.isCopy()) 230 return selectCopy(I, TII, MRI, TRI, RBI); 231 232 return true; 233 } 234 235 MachineInstrBuilder MIB{MF, I}; 236 bool isSExt = false; 237 238 using namespace TargetOpcode; 239 switch (I.getOpcode()) { 240 case G_SEXT: 241 isSExt = true; 242 LLVM_FALLTHROUGH; 243 case G_ZEXT: { 244 LLT DstTy = MRI.getType(I.getOperand(0).getReg()); 245 // FIXME: Smaller destination sizes coming soon! 246 if (DstTy.getSizeInBits() != 32) { 247 DEBUG(dbgs() << "Unsupported destination size for extension"); 248 return false; 249 } 250 251 LLT SrcTy = MRI.getType(I.getOperand(1).getReg()); 252 unsigned SrcSize = SrcTy.getSizeInBits(); 253 switch (SrcSize) { 254 case 1: { 255 // ZExt boils down to & 0x1; for SExt we also subtract that from 0 256 I.setDesc(TII.get(ARM::ANDri)); 257 MIB.addImm(1).add(predOps(ARMCC::AL)).add(condCodeOp()); 258 259 if (isSExt) { 260 unsigned SExtResult = I.getOperand(0).getReg(); 261 262 // Use a new virtual register for the result of the AND 263 unsigned AndResult = MRI.createVirtualRegister(&ARM::GPRRegClass); 264 I.getOperand(0).setReg(AndResult); 265 266 auto InsertBefore = std::next(I.getIterator()); 267 auto SubI = 268 BuildMI(MBB, InsertBefore, I.getDebugLoc(), TII.get(ARM::RSBri)) 269 .addDef(SExtResult) 270 .addUse(AndResult) 271 .addImm(0) 272 .add(predOps(ARMCC::AL)) 273 .add(condCodeOp()); 274 if (!constrainSelectedInstRegOperands(*SubI, TII, TRI, RBI)) 275 return false; 276 } 277 break; 278 } 279 case 8: 280 case 16: { 281 unsigned NewOpc = selectSimpleExtOpc(I.getOpcode(), SrcSize); 282 if (NewOpc == I.getOpcode()) 283 return false; 284 I.setDesc(TII.get(NewOpc)); 285 MIB.addImm(0).add(predOps(ARMCC::AL)); 286 break; 287 } 288 default: 289 DEBUG(dbgs() << "Unsupported source size for extension"); 290 return false; 291 } 292 break; 293 } 294 case G_TRUNC: { 295 // The high bits are undefined, so there's nothing special to do, just 296 // treat it as a copy. 297 auto SrcReg = I.getOperand(1).getReg(); 298 auto DstReg = I.getOperand(0).getReg(); 299 300 const auto &SrcRegBank = *RBI.getRegBank(SrcReg, MRI, TRI); 301 const auto &DstRegBank = *RBI.getRegBank(DstReg, MRI, TRI); 302 303 if (SrcRegBank.getID() != DstRegBank.getID()) { 304 DEBUG(dbgs() << "G_TRUNC operands on different register banks\n"); 305 return false; 306 } 307 308 if (SrcRegBank.getID() != ARM::GPRRegBankID) { 309 DEBUG(dbgs() << "G_TRUNC on non-GPR not supported yet\n"); 310 return false; 311 } 312 313 I.setDesc(TII.get(COPY)); 314 return selectCopy(I, TII, MRI, TRI, RBI); 315 } 316 case G_ADD: 317 case G_GEP: 318 I.setDesc(TII.get(ARM::ADDrr)); 319 MIB.add(predOps(ARMCC::AL)).add(condCodeOp()); 320 break; 321 case G_SUB: 322 I.setDesc(TII.get(ARM::SUBrr)); 323 MIB.add(predOps(ARMCC::AL)).add(condCodeOp()); 324 break; 325 case G_MUL: 326 if (TII.getSubtarget().hasV6Ops()) { 327 I.setDesc(TII.get(ARM::MUL)); 328 } else { 329 assert(TII.getSubtarget().useMulOps() && "Unsupported target"); 330 I.setDesc(TII.get(ARM::MULv5)); 331 MIB->getOperand(0).setIsEarlyClobber(true); 332 } 333 MIB.add(predOps(ARMCC::AL)).add(condCodeOp()); 334 break; 335 case G_FADD: 336 if (!selectFAdd(MIB, TII, MRI)) 337 return false; 338 break; 339 case G_FRAME_INDEX: 340 // Add 0 to the given frame index and hope it will eventually be folded into 341 // the user(s). 342 I.setDesc(TII.get(ARM::ADDri)); 343 MIB.addImm(0).add(predOps(ARMCC::AL)).add(condCodeOp()); 344 break; 345 case G_CONSTANT: { 346 unsigned Reg = I.getOperand(0).getReg(); 347 if (MRI.getType(Reg).getSizeInBits() != 32) 348 return false; 349 350 assert(RBI.getRegBank(Reg, MRI, TRI)->getID() == ARM::GPRRegBankID && 351 "Expected constant to live in a GPR"); 352 I.setDesc(TII.get(ARM::MOVi)); 353 MIB.add(predOps(ARMCC::AL)).add(condCodeOp()); 354 break; 355 } 356 case G_STORE: 357 case G_LOAD: { 358 const auto &MemOp = **I.memoperands_begin(); 359 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) { 360 DEBUG(dbgs() << "Atomic load/store not supported yet\n"); 361 return false; 362 } 363 364 unsigned Reg = I.getOperand(0).getReg(); 365 unsigned RegBank = RBI.getRegBank(Reg, MRI, TRI)->getID(); 366 367 LLT ValTy = MRI.getType(Reg); 368 const auto ValSize = ValTy.getSizeInBits(); 369 370 assert((ValSize != 64 || TII.getSubtarget().hasVFP2()) && 371 "Don't know how to load/store 64-bit value without VFP"); 372 373 const auto NewOpc = selectLoadStoreOpCode(I.getOpcode(), RegBank, ValSize); 374 if (NewOpc == G_LOAD || NewOpc == G_STORE) 375 return false; 376 377 I.setDesc(TII.get(NewOpc)); 378 379 if (NewOpc == ARM::LDRH || NewOpc == ARM::STRH) 380 // LDRH has a funny addressing mode (there's already a FIXME for it). 381 MIB.addReg(0); 382 MIB.addImm(0).add(predOps(ARMCC::AL)); 383 break; 384 } 385 case G_SEQUENCE: { 386 if (!selectSequence(MIB, TII, MRI, TRI, RBI)) 387 return false; 388 break; 389 } 390 case G_EXTRACT: { 391 if (!selectExtract(MIB, TII, MRI, TRI, RBI)) 392 return false; 393 break; 394 } 395 default: 396 return false; 397 } 398 399 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 400 } 401