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