28 #define AVR_EXPAND_PSEUDO_NAME "AVR pseudo instruction expansion pass" 48 typedef Block::iterator BlockIt;
54 const unsigned SCRATCH_REGISTER = AVR::R0;
56 const unsigned SREG_ADDR = 0x3f;
58 bool expandMBB(Block &MBB);
59 bool expandMI(Block &MBB, BlockIt MBBI);
60 template <
unsigned OP>
bool expand(Block &MBB, BlockIt MBBI);
63 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->
get(Opcode));
68 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->
get(Opcode), DstReg);
73 bool expandArith(
unsigned OpLo,
unsigned OpHi, Block &MBB, BlockIt MBBI);
74 bool expandLogic(
unsigned Op, Block &MBB, BlockIt MBBI);
75 bool expandLogicImm(
unsigned Op, Block &MBB, BlockIt MBBI);
76 bool isLogicImmOpRedundant(
unsigned Op,
unsigned ImmVal)
const;
78 template<
typename Func>
79 bool expandAtomic(Block &MBB, BlockIt MBBI, Func f);
81 template<
typename Func>
82 bool expandAtomicBinaryOp(
unsigned Opcode, Block &MBB, BlockIt MBBI, Func f);
84 bool expandAtomicBinaryOp(
unsigned Opcode, Block &MBB, BlockIt MBBI);
86 bool expandAtomicArithmeticOp(
unsigned MemOpcode,
100 BlockIt MBBI = MBB.
begin(),
E = MBB.
end();
102 BlockIt NMBBI = std::next(MBBI);
103 Modified |= expandMI(MBB, MBBI);
120 for (Block &MBB : MF) {
121 bool ContinueExpanding =
true;
122 unsigned ExpandCount = 0;
126 assert(ExpandCount < 10 &&
"pseudo expand limit reached");
128 bool BlockModified = expandMBB(MBB);
129 Modified |= BlockModified;
132 ContinueExpanding = BlockModified;
133 }
while (ContinueExpanding);
139 bool AVRExpandPseudo::
140 expandArith(
unsigned OpLo,
unsigned OpHi, Block &MBB, BlockIt MBBI) {
142 unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
149 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
150 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
152 buildMI(MBB, MBBI, OpLo)
157 auto MIBHI = buildMI(MBB, MBBI, OpHi)
163 MIBHI->getOperand(3).setIsDead();
166 MIBHI->getOperand(4).setIsKill();
172 bool AVRExpandPseudo::
173 expandLogic(
unsigned Op, Block &MBB, BlockIt MBBI) {
175 unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
182 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
183 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
185 auto MIBLO = buildMI(MBB, MBBI, Op)
191 MIBLO->getOperand(3).setIsDead();
193 auto MIBHI = buildMI(MBB, MBBI, Op)
199 MIBHI->getOperand(3).setIsDead();
205 bool AVRExpandPseudo::
206 isLogicImmOpRedundant(
unsigned Op,
unsigned ImmVal)
const {
209 if (Op == AVR::ANDIRdK && ImmVal == 0xff)
213 if (Op == AVR::ORIRdK && ImmVal == 0x0)
219 bool AVRExpandPseudo::
220 expandLogicImm(
unsigned Op, Block &MBB, BlockIt MBBI) {
222 unsigned DstLoReg, DstHiReg;
228 unsigned Lo8 = Imm & 0xff;
229 unsigned Hi8 = (Imm >> 8) & 0xff;
230 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
232 if (!isLogicImmOpRedundant(Op, Lo8)) {
233 auto MIBLO = buildMI(MBB, MBBI, Op)
239 MIBLO->getOperand(3).setIsDead();
242 if (!isLogicImmOpRedundant(Op, Hi8)) {
243 auto MIBHI = buildMI(MBB, MBBI, Op)
249 MIBHI->getOperand(3).setIsDead();
257 bool AVRExpandPseudo::expand<AVR::ADDWRdRr>(Block &MBB, BlockIt MBBI) {
258 return expandArith(AVR::ADDRdRr, AVR::ADCRdRr, MBB, MBBI);
262 bool AVRExpandPseudo::expand<AVR::ADCWRdRr>(Block &MBB, BlockIt MBBI) {
263 return expandArith(AVR::ADCRdRr, AVR::ADCRdRr, MBB, MBBI);
267 bool AVRExpandPseudo::expand<AVR::SUBWRdRr>(Block &MBB, BlockIt MBBI) {
268 return expandArith(AVR::SUBRdRr, AVR::SBCRdRr, MBB, MBBI);
272 bool AVRExpandPseudo::expand<AVR::SUBIWRdK>(Block &MBB, BlockIt MBBI) {
274 unsigned DstLoReg, DstHiReg;
279 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
281 auto MIBLO = buildMI(MBB, MBBI, AVR::SUBIRdK)
285 auto MIBHI = buildMI(MBB, MBBI, AVR::SBCIRdK)
300 MIBLO.addImm(Imm & 0xff);
301 MIBHI.addImm((Imm >> 8) & 0xff);
309 MIBHI->getOperand(3).setIsDead();
312 MIBHI->getOperand(4).setIsKill();
319 bool AVRExpandPseudo::expand<AVR::SBCWRdRr>(Block &MBB, BlockIt MBBI) {
320 return expandArith(AVR::SBCRdRr, AVR::SBCRdRr, MBB, MBBI);
324 bool AVRExpandPseudo::expand<AVR::SBCIWRdK>(Block &MBB, BlockIt MBBI) {
326 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
332 unsigned Lo8 = Imm & 0xff;
333 unsigned Hi8 = (Imm >> 8) & 0xff;
336 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
338 auto MIBLO = buildMI(MBB, MBBI, OpLo)
344 MIBLO->getOperand(4).setIsKill();
346 auto MIBHI = buildMI(MBB, MBBI, OpHi)
352 MIBHI->getOperand(3).setIsDead();
355 MIBHI->getOperand(4).setIsKill();
362 bool AVRExpandPseudo::expand<AVR::ANDWRdRr>(Block &MBB, BlockIt MBBI) {
363 return expandLogic(AVR::ANDRdRr, MBB, MBBI);
367 bool AVRExpandPseudo::expand<AVR::ANDIWRdK>(Block &MBB, BlockIt MBBI) {
368 return expandLogicImm(AVR::ANDIRdK, MBB, MBBI);
372 bool AVRExpandPseudo::expand<AVR::ORWRdRr>(Block &MBB, BlockIt MBBI) {
373 return expandLogic(AVR::ORRdRr, MBB, MBBI);
377 bool AVRExpandPseudo::expand<AVR::ORIWRdK>(Block &MBB, BlockIt MBBI) {
378 return expandLogicImm(AVR::ORIRdK, MBB, MBBI);
382 bool AVRExpandPseudo::expand<AVR::EORWRdRr>(Block &MBB, BlockIt MBBI) {
383 return expandLogic(AVR::EORRdRr, MBB, MBBI);
387 bool AVRExpandPseudo::expand<AVR::COMWRd>(Block &MBB, BlockIt MBBI) {
389 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
396 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
398 auto MIBLO = buildMI(MBB, MBBI, OpLo)
403 MIBLO->getOperand(2).setIsDead();
405 auto MIBHI = buildMI(MBB, MBBI, OpHi)
410 MIBHI->getOperand(2).setIsDead();
417 bool AVRExpandPseudo::expand<AVR::CPWRdRr>(Block &MBB, BlockIt MBBI) {
419 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
427 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
428 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
431 buildMI(MBB, MBBI, OpLo)
435 auto MIBHI = buildMI(MBB, MBBI, OpHi)
440 MIBHI->getOperand(2).setIsDead();
443 MIBHI->getOperand(3).setIsKill();
450 bool AVRExpandPseudo::expand<AVR::CPCWRdRr>(Block &MBB, BlockIt MBBI) {
452 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
460 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
461 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
463 auto MIBLO = buildMI(MBB, MBBI, OpLo)
468 MIBLO->getOperand(3).setIsKill();
470 auto MIBHI = buildMI(MBB, MBBI, OpHi)
475 MIBHI->getOperand(2).setIsDead();
478 MIBHI->getOperand(3).setIsKill();
485 bool AVRExpandPseudo::expand<AVR::LDIWRdK>(Block &MBB, BlockIt MBBI) {
487 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
492 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
494 auto MIBLO = buildMI(MBB, MBBI, OpLo)
497 auto MIBHI = buildMI(MBB, MBBI, OpHi)
521 MIBLO.addImm(Imm & 0xff);
522 MIBHI.addImm((Imm >> 8) & 0xff);
534 bool AVRExpandPseudo::expand<AVR::LDSWRdK>(Block &MBB, BlockIt MBBI) {
536 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
541 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
543 auto MIBLO = buildMI(MBB, MBBI, OpLo)
546 auto MIBHI = buildMI(MBB, MBBI, OpHi)
555 MIBLO.addGlobalAddress(GV, Offs, TF);
556 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
563 MIBHI.addImm(Imm + 1);
578 bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) {
580 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
586 OpHi = AVR::LDDRdPtrQ;
587 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
590 if (DstReg == SrcReg)
591 TmpReg = scavengeGPR8(MI);
593 unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
594 unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
597 auto MIBLO = buildMI(MBB, MBBI, OpLo)
603 buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
606 auto MIBHI = buildMI(MBB, MBBI, OpHi)
613 buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
616 buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
627 bool AVRExpandPseudo::expand<AVR::LDWRdPtrPi>(Block &MBB, BlockIt MBBI) {
629 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
634 OpLo = AVR::LDRdPtrPi;
635 OpHi = AVR::LDRdPtrPi;
636 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
638 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
640 auto MIBLO = buildMI(MBB, MBBI, OpLo)
645 auto MIBHI = buildMI(MBB, MBBI, OpHi)
658 bool AVRExpandPseudo::expand<AVR::LDWRdPtrPd>(Block &MBB, BlockIt MBBI) {
660 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
665 OpLo = AVR::LDRdPtrPd;
666 OpHi = AVR::LDRdPtrPd;
667 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
669 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
671 auto MIBHI = buildMI(MBB, MBBI, OpHi)
676 auto MIBLO = buildMI(MBB, MBBI, OpLo)
689 bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
691 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
697 OpLo = AVR::LDDRdPtrQ;
698 OpHi = AVR::LDDRdPtrQ;
699 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
703 assert(Imm <= 62 &&
"Offset is out of range");
706 if (DstReg == SrcReg)
707 TmpReg = scavengeGPR8(MI);
709 unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
710 unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
713 auto MIBLO = buildMI(MBB, MBBI, OpLo)
720 buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
723 auto MIBHI = buildMI(MBB, MBBI, OpHi)
730 buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
733 buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
744 bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(Block &MBB, BlockIt MBBI) {
746 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
751 OpLo = AVR::LPMRdZPi;
753 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
756 if (DstReg == SrcReg)
757 TmpReg = scavengeGPR8(MI);
759 unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
760 unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
763 auto MIBLO = buildMI(MBB, MBBI, OpLo)
769 buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
772 auto MIBHI = buildMI(MBB, MBBI, OpHi)
778 buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
781 buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
792 bool AVRExpandPseudo::expand<AVR::LPMWRdZPi>(Block &MBB, BlockIt MBBI) {
796 template<
typename Func>
797 bool AVRExpandPseudo::expandAtomic(Block &MBB, BlockIt MBBI, Func f) {
802 buildMI(MBB, MBBI, AVR::INRdA)
807 buildMI(MBB, MBBI, AVR::BCLRs).addImm(7);
812 buildMI(MBB, MBBI, AVR::OUTARr)
814 .addReg(SCRATCH_REGISTER);
820 template<
typename Func>
821 bool AVRExpandPseudo::expandAtomicBinaryOp(
unsigned Opcode,
830 *buildMI(MBB, MBBI, Opcode).add(Op1).add(Op2).getInstr();
835 bool AVRExpandPseudo::expandAtomicBinaryOp(
unsigned Opcode,
838 return expandAtomicBinaryOp(Opcode, MBB, MBBI, [](
MachineInstr &
MI) {});
841 bool AVRExpandPseudo::expandAtomicArithmeticOp(
unsigned Width,
842 unsigned ArithOpcode,
849 unsigned LoadOpcode = (Width == 8) ? AVR::LDRdPtr : AVR::LDWRdPtr;
850 unsigned StoreOpcode = (Width == 8) ? AVR::STPtrRr : AVR::STWPtrRr;
853 buildMI(MBB, MBBI, LoadOpcode).add(Op1).add(Op2);
856 buildMI(MBB, MBBI, ArithOpcode).add(Op1).add(Op1).add(Op2);
859 buildMI(MBB, MBBI, StoreOpcode).add(Op2).add(Op1);
871 TRI->getAllocatableSet
876 if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() &&
878 Candidates.
reset(MO.getReg());
882 Available &= Candidates;
885 assert(Reg != -1 &&
"ran out of registers");
890 bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(Block &MBB, BlockIt MBBI) {
891 return expandAtomicBinaryOp(AVR::LDRdPtr, MBB, MBBI);
895 bool AVRExpandPseudo::expand<AVR::AtomicLoad16>(Block &MBB, BlockIt MBBI) {
896 return expandAtomicBinaryOp(AVR::LDWRdPtr, MBB, MBBI);
900 bool AVRExpandPseudo::expand<AVR::AtomicStore8>(Block &MBB, BlockIt MBBI) {
901 return expandAtomicBinaryOp(AVR::STPtrRr, MBB, MBBI);
905 bool AVRExpandPseudo::expand<AVR::AtomicStore16>(Block &MBB, BlockIt MBBI) {
906 return expandAtomicBinaryOp(AVR::STWPtrRr, MBB, MBBI);
910 bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd8>(Block &MBB, BlockIt MBBI) {
911 return expandAtomicArithmeticOp(8, AVR::ADDRdRr, MBB, MBBI);
915 bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd16>(Block &MBB, BlockIt MBBI) {
916 return expandAtomicArithmeticOp(16, AVR::ADDWRdRr, MBB, MBBI);
920 bool AVRExpandPseudo::expand<AVR::AtomicLoadSub8>(Block &MBB, BlockIt MBBI) {
921 return expandAtomicArithmeticOp(8, AVR::SUBRdRr, MBB, MBBI);
925 bool AVRExpandPseudo::expand<AVR::AtomicLoadSub16>(Block &MBB, BlockIt MBBI) {
926 return expandAtomicArithmeticOp(16, AVR::SUBWRdRr, MBB, MBBI);
930 bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd8>(Block &MBB, BlockIt MBBI) {
931 return expandAtomicArithmeticOp(8, AVR::ANDRdRr, MBB, MBBI);
935 bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd16>(Block &MBB, BlockIt MBBI) {
936 return expandAtomicArithmeticOp(16, AVR::ANDWRdRr, MBB, MBBI);
940 bool AVRExpandPseudo::expand<AVR::AtomicLoadOr8>(Block &MBB, BlockIt MBBI) {
941 return expandAtomicArithmeticOp(8, AVR::ORRdRr, MBB, MBBI);
945 bool AVRExpandPseudo::expand<AVR::AtomicLoadOr16>(Block &MBB, BlockIt MBBI) {
946 return expandAtomicArithmeticOp(16, AVR::ORWRdRr, MBB, MBBI);
950 bool AVRExpandPseudo::expand<AVR::AtomicLoadXor8>(Block &MBB, BlockIt MBBI) {
951 return expandAtomicArithmeticOp(8, AVR::EORRdRr, MBB, MBBI);
955 bool AVRExpandPseudo::expand<AVR::AtomicLoadXor16>(Block &MBB, BlockIt MBBI) {
956 return expandAtomicArithmeticOp(16, AVR::EORWRdRr, MBB, MBBI);
960 bool AVRExpandPseudo::expand<AVR::AtomicFence>(Block &MBB, BlockIt MBBI) {
962 MBBI->eraseFromParent();
967 bool AVRExpandPseudo::expand<AVR::STSWKRr>(Block &MBB, BlockIt MBBI) {
969 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
974 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
978 auto MIBHI = buildMI(MBB, MBBI, OpHi);
979 auto MIBLO = buildMI(MBB, MBBI, OpLo);
987 MIBLO.addGlobalAddress(GV, Offs, TF);
988 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
995 MIBHI.addImm(Imm + 1);
1013 bool AVRExpandPseudo::expand<AVR::STWPtrRr>(Block &MBB, BlockIt MBBI) {
1015 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1019 OpLo = AVR::STPtrRr;
1020 OpHi = AVR::STDPtrQRr;
1021 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1024 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1028 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1041 bool AVRExpandPseudo::expand<AVR::STWPtrPiRr>(Block &MBB, BlockIt MBBI) {
1043 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1049 OpLo = AVR::STPtrPiRr;
1050 OpHi = AVR::STPtrPiRr;
1051 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1053 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
1055 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1061 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1075 bool AVRExpandPseudo::expand<AVR::STWPtrPdRr>(Block &MBB, BlockIt MBBI) {
1077 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1083 OpLo = AVR::STPtrPdRr;
1084 OpHi = AVR::STPtrPdRr;
1085 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1087 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
1089 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1095 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1109 bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(Block &MBB, BlockIt MBBI) {
1111 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1117 OpLo = AVR::STDPtrQRr;
1118 OpHi = AVR::STDPtrQRr;
1119 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1123 assert(Imm <= 62 &&
"Offset is out of range");
1125 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1130 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1143 bool AVRExpandPseudo::expand<AVR::INWRdA>(Block &MBB, BlockIt MBBI) {
1145 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1151 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1155 assert(Imm <= 62 &&
"Address is out of range");
1157 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1161 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1173 bool AVRExpandPseudo::expand<AVR::OUTWARr>(Block &MBB, BlockIt MBBI) {
1175 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1181 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1185 assert(Imm <= 62 &&
"Address is out of range");
1188 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1192 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1204 bool AVRExpandPseudo::expand<AVR::PUSHWRr>(Block &MBB, BlockIt MBBI) {
1206 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1212 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1215 buildMI(MBB, MBBI, OpLo)
1220 buildMI(MBB, MBBI, OpHi)
1229 bool AVRExpandPseudo::expand<AVR::POPWRd>(Block &MBB, BlockIt MBBI) {
1231 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1236 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1238 buildMI(MBB, MBBI, OpHi, DstHiReg).setMIFlags(Flags);
1239 buildMI(MBB, MBBI, OpLo, DstLoReg).setMIFlags(Flags);
1246 bool AVRExpandPseudo::expand<AVR::LSLWRd>(Block &MBB, BlockIt MBBI) {
1248 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1253 OpLo = AVR::ADDRdRr;
1254 OpHi = AVR::ADCRdRr;
1255 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1258 buildMI(MBB, MBBI, OpLo)
1263 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1269 MIBHI->getOperand(3).setIsDead();
1272 MIBHI->getOperand(4).setIsKill();
1279 bool AVRExpandPseudo::expand<AVR::LSRWRd>(Block &MBB, BlockIt MBBI) {
1281 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1288 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1291 buildMI(MBB, MBBI, OpHi)
1295 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1300 MIBLO->getOperand(2).setIsDead();
1303 MIBLO->getOperand(3).setIsKill();
1310 bool AVRExpandPseudo::expand<AVR::RORWRd>(Block &MBB, BlockIt MBBI) {
1316 bool AVRExpandPseudo::expand<AVR::ROLWRd>(Block &MBB, BlockIt MBBI) {
1322 bool AVRExpandPseudo::expand<AVR::ASRWRd>(Block &MBB, BlockIt MBBI) {
1324 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1331 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1334 buildMI(MBB, MBBI, OpHi)
1338 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1343 MIBLO->getOperand(2).setIsDead();
1346 MIBLO->getOperand(3).setIsKill();
1352 template <>
bool AVRExpandPseudo::expand<AVR::SEXT>(Block &MBB, BlockIt MBBI) {
1354 unsigned DstLoReg, DstHiReg;
1373 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1375 if (SrcReg != DstLoReg) {
1376 auto MOV = buildMI(MBB, MBBI, AVR::MOVRdRr)
1380 if (SrcReg == DstHiReg) {
1381 MOV->getOperand(1).setIsKill();
1385 if (SrcReg != DstHiReg) {
1386 buildMI(MBB, MBBI, AVR::MOVRdRr)
1391 buildMI(MBB, MBBI, AVR::ADDRdRr)
1396 auto SBC = buildMI(MBB, MBBI, AVR::SBCRdRr)
1402 SBC->getOperand(3).setIsDead();
1405 SBC->getOperand(4).setIsKill();
1411 template <>
bool AVRExpandPseudo::expand<AVR::ZEXT>(Block &MBB, BlockIt MBBI) {
1413 unsigned DstLoReg, DstHiReg;
1427 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1429 if (SrcReg != DstLoReg) {
1430 buildMI(MBB, MBBI, AVR::MOVRdRr)
1435 auto EOR = buildMI(MBB, MBBI, AVR::EORRdRr)
1441 EOR->getOperand(3).setIsDead();
1448 bool AVRExpandPseudo::expand<AVR::SPREAD>(Block &MBB, BlockIt MBBI) {
1450 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1456 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1459 buildMI(MBB, MBBI, OpLo)
1465 buildMI(MBB, MBBI, OpHi)
1475 bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
1477 unsigned SrcLoReg, SrcHiReg;
1481 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1483 buildMI(MBB, MBBI, AVR::INRdA)
1488 buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
1490 buildMI(MBB, MBBI, AVR::OUTARr)
1495 buildMI(MBB, MBBI, AVR::OUTARr)
1500 buildMI(MBB, MBBI, AVR::OUTARr)
1509 bool AVRExpandPseudo::expandMI(Block &MBB, BlockIt MBBI) {
1511 int Opcode = MBBI->getOpcode();
1513 #define EXPAND(Op) \ 1515 return expand<Op>(MBB, MI) 1541 EXPAND(AVR::AtomicLoad8);
1542 EXPAND(AVR::AtomicLoad16);
1543 EXPAND(AVR::AtomicStore8);
1544 EXPAND(AVR::AtomicStore16);
1545 EXPAND(AVR::AtomicLoadAdd8);
1546 EXPAND(AVR::AtomicLoadAdd16);
1547 EXPAND(AVR::AtomicLoadSub8);
1548 EXPAND(AVR::AtomicLoadSub16);
1549 EXPAND(AVR::AtomicLoadAnd8);
1550 EXPAND(AVR::AtomicLoadAnd16);
1551 EXPAND(AVR::AtomicLoadOr8);
1552 EXPAND(AVR::AtomicLoadOr16);
1553 EXPAND(AVR::AtomicLoadXor8);
1554 EXPAND(AVR::AtomicLoadXor16);
1555 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 &)