29 #define AVR_EXPAND_PSEUDO_NAME "AVR pseudo instruction expansion pass" 49 typedef Block::iterator BlockIt;
55 const unsigned SCRATCH_REGISTER = AVR::R0;
57 const unsigned SREG_ADDR = 0x3f;
59 bool expandMBB(Block &MBB);
60 bool expandMI(Block &MBB, BlockIt MBBI);
61 template <
unsigned OP>
bool expand(Block &MBB, BlockIt MBBI);
64 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->
get(Opcode));
69 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->
get(Opcode), DstReg);
74 bool expandArith(
unsigned OpLo,
unsigned OpHi, Block &MBB, BlockIt MBBI);
75 bool expandLogic(
unsigned Op, Block &MBB, BlockIt MBBI);
76 bool expandLogicImm(
unsigned Op, Block &MBB, BlockIt MBBI);
77 bool isLogicImmOpRedundant(
unsigned Op,
unsigned ImmVal)
const;
79 template<
typename Func>
80 bool expandAtomic(Block &MBB, BlockIt MBBI, Func f);
82 template<
typename Func>
83 bool expandAtomicBinaryOp(
unsigned Opcode, Block &MBB, BlockIt MBBI, Func f);
85 bool expandAtomicBinaryOp(
unsigned Opcode, Block &MBB, BlockIt MBBI);
87 bool expandAtomicArithmeticOp(
unsigned MemOpcode,
101 BlockIt MBBI = MBB.
begin(),
E = MBB.
end();
103 BlockIt NMBBI = std::next(MBBI);
104 Modified |= expandMI(MBB, MBBI);
121 for (Block &MBB : MF) {
122 bool ContinueExpanding =
true;
123 unsigned ExpandCount = 0;
127 assert(ExpandCount < 10 &&
"pseudo expand limit reached");
129 bool BlockModified = expandMBB(MBB);
130 Modified |= BlockModified;
133 ContinueExpanding = BlockModified;
134 }
while (ContinueExpanding);
140 bool AVRExpandPseudo::
141 expandArith(
unsigned OpLo,
unsigned OpHi, Block &MBB, BlockIt MBBI) {
143 unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
150 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
151 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
153 buildMI(MBB, MBBI, OpLo)
158 auto MIBHI = buildMI(MBB, MBBI, OpHi)
164 MIBHI->getOperand(3).setIsDead();
167 MIBHI->getOperand(4).setIsKill();
173 bool AVRExpandPseudo::
174 expandLogic(
unsigned Op, Block &MBB, BlockIt MBBI) {
176 unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
183 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
184 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
186 auto MIBLO = buildMI(MBB, MBBI, Op)
192 MIBLO->getOperand(3).setIsDead();
194 auto MIBHI = buildMI(MBB, MBBI, Op)
200 MIBHI->getOperand(3).setIsDead();
206 bool AVRExpandPseudo::
207 isLogicImmOpRedundant(
unsigned Op,
unsigned ImmVal)
const {
210 if (Op == AVR::ANDIRdK && ImmVal == 0xff)
214 if (Op == AVR::ORIRdK && ImmVal == 0x0)
220 bool AVRExpandPseudo::
221 expandLogicImm(
unsigned Op, Block &MBB, BlockIt MBBI) {
223 unsigned DstLoReg, DstHiReg;
229 unsigned Lo8 = Imm & 0xff;
230 unsigned Hi8 = (Imm >> 8) & 0xff;
231 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
233 if (!isLogicImmOpRedundant(Op, Lo8)) {
234 auto MIBLO = buildMI(MBB, MBBI, Op)
240 MIBLO->getOperand(3).setIsDead();
243 if (!isLogicImmOpRedundant(Op, Hi8)) {
244 auto MIBHI = buildMI(MBB, MBBI, Op)
250 MIBHI->getOperand(3).setIsDead();
258 bool AVRExpandPseudo::expand<AVR::ADDWRdRr>(Block &MBB, BlockIt MBBI) {
259 return expandArith(AVR::ADDRdRr, AVR::ADCRdRr, MBB, MBBI);
263 bool AVRExpandPseudo::expand<AVR::ADCWRdRr>(Block &MBB, BlockIt MBBI) {
264 return expandArith(AVR::ADCRdRr, AVR::ADCRdRr, MBB, MBBI);
268 bool AVRExpandPseudo::expand<AVR::SUBWRdRr>(Block &MBB, BlockIt MBBI) {
269 return expandArith(AVR::SUBRdRr, AVR::SBCRdRr, MBB, MBBI);
273 bool AVRExpandPseudo::expand<AVR::SUBIWRdK>(Block &MBB, BlockIt MBBI) {
275 unsigned DstLoReg, DstHiReg;
280 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
282 auto MIBLO = buildMI(MBB, MBBI, AVR::SUBIRdK)
286 auto MIBHI = buildMI(MBB, MBBI, AVR::SBCIRdK)
301 MIBLO.addImm(Imm & 0xff);
302 MIBHI.addImm((Imm >> 8) & 0xff);
310 MIBHI->getOperand(3).setIsDead();
313 MIBHI->getOperand(4).setIsKill();
320 bool AVRExpandPseudo::expand<AVR::SBCWRdRr>(Block &MBB, BlockIt MBBI) {
321 return expandArith(AVR::SBCRdRr, AVR::SBCRdRr, MBB, MBBI);
325 bool AVRExpandPseudo::expand<AVR::SBCIWRdK>(Block &MBB, BlockIt MBBI) {
327 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
333 unsigned Lo8 = Imm & 0xff;
334 unsigned Hi8 = (Imm >> 8) & 0xff;
337 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
339 auto MIBLO = buildMI(MBB, MBBI, OpLo)
345 MIBLO->getOperand(4).setIsKill();
347 auto MIBHI = buildMI(MBB, MBBI, OpHi)
353 MIBHI->getOperand(3).setIsDead();
356 MIBHI->getOperand(4).setIsKill();
363 bool AVRExpandPseudo::expand<AVR::ANDWRdRr>(Block &MBB, BlockIt MBBI) {
364 return expandLogic(AVR::ANDRdRr, MBB, MBBI);
368 bool AVRExpandPseudo::expand<AVR::ANDIWRdK>(Block &MBB, BlockIt MBBI) {
369 return expandLogicImm(AVR::ANDIRdK, MBB, MBBI);
373 bool AVRExpandPseudo::expand<AVR::ORWRdRr>(Block &MBB, BlockIt MBBI) {
374 return expandLogic(AVR::ORRdRr, MBB, MBBI);
378 bool AVRExpandPseudo::expand<AVR::ORIWRdK>(Block &MBB, BlockIt MBBI) {
379 return expandLogicImm(AVR::ORIRdK, MBB, MBBI);
383 bool AVRExpandPseudo::expand<AVR::EORWRdRr>(Block &MBB, BlockIt MBBI) {
384 return expandLogic(AVR::EORRdRr, MBB, MBBI);
388 bool AVRExpandPseudo::expand<AVR::COMWRd>(Block &MBB, BlockIt MBBI) {
390 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
397 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
399 auto MIBLO = buildMI(MBB, MBBI, OpLo)
404 MIBLO->getOperand(2).setIsDead();
406 auto MIBHI = buildMI(MBB, MBBI, OpHi)
411 MIBHI->getOperand(2).setIsDead();
418 bool AVRExpandPseudo::expand<AVR::CPWRdRr>(Block &MBB, BlockIt MBBI) {
420 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
428 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
429 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
432 buildMI(MBB, MBBI, OpLo)
436 auto MIBHI = buildMI(MBB, MBBI, OpHi)
441 MIBHI->getOperand(2).setIsDead();
444 MIBHI->getOperand(3).setIsKill();
451 bool AVRExpandPseudo::expand<AVR::CPCWRdRr>(Block &MBB, BlockIt MBBI) {
453 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
461 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
462 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
464 auto MIBLO = buildMI(MBB, MBBI, OpLo)
469 MIBLO->getOperand(3).setIsKill();
471 auto MIBHI = buildMI(MBB, MBBI, OpHi)
476 MIBHI->getOperand(2).setIsDead();
479 MIBHI->getOperand(3).setIsKill();
486 bool AVRExpandPseudo::expand<AVR::LDIWRdK>(Block &MBB, BlockIt MBBI) {
488 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
493 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
495 auto MIBLO = buildMI(MBB, MBBI, OpLo)
498 auto MIBHI = buildMI(MBB, MBBI, OpHi)
522 MIBLO.addImm(Imm & 0xff);
523 MIBHI.addImm((Imm >> 8) & 0xff);
535 bool AVRExpandPseudo::expand<AVR::LDSWRdK>(Block &MBB, BlockIt MBBI) {
537 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
542 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
544 auto MIBLO = buildMI(MBB, MBBI, OpLo)
547 auto MIBHI = buildMI(MBB, MBBI, OpHi)
556 MIBLO.addGlobalAddress(GV, Offs, TF);
557 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
564 MIBHI.addImm(Imm + 1);
579 bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) {
581 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
586 OpLo = AVR::LDRdPtrPi;
588 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
591 if (DstReg == SrcReg)
592 TmpReg = scavengeGPR8(MI);
594 unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
595 unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
598 auto MIBLO = buildMI(MBB, MBBI, OpLo)
605 buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
608 auto MIBHI = buildMI(MBB, MBBI, OpHi)
614 buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
617 buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
628 bool AVRExpandPseudo::expand<AVR::LDWRdPtrPi>(Block &MBB, BlockIt MBBI) {
630 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
635 OpLo = AVR::LDRdPtrPi;
636 OpHi = AVR::LDRdPtrPi;
637 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
639 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
641 auto MIBLO = buildMI(MBB, MBBI, OpLo)
646 auto MIBHI = buildMI(MBB, MBBI, OpHi)
659 bool AVRExpandPseudo::expand<AVR::LDWRdPtrPd>(Block &MBB, BlockIt MBBI) {
661 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
666 OpLo = AVR::LDRdPtrPd;
667 OpHi = AVR::LDRdPtrPd;
668 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
670 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
672 auto MIBHI = buildMI(MBB, MBBI, OpHi)
677 auto MIBLO = buildMI(MBB, MBBI, OpLo)
690 bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
692 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
698 OpLo = AVR::LDDRdPtrQ;
699 OpHi = AVR::LDDRdPtrQ;
700 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
704 assert(Imm <= 62 &&
"Offset is out of range");
707 if (DstReg == SrcReg)
708 TmpReg = scavengeGPR8(MI);
710 unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
711 unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
714 auto MIBLO = buildMI(MBB, MBBI, OpLo)
721 buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
724 auto MIBHI = buildMI(MBB, MBBI, OpHi)
731 buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
734 buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
745 bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(Block &MBB, BlockIt MBBI) {
747 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
752 OpLo = AVR::LPMRdZPi;
754 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
757 if (DstReg == SrcReg)
758 TmpReg = scavengeGPR8(MI);
760 unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
761 unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
764 auto MIBLO = buildMI(MBB, MBBI, OpLo)
770 buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
773 auto MIBHI = buildMI(MBB, MBBI, OpHi)
779 buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
782 buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
793 bool AVRExpandPseudo::expand<AVR::LPMWRdZPi>(Block &MBB, BlockIt MBBI) {
797 template<
typename Func>
798 bool AVRExpandPseudo::expandAtomic(Block &MBB, BlockIt MBBI, Func f) {
803 buildMI(MBB, MBBI, AVR::INRdA)
808 buildMI(MBB, MBBI, AVR::BCLRs).addImm(7);
813 buildMI(MBB, MBBI, AVR::OUTARr)
815 .addReg(SCRATCH_REGISTER);
821 template<
typename Func>
822 bool AVRExpandPseudo::expandAtomicBinaryOp(
unsigned Opcode,
831 *buildMI(MBB, MBBI, Opcode).add(Op1).add(Op2).getInstr();
836 bool AVRExpandPseudo::expandAtomicBinaryOp(
unsigned Opcode,
839 return expandAtomicBinaryOp(Opcode, MBB, MBBI, [](
MachineInstr &
MI) {});
842 bool AVRExpandPseudo::expandAtomicArithmeticOp(
unsigned Width,
843 unsigned ArithOpcode,
850 unsigned LoadOpcode = (Width == 8) ? AVR::LDRdPtr : AVR::LDWRdPtr;
851 unsigned StoreOpcode = (Width == 8) ? AVR::STPtrRr : AVR::STWPtrRr;
854 buildMI(MBB, MBBI, LoadOpcode).add(Op1).add(Op2);
857 buildMI(MBB, MBBI, ArithOpcode).add(Op1).add(Op1).add(Op2);
860 buildMI(MBB, MBBI, StoreOpcode).add(Op2).add(Op1);
872 TRI->getAllocatableSet
877 if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() &&
879 Candidates.
reset(MO.getReg());
883 Available &= Candidates;
886 assert(Reg != -1 &&
"ran out of registers");
891 bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(Block &MBB, BlockIt MBBI) {
892 return expandAtomicBinaryOp(AVR::LDRdPtr, MBB, MBBI);
896 bool AVRExpandPseudo::expand<AVR::AtomicLoad16>(Block &MBB, BlockIt MBBI) {
897 return expandAtomicBinaryOp(AVR::LDWRdPtr, MBB, MBBI);
901 bool AVRExpandPseudo::expand<AVR::AtomicStore8>(Block &MBB, BlockIt MBBI) {
902 return expandAtomicBinaryOp(AVR::STPtrRr, MBB, MBBI);
906 bool AVRExpandPseudo::expand<AVR::AtomicStore16>(Block &MBB, BlockIt MBBI) {
907 return expandAtomicBinaryOp(AVR::STWPtrRr, MBB, MBBI);
911 bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd8>(Block &MBB, BlockIt MBBI) {
912 return expandAtomicArithmeticOp(8, AVR::ADDRdRr, MBB, MBBI);
916 bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd16>(Block &MBB, BlockIt MBBI) {
917 return expandAtomicArithmeticOp(16, AVR::ADDWRdRr, MBB, MBBI);
921 bool AVRExpandPseudo::expand<AVR::AtomicLoadSub8>(Block &MBB, BlockIt MBBI) {
922 return expandAtomicArithmeticOp(8, AVR::SUBRdRr, MBB, MBBI);
926 bool AVRExpandPseudo::expand<AVR::AtomicLoadSub16>(Block &MBB, BlockIt MBBI) {
927 return expandAtomicArithmeticOp(16, AVR::SUBWRdRr, MBB, MBBI);
931 bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd8>(Block &MBB, BlockIt MBBI) {
932 return expandAtomicArithmeticOp(8, AVR::ANDRdRr, MBB, MBBI);
936 bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd16>(Block &MBB, BlockIt MBBI) {
937 return expandAtomicArithmeticOp(16, AVR::ANDWRdRr, MBB, MBBI);
941 bool AVRExpandPseudo::expand<AVR::AtomicLoadOr8>(Block &MBB, BlockIt MBBI) {
942 return expandAtomicArithmeticOp(8, AVR::ORRdRr, MBB, MBBI);
946 bool AVRExpandPseudo::expand<AVR::AtomicLoadOr16>(Block &MBB, BlockIt MBBI) {
947 return expandAtomicArithmeticOp(16, AVR::ORWRdRr, MBB, MBBI);
951 bool AVRExpandPseudo::expand<AVR::AtomicLoadXor8>(Block &MBB, BlockIt MBBI) {
952 return expandAtomicArithmeticOp(8, AVR::EORRdRr, MBB, MBBI);
956 bool AVRExpandPseudo::expand<AVR::AtomicLoadXor16>(Block &MBB, BlockIt MBBI) {
957 return expandAtomicArithmeticOp(16, AVR::EORWRdRr, MBB, MBBI);
961 bool AVRExpandPseudo::expand<AVR::AtomicFence>(Block &MBB, BlockIt MBBI) {
963 MBBI->eraseFromParent();
968 bool AVRExpandPseudo::expand<AVR::STSWKRr>(Block &MBB, BlockIt MBBI) {
970 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
975 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
979 auto MIBHI = buildMI(MBB, MBBI, OpHi);
980 auto MIBLO = buildMI(MBB, MBBI, OpLo);
988 MIBLO.addGlobalAddress(GV, Offs, TF);
989 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
996 MIBHI.addImm(Imm + 1);
1014 bool AVRExpandPseudo::expand<AVR::STWPtrRr>(Block &MBB, BlockIt MBBI) {
1016 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1020 OpLo = AVR::STPtrRr;
1021 OpHi = AVR::STDPtrQRr;
1022 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1025 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1029 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1042 bool AVRExpandPseudo::expand<AVR::STWPtrPiRr>(Block &MBB, BlockIt MBBI) {
1044 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1050 OpLo = AVR::STPtrPiRr;
1051 OpHi = AVR::STPtrPiRr;
1052 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1054 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
1056 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1062 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1076 bool AVRExpandPseudo::expand<AVR::STWPtrPdRr>(Block &MBB, BlockIt MBBI) {
1078 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1084 OpLo = AVR::STPtrPdRr;
1085 OpHi = AVR::STPtrPdRr;
1086 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1088 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
1090 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1096 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1110 bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(Block &MBB, BlockIt MBBI) {
1112 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1118 OpLo = AVR::STDPtrQRr;
1119 OpHi = AVR::STDPtrQRr;
1120 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1124 assert(Imm <= 62 &&
"Offset is out of range");
1126 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1131 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1144 bool AVRExpandPseudo::expand<AVR::INWRdA>(Block &MBB, BlockIt MBBI) {
1146 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1152 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1156 assert(Imm <= 62 &&
"Address is out of range");
1158 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1162 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1174 bool AVRExpandPseudo::expand<AVR::OUTWARr>(Block &MBB, BlockIt MBBI) {
1176 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1182 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1186 assert(Imm <= 62 &&
"Address is out of range");
1189 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1193 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1205 bool AVRExpandPseudo::expand<AVR::PUSHWRr>(Block &MBB, BlockIt MBBI) {
1207 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1213 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1216 buildMI(MBB, MBBI, OpLo)
1221 buildMI(MBB, MBBI, OpHi)
1230 bool AVRExpandPseudo::expand<AVR::POPWRd>(Block &MBB, BlockIt MBBI) {
1232 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1237 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1239 buildMI(MBB, MBBI, OpHi, DstHiReg).setMIFlags(Flags);
1240 buildMI(MBB, MBBI, OpLo, DstLoReg).setMIFlags(Flags);
1247 bool AVRExpandPseudo::expand<AVR::LSLWRd>(Block &MBB, BlockIt MBBI) {
1249 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1254 OpLo = AVR::ADDRdRr;
1255 OpHi = AVR::ADCRdRr;
1256 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1259 buildMI(MBB, MBBI, OpLo)
1264 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1270 MIBHI->getOperand(3).setIsDead();
1273 MIBHI->getOperand(4).setIsKill();
1280 bool AVRExpandPseudo::expand<AVR::LSRWRd>(Block &MBB, BlockIt MBBI) {
1282 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1289 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1292 buildMI(MBB, MBBI, OpHi)
1296 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1301 MIBLO->getOperand(2).setIsDead();
1304 MIBLO->getOperand(3).setIsKill();
1311 bool AVRExpandPseudo::expand<AVR::RORWRd>(Block &MBB, BlockIt MBBI) {
1317 bool AVRExpandPseudo::expand<AVR::ROLWRd>(Block &MBB, BlockIt MBBI) {
1323 bool AVRExpandPseudo::expand<AVR::ASRWRd>(Block &MBB, BlockIt MBBI) {
1325 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1332 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1335 buildMI(MBB, MBBI, OpHi)
1339 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1344 MIBLO->getOperand(2).setIsDead();
1347 MIBLO->getOperand(3).setIsKill();
1353 template <>
bool AVRExpandPseudo::expand<AVR::SEXT>(Block &MBB, BlockIt MBBI) {
1355 unsigned DstLoReg, DstHiReg;
1374 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1376 if (SrcReg != DstLoReg) {
1377 auto MOV = buildMI(MBB, MBBI, AVR::MOVRdRr)
1381 if (SrcReg == DstHiReg) {
1382 MOV->getOperand(1).setIsKill();
1386 if (SrcReg != DstHiReg) {
1387 buildMI(MBB, MBBI, AVR::MOVRdRr)
1392 buildMI(MBB, MBBI, AVR::ADDRdRr)
1397 auto SBC = buildMI(MBB, MBBI, AVR::SBCRdRr)
1403 SBC->getOperand(3).setIsDead();
1406 SBC->getOperand(4).setIsKill();
1412 template <>
bool AVRExpandPseudo::expand<AVR::ZEXT>(Block &MBB, BlockIt MBBI) {
1414 unsigned DstLoReg, DstHiReg;
1428 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1430 if (SrcReg != DstLoReg) {
1431 buildMI(MBB, MBBI, AVR::MOVRdRr)
1436 auto EOR = buildMI(MBB, MBBI, AVR::EORRdRr)
1442 EOR->getOperand(3).setIsDead();
1449 bool AVRExpandPseudo::expand<AVR::SPREAD>(Block &MBB, BlockIt MBBI) {
1451 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1457 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1460 buildMI(MBB, MBBI, OpLo)
1466 buildMI(MBB, MBBI, OpHi)
1476 bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
1478 unsigned SrcLoReg, SrcHiReg;
1482 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1484 buildMI(MBB, MBBI, AVR::INRdA)
1489 buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
1491 buildMI(MBB, MBBI, AVR::OUTARr)
1496 buildMI(MBB, MBBI, AVR::OUTARr)
1501 buildMI(MBB, MBBI, AVR::OUTARr)
1510 bool AVRExpandPseudo::expandMI(Block &MBB, BlockIt MBBI) {
1512 int Opcode = MBBI->getOpcode();
1514 #define EXPAND(Op) \ 1516 return expand<Op>(MBB, MI) 1542 EXPAND(AVR::AtomicLoad8);
1543 EXPAND(AVR::AtomicLoad16);
1544 EXPAND(AVR::AtomicStore8);
1545 EXPAND(AVR::AtomicStore16);
1546 EXPAND(AVR::AtomicLoadAdd8);
1547 EXPAND(AVR::AtomicLoadAdd16);
1548 EXPAND(AVR::AtomicLoadSub8);
1549 EXPAND(AVR::AtomicLoadSub16);
1550 EXPAND(AVR::AtomicLoadAnd8);
1551 EXPAND(AVR::AtomicLoadAnd16);
1552 EXPAND(AVR::AtomicLoadOr8);
1553 EXPAND(AVR::AtomicLoadOr16);
1554 EXPAND(AVR::AtomicLoadXor8);
1555 EXPAND(AVR::AtomicLoadXor16);
1556 EXPAND(AVR::AtomicFence);
unsigned getTargetFlags() const
const AVRInstrInfo * getInstrInfo() const override
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
This class represents lattice values for constants.
const MachineFunctionProperties & getProperties() const
Get the function properties.
unsigned getReg() const
getReg - Returns the register number.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
unsigned const TargetRegisterInfo * TRI
iterator_range< mop_iterator > operands()
Utilities relating to AVR registers.
The address of a basic block.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
void forward()
Move the internal MBB iterator and update register states.
BitVector getRegsAvailable(const TargetRegisterClass *RC)
Return all available registers in the register class in Mask.
On a symbol operand, this represents it has to be negated.
unsigned getKillRegState(bool B)
TargetInstrInfo - Interface to description of machine instruction set.
unsigned getDeadRegState(bool B)
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Address of a global value.
This file declares the machine register scavenger class.
ArrayRef< MachineMemOperand * > memoperands() const
Access to memory operands of the instruction.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const GlobalValue * getGlobal() const
static MachineOperand CreateBA(const BlockAddress *BA, int64_t Offset, unsigned char TargetFlags=0)
Address of a basic block.
FunctionPass class - This class is used to implement most global optimizations.
static Expected< BitVector > expand(StringRef S, StringRef Original)
On a symbol operand, this represents the hi part.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MachineOperand class - Representation of each machine instruction operand.
A specific AVR target MCU.
FunctionPass * createAVRExpandPseudoPass()
On a symbol operand, this represents the lo part.
const MachineBasicBlock * getParent() const
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
MachineFunctionProperties & set(Property P)
Representation of each machine instruction.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void enterBasicBlock(MachineBasicBlock &MBB)
Start tracking liveness from the begin of basic block MBB.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
int64_t getOffset() const
Return the offset from the symbol in this operand.
const BlockAddress * getBlockAddress() const
uint16_t getFlags() const
Return the MI flags bitvector.
INITIALIZE_PASS(AVRExpandPseudo, "avr-expand-pseudo", AVR_EXPAND_PSEUDO_NAME, false, false) namespace llvm
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const AVRRegisterInfo * getRegisterInfo() const override
StringRef - Represent a constant reference to a string, i.e.
const MachineOperand & getOperand(unsigned i) const
#define AVR_EXPAND_PSEUDO_NAME
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
void initializeAVRExpandPseudoPass(PassRegistry &)