1 //===-- AVRExpandPseudoInsts.cpp - Expand pseudo instructions -------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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.
14 //===----------------------------------------------------------------------===//
17 #include "AVRInstrInfo.h"
18 #include "AVRTargetMachine.h"
19 #include "MCTargetDesc/AVRMCTargetDesc.h"
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"
29 #define AVR_EXPAND_PSEUDO_NAME "AVR pseudo instruction expansion pass"
33 /// Expands "placeholder" instructions marked as pseudo into
34 /// actual AVR instructions.
35 class AVRExpandPseudo : public MachineFunctionPass {
39 AVRExpandPseudo() : MachineFunctionPass(ID) {
40 initializeAVRExpandPseudoPass(*PassRegistry::getPassRegistry());
43 bool runOnMachineFunction(MachineFunction &MF) override;
45 StringRef getPassName() const override { return AVR_EXPAND_PSEUDO_NAME; }
48 typedef MachineBasicBlock Block;
49 typedef Block::iterator BlockIt;
51 const AVRRegisterInfo *TRI;
52 const TargetInstrInfo *TII;
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;
59 bool expandMBB(Block &MBB);
60 bool expandMI(Block &MBB, BlockIt MBBI);
61 template <unsigned OP> bool expand(Block &MBB, BlockIt MBBI);
63 MachineInstrBuilder buildMI(Block &MBB, BlockIt MBBI, unsigned Opcode) {
64 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opcode));
67 MachineInstrBuilder buildMI(Block &MBB, BlockIt MBBI, unsigned Opcode,
69 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opcode), DstReg);
72 MachineRegisterInfo &getRegInfo(Block &MBB) { return MBB.getParent()->getRegInfo(); }
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;
79 template<typename Func>
80 bool expandAtomic(Block &MBB, BlockIt MBBI, Func f);
82 template<typename Func>
83 bool expandAtomicBinaryOp(unsigned Opcode, Block &MBB, BlockIt MBBI, Func f);
85 bool expandAtomicBinaryOp(unsigned Opcode, Block &MBB, BlockIt MBBI);
87 bool expandAtomicArithmeticOp(unsigned MemOpcode,
93 char AVRExpandPseudo::ID = 0;
95 bool AVRExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
96 bool Modified = false;
98 BlockIt MBBI = MBB.begin(), E = MBB.end();
100 BlockIt NMBBI = std::next(MBBI);
101 Modified |= expandMI(MBB, MBBI);
108 bool AVRExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
109 bool Modified = false;
111 const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
112 TRI = STI.getRegisterInfo();
113 TII = STI.getInstrInfo();
115 // We need to track liveness in order to use register scavenging.
116 MF.getProperties().set(MachineFunctionProperties::Property::TracksLiveness);
118 for (Block &MBB : MF) {
119 bool ContinueExpanding = true;
120 unsigned ExpandCount = 0;
122 // Continue expanding the block until all pseudos are expanded.
124 assert(ExpandCount < 10 && "pseudo expand limit reached");
126 bool BlockModified = expandMBB(MBB);
127 Modified |= BlockModified;
130 ContinueExpanding = BlockModified;
131 } while (ContinueExpanding);
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);
150 buildMI(MBB, MBBI, OpLo)
151 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
152 .addReg(DstLoReg, getKillRegState(DstIsKill))
153 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
155 auto MIBHI = buildMI(MBB, MBBI, OpHi)
156 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
157 .addReg(DstHiReg, getKillRegState(DstIsKill))
158 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
161 MIBHI->getOperand(3).setIsDead();
163 // SREG is always implicitly killed
164 MIBHI->getOperand(4).setIsKill();
166 MI.eraseFromParent();
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);
183 auto MIBLO = buildMI(MBB, MBBI, Op)
184 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
185 .addReg(DstLoReg, getKillRegState(DstIsKill))
186 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
188 // SREG is always implicitly dead
189 MIBLO->getOperand(3).setIsDead();
191 auto MIBHI = buildMI(MBB, MBBI, Op)
192 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
193 .addReg(DstHiReg, getKillRegState(DstIsKill))
194 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
197 MIBHI->getOperand(3).setIsDead();
199 MI.eraseFromParent();
203 bool AVRExpandPseudo::
204 isLogicImmOpRedundant(unsigned Op, unsigned ImmVal) const {
206 // ANDI Rd, 0xff is redundant.
207 if (Op == AVR::ANDIRdK && ImmVal == 0xff)
210 // ORI Rd, 0x0 is redundant.
211 if (Op == AVR::ORIRdK && ImmVal == 0x0)
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);
230 if (!isLogicImmOpRedundant(Op, Lo8)) {
231 auto MIBLO = buildMI(MBB, MBBI, Op)
232 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
233 .addReg(DstLoReg, getKillRegState(SrcIsKill))
236 // SREG is always implicitly dead
237 MIBLO->getOperand(3).setIsDead();
240 if (!isLogicImmOpRedundant(Op, Hi8)) {
241 auto MIBHI = buildMI(MBB, MBBI, Op)
242 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
243 .addReg(DstHiReg, getKillRegState(SrcIsKill))
247 MIBHI->getOperand(3).setIsDead();
250 MI.eraseFromParent();
255 bool AVRExpandPseudo::expand<AVR::ADDWRdRr>(Block &MBB, BlockIt MBBI) {
256 return expandArith(AVR::ADDRdRr, AVR::ADCRdRr, MBB, MBBI);
260 bool AVRExpandPseudo::expand<AVR::ADCWRdRr>(Block &MBB, BlockIt MBBI) {
261 return expandArith(AVR::ADCRdRr, AVR::ADCRdRr, MBB, MBBI);
265 bool AVRExpandPseudo::expand<AVR::SUBWRdRr>(Block &MBB, BlockIt MBBI) {
266 return expandArith(AVR::SUBRdRr, AVR::SBCRdRr, MBB, MBBI);
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);
279 auto MIBLO = buildMI(MBB, MBBI, AVR::SUBIRdK)
280 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
281 .addReg(DstLoReg, getKillRegState(SrcIsKill));
283 auto MIBHI = buildMI(MBB, MBBI, AVR::SBCIRdK)
284 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
285 .addReg(DstHiReg, getKillRegState(SrcIsKill));
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);
296 case MachineOperand::MO_Immediate: {
297 unsigned Imm = MI.getOperand(2).getImm();
298 MIBLO.addImm(Imm & 0xff);
299 MIBHI.addImm((Imm >> 8) & 0xff);
303 llvm_unreachable("Unknown operand type!");
307 MIBHI->getOperand(3).setIsDead();
309 // SREG is always implicitly killed
310 MIBHI->getOperand(4).setIsKill();
312 MI.eraseFromParent();
317 bool AVRExpandPseudo::expand<AVR::SBCWRdRr>(Block &MBB, BlockIt MBBI) {
318 return expandArith(AVR::SBCRdRr, AVR::SBCRdRr, MBB, MBBI);
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;
334 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
336 auto MIBLO = buildMI(MBB, MBBI, OpLo)
337 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
338 .addReg(DstLoReg, getKillRegState(SrcIsKill))
341 // SREG is always implicitly killed
342 MIBLO->getOperand(4).setIsKill();
344 auto MIBHI = buildMI(MBB, MBBI, OpHi)
345 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
346 .addReg(DstHiReg, getKillRegState(SrcIsKill))
350 MIBHI->getOperand(3).setIsDead();
352 // SREG is always implicitly killed
353 MIBHI->getOperand(4).setIsKill();
355 MI.eraseFromParent();
360 bool AVRExpandPseudo::expand<AVR::ANDWRdRr>(Block &MBB, BlockIt MBBI) {
361 return expandLogic(AVR::ANDRdRr, MBB, MBBI);
365 bool AVRExpandPseudo::expand<AVR::ANDIWRdK>(Block &MBB, BlockIt MBBI) {
366 return expandLogicImm(AVR::ANDIRdK, MBB, MBBI);
370 bool AVRExpandPseudo::expand<AVR::ORWRdRr>(Block &MBB, BlockIt MBBI) {
371 return expandLogic(AVR::ORRdRr, MBB, MBBI);
375 bool AVRExpandPseudo::expand<AVR::ORIWRdK>(Block &MBB, BlockIt MBBI) {
376 return expandLogicImm(AVR::ORIRdK, MBB, MBBI);
380 bool AVRExpandPseudo::expand<AVR::EORWRdRr>(Block &MBB, BlockIt MBBI) {
381 return expandLogic(AVR::EORRdRr, MBB, MBBI);
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();
394 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
396 auto MIBLO = buildMI(MBB, MBBI, OpLo)
397 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
398 .addReg(DstLoReg, getKillRegState(DstIsKill));
400 // SREG is always implicitly dead
401 MIBLO->getOperand(2).setIsDead();
403 auto MIBHI = buildMI(MBB, MBBI, OpHi)
404 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
405 .addReg(DstHiReg, getKillRegState(DstIsKill));
408 MIBHI->getOperand(2).setIsDead();
410 MI.eraseFromParent();
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();
425 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
426 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
429 buildMI(MBB, MBBI, OpLo)
430 .addReg(DstLoReg, getKillRegState(DstIsKill))
431 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
433 auto MIBHI = buildMI(MBB, MBBI, OpHi)
434 .addReg(DstHiReg, getKillRegState(DstIsKill))
435 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
438 MIBHI->getOperand(2).setIsDead();
440 // SREG is always implicitly killed
441 MIBHI->getOperand(3).setIsKill();
443 MI.eraseFromParent();
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();
458 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
459 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
461 auto MIBLO = buildMI(MBB, MBBI, OpLo)
462 .addReg(DstLoReg, getKillRegState(DstIsKill))
463 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
465 // SREG is always implicitly killed
466 MIBLO->getOperand(3).setIsKill();
468 auto MIBHI = buildMI(MBB, MBBI, OpHi)
469 .addReg(DstHiReg, getKillRegState(DstIsKill))
470 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
473 MIBHI->getOperand(2).setIsDead();
475 // SREG is always implicitly killed
476 MIBHI->getOperand(3).setIsKill();
478 MI.eraseFromParent();
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();
490 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
492 auto MIBLO = buildMI(MBB, MBBI, OpLo)
493 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead));
495 auto MIBHI = buildMI(MBB, MBBI, OpHi)
496 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead));
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();
504 MIBLO.addGlobalAddress(GV, Offs, TF | AVRII::MO_LO);
505 MIBHI.addGlobalAddress(GV, Offs, TF | AVRII::MO_HI);
508 case MachineOperand::MO_BlockAddress: {
509 const BlockAddress *BA = MI.getOperand(1).getBlockAddress();
510 unsigned TF = MI.getOperand(1).getTargetFlags();
512 MIBLO.addOperand(MachineOperand::CreateBA(BA, TF | AVRII::MO_LO));
513 MIBHI.addOperand(MachineOperand::CreateBA(BA, TF | AVRII::MO_HI));
516 case MachineOperand::MO_Immediate: {
517 unsigned Imm = MI.getOperand(1).getImm();
519 MIBLO.addImm(Imm & 0xff);
520 MIBHI.addImm((Imm >> 8) & 0xff);
524 llvm_unreachable("Unknown operand type!");
527 MI.eraseFromParent();
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();
539 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
541 auto MIBLO = buildMI(MBB, MBBI, OpLo)
542 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead));
544 auto MIBHI = buildMI(MBB, MBBI, OpHi)
545 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead));
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();
553 MIBLO.addGlobalAddress(GV, Offs, TF);
554 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
557 case MachineOperand::MO_Immediate: {
558 unsigned Imm = MI.getOperand(1).getImm();
561 MIBHI.addImm(Imm + 1);
565 llvm_unreachable("Unknown operand type!");
568 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
569 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
571 MI.eraseFromParent();
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();
584 OpHi = AVR::LDDRdPtrQ;
585 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
587 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
589 auto MIBLO = buildMI(MBB, MBBI, OpLo)
590 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
593 auto MIBHI = buildMI(MBB, MBBI, OpHi)
594 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
595 .addReg(SrcReg, getKillRegState(SrcIsKill))
598 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
599 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
601 MI.eraseFromParent();
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);
617 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
619 auto MIBLO = buildMI(MBB, MBBI, OpLo)
620 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
621 .addReg(SrcReg, RegState::Define)
622 .addReg(SrcReg, RegState::Kill);
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);
629 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
630 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
632 MI.eraseFromParent();
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);
648 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
650 auto MIBHI = buildMI(MBB, MBBI, OpHi)
651 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
652 .addReg(SrcReg, RegState::Define)
653 .addReg(SrcReg, RegState::Kill);
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);
660 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
661 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
663 MI.eraseFromParent();
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);
680 assert(Imm <= 63 && "Offset is out of range");
682 MachineInstr *MIBLO, *MIBHI;
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.
689 // In this case, just use a temporary register.
690 if (DstReg == SrcReg) {
693 RS.enterBasicBlock(MBB);
696 BitVector Candidates =
697 TRI->getAllocatableSet
698 (*MBB.getParent(), &AVR::GPR8RegClass);
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());
707 BitVector Available = RS.getRegsAvailable(&AVR::GPR8RegClass);
708 Available &= Candidates;
710 signed TmpReg = Available.find_first();
711 assert(TmpReg != -1 && "ran out of registers");
713 MIBLO = buildMI(MBB, MBBI, OpLo)
714 .addReg(TmpReg, RegState::Define)
718 buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstLoReg).addReg(TmpReg);
720 MIBHI = buildMI(MBB, MBBI, OpHi)
721 .addReg(TmpReg, RegState::Define)
722 .addReg(SrcReg, getKillRegState(SrcIsKill))
725 buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
727 MIBLO = buildMI(MBB, MBBI, OpLo)
728 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
732 MIBHI = buildMI(MBB, MBBI, OpHi)
733 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
734 .addReg(SrcReg, getKillRegState(SrcIsKill))
738 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
739 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
741 MI.eraseFromParent();
746 bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(Block &MBB, BlockIt MBBI) {
747 llvm_unreachable("wide LPM is unimplemented");
751 bool AVRExpandPseudo::expand<AVR::LPMWRdZPi>(Block &MBB, BlockIt MBBI) {
752 llvm_unreachable("wide LPMPi is unimplemented");
755 template<typename Func>
756 bool AVRExpandPseudo::expandAtomic(Block &MBB, BlockIt MBBI, Func f) {
757 // Remove the pseudo instruction.
758 MachineInstr &MI = *MBBI;
761 buildMI(MBB, MBBI, AVR::INRdA)
762 .addReg(SCRATCH_REGISTER, RegState::Define)
765 // Disable exceptions.
766 buildMI(MBB, MBBI, AVR::BCLRs).addImm(7); // CLI
770 // Restore the status reg.
771 buildMI(MBB, MBBI, AVR::OUTARr)
773 .addReg(SCRATCH_REGISTER);
775 MI.eraseFromParent();
779 template<typename Func>
780 bool AVRExpandPseudo::expandAtomicBinaryOp(unsigned Opcode,
784 return expandAtomic(MBB, MBBI, [&](MachineInstr &MI) {
785 auto Op1 = MI.getOperand(0);
786 auto Op2 = MI.getOperand(1);
788 MachineInstr &NewInst = *buildMI(MBB, MBBI, Opcode)
789 .addOperand(Op1).addOperand(Op2)
795 bool AVRExpandPseudo::expandAtomicBinaryOp(unsigned Opcode,
798 return expandAtomicBinaryOp(Opcode, MBB, MBBI, [](MachineInstr &MI) {});
801 bool AVRExpandPseudo::expandAtomicArithmeticOp(unsigned Width,
802 unsigned ArithOpcode,
805 return expandAtomic(MBB, MBBI, [&](MachineInstr &MI) {
806 auto Op1 = MI.getOperand(0);
807 auto Op2 = MI.getOperand(1);
809 unsigned LoadOpcode = (Width == 8) ? AVR::LDRdPtr : AVR::LDWRdPtr;
810 unsigned StoreOpcode = (Width == 8) ? AVR::STPtrRr : AVR::STWPtrRr;
813 buildMI(MBB, MBBI, LoadOpcode).addOperand(Op1).addOperand(Op2);
815 // Create the arithmetic op
816 buildMI(MBB, MBBI, ArithOpcode)
817 .addOperand(Op1).addOperand(Op1)
821 buildMI(MBB, MBBI, StoreOpcode).addOperand(Op2).addOperand(Op1);
826 bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(Block &MBB, BlockIt MBBI) {
827 return expandAtomicBinaryOp(AVR::LDRdPtr, MBB, MBBI);
831 bool AVRExpandPseudo::expand<AVR::AtomicLoad16>(Block &MBB, BlockIt MBBI) {
832 return expandAtomicBinaryOp(AVR::LDWRdPtr, MBB, MBBI);
836 bool AVRExpandPseudo::expand<AVR::AtomicStore8>(Block &MBB, BlockIt MBBI) {
837 return expandAtomicBinaryOp(AVR::STPtrRr, MBB, MBBI);
841 bool AVRExpandPseudo::expand<AVR::AtomicStore16>(Block &MBB, BlockIt MBBI) {
842 return expandAtomicBinaryOp(AVR::STWPtrRr, MBB, MBBI);
846 bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd8>(Block &MBB, BlockIt MBBI) {
847 return expandAtomicArithmeticOp(8, AVR::ADDRdRr, MBB, MBBI);
851 bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd16>(Block &MBB, BlockIt MBBI) {
852 return expandAtomicArithmeticOp(16, AVR::ADDWRdRr, MBB, MBBI);
856 bool AVRExpandPseudo::expand<AVR::AtomicLoadSub8>(Block &MBB, BlockIt MBBI) {
857 return expandAtomicArithmeticOp(8, AVR::SUBRdRr, MBB, MBBI);
861 bool AVRExpandPseudo::expand<AVR::AtomicLoadSub16>(Block &MBB, BlockIt MBBI) {
862 return expandAtomicArithmeticOp(16, AVR::SUBWRdRr, MBB, MBBI);
866 bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd8>(Block &MBB, BlockIt MBBI) {
867 return expandAtomicArithmeticOp(8, AVR::ANDRdRr, MBB, MBBI);
871 bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd16>(Block &MBB, BlockIt MBBI) {
872 return expandAtomicArithmeticOp(16, AVR::ANDWRdRr, MBB, MBBI);
876 bool AVRExpandPseudo::expand<AVR::AtomicLoadOr8>(Block &MBB, BlockIt MBBI) {
877 return expandAtomicArithmeticOp(8, AVR::ORRdRr, MBB, MBBI);
881 bool AVRExpandPseudo::expand<AVR::AtomicLoadOr16>(Block &MBB, BlockIt MBBI) {
882 return expandAtomicArithmeticOp(16, AVR::ORWRdRr, MBB, MBBI);
886 bool AVRExpandPseudo::expand<AVR::AtomicLoadXor8>(Block &MBB, BlockIt MBBI) {
887 return expandAtomicArithmeticOp(8, AVR::EORRdRr, MBB, MBBI);
891 bool AVRExpandPseudo::expand<AVR::AtomicLoadXor16>(Block &MBB, BlockIt MBBI) {
892 return expandAtomicArithmeticOp(16, AVR::EORWRdRr, MBB, MBBI);
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();
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();
910 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
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);
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();
923 MIBLO.addGlobalAddress(GV, Offs, TF);
924 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
927 case MachineOperand::MO_Immediate: {
928 unsigned Imm = MI.getOperand(0).getImm();
931 MIBHI.addImm(Imm + 1);
935 llvm_unreachable("Unknown operand type!");
938 MIBLO.addReg(SrcLoReg, getKillRegState(SrcIsKill));
939 MIBHI.addReg(SrcHiReg, getKillRegState(SrcIsKill));
941 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
942 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
944 MI.eraseFromParent();
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();
957 OpHi = AVR::STDPtrQRr;
958 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
960 //:TODO: need to reverse this order like inw and stsw?
961 auto MIBLO = buildMI(MBB, MBBI, OpLo)
963 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
965 auto MIBHI = buildMI(MBB, MBBI, OpHi)
966 .addReg(DstReg, getKillRegState(DstIsKill))
968 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
970 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
971 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
973 MI.eraseFromParent();
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);
990 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
992 auto MIBLO = buildMI(MBB, MBBI, OpLo)
993 .addReg(DstReg, RegState::Define)
994 .addReg(DstReg, RegState::Kill)
995 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
998 auto MIBHI = buildMI(MBB, MBBI, OpHi)
999 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
1000 .addReg(DstReg, RegState::Kill)
1001 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1004 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1005 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1007 MI.eraseFromParent();
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);
1024 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
1026 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1027 .addReg(DstReg, RegState::Define)
1028 .addReg(DstReg, RegState::Kill)
1029 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1032 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1033 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
1034 .addReg(DstReg, RegState::Kill)
1035 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1038 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1039 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1041 MI.eraseFromParent();
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);
1058 assert(Imm <= 63 && "Offset is out of range");
1060 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1063 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
1065 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1066 .addReg(DstReg, getKillRegState(DstIsKill))
1068 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
1070 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1071 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1073 MI.eraseFromParent();
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();
1086 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1088 assert(Imm <= 63 && "Address is out of range");
1090 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1091 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1094 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1095 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1098 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1099 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1101 MI.eraseFromParent();
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();
1114 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1116 assert(Imm <= 63 && "Address is out of range");
1118 // 16 bit I/O writes need the high byte first
1119 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1121 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
1123 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1125 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
1127 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1128 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1130 MI.eraseFromParent();
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();
1143 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1146 buildMI(MBB, MBBI, OpLo)
1147 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1151 buildMI(MBB, MBBI, OpHi)
1152 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1155 MI.eraseFromParent();
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();
1167 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1169 buildMI(MBB, MBBI, OpHi, DstHiReg).setMIFlags(Flags); // High
1170 buildMI(MBB, MBBI, OpLo, DstLoReg).setMIFlags(Flags); // Low
1172 MI.eraseFromParent();
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();
1186 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1189 buildMI(MBB, MBBI, OpLo)
1190 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1191 .addReg(DstLoReg, getKillRegState(DstIsKill));
1193 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1194 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1195 .addReg(DstHiReg, getKillRegState(DstIsKill));
1198 MIBHI->getOperand(2).setIsDead();
1200 // SREG is always implicitly killed
1201 MIBHI->getOperand(3).setIsKill();
1203 MI.eraseFromParent();
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();
1217 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1220 buildMI(MBB, MBBI, OpHi)
1221 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1222 .addReg(DstHiReg, getKillRegState(DstIsKill));
1224 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1225 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1226 .addReg(DstLoReg, getKillRegState(DstIsKill));
1229 MIBLO->getOperand(2).setIsDead();
1231 // SREG is always implicitly killed
1232 MIBLO->getOperand(3).setIsKill();
1234 MI.eraseFromParent();
1239 bool AVRExpandPseudo::expand<AVR::RORWRd>(Block &MBB, BlockIt MBBI) {
1240 llvm_unreachable("RORW unimplemented");
1245 bool AVRExpandPseudo::expand<AVR::ROLWRd>(Block &MBB, BlockIt MBBI) {
1246 llvm_unreachable("ROLW unimplemented");
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();
1260 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1263 buildMI(MBB, MBBI, OpHi)
1264 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1265 .addReg(DstHiReg, getKillRegState(DstIsKill));
1267 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1268 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1269 .addReg(DstLoReg, getKillRegState(DstIsKill));
1272 MIBLO->getOperand(2).setIsDead();
1274 // SREG is always implicitly killed
1275 MIBLO->getOperand(3).setIsKill();
1277 MI.eraseFromParent();
1281 template <> bool AVRExpandPseudo::expand<AVR::SEXT>(Block &MBB, BlockIt MBBI) {
1282 MachineInstr &MI = *MBBI;
1283 unsigned DstLoReg, DstHiReg;
1284 // sext R17:R16, R17
1288 // sext R17:R16, R13
1293 // sext R17:R16, R16
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);
1304 if (SrcReg != DstLoReg) {
1305 auto MOV = buildMI(MBB, MBBI, AVR::MOVRdRr)
1306 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1309 if (SrcReg == DstHiReg) {
1310 MOV->getOperand(1).setIsKill();
1314 if (SrcReg != DstHiReg) {
1315 buildMI(MBB, MBBI, AVR::MOVRdRr)
1316 .addReg(DstHiReg, RegState::Define)
1317 .addReg(SrcReg, getKillRegState(SrcIsKill));
1320 buildMI(MBB, MBBI, AVR::LSLRd)
1321 .addReg(DstHiReg, RegState::Define)
1322 .addReg(DstHiReg, RegState::Kill);
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);
1330 SBC->getOperand(3).setIsDead();
1332 // SREG is always implicitly killed
1333 SBC->getOperand(4).setIsKill();
1335 MI.eraseFromParent();
1339 template <> bool AVRExpandPseudo::expand<AVR::ZEXT>(Block &MBB, BlockIt MBBI) {
1340 MachineInstr &MI = *MBBI;
1341 unsigned DstLoReg, DstHiReg;
1342 // zext R25:R24, R20
1345 // zext R25:R24, R24
1347 // zext R25:R24, 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);
1357 if (SrcReg != DstLoReg) {
1358 buildMI(MBB, MBBI, AVR::MOVRdRr)
1359 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1360 .addReg(SrcReg, getKillRegState(SrcIsKill));
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);
1369 EOR->getOperand(3).setIsDead();
1371 MI.eraseFromParent();
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();
1384 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1387 buildMI(MBB, MBBI, OpLo)
1388 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1393 buildMI(MBB, MBBI, OpHi)
1394 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1398 MI.eraseFromParent();
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);
1411 buildMI(MBB, MBBI, AVR::INRdA)
1412 .addReg(AVR::R0, RegState::Define)
1416 buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
1418 buildMI(MBB, MBBI, AVR::OUTARr)
1420 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1423 buildMI(MBB, MBBI, AVR::OUTARr)
1425 .addReg(AVR::R0, RegState::Kill)
1428 buildMI(MBB, MBBI, AVR::OUTARr)
1430 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1433 MI.eraseFromParent();
1437 bool AVRExpandPseudo::expandMI(Block &MBB, BlockIt MBBI) {
1438 MachineInstr &MI = *MBBI;
1439 int Opcode = MBBI->getOpcode();
1441 #define EXPAND(Op) \
1443 return expand<Op>(MBB, MI)
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);
1500 EXPAND(AVR::SPREAD);
1501 EXPAND(AVR::SPWRITE);
1507 } // end of anonymous namespace
1509 INITIALIZE_PASS(AVRExpandPseudo, "avr-expand-pseudo",
1510 AVR_EXPAND_PSEUDO_NAME, false, false)
1513 FunctionPass *createAVRExpandPseudoPass() { return new AVRExpandPseudo(); }
1515 } // end of namespace llvm