31#define AVR_EXPAND_PSEUDO_NAME "AVR pseudo instruction expansion pass"
53class AVRExpandPseudoImpl {
74 return MBB.getParent()->getRegInfo();
77 bool expandArith(
unsigned OpLo,
unsigned OpHi,
Block &
MBB, BlockIt
MBBI);
80 bool isLogicImmOpRedundant(
unsigned Op,
unsigned ImmVal)
const;
81 bool isLogicRegOpUndef(
unsigned Op,
unsigned ImmVal)
const;
83 template <
typename Func>
bool expandAtomic(
Block &
MBB, BlockIt
MBBI, Func f);
85 template <
typename Func>
86 bool expandAtomicBinaryOp(
unsigned Opcode,
Block &
MBB, BlockIt
MBBI, Func f);
88 bool expandAtomicBinaryOp(
unsigned Opcode,
Block &
MBB, BlockIt
MBBI);
109 bool expandLPMWELPMW(
Block &
MBB, BlockIt
MBBI,
bool IsELPM);
111 bool expandLPMBELPMB(
Block &
MBB, BlockIt
MBBI,
bool IsELPM);
119char AVRExpandPseudoLegacy::ID = 0;
126 BlockIt NMBBI = std::next(
MBBI);
142 bool ContinueExpanding =
true;
143 unsigned ExpandCount = 0;
147 assert(ExpandCount < 10 &&
"pseudo expand limit reached");
154 ContinueExpanding = BlockModified;
155 }
while (ContinueExpanding);
161bool AVRExpandPseudoImpl::expandArith(
unsigned OpLo,
unsigned OpHi,
Block &
MBB,
164 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
167 bool DstIsDead =
MI.getOperand(0).isDead();
168 bool DstIsKill =
MI.getOperand(1).isKill();
169 bool SrcIsKill =
MI.getOperand(2).isKill();
170 bool ImpIsDead =
MI.getOperand(3).isDead();
171 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
172 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
186 MIBHI->getOperand(3).setIsDead();
189 MIBHI->getOperand(4).setIsKill();
191 MI.eraseFromParent();
195bool AVRExpandPseudoImpl::expandLogic(
unsigned Op,
Block &
MBB, BlockIt
MBBI) {
197 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
200 bool DstIsDead =
MI.getOperand(0).isDead();
201 bool DstIsKill =
MI.getOperand(1).isKill();
202 bool SrcIsKill =
MI.getOperand(2).isKill();
203 bool ImpIsDead =
MI.getOperand(3).isDead();
204 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
205 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
214 MIBLO->getOperand(3).setIsDead();
223 MIBHI->getOperand(3).setIsDead();
225 MI.eraseFromParent();
229bool AVRExpandPseudoImpl::isLogicImmOpRedundant(
unsigned Op,
230 unsigned ImmVal)
const {
233 if (
Op == AVR::ANDIRdK && ImmVal == 0xff)
237 if (
Op == AVR::ORIRdK && ImmVal == 0x0)
243bool AVRExpandPseudoImpl::isLogicRegOpUndef(
unsigned Op,
244 unsigned ImmVal)
const {
246 if (
Op == AVR::ANDIRdK && ImmVal == 0x00)
250 if (
Op == AVR::ORIRdK && ImmVal == 0xff)
256bool AVRExpandPseudoImpl::expandLogicImm(
unsigned Op,
Block &
MBB,
261 bool DstIsDead =
MI.getOperand(0).isDead();
262 bool SrcIsKill =
MI.getOperand(1).isKill();
263 bool ImpIsDead =
MI.getOperand(3).isDead();
264 unsigned Imm =
MI.getOperand(2).getImm();
265 unsigned Lo8 =
Imm & 0xff;
266 unsigned Hi8 = (
Imm >> 8) & 0xff;
267 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
269 if (!isLogicImmOpRedundant(
Op, Lo8)) {
277 MIBLO->getOperand(3).setIsDead();
279 if (isLogicRegOpUndef(
Op, Lo8))
280 MIBLO->getOperand(1).setIsUndef(
true);
283 if (!isLogicImmOpRedundant(
Op, Hi8)) {
291 MIBHI->getOperand(3).setIsDead();
293 if (isLogicRegOpUndef(
Op, Hi8))
294 MIBHI->getOperand(1).setIsUndef(
true);
297 MI.eraseFromParent();
302bool AVRExpandPseudoImpl::expand<AVR::ADDWRdRr>(
Block &
MBB, BlockIt
MBBI) {
303 return expandArith(AVR::ADDRdRr, AVR::ADCRdRr,
MBB,
MBBI);
307bool AVRExpandPseudoImpl::expand<AVR::ADCWRdRr>(
Block &
MBB, BlockIt
MBBI) {
308 return expandArith(AVR::ADCRdRr, AVR::ADCRdRr,
MBB,
MBBI);
312bool AVRExpandPseudoImpl::expand<AVR::ADIWRdKP>(
Block &
MBB, BlockIt
MBBI) {
317 int64_t
Imm =
MI.getOperand(2).getImm();
320 if (SrcReg != DstReg) {
321 TII->copyPhysReg(
MBB,
MI,
MI.getDebugLoc(), DstReg, SrcReg,
false,
false,
326 AVR::IWREGSRegClass.contains(DstReg)) {
327 Opcode = AVR::ADIWRdK;
329 Opcode = AVR::SUBIWRdK;
333 buildMI(
MBB,
MI, Opcode)
339 MI.eraseFromParent();
344bool AVRExpandPseudoImpl::expand<AVR::SUBWRdRr>(
Block &
MBB, BlockIt
MBBI) {
345 return expandArith(AVR::SUBRdRr, AVR::SBCRdRr,
MBB,
MBBI);
349bool AVRExpandPseudoImpl::expand<AVR::SUBIWRdK>(
Block &
MBB, BlockIt
MBBI) {
353 bool DstIsDead =
MI.getOperand(0).isDead();
354 bool SrcIsKill =
MI.getOperand(1).isKill();
355 bool ImpIsDead =
MI.getOperand(3).isDead();
356 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
359 buildMI(
MBB,
MBBI, AVR::SUBIRdK)
364 buildMI(
MBB,
MBBI, AVR::SBCIRdK)
368 switch (
MI.getOperand(2).getType()) {
371 int64_t Offs =
MI.getOperand(2).getOffset();
372 unsigned TF =
MI.getOperand(2).getTargetFlags();
378 unsigned Imm =
MI.getOperand(2).getImm();
379 MIBLO.addImm(
Imm & 0xff);
380 MIBHI.addImm((
Imm >> 8) & 0xff);
388 MIBHI->getOperand(3).setIsDead();
391 MIBHI->getOperand(4).setIsKill();
393 MI.eraseFromParent();
398bool AVRExpandPseudoImpl::expand<AVR::SBCWRdRr>(
Block &
MBB, BlockIt
MBBI) {
399 return expandArith(AVR::SBCRdRr, AVR::SBCRdRr,
MBB,
MBBI);
403bool AVRExpandPseudoImpl::expand<AVR::SBCIWRdK>(
Block &
MBB, BlockIt
MBBI) {
407 bool DstIsDead =
MI.getOperand(0).isDead();
408 bool SrcIsKill =
MI.getOperand(1).isKill();
409 bool ImpIsDead =
MI.getOperand(3).isDead();
410 unsigned Imm =
MI.getOperand(2).getImm();
411 unsigned Lo8 =
Imm & 0xff;
412 unsigned Hi8 = (
Imm >> 8) & 0xff;
413 unsigned OpLo = AVR::SBCIRdK;
414 unsigned OpHi = AVR::SBCIRdK;
415 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
424 MIBLO->getOperand(4).setIsKill();
433 MIBHI->getOperand(3).setIsDead();
436 MIBHI->getOperand(4).setIsKill();
438 MI.eraseFromParent();
443bool AVRExpandPseudoImpl::expand<AVR::ANDWRdRr>(
Block &
MBB, BlockIt
MBBI) {
444 return expandLogic(AVR::ANDRdRr,
MBB,
MBBI);
448bool AVRExpandPseudoImpl::expand<AVR::ANDIWRdK>(
Block &
MBB, BlockIt
MBBI) {
449 return expandLogicImm(AVR::ANDIRdK,
MBB,
MBBI);
453bool AVRExpandPseudoImpl::expand<AVR::ORWRdRr>(
Block &
MBB, BlockIt
MBBI) {
454 return expandLogic(AVR::ORRdRr,
MBB,
MBBI);
458bool AVRExpandPseudoImpl::expand<AVR::ORIWRdK>(
Block &
MBB, BlockIt
MBBI) {
459 return expandLogicImm(AVR::ORIRdK,
MBB,
MBBI);
463bool AVRExpandPseudoImpl::expand<AVR::EORWRdRr>(
Block &
MBB, BlockIt
MBBI) {
464 return expandLogic(AVR::EORRdRr,
MBB,
MBBI);
468bool AVRExpandPseudoImpl::expand<AVR::COMWRd>(
Block &
MBB, BlockIt
MBBI) {
472 bool DstIsDead =
MI.getOperand(0).isDead();
473 bool DstIsKill =
MI.getOperand(1).isKill();
474 bool ImpIsDead =
MI.getOperand(2).isDead();
475 unsigned OpLo = AVR::COMRd;
476 unsigned OpHi = AVR::COMRd;
477 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
485 MIBLO->getOperand(2).setIsDead();
493 MIBHI->getOperand(2).setIsDead();
495 MI.eraseFromParent();
500bool AVRExpandPseudoImpl::expand<AVR::NEGWRd>(
Block &
MBB, BlockIt
MBBI) {
505 bool DstIsDead =
MI.getOperand(0).isDead();
506 bool DstIsKill =
MI.getOperand(1).isKill();
507 bool ImpIsDead =
MI.getOperand(2).isDead();
508 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
516 MIBHI->getOperand(2).setIsDead();
525 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
530 MISBCI->getOperand(3).setIsDead();
532 MISBCI->getOperand(4).setIsKill();
534 MI.eraseFromParent();
539bool AVRExpandPseudoImpl::expand<AVR::CPWRdRr>(
Block &
MBB, BlockIt
MBBI) {
541 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
544 bool DstIsKill =
MI.getOperand(0).isKill();
545 bool SrcIsKill =
MI.getOperand(1).isKill();
546 bool ImpIsDead =
MI.getOperand(2).isDead();
547 unsigned OpLo = AVR::CPRdRr;
548 unsigned OpHi = AVR::CPCRdRr;
549 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
550 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
557 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
562 MIBHI->getOperand(2).setIsDead();
565 MIBHI->getOperand(3).setIsKill();
567 MI.eraseFromParent();
572bool AVRExpandPseudoImpl::expand<AVR::CPCWRdRr>(
Block &
MBB, BlockIt
MBBI) {
574 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
577 bool DstIsKill =
MI.getOperand(0).isKill();
578 bool SrcIsKill =
MI.getOperand(1).isKill();
579 bool ImpIsDead =
MI.getOperand(2).isDead();
580 unsigned OpLo = AVR::CPCRdRr;
581 unsigned OpHi = AVR::CPCRdRr;
582 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
583 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
585 auto MIBLO = buildMI(
MBB,
MBBI, OpLo)
590 MIBLO->getOperand(3).setIsKill();
592 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
597 MIBHI->getOperand(2).setIsDead();
600 MIBHI->getOperand(3).setIsKill();
602 MI.eraseFromParent();
607bool AVRExpandPseudoImpl::expand<AVR::LDIWRdK>(
Block &
MBB, BlockIt
MBBI) {
611 bool DstIsDead =
MI.getOperand(0).isDead();
612 unsigned OpLo = AVR::LDIRdK;
613 unsigned OpHi = AVR::LDIRdK;
614 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
624 switch (
MI.getOperand(1).getType()) {
627 int64_t Offs =
MI.getOperand(1).getOffset();
628 unsigned TF =
MI.getOperand(1).getTargetFlags();
636 unsigned TF =
MI.getOperand(1).getTargetFlags();
643 unsigned Imm =
MI.getOperand(1).getImm();
645 MIBLO.addImm(
Imm & 0xff);
646 MIBHI.addImm((
Imm >> 8) & 0xff);
653 MI.eraseFromParent();
658bool AVRExpandPseudoImpl::expand<AVR::LDSWRdK>(
Block &
MBB, BlockIt
MBBI) {
662 bool DstIsDead =
MI.getOperand(0).isDead();
663 unsigned OpLo = AVR::LDSRdK;
664 unsigned OpHi = AVR::LDSRdK;
665 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
675 switch (
MI.getOperand(1).getType()) {
678 int64_t Offs =
MI.getOperand(1).getOffset();
679 unsigned TF =
MI.getOperand(1).getTargetFlags();
681 MIBLO.addGlobalAddress(GV, Offs, TF);
682 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
686 unsigned Imm =
MI.getOperand(1).getImm();
689 MIBHI.addImm(
Imm + 1);
696 MIBLO.setMemRefs(
MI.memoperands());
697 MIBHI.setMemRefs(
MI.memoperands());
699 MI.eraseFromParent();
704bool AVRExpandPseudoImpl::expand<AVR::LDWRdPtr>(
Block &
MBB, BlockIt
MBBI) {
708 bool DstIsKill =
MI.getOperand(0).isKill();
709 bool SrcIsKill =
MI.getOperand(1).isKill();
714 assert(DstReg != SrcReg &&
"Dst and Src registers are the same!");
716 if (STI.hasTinyEncoding()) {
719 buildMI(
MBB,
MBBI, AVR::LDDWRdPtrQ)
723 .setMemRefs(
MI.memoperands());
727 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
730 buildMI(
MBB,
MBBI, AVR::LDRdPtr)
733 .setMemRefs(
MI.memoperands());
736 buildMI(
MBB,
MBBI, AVR::LDDRdPtrQ)
740 .setMemRefs(
MI.memoperands());
743 MI.eraseFromParent();
748bool AVRExpandPseudoImpl::expand<AVR::LDWRdPtrPi>(
Block &
MBB, BlockIt
MBBI) {
753 bool DstIsDead =
MI.getOperand(0).isDead();
754 bool SrcIsDead =
MI.getOperand(1).isKill();
755 unsigned OpLo = AVR::LDRdPtrPi;
756 unsigned OpHi = AVR::LDRdPtrPi;
757 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
759 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
773 MIBLO.setMemRefs(
MI.memoperands());
774 MIBHI.setMemRefs(
MI.memoperands());
776 MI.eraseFromParent();
781bool AVRExpandPseudoImpl::expand<AVR::LDWRdPtrPd>(
Block &
MBB, BlockIt
MBBI) {
786 bool DstIsDead =
MI.getOperand(0).isDead();
787 bool SrcIsDead =
MI.getOperand(1).isKill();
788 unsigned OpLo = AVR::LDRdPtrPd;
789 unsigned OpHi = AVR::LDRdPtrPd;
790 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
792 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
806 MIBLO.setMemRefs(
MI.memoperands());
807 MIBHI.setMemRefs(
MI.memoperands());
809 MI.eraseFromParent();
814bool AVRExpandPseudoImpl::expand<AVR::LDDRdPtrQ>(
Block &
MBB, BlockIt
MBBI) {
820 if (!STI.hasTinyEncoding())
824 bool DstIsDead =
MI.getOperand(0).isDead();
826 bool SrcIsKill =
MI.getOperand(1).isKill();
827 unsigned Imm =
MI.getOperand(2).getImm();
829 assert((
Imm == 0 || SrcIsKill || !
TRI->regsOverlap(DstReg, SrcReg)) &&
830 "Cannot restore a pointer that the load overwrites");
833 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, SrcReg)
835 .addImm(0x10000 -
Imm);
837 buildMI(
MBB,
MBBI, AVR::LDRdPtr)
840 .setMemRefs(
MI.memoperands());
842 if (
Imm != 0 && !SrcIsKill)
843 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, SrcReg)
847 MI.eraseFromParent();
852bool AVRExpandPseudoImpl::expand<AVR::LDDWRdPtrQ>(
Block &
MBB, BlockIt
MBBI) {
856 unsigned Imm =
MI.getOperand(2).getImm();
857 bool DstIsKill =
MI.getOperand(0).isKill();
858 bool SrcIsKill =
MI.getOperand(1).isKill();
863 assert(
Imm <= 62 &&
"Offset is out of range");
867 assert(DstReg != SrcReg &&
"Dst and Src registers are the same!");
869 if (STI.hasTinyEncoding()) {
877 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, SrcReg)
879 .addImm(0x10000 -
Imm);
884 buildMI(
MBB,
MBBI, AVR::LDWRdPtrPi)
888 .setMemRefs(
MI.memoperands());
894 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, SrcReg).addReg(SrcReg).addImm(
Imm + 2);
898 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
901 buildMI(
MBB,
MBBI, AVR::LDDRdPtrQ)
905 .setMemRefs(
MI.memoperands());
908 buildMI(
MBB,
MBBI, AVR::LDDRdPtrQ)
912 .setMemRefs(
MI.memoperands());
915 MI.eraseFromParent();
919bool AVRExpandPseudoImpl::expandLPMWELPMW(
Block &
MBB, BlockIt
MBBI,
926 bool SrcIsKill =
MI.getOperand(1).isKill();
928 bool IsLPMRn = IsELPM ? STI.hasELPMX() : STI.hasLPMX();
930 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
931 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
941 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
944 unsigned OpLo = IsELPM ? AVR::ELPMRdZPi : AVR::LPMRdZPi;
945 unsigned OpHi = IsELPM ? AVR::ELPMRdZ : AVR::LPMRdZ;
947 auto MIBLO = buildMI(
MBB,
MBBI, OpLo)
951 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
954 MIBLO.setMemRefs(
MI.memoperands());
955 MIBHI.setMemRefs(
MI.memoperands());
957 unsigned Opc = IsELPM ? AVR::ELPM : AVR::LPM;
960 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
963 MIBLO.setMemRefs(
MI.memoperands());
965 if (STI.hasADDSUBIW()) {
967 auto MIINC = buildMI(
MBB,
MBBI, AVR::ADIWRdK)
971 MIINC->getOperand(3).setIsDead();
975 buildMI(
MBB,
MBBI, AVR::SUBIRdK)
979 auto MIZHI = buildMI(
MBB,
MBBI, AVR::SBCIRdK)
983 MIZHI->getOperand(3).setIsDead();
984 MIZHI->getOperand(4).setIsKill();
988 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
991 MIBHI.setMemRefs(
MI.memoperands());
996 if (STI.hasADDSUBIW()) {
998 auto MIDEC = buildMI(
MBB,
MBBI, AVR::SBIWRdK)
1002 MIDEC->getOperand(3).setIsDead();
1006 buildMI(
MBB,
MBBI, AVR::SUBIRdK)
1010 auto MIZHI = buildMI(
MBB,
MBBI, AVR::SBCIRdK)
1014 MIZHI->getOperand(3).setIsDead();
1015 MIZHI->getOperand(4).setIsKill();
1019 MI.eraseFromParent();
1024bool AVRExpandPseudoImpl::expand<AVR::LPMWRdZ>(
Block &
MBB, BlockIt
MBBI) {
1025 return expandLPMWELPMW(
MBB,
MBBI,
false);
1029bool AVRExpandPseudoImpl::expand<AVR::ELPMWRdZ>(
Block &
MBB, BlockIt
MBBI) {
1030 return expandLPMWELPMW(
MBB,
MBBI,
true);
1033bool AVRExpandPseudoImpl::expandLPMBELPMB(
Block &
MBB, BlockIt
MBBI,
1038 bool SrcIsKill =
MI.getOperand(1).isKill();
1040 bool IsLPMRn = IsELPM ? STI.hasELPMX() : STI.hasLPMX();
1044 Register BankReg =
MI.getOperand(2).getReg();
1050 unsigned Opc = IsELPM ? AVR::ELPMRdZ : AVR::LPMRdZ;
1054 MILB.setMemRefs(
MI.memoperands());
1058 unsigned Opc = IsELPM ? AVR::ELPM : AVR::LPM;
1060 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1063 MILB.setMemRefs(
MI.memoperands());
1066 MI.eraseFromParent();
1071bool AVRExpandPseudoImpl::expand<AVR::ELPMBRdZ>(
Block &
MBB, BlockIt
MBBI) {
1072 return expandLPMBELPMB(
MBB,
MBBI,
true);
1076bool AVRExpandPseudoImpl::expand<AVR::LPMBRdZ>(
Block &
MBB, BlockIt
MBBI) {
1077 return expandLPMBELPMB(
MBB,
MBBI,
false);
1081bool AVRExpandPseudoImpl::expand<AVR::LPMWRdZPi>(
Block &
MBB, BlockIt
MBBI) {
1086bool AVRExpandPseudoImpl::expand<AVR::ELPMBRdZPi>(
Block &
MBB, BlockIt
MBBI) {
1091bool AVRExpandPseudoImpl::expand<AVR::ELPMWRdZPi>(
Block &
MBB, BlockIt
MBBI) {
1095template <
typename Func>
1096bool AVRExpandPseudoImpl::expandAtomic(
Block &
MBB, BlockIt
MBBI, Func f) {
1101 buildMI(
MBB,
MBBI, AVR::INRdA)
1106 buildMI(
MBB,
MBBI, AVR::BCLRs).addImm(7);
1111 buildMI(
MBB,
MBBI, AVR::OUTARr)
1115 MI.eraseFromParent();
1119template <
typename Func>
1120bool AVRExpandPseudoImpl::expandAtomicBinaryOp(
unsigned Opcode,
Block &
MBB,
1121 BlockIt
MBBI, Func f) {
1123 auto Op1 =
MI.getOperand(0);
1124 auto Op2 =
MI.getOperand(1);
1127 *buildMI(
MBB,
MBBI, Opcode).add(Op1).add(Op2).getInstr();
1132bool AVRExpandPseudoImpl::expandAtomicBinaryOp(
unsigned Opcode,
Block &
MBB,
1138bool AVRExpandPseudoImpl::expand<AVR::AtomicLoad8>(
Block &
MBB, BlockIt
MBBI) {
1139 return expandAtomicBinaryOp(AVR::LDRdPtr,
MBB,
MBBI);
1143bool AVRExpandPseudoImpl::expand<AVR::AtomicLoad16>(
Block &
MBB, BlockIt
MBBI) {
1144 return expandAtomicBinaryOp(AVR::LDWRdPtr,
MBB,
MBBI);
1148bool AVRExpandPseudoImpl::expand<AVR::AtomicStore8>(
Block &
MBB, BlockIt
MBBI) {
1149 return expandAtomicBinaryOp(AVR::STPtrRr,
MBB,
MBBI);
1153bool AVRExpandPseudoImpl::expand<AVR::AtomicStore16>(
Block &
MBB, BlockIt
MBBI) {
1154 return expandAtomicBinaryOp(AVR::STWPtrRr,
MBB,
MBBI);
1158bool AVRExpandPseudoImpl::expand<AVR::AtomicFence>(
Block &
MBB, BlockIt
MBBI) {
1160 MBBI->eraseFromParent();
1165bool AVRExpandPseudoImpl::expand<AVR::STSWKRr>(
Block &
MBB, BlockIt
MBBI) {
1170 bool SrcIsKill =
MI.getOperand(1).isKill();
1171 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1173 auto MIB0 = buildMI(
MBB,
MBBI, AVR::STSKRr);
1174 auto MIB1 = buildMI(
MBB,
MBBI, AVR::STSKRr);
1176 switch (
MI.getOperand(0).getType()) {
1179 int64_t Offs =
MI.getOperand(0).getOffset();
1180 unsigned TF =
MI.getOperand(0).getTargetFlags();
1182 if (STI.hasLowByteFirst()) {
1184 MIB0.addGlobalAddress(GV, Offs, TF);
1185 MIB1.addGlobalAddress(GV, Offs + 1, TF);
1188 MIB0.addGlobalAddress(GV, Offs + 1, TF);
1189 MIB1.addGlobalAddress(GV, Offs, TF);
1195 unsigned Imm =
MI.getOperand(0).getImm();
1197 if (STI.hasLowByteFirst()) {
1200 MIB1.addImm(
Imm + 1);
1203 MIB0.addImm(
Imm + 1);
1213 if (STI.hasLowByteFirst()) {
1216 .setMemRefs(
MI.memoperands());
1218 .setMemRefs(
MI.memoperands());
1222 .setMemRefs(
MI.memoperands());
1224 .setMemRefs(
MI.memoperands());
1227 MI.eraseFromParent();
1232bool AVRExpandPseudoImpl::expand<AVR::STWPtrRr>(
Block &
MBB, BlockIt
MBBI) {
1236 bool DstIsKill =
MI.getOperand(0).isKill();
1237 bool DstIsUndef =
MI.getOperand(0).isUndef();
1238 bool SrcIsKill =
MI.getOperand(1).isKill();
1241 if (STI.hasTinyEncoding()) {
1244 buildMI(
MBB,
MBBI, AVR::STDWPtrQRr)
1249 .setMemRefs(
MI.memoperands());
1253 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1254 if (STI.hasLowByteFirst()) {
1255 buildMI(
MBB,
MBBI, AVR::STPtrRr)
1258 .setMemRefs(
MI.memoperands());
1259 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1263 .setMemRefs(
MI.memoperands());
1265 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1269 .setMemRefs(
MI.memoperands());
1270 buildMI(
MBB,
MBBI, AVR::STPtrRr)
1273 .setMemRefs(
MI.memoperands());
1277 MI.eraseFromParent();
1282bool AVRExpandPseudoImpl::expand<AVR::STWPtrPiRr>(
Block &
MBB, BlockIt
MBBI) {
1287 unsigned Imm =
MI.getOperand(3).getImm();
1288 bool DstIsDead =
MI.getOperand(0).isDead();
1289 bool SrcIsKill =
MI.getOperand(2).isKill();
1290 unsigned OpLo = AVR::STPtrPiRr;
1291 unsigned OpHi = AVR::STPtrPiRr;
1292 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1294 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
1296 auto MIBLO = buildMI(
MBB,
MBBI, OpLo)
1309 MIBLO.setMemRefs(
MI.memoperands());
1310 MIBHI.setMemRefs(
MI.memoperands());
1312 MI.eraseFromParent();
1317bool AVRExpandPseudoImpl::expand<AVR::STWPtrPdRr>(
Block &
MBB, BlockIt
MBBI) {
1322 unsigned Imm =
MI.getOperand(3).getImm();
1323 bool DstIsDead =
MI.getOperand(0).isDead();
1324 bool SrcIsKill =
MI.getOperand(2).isKill();
1325 unsigned OpLo = AVR::STPtrPdRr;
1326 unsigned OpHi = AVR::STPtrPdRr;
1327 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1329 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
1331 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
1344 MIBLO.setMemRefs(
MI.memoperands());
1345 MIBHI.setMemRefs(
MI.memoperands());
1347 MI.eraseFromParent();
1352bool AVRExpandPseudoImpl::expand<AVR::STDPtrQRr>(
Block &
MBB, BlockIt
MBBI) {
1358 if (!STI.hasTinyEncoding())
1362 bool DstIsKill =
MI.getOperand(0).isKill();
1363 unsigned Imm =
MI.getOperand(1).getImm();
1365 bool SrcIsKill =
MI.getOperand(2).isKill();
1367 assert((
Imm == 0 || !
TRI->regsOverlap(DstReg, SrcReg)) &&
1368 "Cannot adjust a pointer that holds the value to store");
1371 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, DstReg)
1373 .addImm(0x10000 -
Imm);
1375 buildMI(
MBB,
MBBI, AVR::STPtrRr)
1378 .setMemRefs(
MI.memoperands());
1380 if (
Imm != 0 && !DstIsKill)
1381 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, DstReg)
1385 MI.eraseFromParent();
1390bool AVRExpandPseudoImpl::expand<AVR::STDWPtrQRr>(
Block &
MBB, BlockIt
MBBI) {
1395 bool DstIsKill =
MI.getOperand(0).isKill();
1396 unsigned Imm =
MI.getOperand(1).getImm();
1398 bool SrcIsKill =
MI.getOperand(2).isKill();
1404 if (
Imm >= 63 || STI.hasTinyEncoding()) {
1408 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, DstReg)
1410 .addImm(0x10000 -
Imm);
1414 buildMI(
MBB,
MBBI, AVR::STWPtrPiRr, DstReg)
1418 .setMemRefs(
MI.memoperands());
1424 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, DstReg)
1430 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1432 if (STI.hasLowByteFirst()) {
1433 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1437 .setMemRefs(
MI.memoperands());
1438 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1442 .setMemRefs(
MI.memoperands());
1444 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1448 .setMemRefs(
MI.memoperands());
1449 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1453 .setMemRefs(
MI.memoperands());
1457 MI.eraseFromParent();
1462bool AVRExpandPseudoImpl::expand<AVR::STDSPQRr>(
Block &
MBB, BlockIt
MBBI) {
1467 assert(
MI.getOperand(0).getReg() == AVR::SP &&
1468 "SP is expected as base pointer");
1471 "unexpected STDSPQRr pseudo instruction");
1473 if (STI.hasTinyEncoding()) {
1476 unsigned Imm =
MI.getOperand(1).getImm();
1478 bool SrcIsKill =
MI.getOperand(2).isKill();
1481 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, AVR::R29R28)
1483 .addImm(0x10000 -
Imm);
1485 buildMI(
MBB,
MBBI, AVR::STPtrRr)
1488 .setMemRefs(
MI.memoperands());
1491 buildMI(
MBB, std::next(
MBBI), AVR::SUBIWRdK, AVR::R29R28)
1495 MI.eraseFromParent();
1497 MI.setDesc(
TII->get(AVR::STDPtrQRr));
1498 MI.getOperand(0).setReg(AVR::R29R28);
1505bool AVRExpandPseudoImpl::expand<AVR::STDWSPQRr>(
Block &
MBB, BlockIt
MBBI) {
1510 assert(
MI.getOperand(0).getReg() == AVR::SP &&
1511 "SP is expected as base pointer");
1514 "unexpected STDWSPQRr pseudo instruction");
1517 MI.setDesc(
TII->get(AVR::STDWPtrQRr));
1518 MI.getOperand(0).setReg(AVR::R29R28);
1524bool AVRExpandPseudoImpl::expand<AVR::INWRdA>(
Block &
MBB, BlockIt
MBBI) {
1527 unsigned Imm =
MI.getOperand(1).getImm();
1529 bool DstIsDead =
MI.getOperand(0).isDead();
1530 unsigned OpLo = AVR::INRdA;
1531 unsigned OpHi = AVR::INRdA;
1532 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1536 assert(
Imm <= 62 &&
"Address is out of range");
1548 MIBLO.setMemRefs(
MI.memoperands());
1549 MIBHI.setMemRefs(
MI.memoperands());
1551 MI.eraseFromParent();
1556bool AVRExpandPseudoImpl::expand<AVR::OUTWARr>(
Block &
MBB, BlockIt
MBBI) {
1560 unsigned Imm =
MI.getOperand(0).getImm();
1562 bool SrcIsKill =
MI.getOperand(1).isKill();
1563 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1567 assert(
Imm <= 62 &&
"Address is out of range");
1571 auto MIBHI = buildMI(
MBB,
MBBI, AVR::OUTARr)
1572 .addImm(STI.hasLowByteFirst() ?
Imm :
Imm + 1)
1573 .addReg(STI.hasLowByteFirst() ? SrcLoReg : SrcHiReg,
1575 auto MIBLO = buildMI(
MBB,
MBBI, AVR::OUTARr)
1576 .addImm(STI.hasLowByteFirst() ?
Imm + 1 :
Imm)
1577 .addReg(STI.hasLowByteFirst() ? SrcHiReg : SrcLoReg,
1580 MIBLO.setMemRefs(
MI.memoperands());
1581 MIBHI.setMemRefs(
MI.memoperands());
1583 MI.eraseFromParent();
1588bool AVRExpandPseudoImpl::expand<AVR::PUSHWRr>(
Block &
MBB, BlockIt
MBBI) {
1592 bool SrcIsKill =
MI.getOperand(0).isKill();
1593 unsigned Flags =
MI.getFlags();
1594 unsigned OpLo = AVR::PUSHRr;
1595 unsigned OpHi = AVR::PUSHRr;
1596 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1608 MI.eraseFromParent();
1613bool AVRExpandPseudoImpl::expand<AVR::POPWRd>(
Block &
MBB, BlockIt
MBBI) {
1617 unsigned Flags =
MI.getFlags();
1618 unsigned OpLo = AVR::POPRd;
1619 unsigned OpHi = AVR::POPRd;
1620 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1622 buildMI(
MBB,
MBBI, OpHi, DstHiReg).setMIFlags(Flags);
1623 buildMI(
MBB,
MBBI, OpLo, DstLoReg).setMIFlags(Flags);
1625 MI.eraseFromParent();
1629bool AVRExpandPseudoImpl::expandROLBRd(
Block &
MBB, BlockIt
MBBI) {
1637 unsigned OpShift, OpCarry;
1639 Register ZeroReg =
MI.getOperand(3).getReg();
1640 bool DstIsDead =
MI.getOperand(0).isDead();
1641 bool DstIsKill =
MI.getOperand(1).isKill();
1642 OpShift = AVR::ADDRdRr;
1643 OpCarry = AVR::ADCRdRr;
1655 auto MIB = buildMI(
MBB,
MBBI, OpCarry)
1660 MIB->getOperand(3).setIsDead();
1661 MIB->getOperand(4).setIsKill();
1663 MI.eraseFromParent();
1668bool AVRExpandPseudoImpl::expand<AVR::ROLBRdR1>(
Block &
MBB, BlockIt
MBBI) {
1669 return expandROLBRd(
MBB,
MBBI);
1673bool AVRExpandPseudoImpl::expand<AVR::ROLBRdR17>(
Block &
MBB, BlockIt
MBBI) {
1674 return expandROLBRd(
MBB,
MBBI);
1678bool AVRExpandPseudoImpl::expand<AVR::RORBRd>(
Block &
MBB, BlockIt
MBBI) {
1693 buildMI(
MBB,
MBBI, AVR::BST).addReg(DstReg).addImm(0);
1696 buildMI(
MBB,
MBBI, AVR::RORRd, DstReg).addReg(DstReg);
1699 buildMI(
MBB,
MBBI, AVR::BLD, DstReg).addReg(DstReg).addImm(7);
1701 MI.eraseFromParent();
1706bool AVRExpandPseudoImpl::expand<AVR::LSLWRd>(
Block &
MBB, BlockIt
MBBI) {
1710 bool DstIsDead =
MI.getOperand(0).isDead();
1711 bool DstIsKill =
MI.getOperand(1).isKill();
1712 bool ImpIsDead =
MI.getOperand(2).isDead();
1713 unsigned OpLo = AVR::ADDRdRr;
1714 unsigned OpHi = AVR::ADCRdRr;
1715 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1730 MIBHI->getOperand(3).setIsDead();
1733 MIBHI->getOperand(4).setIsKill();
1735 MI.eraseFromParent();
1740bool AVRExpandPseudoImpl::expand<AVR::LSLWHiRd>(
Block &
MBB, BlockIt
MBBI) {
1744 bool DstIsDead =
MI.getOperand(0).isDead();
1745 bool DstIsKill =
MI.getOperand(1).isKill();
1746 bool ImpIsDead =
MI.getOperand(2).isDead();
1747 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1751 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
1757 MILSL->getOperand(3).setIsDead();
1759 MI.eraseFromParent();
1763bool AVRExpandPseudoImpl::expandLSLW4Rd(
Block &
MBB, BlockIt
MBBI) {
1767 bool DstIsDead =
MI.getOperand(0).isDead();
1768 bool DstIsKill =
MI.getOperand(1).isKill();
1769 bool ImpIsDead =
MI.getOperand(3).isDead();
1770 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1774 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1777 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1783 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1788 MI0->getOperand(3).setIsDead();
1792 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1797 MI1->getOperand(3).setIsDead();
1801 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1806 MI2->getOperand(3).setIsDead();
1810 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1815 MI3->getOperand(3).setIsDead();
1817 MI.eraseFromParent();
1821bool AVRExpandPseudoImpl::expandLSLW8Rd(
Block &
MBB, BlockIt
MBBI) {
1825 bool DstIsDead =
MI.getOperand(0).isDead();
1826 bool DstIsKill =
MI.getOperand(1).isKill();
1827 bool ImpIsDead =
MI.getOperand(3).isDead();
1828 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1831 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1837 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1842 MIBLO->getOperand(3).setIsDead();
1844 MI.eraseFromParent();
1848bool AVRExpandPseudoImpl::expandLSLW12Rd(
Block &
MBB, BlockIt
MBBI) {
1852 bool DstIsDead =
MI.getOperand(0).isDead();
1853 bool DstIsKill =
MI.getOperand(1).isKill();
1854 bool ImpIsDead =
MI.getOperand(3).isDead();
1855 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1858 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1863 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1869 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1874 MI0->getOperand(3).setIsDead();
1878 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1883 MI1->getOperand(3).setIsDead();
1885 MI.eraseFromParent();
1890bool AVRExpandPseudoImpl::expand<AVR::LSLWNRd>(
Block &
MBB, BlockIt
MBBI) {
1892 unsigned Imm =
MI.getOperand(2).getImm();
1895 return expandLSLW4Rd(
MBB,
MBBI);
1897 return expandLSLW8Rd(
MBB,
MBBI);
1899 return expandLSLW12Rd(
MBB,
MBBI);
1907bool AVRExpandPseudoImpl::expand<AVR::LSRWRd>(
Block &
MBB, BlockIt
MBBI) {
1911 bool DstIsDead =
MI.getOperand(0).isDead();
1912 bool DstIsKill =
MI.getOperand(1).isKill();
1913 bool ImpIsDead =
MI.getOperand(2).isDead();
1914 unsigned OpLo = AVR::RORRd;
1915 unsigned OpHi = AVR::LSRRd;
1916 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1929 MIBLO->getOperand(2).setIsDead();
1932 MIBLO->getOperand(3).setIsKill();
1934 MI.eraseFromParent();
1939bool AVRExpandPseudoImpl::expand<AVR::LSRWLoRd>(
Block &
MBB, BlockIt
MBBI) {
1943 bool DstIsDead =
MI.getOperand(0).isDead();
1944 bool DstIsKill =
MI.getOperand(1).isKill();
1945 bool ImpIsDead =
MI.getOperand(2).isDead();
1946 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1950 buildMI(
MBB,
MBBI, AVR::LSRRd)
1955 MILSR->getOperand(2).setIsDead();
1957 MI.eraseFromParent();
1961bool AVRExpandPseudoImpl::expandLSRW4Rd(
Block &
MBB, BlockIt
MBBI) {
1965 bool DstIsDead =
MI.getOperand(0).isDead();
1966 bool DstIsKill =
MI.getOperand(1).isKill();
1967 bool ImpIsDead =
MI.getOperand(3).isDead();
1968 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1972 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1975 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1981 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1986 MI0->getOperand(3).setIsDead();
1990 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1995 MI1->getOperand(3).setIsDead();
1999 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
2004 MI2->getOperand(3).setIsDead();
2008 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2013 MI3->getOperand(3).setIsDead();
2015 MI.eraseFromParent();
2019bool AVRExpandPseudoImpl::expandLSRW8Rd(
Block &
MBB, BlockIt
MBBI) {
2023 bool DstIsDead =
MI.getOperand(0).isDead();
2024 bool DstIsKill =
MI.getOperand(1).isKill();
2025 bool ImpIsDead =
MI.getOperand(3).isDead();
2026 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2029 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2035 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2040 MIBHI->getOperand(3).setIsDead();
2042 MI.eraseFromParent();
2046bool AVRExpandPseudoImpl::expandLSRW12Rd(
Block &
MBB, BlockIt
MBBI) {
2050 bool DstIsDead =
MI.getOperand(0).isDead();
2051 bool DstIsKill =
MI.getOperand(1).isKill();
2052 bool ImpIsDead =
MI.getOperand(3).isDead();
2053 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2056 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2061 buildMI(
MBB,
MBBI, AVR::SWAPRd)
2067 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
2072 MI0->getOperand(3).setIsDead();
2076 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2081 MIBHI->getOperand(3).setIsDead();
2083 MI.eraseFromParent();
2088bool AVRExpandPseudoImpl::expand<AVR::LSRWNRd>(
Block &
MBB, BlockIt
MBBI) {
2090 unsigned Imm =
MI.getOperand(2).getImm();
2093 return expandLSRW4Rd(
MBB,
MBBI);
2095 return expandLSRW8Rd(
MBB,
MBBI);
2097 return expandLSRW12Rd(
MBB,
MBBI);
2105bool AVRExpandPseudoImpl::expand<AVR::RORWRd>(
Block &
MBB, BlockIt
MBBI) {
2111bool AVRExpandPseudoImpl::expand<AVR::ROLWRd>(
Block &
MBB, BlockIt
MBBI) {
2117bool AVRExpandPseudoImpl::expand<AVR::ASRWRd>(
Block &
MBB, BlockIt
MBBI) {
2121 bool DstIsDead =
MI.getOperand(0).isDead();
2122 bool DstIsKill =
MI.getOperand(1).isKill();
2123 bool ImpIsDead =
MI.getOperand(2).isDead();
2124 unsigned OpLo = AVR::RORRd;
2125 unsigned OpHi = AVR::ASRRd;
2126 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2139 MIBLO->getOperand(2).setIsDead();
2142 MIBLO->getOperand(3).setIsKill();
2144 MI.eraseFromParent();
2149bool AVRExpandPseudoImpl::expand<AVR::ASRWLoRd>(
Block &
MBB, BlockIt
MBBI) {
2153 bool DstIsDead =
MI.getOperand(0).isDead();
2154 bool DstIsKill =
MI.getOperand(1).isKill();
2155 bool ImpIsDead =
MI.getOperand(2).isDead();
2156 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2160 buildMI(
MBB,
MBBI, AVR::ASRRd)
2165 MIASR->getOperand(2).setIsDead();
2167 MI.eraseFromParent();
2171bool AVRExpandPseudoImpl::expandASRW7Rd(
Block &
MBB, BlockIt
MBBI) {
2175 bool DstIsDead =
MI.getOperand(0).isDead();
2176 bool DstIsKill =
MI.getOperand(1).isKill();
2177 bool ImpIsDead =
MI.getOperand(3).isDead();
2178 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2186 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2192 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2197 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2204 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2210 MISBC->getOperand(3).setIsDead();
2212 MISBC->getOperand(4).setIsKill();
2214 MI.eraseFromParent();
2218bool AVRExpandPseudoImpl::expandASRW8Rd(
Block &
MBB, BlockIt
MBBI) {
2222 bool DstIsDead =
MI.getOperand(0).isDead();
2223 bool DstIsKill =
MI.getOperand(1).isKill();
2224 bool ImpIsDead =
MI.getOperand(3).isDead();
2225 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2228 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2233 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2240 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2246 MIBHI->getOperand(3).setIsDead();
2248 MIBHI->getOperand(4).setIsKill();
2250 MI.eraseFromParent();
2253bool AVRExpandPseudoImpl::expandASRW14Rd(
Block &
MBB, BlockIt
MBBI) {
2257 bool DstIsDead =
MI.getOperand(0).isDead();
2258 bool DstIsKill =
MI.getOperand(1).isKill();
2259 bool ImpIsDead =
MI.getOperand(3).isDead();
2260 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2269 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2275 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2281 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2287 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2293 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2299 MIROL->getOperand(3).setIsDead();
2301 MIROL->getOperand(4).setIsKill();
2303 MI.eraseFromParent();
2307bool AVRExpandPseudoImpl::expandASRW15Rd(
Block &
MBB, BlockIt
MBBI) {
2311 bool DstIsDead =
MI.getOperand(0).isDead();
2312 bool ImpIsDead =
MI.getOperand(3).isDead();
2313 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2320 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2327 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2332 MISBC->getOperand(3).setIsDead();
2334 MISBC->getOperand(4).setIsKill();
2337 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2341 MI.eraseFromParent();
2346bool AVRExpandPseudoImpl::expand<AVR::ASRWNRd>(
Block &
MBB, BlockIt
MBBI) {
2348 unsigned Imm =
MI.getOperand(2).getImm();
2351 return expandASRW7Rd(
MBB,
MBBI);
2353 return expandASRW8Rd(
MBB,
MBBI);
2355 return expandASRW14Rd(
MBB,
MBBI);
2357 return expandASRW15Rd(
MBB,
MBBI);
2364bool AVRExpandPseudoImpl::expandLSLB7Rd(
Block &
MBB, BlockIt
MBBI) {
2367 bool DstIsDead =
MI.getOperand(0).isDead();
2368 bool DstIsKill =
MI.getOperand(1).isKill();
2369 bool ImpIsDead =
MI.getOperand(3).isDead();
2375 buildMI(
MBB,
MBBI, AVR::RORRd)
2381 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2387 buildMI(
MBB,
MBBI, AVR::RORRd)
2392 MIRRC->getOperand(2).setIsDead();
2395 MIRRC->getOperand(3).setIsKill();
2397 MI.eraseFromParent();
2402bool AVRExpandPseudoImpl::expand<AVR::LSLBNRd>(
Block &
MBB, BlockIt
MBBI) {
2404 unsigned Imm =
MI.getOperand(2).getImm();
2407 return expandLSLB7Rd(
MBB,
MBBI);
2414bool AVRExpandPseudoImpl::expandLSRB7Rd(
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();
2425 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2432 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2438 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2444 MIRRC->getOperand(3).setIsDead();
2447 MIRRC->getOperand(4).setIsKill();
2449 MI.eraseFromParent();
2454bool AVRExpandPseudoImpl::expand<AVR::LSRBNRd>(
Block &
MBB, BlockIt
MBBI) {
2456 unsigned Imm =
MI.getOperand(2).getImm();
2459 return expandLSRB7Rd(
MBB,
MBBI);
2466bool AVRExpandPseudoImpl::expandASRB6Rd(
Block &
MBB, BlockIt
MBBI) {
2469 bool DstIsDead =
MI.getOperand(0).isDead();
2470 bool DstIsKill =
MI.getOperand(1).isKill();
2483 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2488 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2500 MI.eraseFromParent();
2504bool AVRExpandPseudoImpl::expandASRB7Rd(
Block &
MBB, BlockIt
MBBI) {
2507 bool DstIsDead =
MI.getOperand(0).isDead();
2508 bool DstIsKill =
MI.getOperand(1).isKill();
2509 bool ImpIsDead =
MI.getOperand(3).isDead();
2514 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2520 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2526 MIRRC->getOperand(3).setIsDead();
2529 MIRRC->getOperand(4).setIsKill();
2531 MI.eraseFromParent();
2536bool AVRExpandPseudoImpl::expand<AVR::ASRBNRd>(
Block &
MBB, BlockIt
MBBI) {
2538 unsigned Imm =
MI.getOperand(2).getImm();
2541 return expandASRB6Rd(
MBB,
MBBI);
2543 return expandASRB7Rd(
MBB,
MBBI);
2551bool AVRExpandPseudoImpl::expand<AVR::SEXT>(
Block &
MBB, BlockIt
MBBI) {
2569 bool DstIsDead =
MI.getOperand(0).isDead();
2570 bool SrcIsKill =
MI.getOperand(1).isKill();
2571 bool ImpIsDead =
MI.getOperand(2).isDead();
2572 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2574 if (SrcReg != DstLoReg)
2575 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2579 if (SrcReg != DstHiReg) {
2580 auto MOV = buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2583 if (SrcReg != DstLoReg && SrcIsKill)
2584 MOV->getOperand(1).setIsKill();
2587 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2593 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2599 SBC->getOperand(3).setIsDead();
2602 SBC->getOperand(4).setIsKill();
2604 MI.eraseFromParent();
2609bool AVRExpandPseudoImpl::expand<AVR::ZEXT>(
Block &
MBB, BlockIt
MBBI) {
2622 bool DstIsDead =
MI.getOperand(0).isDead();
2623 bool SrcIsKill =
MI.getOperand(1).isKill();
2624 bool ImpIsDead =
MI.getOperand(2).isDead();
2625 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2627 if (SrcReg != DstLoReg) {
2628 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2634 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2640 EOR->getOperand(3).setIsDead();
2642 MI.eraseFromParent();
2647bool AVRExpandPseudoImpl::expand<AVR::SPREAD>(
Block &
MBB, BlockIt
MBBI) {
2652 bool DstIsDead =
MI.getOperand(0).isDead();
2653 unsigned Flags =
MI.getFlags();
2654 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2657 buildMI(
MBB,
MBBI, AVR::INRdA)
2664 buildMI(
MBB,
MBBI, AVR::INRdA)
2671 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2677 MI0->getOperand(3).setIsDead();
2680 MI.eraseFromParent();
2685bool AVRExpandPseudoImpl::expand<AVR::SPWRITE>(
Block &
MBB, BlockIt
MBBI) {
2690 bool SrcIsKill =
MI.getOperand(1).isKill();
2691 unsigned Flags =
MI.getFlags();
2692 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
2699 buildMI(
MBB,
MBBI, AVR::OUTARr)
2704 buildMI(
MBB,
MBBI, AVR::OUTARr)
2711 buildMI(
MBB,
MBBI, AVR::INRdA)
2716 buildMI(
MBB,
MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
2718 buildMI(
MBB,
MBBI, AVR::OUTARr)
2723 buildMI(
MBB,
MBBI, AVR::OUTARr)
2729 buildMI(
MBB,
MBBI, AVR::OUTARr)
2735 MI.eraseFromParent();
2740bool AVRExpandPseudoImpl::expand<AVR::FRMSP>(
Block &
MBB, BlockIt
MBBI) {
2745 Register ASOPointer =
MI.getOperand(0).getReg();
2746 int64_t ASOAlignment =
MI.getOperand(1).getImm();
2758 TII->copyPhysReg(
MBB,
MI,
DL, ASOPointer, AVR::R29R28,
false,
false,
false);
2760 buildMI(
MBB,
MI, AVR::ADIWRdKP)
2763 .addImm(ASOOffset.
getFixed() + ASOAlignment - 1)
2766 buildMI(
MBB,
MI, AVR::ANDIWRdK)
2769 .addImm(-ASOAlignment)
2772 MI.eraseFromParent();
2776bool AVRExpandPseudoImpl::expandMI(
Block &
MBB, BlockIt
MBBI) {
2778 int Opcode =
MBBI->getOpcode();
2782 return expand<Op>(MBB, MI)
2816 EXPAND(AVR::AtomicLoad8);
2817 EXPAND(AVR::AtomicLoad16);
2818 EXPAND(AVR::AtomicStore8);
2819 EXPAND(AVR::AtomicStore16);
2820 EXPAND(AVR::AtomicFence);
2866 return new AVRExpandPseudoLegacy();
2869bool AVRExpandPseudoLegacy::runOnMachineFunction(
MachineFunction &MF) {
2870 AVRExpandPseudoImpl Impl;
2871 return Impl.runOnMachineFunction(MF);
2877 AVRExpandPseudoImpl Impl;
2878 return Impl.runOnMachineFunction(MF)
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
static bool expandMBB(MachineBasicBlock &MBB, const MipsSubtarget *STI, const MipsInstrInfo *TII)
static bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MachineBasicBlock::iterator &NMBB, const MipsSubtarget *STI, const MipsInstrInfo *TII)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
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
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
The address of a basic block.
Represents analyses that only rely on functions' control flow.
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...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
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,...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
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.
Pass manager infrastructure for declaring and invalidating analyses.
#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)
FunctionPass * createAVRExpandPseudoLegacyPass()
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
constexpr RegState getDeadRegState(bool B)
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
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)