27#define AVR_EXPAND_PSEUDO_NAME "AVR pseudo instruction expansion pass"
50 bool expandMBB(Block &
MBB);
51 bool expandMI(Block &
MBB, BlockIt
MBBI);
67 bool expandArith(
unsigned OpLo,
unsigned OpHi, Block &
MBB, BlockIt
MBBI);
68 bool expandLogic(
unsigned Op, Block &
MBB, BlockIt
MBBI);
69 bool expandLogicImm(
unsigned Op, Block &
MBB, BlockIt
MBBI);
70 bool isLogicImmOpRedundant(
unsigned Op,
unsigned ImmVal)
const;
71 bool isLogicRegOpUndef(
unsigned Op,
unsigned ImmVal)
const;
73 template <
typename Func>
bool expandAtomic(Block &
MBB, BlockIt
MBBI, Func f);
75 template <
typename Func>
76 bool expandAtomicBinaryOp(
unsigned Opcode, Block &
MBB, BlockIt
MBBI, Func f);
78 bool expandAtomicBinaryOp(
unsigned Opcode, Block &
MBB, BlockIt
MBBI);
81 bool expandLSLB7Rd(Block &
MBB, BlockIt
MBBI);
82 bool expandLSRB7Rd(Block &
MBB, BlockIt
MBBI);
83 bool expandASRB6Rd(Block &
MBB, BlockIt
MBBI);
84 bool expandASRB7Rd(Block &
MBB, BlockIt
MBBI);
87 bool expandLSLW4Rd(Block &
MBB, BlockIt
MBBI);
88 bool expandLSRW4Rd(Block &
MBB, BlockIt
MBBI);
89 bool expandASRW7Rd(Block &
MBB, BlockIt
MBBI);
90 bool expandLSLW8Rd(Block &
MBB, BlockIt
MBBI);
91 bool expandLSRW8Rd(Block &
MBB, BlockIt
MBBI);
92 bool expandASRW8Rd(Block &
MBB, BlockIt
MBBI);
93 bool expandLSLW12Rd(Block &
MBB, BlockIt
MBBI);
94 bool expandLSRW12Rd(Block &
MBB, BlockIt
MBBI);
95 bool expandASRW14Rd(Block &
MBB, BlockIt
MBBI);
96 bool expandASRW15Rd(Block &
MBB, BlockIt
MBBI);
99 bool expandLPMWELPMW(Block &
MBB, BlockIt
MBBI,
bool IsELPM);
101 bool expandLPMBELPMB(Block &
MBB, BlockIt
MBBI,
bool IsELPM);
103 bool expandROLBRd(Block &
MBB, BlockIt
MBBI);
106char AVRExpandPseudo::ID = 0;
113 BlockIt NMBBI = std::next(
MBBI);
129 bool ContinueExpanding =
true;
130 unsigned ExpandCount = 0;
134 assert(ExpandCount < 10 &&
"pseudo expand limit reached");
137 bool BlockModified = expandMBB(
MBB);
141 ContinueExpanding = BlockModified;
142 }
while (ContinueExpanding);
148bool AVRExpandPseudo::expandArith(
unsigned OpLo,
unsigned OpHi,
Block &
MBB,
151 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
154 bool DstIsDead =
MI.getOperand(0).isDead();
155 bool DstIsKill =
MI.getOperand(1).isKill();
156 bool SrcIsKill =
MI.getOperand(2).isKill();
157 bool ImpIsDead =
MI.getOperand(3).isDead();
158 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
159 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
173 MIBHI->getOperand(3).setIsDead();
176 MIBHI->getOperand(4).setIsKill();
178 MI.eraseFromParent();
182bool AVRExpandPseudo::expandLogic(
unsigned Op,
Block &
MBB, BlockIt
MBBI) {
184 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
187 bool DstIsDead =
MI.getOperand(0).isDead();
188 bool DstIsKill =
MI.getOperand(1).isKill();
189 bool SrcIsKill =
MI.getOperand(2).isKill();
190 bool ImpIsDead =
MI.getOperand(3).isDead();
191 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
192 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
201 MIBLO->getOperand(3).setIsDead();
210 MIBHI->getOperand(3).setIsDead();
212 MI.eraseFromParent();
216bool AVRExpandPseudo::isLogicImmOpRedundant(
unsigned Op,
217 unsigned ImmVal)
const {
220 if (
Op == AVR::ANDIRdK && ImmVal == 0xff)
224 if (
Op == AVR::ORIRdK && ImmVal == 0x0)
230bool AVRExpandPseudo::isLogicRegOpUndef(
unsigned Op,
unsigned ImmVal)
const {
232 if (
Op == AVR::ANDIRdK && ImmVal == 0x00)
236 if (
Op == AVR::ORIRdK && ImmVal == 0xff)
242bool AVRExpandPseudo::expandLogicImm(
unsigned Op,
Block &
MBB, BlockIt
MBBI) {
246 bool DstIsDead =
MI.getOperand(0).isDead();
247 bool SrcIsKill =
MI.getOperand(1).isKill();
248 bool ImpIsDead =
MI.getOperand(3).isDead();
249 unsigned Imm =
MI.getOperand(2).getImm();
250 unsigned Lo8 = Imm & 0xff;
251 unsigned Hi8 = (Imm >> 8) & 0xff;
252 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
254 if (!isLogicImmOpRedundant(
Op, Lo8)) {
262 MIBLO->getOperand(3).setIsDead();
264 if (isLogicRegOpUndef(
Op, Lo8))
265 MIBLO->getOperand(1).setIsUndef(
true);
268 if (!isLogicImmOpRedundant(
Op, Hi8)) {
276 MIBHI->getOperand(3).setIsDead();
278 if (isLogicRegOpUndef(
Op, Hi8))
279 MIBHI->getOperand(1).setIsUndef(
true);
282 MI.eraseFromParent();
287bool AVRExpandPseudo::expand<AVR::ADDWRdRr>(
Block &
MBB, BlockIt
MBBI) {
288 return expandArith(AVR::ADDRdRr, AVR::ADCRdRr,
MBB,
MBBI);
292bool AVRExpandPseudo::expand<AVR::ADCWRdRr>(
Block &
MBB, BlockIt
MBBI) {
293 return expandArith(AVR::ADCRdRr, AVR::ADCRdRr,
MBB,
MBBI);
297bool AVRExpandPseudo::expand<AVR::SUBWRdRr>(
Block &
MBB, BlockIt
MBBI) {
298 return expandArith(AVR::SUBRdRr, AVR::SBCRdRr,
MBB,
MBBI);
302bool AVRExpandPseudo::expand<AVR::SUBIWRdK>(
Block &
MBB, BlockIt
MBBI) {
306 bool DstIsDead =
MI.getOperand(0).isDead();
307 bool SrcIsKill =
MI.getOperand(1).isKill();
308 bool ImpIsDead =
MI.getOperand(3).isDead();
309 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
312 buildMI(
MBB,
MBBI, AVR::SUBIRdK)
317 buildMI(
MBB,
MBBI, AVR::SBCIRdK)
321 switch (
MI.getOperand(2).getType()) {
324 int64_t Offs =
MI.getOperand(2).getOffset();
325 unsigned TF =
MI.getOperand(2).getTargetFlags();
331 unsigned Imm =
MI.getOperand(2).getImm();
332 MIBLO.addImm(Imm & 0xff);
333 MIBHI.addImm((Imm >> 8) & 0xff);
341 MIBHI->getOperand(3).setIsDead();
344 MIBHI->getOperand(4).setIsKill();
346 MI.eraseFromParent();
351bool AVRExpandPseudo::expand<AVR::SBCWRdRr>(
Block &
MBB, BlockIt
MBBI) {
352 return expandArith(AVR::SBCRdRr, AVR::SBCRdRr,
MBB,
MBBI);
356bool AVRExpandPseudo::expand<AVR::SBCIWRdK>(
Block &
MBB, BlockIt
MBBI) {
360 bool DstIsDead =
MI.getOperand(0).isDead();
361 bool SrcIsKill =
MI.getOperand(1).isKill();
362 bool ImpIsDead =
MI.getOperand(3).isDead();
363 unsigned Imm =
MI.getOperand(2).getImm();
364 unsigned Lo8 = Imm & 0xff;
365 unsigned Hi8 = (Imm >> 8) & 0xff;
366 unsigned OpLo = AVR::SBCIRdK;
367 unsigned OpHi = AVR::SBCIRdK;
368 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
377 MIBLO->getOperand(4).setIsKill();
386 MIBHI->getOperand(3).setIsDead();
389 MIBHI->getOperand(4).setIsKill();
391 MI.eraseFromParent();
396bool AVRExpandPseudo::expand<AVR::ANDWRdRr>(
Block &
MBB, BlockIt
MBBI) {
397 return expandLogic(AVR::ANDRdRr,
MBB,
MBBI);
401bool AVRExpandPseudo::expand<AVR::ANDIWRdK>(
Block &
MBB, BlockIt
MBBI) {
402 return expandLogicImm(AVR::ANDIRdK,
MBB,
MBBI);
406bool AVRExpandPseudo::expand<AVR::ORWRdRr>(
Block &
MBB, BlockIt
MBBI) {
407 return expandLogic(AVR::ORRdRr,
MBB,
MBBI);
411bool AVRExpandPseudo::expand<AVR::ORIWRdK>(
Block &
MBB, BlockIt
MBBI) {
412 return expandLogicImm(AVR::ORIRdK,
MBB,
MBBI);
416bool AVRExpandPseudo::expand<AVR::EORWRdRr>(
Block &
MBB, BlockIt
MBBI) {
417 return expandLogic(AVR::EORRdRr,
MBB,
MBBI);
421bool AVRExpandPseudo::expand<AVR::COMWRd>(
Block &
MBB, BlockIt
MBBI) {
425 bool DstIsDead =
MI.getOperand(0).isDead();
426 bool DstIsKill =
MI.getOperand(1).isKill();
427 bool ImpIsDead =
MI.getOperand(2).isDead();
428 unsigned OpLo = AVR::COMRd;
429 unsigned OpHi = AVR::COMRd;
430 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
438 MIBLO->getOperand(2).setIsDead();
446 MIBHI->getOperand(2).setIsDead();
448 MI.eraseFromParent();
453bool AVRExpandPseudo::expand<AVR::NEGWRd>(
Block &
MBB, BlockIt
MBBI) {
458 bool DstIsDead =
MI.getOperand(0).isDead();
459 bool DstIsKill =
MI.getOperand(1).isKill();
460 bool ImpIsDead =
MI.getOperand(2).isDead();
461 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
469 MIBHI->getOperand(2).setIsDead();
478 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
483 MISBCI->getOperand(3).setIsDead();
485 MISBCI->getOperand(4).setIsKill();
487 MI.eraseFromParent();
492bool AVRExpandPseudo::expand<AVR::CPWRdRr>(
Block &
MBB, BlockIt
MBBI) {
494 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
497 bool DstIsKill =
MI.getOperand(0).isKill();
498 bool SrcIsKill =
MI.getOperand(1).isKill();
499 bool ImpIsDead =
MI.getOperand(2).isDead();
500 unsigned OpLo = AVR::CPRdRr;
501 unsigned OpHi = AVR::CPCRdRr;
502 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
503 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
510 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
515 MIBHI->getOperand(2).setIsDead();
518 MIBHI->getOperand(3).setIsKill();
520 MI.eraseFromParent();
525bool AVRExpandPseudo::expand<AVR::CPCWRdRr>(
Block &
MBB, BlockIt
MBBI) {
527 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
530 bool DstIsKill =
MI.getOperand(0).isKill();
531 bool SrcIsKill =
MI.getOperand(1).isKill();
532 bool ImpIsDead =
MI.getOperand(2).isDead();
533 unsigned OpLo = AVR::CPCRdRr;
534 unsigned OpHi = AVR::CPCRdRr;
535 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
536 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
538 auto MIBLO = buildMI(
MBB,
MBBI, OpLo)
543 MIBLO->getOperand(3).setIsKill();
545 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
550 MIBHI->getOperand(2).setIsDead();
553 MIBHI->getOperand(3).setIsKill();
555 MI.eraseFromParent();
560bool AVRExpandPseudo::expand<AVR::LDIWRdK>(
Block &
MBB, BlockIt
MBBI) {
564 bool DstIsDead =
MI.getOperand(0).isDead();
565 unsigned OpLo = AVR::LDIRdK;
566 unsigned OpHi = AVR::LDIRdK;
567 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
577 switch (
MI.getOperand(1).getType()) {
580 int64_t Offs =
MI.getOperand(1).getOffset();
581 unsigned TF =
MI.getOperand(1).getTargetFlags();
589 unsigned TF =
MI.getOperand(1).getTargetFlags();
596 unsigned Imm =
MI.getOperand(1).getImm();
598 MIBLO.addImm(Imm & 0xff);
599 MIBHI.addImm((Imm >> 8) & 0xff);
606 MI.eraseFromParent();
611bool AVRExpandPseudo::expand<AVR::LDSWRdK>(
Block &
MBB, BlockIt
MBBI) {
615 bool DstIsDead =
MI.getOperand(0).isDead();
616 unsigned OpLo = AVR::LDSRdK;
617 unsigned OpHi = AVR::LDSRdK;
618 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
628 switch (
MI.getOperand(1).getType()) {
631 int64_t Offs =
MI.getOperand(1).getOffset();
632 unsigned TF =
MI.getOperand(1).getTargetFlags();
634 MIBLO.addGlobalAddress(GV, Offs, TF);
635 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
639 unsigned Imm =
MI.getOperand(1).getImm();
642 MIBHI.addImm(Imm + 1);
649 MIBLO.setMemRefs(
MI.memoperands());
650 MIBHI.setMemRefs(
MI.memoperands());
652 MI.eraseFromParent();
657bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(
Block &
MBB, BlockIt
MBBI) {
661 bool DstIsKill =
MI.getOperand(0).isKill();
662 bool SrcIsKill =
MI.getOperand(1).isKill();
667 assert(DstReg != SrcReg &&
"Dst and Src registers are the same!");
669 if (STI.hasTinyEncoding()) {
672 buildMI(
MBB,
MBBI, AVR::LDDWRdPtrQ)
676 .setMemRefs(
MI.memoperands());
680 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
683 buildMI(
MBB,
MBBI, AVR::LDRdPtr)
686 .setMemRefs(
MI.memoperands());
689 buildMI(
MBB,
MBBI, AVR::LDDRdPtrQ)
693 .setMemRefs(
MI.memoperands());
696 MI.eraseFromParent();
701bool AVRExpandPseudo::expand<AVR::LDWRdPtrPi>(
Block &
MBB, BlockIt
MBBI) {
706 bool DstIsDead =
MI.getOperand(0).isDead();
707 bool SrcIsDead =
MI.getOperand(1).isKill();
708 unsigned OpLo = AVR::LDRdPtrPi;
709 unsigned OpHi = AVR::LDRdPtrPi;
710 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
712 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
726 MIBLO.setMemRefs(
MI.memoperands());
727 MIBHI.setMemRefs(
MI.memoperands());
729 MI.eraseFromParent();
734bool AVRExpandPseudo::expand<AVR::LDWRdPtrPd>(
Block &
MBB, BlockIt
MBBI) {
739 bool DstIsDead =
MI.getOperand(0).isDead();
740 bool SrcIsDead =
MI.getOperand(1).isKill();
741 unsigned OpLo = AVR::LDRdPtrPd;
742 unsigned OpHi = AVR::LDRdPtrPd;
743 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
745 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
759 MIBLO.setMemRefs(
MI.memoperands());
760 MIBHI.setMemRefs(
MI.memoperands());
762 MI.eraseFromParent();
767bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(
Block &
MBB, BlockIt
MBBI) {
771 unsigned Imm =
MI.getOperand(2).getImm();
772 bool DstIsKill =
MI.getOperand(0).isKill();
773 bool SrcIsKill =
MI.getOperand(1).isKill();
778 assert(Imm <= 62 &&
"Offset is out of range");
782 assert(DstReg != SrcReg &&
"Dst and Src registers are the same!");
784 if (STI.hasTinyEncoding()) {
792 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, SrcReg)
794 .addImm(0x10000 - Imm);
799 buildMI(
MBB,
MBBI, AVR::LDWRdPtrPi)
803 .setMemRefs(
MI.memoperands());
809 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, SrcReg).addReg(SrcReg).addImm(Imm + 2);
813 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
816 buildMI(
MBB,
MBBI, AVR::LDDRdPtrQ)
820 .setMemRefs(
MI.memoperands());
823 buildMI(
MBB,
MBBI, AVR::LDDRdPtrQ)
827 .setMemRefs(
MI.memoperands());
830 MI.eraseFromParent();
834bool AVRExpandPseudo::expandLPMWELPMW(
Block &
MBB, BlockIt
MBBI,
bool IsELPM) {
840 bool SrcIsKill =
MI.getOperand(1).isKill();
842 bool IsLPMRn = IsELPM ? STI.hasELPMX() : STI.hasLPMX();
844 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
845 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
855 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
858 unsigned OpLo = IsELPM ? AVR::ELPMRdZPi : AVR::LPMRdZPi;
859 unsigned OpHi = IsELPM ? AVR::ELPMRdZ : AVR::LPMRdZ;
861 auto MIBLO = buildMI(
MBB,
MBBI, OpLo)
865 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
868 MIBLO.setMemRefs(
MI.memoperands());
869 MIBHI.setMemRefs(
MI.memoperands());
871 unsigned Opc = IsELPM ? AVR::ELPM : AVR::LPM;
874 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
877 MIBLO.setMemRefs(
MI.memoperands());
879 if (STI.hasADDSUBIW()) {
881 auto MIINC = buildMI(
MBB,
MBBI, AVR::ADIWRdK)
885 MIINC->getOperand(3).setIsDead();
889 buildMI(
MBB,
MBBI, AVR::SUBIRdK)
893 auto MIZHI = buildMI(
MBB,
MBBI, AVR::SBCIRdK)
897 MIZHI->getOperand(3).setIsDead();
898 MIZHI->getOperand(4).setIsKill();
902 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
905 MIBHI.setMemRefs(
MI.memoperands());
910 if (STI.hasADDSUBIW()) {
912 auto MIDEC = buildMI(
MBB,
MBBI, AVR::SBIWRdK)
916 MIDEC->getOperand(3).setIsDead();
920 buildMI(
MBB,
MBBI, AVR::SUBIRdK)
924 auto MIZHI = buildMI(
MBB,
MBBI, AVR::SBCIRdK)
928 MIZHI->getOperand(3).setIsDead();
929 MIZHI->getOperand(4).setIsKill();
933 MI.eraseFromParent();
938bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(
Block &
MBB, BlockIt
MBBI) {
939 return expandLPMWELPMW(
MBB,
MBBI,
false);
943bool AVRExpandPseudo::expand<AVR::ELPMWRdZ>(
Block &
MBB, BlockIt
MBBI) {
944 return expandLPMWELPMW(
MBB,
MBBI,
true);
947bool AVRExpandPseudo::expandLPMBELPMB(
Block &
MBB, BlockIt
MBBI,
bool IsELPM) {
951 bool SrcIsKill =
MI.getOperand(1).isKill();
953 bool IsLPMRn = IsELPM ? STI.hasELPMX() : STI.hasLPMX();
963 unsigned Opc = IsELPM ? AVR::ELPMRdZ : AVR::LPMRdZ;
967 MILB.setMemRefs(
MI.memoperands());
971 unsigned Opc = IsELPM ? AVR::ELPM : AVR::LPM;
973 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
976 MILB.setMemRefs(
MI.memoperands());
979 MI.eraseFromParent();
984bool AVRExpandPseudo::expand<AVR::ELPMBRdZ>(
Block &
MBB, BlockIt
MBBI) {
985 return expandLPMBELPMB(
MBB,
MBBI,
true);
989bool AVRExpandPseudo::expand<AVR::LPMBRdZ>(
Block &
MBB, BlockIt
MBBI) {
990 return expandLPMBELPMB(
MBB,
MBBI,
false);
994bool AVRExpandPseudo::expand<AVR::LPMWRdZPi>(
Block &
MBB, BlockIt
MBBI) {
999bool AVRExpandPseudo::expand<AVR::ELPMBRdZPi>(
Block &
MBB, BlockIt
MBBI) {
1004bool AVRExpandPseudo::expand<AVR::ELPMWRdZPi>(
Block &
MBB, BlockIt
MBBI) {
1008template <
typename Func>
1009bool AVRExpandPseudo::expandAtomic(
Block &
MBB, BlockIt
MBBI, Func f) {
1014 buildMI(
MBB,
MBBI, AVR::INRdA)
1019 buildMI(
MBB,
MBBI, AVR::BCLRs).addImm(7);
1024 buildMI(
MBB,
MBBI, AVR::OUTARr)
1028 MI.eraseFromParent();
1032template <
typename Func>
1033bool AVRExpandPseudo::expandAtomicBinaryOp(
unsigned Opcode,
Block &
MBB,
1034 BlockIt
MBBI, Func f) {
1036 auto Op1 =
MI.getOperand(0);
1037 auto Op2 =
MI.getOperand(1);
1040 *buildMI(
MBB,
MBBI, Opcode).add(Op1).add(Op2).getInstr();
1045bool AVRExpandPseudo::expandAtomicBinaryOp(
unsigned Opcode,
Block &
MBB,
1051bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(
Block &
MBB, BlockIt
MBBI) {
1052 return expandAtomicBinaryOp(AVR::LDRdPtr,
MBB,
MBBI);
1056bool AVRExpandPseudo::expand<AVR::AtomicLoad16>(
Block &
MBB, BlockIt
MBBI) {
1057 return expandAtomicBinaryOp(AVR::LDWRdPtr,
MBB,
MBBI);
1061bool AVRExpandPseudo::expand<AVR::AtomicStore8>(
Block &
MBB, BlockIt
MBBI) {
1062 return expandAtomicBinaryOp(AVR::STPtrRr,
MBB,
MBBI);
1066bool AVRExpandPseudo::expand<AVR::AtomicStore16>(
Block &
MBB, BlockIt
MBBI) {
1067 return expandAtomicBinaryOp(AVR::STWPtrRr,
MBB,
MBBI);
1071bool AVRExpandPseudo::expand<AVR::AtomicFence>(
Block &
MBB, BlockIt
MBBI) {
1078bool AVRExpandPseudo::expand<AVR::STSWKRr>(
Block &
MBB, BlockIt
MBBI) {
1083 bool SrcIsKill =
MI.getOperand(1).isKill();
1084 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1086 auto MIB0 = buildMI(
MBB,
MBBI, AVR::STSKRr);
1087 auto MIB1 = buildMI(
MBB,
MBBI, AVR::STSKRr);
1089 switch (
MI.getOperand(0).getType()) {
1092 int64_t Offs =
MI.getOperand(0).getOffset();
1093 unsigned TF =
MI.getOperand(0).getTargetFlags();
1095 if (STI.hasLowByteFirst()) {
1097 MIB0.addGlobalAddress(GV, Offs, TF);
1098 MIB1.addGlobalAddress(GV, Offs + 1, TF);
1101 MIB0.addGlobalAddress(GV, Offs + 1, TF);
1102 MIB1.addGlobalAddress(GV, Offs, TF);
1108 unsigned Imm =
MI.getOperand(0).getImm();
1110 if (STI.hasLowByteFirst()) {
1113 MIB1.addImm(Imm + 1);
1116 MIB0.addImm(Imm + 1);
1126 if (STI.hasLowByteFirst()) {
1129 .setMemRefs(
MI.memoperands());
1131 .setMemRefs(
MI.memoperands());
1135 .setMemRefs(
MI.memoperands());
1137 .setMemRefs(
MI.memoperands());
1140 MI.eraseFromParent();
1145bool AVRExpandPseudo::expand<AVR::STWPtrRr>(
Block &
MBB, BlockIt
MBBI) {
1149 bool DstIsKill =
MI.getOperand(0).isKill();
1150 bool DstIsUndef =
MI.getOperand(0).isUndef();
1151 bool SrcIsKill =
MI.getOperand(1).isKill();
1156 if (STI.hasTinyEncoding()) {
1159 buildMI(
MBB,
MBBI, AVR::STDWPtrQRr)
1164 .setMemRefs(
MI.memoperands());
1168 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1169 if (STI.hasLowByteFirst()) {
1170 buildMI(
MBB,
MBBI, AVR::STPtrRr)
1173 .setMemRefs(
MI.memoperands());
1174 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1178 .setMemRefs(
MI.memoperands());
1180 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1184 .setMemRefs(
MI.memoperands());
1185 buildMI(
MBB,
MBBI, AVR::STPtrRr)
1188 .setMemRefs(
MI.memoperands());
1192 MI.eraseFromParent();
1197bool AVRExpandPseudo::expand<AVR::STWPtrPiRr>(
Block &
MBB, BlockIt
MBBI) {
1202 unsigned Imm =
MI.getOperand(3).getImm();
1203 bool DstIsDead =
MI.getOperand(0).isDead();
1204 bool SrcIsKill =
MI.getOperand(2).isKill();
1205 unsigned OpLo = AVR::STPtrPiRr;
1206 unsigned OpHi = AVR::STPtrPiRr;
1207 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1209 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
1211 auto MIBLO = buildMI(
MBB,
MBBI, OpLo)
1224 MIBLO.setMemRefs(
MI.memoperands());
1225 MIBHI.setMemRefs(
MI.memoperands());
1227 MI.eraseFromParent();
1232bool AVRExpandPseudo::expand<AVR::STWPtrPdRr>(
Block &
MBB, BlockIt
MBBI) {
1237 unsigned Imm =
MI.getOperand(3).getImm();
1238 bool DstIsDead =
MI.getOperand(0).isDead();
1239 bool SrcIsKill =
MI.getOperand(2).isKill();
1240 unsigned OpLo = AVR::STPtrPdRr;
1241 unsigned OpHi = AVR::STPtrPdRr;
1242 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1244 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
1246 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
1259 MIBLO.setMemRefs(
MI.memoperands());
1260 MIBHI.setMemRefs(
MI.memoperands());
1262 MI.eraseFromParent();
1267bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(
Block &
MBB, BlockIt
MBBI) {
1272 bool DstIsKill =
MI.getOperand(0).isKill();
1273 unsigned Imm =
MI.getOperand(1).getImm();
1275 bool SrcIsKill =
MI.getOperand(2).isKill();
1281 if (Imm >= 63 || STI.hasTinyEncoding()) {
1285 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, DstReg)
1287 .addImm(0x10000 - Imm);
1291 buildMI(
MBB,
MBBI, AVR::STWPtrPiRr, DstReg)
1295 .setMemRefs(
MI.memoperands());
1301 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, DstReg)
1307 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1309 if (STI.hasLowByteFirst()) {
1310 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1314 .setMemRefs(
MI.memoperands());
1315 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1319 .setMemRefs(
MI.memoperands());
1321 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1325 .setMemRefs(
MI.memoperands());
1326 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1330 .setMemRefs(
MI.memoperands());
1334 MI.eraseFromParent();
1339bool AVRExpandPseudo::expand<AVR::STDSPQRr>(
Block &
MBB, BlockIt
MBBI) {
1344 assert(
MI.getOperand(0).getReg() == AVR::SP &&
1345 "SP is expected as base pointer");
1348 "unexpected STDSPQRr pseudo instruction");
1351 MI.setDesc(
TII->get(AVR::STDPtrQRr));
1352 MI.getOperand(0).setReg(AVR::R29R28);
1358bool AVRExpandPseudo::expand<AVR::STDWSPQRr>(
Block &
MBB, BlockIt
MBBI) {
1363 assert(
MI.getOperand(0).getReg() == AVR::SP &&
1364 "SP is expected as base pointer");
1367 "unexpected STDWSPQRr pseudo instruction");
1370 MI.setDesc(
TII->get(AVR::STDWPtrQRr));
1371 MI.getOperand(0).setReg(AVR::R29R28);
1377bool AVRExpandPseudo::expand<AVR::INWRdA>(
Block &
MBB, BlockIt
MBBI) {
1380 unsigned Imm =
MI.getOperand(1).getImm();
1382 bool DstIsDead =
MI.getOperand(0).isDead();
1383 unsigned OpLo = AVR::INRdA;
1384 unsigned OpHi = AVR::INRdA;
1385 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1389 assert(Imm <= 62 &&
"Address is out of range");
1401 MIBLO.setMemRefs(
MI.memoperands());
1402 MIBHI.setMemRefs(
MI.memoperands());
1404 MI.eraseFromParent();
1409bool AVRExpandPseudo::expand<AVR::OUTWARr>(
Block &
MBB, BlockIt
MBBI) {
1413 unsigned Imm =
MI.getOperand(0).getImm();
1415 bool SrcIsKill =
MI.getOperand(1).isKill();
1416 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1420 assert(Imm <= 62 &&
"Address is out of range");
1424 auto MIBHI = buildMI(
MBB,
MBBI, AVR::OUTARr)
1425 .addImm(STI.hasLowByteFirst() ? Imm : Imm + 1)
1426 .addReg(STI.hasLowByteFirst() ? SrcLoReg : SrcHiReg,
1428 auto MIBLO = buildMI(
MBB,
MBBI, AVR::OUTARr)
1429 .addImm(STI.hasLowByteFirst() ? Imm + 1 : Imm)
1430 .addReg(STI.hasLowByteFirst() ? SrcHiReg : SrcLoReg,
1433 MIBLO.setMemRefs(
MI.memoperands());
1434 MIBHI.setMemRefs(
MI.memoperands());
1436 MI.eraseFromParent();
1441bool AVRExpandPseudo::expand<AVR::PUSHWRr>(
Block &
MBB, BlockIt
MBBI) {
1445 bool SrcIsKill =
MI.getOperand(0).isKill();
1446 unsigned Flags =
MI.getFlags();
1447 unsigned OpLo = AVR::PUSHRr;
1448 unsigned OpHi = AVR::PUSHRr;
1449 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1461 MI.eraseFromParent();
1466bool AVRExpandPseudo::expand<AVR::POPWRd>(
Block &
MBB, BlockIt
MBBI) {
1470 unsigned Flags =
MI.getFlags();
1471 unsigned OpLo = AVR::POPRd;
1472 unsigned OpHi = AVR::POPRd;
1473 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1475 buildMI(
MBB,
MBBI, OpHi, DstHiReg).setMIFlags(Flags);
1476 buildMI(
MBB,
MBBI, OpLo, DstLoReg).setMIFlags(Flags);
1478 MI.eraseFromParent();
1482bool AVRExpandPseudo::expandROLBRd(
Block &
MBB, BlockIt
MBBI) {
1490 unsigned OpShift, OpCarry;
1492 Register ZeroReg =
MI.getOperand(3).getReg();
1493 bool DstIsDead =
MI.getOperand(0).isDead();
1494 bool DstIsKill =
MI.getOperand(1).isKill();
1495 OpShift = AVR::ADDRdRr;
1496 OpCarry = AVR::ADCRdRr;
1508 auto MIB = buildMI(
MBB,
MBBI, OpCarry)
1513 MIB->getOperand(3).setIsDead();
1514 MIB->getOperand(4).setIsKill();
1516 MI.eraseFromParent();
1521bool AVRExpandPseudo::expand<AVR::ROLBRdR1>(
Block &
MBB, BlockIt
MBBI) {
1522 return expandROLBRd(
MBB,
MBBI);
1526bool AVRExpandPseudo::expand<AVR::ROLBRdR17>(
Block &
MBB, BlockIt
MBBI) {
1527 return expandROLBRd(
MBB,
MBBI);
1531bool AVRExpandPseudo::expand<AVR::RORBRd>(
Block &
MBB, BlockIt
MBBI) {
1546 buildMI(
MBB,
MBBI, AVR::BST).addReg(DstReg).addImm(0);
1549 buildMI(
MBB,
MBBI, AVR::RORRd, DstReg).addReg(DstReg);
1552 buildMI(
MBB,
MBBI, AVR::BLD, DstReg).addReg(DstReg).addImm(7);
1554 MI.eraseFromParent();
1559bool AVRExpandPseudo::expand<AVR::LSLWRd>(
Block &
MBB, BlockIt
MBBI) {
1563 bool DstIsDead =
MI.getOperand(0).isDead();
1564 bool DstIsKill =
MI.getOperand(1).isKill();
1565 bool ImpIsDead =
MI.getOperand(2).isDead();
1566 unsigned OpLo = AVR::ADDRdRr;
1567 unsigned OpHi = AVR::ADCRdRr;
1568 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1583 MIBHI->getOperand(3).setIsDead();
1586 MIBHI->getOperand(4).setIsKill();
1588 MI.eraseFromParent();
1593bool AVRExpandPseudo::expand<AVR::LSLWHiRd>(
Block &
MBB, BlockIt
MBBI) {
1597 bool DstIsDead =
MI.getOperand(0).isDead();
1598 bool DstIsKill =
MI.getOperand(1).isKill();
1599 bool ImpIsDead =
MI.getOperand(2).isDead();
1600 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1604 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
1610 MILSL->getOperand(3).setIsDead();
1612 MI.eraseFromParent();
1616bool AVRExpandPseudo::expandLSLW4Rd(
Block &
MBB, BlockIt
MBBI) {
1620 bool DstIsDead =
MI.getOperand(0).isDead();
1621 bool DstIsKill =
MI.getOperand(1).isKill();
1622 bool ImpIsDead =
MI.getOperand(3).isDead();
1623 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1627 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1630 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1636 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1641 MI0->getOperand(3).setIsDead();
1645 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1650 MI1->getOperand(3).setIsDead();
1654 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1659 MI2->getOperand(3).setIsDead();
1663 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1668 MI3->getOperand(3).setIsDead();
1670 MI.eraseFromParent();
1674bool AVRExpandPseudo::expandLSLW8Rd(
Block &
MBB, BlockIt
MBBI) {
1678 bool DstIsDead =
MI.getOperand(0).isDead();
1679 bool DstIsKill =
MI.getOperand(1).isKill();
1680 bool ImpIsDead =
MI.getOperand(3).isDead();
1681 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1684 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1690 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1695 MIBLO->getOperand(3).setIsDead();
1697 MI.eraseFromParent();
1701bool AVRExpandPseudo::expandLSLW12Rd(
Block &
MBB, BlockIt
MBBI) {
1705 bool DstIsDead =
MI.getOperand(0).isDead();
1706 bool DstIsKill =
MI.getOperand(1).isKill();
1707 bool ImpIsDead =
MI.getOperand(3).isDead();
1708 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1711 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1716 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1722 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1727 MI0->getOperand(3).setIsDead();
1731 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1736 MI1->getOperand(3).setIsDead();
1738 MI.eraseFromParent();
1743bool AVRExpandPseudo::expand<AVR::LSLWNRd>(
Block &
MBB, BlockIt
MBBI) {
1745 unsigned Imm =
MI.getOperand(2).getImm();
1748 return expandLSLW4Rd(
MBB,
MBBI);
1750 return expandLSLW8Rd(
MBB,
MBBI);
1752 return expandLSLW12Rd(
MBB,
MBBI);
1760bool AVRExpandPseudo::expand<AVR::LSRWRd>(
Block &
MBB, BlockIt
MBBI) {
1764 bool DstIsDead =
MI.getOperand(0).isDead();
1765 bool DstIsKill =
MI.getOperand(1).isKill();
1766 bool ImpIsDead =
MI.getOperand(2).isDead();
1767 unsigned OpLo = AVR::RORRd;
1768 unsigned OpHi = AVR::LSRRd;
1769 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1782 MIBLO->getOperand(2).setIsDead();
1785 MIBLO->getOperand(3).setIsKill();
1787 MI.eraseFromParent();
1792bool AVRExpandPseudo::expand<AVR::LSRWLoRd>(
Block &
MBB, BlockIt
MBBI) {
1796 bool DstIsDead =
MI.getOperand(0).isDead();
1797 bool DstIsKill =
MI.getOperand(1).isKill();
1798 bool ImpIsDead =
MI.getOperand(2).isDead();
1799 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1803 buildMI(
MBB,
MBBI, AVR::LSRRd)
1808 MILSR->getOperand(2).setIsDead();
1810 MI.eraseFromParent();
1814bool AVRExpandPseudo::expandLSRW4Rd(
Block &
MBB, BlockIt
MBBI) {
1818 bool DstIsDead =
MI.getOperand(0).isDead();
1819 bool DstIsKill =
MI.getOperand(1).isKill();
1820 bool ImpIsDead =
MI.getOperand(3).isDead();
1821 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1825 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1828 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1834 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1839 MI0->getOperand(3).setIsDead();
1843 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1848 MI1->getOperand(3).setIsDead();
1852 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1857 MI2->getOperand(3).setIsDead();
1861 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1866 MI3->getOperand(3).setIsDead();
1868 MI.eraseFromParent();
1872bool AVRExpandPseudo::expandLSRW8Rd(
Block &
MBB, BlockIt
MBBI) {
1876 bool DstIsDead =
MI.getOperand(0).isDead();
1877 bool DstIsKill =
MI.getOperand(1).isKill();
1878 bool ImpIsDead =
MI.getOperand(3).isDead();
1879 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1882 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1888 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1893 MIBHI->getOperand(3).setIsDead();
1895 MI.eraseFromParent();
1899bool AVRExpandPseudo::expandLSRW12Rd(
Block &
MBB, BlockIt
MBBI) {
1903 bool DstIsDead =
MI.getOperand(0).isDead();
1904 bool DstIsKill =
MI.getOperand(1).isKill();
1905 bool ImpIsDead =
MI.getOperand(3).isDead();
1906 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1909 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1914 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1920 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1925 MI0->getOperand(3).setIsDead();
1929 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1934 MIBHI->getOperand(3).setIsDead();
1936 MI.eraseFromParent();
1941bool AVRExpandPseudo::expand<AVR::LSRWNRd>(
Block &
MBB, BlockIt
MBBI) {
1943 unsigned Imm =
MI.getOperand(2).getImm();
1946 return expandLSRW4Rd(
MBB,
MBBI);
1948 return expandLSRW8Rd(
MBB,
MBBI);
1950 return expandLSRW12Rd(
MBB,
MBBI);
1958bool AVRExpandPseudo::expand<AVR::RORWRd>(
Block &
MBB, BlockIt
MBBI) {
1964bool AVRExpandPseudo::expand<AVR::ROLWRd>(
Block &
MBB, BlockIt
MBBI) {
1970bool AVRExpandPseudo::expand<AVR::ASRWRd>(
Block &
MBB, BlockIt
MBBI) {
1974 bool DstIsDead =
MI.getOperand(0).isDead();
1975 bool DstIsKill =
MI.getOperand(1).isKill();
1976 bool ImpIsDead =
MI.getOperand(2).isDead();
1977 unsigned OpLo = AVR::RORRd;
1978 unsigned OpHi = AVR::ASRRd;
1979 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1992 MIBLO->getOperand(2).setIsDead();
1995 MIBLO->getOperand(3).setIsKill();
1997 MI.eraseFromParent();
2002bool AVRExpandPseudo::expand<AVR::ASRWLoRd>(
Block &
MBB, BlockIt
MBBI) {
2006 bool DstIsDead =
MI.getOperand(0).isDead();
2007 bool DstIsKill =
MI.getOperand(1).isKill();
2008 bool ImpIsDead =
MI.getOperand(2).isDead();
2009 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2013 buildMI(
MBB,
MBBI, AVR::ASRRd)
2018 MIASR->getOperand(2).setIsDead();
2020 MI.eraseFromParent();
2024bool AVRExpandPseudo::expandASRW7Rd(
Block &
MBB, BlockIt
MBBI) {
2028 bool DstIsDead =
MI.getOperand(0).isDead();
2029 bool DstIsKill =
MI.getOperand(1).isKill();
2030 bool ImpIsDead =
MI.getOperand(3).isDead();
2031 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2039 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2045 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2050 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2057 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2063 MISBC->getOperand(3).setIsDead();
2065 MISBC->getOperand(4).setIsKill();
2067 MI.eraseFromParent();
2071bool AVRExpandPseudo::expandASRW8Rd(
Block &
MBB, BlockIt
MBBI) {
2075 bool DstIsDead =
MI.getOperand(0).isDead();
2076 bool DstIsKill =
MI.getOperand(1).isKill();
2077 bool ImpIsDead =
MI.getOperand(3).isDead();
2078 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2081 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2086 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2093 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2099 MIBHI->getOperand(3).setIsDead();
2101 MIBHI->getOperand(4).setIsKill();
2103 MI.eraseFromParent();
2106bool AVRExpandPseudo::expandASRW14Rd(
Block &
MBB, BlockIt
MBBI) {
2110 bool DstIsDead =
MI.getOperand(0).isDead();
2111 bool DstIsKill =
MI.getOperand(1).isKill();
2112 bool ImpIsDead =
MI.getOperand(3).isDead();
2113 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2122 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2128 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2134 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2140 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2146 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2152 MIROL->getOperand(3).setIsDead();
2154 MIROL->getOperand(4).setIsKill();
2156 MI.eraseFromParent();
2160bool AVRExpandPseudo::expandASRW15Rd(
Block &
MBB, BlockIt
MBBI) {
2164 bool DstIsDead =
MI.getOperand(0).isDead();
2165 bool ImpIsDead =
MI.getOperand(3).isDead();
2166 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2173 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2180 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2185 MISBC->getOperand(3).setIsDead();
2187 MISBC->getOperand(4).setIsKill();
2190 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2194 MI.eraseFromParent();
2199bool AVRExpandPseudo::expand<AVR::ASRWNRd>(
Block &
MBB, BlockIt
MBBI) {
2201 unsigned Imm =
MI.getOperand(2).getImm();
2204 return expandASRW7Rd(
MBB,
MBBI);
2206 return expandASRW8Rd(
MBB,
MBBI);
2208 return expandASRW14Rd(
MBB,
MBBI);
2210 return expandASRW15Rd(
MBB,
MBBI);
2217bool AVRExpandPseudo::expandLSLB7Rd(
Block &
MBB, BlockIt
MBBI) {
2220 bool DstIsDead =
MI.getOperand(0).isDead();
2221 bool DstIsKill =
MI.getOperand(1).isKill();
2222 bool ImpIsDead =
MI.getOperand(3).isDead();
2228 buildMI(
MBB,
MBBI, AVR::RORRd)
2234 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2240 buildMI(
MBB,
MBBI, AVR::RORRd)
2245 MIRRC->getOperand(2).setIsDead();
2248 MIRRC->getOperand(3).setIsKill();
2250 MI.eraseFromParent();
2255bool AVRExpandPseudo::expand<AVR::LSLBNRd>(
Block &
MBB, BlockIt
MBBI) {
2257 unsigned Imm =
MI.getOperand(2).getImm();
2260 return expandLSLB7Rd(
MBB,
MBBI);
2267bool AVRExpandPseudo::expandLSRB7Rd(
Block &
MBB, BlockIt
MBBI) {
2270 bool DstIsDead =
MI.getOperand(0).isDead();
2271 bool DstIsKill =
MI.getOperand(1).isKill();
2272 bool ImpIsDead =
MI.getOperand(3).isDead();
2278 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2285 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2291 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2297 MIRRC->getOperand(3).setIsDead();
2300 MIRRC->getOperand(4).setIsKill();
2302 MI.eraseFromParent();
2307bool AVRExpandPseudo::expand<AVR::LSRBNRd>(
Block &
MBB, BlockIt
MBBI) {
2309 unsigned Imm =
MI.getOperand(2).getImm();
2312 return expandLSRB7Rd(
MBB,
MBBI);
2319bool AVRExpandPseudo::expandASRB6Rd(
Block &
MBB, BlockIt
MBBI) {
2322 bool DstIsDead =
MI.getOperand(0).isDead();
2323 bool DstIsKill =
MI.getOperand(1).isKill();
2336 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2341 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2353 MI.eraseFromParent();
2357bool AVRExpandPseudo::expandASRB7Rd(
Block &
MBB, BlockIt
MBBI) {
2360 bool DstIsDead =
MI.getOperand(0).isDead();
2361 bool DstIsKill =
MI.getOperand(1).isKill();
2362 bool ImpIsDead =
MI.getOperand(3).isDead();
2367 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2373 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2379 MIRRC->getOperand(3).setIsDead();
2382 MIRRC->getOperand(4).setIsKill();
2384 MI.eraseFromParent();
2389bool AVRExpandPseudo::expand<AVR::ASRBNRd>(
Block &
MBB, BlockIt
MBBI) {
2391 unsigned Imm =
MI.getOperand(2).getImm();
2394 return expandASRB6Rd(
MBB,
MBBI);
2396 return expandASRB7Rd(
MBB,
MBBI);
2403template <>
bool AVRExpandPseudo::expand<AVR::SEXT>(
Block &
MBB, BlockIt
MBBI) {
2421 bool DstIsDead =
MI.getOperand(0).isDead();
2422 bool SrcIsKill =
MI.getOperand(1).isKill();
2423 bool ImpIsDead =
MI.getOperand(2).isDead();
2424 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2426 if (SrcReg != DstLoReg)
2427 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2431 if (SrcReg != DstHiReg) {
2432 auto MOV = buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2435 if (SrcReg != DstLoReg && SrcIsKill)
2436 MOV->getOperand(1).setIsKill();
2439 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2445 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2451 SBC->getOperand(3).setIsDead();
2454 SBC->getOperand(4).setIsKill();
2456 MI.eraseFromParent();
2460template <>
bool AVRExpandPseudo::expand<AVR::ZEXT>(
Block &
MBB, BlockIt
MBBI) {
2473 bool DstIsDead =
MI.getOperand(0).isDead();
2474 bool SrcIsKill =
MI.getOperand(1).isKill();
2475 bool ImpIsDead =
MI.getOperand(2).isDead();
2476 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2478 if (SrcReg != DstLoReg) {
2479 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2485 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2491 EOR->getOperand(3).setIsDead();
2493 MI.eraseFromParent();
2498bool AVRExpandPseudo::expand<AVR::SPREAD>(
Block &
MBB, BlockIt
MBBI) {
2502 bool DstIsDead =
MI.getOperand(0).isDead();
2503 unsigned Flags =
MI.getFlags();
2504 unsigned OpLo = AVR::INRdA;
2505 unsigned OpHi = AVR::INRdA;
2506 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2520 MI.eraseFromParent();
2525bool AVRExpandPseudo::expand<AVR::SPWRITE>(
Block &
MBB, BlockIt
MBBI) {
2530 bool SrcIsKill =
MI.getOperand(1).isKill();
2531 unsigned Flags =
MI.getFlags();
2532 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
2540 buildMI(
MBB,
MBBI, AVR::OUTARr)
2545 buildMI(
MBB,
MBBI, AVR::OUTARr)
2552 buildMI(
MBB,
MBBI, AVR::INRdA)
2557 buildMI(
MBB,
MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
2560 buildMI(
MBB,
MBBI, AVR::OUTARr)
2565 buildMI(
MBB,
MBBI, AVR::OUTARr)
2570 buildMI(
MBB,
MBBI, AVR::OUTARr)
2576 MI.eraseFromParent();
2580bool AVRExpandPseudo::expandMI(
Block &
MBB, BlockIt
MBBI) {
2582 int Opcode =
MBBI->getOpcode();
2586 return expand<Op>(MBB, MI)
2618 EXPAND(AVR::AtomicLoad8);
2619 EXPAND(AVR::AtomicLoad16);
2620 EXPAND(AVR::AtomicStore8);
2621 EXPAND(AVR::AtomicStore16);
2622 EXPAND(AVR::AtomicFence);
2666 return new AVRExpandPseudo();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator MBBI
#define AVR_EXPAND_PSEUDO_NAME
static Expected< BitVector > expand(StringRef S, StringRef Original)
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Utilities relating to AVR registers.
A specific AVR target MCU.
Register getTmpRegister() const
unsigned getELFArch() const
Gets the ELF architecture for the e_flags field of an ELF object file.
const TargetFrameLowering * getFrameLowering() const override
int getIORegRAMPZ() const
Get I/O register addresses.
const AVRInstrInfo * getInstrInfo() const override
const AVRRegisterInfo * getRegisterInfo() const override
The address of a basic block.
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
static MachineOperand CreateBA(const BlockAddress *BA, int64_t Offset, unsigned TargetFlags=0)
@ MO_Immediate
Immediate operand.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
StringRef - Represent a constant reference to a string, i.e.
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
TargetInstrInfo - Interface to description of machine instruction set.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MO_HI
On a symbol operand, this represents the hi part.
@ MO_NEG
On a symbol operand, this represents it has to be negated.
@ MO_LO
On a symbol operand, this represents the lo part.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Define
Register definition.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getDeadRegState(bool B)
FunctionPass * createAVRExpandPseudoPass()
unsigned getUndefRegState(bool B)
unsigned getKillRegState(bool B)