LCOV - code coverage report
Current view: top level - lib/Target/AVR - AVRExpandPseudoInsts.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 685 730 93.8 %
Date: 2018-10-20 13:21:21 Functions: 52 60 86.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- AVRExpandPseudoInsts.cpp - Expand pseudo instructions -------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file contains a pass that expands pseudo instructions into target
      11             : // instructions. This pass should be run after register allocation but before
      12             : // the post-regalloc scheduling pass.
      13             : //
      14             : //===----------------------------------------------------------------------===//
      15             : 
      16             : #include "AVR.h"
      17             : #include "AVRInstrInfo.h"
      18             : #include "AVRTargetMachine.h"
      19             : #include "MCTargetDesc/AVRMCTargetDesc.h"
      20             : 
      21             : #include "llvm/CodeGen/MachineFunctionPass.h"
      22             : #include "llvm/CodeGen/MachineInstrBuilder.h"
      23             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      24             : #include "llvm/CodeGen/RegisterScavenging.h"
      25             : #include "llvm/CodeGen/TargetRegisterInfo.h"
      26             : 
      27             : using namespace llvm;
      28             : 
      29             : #define AVR_EXPAND_PSEUDO_NAME "AVR pseudo instruction expansion pass"
      30             : 
      31             : namespace {
      32             : 
      33             : /// Expands "placeholder" instructions marked as pseudo into
      34             : /// actual AVR instructions.
      35             : class AVRExpandPseudo : public MachineFunctionPass {
      36             : public:
      37             :   static char ID;
      38             : 
      39         115 :   AVRExpandPseudo() : MachineFunctionPass(ID) {
      40         115 :     initializeAVRExpandPseudoPass(*PassRegistry::getPassRegistry());
      41         115 :   }
      42             : 
      43             :   bool runOnMachineFunction(MachineFunction &MF) override;
      44             : 
      45         115 :   StringRef getPassName() const override { return AVR_EXPAND_PSEUDO_NAME; }
      46             : 
      47             : private:
      48             :   typedef MachineBasicBlock Block;
      49             :   typedef Block::iterator BlockIt;
      50             : 
      51             :   const AVRRegisterInfo *TRI;
      52             :   const TargetInstrInfo *TII;
      53             : 
      54             :   /// The register to be used for temporary storage.
      55             :   const unsigned SCRATCH_REGISTER = AVR::R0;
      56             :   /// The IO address of the status register.
      57             :   const unsigned SREG_ADDR = 0x3f;
      58             : 
      59             :   bool expandMBB(Block &MBB);
      60             :   bool expandMI(Block &MBB, BlockIt MBBI);
      61             :   template <unsigned OP> bool expand(Block &MBB, BlockIt MBBI);
      62             : 
      63           0 :   MachineInstrBuilder buildMI(Block &MBB, BlockIt MBBI, unsigned Opcode) {
      64        3037 :     return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opcode));
      65             :   }
      66             : 
      67           0 :   MachineInstrBuilder buildMI(Block &MBB, BlockIt MBBI, unsigned Opcode,
      68             :                               unsigned DstReg) {
      69          30 :     return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opcode), DstReg);
      70             :   }
      71             : 
      72             :   MachineRegisterInfo &getRegInfo(Block &MBB) { return MBB.getParent()->getRegInfo(); }
      73             : 
      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;
      78             : 
      79             :   template<typename Func>
      80             :   bool expandAtomic(Block &MBB, BlockIt MBBI, Func f);
      81             : 
      82             :   template<typename Func>
      83             :   bool expandAtomicBinaryOp(unsigned Opcode, Block &MBB, BlockIt MBBI, Func f);
      84             : 
      85             :   bool expandAtomicBinaryOp(unsigned Opcode, Block &MBB, BlockIt MBBI);
      86             : 
      87             :   bool expandAtomicArithmeticOp(unsigned MemOpcode,
      88             :                                 unsigned ArithOpcode,
      89             :                                 Block &MBB,
      90             :                                 BlockIt MBBI);
      91             : 
      92             :   /// Scavenges a free GPR8 register for use.
      93             :   unsigned scavengeGPR8(MachineInstr &MI);
      94             : };
      95             : 
      96             : char AVRExpandPseudo::ID = 0;
      97             : 
      98         901 : bool AVRExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
      99             :   bool Modified = false;
     100             : 
     101             :   BlockIt MBBI = MBB.begin(), E = MBB.end();
     102       13352 :   while (MBBI != E) {
     103       12451 :     BlockIt NMBBI = std::next(MBBI);
     104       12451 :     Modified |= expandMI(MBB, MBBI);
     105             :     MBBI = NMBBI;
     106             :   }
     107             : 
     108         901 :   return Modified;
     109             : }
     110             : 
     111         338 : bool AVRExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
     112             :   bool Modified = false;
     113             : 
     114         338 :   const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
     115         338 :   TRI = STI.getRegisterInfo();
     116         338 :   TII = STI.getInstrInfo();
     117             : 
     118             :   // We need to track liveness in order to use register scavenging.
     119             :   MF.getProperties().set(MachineFunctionProperties::Property::TracksLiveness);
     120             : 
     121         909 :   for (Block &MBB : MF) {
     122             :     bool ContinueExpanding = true;
     123             :     unsigned ExpandCount = 0;
     124             : 
     125             :     // Continue expanding the block until all pseudos are expanded.
     126         901 :     do {
     127             :       assert(ExpandCount < 10 && "pseudo expand limit reached");
     128             : 
     129         901 :       bool BlockModified = expandMBB(MBB);
     130         901 :       Modified |= BlockModified;
     131             :       ExpandCount++;
     132             : 
     133             :       ContinueExpanding = BlockModified;
     134             :     } while (ContinueExpanding);
     135             :   }
     136             : 
     137         338 :   return Modified;
     138             : }
     139             : 
     140          38 : bool AVRExpandPseudo::
     141             : expandArith(unsigned OpLo, unsigned OpHi, Block &MBB, BlockIt MBBI) {
     142             :   MachineInstr &MI = *MBBI;
     143             :   unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
     144          38 :   unsigned DstReg = MI.getOperand(0).getReg();
     145          38 :   unsigned SrcReg = MI.getOperand(2).getReg();
     146             :   bool DstIsDead = MI.getOperand(0).isDead();
     147             :   bool DstIsKill = MI.getOperand(1).isKill();
     148             :   bool SrcIsKill = MI.getOperand(2).isKill();
     149             :   bool ImpIsDead = MI.getOperand(3).isDead();
     150          38 :   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
     151          38 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
     152             : 
     153          38 :   buildMI(MBB, MBBI, OpLo)
     154          76 :     .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
     155          38 :     .addReg(DstLoReg, getKillRegState(DstIsKill))
     156          76 :     .addReg(SrcLoReg, getKillRegState(SrcIsKill));
     157             : 
     158          38 :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
     159          38 :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
     160          38 :     .addReg(DstHiReg, getKillRegState(DstIsKill))
     161          38 :     .addReg(SrcHiReg, getKillRegState(SrcIsKill));
     162             : 
     163          38 :   if (ImpIsDead)
     164          19 :     MIBHI->getOperand(3).setIsDead();
     165             : 
     166             :   // SREG is always implicitly killed
     167          38 :   MIBHI->getOperand(4).setIsKill();
     168             : 
     169          38 :   MI.eraseFromParent();
     170          38 :   return true;
     171             : }
     172             : 
     173          60 : bool AVRExpandPseudo::
     174             : expandLogic(unsigned Op, Block &MBB, BlockIt MBBI) {
     175             :   MachineInstr &MI = *MBBI;
     176             :   unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
     177          60 :   unsigned DstReg = MI.getOperand(0).getReg();
     178          60 :   unsigned SrcReg = MI.getOperand(2).getReg();
     179             :   bool DstIsDead = MI.getOperand(0).isDead();
     180             :   bool DstIsKill = MI.getOperand(1).isKill();
     181             :   bool SrcIsKill = MI.getOperand(2).isKill();
     182             :   bool ImpIsDead = MI.getOperand(3).isDead();
     183          60 :   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
     184          60 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
     185             : 
     186          60 :   auto MIBLO = buildMI(MBB, MBBI, Op)
     187         120 :     .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
     188          60 :     .addReg(DstLoReg, getKillRegState(DstIsKill))
     189         120 :     .addReg(SrcLoReg, getKillRegState(SrcIsKill));
     190             : 
     191             :   // SREG is always implicitly dead
     192          60 :   MIBLO->getOperand(3).setIsDead();
     193             : 
     194          60 :   auto MIBHI = buildMI(MBB, MBBI, Op)
     195          60 :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
     196          60 :     .addReg(DstHiReg, getKillRegState(DstIsKill))
     197          60 :     .addReg(SrcHiReg, getKillRegState(SrcIsKill));
     198             : 
     199          60 :   if (ImpIsDead)
     200          54 :     MIBHI->getOperand(3).setIsDead();
     201             : 
     202          60 :   MI.eraseFromParent();
     203          60 :   return true;
     204             : }
     205             : 
     206           0 : bool AVRExpandPseudo::
     207             :   isLogicImmOpRedundant(unsigned Op, unsigned ImmVal) const {
     208             : 
     209             :   // ANDI Rd, 0xff is redundant.
     210          70 :   if (Op == AVR::ANDIRdK && ImmVal == 0xff)
     211           0 :     return true;
     212             : 
     213             :   // ORI Rd, 0x0 is redundant.
     214          67 :   if (Op == AVR::ORIRdK && ImmVal == 0x0)
     215           0 :     return true;
     216             : 
     217             :   return false;
     218             : }
     219             : 
     220          36 : bool AVRExpandPseudo::
     221             : expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI) {
     222             :   MachineInstr &MI = *MBBI;
     223             :   unsigned DstLoReg, DstHiReg;
     224          36 :   unsigned DstReg = MI.getOperand(0).getReg();
     225             :   bool DstIsDead = MI.getOperand(0).isDead();
     226             :   bool SrcIsKill = MI.getOperand(1).isKill();
     227             :   bool ImpIsDead = MI.getOperand(3).isDead();
     228          36 :   unsigned Imm = MI.getOperand(2).getImm();
     229          36 :   unsigned Lo8 = Imm & 0xff;
     230          36 :   unsigned Hi8 = (Imm >> 8) & 0xff;
     231          36 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
     232             : 
     233             :   if (!isLogicImmOpRedundant(Op, Lo8)) {
     234          33 :     auto MIBLO = buildMI(MBB, MBBI, Op)
     235          66 :       .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
     236          33 :       .addReg(DstLoReg, getKillRegState(SrcIsKill))
     237          33 :       .addImm(Lo8);
     238             : 
     239             :     // SREG is always implicitly dead
     240          33 :     MIBLO->getOperand(3).setIsDead();
     241             :   }
     242             : 
     243             :   if (!isLogicImmOpRedundant(Op, Hi8)) {
     244          30 :     auto MIBHI = buildMI(MBB, MBBI, Op)
     245          60 :       .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
     246          30 :       .addReg(DstHiReg, getKillRegState(SrcIsKill))
     247          30 :       .addImm(Hi8);
     248             : 
     249          30 :     if (ImpIsDead)
     250          28 :       MIBHI->getOperand(3).setIsDead();
     251             :   }
     252             : 
     253          36 :   MI.eraseFromParent();
     254          36 :   return true;
     255             : }
     256             : 
     257             : template <>
     258             : bool AVRExpandPseudo::expand<AVR::ADDWRdRr>(Block &MBB, BlockIt MBBI) {
     259          13 :   return expandArith(AVR::ADDRdRr, AVR::ADCRdRr, MBB, MBBI);
     260             : }
     261             : 
     262             : template <>
     263             : bool AVRExpandPseudo::expand<AVR::ADCWRdRr>(Block &MBB, BlockIt MBBI) {
     264           9 :   return expandArith(AVR::ADCRdRr, AVR::ADCRdRr, MBB, MBBI);
     265             : }
     266             : 
     267             : template <>
     268             : bool AVRExpandPseudo::expand<AVR::SUBWRdRr>(Block &MBB, BlockIt MBBI) {
     269          11 :   return expandArith(AVR::SUBRdRr, AVR::SBCRdRr, MBB, MBBI);
     270             : }
     271             : 
     272             : template <>
     273          37 : bool AVRExpandPseudo::expand<AVR::SUBIWRdK>(Block &MBB, BlockIt MBBI) {
     274             :   MachineInstr &MI = *MBBI;
     275             :   unsigned DstLoReg, DstHiReg;
     276          37 :   unsigned DstReg = MI.getOperand(0).getReg();
     277             :   bool DstIsDead = MI.getOperand(0).isDead();
     278             :   bool SrcIsKill = MI.getOperand(1).isKill();
     279             :   bool ImpIsDead = MI.getOperand(3).isDead();
     280          37 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
     281             : 
     282          37 :   auto MIBLO = buildMI(MBB, MBBI, AVR::SUBIRdK)
     283          74 :     .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
     284          74 :     .addReg(DstLoReg, getKillRegState(SrcIsKill));
     285             : 
     286          37 :   auto MIBHI = buildMI(MBB, MBBI, AVR::SBCIRdK)
     287          37 :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
     288          37 :     .addReg(DstHiReg, getKillRegState(SrcIsKill));
     289             : 
     290          74 :   switch (MI.getOperand(2).getType()) {
     291           1 :   case MachineOperand::MO_GlobalAddress: {
     292           1 :     const GlobalValue *GV = MI.getOperand(2).getGlobal();
     293           1 :     int64_t Offs = MI.getOperand(2).getOffset();
     294             :     unsigned TF = MI.getOperand(2).getTargetFlags();
     295           1 :     MIBLO.addGlobalAddress(GV, Offs, TF | AVRII::MO_NEG | AVRII::MO_LO);
     296           1 :     MIBHI.addGlobalAddress(GV, Offs, TF | AVRII::MO_NEG | AVRII::MO_HI);
     297             :     break;
     298             :   }
     299          36 :   case MachineOperand::MO_Immediate: {
     300          36 :     unsigned Imm = MI.getOperand(2).getImm();
     301          36 :     MIBLO.addImm(Imm & 0xff);
     302          36 :     MIBHI.addImm((Imm >> 8) & 0xff);
     303             :     break;
     304             :   }
     305           0 :   default:
     306           0 :     llvm_unreachable("Unknown operand type!");
     307             :   }
     308             : 
     309          37 :   if (ImpIsDead)
     310          27 :     MIBHI->getOperand(3).setIsDead();
     311             : 
     312             :   // SREG is always implicitly killed
     313          37 :   MIBHI->getOperand(4).setIsKill();
     314             : 
     315          37 :   MI.eraseFromParent();
     316          37 :   return true;
     317             : }
     318             : 
     319             : template <>
     320             : bool AVRExpandPseudo::expand<AVR::SBCWRdRr>(Block &MBB, BlockIt MBBI) {
     321           5 :   return expandArith(AVR::SBCRdRr, AVR::SBCRdRr, MBB, MBBI);
     322             : }
     323             : 
     324             : template <>
     325          17 : bool AVRExpandPseudo::expand<AVR::SBCIWRdK>(Block &MBB, BlockIt MBBI) {
     326             :   MachineInstr &MI = *MBBI;
     327             :   unsigned OpLo, OpHi, DstLoReg, DstHiReg;
     328          17 :   unsigned DstReg = MI.getOperand(0).getReg();
     329             :   bool DstIsDead = MI.getOperand(0).isDead();
     330             :   bool SrcIsKill = MI.getOperand(1).isKill();
     331             :   bool ImpIsDead = MI.getOperand(3).isDead();
     332          17 :   unsigned Imm = MI.getOperand(2).getImm();
     333          17 :   unsigned Lo8 = Imm & 0xff;
     334          17 :   unsigned Hi8 = (Imm >> 8) & 0xff;
     335             :   OpLo = AVR::SBCIRdK;
     336             :   OpHi = AVR::SBCIRdK;
     337          17 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
     338             : 
     339          17 :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
     340          34 :     .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
     341          17 :     .addReg(DstLoReg, getKillRegState(SrcIsKill))
     342          17 :     .addImm(Lo8);
     343             : 
     344             :   // SREG is always implicitly killed
     345          17 :   MIBLO->getOperand(4).setIsKill();
     346             : 
     347          17 :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
     348          17 :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
     349          17 :     .addReg(DstHiReg, getKillRegState(SrcIsKill))
     350          17 :     .addImm(Hi8);
     351             : 
     352          17 :   if (ImpIsDead)
     353           9 :     MIBHI->getOperand(3).setIsDead();
     354             : 
     355             :   // SREG is always implicitly killed
     356          17 :   MIBHI->getOperand(4).setIsKill();
     357             : 
     358          17 :   MI.eraseFromParent();
     359          17 :   return true;
     360             : }
     361             : 
     362             : template <>
     363             : bool AVRExpandPseudo::expand<AVR::ANDWRdRr>(Block &MBB, BlockIt MBBI) {
     364           9 :   return expandLogic(AVR::ANDRdRr, MBB, MBBI);
     365             : }
     366             : 
     367             : template <>
     368             : bool AVRExpandPseudo::expand<AVR::ANDIWRdK>(Block &MBB, BlockIt MBBI) {
     369          22 :   return expandLogicImm(AVR::ANDIRdK, MBB, MBBI);
     370             : }
     371             : 
     372             : template <>
     373             : bool AVRExpandPseudo::expand<AVR::ORWRdRr>(Block &MBB, BlockIt MBBI) {
     374          29 :   return expandLogic(AVR::ORRdRr, MBB, MBBI);
     375             : }
     376             : 
     377             : template <>
     378             : bool AVRExpandPseudo::expand<AVR::ORIWRdK>(Block &MBB, BlockIt MBBI) {
     379          14 :   return expandLogicImm(AVR::ORIRdK, MBB, MBBI);
     380             : }
     381             : 
     382             : template <>
     383             : bool AVRExpandPseudo::expand<AVR::EORWRdRr>(Block &MBB, BlockIt MBBI) {
     384          22 :   return expandLogic(AVR::EORRdRr, MBB, MBBI);
     385             : }
     386             : 
     387             : template <>
     388           8 : bool AVRExpandPseudo::expand<AVR::COMWRd>(Block &MBB, BlockIt MBBI) {
     389             :   MachineInstr &MI = *MBBI;
     390             :   unsigned OpLo, OpHi, DstLoReg, DstHiReg;
     391           8 :   unsigned DstReg = MI.getOperand(0).getReg();
     392             :   bool DstIsDead = MI.getOperand(0).isDead();
     393             :   bool DstIsKill = MI.getOperand(1).isKill();
     394             :   bool ImpIsDead = MI.getOperand(2).isDead();
     395             :   OpLo = AVR::COMRd;
     396             :   OpHi = AVR::COMRd;
     397           8 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
     398             : 
     399           8 :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
     400          16 :     .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
     401          16 :     .addReg(DstLoReg, getKillRegState(DstIsKill));
     402             : 
     403             :   // SREG is always implicitly dead
     404           8 :   MIBLO->getOperand(2).setIsDead();
     405             : 
     406           8 :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
     407           8 :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
     408           8 :     .addReg(DstHiReg, getKillRegState(DstIsKill));
     409             : 
     410           8 :   if (ImpIsDead)
     411           7 :     MIBHI->getOperand(2).setIsDead();
     412             : 
     413           8 :   MI.eraseFromParent();
     414           8 :   return true;
     415             : }
     416             : 
     417             : template <>
     418          45 : bool AVRExpandPseudo::expand<AVR::CPWRdRr>(Block &MBB, BlockIt MBBI) {
     419             :   MachineInstr &MI = *MBBI;
     420             :   unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
     421          45 :   unsigned DstReg = MI.getOperand(0).getReg();
     422          45 :   unsigned SrcReg = MI.getOperand(1).getReg();
     423             :   bool DstIsKill = MI.getOperand(0).isKill();
     424             :   bool SrcIsKill = MI.getOperand(1).isKill();
     425             :   bool ImpIsDead = MI.getOperand(2).isDead();
     426             :   OpLo = AVR::CPRdRr;
     427             :   OpHi = AVR::CPCRdRr;
     428          45 :   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
     429          45 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
     430             : 
     431             :   // Low part
     432          45 :   buildMI(MBB, MBBI, OpLo)
     433          45 :     .addReg(DstLoReg, getKillRegState(DstIsKill))
     434          90 :     .addReg(SrcLoReg, getKillRegState(SrcIsKill));
     435             : 
     436          45 :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
     437          45 :     .addReg(DstHiReg, getKillRegState(DstIsKill))
     438          45 :     .addReg(SrcHiReg, getKillRegState(SrcIsKill));
     439             : 
     440          45 :   if (ImpIsDead)
     441           0 :     MIBHI->getOperand(2).setIsDead();
     442             : 
     443             :   // SREG is always implicitly killed
     444          45 :   MIBHI->getOperand(3).setIsKill();
     445             : 
     446          45 :   MI.eraseFromParent();
     447          45 :   return true;
     448             : }
     449             : 
     450             : template <>
     451          36 : bool AVRExpandPseudo::expand<AVR::CPCWRdRr>(Block &MBB, BlockIt MBBI) {
     452             :   MachineInstr &MI = *MBBI;
     453             :   unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
     454          36 :   unsigned DstReg = MI.getOperand(0).getReg();
     455          36 :   unsigned SrcReg = MI.getOperand(1).getReg();
     456             :   bool DstIsKill = MI.getOperand(0).isKill();
     457             :   bool SrcIsKill = MI.getOperand(1).isKill();
     458             :   bool ImpIsDead = MI.getOperand(2).isDead();
     459             :   OpLo = AVR::CPCRdRr;
     460             :   OpHi = AVR::CPCRdRr;
     461          36 :   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
     462          36 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
     463             : 
     464          36 :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
     465          36 :     .addReg(DstLoReg, getKillRegState(DstIsKill))
     466          72 :     .addReg(SrcLoReg, getKillRegState(SrcIsKill));
     467             : 
     468             :   // SREG is always implicitly killed
     469          36 :   MIBLO->getOperand(3).setIsKill();
     470             : 
     471          36 :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
     472          36 :     .addReg(DstHiReg, getKillRegState(DstIsKill))
     473          36 :     .addReg(SrcHiReg, getKillRegState(SrcIsKill));
     474             : 
     475          36 :   if (ImpIsDead)
     476           0 :     MIBHI->getOperand(2).setIsDead();
     477             : 
     478             :   // SREG is always implicitly killed
     479          36 :   MIBHI->getOperand(3).setIsKill();
     480             : 
     481          36 :   MI.eraseFromParent();
     482          36 :   return true;
     483             : }
     484             : 
     485             : template <>
     486         249 : bool AVRExpandPseudo::expand<AVR::LDIWRdK>(Block &MBB, BlockIt MBBI) {
     487             :   MachineInstr &MI = *MBBI;
     488             :   unsigned OpLo, OpHi, DstLoReg, DstHiReg;
     489         249 :   unsigned DstReg = MI.getOperand(0).getReg();
     490             :   bool DstIsDead = MI.getOperand(0).isDead();
     491             :   OpLo = AVR::LDIRdK;
     492             :   OpHi = AVR::LDIRdK;
     493         249 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
     494             : 
     495         249 :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
     496         249 :     .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead));
     497             : 
     498         249 :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
     499         249 :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead));
     500             : 
     501         498 :   switch (MI.getOperand(1).getType()) {
     502           4 :   case MachineOperand::MO_GlobalAddress: {
     503           4 :     const GlobalValue *GV = MI.getOperand(1).getGlobal();
     504           4 :     int64_t Offs = MI.getOperand(1).getOffset();
     505             :     unsigned TF = MI.getOperand(1).getTargetFlags();
     506             : 
     507           4 :     MIBLO.addGlobalAddress(GV, Offs, TF | AVRII::MO_LO);
     508           4 :     MIBHI.addGlobalAddress(GV, Offs, TF | AVRII::MO_HI);
     509             :     break;
     510             :   }
     511           0 :   case MachineOperand::MO_BlockAddress: {
     512           0 :     const BlockAddress *BA = MI.getOperand(1).getBlockAddress();
     513             :     unsigned TF = MI.getOperand(1).getTargetFlags();
     514             : 
     515           0 :     MIBLO.add(MachineOperand::CreateBA(BA, TF | AVRII::MO_LO));
     516           0 :     MIBHI.add(MachineOperand::CreateBA(BA, TF | AVRII::MO_HI));
     517           0 :     break;
     518             :   }
     519         245 :   case MachineOperand::MO_Immediate: {
     520         245 :     unsigned Imm = MI.getOperand(1).getImm();
     521             : 
     522         245 :     MIBLO.addImm(Imm & 0xff);
     523         245 :     MIBHI.addImm((Imm >> 8) & 0xff);
     524             :     break;
     525             :   }
     526           0 :   default:
     527           0 :     llvm_unreachable("Unknown operand type!");
     528             :   }
     529             : 
     530         249 :   MI.eraseFromParent();
     531         249 :   return true;
     532             : }
     533             : 
     534             : template <>
     535          33 : bool AVRExpandPseudo::expand<AVR::LDSWRdK>(Block &MBB, BlockIt MBBI) {
     536             :   MachineInstr &MI = *MBBI;
     537             :   unsigned OpLo, OpHi, DstLoReg, DstHiReg;
     538          33 :   unsigned DstReg = MI.getOperand(0).getReg();
     539             :   bool DstIsDead = MI.getOperand(0).isDead();
     540             :   OpLo = AVR::LDSRdK;
     541             :   OpHi = AVR::LDSRdK;
     542          33 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
     543             : 
     544          33 :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
     545          33 :     .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead));
     546             : 
     547          33 :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
     548          33 :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead));
     549             : 
     550          66 :   switch (MI.getOperand(1).getType()) {
     551          21 :   case MachineOperand::MO_GlobalAddress: {
     552          21 :     const GlobalValue *GV = MI.getOperand(1).getGlobal();
     553          21 :     int64_t Offs = MI.getOperand(1).getOffset();
     554             :     unsigned TF = MI.getOperand(1).getTargetFlags();
     555             : 
     556          21 :     MIBLO.addGlobalAddress(GV, Offs, TF);
     557          21 :     MIBHI.addGlobalAddress(GV, Offs + 1, TF);
     558             :     break;
     559             :   }
     560          12 :   case MachineOperand::MO_Immediate: {
     561          12 :     unsigned Imm = MI.getOperand(1).getImm();
     562             : 
     563             :     MIBLO.addImm(Imm);
     564          12 :     MIBHI.addImm(Imm + 1);
     565             :     break;
     566             :   }
     567           0 :   default:
     568           0 :     llvm_unreachable("Unknown operand type!");
     569             :   }
     570             : 
     571          33 :   MIBLO.setMemRefs(MI.memoperands());
     572          33 :   MIBHI.setMemRefs(MI.memoperands());
     573             : 
     574          33 :   MI.eraseFromParent();
     575          33 :   return true;
     576             : }
     577             : 
     578             : template <>
     579          19 : bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) {
     580             :   MachineInstr &MI = *MBBI;
     581             :   unsigned OpLo, OpHi, DstLoReg, DstHiReg;
     582          19 :   unsigned DstReg = MI.getOperand(0).getReg();
     583             :   unsigned TmpReg = 0; // 0 for no temporary register
     584          19 :   unsigned SrcReg = MI.getOperand(1).getReg();
     585             :   bool SrcIsKill = MI.getOperand(1).isKill();
     586             :   OpLo = AVR::LDRdPtrPi;
     587             :   OpHi = AVR::LDRdPtr;
     588          19 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
     589             : 
     590             :   // Use a temporary register if src and dst registers are the same.
     591          19 :   if (DstReg == SrcReg)
     592           1 :     TmpReg = scavengeGPR8(MI);
     593             : 
     594          19 :   unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
     595          19 :   unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
     596             : 
     597             :   // Load low byte.
     598          19 :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
     599          19 :     .addReg(CurDstLoReg, RegState::Define)
     600          19 :     .addReg(SrcReg, RegState::Define)
     601          19 :     .addReg(SrcReg);
     602             : 
     603             :   // Push low byte onto stack if necessary.
     604          19 :   if (TmpReg)
     605           1 :     buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
     606             : 
     607             :   // Load high byte.
     608          19 :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
     609          19 :     .addReg(CurDstHiReg, RegState::Define)
     610          19 :     .addReg(SrcReg, getKillRegState(SrcIsKill));
     611             : 
     612          19 :   if (TmpReg) {
     613             :     // Move the high byte into the final destination.
     614           1 :     buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
     615             : 
     616             :     // Move the low byte from the scratch space into the final destination.
     617           1 :     buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
     618             :   }
     619             : 
     620          19 :   MIBLO.setMemRefs(MI.memoperands());
     621          19 :   MIBHI.setMemRefs(MI.memoperands());
     622             : 
     623          19 :   MI.eraseFromParent();
     624          19 :   return true;
     625             : }
     626             : 
     627             : template <>
     628           7 : bool AVRExpandPseudo::expand<AVR::LDWRdPtrPi>(Block &MBB, BlockIt MBBI) {
     629             :   MachineInstr &MI = *MBBI;
     630             :   unsigned OpLo, OpHi, DstLoReg, DstHiReg;
     631           7 :   unsigned DstReg = MI.getOperand(0).getReg();
     632           7 :   unsigned SrcReg = MI.getOperand(1).getReg();
     633             :   bool DstIsDead = MI.getOperand(0).isDead();
     634             :   bool SrcIsDead = MI.getOperand(1).isKill();
     635             :   OpLo = AVR::LDRdPtrPi;
     636             :   OpHi = AVR::LDRdPtrPi;
     637           7 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
     638             : 
     639             :   assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
     640             : 
     641           7 :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
     642          14 :     .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
     643           7 :     .addReg(SrcReg, RegState::Define)
     644           7 :     .addReg(SrcReg, RegState::Kill);
     645             : 
     646           7 :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
     647           7 :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
     648          14 :     .addReg(SrcReg, RegState::Define | getDeadRegState(SrcIsDead))
     649           7 :     .addReg(SrcReg, RegState::Kill);
     650             : 
     651           7 :   MIBLO.setMemRefs(MI.memoperands());
     652           7 :   MIBHI.setMemRefs(MI.memoperands());
     653             : 
     654           7 :   MI.eraseFromParent();
     655           7 :   return true;
     656             : }
     657             : 
     658             : template <>
     659           2 : bool AVRExpandPseudo::expand<AVR::LDWRdPtrPd>(Block &MBB, BlockIt MBBI) {
     660             :   MachineInstr &MI = *MBBI;
     661             :   unsigned OpLo, OpHi, DstLoReg, DstHiReg;
     662           2 :   unsigned DstReg = MI.getOperand(0).getReg();
     663           2 :   unsigned SrcReg = MI.getOperand(1).getReg();
     664             :   bool DstIsDead = MI.getOperand(0).isDead();
     665             :   bool SrcIsDead = MI.getOperand(1).isKill();
     666             :   OpLo = AVR::LDRdPtrPd;
     667             :   OpHi = AVR::LDRdPtrPd;
     668           2 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
     669             : 
     670             :   assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
     671             : 
     672           2 :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
     673           4 :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
     674           2 :     .addReg(SrcReg, RegState::Define)
     675           2 :     .addReg(SrcReg, RegState::Kill);
     676             : 
     677           2 :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
     678           2 :     .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
     679           4 :     .addReg(SrcReg, RegState::Define | getDeadRegState(SrcIsDead))
     680           2 :     .addReg(SrcReg, RegState::Kill);
     681             : 
     682           2 :   MIBLO.setMemRefs(MI.memoperands());
     683           2 :   MIBHI.setMemRefs(MI.memoperands());
     684             : 
     685           2 :   MI.eraseFromParent();
     686           2 :   return true;
     687             : }
     688             : 
     689             : template <>
     690         113 : bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
     691             :   MachineInstr &MI = *MBBI;
     692             :   unsigned OpLo, OpHi, DstLoReg, DstHiReg;
     693         113 :   unsigned DstReg = MI.getOperand(0).getReg();
     694             :   unsigned TmpReg = 0; // 0 for no temporary register
     695         113 :   unsigned SrcReg = MI.getOperand(1).getReg();
     696         113 :   unsigned Imm = MI.getOperand(2).getImm();
     697             :   bool SrcIsKill = MI.getOperand(1).isKill();
     698             :   OpLo = AVR::LDDRdPtrQ;
     699             :   OpHi = AVR::LDDRdPtrQ;
     700         113 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
     701             : 
     702             :   // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value
     703             :   // allowed for the instruction, 62 is the limit here.
     704             :   assert(Imm <= 62 && "Offset is out of range");
     705             : 
     706             :   // Use a temporary register if src and dst registers are the same.
     707         113 :   if (DstReg == SrcReg)
     708           1 :     TmpReg = scavengeGPR8(MI);
     709             : 
     710         113 :   unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
     711         113 :   unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
     712             : 
     713             :   // Load low byte.
     714         113 :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
     715         113 :     .addReg(CurDstLoReg, RegState::Define)
     716         113 :     .addReg(SrcReg)
     717         113 :     .addImm(Imm);
     718             : 
     719             :   // Push low byte onto stack if necessary.
     720         113 :   if (TmpReg)
     721           1 :     buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
     722             : 
     723             :   // Load high byte.
     724         113 :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
     725         113 :     .addReg(CurDstHiReg, RegState::Define)
     726         113 :     .addReg(SrcReg, getKillRegState(SrcIsKill))
     727         113 :     .addImm(Imm + 1);
     728             : 
     729         113 :   if (TmpReg) {
     730             :     // Move the high byte into the final destination.
     731           1 :     buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
     732             : 
     733             :     // Move the low byte from the scratch space into the final destination.
     734           1 :     buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
     735             :   }
     736             : 
     737         113 :   MIBLO.setMemRefs(MI.memoperands());
     738         113 :   MIBHI.setMemRefs(MI.memoperands());
     739             : 
     740         113 :   MI.eraseFromParent();
     741         113 :   return true;
     742             : }
     743             : 
     744             : template <>
     745           1 : bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(Block &MBB, BlockIt MBBI) {
     746             :   MachineInstr &MI = *MBBI;
     747             :   unsigned OpLo, OpHi, DstLoReg, DstHiReg;
     748           1 :   unsigned DstReg = MI.getOperand(0).getReg();
     749             :   unsigned TmpReg = 0; // 0 for no temporary register
     750           1 :   unsigned SrcReg = MI.getOperand(1).getReg();
     751             :   bool SrcIsKill = MI.getOperand(1).isKill();
     752             :   OpLo = AVR::LPMRdZPi;
     753             :   OpHi = AVR::LPMRdZ;
     754           1 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
     755             : 
     756             :   // Use a temporary register if src and dst registers are the same.
     757           1 :   if (DstReg == SrcReg)
     758           0 :     TmpReg = scavengeGPR8(MI);
     759             : 
     760           1 :   unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
     761           1 :   unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
     762             : 
     763             :   // Load low byte.
     764           1 :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
     765           1 :       .addReg(CurDstLoReg, RegState::Define)
     766           1 :       .addReg(SrcReg);
     767             : 
     768             :   // Push low byte onto stack if necessary.
     769           1 :   if (TmpReg)
     770           0 :     buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
     771             : 
     772             :   // Load high byte.
     773           1 :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
     774           1 :       .addReg(CurDstHiReg, RegState::Define)
     775           1 :       .addReg(SrcReg, getKillRegState(SrcIsKill));
     776             : 
     777           1 :   if (TmpReg) {
     778             :     // Move the high byte into the final destination.
     779           0 :     buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
     780             : 
     781             :     // Move the low byte from the scratch space into the final destination.
     782           0 :     buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
     783             :   }
     784             : 
     785           1 :   MIBLO.setMemRefs(MI.memoperands());
     786           1 :   MIBHI.setMemRefs(MI.memoperands());
     787             : 
     788           1 :   MI.eraseFromParent();
     789           1 :   return true;
     790             : }
     791             : 
     792             : template <>
     793           0 : bool AVRExpandPseudo::expand<AVR::LPMWRdZPi>(Block &MBB, BlockIt MBBI) {
     794           0 :   llvm_unreachable("wide LPMPi is unimplemented");
     795             : }
     796             : 
     797             : template<typename Func>
     798          18 : bool AVRExpandPseudo::expandAtomic(Block &MBB, BlockIt MBBI, Func f) {
     799             :   // Remove the pseudo instruction.
     800             :   MachineInstr &MI = *MBBI;
     801             : 
     802             :   // Store the SREG.
     803          18 :   buildMI(MBB, MBBI, AVR::INRdA)
     804          18 :     .addReg(SCRATCH_REGISTER, RegState::Define)
     805          18 :     .addImm(SREG_ADDR);
     806             : 
     807             :   // Disable exceptions.
     808          18 :   buildMI(MBB, MBBI, AVR::BCLRs).addImm(7); // CLI
     809             : 
     810          18 :   f(MI);
     811             : 
     812             :   // Restore the status reg.
     813          18 :   buildMI(MBB, MBBI, AVR::OUTARr)
     814          18 :     .addImm(SREG_ADDR)
     815          18 :     .addReg(SCRATCH_REGISTER);
     816             : 
     817          18 :   MI.eraseFromParent();
     818          18 :   return true;
     819             : }
     820           8 : 
     821             : template<typename Func>
     822             : bool AVRExpandPseudo::expandAtomicBinaryOp(unsigned Opcode,
     823             :                                            Block &MBB,
     824             :                                            BlockIt MBBI,
     825           8 :                                            Func f) {
     826           8 :   return expandAtomic(MBB, MBBI, [&](MachineInstr &MI) {
     827           8 :       auto Op1 = MI.getOperand(0);
     828             :       auto Op2 = MI.getOperand(1);
     829             : 
     830           8 :       MachineInstr &NewInst =
     831             :           *buildMI(MBB, MBBI, Opcode).add(Op1).add(Op2).getInstr();
     832           8 :       f(NewInst);
     833             :   });
     834             : }
     835           8 : 
     836           8 : bool AVRExpandPseudo::expandAtomicBinaryOp(unsigned Opcode,
     837           8 :                                            Block &MBB,
     838             :                                            BlockIt MBBI) {
     839           8 :   return expandAtomicBinaryOp(Opcode, MBB, MBBI, [](MachineInstr &MI) {});
     840           8 : }
     841             : 
     842          10 : bool AVRExpandPseudo::expandAtomicArithmeticOp(unsigned Width,
     843             :                                                unsigned ArithOpcode,
     844             :                                                Block &MBB,
     845             :                                                BlockIt MBBI) {
     846             :   return expandAtomic(MBB, MBBI, [&](MachineInstr &MI) {
     847          10 :       auto Op1 = MI.getOperand(0);
     848          10 :       auto Op2 = MI.getOperand(1);
     849          10 : 
     850             :       unsigned LoadOpcode = (Width == 8) ? AVR::LDRdPtr : AVR::LDWRdPtr;
     851             :       unsigned StoreOpcode = (Width == 8) ? AVR::STPtrRr : AVR::STWPtrRr;
     852          10 : 
     853             :       // Create the load
     854          10 :       buildMI(MBB, MBBI, LoadOpcode).add(Op1).add(Op2);
     855             : 
     856             :       // Create the arithmetic op
     857          10 :       buildMI(MBB, MBBI, ArithOpcode).add(Op1).add(Op1).add(Op2);
     858          10 : 
     859          10 :       // Create the store
     860             :       buildMI(MBB, MBBI, StoreOpcode).add(Op2).add(Op1);
     861          10 :   });
     862          10 : }
     863             : 
     864             : unsigned AVRExpandPseudo::scavengeGPR8(MachineInstr &MI) {
     865             :   MachineBasicBlock &MBB = *MI.getParent();
     866             :   RegScavenger RS;
     867             : 
     868             :   RS.enterBasicBlock(MBB);
     869             :   RS.forward(MI);
     870             : 
     871             :   BitVector Candidates =
     872             :       TRI->getAllocatableSet
     873             :       (*MBB.getParent(), &AVR::GPR8RegClass);
     874             : 
     875             :   // Exclude all the registers being used by the instruction.
     876             :   for (MachineOperand &MO : MI.operands()) {
     877           8 :     if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() &&
     878             :         !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
     879             :       Candidates.reset(MO.getReg());
     880           8 :   }
     881             : 
     882             :   BitVector Available = RS.getRegsAvailable(&AVR::GPR8RegClass);
     883           8 :   Available &= Candidates;
     884             : 
     885             :   signed Reg = Available.find_first();
     886             :   assert(Reg != -1 && "ran out of registers");
     887             :   return Reg;
     888             : }
     889             : 
     890          10 : template<>
     891             : bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(Block &MBB, BlockIt MBBI) {
     892             :   return expandAtomicBinaryOp(AVR::LDRdPtr, MBB, MBBI);
     893             : }
     894             : 
     895             : template<>
     896             : bool AVRExpandPseudo::expand<AVR::AtomicLoad16>(Block &MBB, BlockIt MBBI) {
     897             :   return expandAtomicBinaryOp(AVR::LDWRdPtr, MBB, MBBI);
     898             : }
     899             : 
     900             : template<>
     901             : bool AVRExpandPseudo::expand<AVR::AtomicStore8>(Block &MBB, BlockIt MBBI) {
     902             :   return expandAtomicBinaryOp(AVR::STPtrRr, MBB, MBBI);
     903             : }
     904             : 
     905             : template<>
     906             : bool AVRExpandPseudo::expand<AVR::AtomicStore16>(Block &MBB, BlockIt MBBI) {
     907             :   return expandAtomicBinaryOp(AVR::STWPtrRr, MBB, MBBI);
     908           0 : }
     909           0 : 
     910           0 : template<>
     911             : bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd8>(Block &MBB, BlockIt MBBI) {
     912           0 :   return expandAtomicArithmeticOp(8, AVR::ADDRdRr, MBB, MBBI);
     913           0 : }
     914             : 
     915             : template<>
     916           0 : bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd16>(Block &MBB, BlockIt MBBI) {
     917           0 :   return expandAtomicArithmeticOp(16, AVR::ADDWRdRr, MBB, MBBI);
     918             : }
     919             : 
     920           0 : template<>
     921           0 : bool AVRExpandPseudo::expand<AVR::AtomicLoadSub8>(Block &MBB, BlockIt MBBI) {
     922             :   return expandAtomicArithmeticOp(8, AVR::SUBRdRr, MBB, MBBI);
     923             : }
     924             : 
     925             : template<>
     926           0 : bool AVRExpandPseudo::expand<AVR::AtomicLoadSub16>(Block &MBB, BlockIt MBBI) {
     927           0 :   return expandAtomicArithmeticOp(16, AVR::SUBWRdRr, MBB, MBBI);
     928             : }
     929             : 
     930             : template<>
     931           0 : bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd8>(Block &MBB, BlockIt MBBI) {
     932             :   return expandAtomicArithmeticOp(8, AVR::ANDRdRr, MBB, MBBI);
     933             : }
     934             : 
     935             : template<>
     936           1 : bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd16>(Block &MBB, BlockIt MBBI) {
     937             :   return expandAtomicArithmeticOp(16, AVR::ANDWRdRr, MBB, MBBI);
     938             : }
     939             : 
     940             : template<>
     941           3 : bool AVRExpandPseudo::expand<AVR::AtomicLoadOr8>(Block &MBB, BlockIt MBBI) {
     942             :   return expandAtomicArithmeticOp(8, AVR::ORRdRr, MBB, MBBI);
     943             : }
     944             : 
     945             : template<>
     946           1 : bool AVRExpandPseudo::expand<AVR::AtomicLoadOr16>(Block &MBB, BlockIt MBBI) {
     947             :   return expandAtomicArithmeticOp(16, AVR::ORWRdRr, MBB, MBBI);
     948             : }
     949             : 
     950             : template<>
     951           3 : bool AVRExpandPseudo::expand<AVR::AtomicLoadXor8>(Block &MBB, BlockIt MBBI) {
     952             :   return expandAtomicArithmeticOp(8, AVR::EORRdRr, MBB, MBBI);
     953             : }
     954             : 
     955           1 : template<>
     956           1 : bool AVRExpandPseudo::expand<AVR::AtomicLoadXor16>(Block &MBB, BlockIt MBBI) {
     957             :   return expandAtomicArithmeticOp(16, AVR::EORWRdRr, MBB, MBBI);
     958             : }
     959             : 
     960           1 : template<>
     961           1 : bool AVRExpandPseudo::expand<AVR::AtomicFence>(Block &MBB, BlockIt MBBI) {
     962             :   // On AVR, there is only one core and so atomic fences do nothing.
     963             :   MBBI->eraseFromParent();
     964             :   return true;
     965           1 : }
     966           1 : 
     967             : template <>
     968             : bool AVRExpandPseudo::expand<AVR::STSWKRr>(Block &MBB, BlockIt MBBI) {
     969             :   MachineInstr &MI = *MBBI;
     970           1 :   unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
     971           1 :   unsigned SrcReg = MI.getOperand(1).getReg();
     972             :   bool SrcIsKill = MI.getOperand(1).isKill();
     973             :   OpLo = AVR::STSKRr;
     974             :   OpHi = AVR::STSKRr;
     975           1 :   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
     976           1 : 
     977             :   // Write the high byte first in case this address belongs to a special
     978             :   // I/O address with a special temporary register.
     979             :   auto MIBHI = buildMI(MBB, MBBI, OpHi);
     980           1 :   auto MIBLO = buildMI(MBB, MBBI, OpLo);
     981           1 : 
     982             :   switch (MI.getOperand(0).getType()) {
     983             :   case MachineOperand::MO_GlobalAddress: {
     984             :     const GlobalValue *GV = MI.getOperand(0).getGlobal();
     985           1 :     int64_t Offs = MI.getOperand(0).getOffset();
     986           1 :     unsigned TF = MI.getOperand(0).getTargetFlags();
     987             : 
     988             :     MIBLO.addGlobalAddress(GV, Offs, TF);
     989             :     MIBHI.addGlobalAddress(GV, Offs + 1, TF);
     990           1 :     break;
     991           1 :   }
     992             :   case MachineOperand::MO_Immediate: {
     993             :     unsigned Imm = MI.getOperand(0).getImm();
     994             : 
     995           1 :     MIBLO.addImm(Imm);
     996           1 :     MIBHI.addImm(Imm + 1);
     997             :     break;
     998             :   }
     999             :   default:
    1000           1 :     llvm_unreachable("Unknown operand type!");
    1001           1 :   }
    1002             : 
    1003             :   MIBLO.addReg(SrcLoReg, getKillRegState(SrcIsKill));
    1004             :   MIBHI.addReg(SrcHiReg, getKillRegState(SrcIsKill));
    1005           0 : 
    1006             :   MIBLO.setMemRefs(MI.memoperands());
    1007           1 :   MIBHI.setMemRefs(MI.memoperands());
    1008           0 : 
    1009             :   MI.eraseFromParent();
    1010             :   return true;
    1011             : }
    1012          60 : 
    1013             : template <>
    1014             : bool AVRExpandPseudo::expand<AVR::STWPtrRr>(Block &MBB, BlockIt MBBI) {
    1015          60 :   MachineInstr &MI = *MBBI;
    1016             :   unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
    1017             :   unsigned DstReg = MI.getOperand(0).getReg();
    1018             :   unsigned SrcReg = MI.getOperand(1).getReg();
    1019          60 :   bool SrcIsKill = MI.getOperand(1).isKill();
    1020             :   OpLo = AVR::STPtrRr;
    1021             :   OpHi = AVR::STDPtrQRr;
    1022             :   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
    1023          60 : 
    1024          60 :   //:TODO: need to reverse this order like inw and stsw?
    1025             :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
    1026         120 :     .addReg(DstReg)
    1027          38 :     .addReg(SrcLoReg, getKillRegState(SrcIsKill));
    1028          38 : 
    1029          38 :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
    1030             :     .addReg(DstReg)
    1031             :     .addImm(1)
    1032          38 :     .addReg(SrcHiReg, getKillRegState(SrcIsKill));
    1033          38 : 
    1034             :   MIBLO.setMemRefs(MI.memoperands());
    1035             :   MIBHI.setMemRefs(MI.memoperands());
    1036          22 : 
    1037          22 :   MI.eraseFromParent();
    1038             :   return true;
    1039             : }
    1040          22 : 
    1041             : template <>
    1042             : bool AVRExpandPseudo::expand<AVR::STWPtrPiRr>(Block &MBB, BlockIt MBBI) {
    1043           0 :   MachineInstr &MI = *MBBI;
    1044           0 :   unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
    1045             :   unsigned DstReg = MI.getOperand(0).getReg();
    1046             :   unsigned SrcReg = MI.getOperand(2).getReg();
    1047          60 :   unsigned Imm = MI.getOperand(3).getImm();
    1048          60 :   bool DstIsDead = MI.getOperand(0).isDead();
    1049             :   bool SrcIsKill = MI.getOperand(2).isKill();
    1050          60 :   OpLo = AVR::STPtrPiRr;
    1051          60 :   OpHi = AVR::STPtrPiRr;
    1052             :   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
    1053          60 : 
    1054          60 :   assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
    1055             : 
    1056             :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
    1057             :     .addReg(DstReg, RegState::Define)
    1058          19 :     .addReg(DstReg, RegState::Kill)
    1059             :     .addReg(SrcLoReg, getKillRegState(SrcIsKill))
    1060             :     .addImm(Imm);
    1061          19 : 
    1062          19 :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
    1063             :     .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
    1064             :     .addReg(DstReg, RegState::Kill)
    1065             :     .addReg(SrcHiReg, getKillRegState(SrcIsKill))
    1066          19 :     .addImm(Imm);
    1067             : 
    1068             :   MIBLO.setMemRefs(MI.memoperands());
    1069          19 :   MIBHI.setMemRefs(MI.memoperands());
    1070          19 : 
    1071          19 :   MI.eraseFromParent();
    1072             :   return true;
    1073          19 : }
    1074          19 : 
    1075             : template <>
    1076          19 : bool AVRExpandPseudo::expand<AVR::STWPtrPdRr>(Block &MBB, BlockIt MBBI) {
    1077             :   MachineInstr &MI = *MBBI;
    1078          19 :   unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
    1079          19 :   unsigned DstReg = MI.getOperand(0).getReg();
    1080             :   unsigned SrcReg = MI.getOperand(2).getReg();
    1081          19 :   unsigned Imm = MI.getOperand(3).getImm();
    1082          19 :   bool DstIsDead = MI.getOperand(0).isDead();
    1083             :   bool SrcIsKill = MI.getOperand(2).isKill();
    1084             :   OpLo = AVR::STPtrPdRr;
    1085             :   OpHi = AVR::STPtrPdRr;
    1086           4 :   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
    1087             : 
    1088             :   assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
    1089           4 : 
    1090           4 :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
    1091           4 :     .addReg(DstReg, RegState::Define)
    1092             :     .addReg(DstReg, RegState::Kill)
    1093             :     .addReg(SrcHiReg, getKillRegState(SrcIsKill))
    1094             :     .addImm(Imm);
    1095             : 
    1096           4 :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
    1097             :     .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
    1098             :     .addReg(DstReg, RegState::Kill)
    1099             :     .addReg(SrcLoReg, getKillRegState(SrcIsKill))
    1100           4 :     .addImm(Imm);
    1101           4 : 
    1102           4 :   MIBLO.setMemRefs(MI.memoperands());
    1103           4 :   MIBHI.setMemRefs(MI.memoperands());
    1104           4 : 
    1105             :   MI.eraseFromParent();
    1106           4 :   return true;
    1107           4 : }
    1108           4 : 
    1109           4 : template <>
    1110           4 : bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(Block &MBB, BlockIt MBBI) {
    1111             :   MachineInstr &MI = *MBBI;
    1112           4 :   unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
    1113           4 :   unsigned DstReg = MI.getOperand(0).getReg();
    1114             :   unsigned SrcReg = MI.getOperand(2).getReg();
    1115           4 :   unsigned Imm = MI.getOperand(1).getImm();
    1116           4 :   bool DstIsKill = MI.getOperand(0).isKill();
    1117             :   bool SrcIsKill = MI.getOperand(2).isKill();
    1118             :   OpLo = AVR::STDPtrQRr;
    1119             :   OpHi = AVR::STDPtrQRr;
    1120           2 :   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
    1121             : 
    1122             :   // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value
    1123           2 :   // allowed for the instruction, 62 is the limit here.
    1124           2 :   assert(Imm <= 62 && "Offset is out of range");
    1125           2 : 
    1126             :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
    1127             :     .addReg(DstReg)
    1128             :     .addImm(Imm)
    1129             :     .addReg(SrcLoReg, getKillRegState(SrcIsKill));
    1130           2 : 
    1131             :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
    1132             :     .addReg(DstReg, getKillRegState(DstIsKill))
    1133             :     .addImm(Imm + 1)
    1134           2 :     .addReg(SrcHiReg, getKillRegState(SrcIsKill));
    1135           2 : 
    1136           2 :   MIBLO.setMemRefs(MI.memoperands());
    1137           2 :   MIBHI.setMemRefs(MI.memoperands());
    1138           2 : 
    1139             :   MI.eraseFromParent();
    1140           2 :   return true;
    1141           2 : }
    1142           2 : 
    1143           2 : template <>
    1144           2 : bool AVRExpandPseudo::expand<AVR::INWRdA>(Block &MBB, BlockIt MBBI) {
    1145             :   MachineInstr &MI = *MBBI;
    1146           2 :   unsigned OpLo, OpHi, DstLoReg, DstHiReg;
    1147           2 :   unsigned Imm = MI.getOperand(1).getImm();
    1148             :   unsigned DstReg = MI.getOperand(0).getReg();
    1149           2 :   bool DstIsDead = MI.getOperand(0).isDead();
    1150           2 :   OpLo = AVR::INRdA;
    1151             :   OpHi = AVR::INRdA;
    1152             :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
    1153             : 
    1154          72 :   // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value
    1155             :   // allowed for the instruction, 62 is the limit here.
    1156             :   assert(Imm <= 62 && "Address is out of range");
    1157          72 : 
    1158          72 :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
    1159          72 :     .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
    1160             :     .addImm(Imm);
    1161             : 
    1162             :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
    1163             :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
    1164          72 :     .addImm(Imm + 1);
    1165             : 
    1166             :   MIBLO.setMemRefs(MI.memoperands());
    1167             :   MIBHI.setMemRefs(MI.memoperands());
    1168             : 
    1169             :   MI.eraseFromParent();
    1170          72 :   return true;
    1171          72 : }
    1172             : 
    1173          72 : template <>
    1174             : bool AVRExpandPseudo::expand<AVR::OUTWARr>(Block &MBB, BlockIt MBBI) {
    1175          72 :   MachineInstr &MI = *MBBI;
    1176          72 :   unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
    1177          72 :   unsigned Imm = MI.getOperand(0).getImm();
    1178          72 :   unsigned SrcReg = MI.getOperand(1).getReg();
    1179             :   bool SrcIsKill = MI.getOperand(1).isKill();
    1180          72 :   OpLo = AVR::OUTARr;
    1181          72 :   OpHi = AVR::OUTARr;
    1182             :   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
    1183          72 : 
    1184          72 :   // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value
    1185             :   // allowed for the instruction, 62 is the limit here.
    1186             :   assert(Imm <= 62 && "Address is out of range");
    1187             : 
    1188           8 :   // 16 bit I/O writes need the high byte first
    1189             :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
    1190             :     .addImm(Imm + 1)
    1191           8 :     .addReg(SrcHiReg, getKillRegState(SrcIsKill));
    1192           8 : 
    1193             :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
    1194             :     .addImm(Imm)
    1195             :     .addReg(SrcLoReg, getKillRegState(SrcIsKill));
    1196           8 : 
    1197             :   MIBLO.setMemRefs(MI.memoperands());
    1198             :   MIBHI.setMemRefs(MI.memoperands());
    1199             : 
    1200             :   MI.eraseFromParent();
    1201             :   return true;
    1202           8 : }
    1203          16 : 
    1204           8 : template <>
    1205             : bool AVRExpandPseudo::expand<AVR::PUSHWRr>(Block &MBB, BlockIt MBBI) {
    1206           8 :   MachineInstr &MI = *MBBI;
    1207           8 :   unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
    1208           8 :   unsigned SrcReg = MI.getOperand(0).getReg();
    1209             :   bool SrcIsKill = MI.getOperand(0).isKill();
    1210           8 :   unsigned Flags = MI.getFlags();
    1211           8 :   OpLo = AVR::PUSHRr;
    1212             :   OpHi = AVR::PUSHRr;
    1213           8 :   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
    1214           8 : 
    1215             :   // Low part
    1216             :   buildMI(MBB, MBBI, OpLo)
    1217             :     .addReg(SrcLoReg, getKillRegState(SrcIsKill))
    1218           8 :     .setMIFlags(Flags);
    1219             : 
    1220             :   // High part
    1221           8 :   buildMI(MBB, MBBI, OpHi)
    1222           8 :     .addReg(SrcHiReg, getKillRegState(SrcIsKill))
    1223             :     .setMIFlags(Flags);
    1224             : 
    1225             :   MI.eraseFromParent();
    1226           8 :   return true;
    1227             : }
    1228             : 
    1229             : template <>
    1230             : bool AVRExpandPseudo::expand<AVR::POPWRd>(Block &MBB, BlockIt MBBI) {
    1231             :   MachineInstr &MI = *MBBI;
    1232             :   unsigned OpLo, OpHi, DstLoReg, DstHiReg;
    1233           8 :   unsigned DstReg = MI.getOperand(0).getReg();
    1234           8 :   unsigned Flags = MI.getFlags();
    1235           8 :   OpLo = AVR::POPRd;
    1236             :   OpHi = AVR::POPRd;
    1237           8 :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
    1238             : 
    1239           8 :   buildMI(MBB, MBBI, OpHi, DstHiReg).setMIFlags(Flags); // High
    1240             :   buildMI(MBB, MBBI, OpLo, DstLoReg).setMIFlags(Flags); // Low
    1241           8 : 
    1242           8 :   MI.eraseFromParent();
    1243             :   return true;
    1244           8 : }
    1245           8 : 
    1246             : template <>
    1247             : bool AVRExpandPseudo::expand<AVR::LSLWRd>(Block &MBB, BlockIt MBBI) {
    1248             :   MachineInstr &MI = *MBBI;
    1249          31 :   unsigned OpLo, OpHi, DstLoReg, DstHiReg;
    1250             :   unsigned DstReg = MI.getOperand(0).getReg();
    1251             :   bool DstIsDead = MI.getOperand(0).isDead();
    1252          31 :   bool DstIsKill = MI.getOperand(1).isKill();
    1253             :   bool ImpIsDead = MI.getOperand(2).isDead();
    1254          31 :   OpLo = AVR::ADDRdRr; // ADD Rd, Rd <==> LSL Rd
    1255             :   OpHi = AVR::ADCRdRr; // ADC Rd, Rd <==> ROL Rd
    1256             :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
    1257          31 : 
    1258             :   // Low part
    1259             :   buildMI(MBB, MBBI, OpLo)
    1260          31 :     .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
    1261          31 :     .addReg(DstLoReg)
    1262          31 :     .addReg(DstLoReg, getKillRegState(DstIsKill));
    1263             : 
    1264             :   auto MIBHI = buildMI(MBB, MBBI, OpHi)
    1265          31 :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
    1266          31 :     .addReg(DstHiReg)
    1267          31 :     .addReg(DstHiReg, getKillRegState(DstIsKill));
    1268             : 
    1269          31 :   if (ImpIsDead)
    1270          31 :     MIBHI->getOperand(3).setIsDead();
    1271             : 
    1272             :   // SREG is always implicitly killed
    1273             :   MIBHI->getOperand(4).setIsKill();
    1274          30 : 
    1275             :   MI.eraseFromParent();
    1276             :   return true;
    1277          30 : }
    1278          30 : 
    1279             : template <>
    1280             : bool AVRExpandPseudo::expand<AVR::LSRWRd>(Block &MBB, BlockIt MBBI) {
    1281          30 :   MachineInstr &MI = *MBBI;
    1282             :   unsigned OpLo, OpHi, DstLoReg, DstHiReg;
    1283          30 :   unsigned DstReg = MI.getOperand(0).getReg();
    1284          30 :   bool DstIsDead = MI.getOperand(0).isDead();
    1285             :   bool DstIsKill = MI.getOperand(1).isKill();
    1286          30 :   bool ImpIsDead = MI.getOperand(2).isDead();
    1287          30 :   OpLo = AVR::RORRd;
    1288             :   OpHi = AVR::LSRRd;
    1289             :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
    1290             : 
    1291         239 :   // High part
    1292             :   buildMI(MBB, MBBI, OpHi)
    1293             :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
    1294         239 :     .addReg(DstHiReg, getKillRegState(DstIsKill));
    1295             : 
    1296             :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
    1297             :     .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
    1298             :     .addReg(DstLoReg, getKillRegState(DstIsKill));
    1299             : 
    1300         239 :   if (ImpIsDead)
    1301             :     MIBLO->getOperand(2).setIsDead();
    1302             : 
    1303         239 :   // SREG is always implicitly killed
    1304         478 :   MIBLO->getOperand(3).setIsKill();
    1305         239 : 
    1306         478 :   MI.eraseFromParent();
    1307             :   return true;
    1308         239 : }
    1309         239 : 
    1310         239 : template <>
    1311         239 : bool AVRExpandPseudo::expand<AVR::RORWRd>(Block &MBB, BlockIt MBBI) {
    1312             :   llvm_unreachable("RORW unimplemented");
    1313         239 :   return false;
    1314         238 : }
    1315             : 
    1316             : template <>
    1317         239 : bool AVRExpandPseudo::expand<AVR::ROLWRd>(Block &MBB, BlockIt MBBI) {
    1318             :   llvm_unreachable("ROLW unimplemented");
    1319         239 :   return false;
    1320         239 : }
    1321             : 
    1322             : template <>
    1323             : bool AVRExpandPseudo::expand<AVR::ASRWRd>(Block &MBB, BlockIt MBBI) {
    1324         105 :   MachineInstr &MI = *MBBI;
    1325             :   unsigned OpLo, OpHi, DstLoReg, DstHiReg;
    1326             :   unsigned DstReg = MI.getOperand(0).getReg();
    1327         105 :   bool DstIsDead = MI.getOperand(0).isDead();
    1328             :   bool DstIsKill = MI.getOperand(1).isKill();
    1329             :   bool ImpIsDead = MI.getOperand(2).isDead();
    1330             :   OpLo = AVR::RORRd;
    1331             :   OpHi = AVR::ASRRd;
    1332             :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
    1333         105 : 
    1334             :   // High part
    1335             :   buildMI(MBB, MBBI, OpHi)
    1336         105 :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
    1337         210 :     .addReg(DstHiReg, getKillRegState(DstIsKill));
    1338         210 : 
    1339             :   auto MIBLO = buildMI(MBB, MBBI, OpLo)
    1340         105 :     .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
    1341         105 :     .addReg(DstLoReg, getKillRegState(DstIsKill));
    1342         105 : 
    1343             :   if (ImpIsDead)
    1344         105 :     MIBLO->getOperand(2).setIsDead();
    1345         104 : 
    1346             :   // SREG is always implicitly killed
    1347             :   MIBLO->getOperand(3).setIsKill();
    1348         105 : 
    1349             :   MI.eraseFromParent();
    1350         105 :   return true;
    1351         105 : }
    1352             : 
    1353             : template <> bool AVRExpandPseudo::expand<AVR::SEXT>(Block &MBB, BlockIt MBBI) {
    1354             :   MachineInstr &MI = *MBBI;
    1355           0 :   unsigned DstLoReg, DstHiReg;
    1356           0 :   // sext R17:R16, R17
    1357             :   // mov     r16, r17
    1358             :   // lsl     r17
    1359             :   // sbc     r17, r17
    1360             :   // sext R17:R16, R13
    1361           0 :   // mov     r16, r13
    1362           0 :   // mov     r17, r13
    1363             :   // lsl     r17
    1364             :   // sbc     r17, r17
    1365             :   // sext R17:R16, R16
    1366             :   // mov     r17, r16
    1367          76 :   // lsl     r17
    1368             :   // sbc     r17, r17
    1369             :   unsigned DstReg = MI.getOperand(0).getReg();
    1370          76 :   unsigned SrcReg = MI.getOperand(1).getReg();
    1371             :   bool DstIsDead = MI.getOperand(0).isDead();
    1372             :   bool SrcIsKill = MI.getOperand(1).isKill();
    1373             :   bool ImpIsDead = MI.getOperand(2).isDead();
    1374             :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
    1375             : 
    1376          76 :   if (SrcReg != DstLoReg) {
    1377             :     auto MOV = buildMI(MBB, MBBI, AVR::MOVRdRr)
    1378             :       .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
    1379          76 :       .addReg(SrcReg);
    1380         152 : 
    1381         152 :     if (SrcReg == DstHiReg) {
    1382             :       MOV->getOperand(1).setIsKill();
    1383          76 :     }
    1384          76 :   }
    1385          76 : 
    1386             :   if (SrcReg != DstHiReg) {
    1387          76 :     buildMI(MBB, MBBI, AVR::MOVRdRr)
    1388          75 :       .addReg(DstHiReg, RegState::Define)
    1389             :       .addReg(SrcReg, getKillRegState(SrcIsKill));
    1390             :   }
    1391          76 : 
    1392             :   buildMI(MBB, MBBI, AVR::ADDRdRr) // LSL Rd <==> ADD Rd, Rr
    1393          76 :     .addReg(DstHiReg, RegState::Define)
    1394          76 :     .addReg(DstHiReg)
    1395             :     .addReg(DstHiReg, RegState::Kill);
    1396             : 
    1397           8 :   auto SBC = buildMI(MBB, MBBI, AVR::SBCRdRr)
    1398             :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
    1399             :     .addReg(DstHiReg, RegState::Kill)
    1400             :     .addReg(DstHiReg, RegState::Kill);
    1401             : 
    1402             :   if (ImpIsDead)
    1403             :     SBC->getOperand(3).setIsDead();
    1404             : 
    1405             :   // SREG is always implicitly killed
    1406             :   SBC->getOperand(4).setIsKill();
    1407             : 
    1408             :   MI.eraseFromParent();
    1409             :   return true;
    1410             : }
    1411             : 
    1412             : template <> bool AVRExpandPseudo::expand<AVR::ZEXT>(Block &MBB, BlockIt MBBI) {
    1413           8 :   MachineInstr &MI = *MBBI;
    1414           8 :   unsigned DstLoReg, DstHiReg;
    1415             :   // zext R25:R24, R20
    1416             :   // mov      R24, R20
    1417             :   // eor      R25, R25
    1418           8 :   // zext R25:R24, R24
    1419             :   // eor      R25, R25
    1420           8 :   // zext R25:R24, R25
    1421           6 :   // mov      R24, R25
    1422          12 :   // eor      R25, R25
    1423           6 :   unsigned DstReg = MI.getOperand(0).getReg();
    1424             :   unsigned SrcReg = MI.getOperand(1).getReg();
    1425           6 :   bool DstIsDead = MI.getOperand(0).isDead();
    1426           0 :   bool SrcIsKill = MI.getOperand(1).isKill();
    1427             :   bool ImpIsDead = MI.getOperand(2).isDead();
    1428             :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
    1429             : 
    1430           8 :   if (SrcReg != DstLoReg) {
    1431          16 :     buildMI(MBB, MBBI, AVR::MOVRdRr)
    1432           8 :       .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
    1433          16 :       .addReg(SrcReg, getKillRegState(SrcIsKill));
    1434             :   }
    1435             : 
    1436           8 :   auto EOR = buildMI(MBB, MBBI, AVR::EORRdRr)
    1437           8 :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
    1438           8 :     .addReg(DstHiReg, RegState::Kill)
    1439           8 :     .addReg(DstHiReg, RegState::Kill);
    1440             : 
    1441           8 :   if (ImpIsDead)
    1442          16 :     EOR->getOperand(3).setIsDead();
    1443           8 : 
    1444           8 :   MI.eraseFromParent();
    1445             :   return true;
    1446           8 : }
    1447           6 : 
    1448             : template <>
    1449             : bool AVRExpandPseudo::expand<AVR::SPREAD>(Block &MBB, BlockIt MBBI) {
    1450           8 :   MachineInstr &MI = *MBBI;
    1451             :   unsigned OpLo, OpHi, DstLoReg, DstHiReg;
    1452           8 :   unsigned DstReg = MI.getOperand(0).getReg();
    1453           8 :   bool DstIsDead = MI.getOperand(0).isDead();
    1454             :   unsigned Flags = MI.getFlags();
    1455             :   OpLo = AVR::INRdA;
    1456           3 :   OpHi = AVR::INRdA;
    1457             :   TRI->splitReg(DstReg, DstLoReg, DstHiReg);
    1458             : 
    1459             :   // Low part
    1460             :   buildMI(MBB, MBBI, OpLo)
    1461             :     .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
    1462             :     .addImm(0x3d)
    1463             :     .setMIFlags(Flags);
    1464             : 
    1465             :   // High part
    1466             :   buildMI(MBB, MBBI, OpHi)
    1467           3 :     .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
    1468           3 :     .addImm(0x3e)
    1469             :     .setMIFlags(Flags);
    1470             : 
    1471             :   MI.eraseFromParent();
    1472           3 :   return true;
    1473             : }
    1474           3 : 
    1475           4 : template <>
    1476           4 : bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
    1477           4 :   MachineInstr &MI = *MBBI;
    1478             :   unsigned SrcLoReg, SrcHiReg;
    1479             :   unsigned SrcReg = MI.getOperand(1).getReg();
    1480           3 :   bool SrcIsKill = MI.getOperand(1).isKill();
    1481           6 :   unsigned Flags = MI.getFlags();
    1482           3 :   TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
    1483           3 : 
    1484             :   buildMI(MBB, MBBI, AVR::INRdA)
    1485           3 :     .addReg(AVR::R0, RegState::Define)
    1486           3 :     .addImm(SREG_ADDR)
    1487             :     .setMIFlags(Flags);
    1488           3 : 
    1489           3 :   buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
    1490             : 
    1491             :   buildMI(MBB, MBBI, AVR::OUTARr)
    1492             :     .addImm(0x3e)
    1493          38 :     .addReg(SrcHiReg, getKillRegState(SrcIsKill))
    1494             :     .setMIFlags(Flags);
    1495             : 
    1496          38 :   buildMI(MBB, MBBI, AVR::OUTARr)
    1497             :     .addImm(SREG_ADDR)
    1498          38 :     .addReg(AVR::R0, RegState::Kill)
    1499             :     .setMIFlags(Flags);
    1500             : 
    1501          38 :   buildMI(MBB, MBBI, AVR::OUTARr)
    1502             :     .addImm(0x3d)
    1503             :     .addReg(SrcLoReg, getKillRegState(SrcIsKill))
    1504          38 :     .setMIFlags(Flags);
    1505          76 : 
    1506          38 :   MI.eraseFromParent();
    1507             :   return true;
    1508             : }
    1509             : 
    1510          38 : bool AVRExpandPseudo::expandMI(Block &MBB, BlockIt MBBI) {
    1511          38 :   MachineInstr &MI = *MBBI;
    1512          38 :   int Opcode = MBBI->getOpcode();
    1513             : 
    1514             : #define EXPAND(Op)               \
    1515          38 :   case Op:                       \
    1516          38 :     return expand<Op>(MBB, MI)
    1517             : 
    1518             :   switch (Opcode) {
    1519             :     EXPAND(AVR::ADDWRdRr);
    1520          57 :     EXPAND(AVR::ADCWRdRr);
    1521             :     EXPAND(AVR::SUBWRdRr);
    1522             :     EXPAND(AVR::SUBIWRdK);
    1523          57 :     EXPAND(AVR::SBCWRdRr);
    1524             :     EXPAND(AVR::SBCIWRdK);
    1525          57 :     EXPAND(AVR::ANDWRdRr);
    1526          57 :     EXPAND(AVR::ANDIWRdK);
    1527             :     EXPAND(AVR::ORWRdRr);
    1528          57 :     EXPAND(AVR::ORIWRdK);
    1529          57 :     EXPAND(AVR::EORWRdRr);
    1530          57 :     EXPAND(AVR::COMWRd);
    1531             :     EXPAND(AVR::CPWRdRr);
    1532             :     EXPAND(AVR::CPCWRdRr);
    1533          57 :     EXPAND(AVR::LDIWRdK);
    1534             :     EXPAND(AVR::LDSWRdK);
    1535          57 :     EXPAND(AVR::LDWRdPtr);
    1536             :     EXPAND(AVR::LDWRdPtrPi);
    1537          57 :     EXPAND(AVR::LDWRdPtrPd);
    1538          57 :   case AVR::LDDWRdYQ: //:FIXME: remove this once PR13375 gets fixed
    1539             :     EXPAND(AVR::LDDWRdPtrQ);
    1540          57 :     EXPAND(AVR::LPMWRdZ);
    1541          57 :     EXPAND(AVR::LPMWRdZPi);
    1542          57 :     EXPAND(AVR::AtomicLoad8);
    1543             :     EXPAND(AVR::AtomicLoad16);
    1544             :     EXPAND(AVR::AtomicStore8);
    1545          57 :     EXPAND(AVR::AtomicStore16);
    1546             :     EXPAND(AVR::AtomicLoadAdd8);
    1547          57 :     EXPAND(AVR::AtomicLoadAdd16);
    1548          57 :     EXPAND(AVR::AtomicLoadSub8);
    1549             :     EXPAND(AVR::AtomicLoadSub16);
    1550          57 :     EXPAND(AVR::AtomicLoadAnd8);
    1551          57 :     EXPAND(AVR::AtomicLoadAnd16);
    1552             :     EXPAND(AVR::AtomicLoadOr8);
    1553             :     EXPAND(AVR::AtomicLoadOr16);
    1554       12451 :     EXPAND(AVR::AtomicLoadXor8);
    1555             :     EXPAND(AVR::AtomicLoadXor16);
    1556       12451 :     EXPAND(AVR::AtomicFence);
    1557             :     EXPAND(AVR::STSWKRr);
    1558             :     EXPAND(AVR::STWPtrRr);
    1559             :     EXPAND(AVR::STWPtrPiRr);
    1560             :     EXPAND(AVR::STWPtrPdRr);
    1561             :     EXPAND(AVR::STDWPtrQRr);
    1562       12451 :     EXPAND(AVR::INWRdA);
    1563          13 :     EXPAND(AVR::OUTWARr);
    1564           9 :     EXPAND(AVR::PUSHWRr);
    1565          11 :     EXPAND(AVR::POPWRd);
    1566          37 :     EXPAND(AVR::LSLWRd);
    1567           5 :     EXPAND(AVR::LSRWRd);
    1568          17 :     EXPAND(AVR::RORWRd);
    1569           9 :     EXPAND(AVR::ROLWRd);
    1570          22 :     EXPAND(AVR::ASRWRd);
    1571          29 :     EXPAND(AVR::SEXT);
    1572          14 :     EXPAND(AVR::ZEXT);
    1573          22 :     EXPAND(AVR::SPREAD);
    1574           8 :     EXPAND(AVR::SPWRITE);
    1575          45 :   }
    1576          36 : #undef EXPAND
    1577         249 :   return false;
    1578          33 : }
    1579          19 : 
    1580           7 : } // end of anonymous namespace
    1581           2 : 
    1582             : INITIALIZE_PASS(AVRExpandPseudo, "avr-expand-pseudo",
    1583         113 :                 AVR_EXPAND_PSEUDO_NAME, false, false)
    1584           1 : namespace llvm {
    1585             : 
    1586           1 : FunctionPass *createAVRExpandPseudoPass() { return new AVRExpandPseudo(); }
    1587           3 : 
    1588           1 : } // end of namespace llvm

Generated by: LCOV version 1.13