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