27#define AVR_EXPAND_PSEUDO_NAME "AVR pseudo instruction expansion pass"
52 bool expandMBB(Block &
MBB);
53 bool expandMI(Block &
MBB, BlockIt
MBBI);
69 bool expandArith(
unsigned OpLo,
unsigned OpHi, Block &
MBB, BlockIt
MBBI);
70 bool expandLogic(
unsigned Op, Block &
MBB, BlockIt
MBBI);
71 bool expandLogicImm(
unsigned Op, Block &
MBB, BlockIt
MBBI);
72 bool isLogicImmOpRedundant(
unsigned Op,
unsigned ImmVal)
const;
73 bool isLogicRegOpUndef(
unsigned Op,
unsigned ImmVal)
const;
75 template <
typename Func>
bool expandAtomic(Block &
MBB, BlockIt
MBBI, Func f);
77 template <
typename Func>
78 bool expandAtomicBinaryOp(
unsigned Opcode, Block &
MBB, BlockIt
MBBI, Func f);
80 bool expandAtomicBinaryOp(
unsigned Opcode, Block &
MBB, BlockIt
MBBI);
83 bool expandLSLB7Rd(Block &
MBB, BlockIt
MBBI);
84 bool expandLSRB7Rd(Block &
MBB, BlockIt
MBBI);
85 bool expandASRB6Rd(Block &
MBB, BlockIt
MBBI);
86 bool expandASRB7Rd(Block &
MBB, BlockIt
MBBI);
89 bool expandLSLW4Rd(Block &
MBB, BlockIt
MBBI);
90 bool expandLSRW4Rd(Block &
MBB, BlockIt
MBBI);
91 bool expandASRW7Rd(Block &
MBB, BlockIt
MBBI);
92 bool expandLSLW8Rd(Block &
MBB, BlockIt
MBBI);
93 bool expandLSRW8Rd(Block &
MBB, BlockIt
MBBI);
94 bool expandASRW8Rd(Block &
MBB, BlockIt
MBBI);
95 bool expandLSLW12Rd(Block &
MBB, BlockIt
MBBI);
96 bool expandLSRW12Rd(Block &
MBB, BlockIt
MBBI);
97 bool expandASRW14Rd(Block &
MBB, BlockIt
MBBI);
98 bool expandASRW15Rd(Block &
MBB, BlockIt
MBBI);
101 bool expandLPMWELPMW(Block &
MBB, BlockIt
MBBI,
bool IsELPM);
103 bool expandLPMBELPMB(Block &
MBB, BlockIt
MBBI,
bool IsELPM);
105 bool expandROLBRd(Block &
MBB, BlockIt
MBBI);
108char AVRExpandPseudo::ID = 0;
115 BlockIt NMBBI = std::next(
MBBI);
131 bool ContinueExpanding =
true;
132 unsigned ExpandCount = 0;
136 assert(ExpandCount < 10 &&
"pseudo expand limit reached");
139 bool BlockModified = expandMBB(
MBB);
143 ContinueExpanding = BlockModified;
144 }
while (ContinueExpanding);
150bool AVRExpandPseudo::expandArith(
unsigned OpLo,
unsigned OpHi,
Block &
MBB,
153 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
156 bool DstIsDead =
MI.getOperand(0).isDead();
157 bool DstIsKill =
MI.getOperand(1).isKill();
158 bool SrcIsKill =
MI.getOperand(2).isKill();
159 bool ImpIsDead =
MI.getOperand(3).isDead();
160 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
161 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
175 MIBHI->getOperand(3).setIsDead();
178 MIBHI->getOperand(4).setIsKill();
180 MI.eraseFromParent();
184bool AVRExpandPseudo::expandLogic(
unsigned Op,
Block &
MBB, BlockIt
MBBI) {
186 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
189 bool DstIsDead =
MI.getOperand(0).isDead();
190 bool DstIsKill =
MI.getOperand(1).isKill();
191 bool SrcIsKill =
MI.getOperand(2).isKill();
192 bool ImpIsDead =
MI.getOperand(3).isDead();
193 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
194 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
203 MIBLO->getOperand(3).setIsDead();
212 MIBHI->getOperand(3).setIsDead();
214 MI.eraseFromParent();
218bool AVRExpandPseudo::isLogicImmOpRedundant(
unsigned Op,
219 unsigned ImmVal)
const {
222 if (
Op == AVR::ANDIRdK && ImmVal == 0xff)
226 if (
Op == AVR::ORIRdK && ImmVal == 0x0)
232bool AVRExpandPseudo::isLogicRegOpUndef(
unsigned Op,
unsigned ImmVal)
const {
234 if (
Op == AVR::ANDIRdK && ImmVal == 0x00)
238 if (
Op == AVR::ORIRdK && ImmVal == 0xff)
244bool AVRExpandPseudo::expandLogicImm(
unsigned Op,
Block &
MBB, BlockIt
MBBI) {
248 bool DstIsDead =
MI.getOperand(0).isDead();
249 bool SrcIsKill =
MI.getOperand(1).isKill();
250 bool ImpIsDead =
MI.getOperand(3).isDead();
251 unsigned Imm =
MI.getOperand(2).getImm();
252 unsigned Lo8 = Imm & 0xff;
253 unsigned Hi8 = (Imm >> 8) & 0xff;
254 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
256 if (!isLogicImmOpRedundant(
Op, Lo8)) {
264 MIBLO->getOperand(3).setIsDead();
266 if (isLogicRegOpUndef(
Op, Lo8))
267 MIBLO->getOperand(1).setIsUndef(
true);
270 if (!isLogicImmOpRedundant(
Op, Hi8)) {
278 MIBHI->getOperand(3).setIsDead();
280 if (isLogicRegOpUndef(
Op, Hi8))
281 MIBHI->getOperand(1).setIsUndef(
true);
284 MI.eraseFromParent();
289bool AVRExpandPseudo::expand<AVR::ADDWRdRr>(
Block &
MBB, BlockIt
MBBI) {
290 return expandArith(AVR::ADDRdRr, AVR::ADCRdRr,
MBB,
MBBI);
294bool AVRExpandPseudo::expand<AVR::ADCWRdRr>(
Block &
MBB, BlockIt
MBBI) {
295 return expandArith(AVR::ADCRdRr, AVR::ADCRdRr,
MBB,
MBBI);
299bool AVRExpandPseudo::expand<AVR::SUBWRdRr>(
Block &
MBB, BlockIt
MBBI) {
300 return expandArith(AVR::SUBRdRr, AVR::SBCRdRr,
MBB,
MBBI);
304bool AVRExpandPseudo::expand<AVR::SUBIWRdK>(
Block &
MBB, BlockIt
MBBI) {
308 bool DstIsDead =
MI.getOperand(0).isDead();
309 bool SrcIsKill =
MI.getOperand(1).isKill();
310 bool ImpIsDead =
MI.getOperand(3).isDead();
311 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
314 buildMI(
MBB,
MBBI, AVR::SUBIRdK)
319 buildMI(
MBB,
MBBI, AVR::SBCIRdK)
323 switch (
MI.getOperand(2).getType()) {
326 int64_t Offs =
MI.getOperand(2).getOffset();
327 unsigned TF =
MI.getOperand(2).getTargetFlags();
333 unsigned Imm =
MI.getOperand(2).getImm();
334 MIBLO.addImm(Imm & 0xff);
335 MIBHI.addImm((Imm >> 8) & 0xff);
343 MIBHI->getOperand(3).setIsDead();
346 MIBHI->getOperand(4).setIsKill();
348 MI.eraseFromParent();
353bool AVRExpandPseudo::expand<AVR::SBCWRdRr>(
Block &
MBB, BlockIt
MBBI) {
354 return expandArith(AVR::SBCRdRr, AVR::SBCRdRr,
MBB,
MBBI);
358bool AVRExpandPseudo::expand<AVR::SBCIWRdK>(
Block &
MBB, BlockIt
MBBI) {
362 bool DstIsDead =
MI.getOperand(0).isDead();
363 bool SrcIsKill =
MI.getOperand(1).isKill();
364 bool ImpIsDead =
MI.getOperand(3).isDead();
365 unsigned Imm =
MI.getOperand(2).getImm();
366 unsigned Lo8 = Imm & 0xff;
367 unsigned Hi8 = (Imm >> 8) & 0xff;
368 unsigned OpLo = AVR::SBCIRdK;
369 unsigned OpHi = AVR::SBCIRdK;
370 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
379 MIBLO->getOperand(4).setIsKill();
388 MIBHI->getOperand(3).setIsDead();
391 MIBHI->getOperand(4).setIsKill();
393 MI.eraseFromParent();
398bool AVRExpandPseudo::expand<AVR::ANDWRdRr>(
Block &
MBB, BlockIt
MBBI) {
399 return expandLogic(AVR::ANDRdRr,
MBB,
MBBI);
403bool AVRExpandPseudo::expand<AVR::ANDIWRdK>(
Block &
MBB, BlockIt
MBBI) {
404 return expandLogicImm(AVR::ANDIRdK,
MBB,
MBBI);
408bool AVRExpandPseudo::expand<AVR::ORWRdRr>(
Block &
MBB, BlockIt
MBBI) {
409 return expandLogic(AVR::ORRdRr,
MBB,
MBBI);
413bool AVRExpandPseudo::expand<AVR::ORIWRdK>(
Block &
MBB, BlockIt
MBBI) {
414 return expandLogicImm(AVR::ORIRdK,
MBB,
MBBI);
418bool AVRExpandPseudo::expand<AVR::EORWRdRr>(
Block &
MBB, BlockIt
MBBI) {
419 return expandLogic(AVR::EORRdRr,
MBB,
MBBI);
423bool AVRExpandPseudo::expand<AVR::COMWRd>(
Block &
MBB, BlockIt
MBBI) {
427 bool DstIsDead =
MI.getOperand(0).isDead();
428 bool DstIsKill =
MI.getOperand(1).isKill();
429 bool ImpIsDead =
MI.getOperand(2).isDead();
430 unsigned OpLo = AVR::COMRd;
431 unsigned OpHi = AVR::COMRd;
432 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
440 MIBLO->getOperand(2).setIsDead();
448 MIBHI->getOperand(2).setIsDead();
450 MI.eraseFromParent();
455bool AVRExpandPseudo::expand<AVR::NEGWRd>(
Block &
MBB, BlockIt
MBBI) {
460 bool DstIsDead =
MI.getOperand(0).isDead();
461 bool DstIsKill =
MI.getOperand(1).isKill();
462 bool ImpIsDead =
MI.getOperand(2).isDead();
463 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
471 MIBHI->getOperand(2).setIsDead();
480 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
485 MISBCI->getOperand(3).setIsDead();
487 MISBCI->getOperand(4).setIsKill();
489 MI.eraseFromParent();
494bool AVRExpandPseudo::expand<AVR::CPWRdRr>(
Block &
MBB, BlockIt
MBBI) {
496 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
499 bool DstIsKill =
MI.getOperand(0).isKill();
500 bool SrcIsKill =
MI.getOperand(1).isKill();
501 bool ImpIsDead =
MI.getOperand(2).isDead();
502 unsigned OpLo = AVR::CPRdRr;
503 unsigned OpHi = AVR::CPCRdRr;
504 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
505 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
512 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
517 MIBHI->getOperand(2).setIsDead();
520 MIBHI->getOperand(3).setIsKill();
522 MI.eraseFromParent();
527bool AVRExpandPseudo::expand<AVR::CPCWRdRr>(
Block &
MBB, BlockIt
MBBI) {
529 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
532 bool DstIsKill =
MI.getOperand(0).isKill();
533 bool SrcIsKill =
MI.getOperand(1).isKill();
534 bool ImpIsDead =
MI.getOperand(2).isDead();
535 unsigned OpLo = AVR::CPCRdRr;
536 unsigned OpHi = AVR::CPCRdRr;
537 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
538 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
540 auto MIBLO = buildMI(
MBB,
MBBI, OpLo)
545 MIBLO->getOperand(3).setIsKill();
547 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
552 MIBHI->getOperand(2).setIsDead();
555 MIBHI->getOperand(3).setIsKill();
557 MI.eraseFromParent();
562bool AVRExpandPseudo::expand<AVR::LDIWRdK>(
Block &
MBB, BlockIt
MBBI) {
566 bool DstIsDead =
MI.getOperand(0).isDead();
567 unsigned OpLo = AVR::LDIRdK;
568 unsigned OpHi = AVR::LDIRdK;
569 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
579 switch (
MI.getOperand(1).getType()) {
582 int64_t Offs =
MI.getOperand(1).getOffset();
583 unsigned TF =
MI.getOperand(1).getTargetFlags();
591 unsigned TF =
MI.getOperand(1).getTargetFlags();
598 unsigned Imm =
MI.getOperand(1).getImm();
600 MIBLO.addImm(Imm & 0xff);
601 MIBHI.addImm((Imm >> 8) & 0xff);
608 MI.eraseFromParent();
613bool AVRExpandPseudo::expand<AVR::LDSWRdK>(
Block &
MBB, BlockIt
MBBI) {
617 bool DstIsDead =
MI.getOperand(0).isDead();
618 unsigned OpLo = AVR::LDSRdK;
619 unsigned OpHi = AVR::LDSRdK;
620 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
630 switch (
MI.getOperand(1).getType()) {
633 int64_t Offs =
MI.getOperand(1).getOffset();
634 unsigned TF =
MI.getOperand(1).getTargetFlags();
636 MIBLO.addGlobalAddress(GV, Offs, TF);
637 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
641 unsigned Imm =
MI.getOperand(1).getImm();
644 MIBHI.addImm(Imm + 1);
651 MIBLO.setMemRefs(
MI.memoperands());
652 MIBHI.setMemRefs(
MI.memoperands());
654 MI.eraseFromParent();
659bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(
Block &
MBB, BlockIt
MBBI) {
663 bool DstIsKill =
MI.getOperand(0).isKill();
664 bool SrcIsKill =
MI.getOperand(1).isKill();
669 assert(DstReg != SrcReg &&
"Dst and Src registers are the same!");
671 if (STI.hasTinyEncoding()) {
674 buildMI(
MBB,
MBBI, AVR::LDDWRdPtrQ)
678 .setMemRefs(
MI.memoperands());
682 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
685 buildMI(
MBB,
MBBI, AVR::LDRdPtr)
688 .setMemRefs(
MI.memoperands());
691 buildMI(
MBB,
MBBI, AVR::LDDRdPtrQ)
695 .setMemRefs(
MI.memoperands());
698 MI.eraseFromParent();
703bool AVRExpandPseudo::expand<AVR::LDWRdPtrPi>(
Block &
MBB, BlockIt
MBBI) {
708 bool DstIsDead =
MI.getOperand(0).isDead();
709 bool SrcIsDead =
MI.getOperand(1).isKill();
710 unsigned OpLo = AVR::LDRdPtrPi;
711 unsigned OpHi = AVR::LDRdPtrPi;
712 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
714 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
728 MIBLO.setMemRefs(
MI.memoperands());
729 MIBHI.setMemRefs(
MI.memoperands());
731 MI.eraseFromParent();
736bool AVRExpandPseudo::expand<AVR::LDWRdPtrPd>(
Block &
MBB, BlockIt
MBBI) {
741 bool DstIsDead =
MI.getOperand(0).isDead();
742 bool SrcIsDead =
MI.getOperand(1).isKill();
743 unsigned OpLo = AVR::LDRdPtrPd;
744 unsigned OpHi = AVR::LDRdPtrPd;
745 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
747 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
761 MIBLO.setMemRefs(
MI.memoperands());
762 MIBHI.setMemRefs(
MI.memoperands());
764 MI.eraseFromParent();
769bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(
Block &
MBB, BlockIt
MBBI) {
773 unsigned Imm =
MI.getOperand(2).getImm();
774 bool DstIsKill =
MI.getOperand(0).isKill();
775 bool SrcIsKill =
MI.getOperand(1).isKill();
780 assert(Imm <= 62 &&
"Offset is out of range");
784 assert(DstReg != SrcReg &&
"Dst and Src registers are the same!");
786 if (STI.hasTinyEncoding()) {
794 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, SrcReg)
796 .addImm(0x10000 - Imm);
801 buildMI(
MBB,
MBBI, AVR::LDWRdPtrPi)
805 .setMemRefs(
MI.memoperands());
811 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, SrcReg).addReg(SrcReg).addImm(Imm + 2);
815 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
818 buildMI(
MBB,
MBBI, AVR::LDDRdPtrQ)
822 .setMemRefs(
MI.memoperands());
825 buildMI(
MBB,
MBBI, AVR::LDDRdPtrQ)
829 .setMemRefs(
MI.memoperands());
832 MI.eraseFromParent();
836bool AVRExpandPseudo::expandLPMWELPMW(
Block &
MBB, BlockIt
MBBI,
bool IsELPM) {
842 bool SrcIsKill =
MI.getOperand(1).isKill();
844 bool IsLPMRn = IsELPM ? STI.hasELPMX() : STI.hasLPMX();
846 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
847 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
857 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
860 unsigned OpLo = IsELPM ? AVR::ELPMRdZPi : AVR::LPMRdZPi;
861 unsigned OpHi = IsELPM ? AVR::ELPMRdZ : AVR::LPMRdZ;
863 auto MIBLO = buildMI(
MBB,
MBBI, OpLo)
867 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
870 MIBLO.setMemRefs(
MI.memoperands());
871 MIBHI.setMemRefs(
MI.memoperands());
873 unsigned Opc = IsELPM ? AVR::ELPM : AVR::LPM;
875 auto MIBLO = buildMI(
MBB,
MBBI, Opc);
876 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
879 MIBLO.setMemRefs(
MI.memoperands());
881 if (STI.hasADDSUBIW()) {
883 auto MIINC = buildMI(
MBB,
MBBI, AVR::ADIWRdK)
887 MIINC->getOperand(3).setIsDead();
891 buildMI(
MBB,
MBBI, AVR::SUBIRdK)
895 auto MIZHI = buildMI(
MBB,
MBBI, AVR::SBCIRdK)
899 MIZHI->getOperand(3).setIsDead();
900 MIZHI->getOperand(4).setIsKill();
903 auto MIBHI = buildMI(
MBB,
MBBI, Opc);
904 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
907 MIBHI.setMemRefs(
MI.memoperands());
912 if (STI.hasADDSUBIW()) {
914 auto MIDEC = buildMI(
MBB,
MBBI, AVR::SBIWRdK)
918 MIDEC->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 MI.eraseFromParent();
940bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(
Block &
MBB, BlockIt
MBBI) {
941 return expandLPMWELPMW(
MBB,
MBBI,
false);
945bool AVRExpandPseudo::expand<AVR::ELPMWRdZ>(
Block &
MBB, BlockIt
MBBI) {
946 return expandLPMWELPMW(
MBB,
MBBI,
true);
949bool AVRExpandPseudo::expandLPMBELPMB(
Block &
MBB, BlockIt
MBBI,
bool IsELPM) {
953 bool SrcIsKill =
MI.getOperand(1).isKill();
955 bool IsLPMRn = IsELPM ? STI.hasELPMX() : STI.hasLPMX();
965 unsigned Opc = IsELPM ? AVR::ELPMRdZ : AVR::LPMRdZ;
966 auto MILB = buildMI(
MBB,
MBBI, Opc)
969 MILB.setMemRefs(
MI.memoperands());
973 unsigned Opc = IsELPM ? AVR::ELPM : AVR::LPM;
974 auto MILB = buildMI(
MBB,
MBBI, Opc);
975 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
978 MILB.setMemRefs(
MI.memoperands());
981 MI.eraseFromParent();
986bool AVRExpandPseudo::expand<AVR::ELPMBRdZ>(
Block &
MBB, BlockIt
MBBI) {
987 return expandLPMBELPMB(
MBB,
MBBI,
true);
991bool AVRExpandPseudo::expand<AVR::LPMBRdZ>(
Block &
MBB, BlockIt
MBBI) {
992 return expandLPMBELPMB(
MBB,
MBBI,
false);
996bool AVRExpandPseudo::expand<AVR::LPMWRdZPi>(
Block &
MBB, BlockIt
MBBI) {
1001bool AVRExpandPseudo::expand<AVR::ELPMBRdZPi>(
Block &
MBB, BlockIt
MBBI) {
1006bool AVRExpandPseudo::expand<AVR::ELPMWRdZPi>(
Block &
MBB, BlockIt
MBBI) {
1010template <
typename Func>
1011bool AVRExpandPseudo::expandAtomic(
Block &
MBB, BlockIt
MBBI, Func f) {
1016 buildMI(
MBB,
MBBI, AVR::INRdA)
1021 buildMI(
MBB,
MBBI, AVR::BCLRs).addImm(7);
1026 buildMI(
MBB,
MBBI, AVR::OUTARr)
1030 MI.eraseFromParent();
1034template <
typename Func>
1035bool AVRExpandPseudo::expandAtomicBinaryOp(
unsigned Opcode,
Block &
MBB,
1036 BlockIt
MBBI, Func f) {
1038 auto Op1 =
MI.getOperand(0);
1039 auto Op2 =
MI.getOperand(1);
1042 *buildMI(
MBB,
MBBI, Opcode).add(Op1).add(Op2).getInstr();
1047bool AVRExpandPseudo::expandAtomicBinaryOp(
unsigned Opcode,
Block &
MBB,
1053bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(
Block &
MBB, BlockIt
MBBI) {
1054 return expandAtomicBinaryOp(AVR::LDRdPtr,
MBB,
MBBI);
1058bool AVRExpandPseudo::expand<AVR::AtomicLoad16>(
Block &
MBB, BlockIt
MBBI) {
1059 return expandAtomicBinaryOp(AVR::LDWRdPtr,
MBB,
MBBI);
1063bool AVRExpandPseudo::expand<AVR::AtomicStore8>(
Block &
MBB, BlockIt
MBBI) {
1064 return expandAtomicBinaryOp(AVR::STPtrRr,
MBB,
MBBI);
1068bool AVRExpandPseudo::expand<AVR::AtomicStore16>(
Block &
MBB, BlockIt
MBBI) {
1069 return expandAtomicBinaryOp(AVR::STWPtrRr,
MBB,
MBBI);
1073bool AVRExpandPseudo::expand<AVR::AtomicFence>(
Block &
MBB, BlockIt
MBBI) {
1080bool AVRExpandPseudo::expand<AVR::STSWKRr>(
Block &
MBB, BlockIt
MBBI) {
1085 bool SrcIsKill =
MI.getOperand(1).isKill();
1086 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1088 auto MIB0 = buildMI(
MBB,
MBBI, AVR::STSKRr);
1089 auto MIB1 = buildMI(
MBB,
MBBI, AVR::STSKRr);
1091 switch (
MI.getOperand(0).getType()) {
1094 int64_t Offs =
MI.getOperand(0).getOffset();
1095 unsigned TF =
MI.getOperand(0).getTargetFlags();
1097 if (STI.hasLowByteFirst()) {
1099 MIB0.addGlobalAddress(GV, Offs, TF);
1100 MIB1.addGlobalAddress(GV, Offs + 1, TF);
1103 MIB0.addGlobalAddress(GV, Offs + 1, TF);
1104 MIB1.addGlobalAddress(GV, Offs, TF);
1110 unsigned Imm =
MI.getOperand(0).getImm();
1112 if (STI.hasLowByteFirst()) {
1115 MIB1.addImm(Imm + 1);
1118 MIB0.addImm(Imm + 1);
1128 if (STI.hasLowByteFirst()) {
1131 .setMemRefs(
MI.memoperands());
1133 .setMemRefs(
MI.memoperands());
1137 .setMemRefs(
MI.memoperands());
1139 .setMemRefs(
MI.memoperands());
1142 MI.eraseFromParent();
1147bool AVRExpandPseudo::expand<AVR::STWPtrRr>(
Block &
MBB, BlockIt
MBBI) {
1151 bool DstIsKill =
MI.getOperand(0).isKill();
1152 bool DstIsUndef =
MI.getOperand(0).isUndef();
1153 bool SrcIsKill =
MI.getOperand(1).isKill();
1158 if (STI.hasTinyEncoding()) {
1161 buildMI(
MBB,
MBBI, AVR::STDWPtrQRr)
1166 .setMemRefs(
MI.memoperands());
1170 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1171 if (STI.hasLowByteFirst()) {
1172 buildMI(
MBB,
MBBI, AVR::STPtrRr)
1175 .setMemRefs(
MI.memoperands());
1176 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1180 .setMemRefs(
MI.memoperands());
1182 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1186 .setMemRefs(
MI.memoperands());
1187 buildMI(
MBB,
MBBI, AVR::STPtrRr)
1190 .setMemRefs(
MI.memoperands());
1194 MI.eraseFromParent();
1199bool AVRExpandPseudo::expand<AVR::STWPtrPiRr>(
Block &
MBB, BlockIt
MBBI) {
1204 unsigned Imm =
MI.getOperand(3).getImm();
1205 bool DstIsDead =
MI.getOperand(0).isDead();
1206 bool SrcIsKill =
MI.getOperand(2).isKill();
1207 unsigned OpLo = AVR::STPtrPiRr;
1208 unsigned OpHi = AVR::STPtrPiRr;
1209 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1211 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
1213 auto MIBLO = buildMI(
MBB,
MBBI, OpLo)
1226 MIBLO.setMemRefs(
MI.memoperands());
1227 MIBHI.setMemRefs(
MI.memoperands());
1229 MI.eraseFromParent();
1234bool AVRExpandPseudo::expand<AVR::STWPtrPdRr>(
Block &
MBB, BlockIt
MBBI) {
1239 unsigned Imm =
MI.getOperand(3).getImm();
1240 bool DstIsDead =
MI.getOperand(0).isDead();
1241 bool SrcIsKill =
MI.getOperand(2).isKill();
1242 unsigned OpLo = AVR::STPtrPdRr;
1243 unsigned OpHi = AVR::STPtrPdRr;
1244 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1246 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
1248 auto MIBHI = buildMI(
MBB,
MBBI, OpHi)
1261 MIBLO.setMemRefs(
MI.memoperands());
1262 MIBHI.setMemRefs(
MI.memoperands());
1264 MI.eraseFromParent();
1269bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(
Block &
MBB, BlockIt
MBBI) {
1274 bool DstIsKill =
MI.getOperand(0).isKill();
1275 unsigned Imm =
MI.getOperand(1).getImm();
1277 bool SrcIsKill =
MI.getOperand(2).isKill();
1283 if (Imm >= 63 || STI.hasTinyEncoding()) {
1287 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, DstReg)
1289 .addImm(0x10000 - Imm);
1293 buildMI(
MBB,
MBBI, AVR::STWPtrPiRr, DstReg)
1297 .setMemRefs(
MI.memoperands());
1303 buildMI(
MBB,
MBBI, AVR::SUBIWRdK, DstReg)
1309 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1311 if (STI.hasLowByteFirst()) {
1312 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1316 .setMemRefs(
MI.memoperands());
1317 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1321 .setMemRefs(
MI.memoperands());
1323 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1327 .setMemRefs(
MI.memoperands());
1328 buildMI(
MBB,
MBBI, AVR::STDPtrQRr)
1332 .setMemRefs(
MI.memoperands());
1336 MI.eraseFromParent();
1341bool AVRExpandPseudo::expand<AVR::STDSPQRr>(
Block &
MBB, BlockIt
MBBI) {
1346 assert(
MI.getOperand(0).getReg() == AVR::SP &&
1347 "SP is expected as base pointer");
1350 "unexpected STDSPQRr pseudo instruction");
1353 MI.setDesc(
TII->get(AVR::STDPtrQRr));
1354 MI.getOperand(0).setReg(AVR::R29R28);
1360bool AVRExpandPseudo::expand<AVR::STDWSPQRr>(
Block &
MBB, BlockIt
MBBI) {
1365 assert(
MI.getOperand(0).getReg() == AVR::SP &&
1366 "SP is expected as base pointer");
1369 "unexpected STDWSPQRr pseudo instruction");
1372 MI.setDesc(
TII->get(AVR::STDWPtrQRr));
1373 MI.getOperand(0).setReg(AVR::R29R28);
1379bool AVRExpandPseudo::expand<AVR::INWRdA>(
Block &
MBB, BlockIt
MBBI) {
1382 unsigned Imm =
MI.getOperand(1).getImm();
1384 bool DstIsDead =
MI.getOperand(0).isDead();
1385 unsigned OpLo = AVR::INRdA;
1386 unsigned OpHi = AVR::INRdA;
1387 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1391 assert(Imm <= 62 &&
"Address is out of range");
1403 MIBLO.setMemRefs(
MI.memoperands());
1404 MIBHI.setMemRefs(
MI.memoperands());
1406 MI.eraseFromParent();
1411bool AVRExpandPseudo::expand<AVR::OUTWARr>(
Block &
MBB, BlockIt
MBBI) {
1415 unsigned Imm =
MI.getOperand(0).getImm();
1417 bool SrcIsKill =
MI.getOperand(1).isKill();
1418 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1422 assert(Imm <= 62 &&
"Address is out of range");
1426 auto MIBHI = buildMI(
MBB,
MBBI, AVR::OUTARr)
1427 .addImm(STI.hasLowByteFirst() ? Imm : Imm + 1)
1428 .addReg(STI.hasLowByteFirst() ? SrcLoReg : SrcHiReg,
1430 auto MIBLO = buildMI(
MBB,
MBBI, AVR::OUTARr)
1431 .addImm(STI.hasLowByteFirst() ? Imm + 1 : Imm)
1432 .addReg(STI.hasLowByteFirst() ? SrcHiReg : SrcLoReg,
1435 MIBLO.setMemRefs(
MI.memoperands());
1436 MIBHI.setMemRefs(
MI.memoperands());
1438 MI.eraseFromParent();
1443bool AVRExpandPseudo::expand<AVR::PUSHWRr>(
Block &
MBB, BlockIt
MBBI) {
1447 bool SrcIsKill =
MI.getOperand(0).isKill();
1448 unsigned Flags =
MI.getFlags();
1449 unsigned OpLo = AVR::PUSHRr;
1450 unsigned OpHi = AVR::PUSHRr;
1451 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1463 MI.eraseFromParent();
1468bool AVRExpandPseudo::expand<AVR::POPWRd>(
Block &
MBB, BlockIt
MBBI) {
1472 unsigned Flags =
MI.getFlags();
1473 unsigned OpLo = AVR::POPRd;
1474 unsigned OpHi = AVR::POPRd;
1475 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1477 buildMI(
MBB,
MBBI, OpHi, DstHiReg).setMIFlags(Flags);
1478 buildMI(
MBB,
MBBI, OpLo, DstLoReg).setMIFlags(Flags);
1480 MI.eraseFromParent();
1484bool AVRExpandPseudo::expandROLBRd(
Block &
MBB, BlockIt
MBBI) {
1492 unsigned OpShift, OpCarry;
1494 Register ZeroReg =
MI.getOperand(3).getReg();
1495 bool DstIsDead =
MI.getOperand(0).isDead();
1496 bool DstIsKill =
MI.getOperand(1).isKill();
1497 OpShift = AVR::ADDRdRr;
1498 OpCarry = AVR::ADCRdRr;
1510 auto MIB = buildMI(
MBB,
MBBI, OpCarry)
1515 MIB->getOperand(3).setIsDead();
1516 MIB->getOperand(4).setIsKill();
1518 MI.eraseFromParent();
1523bool AVRExpandPseudo::expand<AVR::ROLBRdR1>(
Block &
MBB, BlockIt
MBBI) {
1524 return expandROLBRd(
MBB,
MBBI);
1528bool AVRExpandPseudo::expand<AVR::ROLBRdR17>(
Block &
MBB, BlockIt
MBBI) {
1529 return expandROLBRd(
MBB,
MBBI);
1533bool AVRExpandPseudo::expand<AVR::RORBRd>(
Block &
MBB, BlockIt
MBBI) {
1548 buildMI(
MBB,
MBBI, AVR::BST).addReg(DstReg).addImm(0);
1551 buildMI(
MBB,
MBBI, AVR::RORRd, DstReg).addReg(DstReg);
1554 buildMI(
MBB,
MBBI, AVR::BLD, DstReg).addReg(DstReg).addImm(7);
1556 MI.eraseFromParent();
1561bool AVRExpandPseudo::expand<AVR::LSLWRd>(
Block &
MBB, BlockIt
MBBI) {
1565 bool DstIsDead =
MI.getOperand(0).isDead();
1566 bool DstIsKill =
MI.getOperand(1).isKill();
1567 bool ImpIsDead =
MI.getOperand(2).isDead();
1568 unsigned OpLo = AVR::ADDRdRr;
1569 unsigned OpHi = AVR::ADCRdRr;
1570 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1585 MIBHI->getOperand(3).setIsDead();
1588 MIBHI->getOperand(4).setIsKill();
1590 MI.eraseFromParent();
1595bool AVRExpandPseudo::expand<AVR::LSLWHiRd>(
Block &
MBB, BlockIt
MBBI) {
1599 bool DstIsDead =
MI.getOperand(0).isDead();
1600 bool DstIsKill =
MI.getOperand(1).isKill();
1601 bool ImpIsDead =
MI.getOperand(2).isDead();
1602 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1606 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
1612 MILSL->getOperand(3).setIsDead();
1614 MI.eraseFromParent();
1618bool AVRExpandPseudo::expandLSLW4Rd(
Block &
MBB, BlockIt
MBBI) {
1622 bool DstIsDead =
MI.getOperand(0).isDead();
1623 bool DstIsKill =
MI.getOperand(1).isKill();
1624 bool ImpIsDead =
MI.getOperand(3).isDead();
1625 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1629 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1632 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1638 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1643 MI0->getOperand(3).setIsDead();
1647 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1652 MI1->getOperand(3).setIsDead();
1656 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1661 MI2->getOperand(3).setIsDead();
1665 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1670 MI3->getOperand(3).setIsDead();
1672 MI.eraseFromParent();
1676bool AVRExpandPseudo::expandLSLW8Rd(
Block &
MBB, BlockIt
MBBI) {
1680 bool DstIsDead =
MI.getOperand(0).isDead();
1681 bool DstIsKill =
MI.getOperand(1).isKill();
1682 bool ImpIsDead =
MI.getOperand(3).isDead();
1683 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1686 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1692 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1697 MIBLO->getOperand(3).setIsDead();
1699 MI.eraseFromParent();
1703bool AVRExpandPseudo::expandLSLW12Rd(
Block &
MBB, BlockIt
MBBI) {
1707 bool DstIsDead =
MI.getOperand(0).isDead();
1708 bool DstIsKill =
MI.getOperand(1).isKill();
1709 bool ImpIsDead =
MI.getOperand(3).isDead();
1710 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1713 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1718 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1724 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1729 MI0->getOperand(3).setIsDead();
1733 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1738 MI1->getOperand(3).setIsDead();
1740 MI.eraseFromParent();
1745bool AVRExpandPseudo::expand<AVR::LSLWNRd>(
Block &
MBB, BlockIt
MBBI) {
1747 unsigned Imm =
MI.getOperand(2).getImm();
1750 return expandLSLW4Rd(
MBB,
MBBI);
1752 return expandLSLW8Rd(
MBB,
MBBI);
1754 return expandLSLW12Rd(
MBB,
MBBI);
1762bool AVRExpandPseudo::expand<AVR::LSRWRd>(
Block &
MBB, BlockIt
MBBI) {
1766 bool DstIsDead =
MI.getOperand(0).isDead();
1767 bool DstIsKill =
MI.getOperand(1).isKill();
1768 bool ImpIsDead =
MI.getOperand(2).isDead();
1769 unsigned OpLo = AVR::RORRd;
1770 unsigned OpHi = AVR::LSRRd;
1771 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1784 MIBLO->getOperand(2).setIsDead();
1787 MIBLO->getOperand(3).setIsKill();
1789 MI.eraseFromParent();
1794bool AVRExpandPseudo::expand<AVR::LSRWLoRd>(
Block &
MBB, BlockIt
MBBI) {
1798 bool DstIsDead =
MI.getOperand(0).isDead();
1799 bool DstIsKill =
MI.getOperand(1).isKill();
1800 bool ImpIsDead =
MI.getOperand(2).isDead();
1801 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1805 buildMI(
MBB,
MBBI, AVR::LSRRd)
1810 MILSR->getOperand(2).setIsDead();
1812 MI.eraseFromParent();
1816bool AVRExpandPseudo::expandLSRW4Rd(
Block &
MBB, BlockIt
MBBI) {
1820 bool DstIsDead =
MI.getOperand(0).isDead();
1821 bool DstIsKill =
MI.getOperand(1).isKill();
1822 bool ImpIsDead =
MI.getOperand(3).isDead();
1823 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1827 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1830 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1836 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1841 MI0->getOperand(3).setIsDead();
1845 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1850 MI1->getOperand(3).setIsDead();
1854 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1859 MI2->getOperand(3).setIsDead();
1863 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1868 MI3->getOperand(3).setIsDead();
1870 MI.eraseFromParent();
1874bool AVRExpandPseudo::expandLSRW8Rd(
Block &
MBB, BlockIt
MBBI) {
1878 bool DstIsDead =
MI.getOperand(0).isDead();
1879 bool DstIsKill =
MI.getOperand(1).isKill();
1880 bool ImpIsDead =
MI.getOperand(3).isDead();
1881 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1884 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1890 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1895 MIBHI->getOperand(3).setIsDead();
1897 MI.eraseFromParent();
1901bool AVRExpandPseudo::expandLSRW12Rd(
Block &
MBB, BlockIt
MBBI) {
1905 bool DstIsDead =
MI.getOperand(0).isDead();
1906 bool DstIsKill =
MI.getOperand(1).isKill();
1907 bool ImpIsDead =
MI.getOperand(3).isDead();
1908 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1911 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
1916 buildMI(
MBB,
MBBI, AVR::SWAPRd)
1922 buildMI(
MBB,
MBBI, AVR::ANDIRdK)
1927 MI0->getOperand(3).setIsDead();
1931 buildMI(
MBB,
MBBI, AVR::EORRdRr)
1936 MIBHI->getOperand(3).setIsDead();
1938 MI.eraseFromParent();
1943bool AVRExpandPseudo::expand<AVR::LSRWNRd>(
Block &
MBB, BlockIt
MBBI) {
1945 unsigned Imm =
MI.getOperand(2).getImm();
1948 return expandLSRW4Rd(
MBB,
MBBI);
1950 return expandLSRW8Rd(
MBB,
MBBI);
1952 return expandLSRW12Rd(
MBB,
MBBI);
1960bool AVRExpandPseudo::expand<AVR::RORWRd>(
Block &
MBB, BlockIt
MBBI) {
1966bool AVRExpandPseudo::expand<AVR::ROLWRd>(
Block &
MBB, BlockIt
MBBI) {
1972bool AVRExpandPseudo::expand<AVR::ASRWRd>(
Block &
MBB, BlockIt
MBBI) {
1976 bool DstIsDead =
MI.getOperand(0).isDead();
1977 bool DstIsKill =
MI.getOperand(1).isKill();
1978 bool ImpIsDead =
MI.getOperand(2).isDead();
1979 unsigned OpLo = AVR::RORRd;
1980 unsigned OpHi = AVR::ASRRd;
1981 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1994 MIBLO->getOperand(2).setIsDead();
1997 MIBLO->getOperand(3).setIsKill();
1999 MI.eraseFromParent();
2004bool AVRExpandPseudo::expand<AVR::ASRWLoRd>(
Block &
MBB, BlockIt
MBBI) {
2008 bool DstIsDead =
MI.getOperand(0).isDead();
2009 bool DstIsKill =
MI.getOperand(1).isKill();
2010 bool ImpIsDead =
MI.getOperand(2).isDead();
2011 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2015 buildMI(
MBB,
MBBI, AVR::ASRRd)
2020 MIASR->getOperand(2).setIsDead();
2022 MI.eraseFromParent();
2026bool AVRExpandPseudo::expandASRW7Rd(
Block &
MBB, BlockIt
MBBI) {
2030 bool DstIsDead =
MI.getOperand(0).isDead();
2031 bool DstIsKill =
MI.getOperand(1).isKill();
2032 bool ImpIsDead =
MI.getOperand(3).isDead();
2033 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2041 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2047 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2052 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2059 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2065 MISBC->getOperand(3).setIsDead();
2067 MISBC->getOperand(4).setIsKill();
2069 MI.eraseFromParent();
2073bool AVRExpandPseudo::expandASRW8Rd(
Block &
MBB, BlockIt
MBBI) {
2077 bool DstIsDead =
MI.getOperand(0).isDead();
2078 bool DstIsKill =
MI.getOperand(1).isKill();
2079 bool ImpIsDead =
MI.getOperand(3).isDead();
2080 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2083 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2088 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2095 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2101 MIBHI->getOperand(3).setIsDead();
2103 MIBHI->getOperand(4).setIsKill();
2105 MI.eraseFromParent();
2108bool AVRExpandPseudo::expandASRW14Rd(
Block &
MBB, BlockIt
MBBI) {
2112 bool DstIsDead =
MI.getOperand(0).isDead();
2113 bool DstIsKill =
MI.getOperand(1).isKill();
2114 bool ImpIsDead =
MI.getOperand(3).isDead();
2115 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2124 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2130 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2136 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2142 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2148 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2154 MIROL->getOperand(3).setIsDead();
2156 MIROL->getOperand(4).setIsKill();
2158 MI.eraseFromParent();
2162bool AVRExpandPseudo::expandASRW15Rd(
Block &
MBB, BlockIt
MBBI) {
2166 bool DstIsDead =
MI.getOperand(0).isDead();
2167 bool ImpIsDead =
MI.getOperand(3).isDead();
2168 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2175 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2182 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2187 MISBC->getOperand(3).setIsDead();
2189 MISBC->getOperand(4).setIsKill();
2192 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2196 MI.eraseFromParent();
2201bool AVRExpandPseudo::expand<AVR::ASRWNRd>(
Block &
MBB, BlockIt
MBBI) {
2203 unsigned Imm =
MI.getOperand(2).getImm();
2206 return expandASRW7Rd(
MBB,
MBBI);
2208 return expandASRW8Rd(
MBB,
MBBI);
2210 return expandASRW14Rd(
MBB,
MBBI);
2212 return expandASRW15Rd(
MBB,
MBBI);
2219bool AVRExpandPseudo::expandLSLB7Rd(
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();
2230 buildMI(
MBB,
MBBI, AVR::RORRd)
2236 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2242 buildMI(
MBB,
MBBI, AVR::RORRd)
2247 MIRRC->getOperand(2).setIsDead();
2250 MIRRC->getOperand(3).setIsKill();
2252 MI.eraseFromParent();
2257bool AVRExpandPseudo::expand<AVR::LSLBNRd>(
Block &
MBB, BlockIt
MBBI) {
2259 unsigned Imm =
MI.getOperand(2).getImm();
2262 return expandLSLB7Rd(
MBB,
MBBI);
2269bool AVRExpandPseudo::expandLSRB7Rd(
Block &
MBB, BlockIt
MBBI) {
2272 bool DstIsDead =
MI.getOperand(0).isDead();
2273 bool DstIsKill =
MI.getOperand(1).isKill();
2274 bool ImpIsDead =
MI.getOperand(3).isDead();
2280 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2287 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2293 buildMI(
MBB,
MBBI, AVR::ADCRdRr)
2299 MIRRC->getOperand(3).setIsDead();
2302 MIRRC->getOperand(4).setIsKill();
2304 MI.eraseFromParent();
2309bool AVRExpandPseudo::expand<AVR::LSRBNRd>(
Block &
MBB, BlockIt
MBBI) {
2311 unsigned Imm =
MI.getOperand(2).getImm();
2314 return expandLSRB7Rd(
MBB,
MBBI);
2321bool AVRExpandPseudo::expandASRB6Rd(
Block &
MBB, BlockIt
MBBI) {
2324 bool DstIsDead =
MI.getOperand(0).isDead();
2325 bool DstIsKill =
MI.getOperand(1).isKill();
2338 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2343 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2355 MI.eraseFromParent();
2359bool AVRExpandPseudo::expandASRB7Rd(
Block &
MBB, BlockIt
MBBI) {
2362 bool DstIsDead =
MI.getOperand(0).isDead();
2363 bool DstIsKill =
MI.getOperand(1).isKill();
2364 bool ImpIsDead =
MI.getOperand(3).isDead();
2369 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2375 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2381 MIRRC->getOperand(3).setIsDead();
2384 MIRRC->getOperand(4).setIsKill();
2386 MI.eraseFromParent();
2391bool AVRExpandPseudo::expand<AVR::ASRBNRd>(
Block &
MBB, BlockIt
MBBI) {
2393 unsigned Imm =
MI.getOperand(2).getImm();
2396 return expandASRB6Rd(
MBB,
MBBI);
2398 return expandASRB7Rd(
MBB,
MBBI);
2405template <>
bool AVRExpandPseudo::expand<AVR::SEXT>(
Block &
MBB, BlockIt
MBBI) {
2423 bool DstIsDead =
MI.getOperand(0).isDead();
2424 bool SrcIsKill =
MI.getOperand(1).isKill();
2425 bool ImpIsDead =
MI.getOperand(2).isDead();
2426 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2428 if (SrcReg != DstLoReg)
2429 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2433 if (SrcReg != DstHiReg) {
2434 auto MOV = buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2437 if (SrcReg != DstLoReg && SrcIsKill)
2438 MOV->getOperand(1).setIsKill();
2441 buildMI(
MBB,
MBBI, AVR::ADDRdRr)
2447 buildMI(
MBB,
MBBI, AVR::SBCRdRr)
2453 SBC->getOperand(3).setIsDead();
2456 SBC->getOperand(4).setIsKill();
2458 MI.eraseFromParent();
2462template <>
bool AVRExpandPseudo::expand<AVR::ZEXT>(
Block &
MBB, BlockIt
MBBI) {
2475 bool DstIsDead =
MI.getOperand(0).isDead();
2476 bool SrcIsKill =
MI.getOperand(1).isKill();
2477 bool ImpIsDead =
MI.getOperand(2).isDead();
2478 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2480 if (SrcReg != DstLoReg) {
2481 buildMI(
MBB,
MBBI, AVR::MOVRdRr)
2487 buildMI(
MBB,
MBBI, AVR::EORRdRr)
2493 EOR->getOperand(3).setIsDead();
2495 MI.eraseFromParent();
2500bool AVRExpandPseudo::expand<AVR::SPREAD>(
Block &
MBB, BlockIt
MBBI) {
2504 bool DstIsDead =
MI.getOperand(0).isDead();
2505 unsigned Flags =
MI.getFlags();
2506 unsigned OpLo = AVR::INRdA;
2507 unsigned OpHi = AVR::INRdA;
2508 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2522 MI.eraseFromParent();
2527bool AVRExpandPseudo::expand<AVR::SPWRITE>(
Block &
MBB, BlockIt
MBBI) {
2532 bool SrcIsKill =
MI.getOperand(1).isKill();
2533 unsigned Flags =
MI.getFlags();
2534 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
2536 buildMI(
MBB,
MBBI, AVR::INRdA)
2541 buildMI(
MBB,
MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
2543 buildMI(
MBB,
MBBI, AVR::OUTARr)
2548 buildMI(
MBB,
MBBI, AVR::OUTARr)
2553 buildMI(
MBB,
MBBI, AVR::OUTARr)
2558 MI.eraseFromParent();
2562bool AVRExpandPseudo::expandMI(
Block &
MBB, BlockIt
MBBI) {
2564 int Opcode =
MBBI->getOpcode();
2568 return expand<Op>(MBB, MI)
2600 EXPAND(AVR::AtomicLoad8);
2601 EXPAND(AVR::AtomicLoad16);
2602 EXPAND(AVR::AtomicStore8);
2603 EXPAND(AVR::AtomicStore16);
2604 EXPAND(AVR::AtomicFence);
MachineBasicBlock MachineBasicBlock::iterator MBBI
#define AVR_EXPAND_PSEUDO_NAME
static Expected< BitVector > expand(StringRef S, StringRef Original)
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Utilities relating to AVR registers.
A specific AVR target MCU.
Register getTmpRegister() const
const TargetFrameLowering * getFrameLowering() const override
int getIORegRAMPZ() const
Get I/O register addresses.
const AVRInstrInfo * getInstrInfo() const override
const AVRRegisterInfo * getRegisterInfo() const override
The address of a basic block.
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
static MachineOperand CreateBA(const BlockAddress *BA, int64_t Offset, unsigned TargetFlags=0)
@ MO_Immediate
Immediate operand.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
StringRef - Represent a constant reference to a string, i.e.
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
TargetInstrInfo - Interface to description of machine instruction set.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MO_HI
On a symbol operand, this represents the hi part.
@ MO_NEG
On a symbol operand, this represents it has to be negated.
@ MO_LO
On a symbol operand, this represents the lo part.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Define
Register definition.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
This is an optimization pass for GlobalISel generic memory operations.
void initializeAVRExpandPseudoPass(PassRegistry &)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
unsigned getDeadRegState(bool B)
FunctionPass * createAVRExpandPseudoPass()
unsigned getUndefRegState(bool B)
unsigned getKillRegState(bool B)