28#define AVR_EXPAND_PSEUDO_NAME "AVR pseudo instruction expansion pass"
65 return MBB.getParent()->getRegInfo();
68 bool expandArith(
unsigned OpLo,
unsigned OpHi,
Block &
MBB, BlockIt
MBBI);
71 bool isLogicImmOpRedundant(
unsigned Op,
unsigned ImmVal)
const;
72 bool isLogicRegOpUndef(
unsigned Op,
unsigned ImmVal)
const;
74 template <
typename Func>
bool expandAtomic(
Block &
MBB, BlockIt
MBBI, Func f);
76 template <
typename Func>
77 bool expandAtomicBinaryOp(
unsigned Opcode,
Block &
MBB, BlockIt
MBBI, Func f);
79 bool expandAtomicBinaryOp(
unsigned Opcode,
Block &
MBB, BlockIt
MBBI);
100 bool expandLPMWELPMW(
Block &
MBB, BlockIt
MBBI,
bool IsELPM);
102 bool expandLPMBELPMB(
Block &
MBB, BlockIt
MBBI,
bool IsELPM);
107char AVRExpandPseudo::ID = 0;
114 BlockIt NMBBI = std::next(
MBBI);
130 bool ContinueExpanding =
true;
131 unsigned ExpandCount = 0;
135 assert(ExpandCount < 10 &&
"pseudo expand limit reached");
138 bool BlockModified = expandMBB(
MBB);
142 ContinueExpanding = BlockModified;
143 }
while (ContinueExpanding);
149bool AVRExpandPseudo::expandArith(
unsigned OpLo,
unsigned OpHi,
Block &
MBB,
152 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
155 bool DstIsDead =
MI.getOperand(0).isDead();
156 bool DstIsKill =
MI.getOperand(1).isKill();
157 bool SrcIsKill =
MI.getOperand(2).isKill();
158 bool ImpIsDead =
MI.getOperand(3).isDead();
159 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
160 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
174 MIBHI->getOperand(3).setIsDead();
177 MIBHI->getOperand(4).setIsKill();
179 MI.eraseFromParent();
183bool AVRExpandPseudo::expandLogic(
unsigned Op,
Block &
MBB, BlockIt
MBBI) {
185 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
188 bool DstIsDead =
MI.getOperand(0).isDead();
189 bool DstIsKill =
MI.getOperand(1).isKill();
190 bool SrcIsKill =
MI.getOperand(2).isKill();
191 bool ImpIsDead =
MI.getOperand(3).isDead();
192 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
193 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
202 MIBLO->getOperand(3).setIsDead();
211 MIBHI->getOperand(3).setIsDead();
213 MI.eraseFromParent();
217bool AVRExpandPseudo::isLogicImmOpRedundant(
unsigned Op,
218 unsigned ImmVal)
const {
221 if (
Op == AVR::ANDIRdK && ImmVal == 0xff)
225 if (
Op == AVR::ORIRdK && ImmVal == 0x0)
231bool AVRExpandPseudo::isLogicRegOpUndef(
unsigned Op,
unsigned ImmVal)
const {
233 if (
Op == AVR::ANDIRdK && ImmVal == 0x00)
237 if (
Op == AVR::ORIRdK && ImmVal == 0xff)
243bool AVRExpandPseudo::expandLogicImm(
unsigned Op,
Block &
MBB, BlockIt
MBBI) {
247 bool DstIsDead =
MI.getOperand(0).isDead();
248 bool SrcIsKill =
MI.getOperand(1).isKill();
249 bool ImpIsDead =
MI.getOperand(3).isDead();
250 unsigned Imm =
MI.getOperand(2).getImm();
251 unsigned Lo8 =
Imm & 0xff;
252 unsigned Hi8 = (
Imm >> 8) & 0xff;
253 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
255 if (!isLogicImmOpRedundant(
Op, Lo8)) {
263 MIBLO->getOperand(3).setIsDead();
265 if (isLogicRegOpUndef(
Op, Lo8))
266 MIBLO->getOperand(1).setIsUndef(
true);
269 if (!isLogicImmOpRedundant(
Op, Hi8)) {
277 MIBHI->getOperand(3).setIsDead();
279 if (isLogicRegOpUndef(
Op, Hi8))
280 MIBHI->getOperand(1).setIsUndef(
true);
283 MI.eraseFromParent();
288bool AVRExpandPseudo::expand<AVR::ADDWRdRr>(
Block &
MBB, BlockIt
MBBI) {
289 return expandArith(AVR::ADDRdRr, AVR::ADCRdRr,
MBB,
MBBI);
293bool AVRExpandPseudo::expand<AVR::ADCWRdRr>(
Block &
MBB, BlockIt
MBBI) {
294 return expandArith(AVR::ADCRdRr, AVR::ADCRdRr,
MBB,
MBBI);
298bool AVRExpandPseudo::expand<AVR::ADIWRdKP>(
Block &
MBB, BlockIt
MBBI) {
303 int64_t
Imm =
MI.getOperand(2).getImm();
306 if (SrcReg != DstReg) {
307 TII->copyPhysReg(
MBB,
MI,
MI.getDebugLoc(), DstReg, SrcReg,
false,
false,
312 AVR::IWREGSRegClass.contains(DstReg)) {
313 Opcode = AVR::ADIWRdK;
315 Opcode = AVR::SUBIWRdK;
319 buildMI(
MBB,
MI, Opcode)
325 MI.eraseFromParent();
330bool AVRExpandPseudo::expand<AVR::SUBWRdRr>(
Block &
MBB, BlockIt
MBBI) {
331 return expandArith(AVR::SUBRdRr, AVR::SBCRdRr,
MBB,
MBBI);
335bool AVRExpandPseudo::expand<AVR::SUBIWRdK>(
Block &
MBB, BlockIt
MBBI) {
339 bool DstIsDead =
MI.getOperand(0).isDead();
340 bool SrcIsKill =
MI.getOperand(1).isKill();
341 bool ImpIsDead =
MI.getOperand(3).isDead();
342 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
345 buildMI(
MBB,
MBBI, AVR::SUBIRdK)
350 buildMI(
MBB,
MBBI, AVR::SBCIRdK)
354 switch (
MI.getOperand(2).getType()) {
357 int64_t Offs =
MI.getOperand(2).getOffset();
358 unsigned TF =
MI.getOperand(2).getTargetFlags();
364 unsigned Imm =
MI.getOperand(2).getImm();
365 MIBLO.addImm(
Imm & 0xff);
366 MIBHI.addImm((
Imm >> 8) & 0xff);
374 MIBHI->getOperand(3).setIsDead();
377 MIBHI->getOperand(4).setIsKill();
379 MI.eraseFromParent();
384bool AVRExpandPseudo::expand<AVR::SBCWRdRr>(
Block &
MBB, BlockIt
MBBI) {
385 return expandArith(AVR::SBCRdRr, AVR::SBCRdRr,
MBB,
MBBI);
389bool AVRExpandPseudo::expand<AVR::SBCIWRdK>(
Block &
MBB, BlockIt
MBBI) {
393 bool DstIsDead =
MI.getOperand(0).isDead();
394 bool SrcIsKill =
MI.getOperand(1).isKill();
395 bool ImpIsDead =
MI.getOperand(3).isDead();
396 unsigned Imm =
MI.getOperand(2).getImm();
397 unsigned Lo8 =
Imm & 0xff;
398 unsigned Hi8 = (
Imm >> 8) & 0xff;
399 unsigned OpLo = AVR::SBCIRdK;
400 unsigned OpHi = AVR::SBCIRdK;
401 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
410 MIBLO->getOperand(4).setIsKill();
419 MIBHI->getOperand(3).setIsDead();
422 MIBHI->getOperand(4).setIsKill();
424 MI.eraseFromParent();
429bool AVRExpandPseudo::expand<AVR::ANDWRdRr>(
Block &
MBB, BlockIt
MBBI) {
430 return expandLogic(AVR::ANDRdRr,
MBB,
MBBI);
434bool AVRExpandPseudo::expand<AVR::ANDIWRdK>(
Block &
MBB, BlockIt
MBBI) {
435 return expandLogicImm(AVR::ANDIRdK,
MBB,
MBBI);
439bool AVRExpandPseudo::expand<AVR::ORWRdRr>(
Block &
MBB, BlockIt
MBBI) {
440 return expandLogic(AVR::ORRdRr,
MBB,
MBBI);
444bool AVRExpandPseudo::expand<AVR::ORIWRdK>(
Block &
MBB, BlockIt
MBBI) {
445 return expandLogicImm(AVR::ORIRdK,
MBB,
MBBI);
449bool AVRExpandPseudo::expand<AVR::EORWRdRr>(
Block &
MBB, BlockIt
MBBI) {
450 return expandLogic(AVR::EORRdRr,
MBB,
MBBI);
454bool AVRExpandPseudo::expand<AVR::COMWRd>(
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 unsigned OpLo = AVR::COMRd;
462 unsigned OpHi = AVR::COMRd;
463 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
471 MIBLO->getOperand(2).setIsDead();
479 MIBHI->getOperand(2).setIsDead();
481 MI.eraseFromParent();
486bool AVRExpandPseudo::expand<AVR::NEGWRd>(
Block &
MBB, BlockIt
MBBI) {
491 bool DstIsDead =
MI.getOperand(0).isDead();
492 bool DstIsKill =
MI.getOperand(1).isKill();
493 bool ImpIsDead =
MI.getOperand(2).isDead();
494 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
502 MIBHI->getOperand(2).setIsDead();
511 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
516 MISBCI->getOperand(3).setIsDead();
518 MISBCI->getOperand(4).setIsKill();
520 MI.eraseFromParent();
525bool AVRExpandPseudo::expand<AVR::CPWRdRr>(
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::CPRdRr;
534 unsigned OpHi = AVR::CPCRdRr;
535 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
536 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
543 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
548 MIBHI->getOperand(2).setIsDead();
551 MIBHI->getOperand(3).setIsKill();
553 MI.eraseFromParent();
558bool AVRExpandPseudo::expand<AVR::CPCWRdRr>(
Block &
MBB, BlockIt
MBBI) {
560 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
563 bool DstIsKill =
MI.getOperand(0).isKill();
564 bool SrcIsKill =
MI.getOperand(1).isKill();
565 bool ImpIsDead =
MI.getOperand(2).isDead();
566 unsigned OpLo = AVR::CPCRdRr;
567 unsigned OpHi = AVR::CPCRdRr;
568 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
569 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
571 auto MIBLO = buildMI(
MBB,
MBBI, OpLo)
576 MIBLO->getOperand(3).setIsKill();
578 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
583 MIBHI->getOperand(2).setIsDead();
586 MIBHI->getOperand(3).setIsKill();
588 MI.eraseFromParent();
593bool AVRExpandPseudo::expand<AVR::LDIWRdK>(
Block &
MBB, BlockIt
MBBI) {
597 bool DstIsDead =
MI.getOperand(0).isDead();
598 unsigned OpLo = AVR::LDIRdK;
599 unsigned OpHi = AVR::LDIRdK;
600 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
610 switch (
MI.getOperand(1).getType()) {
613 int64_t Offs =
MI.getOperand(1).getOffset();
614 unsigned TF =
MI.getOperand(1).getTargetFlags();
622 unsigned TF =
MI.getOperand(1).getTargetFlags();
629 unsigned Imm =
MI.getOperand(1).getImm();
631 MIBLO.addImm(
Imm & 0xff);
632 MIBHI.addImm((
Imm >> 8) & 0xff);
639 MI.eraseFromParent();
644bool AVRExpandPseudo::expand<AVR::LDSWRdK>(
Block &
MBB, BlockIt
MBBI) {
648 bool DstIsDead =
MI.getOperand(0).isDead();
649 unsigned OpLo = AVR::LDSRdK;
650 unsigned OpHi = AVR::LDSRdK;
651 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
661 switch (
MI.getOperand(1).getType()) {
664 int64_t Offs =
MI.getOperand(1).getOffset();
665 unsigned TF =
MI.getOperand(1).getTargetFlags();
667 MIBLO.addGlobalAddress(GV, Offs, TF);
668 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
672 unsigned Imm =
MI.getOperand(1).getImm();
675 MIBHI.addImm(
Imm + 1);
682 MIBLO.setMemRefs(
MI.memoperands());
683 MIBHI.setMemRefs(
MI.memoperands());
685 MI.eraseFromParent();
690bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(
Block &
MBB, BlockIt
MBBI) {
694 bool DstIsKill =
MI.getOperand(0).isKill();
695 bool SrcIsKill =
MI.getOperand(1).isKill();
700 assert(DstReg != SrcReg &&
"Dst and Src registers are the same!");
702 if (STI.hasTinyEncoding()) {
705 buildMI(
MBB,
MBBI, AVR::LDDWRdPtrQ)
709 .setMemRefs(
MI.memoperands());
713 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
716 buildMI(
MBB,
MBBI, AVR::LDRdPtr)
719 .setMemRefs(
MI.memoperands());
722 buildMI(
MBB,
MBBI, AVR::LDDRdPtrQ)
726 .setMemRefs(
MI.memoperands());
729 MI.eraseFromParent();
734bool AVRExpandPseudo::expand<AVR::LDWRdPtrPi>(
Block &
MBB, BlockIt
MBBI) {
739 bool DstIsDead =
MI.getOperand(0).isDead();
740 bool SrcIsDead =
MI.getOperand(1).isKill();
741 unsigned OpLo = AVR::LDRdPtrPi;
742 unsigned OpHi = AVR::LDRdPtrPi;
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::LDWRdPtrPd>(
Block &
MBB, BlockIt
MBBI) {
772 bool DstIsDead =
MI.getOperand(0).isDead();
773 bool SrcIsDead =
MI.getOperand(1).isKill();
774 unsigned OpLo = AVR::LDRdPtrPd;
775 unsigned OpHi = AVR::LDRdPtrPd;
776 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
778 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
792 MIBLO.setMemRefs(
MI.memoperands());
793 MIBHI.setMemRefs(
MI.memoperands());
795 MI.eraseFromParent();
800bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(
Block &
MBB, BlockIt
MBBI) {
804 unsigned Imm =
MI.getOperand(2).getImm();
805 bool DstIsKill =
MI.getOperand(0).isKill();
806 bool SrcIsKill =
MI.getOperand(1).isKill();
811 assert(
Imm <= 62 &&
"Offset is out of range");
815 assert(DstReg != SrcReg &&
"Dst and Src registers are the same!");
817 if (STI.hasTinyEncoding()) {
825 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, SrcReg)
827 .addImm(0x10000 -
Imm);
832 buildMI(
MBB,
MBBI, AVR::LDWRdPtrPi)
836 .setMemRefs(
MI.memoperands());
842 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, SrcReg).addReg(SrcReg).addImm(
Imm + 2);
846 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
849 buildMI(
MBB,
MBBI, AVR::LDDRdPtrQ)
853 .setMemRefs(
MI.memoperands());
856 buildMI(
MBB,
MBBI, AVR::LDDRdPtrQ)
860 .setMemRefs(
MI.memoperands());
863 MI.eraseFromParent();
867bool AVRExpandPseudo::expandLPMWELPMW(
Block &
MBB, BlockIt
MBBI,
bool IsELPM) {
873 bool SrcIsKill =
MI.getOperand(1).isKill();
875 bool IsLPMRn = IsELPM ? STI.hasELPMX() : STI.hasLPMX();
877 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
878 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
888 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
891 unsigned OpLo = IsELPM ? AVR::ELPMRdZPi : AVR::LPMRdZPi;
892 unsigned OpHi = IsELPM ? AVR::ELPMRdZ : AVR::LPMRdZ;
894 auto MIBLO = buildMI(
MBB,
MBBI, OpLo)
898 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
901 MIBLO.setMemRefs(
MI.memoperands());
902 MIBHI.setMemRefs(
MI.memoperands());
904 unsigned Opc = IsELPM ? AVR::ELPM : AVR::LPM;
907 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
910 MIBLO.setMemRefs(
MI.memoperands());
912 if (STI.hasADDSUBIW()) {
914 auto MIINC = buildMI(
MBB,
MBBI, AVR::ADIWRdK)
918 MIINC->getOperand(3).setIsDead();
922 buildMI(
MBB,
MBBI, AVR::SUBIRdK)
926 auto MIZHI = buildMI(
MBB,
MBBI, AVR::SBCIRdK)
930 MIZHI->getOperand(3).setIsDead();
931 MIZHI->getOperand(4).setIsKill();
935 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
938 MIBHI.setMemRefs(
MI.memoperands());
943 if (STI.hasADDSUBIW()) {
945 auto MIDEC = buildMI(
MBB,
MBBI, AVR::SBIWRdK)
949 MIDEC->getOperand(3).setIsDead();
953 buildMI(
MBB,
MBBI, AVR::SUBIRdK)
957 auto MIZHI = buildMI(
MBB,
MBBI, AVR::SBCIRdK)
961 MIZHI->getOperand(3).setIsDead();
962 MIZHI->getOperand(4).setIsKill();
966 MI.eraseFromParent();
971bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(
Block &
MBB, BlockIt
MBBI) {
972 return expandLPMWELPMW(
MBB,
MBBI,
false);
976bool AVRExpandPseudo::expand<AVR::ELPMWRdZ>(
Block &
MBB, BlockIt
MBBI) {
977 return expandLPMWELPMW(
MBB,
MBBI,
true);
980bool AVRExpandPseudo::expandLPMBELPMB(
Block &
MBB, BlockIt
MBBI,
bool IsELPM) {
984 bool SrcIsKill =
MI.getOperand(1).isKill();
986 bool IsLPMRn = IsELPM ? STI.hasELPMX() : STI.hasLPMX();
996 unsigned Opc = IsELPM ? AVR::ELPMRdZ : AVR::LPMRdZ;
1000 MILB.setMemRefs(
MI.memoperands());
1004 unsigned Opc = IsELPM ? AVR::ELPM : AVR::LPM;
1006 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1009 MILB.setMemRefs(
MI.memoperands());
1012 MI.eraseFromParent();
1017bool AVRExpandPseudo::expand<AVR::ELPMBRdZ>(
Block &
MBB, BlockIt
MBBI) {
1018 return expandLPMBELPMB(
MBB,
MBBI,
true);
1022bool AVRExpandPseudo::expand<AVR::LPMBRdZ>(
Block &
MBB, BlockIt
MBBI) {
1023 return expandLPMBELPMB(
MBB,
MBBI,
false);
1027bool AVRExpandPseudo::expand<AVR::LPMWRdZPi>(
Block &
MBB, BlockIt
MBBI) {
1032bool AVRExpandPseudo::expand<AVR::ELPMBRdZPi>(
Block &
MBB, BlockIt
MBBI) {
1037bool AVRExpandPseudo::expand<AVR::ELPMWRdZPi>(
Block &
MBB, BlockIt
MBBI) {
1041template <
typename Func>
1042bool AVRExpandPseudo::expandAtomic(
Block &
MBB, BlockIt
MBBI, Func f) {
1047 buildMI(
MBB,
MBBI, AVR::INRdA)
1052 buildMI(
MBB,
MBBI, AVR::BCLRs).addImm(7);
1057 buildMI(
MBB,
MBBI, AVR::OUTARr)
1061 MI.eraseFromParent();
1065template <
typename Func>
1066bool AVRExpandPseudo::expandAtomicBinaryOp(
unsigned Opcode,
Block &
MBB,
1067 BlockIt
MBBI, Func f) {
1069 auto Op1 =
MI.getOperand(0);
1070 auto Op2 =
MI.getOperand(1);
1073 *buildMI(
MBB,
MBBI, Opcode).add(Op1).add(Op2).getInstr();
1078bool AVRExpandPseudo::expandAtomicBinaryOp(
unsigned Opcode,
Block &
MBB,
1084bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(
Block &
MBB, BlockIt
MBBI) {
1085 return expandAtomicBinaryOp(AVR::LDRdPtr,
MBB,
MBBI);
1089bool AVRExpandPseudo::expand<AVR::AtomicLoad16>(
Block &
MBB, BlockIt
MBBI) {
1090 return expandAtomicBinaryOp(AVR::LDWRdPtr,
MBB,
MBBI);
1094bool AVRExpandPseudo::expand<AVR::AtomicStore8>(
Block &
MBB, BlockIt
MBBI) {
1095 return expandAtomicBinaryOp(AVR::STPtrRr,
MBB,
MBBI);
1099bool AVRExpandPseudo::expand<AVR::AtomicStore16>(
Block &
MBB, BlockIt
MBBI) {
1100 return expandAtomicBinaryOp(AVR::STWPtrRr,
MBB,
MBBI);
1104bool AVRExpandPseudo::expand<AVR::AtomicFence>(
Block &
MBB, BlockIt
MBBI) {
1106 MBBI->eraseFromParent();
1111bool AVRExpandPseudo::expand<AVR::STSWKRr>(
Block &
MBB, BlockIt
MBBI) {
1116 bool SrcIsKill =
MI.getOperand(1).isKill();
1117 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1119 auto MIB0 = buildMI(
MBB,
MBBI, AVR::STSKRr);
1120 auto MIB1 = buildMI(
MBB,
MBBI, AVR::STSKRr);
1122 switch (
MI.getOperand(0).getType()) {
1125 int64_t Offs =
MI.getOperand(0).getOffset();
1126 unsigned TF =
MI.getOperand(0).getTargetFlags();
1128 if (STI.hasLowByteFirst()) {
1130 MIB0.addGlobalAddress(GV, Offs, TF);
1131 MIB1.addGlobalAddress(GV, Offs + 1, TF);
1134 MIB0.addGlobalAddress(GV, Offs + 1, TF);
1135 MIB1.addGlobalAddress(GV, Offs, TF);
1141 unsigned Imm =
MI.getOperand(0).getImm();
1143 if (STI.hasLowByteFirst()) {
1146 MIB1.addImm(
Imm + 1);
1149 MIB0.addImm(
Imm + 1);
1159 if (STI.hasLowByteFirst()) {
1162 .setMemRefs(
MI.memoperands());
1164 .setMemRefs(
MI.memoperands());
1168 .setMemRefs(
MI.memoperands());
1170 .setMemRefs(
MI.memoperands());
1173 MI.eraseFromParent();
1178bool AVRExpandPseudo::expand<AVR::STWPtrRr>(
Block &
MBB, BlockIt
MBBI) {
1182 bool DstIsKill =
MI.getOperand(0).isKill();
1183 bool DstIsUndef =
MI.getOperand(0).isUndef();
1184 bool SrcIsKill =
MI.getOperand(1).isKill();
1189 if (STI.hasTinyEncoding()) {
1192 buildMI(
MBB,
MBBI, AVR::STDWPtrQRr)
1197 .setMemRefs(
MI.memoperands());
1201 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1202 if (STI.hasLowByteFirst()) {
1203 buildMI(
MBB,
MBBI, AVR::STPtrRr)
1206 .setMemRefs(
MI.memoperands());
1207 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1211 .setMemRefs(
MI.memoperands());
1213 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1217 .setMemRefs(
MI.memoperands());
1218 buildMI(
MBB,
MBBI, AVR::STPtrRr)
1221 .setMemRefs(
MI.memoperands());
1225 MI.eraseFromParent();
1230bool AVRExpandPseudo::expand<AVR::STWPtrPiRr>(
Block &
MBB, BlockIt
MBBI) {
1235 unsigned Imm =
MI.getOperand(3).getImm();
1236 bool DstIsDead =
MI.getOperand(0).isDead();
1237 bool SrcIsKill =
MI.getOperand(2).isKill();
1238 unsigned OpLo = AVR::STPtrPiRr;
1239 unsigned OpHi = AVR::STPtrPiRr;
1240 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1242 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
1244 auto MIBLO = buildMI(
MBB,
MBBI, OpLo)
1257 MIBLO.setMemRefs(
MI.memoperands());
1258 MIBHI.setMemRefs(
MI.memoperands());
1260 MI.eraseFromParent();
1265bool AVRExpandPseudo::expand<AVR::STWPtrPdRr>(
Block &
MBB, BlockIt
MBBI) {
1270 unsigned Imm =
MI.getOperand(3).getImm();
1271 bool DstIsDead =
MI.getOperand(0).isDead();
1272 bool SrcIsKill =
MI.getOperand(2).isKill();
1273 unsigned OpLo = AVR::STPtrPdRr;
1274 unsigned OpHi = AVR::STPtrPdRr;
1275 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1277 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
1279 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
1292 MIBLO.setMemRefs(
MI.memoperands());
1293 MIBHI.setMemRefs(
MI.memoperands());
1295 MI.eraseFromParent();
1300bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(
Block &
MBB, BlockIt
MBBI) {
1305 bool DstIsKill =
MI.getOperand(0).isKill();
1306 unsigned Imm =
MI.getOperand(1).getImm();
1308 bool SrcIsKill =
MI.getOperand(2).isKill();
1314 if (
Imm >= 63 || STI.hasTinyEncoding()) {
1318 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, DstReg)
1320 .addImm(0x10000 -
Imm);
1324 buildMI(
MBB,
MBBI, AVR::STWPtrPiRr, DstReg)
1328 .setMemRefs(
MI.memoperands());
1334 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, DstReg)
1340 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1342 if (STI.hasLowByteFirst()) {
1343 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1347 .setMemRefs(
MI.memoperands());
1348 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1352 .setMemRefs(
MI.memoperands());
1354 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1358 .setMemRefs(
MI.memoperands());
1359 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1363 .setMemRefs(
MI.memoperands());
1367 MI.eraseFromParent();
1372bool AVRExpandPseudo::expand<AVR::STDSPQRr>(
Block &
MBB, BlockIt
MBBI) {
1377 assert(
MI.getOperand(0).getReg() == AVR::SP &&
1378 "SP is expected as base pointer");
1381 "unexpected STDSPQRr pseudo instruction");
1384 MI.setDesc(
TII->get(AVR::STDPtrQRr));
1385 MI.getOperand(0).setReg(AVR::R29R28);
1391bool AVRExpandPseudo::expand<AVR::STDWSPQRr>(
Block &
MBB, BlockIt
MBBI) {
1396 assert(
MI.getOperand(0).getReg() == AVR::SP &&
1397 "SP is expected as base pointer");
1400 "unexpected STDWSPQRr pseudo instruction");
1403 MI.setDesc(
TII->get(AVR::STDWPtrQRr));
1404 MI.getOperand(0).setReg(AVR::R29R28);
1410bool AVRExpandPseudo::expand<AVR::INWRdA>(
Block &
MBB, BlockIt
MBBI) {
1413 unsigned Imm =
MI.getOperand(1).getImm();
1415 bool DstIsDead =
MI.getOperand(0).isDead();
1416 unsigned OpLo = AVR::INRdA;
1417 unsigned OpHi = AVR::INRdA;
1418 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1422 assert(
Imm <= 62 &&
"Address is out of range");
1434 MIBLO.setMemRefs(
MI.memoperands());
1435 MIBHI.setMemRefs(
MI.memoperands());
1437 MI.eraseFromParent();
1442bool AVRExpandPseudo::expand<AVR::OUTWARr>(
Block &
MBB, BlockIt
MBBI) {
1446 unsigned Imm =
MI.getOperand(0).getImm();
1448 bool SrcIsKill =
MI.getOperand(1).isKill();
1449 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1453 assert(
Imm <= 62 &&
"Address is out of range");
1457 auto MIBHI = buildMI(
MBB,
MBBI, AVR::OUTARr)
1458 .addImm(STI.hasLowByteFirst() ?
Imm :
Imm + 1)
1459 .addReg(STI.hasLowByteFirst() ? SrcLoReg : SrcHiReg,
1461 auto MIBLO = buildMI(
MBB,
MBBI, AVR::OUTARr)
1462 .addImm(STI.hasLowByteFirst() ?
Imm + 1 :
Imm)
1463 .addReg(STI.hasLowByteFirst() ? SrcHiReg : SrcLoReg,
1466 MIBLO.setMemRefs(
MI.memoperands());
1467 MIBHI.setMemRefs(
MI.memoperands());
1469 MI.eraseFromParent();
1474bool AVRExpandPseudo::expand<AVR::PUSHWRr>(
Block &
MBB, BlockIt
MBBI) {
1478 bool SrcIsKill =
MI.getOperand(0).isKill();
1479 unsigned Flags =
MI.getFlags();
1480 unsigned OpLo = AVR::PUSHRr;
1481 unsigned OpHi = AVR::PUSHRr;
1482 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1494 MI.eraseFromParent();
1499bool AVRExpandPseudo::expand<AVR::POPWRd>(
Block &
MBB, BlockIt
MBBI) {
1503 unsigned Flags =
MI.getFlags();
1504 unsigned OpLo = AVR::POPRd;
1505 unsigned OpHi = AVR::POPRd;
1506 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1508 buildMI(
MBB,
MBBI, OpHi, DstHiReg).setMIFlags(Flags);
1509 buildMI(
MBB,
MBBI, OpLo, DstLoReg).setMIFlags(Flags);
1511 MI.eraseFromParent();
1515bool AVRExpandPseudo::expandROLBRd(
Block &
MBB, BlockIt
MBBI) {
1523 unsigned OpShift, OpCarry;
1525 Register ZeroReg =
MI.getOperand(3).getReg();
1526 bool DstIsDead =
MI.getOperand(0).isDead();
1527 bool DstIsKill =
MI.getOperand(1).isKill();
1528 OpShift = AVR::ADDRdRr;
1529 OpCarry = AVR::ADCRdRr;
1541 auto MIB = buildMI(
MBB,
MBBI, OpCarry)
1546 MIB->getOperand(3).setIsDead();
1547 MIB->getOperand(4).setIsKill();
1549 MI.eraseFromParent();
1554bool AVRExpandPseudo::expand<AVR::ROLBRdR1>(
Block &
MBB, BlockIt
MBBI) {
1555 return expandROLBRd(
MBB,
MBBI);
1559bool AVRExpandPseudo::expand<AVR::ROLBRdR17>(
Block &
MBB, BlockIt
MBBI) {
1560 return expandROLBRd(
MBB,
MBBI);
1564bool AVRExpandPseudo::expand<AVR::RORBRd>(
Block &
MBB, BlockIt
MBBI) {
1579 buildMI(
MBB,
MBBI, AVR::BST).addReg(DstReg).addImm(0);
1582 buildMI(
MBB,
MBBI, AVR::RORRd, DstReg).addReg(DstReg);
1585 buildMI(
MBB,
MBBI, AVR::BLD, DstReg).addReg(DstReg).addImm(7);
1587 MI.eraseFromParent();
1592bool AVRExpandPseudo::expand<AVR::LSLWRd>(
Block &
MBB, BlockIt
MBBI) {
1596 bool DstIsDead =
MI.getOperand(0).isDead();
1597 bool DstIsKill =
MI.getOperand(1).isKill();
1598 bool ImpIsDead =
MI.getOperand(2).isDead();
1599 unsigned OpLo = AVR::ADDRdRr;
1600 unsigned OpHi = AVR::ADCRdRr;
1601 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1616 MIBHI->getOperand(3).setIsDead();
1619 MIBHI->getOperand(4).setIsKill();
1621 MI.eraseFromParent();
1626bool AVRExpandPseudo::expand<AVR::LSLWHiRd>(
Block &
MBB, BlockIt
MBBI) {
1630 bool DstIsDead =
MI.getOperand(0).isDead();
1631 bool DstIsKill =
MI.getOperand(1).isKill();
1632 bool ImpIsDead =
MI.getOperand(2).isDead();
1633 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1637 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
1643 MILSL->getOperand(3).setIsDead();
1645 MI.eraseFromParent();
1649bool AVRExpandPseudo::expandLSLW4Rd(
Block &
MBB, BlockIt
MBBI) {
1653 bool DstIsDead =
MI.getOperand(0).isDead();
1654 bool DstIsKill =
MI.getOperand(1).isKill();
1655 bool ImpIsDead =
MI.getOperand(3).isDead();
1656 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1660 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1663 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1669 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1674 MI0->getOperand(3).setIsDead();
1678 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1683 MI1->getOperand(3).setIsDead();
1687 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1692 MI2->getOperand(3).setIsDead();
1696 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1701 MI3->getOperand(3).setIsDead();
1703 MI.eraseFromParent();
1707bool AVRExpandPseudo::expandLSLW8Rd(
Block &
MBB, BlockIt
MBBI) {
1711 bool DstIsDead =
MI.getOperand(0).isDead();
1712 bool DstIsKill =
MI.getOperand(1).isKill();
1713 bool ImpIsDead =
MI.getOperand(3).isDead();
1714 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1717 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1723 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1728 MIBLO->getOperand(3).setIsDead();
1730 MI.eraseFromParent();
1734bool AVRExpandPseudo::expandLSLW12Rd(
Block &
MBB, BlockIt
MBBI) {
1738 bool DstIsDead =
MI.getOperand(0).isDead();
1739 bool DstIsKill =
MI.getOperand(1).isKill();
1740 bool ImpIsDead =
MI.getOperand(3).isDead();
1741 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1744 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1749 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1755 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1760 MI0->getOperand(3).setIsDead();
1764 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1769 MI1->getOperand(3).setIsDead();
1771 MI.eraseFromParent();
1776bool AVRExpandPseudo::expand<AVR::LSLWNRd>(
Block &
MBB, BlockIt
MBBI) {
1778 unsigned Imm =
MI.getOperand(2).getImm();
1781 return expandLSLW4Rd(
MBB,
MBBI);
1783 return expandLSLW8Rd(
MBB,
MBBI);
1785 return expandLSLW12Rd(
MBB,
MBBI);
1793bool AVRExpandPseudo::expand<AVR::LSRWRd>(
Block &
MBB, BlockIt
MBBI) {
1797 bool DstIsDead =
MI.getOperand(0).isDead();
1798 bool DstIsKill =
MI.getOperand(1).isKill();
1799 bool ImpIsDead =
MI.getOperand(2).isDead();
1800 unsigned OpLo = AVR::RORRd;
1801 unsigned OpHi = AVR::LSRRd;
1802 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1815 MIBLO->getOperand(2).setIsDead();
1818 MIBLO->getOperand(3).setIsKill();
1820 MI.eraseFromParent();
1825bool AVRExpandPseudo::expand<AVR::LSRWLoRd>(
Block &
MBB, BlockIt
MBBI) {
1829 bool DstIsDead =
MI.getOperand(0).isDead();
1830 bool DstIsKill =
MI.getOperand(1).isKill();
1831 bool ImpIsDead =
MI.getOperand(2).isDead();
1832 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1836 buildMI(
MBB,
MBBI, AVR::LSRRd)
1841 MILSR->getOperand(2).setIsDead();
1843 MI.eraseFromParent();
1847bool AVRExpandPseudo::expandLSRW4Rd(
Block &
MBB, BlockIt
MBBI) {
1851 bool DstIsDead =
MI.getOperand(0).isDead();
1852 bool DstIsKill =
MI.getOperand(1).isKill();
1853 bool ImpIsDead =
MI.getOperand(3).isDead();
1854 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1858 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1861 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1867 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1872 MI0->getOperand(3).setIsDead();
1876 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1881 MI1->getOperand(3).setIsDead();
1885 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1890 MI2->getOperand(3).setIsDead();
1894 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1899 MI3->getOperand(3).setIsDead();
1901 MI.eraseFromParent();
1905bool AVRExpandPseudo::expandLSRW8Rd(
Block &
MBB, BlockIt
MBBI) {
1909 bool DstIsDead =
MI.getOperand(0).isDead();
1910 bool DstIsKill =
MI.getOperand(1).isKill();
1911 bool ImpIsDead =
MI.getOperand(3).isDead();
1912 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1915 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1921 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1926 MIBHI->getOperand(3).setIsDead();
1928 MI.eraseFromParent();
1932bool AVRExpandPseudo::expandLSRW12Rd(
Block &
MBB, BlockIt
MBBI) {
1936 bool DstIsDead =
MI.getOperand(0).isDead();
1937 bool DstIsKill =
MI.getOperand(1).isKill();
1938 bool ImpIsDead =
MI.getOperand(3).isDead();
1939 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1942 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1947 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1953 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1958 MI0->getOperand(3).setIsDead();
1962 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1967 MIBHI->getOperand(3).setIsDead();
1969 MI.eraseFromParent();
1974bool AVRExpandPseudo::expand<AVR::LSRWNRd>(
Block &
MBB, BlockIt
MBBI) {
1976 unsigned Imm =
MI.getOperand(2).getImm();
1979 return expandLSRW4Rd(
MBB,
MBBI);
1981 return expandLSRW8Rd(
MBB,
MBBI);
1983 return expandLSRW12Rd(
MBB,
MBBI);
1991bool AVRExpandPseudo::expand<AVR::RORWRd>(
Block &
MBB, BlockIt
MBBI) {
1997bool AVRExpandPseudo::expand<AVR::ROLWRd>(
Block &
MBB, BlockIt
MBBI) {
2003bool AVRExpandPseudo::expand<AVR::ASRWRd>(
Block &
MBB, BlockIt
MBBI) {
2007 bool DstIsDead =
MI.getOperand(0).isDead();
2008 bool DstIsKill =
MI.getOperand(1).isKill();
2009 bool ImpIsDead =
MI.getOperand(2).isDead();
2010 unsigned OpLo = AVR::RORRd;
2011 unsigned OpHi = AVR::ASRRd;
2012 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2025 MIBLO->getOperand(2).setIsDead();
2028 MIBLO->getOperand(3).setIsKill();
2030 MI.eraseFromParent();
2035bool AVRExpandPseudo::expand<AVR::ASRWLoRd>(
Block &
MBB, BlockIt
MBBI) {
2039 bool DstIsDead =
MI.getOperand(0).isDead();
2040 bool DstIsKill =
MI.getOperand(1).isKill();
2041 bool ImpIsDead =
MI.getOperand(2).isDead();
2042 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2046 buildMI(
MBB,
MBBI, AVR::ASRRd)
2051 MIASR->getOperand(2).setIsDead();
2053 MI.eraseFromParent();
2057bool AVRExpandPseudo::expandASRW7Rd(
Block &
MBB, BlockIt
MBBI) {
2061 bool DstIsDead =
MI.getOperand(0).isDead();
2062 bool DstIsKill =
MI.getOperand(1).isKill();
2063 bool ImpIsDead =
MI.getOperand(3).isDead();
2064 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2072 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2078 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2083 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2090 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2096 MISBC->getOperand(3).setIsDead();
2098 MISBC->getOperand(4).setIsKill();
2100 MI.eraseFromParent();
2104bool AVRExpandPseudo::expandASRW8Rd(
Block &
MBB, BlockIt
MBBI) {
2108 bool DstIsDead =
MI.getOperand(0).isDead();
2109 bool DstIsKill =
MI.getOperand(1).isKill();
2110 bool ImpIsDead =
MI.getOperand(3).isDead();
2111 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2114 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2119 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2126 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2132 MIBHI->getOperand(3).setIsDead();
2134 MIBHI->getOperand(4).setIsKill();
2136 MI.eraseFromParent();
2139bool AVRExpandPseudo::expandASRW14Rd(
Block &
MBB, BlockIt
MBBI) {
2143 bool DstIsDead =
MI.getOperand(0).isDead();
2144 bool DstIsKill =
MI.getOperand(1).isKill();
2145 bool ImpIsDead =
MI.getOperand(3).isDead();
2146 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2155 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2161 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2167 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2173 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2179 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2185 MIROL->getOperand(3).setIsDead();
2187 MIROL->getOperand(4).setIsKill();
2189 MI.eraseFromParent();
2193bool AVRExpandPseudo::expandASRW15Rd(
Block &
MBB, BlockIt
MBBI) {
2197 bool DstIsDead =
MI.getOperand(0).isDead();
2198 bool ImpIsDead =
MI.getOperand(3).isDead();
2199 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2206 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2213 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2218 MISBC->getOperand(3).setIsDead();
2220 MISBC->getOperand(4).setIsKill();
2223 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2227 MI.eraseFromParent();
2232bool AVRExpandPseudo::expand<AVR::ASRWNRd>(
Block &
MBB, BlockIt
MBBI) {
2234 unsigned Imm =
MI.getOperand(2).getImm();
2237 return expandASRW7Rd(
MBB,
MBBI);
2239 return expandASRW8Rd(
MBB,
MBBI);
2241 return expandASRW14Rd(
MBB,
MBBI);
2243 return expandASRW15Rd(
MBB,
MBBI);
2250bool AVRExpandPseudo::expandLSLB7Rd(
Block &
MBB, BlockIt
MBBI) {
2253 bool DstIsDead =
MI.getOperand(0).isDead();
2254 bool DstIsKill =
MI.getOperand(1).isKill();
2255 bool ImpIsDead =
MI.getOperand(3).isDead();
2261 buildMI(
MBB,
MBBI, AVR::RORRd)
2267 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2273 buildMI(
MBB,
MBBI, AVR::RORRd)
2278 MIRRC->getOperand(2).setIsDead();
2281 MIRRC->getOperand(3).setIsKill();
2283 MI.eraseFromParent();
2288bool AVRExpandPseudo::expand<AVR::LSLBNRd>(
Block &
MBB, BlockIt
MBBI) {
2290 unsigned Imm =
MI.getOperand(2).getImm();
2293 return expandLSLB7Rd(
MBB,
MBBI);
2300bool AVRExpandPseudo::expandLSRB7Rd(
Block &
MBB, BlockIt
MBBI) {
2303 bool DstIsDead =
MI.getOperand(0).isDead();
2304 bool DstIsKill =
MI.getOperand(1).isKill();
2305 bool ImpIsDead =
MI.getOperand(3).isDead();
2311 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2318 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2324 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2330 MIRRC->getOperand(3).setIsDead();
2333 MIRRC->getOperand(4).setIsKill();
2335 MI.eraseFromParent();
2340bool AVRExpandPseudo::expand<AVR::LSRBNRd>(
Block &
MBB, BlockIt
MBBI) {
2342 unsigned Imm =
MI.getOperand(2).getImm();
2345 return expandLSRB7Rd(
MBB,
MBBI);
2352bool AVRExpandPseudo::expandASRB6Rd(
Block &
MBB, BlockIt
MBBI) {
2355 bool DstIsDead =
MI.getOperand(0).isDead();
2356 bool DstIsKill =
MI.getOperand(1).isKill();
2369 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2374 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2386 MI.eraseFromParent();
2390bool AVRExpandPseudo::expandASRB7Rd(
Block &
MBB, BlockIt
MBBI) {
2393 bool DstIsDead =
MI.getOperand(0).isDead();
2394 bool DstIsKill =
MI.getOperand(1).isKill();
2395 bool ImpIsDead =
MI.getOperand(3).isDead();
2400 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2406 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2412 MIRRC->getOperand(3).setIsDead();
2415 MIRRC->getOperand(4).setIsKill();
2417 MI.eraseFromParent();
2422bool AVRExpandPseudo::expand<AVR::ASRBNRd>(
Block &
MBB, BlockIt
MBBI) {
2424 unsigned Imm =
MI.getOperand(2).getImm();
2427 return expandASRB6Rd(
MBB,
MBBI);
2429 return expandASRB7Rd(
MBB,
MBBI);
2436template <>
bool AVRExpandPseudo::expand<AVR::SEXT>(
Block &
MBB, BlockIt
MBBI) {
2454 bool DstIsDead =
MI.getOperand(0).isDead();
2455 bool SrcIsKill =
MI.getOperand(1).isKill();
2456 bool ImpIsDead =
MI.getOperand(2).isDead();
2457 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2459 if (SrcReg != DstLoReg)
2460 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2464 if (SrcReg != DstHiReg) {
2465 auto MOV = buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2468 if (SrcReg != DstLoReg && SrcIsKill)
2469 MOV->getOperand(1).setIsKill();
2472 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2478 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2484 SBC->getOperand(3).setIsDead();
2487 SBC->getOperand(4).setIsKill();
2489 MI.eraseFromParent();
2493template <>
bool AVRExpandPseudo::expand<AVR::ZEXT>(
Block &
MBB, BlockIt
MBBI) {
2506 bool DstIsDead =
MI.getOperand(0).isDead();
2507 bool SrcIsKill =
MI.getOperand(1).isKill();
2508 bool ImpIsDead =
MI.getOperand(2).isDead();
2509 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2511 if (SrcReg != DstLoReg) {
2512 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2518 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2524 EOR->getOperand(3).setIsDead();
2526 MI.eraseFromParent();
2531bool AVRExpandPseudo::expand<AVR::SPREAD>(
Block &
MBB, BlockIt
MBBI) {
2536 bool DstIsDead =
MI.getOperand(0).isDead();
2537 unsigned Flags =
MI.getFlags();
2538 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2541 buildMI(
MBB,
MBBI, AVR::INRdA)
2548 buildMI(
MBB,
MBBI, AVR::INRdA)
2555 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2560 MI0->getOperand(3).setIsDead();
2563 MI.eraseFromParent();
2568bool AVRExpandPseudo::expand<AVR::SPWRITE>(
Block &
MBB, BlockIt
MBBI) {
2573 bool SrcIsKill =
MI.getOperand(1).isKill();
2574 unsigned Flags =
MI.getFlags();
2575 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
2582 buildMI(
MBB,
MBBI, AVR::OUTARr)
2587 buildMI(
MBB,
MBBI, AVR::OUTARr)
2594 buildMI(
MBB,
MBBI, AVR::INRdA)
2599 buildMI(
MBB,
MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
2601 buildMI(
MBB,
MBBI, AVR::OUTARr)
2606 buildMI(
MBB,
MBBI, AVR::OUTARr)
2612 buildMI(
MBB,
MBBI, AVR::OUTARr)
2618 MI.eraseFromParent();
2622template <>
bool AVRExpandPseudo::expand<AVR::FRMSP>(
Block &
MBB, BlockIt
MBBI) {
2627 Register ASOPointer =
MI.getOperand(0).getReg();
2628 int64_t ASOAlignment =
MI.getOperand(1).getImm();
2635 TII->copyPhysReg(
MBB,
MI,
DL, ASOPointer, AVR::R29R28,
false,
false,
false);
2637 buildMI(
MBB,
MI, AVR::ADIWRdKP)
2640 .addImm(ASOOffset.
getFixed() + ASOAlignment - 1)
2643 buildMI(
MBB,
MI, AVR::ANDIWRdK)
2646 .addImm(-ASOAlignment)
2649 MI.eraseFromParent();
2653bool AVRExpandPseudo::expandMI(
Block &
MBB, BlockIt
MBBI) {
2655 int Opcode =
MBBI->getOpcode();
2659 return expand<Op>(MBB, MI)
2692 EXPAND(AVR::AtomicLoad8);
2693 EXPAND(AVR::AtomicLoad16);
2694 EXPAND(AVR::AtomicStore8);
2695 EXPAND(AVR::AtomicStore16);
2696 EXPAND(AVR::AtomicFence);
2741 return new AVRExpandPseudo();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
#define AVR_EXPAND_PSEUDO_NAME
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Expected< BitVector > expand(StringRef S, StringRef Original)
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Contains AVR-specific information for each MachineFunction.
unsigned AlignedStackObjectIdx
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.
FunctionPass class - This class is used to implement most global optimizations.
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
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,...
Wrapper class representing virtual and physical registers.
StackOffset holds a fixed and a scalable offset in bytes.
static StackOffset getFixed(int64_t Fixed)
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.
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.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
@ Define
Register definition.
constexpr RegState getKillRegState(bool B)
constexpr RegState getDeadRegState(bool B)
FunctionPass * createAVRExpandPseudoPass()
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
DWARFExpression::Operation Op
constexpr RegState getUndefRegState(bool B)