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::LDDRdPtrQ>(
Block &
MBB, BlockIt
MBBI) {
806 if (!STI.hasTinyEncoding())
810 bool DstIsDead =
MI.getOperand(0).isDead();
812 bool SrcIsKill =
MI.getOperand(1).isKill();
813 unsigned Imm =
MI.getOperand(2).getImm();
815 assert((
Imm == 0 || SrcIsKill || !
TRI->regsOverlap(DstReg, SrcReg)) &&
816 "Cannot restore a pointer that the load overwrites");
819 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, SrcReg)
821 .addImm(0x10000 -
Imm);
823 buildMI(
MBB,
MBBI, AVR::LDRdPtr)
826 .setMemRefs(
MI.memoperands());
828 if (
Imm != 0 && !SrcIsKill)
829 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, SrcReg)
833 MI.eraseFromParent();
838bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(
Block &
MBB, BlockIt
MBBI) {
842 unsigned Imm =
MI.getOperand(2).getImm();
843 bool DstIsKill =
MI.getOperand(0).isKill();
844 bool SrcIsKill =
MI.getOperand(1).isKill();
849 assert(
Imm <= 62 &&
"Offset is out of range");
853 assert(DstReg != SrcReg &&
"Dst and Src registers are the same!");
855 if (STI.hasTinyEncoding()) {
863 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, SrcReg)
865 .addImm(0x10000 -
Imm);
870 buildMI(
MBB,
MBBI, AVR::LDWRdPtrPi)
874 .setMemRefs(
MI.memoperands());
880 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, SrcReg).addReg(SrcReg).addImm(
Imm + 2);
884 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
887 buildMI(
MBB,
MBBI, AVR::LDDRdPtrQ)
891 .setMemRefs(
MI.memoperands());
894 buildMI(
MBB,
MBBI, AVR::LDDRdPtrQ)
898 .setMemRefs(
MI.memoperands());
901 MI.eraseFromParent();
905bool AVRExpandPseudo::expandLPMWELPMW(
Block &
MBB, BlockIt
MBBI,
bool IsELPM) {
911 bool SrcIsKill =
MI.getOperand(1).isKill();
913 bool IsLPMRn = IsELPM ? STI.hasELPMX() : STI.hasLPMX();
915 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
916 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
926 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
929 unsigned OpLo = IsELPM ? AVR::ELPMRdZPi : AVR::LPMRdZPi;
930 unsigned OpHi = IsELPM ? AVR::ELPMRdZ : AVR::LPMRdZ;
932 auto MIBLO = buildMI(
MBB,
MBBI, OpLo)
936 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
939 MIBLO.setMemRefs(
MI.memoperands());
940 MIBHI.setMemRefs(
MI.memoperands());
942 unsigned Opc = IsELPM ? AVR::ELPM : AVR::LPM;
945 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
948 MIBLO.setMemRefs(
MI.memoperands());
950 if (STI.hasADDSUBIW()) {
952 auto MIINC = buildMI(
MBB,
MBBI, AVR::ADIWRdK)
956 MIINC->getOperand(3).setIsDead();
960 buildMI(
MBB,
MBBI, AVR::SUBIRdK)
964 auto MIZHI = buildMI(
MBB,
MBBI, AVR::SBCIRdK)
968 MIZHI->getOperand(3).setIsDead();
969 MIZHI->getOperand(4).setIsKill();
973 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
976 MIBHI.setMemRefs(
MI.memoperands());
981 if (STI.hasADDSUBIW()) {
983 auto MIDEC = buildMI(
MBB,
MBBI, AVR::SBIWRdK)
987 MIDEC->getOperand(3).setIsDead();
991 buildMI(
MBB,
MBBI, AVR::SUBIRdK)
995 auto MIZHI = buildMI(
MBB,
MBBI, AVR::SBCIRdK)
999 MIZHI->getOperand(3).setIsDead();
1000 MIZHI->getOperand(4).setIsKill();
1004 MI.eraseFromParent();
1009bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(
Block &
MBB, BlockIt
MBBI) {
1010 return expandLPMWELPMW(
MBB,
MBBI,
false);
1014bool AVRExpandPseudo::expand<AVR::ELPMWRdZ>(
Block &
MBB, BlockIt
MBBI) {
1015 return expandLPMWELPMW(
MBB,
MBBI,
true);
1018bool AVRExpandPseudo::expandLPMBELPMB(
Block &
MBB, BlockIt
MBBI,
bool IsELPM) {
1022 bool SrcIsKill =
MI.getOperand(1).isKill();
1024 bool IsLPMRn = IsELPM ? STI.hasELPMX() : STI.hasLPMX();
1028 Register BankReg =
MI.getOperand(2).getReg();
1034 unsigned Opc = IsELPM ? AVR::ELPMRdZ : AVR::LPMRdZ;
1038 MILB.setMemRefs(
MI.memoperands());
1042 unsigned Opc = IsELPM ? AVR::ELPM : AVR::LPM;
1044 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1047 MILB.setMemRefs(
MI.memoperands());
1050 MI.eraseFromParent();
1055bool AVRExpandPseudo::expand<AVR::ELPMBRdZ>(
Block &
MBB, BlockIt
MBBI) {
1056 return expandLPMBELPMB(
MBB,
MBBI,
true);
1060bool AVRExpandPseudo::expand<AVR::LPMBRdZ>(
Block &
MBB, BlockIt
MBBI) {
1061 return expandLPMBELPMB(
MBB,
MBBI,
false);
1065bool AVRExpandPseudo::expand<AVR::LPMWRdZPi>(
Block &
MBB, BlockIt
MBBI) {
1070bool AVRExpandPseudo::expand<AVR::ELPMBRdZPi>(
Block &
MBB, BlockIt
MBBI) {
1075bool AVRExpandPseudo::expand<AVR::ELPMWRdZPi>(
Block &
MBB, BlockIt
MBBI) {
1079template <
typename Func>
1080bool AVRExpandPseudo::expandAtomic(
Block &
MBB, BlockIt
MBBI, Func f) {
1085 buildMI(
MBB,
MBBI, AVR::INRdA)
1090 buildMI(
MBB,
MBBI, AVR::BCLRs).addImm(7);
1095 buildMI(
MBB,
MBBI, AVR::OUTARr)
1099 MI.eraseFromParent();
1103template <
typename Func>
1104bool AVRExpandPseudo::expandAtomicBinaryOp(
unsigned Opcode,
Block &
MBB,
1105 BlockIt
MBBI, Func f) {
1107 auto Op1 =
MI.getOperand(0);
1108 auto Op2 =
MI.getOperand(1);
1111 *buildMI(
MBB,
MBBI, Opcode).add(Op1).add(Op2).getInstr();
1116bool AVRExpandPseudo::expandAtomicBinaryOp(
unsigned Opcode,
Block &
MBB,
1122bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(
Block &
MBB, BlockIt
MBBI) {
1123 return expandAtomicBinaryOp(AVR::LDRdPtr,
MBB,
MBBI);
1127bool AVRExpandPseudo::expand<AVR::AtomicLoad16>(
Block &
MBB, BlockIt
MBBI) {
1128 return expandAtomicBinaryOp(AVR::LDWRdPtr,
MBB,
MBBI);
1132bool AVRExpandPseudo::expand<AVR::AtomicStore8>(
Block &
MBB, BlockIt
MBBI) {
1133 return expandAtomicBinaryOp(AVR::STPtrRr,
MBB,
MBBI);
1137bool AVRExpandPseudo::expand<AVR::AtomicStore16>(
Block &
MBB, BlockIt
MBBI) {
1138 return expandAtomicBinaryOp(AVR::STWPtrRr,
MBB,
MBBI);
1142bool AVRExpandPseudo::expand<AVR::AtomicFence>(
Block &
MBB, BlockIt
MBBI) {
1144 MBBI->eraseFromParent();
1149bool AVRExpandPseudo::expand<AVR::STSWKRr>(
Block &
MBB, BlockIt
MBBI) {
1154 bool SrcIsKill =
MI.getOperand(1).isKill();
1155 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1157 auto MIB0 = buildMI(
MBB,
MBBI, AVR::STSKRr);
1158 auto MIB1 = buildMI(
MBB,
MBBI, AVR::STSKRr);
1160 switch (
MI.getOperand(0).getType()) {
1163 int64_t Offs =
MI.getOperand(0).getOffset();
1164 unsigned TF =
MI.getOperand(0).getTargetFlags();
1166 if (STI.hasLowByteFirst()) {
1168 MIB0.addGlobalAddress(GV, Offs, TF);
1169 MIB1.addGlobalAddress(GV, Offs + 1, TF);
1172 MIB0.addGlobalAddress(GV, Offs + 1, TF);
1173 MIB1.addGlobalAddress(GV, Offs, TF);
1179 unsigned Imm =
MI.getOperand(0).getImm();
1181 if (STI.hasLowByteFirst()) {
1184 MIB1.addImm(
Imm + 1);
1187 MIB0.addImm(
Imm + 1);
1197 if (STI.hasLowByteFirst()) {
1200 .setMemRefs(
MI.memoperands());
1202 .setMemRefs(
MI.memoperands());
1206 .setMemRefs(
MI.memoperands());
1208 .setMemRefs(
MI.memoperands());
1211 MI.eraseFromParent();
1216bool AVRExpandPseudo::expand<AVR::STWPtrRr>(
Block &
MBB, BlockIt
MBBI) {
1220 bool DstIsKill =
MI.getOperand(0).isKill();
1221 bool DstIsUndef =
MI.getOperand(0).isUndef();
1222 bool SrcIsKill =
MI.getOperand(1).isKill();
1225 if (STI.hasTinyEncoding()) {
1228 buildMI(
MBB,
MBBI, AVR::STDWPtrQRr)
1233 .setMemRefs(
MI.memoperands());
1237 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1238 if (STI.hasLowByteFirst()) {
1239 buildMI(
MBB,
MBBI, AVR::STPtrRr)
1242 .setMemRefs(
MI.memoperands());
1243 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1247 .setMemRefs(
MI.memoperands());
1249 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1253 .setMemRefs(
MI.memoperands());
1254 buildMI(
MBB,
MBBI, AVR::STPtrRr)
1257 .setMemRefs(
MI.memoperands());
1261 MI.eraseFromParent();
1266bool AVRExpandPseudo::expand<AVR::STWPtrPiRr>(
Block &
MBB, BlockIt
MBBI) {
1271 unsigned Imm =
MI.getOperand(3).getImm();
1272 bool DstIsDead =
MI.getOperand(0).isDead();
1273 bool SrcIsKill =
MI.getOperand(2).isKill();
1274 unsigned OpLo = AVR::STPtrPiRr;
1275 unsigned OpHi = AVR::STPtrPiRr;
1276 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1278 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
1280 auto MIBLO = buildMI(
MBB,
MBBI, OpLo)
1293 MIBLO.setMemRefs(
MI.memoperands());
1294 MIBHI.setMemRefs(
MI.memoperands());
1296 MI.eraseFromParent();
1301bool AVRExpandPseudo::expand<AVR::STWPtrPdRr>(
Block &
MBB, BlockIt
MBBI) {
1306 unsigned Imm =
MI.getOperand(3).getImm();
1307 bool DstIsDead =
MI.getOperand(0).isDead();
1308 bool SrcIsKill =
MI.getOperand(2).isKill();
1309 unsigned OpLo = AVR::STPtrPdRr;
1310 unsigned OpHi = AVR::STPtrPdRr;
1311 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1313 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
1315 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
1328 MIBLO.setMemRefs(
MI.memoperands());
1329 MIBHI.setMemRefs(
MI.memoperands());
1331 MI.eraseFromParent();
1336bool AVRExpandPseudo::expand<AVR::STDPtrQRr>(
Block &
MBB, BlockIt
MBBI) {
1342 if (!STI.hasTinyEncoding())
1346 bool DstIsKill =
MI.getOperand(0).isKill();
1347 unsigned Imm =
MI.getOperand(1).getImm();
1349 bool SrcIsKill =
MI.getOperand(2).isKill();
1351 assert((
Imm == 0 || !
TRI->regsOverlap(DstReg, SrcReg)) &&
1352 "Cannot adjust a pointer that holds the value to store");
1355 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, DstReg)
1357 .addImm(0x10000 -
Imm);
1359 buildMI(
MBB,
MBBI, AVR::STPtrRr)
1362 .setMemRefs(
MI.memoperands());
1364 if (
Imm != 0 && !DstIsKill)
1365 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, DstReg)
1369 MI.eraseFromParent();
1374bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(
Block &
MBB, BlockIt
MBBI) {
1379 bool DstIsKill =
MI.getOperand(0).isKill();
1380 unsigned Imm =
MI.getOperand(1).getImm();
1382 bool SrcIsKill =
MI.getOperand(2).isKill();
1388 if (
Imm >= 63 || STI.hasTinyEncoding()) {
1392 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, DstReg)
1394 .addImm(0x10000 -
Imm);
1398 buildMI(
MBB,
MBBI, AVR::STWPtrPiRr, DstReg)
1402 .setMemRefs(
MI.memoperands());
1408 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, DstReg)
1414 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1416 if (STI.hasLowByteFirst()) {
1417 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1421 .setMemRefs(
MI.memoperands());
1422 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1426 .setMemRefs(
MI.memoperands());
1428 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1432 .setMemRefs(
MI.memoperands());
1433 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1437 .setMemRefs(
MI.memoperands());
1441 MI.eraseFromParent();
1446bool AVRExpandPseudo::expand<AVR::STDSPQRr>(
Block &
MBB, BlockIt
MBBI) {
1451 assert(
MI.getOperand(0).getReg() == AVR::SP &&
1452 "SP is expected as base pointer");
1455 "unexpected STDSPQRr pseudo instruction");
1457 if (STI.hasTinyEncoding()) {
1460 unsigned Imm =
MI.getOperand(1).getImm();
1462 bool SrcIsKill =
MI.getOperand(2).isKill();
1465 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, AVR::R29R28)
1467 .addImm(0x10000 -
Imm);
1469 buildMI(
MBB,
MBBI, AVR::STPtrRr)
1472 .setMemRefs(
MI.memoperands());
1475 buildMI(
MBB, std::next(
MBBI), AVR::SUBIWRdK, AVR::R29R28)
1479 MI.eraseFromParent();
1481 MI.setDesc(
TII->get(AVR::STDPtrQRr));
1482 MI.getOperand(0).setReg(AVR::R29R28);
1489bool AVRExpandPseudo::expand<AVR::STDWSPQRr>(
Block &
MBB, BlockIt
MBBI) {
1494 assert(
MI.getOperand(0).getReg() == AVR::SP &&
1495 "SP is expected as base pointer");
1498 "unexpected STDWSPQRr pseudo instruction");
1501 MI.setDesc(
TII->get(AVR::STDWPtrQRr));
1502 MI.getOperand(0).setReg(AVR::R29R28);
1508bool AVRExpandPseudo::expand<AVR::INWRdA>(
Block &
MBB, BlockIt
MBBI) {
1511 unsigned Imm =
MI.getOperand(1).getImm();
1513 bool DstIsDead =
MI.getOperand(0).isDead();
1514 unsigned OpLo = AVR::INRdA;
1515 unsigned OpHi = AVR::INRdA;
1516 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1520 assert(
Imm <= 62 &&
"Address is out of range");
1532 MIBLO.setMemRefs(
MI.memoperands());
1533 MIBHI.setMemRefs(
MI.memoperands());
1535 MI.eraseFromParent();
1540bool AVRExpandPseudo::expand<AVR::OUTWARr>(
Block &
MBB, BlockIt
MBBI) {
1544 unsigned Imm =
MI.getOperand(0).getImm();
1546 bool SrcIsKill =
MI.getOperand(1).isKill();
1547 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1551 assert(
Imm <= 62 &&
"Address is out of range");
1555 auto MIBHI = buildMI(
MBB,
MBBI, AVR::OUTARr)
1556 .addImm(STI.hasLowByteFirst() ?
Imm :
Imm + 1)
1557 .addReg(STI.hasLowByteFirst() ? SrcLoReg : SrcHiReg,
1559 auto MIBLO = buildMI(
MBB,
MBBI, AVR::OUTARr)
1560 .addImm(STI.hasLowByteFirst() ?
Imm + 1 :
Imm)
1561 .addReg(STI.hasLowByteFirst() ? SrcHiReg : SrcLoReg,
1564 MIBLO.setMemRefs(
MI.memoperands());
1565 MIBHI.setMemRefs(
MI.memoperands());
1567 MI.eraseFromParent();
1572bool AVRExpandPseudo::expand<AVR::PUSHWRr>(
Block &
MBB, BlockIt
MBBI) {
1576 bool SrcIsKill =
MI.getOperand(0).isKill();
1577 unsigned Flags =
MI.getFlags();
1578 unsigned OpLo = AVR::PUSHRr;
1579 unsigned OpHi = AVR::PUSHRr;
1580 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1592 MI.eraseFromParent();
1597bool AVRExpandPseudo::expand<AVR::POPWRd>(
Block &
MBB, BlockIt
MBBI) {
1601 unsigned Flags =
MI.getFlags();
1602 unsigned OpLo = AVR::POPRd;
1603 unsigned OpHi = AVR::POPRd;
1604 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1606 buildMI(
MBB,
MBBI, OpHi, DstHiReg).setMIFlags(Flags);
1607 buildMI(
MBB,
MBBI, OpLo, DstLoReg).setMIFlags(Flags);
1609 MI.eraseFromParent();
1613bool AVRExpandPseudo::expandROLBRd(
Block &
MBB, BlockIt
MBBI) {
1621 unsigned OpShift, OpCarry;
1623 Register ZeroReg =
MI.getOperand(3).getReg();
1624 bool DstIsDead =
MI.getOperand(0).isDead();
1625 bool DstIsKill =
MI.getOperand(1).isKill();
1626 OpShift = AVR::ADDRdRr;
1627 OpCarry = AVR::ADCRdRr;
1639 auto MIB = buildMI(
MBB,
MBBI, OpCarry)
1644 MIB->getOperand(3).setIsDead();
1645 MIB->getOperand(4).setIsKill();
1647 MI.eraseFromParent();
1652bool AVRExpandPseudo::expand<AVR::ROLBRdR1>(
Block &
MBB, BlockIt
MBBI) {
1653 return expandROLBRd(
MBB,
MBBI);
1657bool AVRExpandPseudo::expand<AVR::ROLBRdR17>(
Block &
MBB, BlockIt
MBBI) {
1658 return expandROLBRd(
MBB,
MBBI);
1662bool AVRExpandPseudo::expand<AVR::RORBRd>(
Block &
MBB, BlockIt
MBBI) {
1677 buildMI(
MBB,
MBBI, AVR::BST).addReg(DstReg).addImm(0);
1680 buildMI(
MBB,
MBBI, AVR::RORRd, DstReg).addReg(DstReg);
1683 buildMI(
MBB,
MBBI, AVR::BLD, DstReg).addReg(DstReg).addImm(7);
1685 MI.eraseFromParent();
1690bool AVRExpandPseudo::expand<AVR::LSLWRd>(
Block &
MBB, BlockIt
MBBI) {
1694 bool DstIsDead =
MI.getOperand(0).isDead();
1695 bool DstIsKill =
MI.getOperand(1).isKill();
1696 bool ImpIsDead =
MI.getOperand(2).isDead();
1697 unsigned OpLo = AVR::ADDRdRr;
1698 unsigned OpHi = AVR::ADCRdRr;
1699 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1714 MIBHI->getOperand(3).setIsDead();
1717 MIBHI->getOperand(4).setIsKill();
1719 MI.eraseFromParent();
1724bool AVRExpandPseudo::expand<AVR::LSLWHiRd>(
Block &
MBB, BlockIt
MBBI) {
1728 bool DstIsDead =
MI.getOperand(0).isDead();
1729 bool DstIsKill =
MI.getOperand(1).isKill();
1730 bool ImpIsDead =
MI.getOperand(2).isDead();
1731 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1735 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
1741 MILSL->getOperand(3).setIsDead();
1743 MI.eraseFromParent();
1747bool AVRExpandPseudo::expandLSLW4Rd(
Block &
MBB, BlockIt
MBBI) {
1751 bool DstIsDead =
MI.getOperand(0).isDead();
1752 bool DstIsKill =
MI.getOperand(1).isKill();
1753 bool ImpIsDead =
MI.getOperand(3).isDead();
1754 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1758 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1761 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1767 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1772 MI0->getOperand(3).setIsDead();
1776 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1781 MI1->getOperand(3).setIsDead();
1785 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1790 MI2->getOperand(3).setIsDead();
1794 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1799 MI3->getOperand(3).setIsDead();
1801 MI.eraseFromParent();
1805bool AVRExpandPseudo::expandLSLW8Rd(
Block &
MBB, BlockIt
MBBI) {
1809 bool DstIsDead =
MI.getOperand(0).isDead();
1810 bool DstIsKill =
MI.getOperand(1).isKill();
1811 bool ImpIsDead =
MI.getOperand(3).isDead();
1812 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1815 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1821 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1826 MIBLO->getOperand(3).setIsDead();
1828 MI.eraseFromParent();
1832bool AVRExpandPseudo::expandLSLW12Rd(
Block &
MBB, BlockIt
MBBI) {
1836 bool DstIsDead =
MI.getOperand(0).isDead();
1837 bool DstIsKill =
MI.getOperand(1).isKill();
1838 bool ImpIsDead =
MI.getOperand(3).isDead();
1839 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1842 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1847 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1853 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1858 MI0->getOperand(3).setIsDead();
1862 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1867 MI1->getOperand(3).setIsDead();
1869 MI.eraseFromParent();
1874bool AVRExpandPseudo::expand<AVR::LSLWNRd>(
Block &
MBB, BlockIt
MBBI) {
1876 unsigned Imm =
MI.getOperand(2).getImm();
1879 return expandLSLW4Rd(
MBB,
MBBI);
1881 return expandLSLW8Rd(
MBB,
MBBI);
1883 return expandLSLW12Rd(
MBB,
MBBI);
1891bool AVRExpandPseudo::expand<AVR::LSRWRd>(
Block &
MBB, BlockIt
MBBI) {
1895 bool DstIsDead =
MI.getOperand(0).isDead();
1896 bool DstIsKill =
MI.getOperand(1).isKill();
1897 bool ImpIsDead =
MI.getOperand(2).isDead();
1898 unsigned OpLo = AVR::RORRd;
1899 unsigned OpHi = AVR::LSRRd;
1900 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1913 MIBLO->getOperand(2).setIsDead();
1916 MIBLO->getOperand(3).setIsKill();
1918 MI.eraseFromParent();
1923bool AVRExpandPseudo::expand<AVR::LSRWLoRd>(
Block &
MBB, BlockIt
MBBI) {
1927 bool DstIsDead =
MI.getOperand(0).isDead();
1928 bool DstIsKill =
MI.getOperand(1).isKill();
1929 bool ImpIsDead =
MI.getOperand(2).isDead();
1930 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1934 buildMI(
MBB,
MBBI, AVR::LSRRd)
1939 MILSR->getOperand(2).setIsDead();
1941 MI.eraseFromParent();
1945bool AVRExpandPseudo::expandLSRW4Rd(
Block &
MBB, BlockIt
MBBI) {
1949 bool DstIsDead =
MI.getOperand(0).isDead();
1950 bool DstIsKill =
MI.getOperand(1).isKill();
1951 bool ImpIsDead =
MI.getOperand(3).isDead();
1952 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1956 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1959 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1965 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1970 MI0->getOperand(3).setIsDead();
1974 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1979 MI1->getOperand(3).setIsDead();
1983 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1988 MI2->getOperand(3).setIsDead();
1992 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1997 MI3->getOperand(3).setIsDead();
1999 MI.eraseFromParent();
2003bool AVRExpandPseudo::expandLSRW8Rd(
Block &
MBB, BlockIt
MBBI) {
2007 bool DstIsDead =
MI.getOperand(0).isDead();
2008 bool DstIsKill =
MI.getOperand(1).isKill();
2009 bool ImpIsDead =
MI.getOperand(3).isDead();
2010 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2013 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2019 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2024 MIBHI->getOperand(3).setIsDead();
2026 MI.eraseFromParent();
2030bool AVRExpandPseudo::expandLSRW12Rd(
Block &
MBB, BlockIt
MBBI) {
2034 bool DstIsDead =
MI.getOperand(0).isDead();
2035 bool DstIsKill =
MI.getOperand(1).isKill();
2036 bool ImpIsDead =
MI.getOperand(3).isDead();
2037 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2040 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2045 buildMI(
MBB,
MBBI, AVR::SWAPRd)
2051 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
2056 MI0->getOperand(3).setIsDead();
2060 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2065 MIBHI->getOperand(3).setIsDead();
2067 MI.eraseFromParent();
2072bool AVRExpandPseudo::expand<AVR::LSRWNRd>(
Block &
MBB, BlockIt
MBBI) {
2074 unsigned Imm =
MI.getOperand(2).getImm();
2077 return expandLSRW4Rd(
MBB,
MBBI);
2079 return expandLSRW8Rd(
MBB,
MBBI);
2081 return expandLSRW12Rd(
MBB,
MBBI);
2089bool AVRExpandPseudo::expand<AVR::RORWRd>(
Block &
MBB, BlockIt
MBBI) {
2095bool AVRExpandPseudo::expand<AVR::ROLWRd>(
Block &
MBB, BlockIt
MBBI) {
2101bool AVRExpandPseudo::expand<AVR::ASRWRd>(
Block &
MBB, BlockIt
MBBI) {
2105 bool DstIsDead =
MI.getOperand(0).isDead();
2106 bool DstIsKill =
MI.getOperand(1).isKill();
2107 bool ImpIsDead =
MI.getOperand(2).isDead();
2108 unsigned OpLo = AVR::RORRd;
2109 unsigned OpHi = AVR::ASRRd;
2110 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2123 MIBLO->getOperand(2).setIsDead();
2126 MIBLO->getOperand(3).setIsKill();
2128 MI.eraseFromParent();
2133bool AVRExpandPseudo::expand<AVR::ASRWLoRd>(
Block &
MBB, BlockIt
MBBI) {
2137 bool DstIsDead =
MI.getOperand(0).isDead();
2138 bool DstIsKill =
MI.getOperand(1).isKill();
2139 bool ImpIsDead =
MI.getOperand(2).isDead();
2140 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2144 buildMI(
MBB,
MBBI, AVR::ASRRd)
2149 MIASR->getOperand(2).setIsDead();
2151 MI.eraseFromParent();
2155bool AVRExpandPseudo::expandASRW7Rd(
Block &
MBB, BlockIt
MBBI) {
2159 bool DstIsDead =
MI.getOperand(0).isDead();
2160 bool DstIsKill =
MI.getOperand(1).isKill();
2161 bool ImpIsDead =
MI.getOperand(3).isDead();
2162 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2170 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2176 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2181 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2188 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2194 MISBC->getOperand(3).setIsDead();
2196 MISBC->getOperand(4).setIsKill();
2198 MI.eraseFromParent();
2202bool AVRExpandPseudo::expandASRW8Rd(
Block &
MBB, BlockIt
MBBI) {
2206 bool DstIsDead =
MI.getOperand(0).isDead();
2207 bool DstIsKill =
MI.getOperand(1).isKill();
2208 bool ImpIsDead =
MI.getOperand(3).isDead();
2209 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2212 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2217 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2224 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2230 MIBHI->getOperand(3).setIsDead();
2232 MIBHI->getOperand(4).setIsKill();
2234 MI.eraseFromParent();
2237bool AVRExpandPseudo::expandASRW14Rd(
Block &
MBB, BlockIt
MBBI) {
2241 bool DstIsDead =
MI.getOperand(0).isDead();
2242 bool DstIsKill =
MI.getOperand(1).isKill();
2243 bool ImpIsDead =
MI.getOperand(3).isDead();
2244 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2253 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2259 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2265 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2271 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2277 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2283 MIROL->getOperand(3).setIsDead();
2285 MIROL->getOperand(4).setIsKill();
2287 MI.eraseFromParent();
2291bool AVRExpandPseudo::expandASRW15Rd(
Block &
MBB, BlockIt
MBBI) {
2295 bool DstIsDead =
MI.getOperand(0).isDead();
2296 bool ImpIsDead =
MI.getOperand(3).isDead();
2297 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2304 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2311 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2316 MISBC->getOperand(3).setIsDead();
2318 MISBC->getOperand(4).setIsKill();
2321 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2325 MI.eraseFromParent();
2330bool AVRExpandPseudo::expand<AVR::ASRWNRd>(
Block &
MBB, BlockIt
MBBI) {
2332 unsigned Imm =
MI.getOperand(2).getImm();
2335 return expandASRW7Rd(
MBB,
MBBI);
2337 return expandASRW8Rd(
MBB,
MBBI);
2339 return expandASRW14Rd(
MBB,
MBBI);
2341 return expandASRW15Rd(
MBB,
MBBI);
2348bool AVRExpandPseudo::expandLSLB7Rd(
Block &
MBB, BlockIt
MBBI) {
2351 bool DstIsDead =
MI.getOperand(0).isDead();
2352 bool DstIsKill =
MI.getOperand(1).isKill();
2353 bool ImpIsDead =
MI.getOperand(3).isDead();
2359 buildMI(
MBB,
MBBI, AVR::RORRd)
2365 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2371 buildMI(
MBB,
MBBI, AVR::RORRd)
2376 MIRRC->getOperand(2).setIsDead();
2379 MIRRC->getOperand(3).setIsKill();
2381 MI.eraseFromParent();
2386bool AVRExpandPseudo::expand<AVR::LSLBNRd>(
Block &
MBB, BlockIt
MBBI) {
2388 unsigned Imm =
MI.getOperand(2).getImm();
2391 return expandLSLB7Rd(
MBB,
MBBI);
2398bool AVRExpandPseudo::expandLSRB7Rd(
Block &
MBB, BlockIt
MBBI) {
2401 bool DstIsDead =
MI.getOperand(0).isDead();
2402 bool DstIsKill =
MI.getOperand(1).isKill();
2403 bool ImpIsDead =
MI.getOperand(3).isDead();
2409 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2416 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2422 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2428 MIRRC->getOperand(3).setIsDead();
2431 MIRRC->getOperand(4).setIsKill();
2433 MI.eraseFromParent();
2438bool AVRExpandPseudo::expand<AVR::LSRBNRd>(
Block &
MBB, BlockIt
MBBI) {
2440 unsigned Imm =
MI.getOperand(2).getImm();
2443 return expandLSRB7Rd(
MBB,
MBBI);
2450bool AVRExpandPseudo::expandASRB6Rd(
Block &
MBB, BlockIt
MBBI) {
2453 bool DstIsDead =
MI.getOperand(0).isDead();
2454 bool DstIsKill =
MI.getOperand(1).isKill();
2467 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2472 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2484 MI.eraseFromParent();
2488bool AVRExpandPseudo::expandASRB7Rd(
Block &
MBB, BlockIt
MBBI) {
2491 bool DstIsDead =
MI.getOperand(0).isDead();
2492 bool DstIsKill =
MI.getOperand(1).isKill();
2493 bool ImpIsDead =
MI.getOperand(3).isDead();
2498 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2504 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2510 MIRRC->getOperand(3).setIsDead();
2513 MIRRC->getOperand(4).setIsKill();
2515 MI.eraseFromParent();
2520bool AVRExpandPseudo::expand<AVR::ASRBNRd>(
Block &
MBB, BlockIt
MBBI) {
2522 unsigned Imm =
MI.getOperand(2).getImm();
2525 return expandASRB6Rd(
MBB,
MBBI);
2527 return expandASRB7Rd(
MBB,
MBBI);
2534template <>
bool AVRExpandPseudo::expand<AVR::SEXT>(
Block &
MBB, BlockIt
MBBI) {
2552 bool DstIsDead =
MI.getOperand(0).isDead();
2553 bool SrcIsKill =
MI.getOperand(1).isKill();
2554 bool ImpIsDead =
MI.getOperand(2).isDead();
2555 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2557 if (SrcReg != DstLoReg)
2558 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2562 if (SrcReg != DstHiReg) {
2563 auto MOV = buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2566 if (SrcReg != DstLoReg && SrcIsKill)
2567 MOV->getOperand(1).setIsKill();
2570 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2576 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2582 SBC->getOperand(3).setIsDead();
2585 SBC->getOperand(4).setIsKill();
2587 MI.eraseFromParent();
2591template <>
bool AVRExpandPseudo::expand<AVR::ZEXT>(
Block &
MBB, BlockIt
MBBI) {
2604 bool DstIsDead =
MI.getOperand(0).isDead();
2605 bool SrcIsKill =
MI.getOperand(1).isKill();
2606 bool ImpIsDead =
MI.getOperand(2).isDead();
2607 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2609 if (SrcReg != DstLoReg) {
2610 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2616 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2622 EOR->getOperand(3).setIsDead();
2624 MI.eraseFromParent();
2629bool AVRExpandPseudo::expand<AVR::SPREAD>(
Block &
MBB, BlockIt
MBBI) {
2634 bool DstIsDead =
MI.getOperand(0).isDead();
2635 unsigned Flags =
MI.getFlags();
2636 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2639 buildMI(
MBB,
MBBI, AVR::INRdA)
2646 buildMI(
MBB,
MBBI, AVR::INRdA)
2653 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2659 MI0->getOperand(3).setIsDead();
2662 MI.eraseFromParent();
2667bool AVRExpandPseudo::expand<AVR::SPWRITE>(
Block &
MBB, BlockIt
MBBI) {
2672 bool SrcIsKill =
MI.getOperand(1).isKill();
2673 unsigned Flags =
MI.getFlags();
2674 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
2681 buildMI(
MBB,
MBBI, AVR::OUTARr)
2686 buildMI(
MBB,
MBBI, AVR::OUTARr)
2693 buildMI(
MBB,
MBBI, AVR::INRdA)
2698 buildMI(
MBB,
MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
2700 buildMI(
MBB,
MBBI, AVR::OUTARr)
2705 buildMI(
MBB,
MBBI, AVR::OUTARr)
2711 buildMI(
MBB,
MBBI, AVR::OUTARr)
2717 MI.eraseFromParent();
2721template <>
bool AVRExpandPseudo::expand<AVR::FRMSP>(
Block &
MBB, BlockIt
MBBI) {
2726 Register ASOPointer =
MI.getOperand(0).getReg();
2727 int64_t ASOAlignment =
MI.getOperand(1).getImm();
2739 TII->copyPhysReg(
MBB,
MI,
DL, ASOPointer, AVR::R29R28,
false,
false,
false);
2741 buildMI(
MBB,
MI, AVR::ADIWRdKP)
2744 .addImm(ASOOffset.
getFixed() + ASOAlignment - 1)
2747 buildMI(
MBB,
MI, AVR::ANDIWRdK)
2750 .addImm(-ASOAlignment)
2753 MI.eraseFromParent();
2757bool AVRExpandPseudo::expandMI(
Block &
MBB, BlockIt
MBBI) {
2759 int Opcode =
MBBI->getOpcode();
2763 return expand<Op>(MBB, MI)
2797 EXPAND(AVR::AtomicLoad8);
2798 EXPAND(AVR::AtomicLoad16);
2799 EXPAND(AVR::AtomicStore8);
2800 EXPAND(AVR::AtomicStore16);
2801 EXPAND(AVR::AtomicFence);
2847 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)