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");
1383 if (STI.hasTinyEncoding()) {
1386 unsigned Imm =
MI.getOperand(1).getImm();
1388 bool SrcIsKill =
MI.getOperand(2).isKill();
1391 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, AVR::R29R28)
1393 .addImm(0x10000 -
Imm);
1395 buildMI(
MBB,
MBBI, AVR::STPtrRr)
1398 .setMemRefs(
MI.memoperands());
1401 buildMI(
MBB, std::next(
MBBI), AVR::SUBIWRdK, AVR::R29R28)
1405 MI.eraseFromParent();
1407 MI.setDesc(
TII->get(AVR::STDPtrQRr));
1408 MI.getOperand(0).setReg(AVR::R29R28);
1415bool AVRExpandPseudo::expand<AVR::STDWSPQRr>(
Block &
MBB, BlockIt
MBBI) {
1420 assert(
MI.getOperand(0).getReg() == AVR::SP &&
1421 "SP is expected as base pointer");
1424 "unexpected STDWSPQRr pseudo instruction");
1427 MI.setDesc(
TII->get(AVR::STDWPtrQRr));
1428 MI.getOperand(0).setReg(AVR::R29R28);
1434bool AVRExpandPseudo::expand<AVR::INWRdA>(
Block &
MBB, BlockIt
MBBI) {
1437 unsigned Imm =
MI.getOperand(1).getImm();
1439 bool DstIsDead =
MI.getOperand(0).isDead();
1440 unsigned OpLo = AVR::INRdA;
1441 unsigned OpHi = AVR::INRdA;
1442 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1446 assert(
Imm <= 62 &&
"Address is out of range");
1458 MIBLO.setMemRefs(
MI.memoperands());
1459 MIBHI.setMemRefs(
MI.memoperands());
1461 MI.eraseFromParent();
1466bool AVRExpandPseudo::expand<AVR::OUTWARr>(
Block &
MBB, BlockIt
MBBI) {
1470 unsigned Imm =
MI.getOperand(0).getImm();
1472 bool SrcIsKill =
MI.getOperand(1).isKill();
1473 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1477 assert(
Imm <= 62 &&
"Address is out of range");
1481 auto MIBHI = buildMI(
MBB,
MBBI, AVR::OUTARr)
1482 .addImm(STI.hasLowByteFirst() ?
Imm :
Imm + 1)
1483 .addReg(STI.hasLowByteFirst() ? SrcLoReg : SrcHiReg,
1485 auto MIBLO = buildMI(
MBB,
MBBI, AVR::OUTARr)
1486 .addImm(STI.hasLowByteFirst() ?
Imm + 1 :
Imm)
1487 .addReg(STI.hasLowByteFirst() ? SrcHiReg : SrcLoReg,
1490 MIBLO.setMemRefs(
MI.memoperands());
1491 MIBHI.setMemRefs(
MI.memoperands());
1493 MI.eraseFromParent();
1498bool AVRExpandPseudo::expand<AVR::PUSHWRr>(
Block &
MBB, BlockIt
MBBI) {
1502 bool SrcIsKill =
MI.getOperand(0).isKill();
1503 unsigned Flags =
MI.getFlags();
1504 unsigned OpLo = AVR::PUSHRr;
1505 unsigned OpHi = AVR::PUSHRr;
1506 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1518 MI.eraseFromParent();
1523bool AVRExpandPseudo::expand<AVR::POPWRd>(
Block &
MBB, BlockIt
MBBI) {
1527 unsigned Flags =
MI.getFlags();
1528 unsigned OpLo = AVR::POPRd;
1529 unsigned OpHi = AVR::POPRd;
1530 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1532 buildMI(
MBB,
MBBI, OpHi, DstHiReg).setMIFlags(Flags);
1533 buildMI(
MBB,
MBBI, OpLo, DstLoReg).setMIFlags(Flags);
1535 MI.eraseFromParent();
1539bool AVRExpandPseudo::expandROLBRd(
Block &
MBB, BlockIt
MBBI) {
1547 unsigned OpShift, OpCarry;
1549 Register ZeroReg =
MI.getOperand(3).getReg();
1550 bool DstIsDead =
MI.getOperand(0).isDead();
1551 bool DstIsKill =
MI.getOperand(1).isKill();
1552 OpShift = AVR::ADDRdRr;
1553 OpCarry = AVR::ADCRdRr;
1565 auto MIB = buildMI(
MBB,
MBBI, OpCarry)
1570 MIB->getOperand(3).setIsDead();
1571 MIB->getOperand(4).setIsKill();
1573 MI.eraseFromParent();
1578bool AVRExpandPseudo::expand<AVR::ROLBRdR1>(
Block &
MBB, BlockIt
MBBI) {
1579 return expandROLBRd(
MBB,
MBBI);
1583bool AVRExpandPseudo::expand<AVR::ROLBRdR17>(
Block &
MBB, BlockIt
MBBI) {
1584 return expandROLBRd(
MBB,
MBBI);
1588bool AVRExpandPseudo::expand<AVR::RORBRd>(
Block &
MBB, BlockIt
MBBI) {
1603 buildMI(
MBB,
MBBI, AVR::BST).addReg(DstReg).addImm(0);
1606 buildMI(
MBB,
MBBI, AVR::RORRd, DstReg).addReg(DstReg);
1609 buildMI(
MBB,
MBBI, AVR::BLD, DstReg).addReg(DstReg).addImm(7);
1611 MI.eraseFromParent();
1616bool AVRExpandPseudo::expand<AVR::LSLWRd>(
Block &
MBB, BlockIt
MBBI) {
1620 bool DstIsDead =
MI.getOperand(0).isDead();
1621 bool DstIsKill =
MI.getOperand(1).isKill();
1622 bool ImpIsDead =
MI.getOperand(2).isDead();
1623 unsigned OpLo = AVR::ADDRdRr;
1624 unsigned OpHi = AVR::ADCRdRr;
1625 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1640 MIBHI->getOperand(3).setIsDead();
1643 MIBHI->getOperand(4).setIsKill();
1645 MI.eraseFromParent();
1650bool AVRExpandPseudo::expand<AVR::LSLWHiRd>(
Block &
MBB, BlockIt
MBBI) {
1654 bool DstIsDead =
MI.getOperand(0).isDead();
1655 bool DstIsKill =
MI.getOperand(1).isKill();
1656 bool ImpIsDead =
MI.getOperand(2).isDead();
1657 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1661 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
1667 MILSL->getOperand(3).setIsDead();
1669 MI.eraseFromParent();
1673bool AVRExpandPseudo::expandLSLW4Rd(
Block &
MBB, BlockIt
MBBI) {
1677 bool DstIsDead =
MI.getOperand(0).isDead();
1678 bool DstIsKill =
MI.getOperand(1).isKill();
1679 bool ImpIsDead =
MI.getOperand(3).isDead();
1680 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1684 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1687 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1693 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1698 MI0->getOperand(3).setIsDead();
1702 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1707 MI1->getOperand(3).setIsDead();
1711 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1716 MI2->getOperand(3).setIsDead();
1720 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1725 MI3->getOperand(3).setIsDead();
1727 MI.eraseFromParent();
1731bool AVRExpandPseudo::expandLSLW8Rd(
Block &
MBB, BlockIt
MBBI) {
1735 bool DstIsDead =
MI.getOperand(0).isDead();
1736 bool DstIsKill =
MI.getOperand(1).isKill();
1737 bool ImpIsDead =
MI.getOperand(3).isDead();
1738 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1741 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1747 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1752 MIBLO->getOperand(3).setIsDead();
1754 MI.eraseFromParent();
1758bool AVRExpandPseudo::expandLSLW12Rd(
Block &
MBB, BlockIt
MBBI) {
1762 bool DstIsDead =
MI.getOperand(0).isDead();
1763 bool DstIsKill =
MI.getOperand(1).isKill();
1764 bool ImpIsDead =
MI.getOperand(3).isDead();
1765 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1768 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1773 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1779 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1784 MI0->getOperand(3).setIsDead();
1788 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1793 MI1->getOperand(3).setIsDead();
1795 MI.eraseFromParent();
1800bool AVRExpandPseudo::expand<AVR::LSLWNRd>(
Block &
MBB, BlockIt
MBBI) {
1802 unsigned Imm =
MI.getOperand(2).getImm();
1805 return expandLSLW4Rd(
MBB,
MBBI);
1807 return expandLSLW8Rd(
MBB,
MBBI);
1809 return expandLSLW12Rd(
MBB,
MBBI);
1817bool AVRExpandPseudo::expand<AVR::LSRWRd>(
Block &
MBB, BlockIt
MBBI) {
1821 bool DstIsDead =
MI.getOperand(0).isDead();
1822 bool DstIsKill =
MI.getOperand(1).isKill();
1823 bool ImpIsDead =
MI.getOperand(2).isDead();
1824 unsigned OpLo = AVR::RORRd;
1825 unsigned OpHi = AVR::LSRRd;
1826 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1839 MIBLO->getOperand(2).setIsDead();
1842 MIBLO->getOperand(3).setIsKill();
1844 MI.eraseFromParent();
1849bool AVRExpandPseudo::expand<AVR::LSRWLoRd>(
Block &
MBB, BlockIt
MBBI) {
1853 bool DstIsDead =
MI.getOperand(0).isDead();
1854 bool DstIsKill =
MI.getOperand(1).isKill();
1855 bool ImpIsDead =
MI.getOperand(2).isDead();
1856 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1860 buildMI(
MBB,
MBBI, AVR::LSRRd)
1865 MILSR->getOperand(2).setIsDead();
1867 MI.eraseFromParent();
1871bool AVRExpandPseudo::expandLSRW4Rd(
Block &
MBB, BlockIt
MBBI) {
1875 bool DstIsDead =
MI.getOperand(0).isDead();
1876 bool DstIsKill =
MI.getOperand(1).isKill();
1877 bool ImpIsDead =
MI.getOperand(3).isDead();
1878 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1882 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1885 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1891 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1896 MI0->getOperand(3).setIsDead();
1900 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1905 MI1->getOperand(3).setIsDead();
1909 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1914 MI2->getOperand(3).setIsDead();
1918 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1923 MI3->getOperand(3).setIsDead();
1925 MI.eraseFromParent();
1929bool AVRExpandPseudo::expandLSRW8Rd(
Block &
MBB, BlockIt
MBBI) {
1933 bool DstIsDead =
MI.getOperand(0).isDead();
1934 bool DstIsKill =
MI.getOperand(1).isKill();
1935 bool ImpIsDead =
MI.getOperand(3).isDead();
1936 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1939 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1945 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1950 MIBHI->getOperand(3).setIsDead();
1952 MI.eraseFromParent();
1956bool AVRExpandPseudo::expandLSRW12Rd(
Block &
MBB, BlockIt
MBBI) {
1960 bool DstIsDead =
MI.getOperand(0).isDead();
1961 bool DstIsKill =
MI.getOperand(1).isKill();
1962 bool ImpIsDead =
MI.getOperand(3).isDead();
1963 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1966 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1971 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1977 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1982 MI0->getOperand(3).setIsDead();
1986 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1991 MIBHI->getOperand(3).setIsDead();
1993 MI.eraseFromParent();
1998bool AVRExpandPseudo::expand<AVR::LSRWNRd>(
Block &
MBB, BlockIt
MBBI) {
2000 unsigned Imm =
MI.getOperand(2).getImm();
2003 return expandLSRW4Rd(
MBB,
MBBI);
2005 return expandLSRW8Rd(
MBB,
MBBI);
2007 return expandLSRW12Rd(
MBB,
MBBI);
2015bool AVRExpandPseudo::expand<AVR::RORWRd>(
Block &
MBB, BlockIt
MBBI) {
2021bool AVRExpandPseudo::expand<AVR::ROLWRd>(
Block &
MBB, BlockIt
MBBI) {
2027bool AVRExpandPseudo::expand<AVR::ASRWRd>(
Block &
MBB, BlockIt
MBBI) {
2031 bool DstIsDead =
MI.getOperand(0).isDead();
2032 bool DstIsKill =
MI.getOperand(1).isKill();
2033 bool ImpIsDead =
MI.getOperand(2).isDead();
2034 unsigned OpLo = AVR::RORRd;
2035 unsigned OpHi = AVR::ASRRd;
2036 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2049 MIBLO->getOperand(2).setIsDead();
2052 MIBLO->getOperand(3).setIsKill();
2054 MI.eraseFromParent();
2059bool AVRExpandPseudo::expand<AVR::ASRWLoRd>(
Block &
MBB, BlockIt
MBBI) {
2063 bool DstIsDead =
MI.getOperand(0).isDead();
2064 bool DstIsKill =
MI.getOperand(1).isKill();
2065 bool ImpIsDead =
MI.getOperand(2).isDead();
2066 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2070 buildMI(
MBB,
MBBI, AVR::ASRRd)
2075 MIASR->getOperand(2).setIsDead();
2077 MI.eraseFromParent();
2081bool AVRExpandPseudo::expandASRW7Rd(
Block &
MBB, BlockIt
MBBI) {
2085 bool DstIsDead =
MI.getOperand(0).isDead();
2086 bool DstIsKill =
MI.getOperand(1).isKill();
2087 bool ImpIsDead =
MI.getOperand(3).isDead();
2088 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2096 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2102 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2107 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2114 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2120 MISBC->getOperand(3).setIsDead();
2122 MISBC->getOperand(4).setIsKill();
2124 MI.eraseFromParent();
2128bool AVRExpandPseudo::expandASRW8Rd(
Block &
MBB, BlockIt
MBBI) {
2132 bool DstIsDead =
MI.getOperand(0).isDead();
2133 bool DstIsKill =
MI.getOperand(1).isKill();
2134 bool ImpIsDead =
MI.getOperand(3).isDead();
2135 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2138 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2143 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2150 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2156 MIBHI->getOperand(3).setIsDead();
2158 MIBHI->getOperand(4).setIsKill();
2160 MI.eraseFromParent();
2163bool AVRExpandPseudo::expandASRW14Rd(
Block &
MBB, BlockIt
MBBI) {
2167 bool DstIsDead =
MI.getOperand(0).isDead();
2168 bool DstIsKill =
MI.getOperand(1).isKill();
2169 bool ImpIsDead =
MI.getOperand(3).isDead();
2170 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2179 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2185 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2191 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2197 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2203 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2209 MIROL->getOperand(3).setIsDead();
2211 MIROL->getOperand(4).setIsKill();
2213 MI.eraseFromParent();
2217bool AVRExpandPseudo::expandASRW15Rd(
Block &
MBB, BlockIt
MBBI) {
2221 bool DstIsDead =
MI.getOperand(0).isDead();
2222 bool ImpIsDead =
MI.getOperand(3).isDead();
2223 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2230 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2237 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2242 MISBC->getOperand(3).setIsDead();
2244 MISBC->getOperand(4).setIsKill();
2247 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2251 MI.eraseFromParent();
2256bool AVRExpandPseudo::expand<AVR::ASRWNRd>(
Block &
MBB, BlockIt
MBBI) {
2258 unsigned Imm =
MI.getOperand(2).getImm();
2261 return expandASRW7Rd(
MBB,
MBBI);
2263 return expandASRW8Rd(
MBB,
MBBI);
2265 return expandASRW14Rd(
MBB,
MBBI);
2267 return expandASRW15Rd(
MBB,
MBBI);
2274bool AVRExpandPseudo::expandLSLB7Rd(
Block &
MBB, BlockIt
MBBI) {
2277 bool DstIsDead =
MI.getOperand(0).isDead();
2278 bool DstIsKill =
MI.getOperand(1).isKill();
2279 bool ImpIsDead =
MI.getOperand(3).isDead();
2285 buildMI(
MBB,
MBBI, AVR::RORRd)
2291 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2297 buildMI(
MBB,
MBBI, AVR::RORRd)
2302 MIRRC->getOperand(2).setIsDead();
2305 MIRRC->getOperand(3).setIsKill();
2307 MI.eraseFromParent();
2312bool AVRExpandPseudo::expand<AVR::LSLBNRd>(
Block &
MBB, BlockIt
MBBI) {
2314 unsigned Imm =
MI.getOperand(2).getImm();
2317 return expandLSLB7Rd(
MBB,
MBBI);
2324bool AVRExpandPseudo::expandLSRB7Rd(
Block &
MBB, BlockIt
MBBI) {
2327 bool DstIsDead =
MI.getOperand(0).isDead();
2328 bool DstIsKill =
MI.getOperand(1).isKill();
2329 bool ImpIsDead =
MI.getOperand(3).isDead();
2335 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2342 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2348 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2354 MIRRC->getOperand(3).setIsDead();
2357 MIRRC->getOperand(4).setIsKill();
2359 MI.eraseFromParent();
2364bool AVRExpandPseudo::expand<AVR::LSRBNRd>(
Block &
MBB, BlockIt
MBBI) {
2366 unsigned Imm =
MI.getOperand(2).getImm();
2369 return expandLSRB7Rd(
MBB,
MBBI);
2376bool AVRExpandPseudo::expandASRB6Rd(
Block &
MBB, BlockIt
MBBI) {
2379 bool DstIsDead =
MI.getOperand(0).isDead();
2380 bool DstIsKill =
MI.getOperand(1).isKill();
2393 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2398 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2410 MI.eraseFromParent();
2414bool AVRExpandPseudo::expandASRB7Rd(
Block &
MBB, BlockIt
MBBI) {
2417 bool DstIsDead =
MI.getOperand(0).isDead();
2418 bool DstIsKill =
MI.getOperand(1).isKill();
2419 bool ImpIsDead =
MI.getOperand(3).isDead();
2424 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2430 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2436 MIRRC->getOperand(3).setIsDead();
2439 MIRRC->getOperand(4).setIsKill();
2441 MI.eraseFromParent();
2446bool AVRExpandPseudo::expand<AVR::ASRBNRd>(
Block &
MBB, BlockIt
MBBI) {
2448 unsigned Imm =
MI.getOperand(2).getImm();
2451 return expandASRB6Rd(
MBB,
MBBI);
2453 return expandASRB7Rd(
MBB,
MBBI);
2460template <>
bool AVRExpandPseudo::expand<AVR::SEXT>(
Block &
MBB, BlockIt
MBBI) {
2478 bool DstIsDead =
MI.getOperand(0).isDead();
2479 bool SrcIsKill =
MI.getOperand(1).isKill();
2480 bool ImpIsDead =
MI.getOperand(2).isDead();
2481 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2483 if (SrcReg != DstLoReg)
2484 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2488 if (SrcReg != DstHiReg) {
2489 auto MOV = buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2492 if (SrcReg != DstLoReg && SrcIsKill)
2493 MOV->getOperand(1).setIsKill();
2496 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2502 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2508 SBC->getOperand(3).setIsDead();
2511 SBC->getOperand(4).setIsKill();
2513 MI.eraseFromParent();
2517template <>
bool AVRExpandPseudo::expand<AVR::ZEXT>(
Block &
MBB, BlockIt
MBBI) {
2530 bool DstIsDead =
MI.getOperand(0).isDead();
2531 bool SrcIsKill =
MI.getOperand(1).isKill();
2532 bool ImpIsDead =
MI.getOperand(2).isDead();
2533 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2535 if (SrcReg != DstLoReg) {
2536 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2542 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2548 EOR->getOperand(3).setIsDead();
2550 MI.eraseFromParent();
2555bool AVRExpandPseudo::expand<AVR::SPREAD>(
Block &
MBB, BlockIt
MBBI) {
2560 bool DstIsDead =
MI.getOperand(0).isDead();
2561 unsigned Flags =
MI.getFlags();
2562 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2565 buildMI(
MBB,
MBBI, AVR::INRdA)
2572 buildMI(
MBB,
MBBI, AVR::INRdA)
2579 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2584 MI0->getOperand(3).setIsDead();
2587 MI.eraseFromParent();
2592bool AVRExpandPseudo::expand<AVR::SPWRITE>(
Block &
MBB, BlockIt
MBBI) {
2597 bool SrcIsKill =
MI.getOperand(1).isKill();
2598 unsigned Flags =
MI.getFlags();
2599 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
2606 buildMI(
MBB,
MBBI, AVR::OUTARr)
2611 buildMI(
MBB,
MBBI, AVR::OUTARr)
2618 buildMI(
MBB,
MBBI, AVR::INRdA)
2623 buildMI(
MBB,
MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
2625 buildMI(
MBB,
MBBI, AVR::OUTARr)
2630 buildMI(
MBB,
MBBI, AVR::OUTARr)
2636 buildMI(
MBB,
MBBI, AVR::OUTARr)
2642 MI.eraseFromParent();
2646template <>
bool AVRExpandPseudo::expand<AVR::FRMSP>(
Block &
MBB, BlockIt
MBBI) {
2651 Register ASOPointer =
MI.getOperand(0).getReg();
2652 int64_t ASOAlignment =
MI.getOperand(1).getImm();
2664 TII->copyPhysReg(
MBB,
MI,
DL, ASOPointer, AVR::R29R28,
false,
false,
false);
2666 buildMI(
MBB,
MI, AVR::ADIWRdKP)
2669 .addImm(ASOOffset.
getFixed() + ASOAlignment - 1)
2672 buildMI(
MBB,
MI, AVR::ANDIWRdK)
2675 .addImm(-ASOAlignment)
2678 MI.eraseFromParent();
2682bool AVRExpandPseudo::expandMI(
Block &
MBB, BlockIt
MBBI) {
2684 int Opcode =
MBBI->getOpcode();
2688 return expand<Op>(MBB, MI)
2721 EXPAND(AVR::AtomicLoad8);
2722 EXPAND(AVR::AtomicLoad16);
2723 EXPAND(AVR::AtomicStore8);
2724 EXPAND(AVR::AtomicStore16);
2725 EXPAND(AVR::AtomicFence);
2770 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)