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,
96 bool Modified =
false;
98 BlockIt MBBI = MBB.
begin(),
E = MBB.
end();
100 BlockIt NMBBI = std::next(MBBI);
101 Modified |= expandMI(MBB, MBBI);
109 bool Modified =
false;
118 for (Block &MBB : MF) {
119 bool ContinueExpanding =
true;
120 unsigned ExpandCount = 0;
124 assert(ExpandCount < 10 &&
"pseudo expand limit reached");
126 bool BlockModified = expandMBB(MBB);
127 Modified |= BlockModified;
130 ContinueExpanding = BlockModified;
131 }
while (ContinueExpanding);
137 bool AVRExpandPseudo::
138 expandArith(
unsigned OpLo,
unsigned OpHi, Block &MBB, BlockIt MBBI) {
140 unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
147 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
148 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
150 buildMI(MBB, MBBI, OpLo)
155 auto MIBHI = buildMI(MBB, MBBI, OpHi)
161 MIBHI->getOperand(3).setIsDead();
164 MIBHI->getOperand(4).setIsKill();
170 bool AVRExpandPseudo::
171 expandLogic(
unsigned Op, Block &MBB, BlockIt MBBI) {
173 unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
180 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
181 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
183 auto MIBLO = buildMI(MBB, MBBI, Op)
189 MIBLO->getOperand(3).setIsDead();
191 auto MIBHI = buildMI(MBB, MBBI, Op)
197 MIBHI->getOperand(3).setIsDead();
203 bool AVRExpandPseudo::
204 isLogicImmOpRedundant(
unsigned Op,
unsigned ImmVal)
const {
207 if (Op == AVR::ANDIRdK && ImmVal == 0xff)
211 if (Op == AVR::ORIRdK && ImmVal == 0x0)
217 bool AVRExpandPseudo::
218 expandLogicImm(
unsigned Op, Block &MBB, BlockIt MBBI) {
220 unsigned DstLoReg, DstHiReg;
226 unsigned Lo8 = Imm & 0xff;
227 unsigned Hi8 = (Imm >> 8) & 0xff;
228 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
230 if (!isLogicImmOpRedundant(Op, Lo8)) {
231 auto MIBLO = buildMI(MBB, MBBI, Op)
237 MIBLO->getOperand(3).setIsDead();
240 if (!isLogicImmOpRedundant(Op, Hi8)) {
241 auto MIBHI = buildMI(MBB, MBBI, Op)
247 MIBHI->getOperand(3).setIsDead();
255 bool AVRExpandPseudo::expand<AVR::ADDWRdRr>(Block &
MBB, BlockIt MBBI) {
256 return expandArith(AVR::ADDRdRr, AVR::ADCRdRr, MBB, MBBI);
260 bool AVRExpandPseudo::expand<AVR::ADCWRdRr>(Block &
MBB, BlockIt MBBI) {
261 return expandArith(AVR::ADCRdRr, AVR::ADCRdRr, MBB, MBBI);
265 bool AVRExpandPseudo::expand<AVR::SUBWRdRr>(Block &
MBB, BlockIt MBBI) {
266 return expandArith(AVR::SUBRdRr, AVR::SBCRdRr, MBB, MBBI);
270 bool AVRExpandPseudo::expand<AVR::SUBIWRdK>(Block &
MBB, BlockIt MBBI) {
272 unsigned DstLoReg, DstHiReg;
277 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
279 auto MIBLO = buildMI(MBB, MBBI, AVR::SUBIRdK)
283 auto MIBHI = buildMI(MBB, MBBI, AVR::SBCIRdK)
298 MIBLO.addImm(Imm & 0xff);
299 MIBHI.addImm((Imm >> 8) & 0xff);
307 MIBHI->getOperand(3).setIsDead();
310 MIBHI->getOperand(4).setIsKill();
317 bool AVRExpandPseudo::expand<AVR::SBCWRdRr>(Block &
MBB, BlockIt MBBI) {
318 return expandArith(AVR::SBCRdRr, AVR::SBCRdRr, MBB, MBBI);
322 bool AVRExpandPseudo::expand<AVR::SBCIWRdK>(Block &
MBB, BlockIt MBBI) {
324 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
330 unsigned Lo8 = Imm & 0xff;
331 unsigned Hi8 = (Imm >> 8) & 0xff;
334 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
336 auto MIBLO = buildMI(MBB, MBBI, OpLo)
342 MIBLO->getOperand(4).setIsKill();
344 auto MIBHI = buildMI(MBB, MBBI, OpHi)
350 MIBHI->getOperand(3).setIsDead();
353 MIBHI->getOperand(4).setIsKill();
360 bool AVRExpandPseudo::expand<AVR::ANDWRdRr>(Block &
MBB, BlockIt MBBI) {
361 return expandLogic(AVR::ANDRdRr, MBB, MBBI);
365 bool AVRExpandPseudo::expand<AVR::ANDIWRdK>(Block &
MBB, BlockIt MBBI) {
366 return expandLogicImm(AVR::ANDIRdK, MBB, MBBI);
370 bool AVRExpandPseudo::expand<AVR::ORWRdRr>(Block &
MBB, BlockIt MBBI) {
371 return expandLogic(AVR::ORRdRr, MBB, MBBI);
375 bool AVRExpandPseudo::expand<AVR::ORIWRdK>(Block &
MBB, BlockIt MBBI) {
376 return expandLogicImm(AVR::ORIRdK, MBB, MBBI);
380 bool AVRExpandPseudo::expand<AVR::EORWRdRr>(Block &
MBB, BlockIt MBBI) {
381 return expandLogic(AVR::EORRdRr, MBB, MBBI);
385 bool AVRExpandPseudo::expand<AVR::COMWRd>(Block &
MBB, BlockIt MBBI) {
387 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
394 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
396 auto MIBLO = buildMI(MBB, MBBI, OpLo)
401 MIBLO->getOperand(2).setIsDead();
403 auto MIBHI = buildMI(MBB, MBBI, OpHi)
408 MIBHI->getOperand(2).setIsDead();
415 bool AVRExpandPseudo::expand<AVR::CPWRdRr>(Block &
MBB, BlockIt MBBI) {
417 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
425 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
426 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
429 buildMI(MBB, MBBI, OpLo)
433 auto MIBHI = buildMI(MBB, MBBI, OpHi)
438 MIBHI->getOperand(2).setIsDead();
441 MIBHI->getOperand(3).setIsKill();
448 bool AVRExpandPseudo::expand<AVR::CPCWRdRr>(Block &
MBB, BlockIt MBBI) {
450 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
458 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
459 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
461 auto MIBLO = buildMI(MBB, MBBI, OpLo)
466 MIBLO->getOperand(3).setIsKill();
468 auto MIBHI = buildMI(MBB, MBBI, OpHi)
473 MIBHI->getOperand(2).setIsDead();
476 MIBHI->getOperand(3).setIsKill();
483 bool AVRExpandPseudo::expand<AVR::LDIWRdK>(Block &
MBB, BlockIt MBBI) {
485 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
490 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
492 auto MIBLO = buildMI(MBB, MBBI, OpLo)
495 auto MIBHI = buildMI(MBB, MBBI, OpHi)
519 MIBLO.addImm(Imm & 0xff);
520 MIBHI.addImm((Imm >> 8) & 0xff);
532 bool AVRExpandPseudo::expand<AVR::LDSWRdK>(Block &
MBB, BlockIt MBBI) {
534 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
539 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
541 auto MIBLO = buildMI(MBB, MBBI, OpLo)
544 auto MIBHI = buildMI(MBB, MBBI, OpHi)
553 MIBLO.addGlobalAddress(GV, Offs, TF);
554 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
561 MIBHI.addImm(Imm + 1);
576 bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &
MBB, BlockIt MBBI) {
578 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
584 OpHi = AVR::LDDRdPtrQ;
585 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
587 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
589 auto MIBLO = buildMI(MBB, MBBI, OpLo)
593 auto MIBHI = buildMI(MBB, MBBI, OpHi)
606 bool AVRExpandPseudo::expand<AVR::LDWRdPtrPi>(Block &
MBB, BlockIt MBBI) {
608 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
613 OpLo = AVR::LDRdPtrPi;
614 OpHi = AVR::LDRdPtrPi;
615 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
617 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
619 auto MIBLO = buildMI(MBB, MBBI, OpLo)
624 auto MIBHI = buildMI(MBB, MBBI, OpHi)
637 bool AVRExpandPseudo::expand<AVR::LDWRdPtrPd>(Block &
MBB, BlockIt MBBI) {
639 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
644 OpLo = AVR::LDRdPtrPd;
645 OpHi = AVR::LDRdPtrPd;
646 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
648 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
650 auto MIBHI = buildMI(MBB, MBBI, OpHi)
655 auto MIBLO = buildMI(MBB, MBBI, OpLo)
668 bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &
MBB, BlockIt MBBI) {
670 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
676 OpLo = AVR::LDDRdPtrQ;
677 OpHi = AVR::LDDRdPtrQ;
678 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
680 assert(Imm <= 63 &&
"Offset is out of range");
690 if (DstReg == SrcReg) {
697 TRI->getAllocatableSet
698 (*MBB.getParent(), &AVR::GPR8RegClass);
702 if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() &&
704 Candidates.
reset(MO.getReg());
708 Available &= Candidates;
711 assert(TmpReg != -1 &&
"ran out of registers");
713 MIBLO = buildMI(MBB, MBBI, OpLo)
718 buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstLoReg).addReg(TmpReg);
720 MIBHI = buildMI(MBB, MBBI, OpHi)
725 buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
727 MIBLO = buildMI(MBB, MBBI, OpLo)
732 MIBHI = buildMI(MBB, MBBI, OpHi)
746 bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(Block &
MBB, BlockIt MBBI) {
751 bool AVRExpandPseudo::expand<AVR::LPMWRdZPi>(Block &
MBB, BlockIt MBBI) {
755 template<
typename Func>
756 bool AVRExpandPseudo::expandAtomic(Block &MBB, BlockIt MBBI,
Func f) {
761 buildMI(MBB, MBBI, AVR::INRdA)
766 buildMI(MBB, MBBI, AVR::BCLRs).addImm(7);
771 buildMI(MBB, MBBI, AVR::OUTARr)
773 .addReg(SCRATCH_REGISTER);
779 template<
typename Func>
780 bool AVRExpandPseudo::expandAtomicBinaryOp(
unsigned Opcode,
795 bool AVRExpandPseudo::expandAtomicBinaryOp(
unsigned Opcode,
798 return expandAtomicBinaryOp(Opcode, MBB, MBBI, [](
MachineInstr &
MI) {});
801 bool AVRExpandPseudo::expandAtomicArithmeticOp(
unsigned Width,
802 unsigned ArithOpcode,
809 unsigned LoadOpcode = (Width == 8) ? AVR::LDRdPtr : AVR::LDWRdPtr;
810 unsigned StoreOpcode = (Width == 8) ? AVR::STPtrRr : AVR::STWPtrRr;
813 buildMI(MBB, MBBI, LoadOpcode).addOperand(Op1).addOperand(Op2);
816 buildMI(MBB, MBBI, ArithOpcode)
817 .addOperand(Op1).addOperand(Op1)
821 buildMI(MBB, MBBI, StoreOpcode).addOperand(Op2).addOperand(Op1);
826 bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(Block &
MBB, BlockIt MBBI) {
827 return expandAtomicBinaryOp(AVR::LDRdPtr, MBB, MBBI);
831 bool AVRExpandPseudo::expand<AVR::AtomicLoad16>(Block &
MBB, BlockIt MBBI) {
832 return expandAtomicBinaryOp(AVR::LDWRdPtr, MBB, MBBI);
836 bool AVRExpandPseudo::expand<AVR::AtomicStore8>(Block &
MBB, BlockIt MBBI) {
837 return expandAtomicBinaryOp(AVR::STPtrRr, MBB, MBBI);
841 bool AVRExpandPseudo::expand<AVR::AtomicStore16>(Block &
MBB, BlockIt MBBI) {
842 return expandAtomicBinaryOp(AVR::STWPtrRr, MBB, MBBI);
846 bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd8>(Block &
MBB, BlockIt MBBI) {
847 return expandAtomicArithmeticOp(8, AVR::ADDRdRr, MBB, MBBI);
851 bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd16>(Block &
MBB, BlockIt MBBI) {
852 return expandAtomicArithmeticOp(16, AVR::ADDWRdRr, MBB, MBBI);
856 bool AVRExpandPseudo::expand<AVR::AtomicLoadSub8>(Block &
MBB, BlockIt MBBI) {
857 return expandAtomicArithmeticOp(8, AVR::SUBRdRr, MBB, MBBI);
861 bool AVRExpandPseudo::expand<AVR::AtomicLoadSub16>(Block &
MBB, BlockIt MBBI) {
862 return expandAtomicArithmeticOp(16, AVR::SUBWRdRr, MBB, MBBI);
866 bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd8>(Block &
MBB, BlockIt MBBI) {
867 return expandAtomicArithmeticOp(8, AVR::ANDRdRr, MBB, MBBI);
871 bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd16>(Block &
MBB, BlockIt MBBI) {
872 return expandAtomicArithmeticOp(16, AVR::ANDWRdRr, MBB, MBBI);
876 bool AVRExpandPseudo::expand<AVR::AtomicLoadOr8>(Block &
MBB, BlockIt MBBI) {
877 return expandAtomicArithmeticOp(8, AVR::ORRdRr, MBB, MBBI);
881 bool AVRExpandPseudo::expand<AVR::AtomicLoadOr16>(Block &
MBB, BlockIt MBBI) {
882 return expandAtomicArithmeticOp(16, AVR::ORWRdRr, MBB, MBBI);
886 bool AVRExpandPseudo::expand<AVR::AtomicLoadXor8>(Block &
MBB, BlockIt MBBI) {
887 return expandAtomicArithmeticOp(8, AVR::EORRdRr, MBB, MBBI);
891 bool AVRExpandPseudo::expand<AVR::AtomicLoadXor16>(Block &
MBB, BlockIt MBBI) {
892 return expandAtomicArithmeticOp(16, AVR::EORWRdRr, MBB, MBBI);
896 bool AVRExpandPseudo::expand<AVR::AtomicFence>(Block &
MBB, BlockIt MBBI) {
898 MBBI->eraseFromParent();
903 bool AVRExpandPseudo::expand<AVR::STSWKRr>(Block &
MBB, BlockIt MBBI) {
905 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
910 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
914 auto MIBHI = buildMI(MBB, MBBI, OpHi);
915 auto MIBLO = buildMI(MBB, MBBI, OpLo);
923 MIBLO.addGlobalAddress(GV, Offs, TF);
924 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
931 MIBHI.addImm(Imm + 1);
949 bool AVRExpandPseudo::expand<AVR::STWPtrRr>(Block &
MBB, BlockIt MBBI) {
951 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
957 OpHi = AVR::STDPtrQRr;
958 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
961 auto MIBLO = buildMI(MBB, MBBI, OpLo)
965 auto MIBHI = buildMI(MBB, MBBI, OpHi)
978 bool AVRExpandPseudo::expand<AVR::STWPtrPiRr>(Block &
MBB, BlockIt MBBI) {
980 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
986 OpLo = AVR::STPtrPiRr;
987 OpHi = AVR::STPtrPiRr;
988 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
990 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
992 auto MIBLO = buildMI(MBB, MBBI, OpLo)
998 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1012 bool AVRExpandPseudo::expand<AVR::STWPtrPdRr>(Block &
MBB, BlockIt MBBI) {
1014 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1020 OpLo = AVR::STPtrPdRr;
1021 OpHi = AVR::STPtrPdRr;
1022 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1024 assert(DstReg != SrcReg &&
"SrcReg and DstReg cannot be the same");
1026 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1032 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1046 bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(Block &
MBB, BlockIt MBBI) {
1048 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1054 OpLo = AVR::STDPtrQRr;
1055 OpHi = AVR::STDPtrQRr;
1056 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1058 assert(Imm <= 63 &&
"Offset is out of range");
1060 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1065 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1078 bool AVRExpandPseudo::expand<AVR::INWRdA>(Block &
MBB, BlockIt MBBI) {
1080 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1086 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1088 assert(Imm <= 63 &&
"Address is out of range");
1090 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1094 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1106 bool AVRExpandPseudo::expand<AVR::OUTWARr>(Block &
MBB, BlockIt MBBI) {
1108 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1114 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1116 assert(Imm <= 63 &&
"Address is out of range");
1119 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1123 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1135 bool AVRExpandPseudo::expand<AVR::PUSHWRr>(Block &
MBB, BlockIt MBBI) {
1137 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1143 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1146 buildMI(MBB, MBBI, OpLo)
1151 buildMI(MBB, MBBI, OpHi)
1160 bool AVRExpandPseudo::expand<AVR::POPWRd>(Block &
MBB, BlockIt MBBI) {
1162 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1167 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1169 buildMI(MBB, MBBI, OpHi, DstHiReg).setMIFlags(Flags);
1170 buildMI(MBB, MBBI, OpLo, DstLoReg).setMIFlags(Flags);
1177 bool AVRExpandPseudo::expand<AVR::LSLWRd>(Block &
MBB, BlockIt MBBI) {
1179 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1186 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1189 buildMI(MBB, MBBI, OpLo)
1193 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1198 MIBHI->getOperand(2).setIsDead();
1201 MIBHI->getOperand(3).setIsKill();
1208 bool AVRExpandPseudo::expand<AVR::LSRWRd>(Block &
MBB, BlockIt MBBI) {
1210 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1217 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1220 buildMI(MBB, MBBI, OpHi)
1224 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1229 MIBLO->getOperand(2).setIsDead();
1232 MIBLO->getOperand(3).setIsKill();
1239 bool AVRExpandPseudo::expand<AVR::RORWRd>(Block &
MBB, BlockIt MBBI) {
1245 bool AVRExpandPseudo::expand<AVR::ROLWRd>(Block &
MBB, BlockIt MBBI) {
1251 bool AVRExpandPseudo::expand<AVR::ASRWRd>(Block &
MBB, BlockIt MBBI) {
1253 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1260 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1263 buildMI(MBB, MBBI, OpHi)
1267 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1272 MIBLO->getOperand(2).setIsDead();
1275 MIBLO->getOperand(3).setIsKill();
1281 template <>
bool AVRExpandPseudo::expand<AVR::SEXT>(Block &
MBB, BlockIt MBBI) {
1283 unsigned DstLoReg, DstHiReg;
1302 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1304 if (SrcReg != DstLoReg) {
1305 auto MOV = buildMI(MBB, MBBI, AVR::MOVRdRr)
1309 if (SrcReg == DstHiReg) {
1310 MOV->getOperand(1).setIsKill();
1314 if (SrcReg != DstHiReg) {
1315 buildMI(MBB, MBBI, AVR::MOVRdRr)
1320 buildMI(MBB, MBBI, AVR::LSLRd)
1324 auto SBC = buildMI(MBB, MBBI, AVR::SBCRdRr)
1330 SBC->getOperand(3).setIsDead();
1333 SBC->getOperand(4).setIsKill();
1339 template <>
bool AVRExpandPseudo::expand<AVR::ZEXT>(Block &
MBB, BlockIt MBBI) {
1341 unsigned DstLoReg, DstHiReg;
1355 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1357 if (SrcReg != DstLoReg) {
1358 buildMI(MBB, MBBI, AVR::MOVRdRr)
1363 auto EOR = buildMI(MBB, MBBI, AVR::EORRdRr)
1369 EOR->getOperand(3).setIsDead();
1376 bool AVRExpandPseudo::expand<AVR::SPREAD>(Block &
MBB, BlockIt MBBI) {
1378 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1384 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1387 buildMI(MBB, MBBI, OpLo)
1393 buildMI(MBB, MBBI, OpHi)
1403 bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &
MBB, BlockIt MBBI) {
1405 unsigned SrcLoReg, SrcHiReg;
1409 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1411 buildMI(MBB, MBBI, AVR::INRdA)
1416 buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
1418 buildMI(MBB, MBBI, AVR::OUTARr)
1423 buildMI(MBB, MBBI, AVR::OUTARr)
1428 buildMI(MBB, MBBI, AVR::OUTARr)
1437 bool AVRExpandPseudo::expandMI(Block &MBB, BlockIt MBBI) {
1439 int Opcode = MBBI->getOpcode();
1441 #define EXPAND(Op) \
1443 return expand<Op>(MBB, MI)
1469 EXPAND(AVR::AtomicLoad8);
1470 EXPAND(AVR::AtomicLoad16);
1471 EXPAND(AVR::AtomicStore8);
1472 EXPAND(AVR::AtomicStore16);
1473 EXPAND(AVR::AtomicLoadAdd8);
1474 EXPAND(AVR::AtomicLoadAdd16);
1475 EXPAND(AVR::AtomicLoadSub8);
1476 EXPAND(AVR::AtomicLoadSub16);
1477 EXPAND(AVR::AtomicLoadAnd8);
1478 EXPAND(AVR::AtomicLoadAnd16);
1479 EXPAND(AVR::AtomicLoadOr8);
1480 EXPAND(AVR::AtomicLoadOr16);
1481 EXPAND(AVR::AtomicLoadXor8);
1482 EXPAND(AVR::AtomicLoadXor16);
1483 EXPAND(AVR::AtomicFence);
const AVRInstrInfo * getInstrInfo() const override
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
const GlobalValue * getGlobal() const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
iterator_range< mop_iterator > operands()
Utilities relating to AVR registers.
The address of a basic block.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
struct fuzzer::@269 Flags
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineFunctionProperties & getProperties() const
Get the function properties.
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)
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
TargetInstrInfo - Interface to description of machine instruction set.
unsigned getDeadRegState(bool B)
mmo_iterator memoperands_end() const
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.
unsigned getTargetFlags() const
This file declares the machine register scavenger class.
const MachineOperand & getOperand(unsigned i) 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.
int64_t getOffset() const
Return the offset from the symbol in this operand.
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.
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
MachineOperand class - Representation of each machine instruction operand.
A specific AVR target MCU.
FunctionPass * createAVRExpandPseudoPass()
On a symbol operand, this represents the lo part.
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.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
INITIALIZE_PASS(AVRExpandPseudo,"avr-expand-pseudo", AVR_EXPAND_PSEUDO_NAME, false, false) namespace llvm
void enterBasicBlock(MachineBasicBlock &MBB)
Start tracking liveness from the begin of basic block MBB.
uint8_t getFlags() const
Return the MI flags bitvector.
unsigned getReg() const
getReg - Returns the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const AVRRegisterInfo * getRegisterInfo() const override
StringRef - Represent a constant reference to a string, i.e.
const BlockAddress * getBlockAddress() const
#define AVR_EXPAND_PSEUDO_NAME
void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd)
Assign this MachineInstr's memory reference descriptor list.
void initializeAVRExpandPseudoPass(PassRegistry &)
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.