1 //===-- AVRExpandPseudoInsts.cpp - Expand pseudo instructions -------------===// 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 contains a pass that expands pseudo instructions into target 11 // instructions. This pass should be run after register allocation but before 12 // the post-regalloc scheduling pass. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "AVR.h" 17 #include "AVRInstrInfo.h" 18 #include "AVRTargetMachine.h" 19 #include "MCTargetDesc/AVRMCTargetDesc.h" 20 21 #include "llvm/CodeGen/MachineFunctionPass.h" 22 #include "llvm/CodeGen/MachineInstrBuilder.h" 23 #include "llvm/CodeGen/MachineRegisterInfo.h" 24 #include "llvm/CodeGen/RegisterScavenging.h" 25 #include "llvm/Target/TargetRegisterInfo.h" 26 27 using namespace llvm; 28 29 #define AVR_EXPAND_PSEUDO_NAME "AVR pseudo instruction expansion pass" 30 31 namespace { 32 33 /// Expands "placeholder" instructions marked as pseudo into 34 /// actual AVR instructions. 35 class AVRExpandPseudo : public MachineFunctionPass { 36 public: 37 static char ID; 38 39 AVRExpandPseudo() : MachineFunctionPass(ID) { 40 initializeAVRExpandPseudoPass(*PassRegistry::getPassRegistry()); 41 } 42 43 bool runOnMachineFunction(MachineFunction &MF) override; 44 45 StringRef getPassName() const override { return AVR_EXPAND_PSEUDO_NAME; } 46 47 private: 48 typedef MachineBasicBlock Block; 49 typedef Block::iterator BlockIt; 50 51 const AVRRegisterInfo *TRI; 52 const TargetInstrInfo *TII; 53 54 /// The register to be used for temporary storage. 55 const unsigned SCRATCH_REGISTER = AVR::R0; 56 /// The IO address of the status register. 57 const unsigned SREG_ADDR = 0x3f; 58 59 bool expandMBB(Block &MBB); 60 bool expandMI(Block &MBB, BlockIt MBBI); 61 template <unsigned OP> bool expand(Block &MBB, BlockIt MBBI); 62 63 MachineInstrBuilder buildMI(Block &MBB, BlockIt MBBI, unsigned Opcode) { 64 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opcode)); 65 } 66 67 MachineInstrBuilder buildMI(Block &MBB, BlockIt MBBI, unsigned Opcode, 68 unsigned DstReg) { 69 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opcode), DstReg); 70 } 71 72 MachineRegisterInfo &getRegInfo(Block &MBB) { return MBB.getParent()->getRegInfo(); } 73 74 bool expandArith(unsigned OpLo, unsigned OpHi, Block &MBB, BlockIt MBBI); 75 bool expandLogic(unsigned Op, Block &MBB, BlockIt MBBI); 76 bool expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI); 77 78 template<typename Func> 79 bool expandAtomic(Block &MBB, BlockIt MBBI, Func f); 80 81 template<typename Func> 82 bool expandAtomicBinaryOp(unsigned Opcode, Block &MBB, BlockIt MBBI, Func f); 83 84 bool expandAtomicBinaryOp(unsigned Opcode, Block &MBB, BlockIt MBBI); 85 86 bool expandAtomicArithmeticOp(unsigned MemOpcode, 87 unsigned ArithOpcode, 88 Block &MBB, 89 BlockIt MBBI); 90 }; 91 92 char AVRExpandPseudo::ID = 0; 93 94 bool AVRExpandPseudo::expandMBB(MachineBasicBlock &MBB) { 95 bool Modified = false; 96 97 BlockIt MBBI = MBB.begin(), E = MBB.end(); 98 while (MBBI != E) { 99 BlockIt NMBBI = std::next(MBBI); 100 Modified |= expandMI(MBB, MBBI); 101 MBBI = NMBBI; 102 } 103 104 return Modified; 105 } 106 107 bool AVRExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 108 bool Modified = false; 109 110 const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>(); 111 TRI = STI.getRegisterInfo(); 112 TII = STI.getInstrInfo(); 113 114 // We need to track liveness in order to use register scavenging. 115 MF.getProperties().set(MachineFunctionProperties::Property::TracksLiveness); 116 117 for (Block &MBB : MF) { 118 bool ContinueExpanding = true; 119 unsigned ExpandCount = 0; 120 121 // Continue expanding the block until all pseudos are expanded. 122 do { 123 assert(ExpandCount < 10 && "pseudo expand limit reached"); 124 125 bool BlockModified = expandMBB(MBB); 126 Modified |= BlockModified; 127 ExpandCount++; 128 129 ContinueExpanding = BlockModified; 130 } while (ContinueExpanding); 131 } 132 133 return Modified; 134 } 135 136 bool AVRExpandPseudo:: 137 expandArith(unsigned OpLo, unsigned OpHi, Block &MBB, BlockIt MBBI) { 138 MachineInstr &MI = *MBBI; 139 unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg; 140 unsigned DstReg = MI.getOperand(0).getReg(); 141 unsigned SrcReg = MI.getOperand(2).getReg(); 142 bool DstIsDead = MI.getOperand(0).isDead(); 143 bool DstIsKill = MI.getOperand(1).isKill(); 144 bool SrcIsKill = MI.getOperand(2).isKill(); 145 bool ImpIsDead = MI.getOperand(3).isDead(); 146 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); 147 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 148 149 buildMI(MBB, MBBI, OpLo) 150 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 151 .addReg(DstLoReg, getKillRegState(DstIsKill)) 152 .addReg(SrcLoReg, getKillRegState(SrcIsKill)); 153 154 auto MIBHI = buildMI(MBB, MBBI, OpHi) 155 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 156 .addReg(DstHiReg, getKillRegState(DstIsKill)) 157 .addReg(SrcHiReg, getKillRegState(SrcIsKill)); 158 159 if (ImpIsDead) 160 MIBHI->getOperand(3).setIsDead(); 161 162 // SREG is always implicitly killed 163 MIBHI->getOperand(4).setIsKill(); 164 165 MI.eraseFromParent(); 166 return true; 167 } 168 169 bool AVRExpandPseudo:: 170 expandLogic(unsigned Op, Block &MBB, BlockIt MBBI) { 171 MachineInstr &MI = *MBBI; 172 unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg; 173 unsigned DstReg = MI.getOperand(0).getReg(); 174 unsigned SrcReg = MI.getOperand(2).getReg(); 175 bool DstIsDead = MI.getOperand(0).isDead(); 176 bool DstIsKill = MI.getOperand(1).isKill(); 177 bool SrcIsKill = MI.getOperand(2).isKill(); 178 bool ImpIsDead = MI.getOperand(3).isDead(); 179 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); 180 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 181 182 auto MIBLO = buildMI(MBB, MBBI, Op) 183 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 184 .addReg(DstLoReg, getKillRegState(DstIsKill)) 185 .addReg(SrcLoReg, getKillRegState(SrcIsKill)); 186 187 // SREG is always implicitly dead 188 MIBLO->getOperand(3).setIsDead(); 189 190 auto MIBHI = buildMI(MBB, MBBI, Op) 191 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 192 .addReg(DstHiReg, getKillRegState(DstIsKill)) 193 .addReg(SrcHiReg, getKillRegState(SrcIsKill)); 194 195 if (ImpIsDead) 196 MIBHI->getOperand(3).setIsDead(); 197 198 MI.eraseFromParent(); 199 return true; 200 } 201 202 bool AVRExpandPseudo:: 203 expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI) { 204 MachineInstr &MI = *MBBI; 205 unsigned DstLoReg, DstHiReg; 206 unsigned DstReg = MI.getOperand(0).getReg(); 207 bool DstIsDead = MI.getOperand(0).isDead(); 208 bool SrcIsKill = MI.getOperand(1).isKill(); 209 bool ImpIsDead = MI.getOperand(3).isDead(); 210 unsigned Imm = MI.getOperand(2).getImm(); 211 unsigned Lo8 = Imm & 0xff; 212 unsigned Hi8 = (Imm >> 8) & 0xff; 213 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 214 215 auto MIBLO = buildMI(MBB, MBBI, Op) 216 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 217 .addReg(DstLoReg, getKillRegState(SrcIsKill)) 218 .addImm(Lo8); 219 220 // SREG is always implicitly dead 221 MIBLO->getOperand(3).setIsDead(); 222 223 auto MIBHI = buildMI(MBB, MBBI, Op) 224 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 225 .addReg(DstHiReg, getKillRegState(SrcIsKill)) 226 .addImm(Hi8); 227 228 if (ImpIsDead) 229 MIBHI->getOperand(3).setIsDead(); 230 231 MI.eraseFromParent(); 232 return true; 233 } 234 235 template <> 236 bool AVRExpandPseudo::expand<AVR::ADDWRdRr>(Block &MBB, BlockIt MBBI) { 237 return expandArith(AVR::ADDRdRr, AVR::ADCRdRr, MBB, MBBI); 238 } 239 240 template <> 241 bool AVRExpandPseudo::expand<AVR::ADCWRdRr>(Block &MBB, BlockIt MBBI) { 242 return expandArith(AVR::ADCRdRr, AVR::ADCRdRr, MBB, MBBI); 243 } 244 245 template <> 246 bool AVRExpandPseudo::expand<AVR::SUBWRdRr>(Block &MBB, BlockIt MBBI) { 247 return expandArith(AVR::SUBRdRr, AVR::SBCRdRr, MBB, MBBI); 248 } 249 250 template <> 251 bool AVRExpandPseudo::expand<AVR::SUBIWRdK>(Block &MBB, BlockIt MBBI) { 252 MachineInstr &MI = *MBBI; 253 unsigned DstLoReg, DstHiReg; 254 unsigned DstReg = MI.getOperand(0).getReg(); 255 bool DstIsDead = MI.getOperand(0).isDead(); 256 bool SrcIsKill = MI.getOperand(1).isKill(); 257 bool ImpIsDead = MI.getOperand(3).isDead(); 258 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 259 260 auto MIBLO = buildMI(MBB, MBBI, AVR::SUBIRdK) 261 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 262 .addReg(DstLoReg, getKillRegState(SrcIsKill)); 263 264 auto MIBHI = buildMI(MBB, MBBI, AVR::SBCIRdK) 265 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 266 .addReg(DstHiReg, getKillRegState(SrcIsKill)); 267 268 switch (MI.getOperand(2).getType()) { 269 case MachineOperand::MO_GlobalAddress: { 270 const GlobalValue *GV = MI.getOperand(2).getGlobal(); 271 int64_t Offs = MI.getOperand(2).getOffset(); 272 unsigned TF = MI.getOperand(2).getTargetFlags(); 273 MIBLO.addGlobalAddress(GV, Offs, TF | AVRII::MO_NEG | AVRII::MO_LO); 274 MIBHI.addGlobalAddress(GV, Offs, TF | AVRII::MO_NEG | AVRII::MO_HI); 275 break; 276 } 277 case MachineOperand::MO_Immediate: { 278 unsigned Imm = MI.getOperand(2).getImm(); 279 MIBLO.addImm(Imm & 0xff); 280 MIBHI.addImm((Imm >> 8) & 0xff); 281 break; 282 } 283 default: 284 llvm_unreachable("Unknown operand type!"); 285 } 286 287 if (ImpIsDead) 288 MIBHI->getOperand(3).setIsDead(); 289 290 // SREG is always implicitly killed 291 MIBHI->getOperand(4).setIsKill(); 292 293 MI.eraseFromParent(); 294 return true; 295 } 296 297 template <> 298 bool AVRExpandPseudo::expand<AVR::SBCWRdRr>(Block &MBB, BlockIt MBBI) { 299 return expandArith(AVR::SBCRdRr, AVR::SBCRdRr, MBB, MBBI); 300 } 301 302 template <> 303 bool AVRExpandPseudo::expand<AVR::SBCIWRdK>(Block &MBB, BlockIt MBBI) { 304 MachineInstr &MI = *MBBI; 305 unsigned OpLo, OpHi, DstLoReg, DstHiReg; 306 unsigned DstReg = MI.getOperand(0).getReg(); 307 bool DstIsDead = MI.getOperand(0).isDead(); 308 bool SrcIsKill = MI.getOperand(1).isKill(); 309 bool ImpIsDead = MI.getOperand(3).isDead(); 310 unsigned Imm = MI.getOperand(2).getImm(); 311 unsigned Lo8 = Imm & 0xff; 312 unsigned Hi8 = (Imm >> 8) & 0xff; 313 OpLo = AVR::SBCIRdK; 314 OpHi = AVR::SBCIRdK; 315 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 316 317 auto MIBLO = buildMI(MBB, MBBI, OpLo) 318 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 319 .addReg(DstLoReg, getKillRegState(SrcIsKill)) 320 .addImm(Lo8); 321 322 // SREG is always implicitly killed 323 MIBLO->getOperand(4).setIsKill(); 324 325 auto MIBHI = buildMI(MBB, MBBI, OpHi) 326 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 327 .addReg(DstHiReg, getKillRegState(SrcIsKill)) 328 .addImm(Hi8); 329 330 if (ImpIsDead) 331 MIBHI->getOperand(3).setIsDead(); 332 333 // SREG is always implicitly killed 334 MIBHI->getOperand(4).setIsKill(); 335 336 MI.eraseFromParent(); 337 return true; 338 } 339 340 template <> 341 bool AVRExpandPseudo::expand<AVR::ANDWRdRr>(Block &MBB, BlockIt MBBI) { 342 return expandLogic(AVR::ANDRdRr, MBB, MBBI); 343 } 344 345 template <> 346 bool AVRExpandPseudo::expand<AVR::ANDIWRdK>(Block &MBB, BlockIt MBBI) { 347 return expandLogicImm(AVR::ANDIRdK, MBB, MBBI); 348 } 349 350 template <> 351 bool AVRExpandPseudo::expand<AVR::ORWRdRr>(Block &MBB, BlockIt MBBI) { 352 return expandLogic(AVR::ORRdRr, MBB, MBBI); 353 } 354 355 template <> 356 bool AVRExpandPseudo::expand<AVR::ORIWRdK>(Block &MBB, BlockIt MBBI) { 357 return expandLogicImm(AVR::ORIRdK, MBB, MBBI); 358 } 359 360 template <> 361 bool AVRExpandPseudo::expand<AVR::EORWRdRr>(Block &MBB, BlockIt MBBI) { 362 return expandLogic(AVR::EORRdRr, MBB, MBBI); 363 } 364 365 template <> 366 bool AVRExpandPseudo::expand<AVR::COMWRd>(Block &MBB, BlockIt MBBI) { 367 MachineInstr &MI = *MBBI; 368 unsigned OpLo, OpHi, DstLoReg, DstHiReg; 369 unsigned DstReg = MI.getOperand(0).getReg(); 370 bool DstIsDead = MI.getOperand(0).isDead(); 371 bool DstIsKill = MI.getOperand(1).isKill(); 372 bool ImpIsDead = MI.getOperand(2).isDead(); 373 OpLo = AVR::COMRd; 374 OpHi = AVR::COMRd; 375 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 376 377 auto MIBLO = buildMI(MBB, MBBI, OpLo) 378 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 379 .addReg(DstLoReg, getKillRegState(DstIsKill)); 380 381 // SREG is always implicitly dead 382 MIBLO->getOperand(2).setIsDead(); 383 384 auto MIBHI = buildMI(MBB, MBBI, OpHi) 385 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 386 .addReg(DstHiReg, getKillRegState(DstIsKill)); 387 388 if (ImpIsDead) 389 MIBHI->getOperand(2).setIsDead(); 390 391 MI.eraseFromParent(); 392 return true; 393 } 394 395 template <> 396 bool AVRExpandPseudo::expand<AVR::CPWRdRr>(Block &MBB, BlockIt MBBI) { 397 MachineInstr &MI = *MBBI; 398 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg; 399 unsigned DstReg = MI.getOperand(0).getReg(); 400 unsigned SrcReg = MI.getOperand(1).getReg(); 401 bool DstIsKill = MI.getOperand(0).isKill(); 402 bool SrcIsKill = MI.getOperand(1).isKill(); 403 bool ImpIsDead = MI.getOperand(2).isDead(); 404 OpLo = AVR::CPRdRr; 405 OpHi = AVR::CPCRdRr; 406 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); 407 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 408 409 // Low part 410 buildMI(MBB, MBBI, OpLo) 411 .addReg(DstLoReg, getKillRegState(DstIsKill)) 412 .addReg(SrcLoReg, getKillRegState(SrcIsKill)); 413 414 auto MIBHI = buildMI(MBB, MBBI, OpHi) 415 .addReg(DstHiReg, getKillRegState(DstIsKill)) 416 .addReg(SrcHiReg, getKillRegState(SrcIsKill)); 417 418 if (ImpIsDead) 419 MIBHI->getOperand(2).setIsDead(); 420 421 // SREG is always implicitly killed 422 MIBHI->getOperand(3).setIsKill(); 423 424 MI.eraseFromParent(); 425 return true; 426 } 427 428 template <> 429 bool AVRExpandPseudo::expand<AVR::CPCWRdRr>(Block &MBB, BlockIt MBBI) { 430 MachineInstr &MI = *MBBI; 431 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg; 432 unsigned DstReg = MI.getOperand(0).getReg(); 433 unsigned SrcReg = MI.getOperand(1).getReg(); 434 bool DstIsKill = MI.getOperand(0).isKill(); 435 bool SrcIsKill = MI.getOperand(1).isKill(); 436 bool ImpIsDead = MI.getOperand(2).isDead(); 437 OpLo = AVR::CPCRdRr; 438 OpHi = AVR::CPCRdRr; 439 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); 440 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 441 442 auto MIBLO = buildMI(MBB, MBBI, OpLo) 443 .addReg(DstLoReg, getKillRegState(DstIsKill)) 444 .addReg(SrcLoReg, getKillRegState(SrcIsKill)); 445 446 // SREG is always implicitly killed 447 MIBLO->getOperand(3).setIsKill(); 448 449 auto MIBHI = buildMI(MBB, MBBI, OpHi) 450 .addReg(DstHiReg, getKillRegState(DstIsKill)) 451 .addReg(SrcHiReg, getKillRegState(SrcIsKill)); 452 453 if (ImpIsDead) 454 MIBHI->getOperand(2).setIsDead(); 455 456 // SREG is always implicitly killed 457 MIBHI->getOperand(3).setIsKill(); 458 459 MI.eraseFromParent(); 460 return true; 461 } 462 463 template <> 464 bool AVRExpandPseudo::expand<AVR::LDIWRdK>(Block &MBB, BlockIt MBBI) { 465 MachineInstr &MI = *MBBI; 466 unsigned OpLo, OpHi, DstLoReg, DstHiReg; 467 unsigned DstReg = MI.getOperand(0).getReg(); 468 bool DstIsDead = MI.getOperand(0).isDead(); 469 OpLo = AVR::LDIRdK; 470 OpHi = AVR::LDIRdK; 471 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 472 473 auto MIBLO = buildMI(MBB, MBBI, OpLo) 474 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)); 475 476 auto MIBHI = buildMI(MBB, MBBI, OpHi) 477 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)); 478 479 switch (MI.getOperand(1).getType()) { 480 case MachineOperand::MO_GlobalAddress: { 481 const GlobalValue *GV = MI.getOperand(1).getGlobal(); 482 int64_t Offs = MI.getOperand(1).getOffset(); 483 unsigned TF = MI.getOperand(1).getTargetFlags(); 484 485 MIBLO.addGlobalAddress(GV, Offs, TF | AVRII::MO_LO); 486 MIBHI.addGlobalAddress(GV, Offs, TF | AVRII::MO_HI); 487 break; 488 } 489 case MachineOperand::MO_BlockAddress: { 490 const BlockAddress *BA = MI.getOperand(1).getBlockAddress(); 491 unsigned TF = MI.getOperand(1).getTargetFlags(); 492 493 MIBLO.addOperand(MachineOperand::CreateBA(BA, TF | AVRII::MO_LO)); 494 MIBHI.addOperand(MachineOperand::CreateBA(BA, TF | AVRII::MO_HI)); 495 break; 496 } 497 case MachineOperand::MO_Immediate: { 498 unsigned Imm = MI.getOperand(1).getImm(); 499 500 MIBLO.addImm(Imm & 0xff); 501 MIBHI.addImm((Imm >> 8) & 0xff); 502 break; 503 } 504 default: 505 llvm_unreachable("Unknown operand type!"); 506 } 507 508 MI.eraseFromParent(); 509 return true; 510 } 511 512 template <> 513 bool AVRExpandPseudo::expand<AVR::LDSWRdK>(Block &MBB, BlockIt MBBI) { 514 MachineInstr &MI = *MBBI; 515 unsigned OpLo, OpHi, DstLoReg, DstHiReg; 516 unsigned DstReg = MI.getOperand(0).getReg(); 517 bool DstIsDead = MI.getOperand(0).isDead(); 518 OpLo = AVR::LDSRdK; 519 OpHi = AVR::LDSRdK; 520 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 521 522 auto MIBLO = buildMI(MBB, MBBI, OpLo) 523 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)); 524 525 auto MIBHI = buildMI(MBB, MBBI, OpHi) 526 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)); 527 528 switch (MI.getOperand(1).getType()) { 529 case MachineOperand::MO_GlobalAddress: { 530 const GlobalValue *GV = MI.getOperand(1).getGlobal(); 531 int64_t Offs = MI.getOperand(1).getOffset(); 532 unsigned TF = MI.getOperand(1).getTargetFlags(); 533 534 MIBLO.addGlobalAddress(GV, Offs, TF); 535 MIBHI.addGlobalAddress(GV, Offs + 1, TF); 536 break; 537 } 538 case MachineOperand::MO_Immediate: { 539 unsigned Imm = MI.getOperand(1).getImm(); 540 541 MIBLO.addImm(Imm); 542 MIBHI.addImm(Imm + 1); 543 break; 544 } 545 default: 546 llvm_unreachable("Unknown operand type!"); 547 } 548 549 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 550 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 551 552 MI.eraseFromParent(); 553 return true; 554 } 555 556 template <> 557 bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) { 558 MachineInstr &MI = *MBBI; 559 unsigned OpLo, OpHi, DstLoReg, DstHiReg; 560 unsigned DstReg = MI.getOperand(0).getReg(); 561 unsigned SrcReg = MI.getOperand(1).getReg(); 562 bool DstIsDead = MI.getOperand(0).isDead(); 563 bool SrcIsKill = MI.getOperand(1).isKill(); 564 OpLo = AVR::LDRdPtr; 565 OpHi = AVR::LDDRdPtrQ; 566 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 567 568 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same"); 569 570 auto MIBLO = buildMI(MBB, MBBI, OpLo) 571 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 572 .addReg(SrcReg); 573 574 auto MIBHI = buildMI(MBB, MBBI, OpHi) 575 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 576 .addReg(SrcReg, getKillRegState(SrcIsKill)) 577 .addImm(1); 578 579 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 580 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 581 582 MI.eraseFromParent(); 583 return true; 584 } 585 586 template <> 587 bool AVRExpandPseudo::expand<AVR::LDWRdPtrPi>(Block &MBB, BlockIt MBBI) { 588 MachineInstr &MI = *MBBI; 589 unsigned OpLo, OpHi, DstLoReg, DstHiReg; 590 unsigned DstReg = MI.getOperand(0).getReg(); 591 unsigned SrcReg = MI.getOperand(1).getReg(); 592 bool DstIsDead = MI.getOperand(0).isDead(); 593 bool SrcIsDead = MI.getOperand(1).isKill(); 594 OpLo = AVR::LDRdPtrPi; 595 OpHi = AVR::LDRdPtrPi; 596 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 597 598 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same"); 599 600 auto MIBLO = buildMI(MBB, MBBI, OpLo) 601 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 602 .addReg(SrcReg, RegState::Define) 603 .addReg(SrcReg, RegState::Kill); 604 605 auto MIBHI = buildMI(MBB, MBBI, OpHi) 606 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 607 .addReg(SrcReg, RegState::Define | getDeadRegState(SrcIsDead)) 608 .addReg(SrcReg, RegState::Kill); 609 610 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 611 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 612 613 MI.eraseFromParent(); 614 return true; 615 } 616 617 template <> 618 bool AVRExpandPseudo::expand<AVR::LDWRdPtrPd>(Block &MBB, BlockIt MBBI) { 619 MachineInstr &MI = *MBBI; 620 unsigned OpLo, OpHi, DstLoReg, DstHiReg; 621 unsigned DstReg = MI.getOperand(0).getReg(); 622 unsigned SrcReg = MI.getOperand(1).getReg(); 623 bool DstIsDead = MI.getOperand(0).isDead(); 624 bool SrcIsDead = MI.getOperand(1).isKill(); 625 OpLo = AVR::LDRdPtrPd; 626 OpHi = AVR::LDRdPtrPd; 627 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 628 629 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same"); 630 631 auto MIBHI = buildMI(MBB, MBBI, OpHi) 632 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 633 .addReg(SrcReg, RegState::Define) 634 .addReg(SrcReg, RegState::Kill); 635 636 auto MIBLO = buildMI(MBB, MBBI, OpLo) 637 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 638 .addReg(SrcReg, RegState::Define | getDeadRegState(SrcIsDead)) 639 .addReg(SrcReg, RegState::Kill); 640 641 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 642 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 643 644 MI.eraseFromParent(); 645 return true; 646 } 647 648 template <> 649 bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) { 650 MachineInstr &MI = *MBBI; 651 unsigned OpLo, OpHi, DstLoReg, DstHiReg; 652 unsigned DstReg = MI.getOperand(0).getReg(); 653 unsigned SrcReg = MI.getOperand(1).getReg(); 654 unsigned Imm = MI.getOperand(2).getImm(); 655 bool DstIsDead = MI.getOperand(0).isDead(); 656 bool SrcIsKill = MI.getOperand(1).isKill(); 657 OpLo = AVR::LDDRdPtrQ; 658 OpHi = AVR::LDDRdPtrQ; 659 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 660 661 assert(Imm <= 63 && "Offset is out of range"); 662 663 MachineInstr *MIBLO, *MIBHI; 664 665 // HACK: We shouldn't have instances of this instruction 666 // where src==dest because the instruction itself is 667 // marked earlyclobber. We do however get this instruction when 668 // loading from stack slots where the earlyclobber isn't useful. 669 // 670 // In this case, just use a temporary register. 671 if (DstReg == SrcReg) { 672 RegScavenger RS; 673 674 RS.enterBasicBlock(MBB); 675 RS.forward(MBBI); 676 677 BitVector Candidates = 678 TRI->getAllocatableSet 679 (*MBB.getParent(), &AVR::GPR8RegClass); 680 681 // Exclude all the registers being used by the instruction. 682 for (MachineOperand &MO : MI.operands()) { 683 if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() && 684 !TargetRegisterInfo::isVirtualRegister(MO.getReg())) 685 Candidates.reset(MO.getReg()); 686 } 687 688 BitVector Available = RS.getRegsAvailable(&AVR::GPR8RegClass); 689 Available &= Candidates; 690 691 signed TmpReg = Available.find_first(); 692 assert(TmpReg != -1 && "ran out of registers"); 693 694 MIBLO = buildMI(MBB, MBBI, OpLo) 695 .addReg(TmpReg, RegState::Define) 696 .addReg(SrcReg) 697 .addImm(Imm); 698 699 buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstLoReg).addReg(TmpReg); 700 701 MIBHI = buildMI(MBB, MBBI, OpHi) 702 .addReg(TmpReg, RegState::Define) 703 .addReg(SrcReg, getKillRegState(SrcIsKill)) 704 .addImm(Imm + 1); 705 706 buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg); 707 } else { 708 MIBLO = buildMI(MBB, MBBI, OpLo) 709 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 710 .addReg(SrcReg) 711 .addImm(Imm); 712 713 MIBHI = buildMI(MBB, MBBI, OpHi) 714 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 715 .addReg(SrcReg, getKillRegState(SrcIsKill)) 716 .addImm(Imm + 1); 717 } 718 719 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 720 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 721 722 MI.eraseFromParent(); 723 return true; 724 } 725 726 template <> 727 bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(Block &MBB, BlockIt MBBI) { 728 llvm_unreachable("wide LPM is unimplemented"); 729 } 730 731 template <> 732 bool AVRExpandPseudo::expand<AVR::LPMWRdZPi>(Block &MBB, BlockIt MBBI) { 733 llvm_unreachable("wide LPMPi is unimplemented"); 734 } 735 736 template<typename Func> 737 bool AVRExpandPseudo::expandAtomic(Block &MBB, BlockIt MBBI, Func f) { 738 // Remove the pseudo instruction. 739 MachineInstr &MI = *MBBI; 740 741 // Store the SREG. 742 buildMI(MBB, MBBI, AVR::INRdA) 743 .addReg(SCRATCH_REGISTER, RegState::Define) 744 .addImm(SREG_ADDR); 745 746 // Disable exceptions. 747 buildMI(MBB, MBBI, AVR::BCLRs).addImm(7); // CLI 748 749 f(MI); 750 751 // Restore the status reg. 752 buildMI(MBB, MBBI, AVR::OUTARr) 753 .addImm(SREG_ADDR) 754 .addReg(SCRATCH_REGISTER); 755 756 MI.eraseFromParent(); 757 return true; 758 } 759 760 template<typename Func> 761 bool AVRExpandPseudo::expandAtomicBinaryOp(unsigned Opcode, 762 Block &MBB, 763 BlockIt MBBI, 764 Func f) { 765 return expandAtomic(MBB, MBBI, [&](MachineInstr &MI) { 766 auto Op1 = MI.getOperand(0); 767 auto Op2 = MI.getOperand(1); 768 769 MachineInstr &NewInst = *buildMI(MBB, MBBI, Opcode) 770 .addOperand(Op1).addOperand(Op2) 771 .getInstr(); 772 f(NewInst); 773 }); 774 } 775 776 bool AVRExpandPseudo::expandAtomicBinaryOp(unsigned Opcode, 777 Block &MBB, 778 BlockIt MBBI) { 779 return expandAtomicBinaryOp(Opcode, MBB, MBBI, [](MachineInstr &MI) {}); 780 } 781 782 bool AVRExpandPseudo::expandAtomicArithmeticOp(unsigned Width, 783 unsigned ArithOpcode, 784 Block &MBB, 785 BlockIt MBBI) { 786 return expandAtomic(MBB, MBBI, [&](MachineInstr &MI) { 787 auto Op1 = MI.getOperand(0); 788 auto Op2 = MI.getOperand(1); 789 790 unsigned LoadOpcode = (Width == 8) ? AVR::LDRdPtr : AVR::LDWRdPtr; 791 unsigned StoreOpcode = (Width == 8) ? AVR::STPtrRr : AVR::STWPtrRr; 792 793 // Create the load 794 buildMI(MBB, MBBI, LoadOpcode).addOperand(Op1).addOperand(Op2); 795 796 // Create the arithmetic op 797 buildMI(MBB, MBBI, ArithOpcode) 798 .addOperand(Op1).addOperand(Op1) 799 .addOperand(Op2); 800 801 // Create the store 802 buildMI(MBB, MBBI, StoreOpcode).addOperand(Op2).addOperand(Op1); 803 }); 804 } 805 806 template<> 807 bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(Block &MBB, BlockIt MBBI) { 808 return expandAtomicBinaryOp(AVR::LDRdPtr, MBB, MBBI); 809 } 810 811 template<> 812 bool AVRExpandPseudo::expand<AVR::AtomicLoad16>(Block &MBB, BlockIt MBBI) { 813 return expandAtomicBinaryOp(AVR::LDWRdPtr, MBB, MBBI); 814 } 815 816 template<> 817 bool AVRExpandPseudo::expand<AVR::AtomicStore8>(Block &MBB, BlockIt MBBI) { 818 return expandAtomicBinaryOp(AVR::STPtrRr, MBB, MBBI); 819 } 820 821 template<> 822 bool AVRExpandPseudo::expand<AVR::AtomicStore16>(Block &MBB, BlockIt MBBI) { 823 return expandAtomicBinaryOp(AVR::STWPtrRr, MBB, MBBI); 824 } 825 826 template<> 827 bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd8>(Block &MBB, BlockIt MBBI) { 828 return expandAtomicArithmeticOp(8, AVR::ADDRdRr, MBB, MBBI); 829 } 830 831 template<> 832 bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd16>(Block &MBB, BlockIt MBBI) { 833 return expandAtomicArithmeticOp(16, AVR::ADDWRdRr, MBB, MBBI); 834 } 835 836 template<> 837 bool AVRExpandPseudo::expand<AVR::AtomicLoadSub8>(Block &MBB, BlockIt MBBI) { 838 return expandAtomicArithmeticOp(8, AVR::SUBRdRr, MBB, MBBI); 839 } 840 841 template<> 842 bool AVRExpandPseudo::expand<AVR::AtomicLoadSub16>(Block &MBB, BlockIt MBBI) { 843 return expandAtomicArithmeticOp(16, AVR::SUBWRdRr, MBB, MBBI); 844 } 845 846 template<> 847 bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd8>(Block &MBB, BlockIt MBBI) { 848 return expandAtomicArithmeticOp(8, AVR::ANDRdRr, MBB, MBBI); 849 } 850 851 template<> 852 bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd16>(Block &MBB, BlockIt MBBI) { 853 return expandAtomicArithmeticOp(16, AVR::ANDWRdRr, MBB, MBBI); 854 } 855 856 template<> 857 bool AVRExpandPseudo::expand<AVR::AtomicLoadOr8>(Block &MBB, BlockIt MBBI) { 858 return expandAtomicArithmeticOp(8, AVR::ORRdRr, MBB, MBBI); 859 } 860 861 template<> 862 bool AVRExpandPseudo::expand<AVR::AtomicLoadOr16>(Block &MBB, BlockIt MBBI) { 863 return expandAtomicArithmeticOp(16, AVR::ORWRdRr, MBB, MBBI); 864 } 865 866 template<> 867 bool AVRExpandPseudo::expand<AVR::AtomicLoadXor8>(Block &MBB, BlockIt MBBI) { 868 return expandAtomicArithmeticOp(8, AVR::EORRdRr, MBB, MBBI); 869 } 870 871 template<> 872 bool AVRExpandPseudo::expand<AVR::AtomicLoadXor16>(Block &MBB, BlockIt MBBI) { 873 return expandAtomicArithmeticOp(16, AVR::EORWRdRr, MBB, MBBI); 874 } 875 876 template<> 877 bool AVRExpandPseudo::expand<AVR::AtomicFence>(Block &MBB, BlockIt MBBI) { 878 // On AVR, there is only one core and so atomic fences do nothing. 879 MBBI->eraseFromParent(); 880 return true; 881 } 882 883 template <> 884 bool AVRExpandPseudo::expand<AVR::STSWKRr>(Block &MBB, BlockIt MBBI) { 885 MachineInstr &MI = *MBBI; 886 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg; 887 unsigned SrcReg = MI.getOperand(1).getReg(); 888 bool SrcIsKill = MI.getOperand(1).isKill(); 889 OpLo = AVR::STSKRr; 890 OpHi = AVR::STSKRr; 891 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); 892 893 // Write the high byte first in case this address belongs to a special 894 // I/O address with a special temporary register. 895 auto MIBHI = buildMI(MBB, MBBI, OpHi); 896 auto MIBLO = buildMI(MBB, MBBI, OpLo); 897 898 switch (MI.getOperand(0).getType()) { 899 case MachineOperand::MO_GlobalAddress: { 900 const GlobalValue *GV = MI.getOperand(0).getGlobal(); 901 int64_t Offs = MI.getOperand(0).getOffset(); 902 unsigned TF = MI.getOperand(0).getTargetFlags(); 903 904 MIBLO.addGlobalAddress(GV, Offs, TF); 905 MIBHI.addGlobalAddress(GV, Offs + 1, TF); 906 break; 907 } 908 case MachineOperand::MO_Immediate: { 909 unsigned Imm = MI.getOperand(0).getImm(); 910 911 MIBLO.addImm(Imm); 912 MIBHI.addImm(Imm + 1); 913 break; 914 } 915 default: 916 llvm_unreachable("Unknown operand type!"); 917 } 918 919 MIBLO.addReg(SrcLoReg, getKillRegState(SrcIsKill)); 920 MIBHI.addReg(SrcHiReg, getKillRegState(SrcIsKill)); 921 922 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 923 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 924 925 MI.eraseFromParent(); 926 return true; 927 } 928 929 template <> 930 bool AVRExpandPseudo::expand<AVR::STWPtrRr>(Block &MBB, BlockIt MBBI) { 931 MachineInstr &MI = *MBBI; 932 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg; 933 unsigned DstReg = MI.getOperand(0).getReg(); 934 unsigned SrcReg = MI.getOperand(1).getReg(); 935 bool DstIsKill = MI.getOperand(0).isKill(); 936 bool SrcIsKill = MI.getOperand(1).isKill(); 937 OpLo = AVR::STPtrRr; 938 OpHi = AVR::STDPtrQRr; 939 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); 940 941 //:TODO: need to reverse this order like inw and stsw? 942 auto MIBLO = buildMI(MBB, MBBI, OpLo) 943 .addReg(DstReg) 944 .addReg(SrcLoReg, getKillRegState(SrcIsKill)); 945 946 auto MIBHI = buildMI(MBB, MBBI, OpHi) 947 .addReg(DstReg, getKillRegState(DstIsKill)) 948 .addImm(1) 949 .addReg(SrcHiReg, getKillRegState(SrcIsKill)); 950 951 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 952 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 953 954 MI.eraseFromParent(); 955 return true; 956 } 957 958 template <> 959 bool AVRExpandPseudo::expand<AVR::STWPtrPiRr>(Block &MBB, BlockIt MBBI) { 960 MachineInstr &MI = *MBBI; 961 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg; 962 unsigned DstReg = MI.getOperand(0).getReg(); 963 unsigned SrcReg = MI.getOperand(2).getReg(); 964 unsigned Imm = MI.getOperand(3).getImm(); 965 bool DstIsDead = MI.getOperand(0).isDead(); 966 bool SrcIsKill = MI.getOperand(2).isKill(); 967 OpLo = AVR::STPtrPiRr; 968 OpHi = AVR::STPtrPiRr; 969 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); 970 971 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same"); 972 973 auto MIBLO = buildMI(MBB, MBBI, OpLo) 974 .addReg(DstReg, RegState::Define) 975 .addReg(DstReg, RegState::Kill) 976 .addReg(SrcLoReg, getKillRegState(SrcIsKill)) 977 .addImm(Imm); 978 979 auto MIBHI = buildMI(MBB, MBBI, OpHi) 980 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) 981 .addReg(DstReg, RegState::Kill) 982 .addReg(SrcHiReg, getKillRegState(SrcIsKill)) 983 .addImm(Imm); 984 985 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 986 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 987 988 MI.eraseFromParent(); 989 return true; 990 } 991 992 template <> 993 bool AVRExpandPseudo::expand<AVR::STWPtrPdRr>(Block &MBB, BlockIt MBBI) { 994 MachineInstr &MI = *MBBI; 995 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg; 996 unsigned DstReg = MI.getOperand(0).getReg(); 997 unsigned SrcReg = MI.getOperand(2).getReg(); 998 unsigned Imm = MI.getOperand(3).getImm(); 999 bool DstIsDead = MI.getOperand(0).isDead(); 1000 bool SrcIsKill = MI.getOperand(2).isKill(); 1001 OpLo = AVR::STPtrPdRr; 1002 OpHi = AVR::STPtrPdRr; 1003 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); 1004 1005 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same"); 1006 1007 auto MIBHI = buildMI(MBB, MBBI, OpHi) 1008 .addReg(DstReg, RegState::Define) 1009 .addReg(DstReg, RegState::Kill) 1010 .addReg(SrcHiReg, getKillRegState(SrcIsKill)) 1011 .addImm(Imm); 1012 1013 auto MIBLO = buildMI(MBB, MBBI, OpLo) 1014 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) 1015 .addReg(DstReg, RegState::Kill) 1016 .addReg(SrcLoReg, getKillRegState(SrcIsKill)) 1017 .addImm(Imm); 1018 1019 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 1020 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 1021 1022 MI.eraseFromParent(); 1023 return true; 1024 } 1025 1026 template <> 1027 bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(Block &MBB, BlockIt MBBI) { 1028 MachineInstr &MI = *MBBI; 1029 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg; 1030 unsigned DstReg = MI.getOperand(0).getReg(); 1031 unsigned SrcReg = MI.getOperand(2).getReg(); 1032 unsigned Imm = MI.getOperand(1).getImm(); 1033 bool DstIsKill = MI.getOperand(0).isKill(); 1034 bool SrcIsKill = MI.getOperand(2).isKill(); 1035 OpLo = AVR::STDPtrQRr; 1036 OpHi = AVR::STDPtrQRr; 1037 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); 1038 1039 assert(Imm <= 63 && "Offset is out of range"); 1040 1041 auto MIBLO = buildMI(MBB, MBBI, OpLo) 1042 .addReg(DstReg) 1043 .addImm(Imm) 1044 .addReg(SrcLoReg, getKillRegState(SrcIsKill)); 1045 1046 auto MIBHI = buildMI(MBB, MBBI, OpHi) 1047 .addReg(DstReg, getKillRegState(DstIsKill)) 1048 .addImm(Imm + 1) 1049 .addReg(SrcHiReg, getKillRegState(SrcIsKill)); 1050 1051 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 1052 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 1053 1054 MI.eraseFromParent(); 1055 return true; 1056 } 1057 1058 template <> 1059 bool AVRExpandPseudo::expand<AVR::INWRdA>(Block &MBB, BlockIt MBBI) { 1060 MachineInstr &MI = *MBBI; 1061 unsigned OpLo, OpHi, DstLoReg, DstHiReg; 1062 unsigned Imm = MI.getOperand(1).getImm(); 1063 unsigned DstReg = MI.getOperand(0).getReg(); 1064 bool DstIsDead = MI.getOperand(0).isDead(); 1065 OpLo = AVR::INRdA; 1066 OpHi = AVR::INRdA; 1067 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 1068 1069 assert(Imm <= 63 && "Address is out of range"); 1070 1071 auto MIBLO = buildMI(MBB, MBBI, OpLo) 1072 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 1073 .addImm(Imm); 1074 1075 auto MIBHI = buildMI(MBB, MBBI, OpHi) 1076 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 1077 .addImm(Imm + 1); 1078 1079 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 1080 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 1081 1082 MI.eraseFromParent(); 1083 return true; 1084 } 1085 1086 template <> 1087 bool AVRExpandPseudo::expand<AVR::OUTWARr>(Block &MBB, BlockIt MBBI) { 1088 MachineInstr &MI = *MBBI; 1089 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg; 1090 unsigned Imm = MI.getOperand(0).getImm(); 1091 unsigned SrcReg = MI.getOperand(1).getReg(); 1092 bool SrcIsKill = MI.getOperand(1).isKill(); 1093 OpLo = AVR::OUTARr; 1094 OpHi = AVR::OUTARr; 1095 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); 1096 1097 assert(Imm <= 63 && "Address is out of range"); 1098 1099 // 16 bit I/O writes need the high byte first 1100 auto MIBHI = buildMI(MBB, MBBI, OpHi) 1101 .addImm(Imm + 1) 1102 .addReg(SrcHiReg, getKillRegState(SrcIsKill)); 1103 1104 auto MIBLO = buildMI(MBB, MBBI, OpLo) 1105 .addImm(Imm) 1106 .addReg(SrcLoReg, getKillRegState(SrcIsKill)); 1107 1108 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 1109 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 1110 1111 MI.eraseFromParent(); 1112 return true; 1113 } 1114 1115 template <> 1116 bool AVRExpandPseudo::expand<AVR::PUSHWRr>(Block &MBB, BlockIt MBBI) { 1117 MachineInstr &MI = *MBBI; 1118 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg; 1119 unsigned SrcReg = MI.getOperand(0).getReg(); 1120 bool SrcIsKill = MI.getOperand(0).isKill(); 1121 unsigned Flags = MI.getFlags(); 1122 OpLo = AVR::PUSHRr; 1123 OpHi = AVR::PUSHRr; 1124 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); 1125 1126 // Low part 1127 buildMI(MBB, MBBI, OpLo) 1128 .addReg(SrcLoReg, getKillRegState(SrcIsKill)) 1129 .setMIFlags(Flags); 1130 1131 // High part 1132 buildMI(MBB, MBBI, OpHi) 1133 .addReg(SrcHiReg, getKillRegState(SrcIsKill)) 1134 .setMIFlags(Flags); 1135 1136 MI.eraseFromParent(); 1137 return true; 1138 } 1139 1140 template <> 1141 bool AVRExpandPseudo::expand<AVR::POPWRd>(Block &MBB, BlockIt MBBI) { 1142 MachineInstr &MI = *MBBI; 1143 unsigned OpLo, OpHi, DstLoReg, DstHiReg; 1144 unsigned DstReg = MI.getOperand(0).getReg(); 1145 unsigned Flags = MI.getFlags(); 1146 OpLo = AVR::POPRd; 1147 OpHi = AVR::POPRd; 1148 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 1149 1150 buildMI(MBB, MBBI, OpHi, DstHiReg).setMIFlags(Flags); // High 1151 buildMI(MBB, MBBI, OpLo, DstLoReg).setMIFlags(Flags); // Low 1152 1153 MI.eraseFromParent(); 1154 return true; 1155 } 1156 1157 template <> 1158 bool AVRExpandPseudo::expand<AVR::LSLWRd>(Block &MBB, BlockIt MBBI) { 1159 MachineInstr &MI = *MBBI; 1160 unsigned OpLo, OpHi, DstLoReg, DstHiReg; 1161 unsigned DstReg = MI.getOperand(0).getReg(); 1162 bool DstIsDead = MI.getOperand(0).isDead(); 1163 bool DstIsKill = MI.getOperand(1).isKill(); 1164 bool ImpIsDead = MI.getOperand(2).isDead(); 1165 OpLo = AVR::LSLRd; 1166 OpHi = AVR::ROLRd; 1167 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 1168 1169 // Low part 1170 buildMI(MBB, MBBI, OpLo) 1171 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 1172 .addReg(DstLoReg, getKillRegState(DstIsKill)); 1173 1174 auto MIBHI = buildMI(MBB, MBBI, OpHi) 1175 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 1176 .addReg(DstHiReg, getKillRegState(DstIsKill)); 1177 1178 if (ImpIsDead) 1179 MIBHI->getOperand(2).setIsDead(); 1180 1181 // SREG is always implicitly killed 1182 MIBHI->getOperand(3).setIsKill(); 1183 1184 MI.eraseFromParent(); 1185 return true; 1186 } 1187 1188 template <> 1189 bool AVRExpandPseudo::expand<AVR::LSRWRd>(Block &MBB, BlockIt MBBI) { 1190 MachineInstr &MI = *MBBI; 1191 unsigned OpLo, OpHi, DstLoReg, DstHiReg; 1192 unsigned DstReg = MI.getOperand(0).getReg(); 1193 bool DstIsDead = MI.getOperand(0).isDead(); 1194 bool DstIsKill = MI.getOperand(1).isKill(); 1195 bool ImpIsDead = MI.getOperand(2).isDead(); 1196 OpLo = AVR::RORRd; 1197 OpHi = AVR::LSRRd; 1198 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 1199 1200 // High part 1201 buildMI(MBB, MBBI, OpHi) 1202 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 1203 .addReg(DstHiReg, getKillRegState(DstIsKill)); 1204 1205 auto MIBLO = buildMI(MBB, MBBI, OpLo) 1206 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 1207 .addReg(DstLoReg, getKillRegState(DstIsKill)); 1208 1209 if (ImpIsDead) 1210 MIBLO->getOperand(2).setIsDead(); 1211 1212 // SREG is always implicitly killed 1213 MIBLO->getOperand(3).setIsKill(); 1214 1215 MI.eraseFromParent(); 1216 return true; 1217 } 1218 1219 template <> 1220 bool AVRExpandPseudo::expand<AVR::RORWRd>(Block &MBB, BlockIt MBBI) { 1221 llvm_unreachable("RORW unimplemented"); 1222 return false; 1223 } 1224 1225 template <> 1226 bool AVRExpandPseudo::expand<AVR::ROLWRd>(Block &MBB, BlockIt MBBI) { 1227 llvm_unreachable("ROLW unimplemented"); 1228 return false; 1229 } 1230 1231 template <> 1232 bool AVRExpandPseudo::expand<AVR::ASRWRd>(Block &MBB, BlockIt MBBI) { 1233 MachineInstr &MI = *MBBI; 1234 unsigned OpLo, OpHi, DstLoReg, DstHiReg; 1235 unsigned DstReg = MI.getOperand(0).getReg(); 1236 bool DstIsDead = MI.getOperand(0).isDead(); 1237 bool DstIsKill = MI.getOperand(1).isKill(); 1238 bool ImpIsDead = MI.getOperand(2).isDead(); 1239 OpLo = AVR::RORRd; 1240 OpHi = AVR::ASRRd; 1241 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 1242 1243 // High part 1244 buildMI(MBB, MBBI, OpHi) 1245 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 1246 .addReg(DstHiReg, getKillRegState(DstIsKill)); 1247 1248 auto MIBLO = buildMI(MBB, MBBI, OpLo) 1249 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 1250 .addReg(DstLoReg, getKillRegState(DstIsKill)); 1251 1252 if (ImpIsDead) 1253 MIBLO->getOperand(2).setIsDead(); 1254 1255 // SREG is always implicitly killed 1256 MIBLO->getOperand(3).setIsKill(); 1257 1258 MI.eraseFromParent(); 1259 return true; 1260 } 1261 1262 template <> bool AVRExpandPseudo::expand<AVR::SEXT>(Block &MBB, BlockIt MBBI) { 1263 MachineInstr &MI = *MBBI; 1264 unsigned DstLoReg, DstHiReg; 1265 // sext R17:R16, R17 1266 // mov r16, r17 1267 // lsl r17 1268 // sbc r17, r17 1269 // sext R17:R16, R13 1270 // mov r16, r13 1271 // mov r17, r13 1272 // lsl r17 1273 // sbc r17, r17 1274 // sext R17:R16, R16 1275 // mov r17, r16 1276 // lsl r17 1277 // sbc r17, r17 1278 unsigned DstReg = MI.getOperand(0).getReg(); 1279 unsigned SrcReg = MI.getOperand(1).getReg(); 1280 bool DstIsDead = MI.getOperand(0).isDead(); 1281 bool SrcIsKill = MI.getOperand(1).isKill(); 1282 bool ImpIsDead = MI.getOperand(2).isDead(); 1283 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 1284 1285 if (SrcReg != DstLoReg) { 1286 auto MOV = buildMI(MBB, MBBI, AVR::MOVRdRr) 1287 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 1288 .addReg(SrcReg); 1289 1290 if (SrcReg == DstHiReg) { 1291 MOV->getOperand(1).setIsKill(); 1292 } 1293 } 1294 1295 if (SrcReg != DstHiReg) { 1296 buildMI(MBB, MBBI, AVR::MOVRdRr) 1297 .addReg(DstHiReg, RegState::Define) 1298 .addReg(SrcReg, getKillRegState(SrcIsKill)); 1299 } 1300 1301 buildMI(MBB, MBBI, AVR::LSLRd) 1302 .addReg(DstHiReg, RegState::Define) 1303 .addReg(DstHiReg, RegState::Kill); 1304 1305 auto SBC = buildMI(MBB, MBBI, AVR::SBCRdRr) 1306 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 1307 .addReg(DstHiReg, RegState::Kill) 1308 .addReg(DstHiReg, RegState::Kill); 1309 1310 if (ImpIsDead) 1311 SBC->getOperand(3).setIsDead(); 1312 1313 // SREG is always implicitly killed 1314 SBC->getOperand(4).setIsKill(); 1315 1316 MI.eraseFromParent(); 1317 return true; 1318 } 1319 1320 template <> bool AVRExpandPseudo::expand<AVR::ZEXT>(Block &MBB, BlockIt MBBI) { 1321 MachineInstr &MI = *MBBI; 1322 unsigned DstLoReg, DstHiReg; 1323 // zext R25:R24, R20 1324 // mov R24, R20 1325 // eor R25, R25 1326 // zext R25:R24, R24 1327 // eor R25, R25 1328 // zext R25:R24, R25 1329 // mov R24, R25 1330 // eor R25, R25 1331 unsigned DstReg = MI.getOperand(0).getReg(); 1332 unsigned SrcReg = MI.getOperand(1).getReg(); 1333 bool DstIsDead = MI.getOperand(0).isDead(); 1334 bool SrcIsKill = MI.getOperand(1).isKill(); 1335 bool ImpIsDead = MI.getOperand(2).isDead(); 1336 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 1337 1338 if (SrcReg != DstLoReg) { 1339 buildMI(MBB, MBBI, AVR::MOVRdRr) 1340 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 1341 .addReg(SrcReg, getKillRegState(SrcIsKill)); 1342 } 1343 1344 auto EOR = buildMI(MBB, MBBI, AVR::EORRdRr) 1345 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 1346 .addReg(DstHiReg, RegState::Kill) 1347 .addReg(DstHiReg, RegState::Kill); 1348 1349 if (ImpIsDead) 1350 EOR->getOperand(3).setIsDead(); 1351 1352 MI.eraseFromParent(); 1353 return true; 1354 } 1355 1356 template <> 1357 bool AVRExpandPseudo::expand<AVR::SPREAD>(Block &MBB, BlockIt MBBI) { 1358 MachineInstr &MI = *MBBI; 1359 unsigned OpLo, OpHi, DstLoReg, DstHiReg; 1360 unsigned DstReg = MI.getOperand(0).getReg(); 1361 bool DstIsDead = MI.getOperand(0).isDead(); 1362 unsigned Flags = MI.getFlags(); 1363 OpLo = AVR::INRdA; 1364 OpHi = AVR::INRdA; 1365 TRI->splitReg(DstReg, DstLoReg, DstHiReg); 1366 1367 // Low part 1368 buildMI(MBB, MBBI, OpLo) 1369 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead)) 1370 .addImm(0x3d) 1371 .setMIFlags(Flags); 1372 1373 // High part 1374 buildMI(MBB, MBBI, OpHi) 1375 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead)) 1376 .addImm(0x3e) 1377 .setMIFlags(Flags); 1378 1379 MI.eraseFromParent(); 1380 return true; 1381 } 1382 1383 template <> 1384 bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) { 1385 MachineInstr &MI = *MBBI; 1386 unsigned SrcLoReg, SrcHiReg; 1387 unsigned SrcReg = MI.getOperand(1).getReg(); 1388 bool SrcIsKill = MI.getOperand(1).isKill(); 1389 unsigned Flags = MI.getFlags(); 1390 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg); 1391 1392 buildMI(MBB, MBBI, AVR::INRdA) 1393 .addReg(AVR::R0, RegState::Define) 1394 .addImm(SREG_ADDR) 1395 .setMIFlags(Flags); 1396 1397 buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags); 1398 1399 buildMI(MBB, MBBI, AVR::OUTARr) 1400 .addImm(0x3e) 1401 .addReg(SrcHiReg, getKillRegState(SrcIsKill)) 1402 .setMIFlags(Flags); 1403 1404 buildMI(MBB, MBBI, AVR::OUTARr) 1405 .addImm(SREG_ADDR) 1406 .addReg(AVR::R0, RegState::Kill) 1407 .setMIFlags(Flags); 1408 1409 buildMI(MBB, MBBI, AVR::OUTARr) 1410 .addImm(0x3d) 1411 .addReg(SrcLoReg, getKillRegState(SrcIsKill)) 1412 .setMIFlags(Flags); 1413 1414 MI.eraseFromParent(); 1415 return true; 1416 } 1417 1418 bool AVRExpandPseudo::expandMI(Block &MBB, BlockIt MBBI) { 1419 MachineInstr &MI = *MBBI; 1420 int Opcode = MBBI->getOpcode(); 1421 1422 #define EXPAND(Op) \ 1423 case Op: \ 1424 return expand<Op>(MBB, MI) 1425 1426 switch (Opcode) { 1427 EXPAND(AVR::ADDWRdRr); 1428 EXPAND(AVR::ADCWRdRr); 1429 EXPAND(AVR::SUBWRdRr); 1430 EXPAND(AVR::SUBIWRdK); 1431 EXPAND(AVR::SBCWRdRr); 1432 EXPAND(AVR::SBCIWRdK); 1433 EXPAND(AVR::ANDWRdRr); 1434 EXPAND(AVR::ANDIWRdK); 1435 EXPAND(AVR::ORWRdRr); 1436 EXPAND(AVR::ORIWRdK); 1437 EXPAND(AVR::EORWRdRr); 1438 EXPAND(AVR::COMWRd); 1439 EXPAND(AVR::CPWRdRr); 1440 EXPAND(AVR::CPCWRdRr); 1441 EXPAND(AVR::LDIWRdK); 1442 EXPAND(AVR::LDSWRdK); 1443 EXPAND(AVR::LDWRdPtr); 1444 EXPAND(AVR::LDWRdPtrPi); 1445 EXPAND(AVR::LDWRdPtrPd); 1446 case AVR::LDDWRdYQ: //:FIXME: remove this once PR13375 gets fixed 1447 EXPAND(AVR::LDDWRdPtrQ); 1448 EXPAND(AVR::LPMWRdZ); 1449 EXPAND(AVR::LPMWRdZPi); 1450 EXPAND(AVR::AtomicLoad8); 1451 EXPAND(AVR::AtomicLoad16); 1452 EXPAND(AVR::AtomicStore8); 1453 EXPAND(AVR::AtomicStore16); 1454 EXPAND(AVR::AtomicLoadAdd8); 1455 EXPAND(AVR::AtomicLoadAdd16); 1456 EXPAND(AVR::AtomicLoadSub8); 1457 EXPAND(AVR::AtomicLoadSub16); 1458 EXPAND(AVR::AtomicLoadAnd8); 1459 EXPAND(AVR::AtomicLoadAnd16); 1460 EXPAND(AVR::AtomicLoadOr8); 1461 EXPAND(AVR::AtomicLoadOr16); 1462 EXPAND(AVR::AtomicLoadXor8); 1463 EXPAND(AVR::AtomicLoadXor16); 1464 EXPAND(AVR::AtomicFence); 1465 EXPAND(AVR::STSWKRr); 1466 EXPAND(AVR::STWPtrRr); 1467 EXPAND(AVR::STWPtrPiRr); 1468 EXPAND(AVR::STWPtrPdRr); 1469 EXPAND(AVR::STDWPtrQRr); 1470 EXPAND(AVR::INWRdA); 1471 EXPAND(AVR::OUTWARr); 1472 EXPAND(AVR::PUSHWRr); 1473 EXPAND(AVR::POPWRd); 1474 EXPAND(AVR::LSLWRd); 1475 EXPAND(AVR::LSRWRd); 1476 EXPAND(AVR::RORWRd); 1477 EXPAND(AVR::ROLWRd); 1478 EXPAND(AVR::ASRWRd); 1479 EXPAND(AVR::SEXT); 1480 EXPAND(AVR::ZEXT); 1481 EXPAND(AVR::SPREAD); 1482 EXPAND(AVR::SPWRITE); 1483 } 1484 #undef EXPAND 1485 return false; 1486 } 1487 1488 } // end of anonymous namespace 1489 1490 INITIALIZE_PASS(AVRExpandPseudo, "avr-expand-pseudo", 1491 AVR_EXPAND_PSEUDO_NAME, false, false) 1492 namespace llvm { 1493 1494 FunctionPass *createAVRExpandPseudoPass() { return new AVRExpandPseudo(); } 1495 1496 } // end of namespace llvm 1497