LLVM 24.0.0git
AVRExpandPseudoInsts.cpp
Go to the documentation of this file.
1//===-- AVRExpandPseudoInsts.cpp - Expand pseudo instructions -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains a pass that expands pseudo instructions into target
10// instructions. This pass should be run after register allocation but before
11// the post-regalloc scheduling pass.
12//
13//===----------------------------------------------------------------------===//
14
15#include "AVR.h"
16#include "AVRInstrInfo.h"
18#include "AVRTargetMachine.h"
20
25
26using namespace llvm;
27
28#define AVR_EXPAND_PSEUDO_NAME "AVR pseudo instruction expansion pass"
29
30namespace {
31
32/// Expands "placeholder" instructions marked as pseudo into
33/// actual AVR instructions.
34class AVRExpandPseudo : public MachineFunctionPass {
35public:
36 static char ID;
37
38 AVRExpandPseudo() : MachineFunctionPass(ID) {}
39
40 bool runOnMachineFunction(MachineFunction &MF) override;
41
42 StringRef getPassName() const override { return AVR_EXPAND_PSEUDO_NAME; }
43
44private:
46 typedef Block::iterator BlockIt;
47
48 const AVRRegisterInfo *TRI;
49 const TargetInstrInfo *TII;
50
51 bool expandMBB(Block &MBB);
52 bool expandMI(Block &MBB, BlockIt MBBI);
53 template <unsigned OP> bool expand(Block &MBB, BlockIt MBBI);
54
55 MachineInstrBuilder buildMI(Block &MBB, BlockIt MBBI, unsigned Opcode) {
56 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opcode));
57 }
58
59 MachineInstrBuilder buildMI(Block &MBB, BlockIt MBBI, unsigned Opcode,
60 Register DstReg) {
61 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opcode), DstReg);
62 }
63
64 MachineRegisterInfo &getRegInfo(Block &MBB) {
65 return MBB.getParent()->getRegInfo();
66 }
67
68 bool expandArith(unsigned OpLo, unsigned OpHi, Block &MBB, BlockIt MBBI);
69 bool expandLogic(unsigned Op, Block &MBB, BlockIt MBBI);
70 bool expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI);
71 bool isLogicImmOpRedundant(unsigned Op, unsigned ImmVal) const;
72 bool isLogicRegOpUndef(unsigned Op, unsigned ImmVal) const;
73
74 template <typename Func> bool expandAtomic(Block &MBB, BlockIt MBBI, Func f);
75
76 template <typename Func>
77 bool expandAtomicBinaryOp(unsigned Opcode, Block &MBB, BlockIt MBBI, Func f);
78
79 bool expandAtomicBinaryOp(unsigned Opcode, Block &MBB, BlockIt MBBI);
80
81 /// Specific shift implementation for int8.
82 bool expandLSLB7Rd(Block &MBB, BlockIt MBBI);
83 bool expandLSRB7Rd(Block &MBB, BlockIt MBBI);
84 bool expandASRB6Rd(Block &MBB, BlockIt MBBI);
85 bool expandASRB7Rd(Block &MBB, BlockIt MBBI);
86
87 /// Specific shift implementation for int16.
88 bool expandLSLW4Rd(Block &MBB, BlockIt MBBI);
89 bool expandLSRW4Rd(Block &MBB, BlockIt MBBI);
90 bool expandASRW7Rd(Block &MBB, BlockIt MBBI);
91 bool expandLSLW8Rd(Block &MBB, BlockIt MBBI);
92 bool expandLSRW8Rd(Block &MBB, BlockIt MBBI);
93 bool expandASRW8Rd(Block &MBB, BlockIt MBBI);
94 bool expandLSLW12Rd(Block &MBB, BlockIt MBBI);
95 bool expandLSRW12Rd(Block &MBB, BlockIt MBBI);
96 bool expandASRW14Rd(Block &MBB, BlockIt MBBI);
97 bool expandASRW15Rd(Block &MBB, BlockIt MBBI);
98
99 // Common implementation of LPMWRdZ and ELPMWRdZ.
100 bool expandLPMWELPMW(Block &MBB, BlockIt MBBI, bool IsELPM);
101 // Common implementation of LPMBRdZ and ELPMBRdZ.
102 bool expandLPMBELPMB(Block &MBB, BlockIt MBBI, bool IsELPM);
103 // Common implementation of ROLBRdR1 and ROLBRdR17.
104 bool expandROLBRd(Block &MBB, BlockIt MBBI);
105};
106
107char AVRExpandPseudo::ID = 0;
108
109bool AVRExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
110 bool Modified = false;
111
112 BlockIt MBBI = MBB.begin(), E = MBB.end();
113 while (MBBI != E) {
114 BlockIt NMBBI = std::next(MBBI);
115 Modified |= expandMI(MBB, MBBI);
116 MBBI = NMBBI;
117 }
118
119 return Modified;
120}
121
122bool AVRExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
123 bool Modified = false;
124
125 const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
126 TRI = STI.getRegisterInfo();
127 TII = STI.getInstrInfo();
128
129 for (Block &MBB : MF) {
130 bool ContinueExpanding = true;
131 unsigned ExpandCount = 0;
132
133 // Continue expanding the block until all pseudos are expanded.
134 do {
135 assert(ExpandCount < 10 && "pseudo expand limit reached");
136 (void)ExpandCount;
137
138 bool BlockModified = expandMBB(MBB);
139 Modified |= BlockModified;
140 ExpandCount++;
141
142 ContinueExpanding = BlockModified;
143 } while (ContinueExpanding);
144 }
145
146 return Modified;
147}
148
149bool AVRExpandPseudo::expandArith(unsigned OpLo, unsigned OpHi, Block &MBB,
150 BlockIt MBBI) {
151 MachineInstr &MI = *MBBI;
152 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
153 Register DstReg = MI.getOperand(0).getReg();
154 Register SrcReg = MI.getOperand(2).getReg();
155 bool DstIsDead = MI.getOperand(0).isDead();
156 bool DstIsKill = MI.getOperand(1).isKill();
157 bool SrcIsKill = MI.getOperand(2).isKill();
158 bool ImpIsDead = MI.getOperand(3).isDead();
159 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
160 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
161
162 buildMI(MBB, MBBI, OpLo)
163 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
164 .addReg(DstLoReg, getKillRegState(DstIsKill))
165 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
166
167 auto MIBHI =
168 buildMI(MBB, MBBI, OpHi)
169 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
170 .addReg(DstHiReg, getKillRegState(DstIsKill))
171 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
172
173 if (ImpIsDead)
174 MIBHI->getOperand(3).setIsDead();
175
176 // SREG is always implicitly killed
177 MIBHI->getOperand(4).setIsKill();
178
179 MI.eraseFromParent();
180 return true;
181}
182
183bool AVRExpandPseudo::expandLogic(unsigned Op, Block &MBB, BlockIt MBBI) {
184 MachineInstr &MI = *MBBI;
185 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
186 Register DstReg = MI.getOperand(0).getReg();
187 Register SrcReg = MI.getOperand(2).getReg();
188 bool DstIsDead = MI.getOperand(0).isDead();
189 bool DstIsKill = MI.getOperand(1).isKill();
190 bool SrcIsKill = MI.getOperand(2).isKill();
191 bool ImpIsDead = MI.getOperand(3).isDead();
192 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
193 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
194
195 auto MIBLO =
196 buildMI(MBB, MBBI, Op)
197 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
198 .addReg(DstLoReg, getKillRegState(DstIsKill))
199 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
200
201 // SREG is always implicitly dead
202 MIBLO->getOperand(3).setIsDead();
203
204 auto MIBHI =
205 buildMI(MBB, MBBI, Op)
206 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
207 .addReg(DstHiReg, getKillRegState(DstIsKill))
208 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
209
210 if (ImpIsDead)
211 MIBHI->getOperand(3).setIsDead();
212
213 MI.eraseFromParent();
214 return true;
215}
216
217bool AVRExpandPseudo::isLogicImmOpRedundant(unsigned Op,
218 unsigned ImmVal) const {
219
220 // ANDI Rd, 0xff is redundant.
221 if (Op == AVR::ANDIRdK && ImmVal == 0xff)
222 return true;
223
224 // ORI Rd, 0x0 is redundant.
225 if (Op == AVR::ORIRdK && ImmVal == 0x0)
226 return true;
227
228 return false;
229}
230
231bool AVRExpandPseudo::isLogicRegOpUndef(unsigned Op, unsigned ImmVal) const {
232 // ANDI Rd, 0x00 clears all input bits.
233 if (Op == AVR::ANDIRdK && ImmVal == 0x00)
234 return true;
235
236 // ORI Rd, 0xff sets all input bits.
237 if (Op == AVR::ORIRdK && ImmVal == 0xff)
238 return true;
239
240 return false;
241}
242
243bool AVRExpandPseudo::expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI) {
244 MachineInstr &MI = *MBBI;
245 Register DstLoReg, DstHiReg;
246 Register DstReg = MI.getOperand(0).getReg();
247 bool DstIsDead = MI.getOperand(0).isDead();
248 bool SrcIsKill = MI.getOperand(1).isKill();
249 bool ImpIsDead = MI.getOperand(3).isDead();
250 unsigned Imm = MI.getOperand(2).getImm();
251 unsigned Lo8 = Imm & 0xff;
252 unsigned Hi8 = (Imm >> 8) & 0xff;
253 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
254
255 if (!isLogicImmOpRedundant(Op, Lo8)) {
256 auto MIBLO =
257 buildMI(MBB, MBBI, Op)
258 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
259 .addReg(DstLoReg, getKillRegState(SrcIsKill))
260 .addImm(Lo8);
261
262 // SREG is always implicitly dead
263 MIBLO->getOperand(3).setIsDead();
264
265 if (isLogicRegOpUndef(Op, Lo8))
266 MIBLO->getOperand(1).setIsUndef(true);
267 }
268
269 if (!isLogicImmOpRedundant(Op, Hi8)) {
270 auto MIBHI =
271 buildMI(MBB, MBBI, Op)
272 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
273 .addReg(DstHiReg, getKillRegState(SrcIsKill))
274 .addImm(Hi8);
275
276 if (ImpIsDead)
277 MIBHI->getOperand(3).setIsDead();
278
279 if (isLogicRegOpUndef(Op, Hi8))
280 MIBHI->getOperand(1).setIsUndef(true);
281 }
282
283 MI.eraseFromParent();
284 return true;
285}
286
287template <>
288bool AVRExpandPseudo::expand<AVR::ADDWRdRr>(Block &MBB, BlockIt MBBI) {
289 return expandArith(AVR::ADDRdRr, AVR::ADCRdRr, MBB, MBBI);
290}
291
292template <>
293bool AVRExpandPseudo::expand<AVR::ADCWRdRr>(Block &MBB, BlockIt MBBI) {
294 return expandArith(AVR::ADCRdRr, AVR::ADCRdRr, MBB, MBBI);
295}
296
297template <>
298bool AVRExpandPseudo::expand<AVR::ADIWRdKP>(Block &MBB, BlockIt MBBI) {
299 const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
300 MachineInstr &MI = *MBBI;
301 Register DstReg = MI.getOperand(0).getReg();
302 Register SrcReg = MI.getOperand(1).getReg();
303 int64_t Imm = MI.getOperand(2).getImm();
304 unsigned Opcode;
305
306 if (SrcReg != DstReg) {
307 TII->copyPhysReg(MBB, MI, MI.getDebugLoc(), DstReg, SrcReg, false, false,
308 false);
309 }
310
311 if (isUInt<6>(Imm) && STI.hasADDSUBIW() &&
312 AVR::IWREGSRegClass.contains(DstReg)) {
313 Opcode = AVR::ADIWRdK;
314 } else {
315 Opcode = AVR::SUBIWRdK;
316 Imm = -Imm;
317 }
318
319 buildMI(MBB, MI, Opcode)
320 .addReg(DstReg, RegState::Define)
321 .addReg(DstReg, RegState::Kill)
322 .addImm(Imm)
323 .setOperandDead(3); // implicit-def $sreg
324
325 MI.eraseFromParent();
326 return true;
327}
328
329template <>
330bool AVRExpandPseudo::expand<AVR::SUBWRdRr>(Block &MBB, BlockIt MBBI) {
331 return expandArith(AVR::SUBRdRr, AVR::SBCRdRr, MBB, MBBI);
332}
333
334template <>
335bool AVRExpandPseudo::expand<AVR::SUBIWRdK>(Block &MBB, BlockIt MBBI) {
336 MachineInstr &MI = *MBBI;
337 Register DstLoReg, DstHiReg;
338 Register DstReg = MI.getOperand(0).getReg();
339 bool DstIsDead = MI.getOperand(0).isDead();
340 bool SrcIsKill = MI.getOperand(1).isKill();
341 bool ImpIsDead = MI.getOperand(3).isDead();
342 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
343
344 auto MIBLO =
345 buildMI(MBB, MBBI, AVR::SUBIRdK)
346 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
347 .addReg(DstLoReg, getKillRegState(SrcIsKill));
348
349 auto MIBHI =
350 buildMI(MBB, MBBI, AVR::SBCIRdK)
351 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
352 .addReg(DstHiReg, getKillRegState(SrcIsKill));
353
354 switch (MI.getOperand(2).getType()) {
356 const GlobalValue *GV = MI.getOperand(2).getGlobal();
357 int64_t Offs = MI.getOperand(2).getOffset();
358 unsigned TF = MI.getOperand(2).getTargetFlags();
359 MIBLO.addGlobalAddress(GV, Offs, TF | AVRII::MO_NEG | AVRII::MO_LO);
360 MIBHI.addGlobalAddress(GV, Offs, TF | AVRII::MO_NEG | AVRII::MO_HI);
361 break;
362 }
364 unsigned Imm = MI.getOperand(2).getImm();
365 MIBLO.addImm(Imm & 0xff);
366 MIBHI.addImm((Imm >> 8) & 0xff);
367 break;
368 }
369 default:
370 llvm_unreachable("Unknown operand type!");
371 }
372
373 if (ImpIsDead)
374 MIBHI->getOperand(3).setIsDead();
375
376 // SREG is always implicitly killed
377 MIBHI->getOperand(4).setIsKill();
378
379 MI.eraseFromParent();
380 return true;
381}
382
383template <>
384bool AVRExpandPseudo::expand<AVR::SBCWRdRr>(Block &MBB, BlockIt MBBI) {
385 return expandArith(AVR::SBCRdRr, AVR::SBCRdRr, MBB, MBBI);
386}
387
388template <>
389bool AVRExpandPseudo::expand<AVR::SBCIWRdK>(Block &MBB, BlockIt MBBI) {
390 MachineInstr &MI = *MBBI;
391 Register DstLoReg, DstHiReg;
392 Register DstReg = MI.getOperand(0).getReg();
393 bool DstIsDead = MI.getOperand(0).isDead();
394 bool SrcIsKill = MI.getOperand(1).isKill();
395 bool ImpIsDead = MI.getOperand(3).isDead();
396 unsigned Imm = MI.getOperand(2).getImm();
397 unsigned Lo8 = Imm & 0xff;
398 unsigned Hi8 = (Imm >> 8) & 0xff;
399 unsigned OpLo = AVR::SBCIRdK;
400 unsigned OpHi = AVR::SBCIRdK;
401 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
402
403 auto MIBLO =
404 buildMI(MBB, MBBI, OpLo)
405 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
406 .addReg(DstLoReg, getKillRegState(SrcIsKill))
407 .addImm(Lo8);
408
409 // SREG is always implicitly killed
410 MIBLO->getOperand(4).setIsKill();
411
412 auto MIBHI =
413 buildMI(MBB, MBBI, OpHi)
414 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
415 .addReg(DstHiReg, getKillRegState(SrcIsKill))
416 .addImm(Hi8);
417
418 if (ImpIsDead)
419 MIBHI->getOperand(3).setIsDead();
420
421 // SREG is always implicitly killed
422 MIBHI->getOperand(4).setIsKill();
423
424 MI.eraseFromParent();
425 return true;
426}
427
428template <>
429bool AVRExpandPseudo::expand<AVR::ANDWRdRr>(Block &MBB, BlockIt MBBI) {
430 return expandLogic(AVR::ANDRdRr, MBB, MBBI);
431}
432
433template <>
434bool AVRExpandPseudo::expand<AVR::ANDIWRdK>(Block &MBB, BlockIt MBBI) {
435 return expandLogicImm(AVR::ANDIRdK, MBB, MBBI);
436}
437
438template <>
439bool AVRExpandPseudo::expand<AVR::ORWRdRr>(Block &MBB, BlockIt MBBI) {
440 return expandLogic(AVR::ORRdRr, MBB, MBBI);
441}
442
443template <>
444bool AVRExpandPseudo::expand<AVR::ORIWRdK>(Block &MBB, BlockIt MBBI) {
445 return expandLogicImm(AVR::ORIRdK, MBB, MBBI);
446}
447
448template <>
449bool AVRExpandPseudo::expand<AVR::EORWRdRr>(Block &MBB, BlockIt MBBI) {
450 return expandLogic(AVR::EORRdRr, MBB, MBBI);
451}
452
453template <>
454bool AVRExpandPseudo::expand<AVR::COMWRd>(Block &MBB, BlockIt MBBI) {
455 MachineInstr &MI = *MBBI;
456 Register DstLoReg, DstHiReg;
457 Register DstReg = MI.getOperand(0).getReg();
458 bool DstIsDead = MI.getOperand(0).isDead();
459 bool DstIsKill = MI.getOperand(1).isKill();
460 bool ImpIsDead = MI.getOperand(2).isDead();
461 unsigned OpLo = AVR::COMRd;
462 unsigned OpHi = AVR::COMRd;
463 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
464
465 auto MIBLO =
466 buildMI(MBB, MBBI, OpLo)
467 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
468 .addReg(DstLoReg, getKillRegState(DstIsKill));
469
470 // SREG is always implicitly dead
471 MIBLO->getOperand(2).setIsDead();
472
473 auto MIBHI =
474 buildMI(MBB, MBBI, OpHi)
475 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
476 .addReg(DstHiReg, getKillRegState(DstIsKill));
477
478 if (ImpIsDead)
479 MIBHI->getOperand(2).setIsDead();
480
481 MI.eraseFromParent();
482 return true;
483}
484
485template <>
486bool AVRExpandPseudo::expand<AVR::NEGWRd>(Block &MBB, BlockIt MBBI) {
487 MachineInstr &MI = *MBBI;
488 Register DstLoReg, DstHiReg;
489 Register DstReg = MI.getOperand(0).getReg();
490 Register ZeroReg = MI.getOperand(2).getReg();
491 bool DstIsDead = MI.getOperand(0).isDead();
492 bool DstIsKill = MI.getOperand(1).isKill();
493 bool ImpIsDead = MI.getOperand(2).isDead();
494 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
495
496 // Do NEG on the upper byte.
497 auto MIBHI =
498 buildMI(MBB, MBBI, AVR::NEGRd)
499 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
500 .addReg(DstHiReg, RegState::Kill);
501 // SREG is always implicitly dead
502 MIBHI->getOperand(2).setIsDead();
503
504 // Do NEG on the lower byte.
505 buildMI(MBB, MBBI, AVR::NEGRd)
506 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
507 .addReg(DstLoReg, getKillRegState(DstIsKill));
508
509 // Do an extra SBC.
510 auto MISBCI =
511 buildMI(MBB, MBBI, AVR::SBCRdRr)
512 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
513 .addReg(DstHiReg, getKillRegState(DstIsKill))
514 .addReg(ZeroReg);
515 if (ImpIsDead)
516 MISBCI->getOperand(3).setIsDead();
517 // SREG is always implicitly killed
518 MISBCI->getOperand(4).setIsKill();
519
520 MI.eraseFromParent();
521 return true;
522}
523
524template <>
525bool AVRExpandPseudo::expand<AVR::CPWRdRr>(Block &MBB, BlockIt MBBI) {
526 MachineInstr &MI = *MBBI;
527 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
528 Register DstReg = MI.getOperand(0).getReg();
529 Register SrcReg = MI.getOperand(1).getReg();
530 bool DstIsKill = MI.getOperand(0).isKill();
531 bool SrcIsKill = MI.getOperand(1).isKill();
532 bool ImpIsDead = MI.getOperand(2).isDead();
533 unsigned OpLo = AVR::CPRdRr;
534 unsigned OpHi = AVR::CPCRdRr;
535 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
536 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
537
538 // Low part
539 buildMI(MBB, MBBI, OpLo)
540 .addReg(DstLoReg, getKillRegState(DstIsKill))
541 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
542
543 auto MIBHI = buildMI(MBB, MBBI, OpHi)
544 .addReg(DstHiReg, getKillRegState(DstIsKill))
545 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
546
547 if (ImpIsDead)
548 MIBHI->getOperand(2).setIsDead();
549
550 // SREG is always implicitly killed
551 MIBHI->getOperand(3).setIsKill();
552
553 MI.eraseFromParent();
554 return true;
555}
556
557template <>
558bool AVRExpandPseudo::expand<AVR::CPCWRdRr>(Block &MBB, BlockIt MBBI) {
559 MachineInstr &MI = *MBBI;
560 Register SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
561 Register DstReg = MI.getOperand(0).getReg();
562 Register SrcReg = MI.getOperand(1).getReg();
563 bool DstIsKill = MI.getOperand(0).isKill();
564 bool SrcIsKill = MI.getOperand(1).isKill();
565 bool ImpIsDead = MI.getOperand(2).isDead();
566 unsigned OpLo = AVR::CPCRdRr;
567 unsigned OpHi = AVR::CPCRdRr;
568 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
569 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
570
571 auto MIBLO = buildMI(MBB, MBBI, OpLo)
572 .addReg(DstLoReg, getKillRegState(DstIsKill))
573 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
574
575 // SREG is always implicitly killed
576 MIBLO->getOperand(3).setIsKill();
577
578 auto MIBHI = buildMI(MBB, MBBI, OpHi)
579 .addReg(DstHiReg, getKillRegState(DstIsKill))
580 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
581
582 if (ImpIsDead)
583 MIBHI->getOperand(2).setIsDead();
584
585 // SREG is always implicitly killed
586 MIBHI->getOperand(3).setIsKill();
587
588 MI.eraseFromParent();
589 return true;
590}
591
592template <>
593bool AVRExpandPseudo::expand<AVR::LDIWRdK>(Block &MBB, BlockIt MBBI) {
594 MachineInstr &MI = *MBBI;
595 Register DstLoReg, DstHiReg;
596 Register DstReg = MI.getOperand(0).getReg();
597 bool DstIsDead = MI.getOperand(0).isDead();
598 unsigned OpLo = AVR::LDIRdK;
599 unsigned OpHi = AVR::LDIRdK;
600 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
601
602 auto MIBLO =
603 buildMI(MBB, MBBI, OpLo)
604 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead));
605
606 auto MIBHI =
607 buildMI(MBB, MBBI, OpHi)
608 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead));
609
610 switch (MI.getOperand(1).getType()) {
612 const GlobalValue *GV = MI.getOperand(1).getGlobal();
613 int64_t Offs = MI.getOperand(1).getOffset();
614 unsigned TF = MI.getOperand(1).getTargetFlags();
615
616 MIBLO.addGlobalAddress(GV, Offs, TF | AVRII::MO_LO);
617 MIBHI.addGlobalAddress(GV, Offs, TF | AVRII::MO_HI);
618 break;
619 }
621 const BlockAddress *BA = MI.getOperand(1).getBlockAddress();
622 unsigned TF = MI.getOperand(1).getTargetFlags();
623
624 MIBLO.add(MachineOperand::CreateBA(BA, TF | AVRII::MO_LO));
625 MIBHI.add(MachineOperand::CreateBA(BA, TF | AVRII::MO_HI));
626 break;
627 }
629 unsigned Imm = MI.getOperand(1).getImm();
630
631 MIBLO.addImm(Imm & 0xff);
632 MIBHI.addImm((Imm >> 8) & 0xff);
633 break;
634 }
635 default:
636 llvm_unreachable("Unknown operand type!");
637 }
638
639 MI.eraseFromParent();
640 return true;
641}
642
643template <>
644bool AVRExpandPseudo::expand<AVR::LDSWRdK>(Block &MBB, BlockIt MBBI) {
645 MachineInstr &MI = *MBBI;
646 Register DstLoReg, DstHiReg;
647 Register DstReg = MI.getOperand(0).getReg();
648 bool DstIsDead = MI.getOperand(0).isDead();
649 unsigned OpLo = AVR::LDSRdK;
650 unsigned OpHi = AVR::LDSRdK;
651 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
652
653 auto MIBLO =
654 buildMI(MBB, MBBI, OpLo)
655 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead));
656
657 auto MIBHI =
658 buildMI(MBB, MBBI, OpHi)
659 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead));
660
661 switch (MI.getOperand(1).getType()) {
663 const GlobalValue *GV = MI.getOperand(1).getGlobal();
664 int64_t Offs = MI.getOperand(1).getOffset();
665 unsigned TF = MI.getOperand(1).getTargetFlags();
666
667 MIBLO.addGlobalAddress(GV, Offs, TF);
668 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
669 break;
670 }
672 unsigned Imm = MI.getOperand(1).getImm();
673
674 MIBLO.addImm(Imm);
675 MIBHI.addImm(Imm + 1);
676 break;
677 }
678 default:
679 llvm_unreachable("Unknown operand type!");
680 }
681
682 MIBLO.setMemRefs(MI.memoperands());
683 MIBHI.setMemRefs(MI.memoperands());
684
685 MI.eraseFromParent();
686 return true;
687}
688
689template <>
690bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) {
691 MachineInstr &MI = *MBBI;
692 Register DstReg = MI.getOperand(0).getReg();
693 Register SrcReg = MI.getOperand(1).getReg();
694 bool DstIsKill = MI.getOperand(0).isKill();
695 bool SrcIsKill = MI.getOperand(1).isKill();
696 const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
697
698 // DstReg has an earlyclobber so the register allocator will allocate them in
699 // separate registers.
700 assert(DstReg != SrcReg && "Dst and Src registers are the same!");
701
702 if (STI.hasTinyEncoding()) {
703 // Handle this case in the expansion of LDDWRdPtrQ because it is very
704 // similar.
705 buildMI(MBB, MBBI, AVR::LDDWRdPtrQ)
706 .addDef(DstReg, getKillRegState(DstIsKill))
707 .addReg(SrcReg, getKillRegState(SrcIsKill))
708 .addImm(0)
709 .setMemRefs(MI.memoperands());
710
711 } else {
712 Register DstLoReg, DstHiReg;
713 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
714
715 // Load low byte.
716 buildMI(MBB, MBBI, AVR::LDRdPtr)
717 .addReg(DstLoReg, RegState::Define)
718 .addReg(SrcReg)
719 .setMemRefs(MI.memoperands());
720
721 // Load high byte.
722 buildMI(MBB, MBBI, AVR::LDDRdPtrQ)
723 .addReg(DstHiReg, RegState::Define)
724 .addReg(SrcReg, getKillRegState(SrcIsKill))
725 .addImm(1)
726 .setMemRefs(MI.memoperands());
727 }
728
729 MI.eraseFromParent();
730 return true;
731}
732
733template <>
734bool AVRExpandPseudo::expand<AVR::LDWRdPtrPi>(Block &MBB, BlockIt MBBI) {
735 MachineInstr &MI = *MBBI;
736 Register DstLoReg, DstHiReg;
737 Register DstReg = MI.getOperand(0).getReg();
738 Register SrcReg = MI.getOperand(1).getReg();
739 bool DstIsDead = MI.getOperand(0).isDead();
740 bool SrcIsDead = MI.getOperand(1).isKill();
741 unsigned OpLo = AVR::LDRdPtrPi;
742 unsigned OpHi = AVR::LDRdPtrPi;
743 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
744
745 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
746
747 auto MIBLO =
748 buildMI(MBB, MBBI, OpLo)
749 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
750 .addReg(SrcReg, RegState::Define)
751 .addReg(SrcReg, RegState::Kill);
752
753 auto MIBHI =
754 buildMI(MBB, MBBI, OpHi)
755 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
756 .addReg(SrcReg, RegState::Define | getDeadRegState(SrcIsDead))
757 .addReg(SrcReg, RegState::Kill);
758
759 MIBLO.setMemRefs(MI.memoperands());
760 MIBHI.setMemRefs(MI.memoperands());
761
762 MI.eraseFromParent();
763 return true;
764}
765
766template <>
767bool AVRExpandPseudo::expand<AVR::LDWRdPtrPd>(Block &MBB, BlockIt MBBI) {
768 MachineInstr &MI = *MBBI;
769 Register DstLoReg, DstHiReg;
770 Register DstReg = MI.getOperand(0).getReg();
771 Register SrcReg = MI.getOperand(1).getReg();
772 bool DstIsDead = MI.getOperand(0).isDead();
773 bool SrcIsDead = MI.getOperand(1).isKill();
774 unsigned OpLo = AVR::LDRdPtrPd;
775 unsigned OpHi = AVR::LDRdPtrPd;
776 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
777
778 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
779
780 auto MIBHI =
781 buildMI(MBB, MBBI, OpHi)
782 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
783 .addReg(SrcReg, RegState::Define)
784 .addReg(SrcReg, RegState::Kill);
785
786 auto MIBLO =
787 buildMI(MBB, MBBI, OpLo)
788 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
789 .addReg(SrcReg, RegState::Define | getDeadRegState(SrcIsDead))
790 .addReg(SrcReg, RegState::Kill);
791
792 MIBLO.setMemRefs(MI.memoperands());
793 MIBHI.setMemRefs(MI.memoperands());
794
795 MI.eraseFromParent();
796 return true;
797}
798
799template <>
800bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
801 MachineInstr &MI = *MBBI;
802 Register DstReg = MI.getOperand(0).getReg();
803 Register SrcReg = MI.getOperand(1).getReg();
804 unsigned Imm = MI.getOperand(2).getImm();
805 bool DstIsKill = MI.getOperand(0).isKill();
806 bool SrcIsKill = MI.getOperand(1).isKill();
807 const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
808
809 // Since we add 1 to the Imm value for the high byte below, and 63 is the
810 // highest Imm value allowed for the instruction, 62 is the limit here.
811 assert(Imm <= 62 && "Offset is out of range");
812
813 // DstReg has an earlyclobber so the register allocator will allocate them in
814 // separate registers.
815 assert(DstReg != SrcReg && "Dst and Src registers are the same!");
816
817 if (STI.hasTinyEncoding()) {
818 // Reduced tiny cores don't support load/store with displacement. However,
819 // they do support postincrement. So we'll simply adjust the pointer before
820 // and after and use postincrement to load multiple registers.
821
822 // Add offset. The offset can be 0 when expanding this instruction from the
823 // more specific LDWRdPtr instruction.
824 if (Imm != 0) {
825 buildMI(MBB, MBBI, AVR::SUBIWRdK, SrcReg)
826 .addReg(SrcReg)
827 .addImm(0x10000 - Imm);
828 }
829
830 // Do a word load with postincrement. This will be lowered to a two byte
831 // load.
832 buildMI(MBB, MBBI, AVR::LDWRdPtrPi)
833 .addDef(DstReg, getKillRegState(DstIsKill))
834 .addReg(SrcReg, getKillRegState(SrcIsKill))
835 .addImm(0)
836 .setMemRefs(MI.memoperands());
837
838 // If the pointer is used after the store instruction, subtract the new
839 // offset (with 2 added after the postincrement instructions) so it is the
840 // same as before.
841 if (!SrcIsKill) {
842 buildMI(MBB, MBBI, AVR::SUBIWRdK, SrcReg).addReg(SrcReg).addImm(Imm + 2);
843 }
844 } else {
845 Register DstLoReg, DstHiReg;
846 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
847
848 // Load low byte.
849 buildMI(MBB, MBBI, AVR::LDDRdPtrQ)
850 .addReg(DstLoReg, RegState::Define)
851 .addReg(SrcReg)
852 .addImm(Imm)
853 .setMemRefs(MI.memoperands());
854
855 // Load high byte.
856 buildMI(MBB, MBBI, AVR::LDDRdPtrQ)
857 .addReg(DstHiReg, RegState::Define)
858 .addReg(SrcReg, getKillRegState(SrcIsKill))
859 .addImm(Imm + 1)
860 .setMemRefs(MI.memoperands());
861 }
862
863 MI.eraseFromParent();
864 return true;
865}
866
867bool AVRExpandPseudo::expandLPMWELPMW(Block &MBB, BlockIt MBBI, bool IsELPM) {
868 MachineInstr &MI = *MBBI;
869 Register DstLoReg, DstHiReg;
870 Register DstReg = MI.getOperand(0).getReg();
871 Register SrcReg = MI.getOperand(1).getReg();
872 Register SrcLoReg, SrcHiReg;
873 bool SrcIsKill = MI.getOperand(1).isKill();
874 const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
875 bool IsLPMRn = IsELPM ? STI.hasELPMX() : STI.hasLPMX();
876
877 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
878 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
879
880 // Set the I/O register RAMPZ for ELPM.
881 if (IsELPM) {
882 Register Bank = MI.getOperand(2).getReg();
883 // out RAMPZ, rtmp
884 buildMI(MBB, MBBI, AVR::OUTARr).addImm(STI.getIORegRAMPZ()).addReg(Bank);
885 }
886
887 // This is enforced by the @earlyclobber constraint.
888 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
889
890 if (IsLPMRn) {
891 unsigned OpLo = IsELPM ? AVR::ELPMRdZPi : AVR::LPMRdZPi;
892 unsigned OpHi = IsELPM ? AVR::ELPMRdZ : AVR::LPMRdZ;
893 // Load low byte.
894 auto MIBLO = buildMI(MBB, MBBI, OpLo)
895 .addReg(DstLoReg, RegState::Define)
896 .addReg(SrcReg);
897 // Load high byte.
898 auto MIBHI = buildMI(MBB, MBBI, OpHi)
899 .addReg(DstHiReg, RegState::Define)
900 .addReg(SrcReg, getKillRegState(SrcIsKill));
901 MIBLO.setMemRefs(MI.memoperands());
902 MIBHI.setMemRefs(MI.memoperands());
903 } else {
904 unsigned Opc = IsELPM ? AVR::ELPM : AVR::LPM;
905 // Load low byte, and copy to the low destination register.
906 auto MIBLO = buildMI(MBB, MBBI, Opc);
907 buildMI(MBB, MBBI, AVR::MOVRdRr)
908 .addReg(DstLoReg, RegState::Define)
909 .addReg(STI.getTmpRegister(), RegState::Kill);
910 MIBLO.setMemRefs(MI.memoperands());
911 // Increase the Z register by 1.
912 if (STI.hasADDSUBIW()) {
913 // adiw r31:r30, 1
914 auto MIINC = buildMI(MBB, MBBI, AVR::ADIWRdK)
915 .addReg(SrcReg, RegState::Define)
916 .addReg(SrcReg, getKillRegState(SrcIsKill))
917 .addImm(1);
918 MIINC->getOperand(3).setIsDead();
919 } else {
920 // subi r30, 255
921 // sbci r31, 255
922 buildMI(MBB, MBBI, AVR::SUBIRdK)
923 .addReg(SrcLoReg, RegState::Define)
924 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
925 .addImm(255);
926 auto MIZHI = buildMI(MBB, MBBI, AVR::SBCIRdK)
927 .addReg(SrcHiReg, RegState::Define)
928 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
929 .addImm(255);
930 MIZHI->getOperand(3).setIsDead();
931 MIZHI->getOperand(4).setIsKill();
932 }
933 // Load high byte, and copy to the high destination register.
934 auto MIBHI = buildMI(MBB, MBBI, Opc);
935 buildMI(MBB, MBBI, AVR::MOVRdRr)
936 .addReg(DstHiReg, RegState::Define)
937 .addReg(STI.getTmpRegister(), RegState::Kill);
938 MIBHI.setMemRefs(MI.memoperands());
939 }
940
941 // Restore the Z register if it is not killed.
942 if (!SrcIsKill) {
943 if (STI.hasADDSUBIW()) {
944 // sbiw r31:r30, 1
945 auto MIDEC = buildMI(MBB, MBBI, AVR::SBIWRdK)
946 .addReg(SrcReg, RegState::Define)
947 .addReg(SrcReg, getKillRegState(SrcIsKill))
948 .addImm(1);
949 MIDEC->getOperand(3).setIsDead();
950 } else {
951 // subi r30, 1
952 // sbci r31, 0
953 buildMI(MBB, MBBI, AVR::SUBIRdK)
954 .addReg(SrcLoReg, RegState::Define)
955 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
956 .addImm(1);
957 auto MIZHI = buildMI(MBB, MBBI, AVR::SBCIRdK)
958 .addReg(SrcHiReg, RegState::Define)
959 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
960 .addImm(0);
961 MIZHI->getOperand(3).setIsDead();
962 MIZHI->getOperand(4).setIsKill();
963 }
964 }
965
966 MI.eraseFromParent();
967 return true;
968}
969
970template <>
971bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(Block &MBB, BlockIt MBBI) {
972 return expandLPMWELPMW(MBB, MBBI, false);
973}
974
975template <>
976bool AVRExpandPseudo::expand<AVR::ELPMWRdZ>(Block &MBB, BlockIt MBBI) {
977 return expandLPMWELPMW(MBB, MBBI, true);
978}
979
980bool AVRExpandPseudo::expandLPMBELPMB(Block &MBB, BlockIt MBBI, bool IsELPM) {
981 MachineInstr &MI = *MBBI;
982 Register DstReg = MI.getOperand(0).getReg();
983 Register SrcReg = MI.getOperand(1).getReg();
984 bool SrcIsKill = MI.getOperand(1).isKill();
985 const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
986 bool IsLPMRn = IsELPM ? STI.hasELPMX() : STI.hasLPMX();
987
988 // Set the I/O register RAMPZ for ELPM (out RAMPZ, rtmp).
989 if (IsELPM) {
990 Register BankReg = MI.getOperand(2).getReg();
991 buildMI(MBB, MBBI, AVR::OUTARr).addImm(STI.getIORegRAMPZ()).addReg(BankReg);
992 }
993
994 // Load byte.
995 if (IsLPMRn) {
996 unsigned Opc = IsELPM ? AVR::ELPMRdZ : AVR::LPMRdZ;
997 auto MILB = buildMI(MBB, MBBI, Opc)
998 .addReg(DstReg, RegState::Define)
999 .addReg(SrcReg, getKillRegState(SrcIsKill));
1000 MILB.setMemRefs(MI.memoperands());
1001 } else {
1002 // For the basic ELPM/LPM instruction, its operand[0] is the implicit
1003 // 'Z' register, and its operand[1] is the implicit 'R0' register.
1004 unsigned Opc = IsELPM ? AVR::ELPM : AVR::LPM;
1005 auto MILB = buildMI(MBB, MBBI, Opc);
1006 buildMI(MBB, MBBI, AVR::MOVRdRr)
1007 .addReg(DstReg, RegState::Define)
1008 .addReg(STI.getTmpRegister(), RegState::Kill);
1009 MILB.setMemRefs(MI.memoperands());
1010 }
1011
1012 MI.eraseFromParent();
1013 return true;
1014}
1015
1016template <>
1017bool AVRExpandPseudo::expand<AVR::ELPMBRdZ>(Block &MBB, BlockIt MBBI) {
1018 return expandLPMBELPMB(MBB, MBBI, true);
1019}
1020
1021template <>
1022bool AVRExpandPseudo::expand<AVR::LPMBRdZ>(Block &MBB, BlockIt MBBI) {
1023 return expandLPMBELPMB(MBB, MBBI, false);
1024}
1025
1026template <>
1027bool AVRExpandPseudo::expand<AVR::LPMWRdZPi>(Block &MBB, BlockIt MBBI) {
1028 llvm_unreachable("16-bit LPMPi is unimplemented");
1029}
1030
1031template <>
1032bool AVRExpandPseudo::expand<AVR::ELPMBRdZPi>(Block &MBB, BlockIt MBBI) {
1033 llvm_unreachable("8-bit ELPMPi is unimplemented");
1034}
1035
1036template <>
1037bool AVRExpandPseudo::expand<AVR::ELPMWRdZPi>(Block &MBB, BlockIt MBBI) {
1038 llvm_unreachable("16-bit ELPMPi is unimplemented");
1039}
1040
1041template <typename Func>
1042bool AVRExpandPseudo::expandAtomic(Block &MBB, BlockIt MBBI, Func f) {
1043 MachineInstr &MI = *MBBI;
1044 const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
1045
1046 // Store the SREG.
1047 buildMI(MBB, MBBI, AVR::INRdA)
1048 .addReg(STI.getTmpRegister(), RegState::Define)
1049 .addImm(STI.getIORegSREG());
1050
1051 // Disable exceptions.
1052 buildMI(MBB, MBBI, AVR::BCLRs).addImm(7); // CLI
1053
1054 f(MI);
1055
1056 // Restore the status reg.
1057 buildMI(MBB, MBBI, AVR::OUTARr)
1058 .addImm(STI.getIORegSREG())
1059 .addReg(STI.getTmpRegister());
1060
1061 MI.eraseFromParent();
1062 return true;
1063}
1064
1065template <typename Func>
1066bool AVRExpandPseudo::expandAtomicBinaryOp(unsigned Opcode, Block &MBB,
1067 BlockIt MBBI, Func f) {
1068 return expandAtomic(MBB, MBBI, [&](MachineInstr &MI) {
1069 auto Op1 = MI.getOperand(0);
1070 auto Op2 = MI.getOperand(1);
1071
1072 MachineInstr &NewInst =
1073 *buildMI(MBB, MBBI, Opcode).add(Op1).add(Op2).getInstr();
1074 f(NewInst);
1075 });
1076}
1077
1078bool AVRExpandPseudo::expandAtomicBinaryOp(unsigned Opcode, Block &MBB,
1079 BlockIt MBBI) {
1080 return expandAtomicBinaryOp(Opcode, MBB, MBBI, [](MachineInstr &MI) {});
1081}
1082
1083template <>
1084bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(Block &MBB, BlockIt MBBI) {
1085 return expandAtomicBinaryOp(AVR::LDRdPtr, MBB, MBBI);
1086}
1087
1088template <>
1089bool AVRExpandPseudo::expand<AVR::AtomicLoad16>(Block &MBB, BlockIt MBBI) {
1090 return expandAtomicBinaryOp(AVR::LDWRdPtr, MBB, MBBI);
1091}
1092
1093template <>
1094bool AVRExpandPseudo::expand<AVR::AtomicStore8>(Block &MBB, BlockIt MBBI) {
1095 return expandAtomicBinaryOp(AVR::STPtrRr, MBB, MBBI);
1096}
1097
1098template <>
1099bool AVRExpandPseudo::expand<AVR::AtomicStore16>(Block &MBB, BlockIt MBBI) {
1100 return expandAtomicBinaryOp(AVR::STWPtrRr, MBB, MBBI);
1101}
1102
1103template <>
1104bool AVRExpandPseudo::expand<AVR::AtomicFence>(Block &MBB, BlockIt MBBI) {
1105 // On AVR, there is only one core and so atomic fences do nothing.
1106 MBBI->eraseFromParent();
1107 return true;
1108}
1109
1110template <>
1111bool AVRExpandPseudo::expand<AVR::STSWKRr>(Block &MBB, BlockIt MBBI) {
1112 const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
1113 MachineInstr &MI = *MBBI;
1114 Register SrcLoReg, SrcHiReg;
1115 Register SrcReg = MI.getOperand(1).getReg();
1116 bool SrcIsKill = MI.getOperand(1).isKill();
1117 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1118
1119 auto MIB0 = buildMI(MBB, MBBI, AVR::STSKRr);
1120 auto MIB1 = buildMI(MBB, MBBI, AVR::STSKRr);
1121
1122 switch (MI.getOperand(0).getType()) {
1124 const GlobalValue *GV = MI.getOperand(0).getGlobal();
1125 int64_t Offs = MI.getOperand(0).getOffset();
1126 unsigned TF = MI.getOperand(0).getTargetFlags();
1127
1128 if (STI.hasLowByteFirst()) {
1129 // Write the low byte first for XMEGA devices.
1130 MIB0.addGlobalAddress(GV, Offs, TF);
1131 MIB1.addGlobalAddress(GV, Offs + 1, TF);
1132 } else {
1133 // Write the high byte first for traditional devices.
1134 MIB0.addGlobalAddress(GV, Offs + 1, TF);
1135 MIB1.addGlobalAddress(GV, Offs, TF);
1136 }
1137
1138 break;
1139 }
1141 unsigned Imm = MI.getOperand(0).getImm();
1142
1143 if (STI.hasLowByteFirst()) {
1144 // Write the low byte first for XMEGA devices.
1145 MIB0.addImm(Imm);
1146 MIB1.addImm(Imm + 1);
1147 } else {
1148 // Write the high byte first for traditional devices.
1149 MIB0.addImm(Imm + 1);
1150 MIB1.addImm(Imm);
1151 }
1152
1153 break;
1154 }
1155 default:
1156 llvm_unreachable("Unknown operand type!");
1157 }
1158
1159 if (STI.hasLowByteFirst()) {
1160 // Write the low byte first for XMEGA devices.
1161 MIB0.addReg(SrcLoReg, getKillRegState(SrcIsKill))
1162 .setMemRefs(MI.memoperands());
1163 MIB1.addReg(SrcHiReg, getKillRegState(SrcIsKill))
1164 .setMemRefs(MI.memoperands());
1165 } else {
1166 // Write the high byte first for traditional devices.
1167 MIB0.addReg(SrcHiReg, getKillRegState(SrcIsKill))
1168 .setMemRefs(MI.memoperands());
1169 MIB1.addReg(SrcLoReg, getKillRegState(SrcIsKill))
1170 .setMemRefs(MI.memoperands());
1171 }
1172
1173 MI.eraseFromParent();
1174 return true;
1175}
1176
1177template <>
1178bool AVRExpandPseudo::expand<AVR::STWPtrRr>(Block &MBB, BlockIt MBBI) {
1179 MachineInstr &MI = *MBBI;
1180 Register DstReg = MI.getOperand(0).getReg();
1181 Register SrcReg = MI.getOperand(1).getReg();
1182 bool DstIsKill = MI.getOperand(0).isKill();
1183 bool DstIsUndef = MI.getOperand(0).isUndef();
1184 bool SrcIsKill = MI.getOperand(1).isKill();
1185 const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
1186
1187 // TODO: Need to reverse this order like inw and stsw?
1188
1189 if (STI.hasTinyEncoding()) {
1190 // Handle this case in the expansion of STDWPtrQRr because it is very
1191 // similar.
1192 buildMI(MBB, MBBI, AVR::STDWPtrQRr)
1193 .addReg(DstReg,
1194 getKillRegState(DstIsKill) | getUndefRegState(DstIsUndef))
1195 .addImm(0)
1196 .addReg(SrcReg, getKillRegState(SrcIsKill))
1197 .setMemRefs(MI.memoperands());
1198
1199 } else {
1200 Register SrcLoReg, SrcHiReg;
1201 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1202 if (STI.hasLowByteFirst()) {
1203 buildMI(MBB, MBBI, AVR::STPtrRr)
1204 .addReg(DstReg, getUndefRegState(DstIsUndef))
1205 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1206 .setMemRefs(MI.memoperands());
1207 buildMI(MBB, MBBI, AVR::STDPtrQRr)
1208 .addReg(DstReg, getUndefRegState(DstIsUndef))
1209 .addImm(1)
1210 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1211 .setMemRefs(MI.memoperands());
1212 } else {
1213 buildMI(MBB, MBBI, AVR::STDPtrQRr)
1214 .addReg(DstReg, getUndefRegState(DstIsUndef))
1215 .addImm(1)
1216 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1217 .setMemRefs(MI.memoperands());
1218 buildMI(MBB, MBBI, AVR::STPtrRr)
1219 .addReg(DstReg, getUndefRegState(DstIsUndef))
1220 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1221 .setMemRefs(MI.memoperands());
1222 }
1223 }
1224
1225 MI.eraseFromParent();
1226 return true;
1227}
1228
1229template <>
1230bool AVRExpandPseudo::expand<AVR::STWPtrPiRr>(Block &MBB, BlockIt MBBI) {
1231 MachineInstr &MI = *MBBI;
1232 Register SrcLoReg, SrcHiReg;
1233 Register DstReg = MI.getOperand(0).getReg();
1234 Register SrcReg = MI.getOperand(2).getReg();
1235 unsigned Imm = MI.getOperand(3).getImm();
1236 bool DstIsDead = MI.getOperand(0).isDead();
1237 bool SrcIsKill = MI.getOperand(2).isKill();
1238 unsigned OpLo = AVR::STPtrPiRr;
1239 unsigned OpHi = AVR::STPtrPiRr;
1240 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1241
1242 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
1243
1244 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1245 .addReg(DstReg, RegState::Define)
1246 .addReg(DstReg, RegState::Kill)
1247 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1248 .addImm(Imm);
1249
1250 auto MIBHI =
1251 buildMI(MBB, MBBI, OpHi)
1252 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
1253 .addReg(DstReg, RegState::Kill)
1254 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1255 .addImm(Imm);
1256
1257 MIBLO.setMemRefs(MI.memoperands());
1258 MIBHI.setMemRefs(MI.memoperands());
1259
1260 MI.eraseFromParent();
1261 return true;
1262}
1263
1264template <>
1265bool AVRExpandPseudo::expand<AVR::STWPtrPdRr>(Block &MBB, BlockIt MBBI) {
1266 MachineInstr &MI = *MBBI;
1267 Register SrcLoReg, SrcHiReg;
1268 Register DstReg = MI.getOperand(0).getReg();
1269 Register SrcReg = MI.getOperand(2).getReg();
1270 unsigned Imm = MI.getOperand(3).getImm();
1271 bool DstIsDead = MI.getOperand(0).isDead();
1272 bool SrcIsKill = MI.getOperand(2).isKill();
1273 unsigned OpLo = AVR::STPtrPdRr;
1274 unsigned OpHi = AVR::STPtrPdRr;
1275 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1276
1277 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
1278
1279 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1280 .addReg(DstReg, RegState::Define)
1281 .addReg(DstReg, RegState::Kill)
1282 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1283 .addImm(Imm);
1284
1285 auto MIBLO =
1286 buildMI(MBB, MBBI, OpLo)
1287 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
1288 .addReg(DstReg, RegState::Kill)
1289 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1290 .addImm(Imm);
1291
1292 MIBLO.setMemRefs(MI.memoperands());
1293 MIBHI.setMemRefs(MI.memoperands());
1294
1295 MI.eraseFromParent();
1296 return true;
1297}
1298
1299template <>
1300bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(Block &MBB, BlockIt MBBI) {
1301 MachineInstr &MI = *MBBI;
1302 const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
1303
1304 Register DstReg = MI.getOperand(0).getReg();
1305 bool DstIsKill = MI.getOperand(0).isKill();
1306 unsigned Imm = MI.getOperand(1).getImm();
1307 Register SrcReg = MI.getOperand(2).getReg();
1308 bool SrcIsKill = MI.getOperand(2).isKill();
1309
1310 // STD's maximum displacement is 63, so larger stores have to be split into a
1311 // set of operations.
1312 // For avrtiny chips, STD is not available at all so we always have to fall
1313 // back to manual pointer adjustments.
1314 if (Imm >= 63 || STI.hasTinyEncoding()) {
1315 // Add offset. The offset can be 0 when expanding this instruction from the
1316 // more specific STWPtrRr instruction.
1317 if (Imm != 0) {
1318 buildMI(MBB, MBBI, AVR::SUBIWRdK, DstReg)
1319 .addReg(DstReg, RegState::Kill)
1320 .addImm(0x10000 - Imm);
1321 }
1322
1323 // Do the store. This is a word store, that will be expanded further.
1324 buildMI(MBB, MBBI, AVR::STWPtrPiRr, DstReg)
1325 .addReg(DstReg, getKillRegState(DstIsKill))
1326 .addReg(SrcReg, getKillRegState(SrcIsKill))
1327 .addImm(0)
1328 .setMemRefs(MI.memoperands());
1329
1330 // If the pointer is used after the store instruction, subtract the new
1331 // offset (with 2 added after the postincrement instructions) so it is the
1332 // same as before.
1333 if (!DstIsKill) {
1334 buildMI(MBB, MBBI, AVR::SUBIWRdK, DstReg)
1335 .addReg(DstReg, RegState::Kill)
1336 .addImm(Imm + 2);
1337 }
1338 } else {
1339 Register SrcLoReg, SrcHiReg;
1340 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1341
1342 if (STI.hasLowByteFirst()) {
1343 buildMI(MBB, MBBI, AVR::STDPtrQRr)
1344 .addReg(DstReg)
1345 .addImm(Imm)
1346 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1347 .setMemRefs(MI.memoperands());
1348 buildMI(MBB, MBBI, AVR::STDPtrQRr)
1349 .addReg(DstReg, getKillRegState(DstIsKill))
1350 .addImm(Imm + 1)
1351 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1352 .setMemRefs(MI.memoperands());
1353 } else {
1354 buildMI(MBB, MBBI, AVR::STDPtrQRr)
1355 .addReg(DstReg)
1356 .addImm(Imm + 1)
1357 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1358 .setMemRefs(MI.memoperands());
1359 buildMI(MBB, MBBI, AVR::STDPtrQRr)
1360 .addReg(DstReg, getKillRegState(DstIsKill))
1361 .addImm(Imm)
1362 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1363 .setMemRefs(MI.memoperands());
1364 }
1365 }
1366
1367 MI.eraseFromParent();
1368 return true;
1369}
1370
1371template <>
1372bool AVRExpandPseudo::expand<AVR::STDSPQRr>(Block &MBB, BlockIt MBBI) {
1373 MachineInstr &MI = *MBBI;
1374 const MachineFunction &MF = *MBB.getParent();
1375 const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
1376
1377 assert(MI.getOperand(0).getReg() == AVR::SP &&
1378 "SP is expected as base pointer");
1379
1381 "unexpected STDSPQRr pseudo instruction");
1382
1383 if (STI.hasTinyEncoding()) {
1384 // Reduced tiny cores don't support std, so emulate it with a plain store
1385 // and pointer adjustments.
1386 unsigned Imm = MI.getOperand(1).getImm();
1387 Register SrcReg = MI.getOperand(2).getReg();
1388 bool SrcIsKill = MI.getOperand(2).isKill();
1389
1390 if (Imm != 0)
1391 buildMI(MBB, MBBI, AVR::SUBIWRdK, AVR::R29R28)
1392 .addReg(AVR::R29R28, RegState::Kill)
1393 .addImm(0x10000 - Imm);
1394
1395 buildMI(MBB, MBBI, AVR::STPtrRr)
1396 .addReg(AVR::R29R28, RegState::Kill)
1397 .addReg(SrcReg, getKillRegState(SrcIsKill))
1398 .setMemRefs(MI.memoperands());
1399
1400 if (Imm != 0)
1401 buildMI(MBB, std::next(MBBI), AVR::SUBIWRdK, AVR::R29R28)
1402 .addReg(AVR::R29R28, RegState::Kill)
1403 .addImm(Imm);
1404
1405 MI.eraseFromParent();
1406 } else {
1407 MI.setDesc(TII->get(AVR::STDPtrQRr));
1408 MI.getOperand(0).setReg(AVR::R29R28);
1409 }
1410
1411 return true;
1412}
1413
1414template <>
1415bool AVRExpandPseudo::expand<AVR::STDWSPQRr>(Block &MBB, BlockIt MBBI) {
1416 MachineInstr &MI = *MBBI;
1417 const MachineFunction &MF = *MBB.getParent();
1418 const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
1419
1420 assert(MI.getOperand(0).getReg() == AVR::SP &&
1421 "SP is expected as base pointer");
1422
1424 "unexpected STDWSPQRr pseudo instruction");
1425 (void)STI;
1426
1427 MI.setDesc(TII->get(AVR::STDWPtrQRr));
1428 MI.getOperand(0).setReg(AVR::R29R28);
1429
1430 return true;
1431}
1432
1433template <>
1434bool AVRExpandPseudo::expand<AVR::INWRdA>(Block &MBB, BlockIt MBBI) {
1435 MachineInstr &MI = *MBBI;
1436 Register DstLoReg, DstHiReg;
1437 unsigned Imm = MI.getOperand(1).getImm();
1438 Register DstReg = MI.getOperand(0).getReg();
1439 bool DstIsDead = MI.getOperand(0).isDead();
1440 unsigned OpLo = AVR::INRdA;
1441 unsigned OpHi = AVR::INRdA;
1442 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1443
1444 // Since we add 1 to the Imm value for the high byte below, and 63 is the
1445 // highest Imm value allowed for the instruction, 62 is the limit here.
1446 assert(Imm <= 62 && "Address is out of range");
1447
1448 auto MIBLO =
1449 buildMI(MBB, MBBI, OpLo)
1450 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1451 .addImm(Imm);
1452
1453 auto MIBHI =
1454 buildMI(MBB, MBBI, OpHi)
1455 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1456 .addImm(Imm + 1);
1457
1458 MIBLO.setMemRefs(MI.memoperands());
1459 MIBHI.setMemRefs(MI.memoperands());
1460
1461 MI.eraseFromParent();
1462 return true;
1463}
1464
1465template <>
1466bool AVRExpandPseudo::expand<AVR::OUTWARr>(Block &MBB, BlockIt MBBI) {
1467 const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
1468 MachineInstr &MI = *MBBI;
1469 Register SrcLoReg, SrcHiReg;
1470 unsigned Imm = MI.getOperand(0).getImm();
1471 Register SrcReg = MI.getOperand(1).getReg();
1472 bool SrcIsKill = MI.getOperand(1).isKill();
1473 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1474
1475 // Since we add 1 to the Imm value for the high byte below, and 63 is the
1476 // highest Imm value allowed for the instruction, 62 is the limit here.
1477 assert(Imm <= 62 && "Address is out of range");
1478
1479 // 16 bit I/O writes need the high byte first on normal AVR devices,
1480 // and in reverse order for the XMEGA/XMEGA3/XMEGAU families.
1481 auto MIBHI = buildMI(MBB, MBBI, AVR::OUTARr)
1482 .addImm(STI.hasLowByteFirst() ? Imm : Imm + 1)
1483 .addReg(STI.hasLowByteFirst() ? SrcLoReg : SrcHiReg,
1484 getKillRegState(SrcIsKill));
1485 auto MIBLO = buildMI(MBB, MBBI, AVR::OUTARr)
1486 .addImm(STI.hasLowByteFirst() ? Imm + 1 : Imm)
1487 .addReg(STI.hasLowByteFirst() ? SrcHiReg : SrcLoReg,
1488 getKillRegState(SrcIsKill));
1489
1490 MIBLO.setMemRefs(MI.memoperands());
1491 MIBHI.setMemRefs(MI.memoperands());
1492
1493 MI.eraseFromParent();
1494 return true;
1495}
1496
1497template <>
1498bool AVRExpandPseudo::expand<AVR::PUSHWRr>(Block &MBB, BlockIt MBBI) {
1499 MachineInstr &MI = *MBBI;
1500 Register SrcLoReg, SrcHiReg;
1501 Register SrcReg = MI.getOperand(0).getReg();
1502 bool SrcIsKill = MI.getOperand(0).isKill();
1503 unsigned Flags = MI.getFlags();
1504 unsigned OpLo = AVR::PUSHRr;
1505 unsigned OpHi = AVR::PUSHRr;
1506 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1507
1508 // Low part
1509 buildMI(MBB, MBBI, OpLo)
1510 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1511 .setMIFlags(Flags);
1512
1513 // High part
1514 buildMI(MBB, MBBI, OpHi)
1515 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1516 .setMIFlags(Flags);
1517
1518 MI.eraseFromParent();
1519 return true;
1520}
1521
1522template <>
1523bool AVRExpandPseudo::expand<AVR::POPWRd>(Block &MBB, BlockIt MBBI) {
1524 MachineInstr &MI = *MBBI;
1525 Register DstLoReg, DstHiReg;
1526 Register DstReg = MI.getOperand(0).getReg();
1527 unsigned Flags = MI.getFlags();
1528 unsigned OpLo = AVR::POPRd;
1529 unsigned OpHi = AVR::POPRd;
1530 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1531
1532 buildMI(MBB, MBBI, OpHi, DstHiReg).setMIFlags(Flags); // High
1533 buildMI(MBB, MBBI, OpLo, DstLoReg).setMIFlags(Flags); // Low
1534
1535 MI.eraseFromParent();
1536 return true;
1537}
1538
1539bool AVRExpandPseudo::expandROLBRd(Block &MBB, BlockIt MBBI) {
1540 // In AVR, the rotate instructions behave quite unintuitively. They rotate
1541 // bits through the carry bit in SREG, effectively rotating over 9 bits,
1542 // instead of 8. This is useful when we are dealing with numbers over
1543 // multiple registers, but when we actually need to rotate stuff, we have
1544 // to explicitly add the carry bit.
1545
1546 MachineInstr &MI = *MBBI;
1547 unsigned OpShift, OpCarry;
1548 Register DstReg = MI.getOperand(0).getReg();
1549 Register ZeroReg = MI.getOperand(3).getReg();
1550 bool DstIsDead = MI.getOperand(0).isDead();
1551 bool DstIsKill = MI.getOperand(1).isKill();
1552 OpShift = AVR::ADDRdRr;
1553 OpCarry = AVR::ADCRdRr;
1554
1555 // add r16, r16
1556 // adc r16, r1
1557
1558 // Shift part
1559 buildMI(MBB, MBBI, OpShift)
1560 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
1561 .addReg(DstReg, RegState::Kill)
1562 .addReg(DstReg, RegState::Kill);
1563
1564 // Add the carry bit
1565 auto MIB = buildMI(MBB, MBBI, OpCarry)
1566 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
1567 .addReg(DstReg, getKillRegState(DstIsKill))
1568 .addReg(ZeroReg);
1569
1570 MIB->getOperand(3).setIsDead(); // SREG is always dead
1571 MIB->getOperand(4).setIsKill(); // SREG is always implicitly killed
1572
1573 MI.eraseFromParent();
1574 return true;
1575}
1576
1577template <>
1578bool AVRExpandPseudo::expand<AVR::ROLBRdR1>(Block &MBB, BlockIt MBBI) {
1579 return expandROLBRd(MBB, MBBI);
1580}
1581
1582template <>
1583bool AVRExpandPseudo::expand<AVR::ROLBRdR17>(Block &MBB, BlockIt MBBI) {
1584 return expandROLBRd(MBB, MBBI);
1585}
1586
1587template <>
1588bool AVRExpandPseudo::expand<AVR::RORBRd>(Block &MBB, BlockIt MBBI) {
1589 // In AVR, the rotate instructions behave quite unintuitively. They rotate
1590 // bits through the carry bit in SREG, effectively rotating over 9 bits,
1591 // instead of 8. This is useful when we are dealing with numbers over
1592 // multiple registers, but when we actually need to rotate stuff, we have
1593 // to explicitly add the carry bit.
1594
1595 MachineInstr &MI = *MBBI;
1596 Register DstReg = MI.getOperand(0).getReg();
1597
1598 // bst r16, 0
1599 // ror r16
1600 // bld r16, 7
1601
1602 // Move the lowest bit from DstReg into the T bit
1603 buildMI(MBB, MBBI, AVR::BST).addReg(DstReg).addImm(0);
1604
1605 // Rotate to the right
1606 buildMI(MBB, MBBI, AVR::RORRd, DstReg).addReg(DstReg);
1607
1608 // Move the T bit into the highest bit of DstReg.
1609 buildMI(MBB, MBBI, AVR::BLD, DstReg).addReg(DstReg).addImm(7);
1610
1611 MI.eraseFromParent();
1612 return true;
1613}
1614
1615template <>
1616bool AVRExpandPseudo::expand<AVR::LSLWRd>(Block &MBB, BlockIt MBBI) {
1617 MachineInstr &MI = *MBBI;
1618 Register DstLoReg, DstHiReg;
1619 Register DstReg = MI.getOperand(0).getReg();
1620 bool DstIsDead = MI.getOperand(0).isDead();
1621 bool DstIsKill = MI.getOperand(1).isKill();
1622 bool ImpIsDead = MI.getOperand(2).isDead();
1623 unsigned OpLo = AVR::ADDRdRr; // ADD Rd, Rd <==> LSL Rd
1624 unsigned OpHi = AVR::ADCRdRr; // ADC Rd, Rd <==> ROL Rd
1625 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1626
1627 // Low part
1628 buildMI(MBB, MBBI, OpLo)
1629 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1630 .addReg(DstLoReg, getKillRegState(DstIsKill))
1631 .addReg(DstLoReg, getKillRegState(DstIsKill));
1632
1633 auto MIBHI =
1634 buildMI(MBB, MBBI, OpHi)
1635 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1636 .addReg(DstHiReg, getKillRegState(DstIsKill))
1637 .addReg(DstHiReg, getKillRegState(DstIsKill));
1638
1639 if (ImpIsDead)
1640 MIBHI->getOperand(3).setIsDead();
1641
1642 // SREG is always implicitly killed
1643 MIBHI->getOperand(4).setIsKill();
1644
1645 MI.eraseFromParent();
1646 return true;
1647}
1648
1649template <>
1650bool AVRExpandPseudo::expand<AVR::LSLWHiRd>(Block &MBB, BlockIt MBBI) {
1651 MachineInstr &MI = *MBBI;
1652 Register DstLoReg, DstHiReg;
1653 Register DstReg = MI.getOperand(0).getReg();
1654 bool DstIsDead = MI.getOperand(0).isDead();
1655 bool DstIsKill = MI.getOperand(1).isKill();
1656 bool ImpIsDead = MI.getOperand(2).isDead();
1657 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1658
1659 // add hireg, hireg <==> lsl hireg
1660 auto MILSL =
1661 buildMI(MBB, MBBI, AVR::ADDRdRr)
1662 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1663 .addReg(DstHiReg, getKillRegState(DstIsKill))
1664 .addReg(DstHiReg, getKillRegState(DstIsKill));
1665
1666 if (ImpIsDead)
1667 MILSL->getOperand(3).setIsDead();
1668
1669 MI.eraseFromParent();
1670 return true;
1671}
1672
1673bool AVRExpandPseudo::expandLSLW4Rd(Block &MBB, BlockIt MBBI) {
1674 MachineInstr &MI = *MBBI;
1675 Register DstLoReg, DstHiReg;
1676 Register DstReg = MI.getOperand(0).getReg();
1677 bool DstIsDead = MI.getOperand(0).isDead();
1678 bool DstIsKill = MI.getOperand(1).isKill();
1679 bool ImpIsDead = MI.getOperand(3).isDead();
1680 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1681
1682 // swap Rh
1683 // swap Rl
1684 buildMI(MBB, MBBI, AVR::SWAPRd)
1685 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1686 .addReg(DstHiReg, RegState::Kill);
1687 buildMI(MBB, MBBI, AVR::SWAPRd)
1688 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1689 .addReg(DstLoReg, RegState::Kill);
1690
1691 // andi Rh, 0xf0
1692 auto MI0 =
1693 buildMI(MBB, MBBI, AVR::ANDIRdK)
1694 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1695 .addReg(DstHiReg, RegState::Kill)
1696 .addImm(0xf0);
1697 // SREG is implicitly dead.
1698 MI0->getOperand(3).setIsDead();
1699
1700 // eor Rh, Rl
1701 auto MI1 =
1702 buildMI(MBB, MBBI, AVR::EORRdRr)
1703 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1704 .addReg(DstHiReg, RegState::Kill)
1705 .addReg(DstLoReg);
1706 // SREG is implicitly dead.
1707 MI1->getOperand(3).setIsDead();
1708
1709 // andi Rl, 0xf0
1710 auto MI2 =
1711 buildMI(MBB, MBBI, AVR::ANDIRdK)
1712 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1713 .addReg(DstLoReg, getKillRegState(DstIsKill))
1714 .addImm(0xf0);
1715 // SREG is implicitly dead.
1716 MI2->getOperand(3).setIsDead();
1717
1718 // eor Rh, Rl
1719 auto MI3 =
1720 buildMI(MBB, MBBI, AVR::EORRdRr)
1721 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1722 .addReg(DstHiReg, getKillRegState(DstIsKill))
1723 .addReg(DstLoReg);
1724 if (ImpIsDead)
1725 MI3->getOperand(3).setIsDead();
1726
1727 MI.eraseFromParent();
1728 return true;
1729}
1730
1731bool AVRExpandPseudo::expandLSLW8Rd(Block &MBB, BlockIt MBBI) {
1732 MachineInstr &MI = *MBBI;
1733 Register DstLoReg, DstHiReg;
1734 Register DstReg = MI.getOperand(0).getReg();
1735 bool DstIsDead = MI.getOperand(0).isDead();
1736 bool DstIsKill = MI.getOperand(1).isKill();
1737 bool ImpIsDead = MI.getOperand(3).isDead();
1738 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1739
1740 // mov Rh, Rl
1741 buildMI(MBB, MBBI, AVR::MOVRdRr)
1742 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1743 .addReg(DstLoReg);
1744
1745 // clr Rl
1746 auto MIBLO =
1747 buildMI(MBB, MBBI, AVR::EORRdRr)
1748 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1749 .addReg(DstLoReg, getKillRegState(DstIsKill))
1750 .addReg(DstLoReg, getKillRegState(DstIsKill));
1751 if (ImpIsDead)
1752 MIBLO->getOperand(3).setIsDead();
1753
1754 MI.eraseFromParent();
1755 return true;
1756}
1757
1758bool AVRExpandPseudo::expandLSLW12Rd(Block &MBB, BlockIt MBBI) {
1759 MachineInstr &MI = *MBBI;
1760 Register DstLoReg, DstHiReg;
1761 Register DstReg = MI.getOperand(0).getReg();
1762 bool DstIsDead = MI.getOperand(0).isDead();
1763 bool DstIsKill = MI.getOperand(1).isKill();
1764 bool ImpIsDead = MI.getOperand(3).isDead();
1765 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1766
1767 // mov Rh, Rl
1768 buildMI(MBB, MBBI, AVR::MOVRdRr)
1769 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1770 .addReg(DstLoReg);
1771
1772 // swap Rh
1773 buildMI(MBB, MBBI, AVR::SWAPRd)
1774 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1775 .addReg(DstHiReg, RegState::Kill);
1776
1777 // andi Rh, 0xf0
1778 auto MI0 =
1779 buildMI(MBB, MBBI, AVR::ANDIRdK)
1780 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1781 .addReg(DstHiReg, getKillRegState(DstIsKill))
1782 .addImm(0xf0);
1783 // SREG is implicitly dead.
1784 MI0->getOperand(3).setIsDead();
1785
1786 // clr Rl
1787 auto MI1 =
1788 buildMI(MBB, MBBI, AVR::EORRdRr)
1789 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1790 .addReg(DstLoReg, getKillRegState(DstIsKill))
1791 .addReg(DstLoReg, getKillRegState(DstIsKill));
1792 if (ImpIsDead)
1793 MI1->getOperand(3).setIsDead();
1794
1795 MI.eraseFromParent();
1796 return true;
1797}
1798
1799template <>
1800bool AVRExpandPseudo::expand<AVR::LSLWNRd>(Block &MBB, BlockIt MBBI) {
1801 MachineInstr &MI = *MBBI;
1802 unsigned Imm = MI.getOperand(2).getImm();
1803 switch (Imm) {
1804 case 4:
1805 return expandLSLW4Rd(MBB, MBBI);
1806 case 8:
1807 return expandLSLW8Rd(MBB, MBBI);
1808 case 12:
1809 return expandLSLW12Rd(MBB, MBBI);
1810 default:
1811 llvm_unreachable("unimplemented lslwn");
1812 return false;
1813 }
1814}
1815
1816template <>
1817bool AVRExpandPseudo::expand<AVR::LSRWRd>(Block &MBB, BlockIt MBBI) {
1818 MachineInstr &MI = *MBBI;
1819 Register DstLoReg, DstHiReg;
1820 Register DstReg = MI.getOperand(0).getReg();
1821 bool DstIsDead = MI.getOperand(0).isDead();
1822 bool DstIsKill = MI.getOperand(1).isKill();
1823 bool ImpIsDead = MI.getOperand(2).isDead();
1824 unsigned OpLo = AVR::RORRd;
1825 unsigned OpHi = AVR::LSRRd;
1826 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1827
1828 // High part
1829 buildMI(MBB, MBBI, OpHi)
1830 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1831 .addReg(DstHiReg, getKillRegState(DstIsKill));
1832
1833 auto MIBLO =
1834 buildMI(MBB, MBBI, OpLo)
1835 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1836 .addReg(DstLoReg, getKillRegState(DstIsKill));
1837
1838 if (ImpIsDead)
1839 MIBLO->getOperand(2).setIsDead();
1840
1841 // SREG is always implicitly killed
1842 MIBLO->getOperand(3).setIsKill();
1843
1844 MI.eraseFromParent();
1845 return true;
1846}
1847
1848template <>
1849bool AVRExpandPseudo::expand<AVR::LSRWLoRd>(Block &MBB, BlockIt MBBI) {
1850 MachineInstr &MI = *MBBI;
1851 Register DstLoReg, DstHiReg;
1852 Register DstReg = MI.getOperand(0).getReg();
1853 bool DstIsDead = MI.getOperand(0).isDead();
1854 bool DstIsKill = MI.getOperand(1).isKill();
1855 bool ImpIsDead = MI.getOperand(2).isDead();
1856 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1857
1858 // lsr loreg
1859 auto MILSR =
1860 buildMI(MBB, MBBI, AVR::LSRRd)
1861 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1862 .addReg(DstLoReg, getKillRegState(DstIsKill));
1863
1864 if (ImpIsDead)
1865 MILSR->getOperand(2).setIsDead();
1866
1867 MI.eraseFromParent();
1868 return true;
1869}
1870
1871bool AVRExpandPseudo::expandLSRW4Rd(Block &MBB, BlockIt MBBI) {
1872 MachineInstr &MI = *MBBI;
1873 Register DstLoReg, DstHiReg;
1874 Register DstReg = MI.getOperand(0).getReg();
1875 bool DstIsDead = MI.getOperand(0).isDead();
1876 bool DstIsKill = MI.getOperand(1).isKill();
1877 bool ImpIsDead = MI.getOperand(3).isDead();
1878 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1879
1880 // swap Rh
1881 // swap Rl
1882 buildMI(MBB, MBBI, AVR::SWAPRd)
1883 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1884 .addReg(DstHiReg, RegState::Kill);
1885 buildMI(MBB, MBBI, AVR::SWAPRd)
1886 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1887 .addReg(DstLoReg, RegState::Kill);
1888
1889 // andi Rl, 0xf
1890 auto MI0 =
1891 buildMI(MBB, MBBI, AVR::ANDIRdK)
1892 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1893 .addReg(DstLoReg, RegState::Kill)
1894 .addImm(0xf);
1895 // SREG is implicitly dead.
1896 MI0->getOperand(3).setIsDead();
1897
1898 // eor Rl, Rh
1899 auto MI1 =
1900 buildMI(MBB, MBBI, AVR::EORRdRr)
1901 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1902 .addReg(DstLoReg, RegState::Kill)
1903 .addReg(DstHiReg);
1904 // SREG is implicitly dead.
1905 MI1->getOperand(3).setIsDead();
1906
1907 // andi Rh, 0xf
1908 auto MI2 =
1909 buildMI(MBB, MBBI, AVR::ANDIRdK)
1910 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1911 .addReg(DstHiReg, getKillRegState(DstIsKill))
1912 .addImm(0xf);
1913 // SREG is implicitly dead.
1914 MI2->getOperand(3).setIsDead();
1915
1916 // eor Rl, Rh
1917 auto MI3 =
1918 buildMI(MBB, MBBI, AVR::EORRdRr)
1919 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1920 .addReg(DstLoReg, getKillRegState(DstIsKill))
1921 .addReg(DstHiReg);
1922 if (ImpIsDead)
1923 MI3->getOperand(3).setIsDead();
1924
1925 MI.eraseFromParent();
1926 return true;
1927}
1928
1929bool AVRExpandPseudo::expandLSRW8Rd(Block &MBB, BlockIt MBBI) {
1930 MachineInstr &MI = *MBBI;
1931 Register DstLoReg, DstHiReg;
1932 Register DstReg = MI.getOperand(0).getReg();
1933 bool DstIsDead = MI.getOperand(0).isDead();
1934 bool DstIsKill = MI.getOperand(1).isKill();
1935 bool ImpIsDead = MI.getOperand(3).isDead();
1936 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1937
1938 // Move upper byte to lower byte.
1939 buildMI(MBB, MBBI, AVR::MOVRdRr)
1940 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1941 .addReg(DstHiReg);
1942
1943 // Clear upper byte.
1944 auto MIBHI =
1945 buildMI(MBB, MBBI, AVR::EORRdRr)
1946 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1947 .addReg(DstHiReg, getKillRegState(DstIsKill))
1948 .addReg(DstHiReg, getKillRegState(DstIsKill));
1949 if (ImpIsDead)
1950 MIBHI->getOperand(3).setIsDead();
1951
1952 MI.eraseFromParent();
1953 return true;
1954}
1955
1956bool AVRExpandPseudo::expandLSRW12Rd(Block &MBB, BlockIt MBBI) {
1957 MachineInstr &MI = *MBBI;
1958 Register DstLoReg, DstHiReg;
1959 Register DstReg = MI.getOperand(0).getReg();
1960 bool DstIsDead = MI.getOperand(0).isDead();
1961 bool DstIsKill = MI.getOperand(1).isKill();
1962 bool ImpIsDead = MI.getOperand(3).isDead();
1963 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1964
1965 // Move upper byte to lower byte.
1966 buildMI(MBB, MBBI, AVR::MOVRdRr)
1967 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1968 .addReg(DstHiReg);
1969
1970 // swap Rl
1971 buildMI(MBB, MBBI, AVR::SWAPRd)
1972 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1973 .addReg(DstLoReg, RegState::Kill);
1974
1975 // andi Rl, 0xf
1976 auto MI0 =
1977 buildMI(MBB, MBBI, AVR::ANDIRdK)
1978 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1979 .addReg(DstLoReg, getKillRegState(DstIsKill))
1980 .addImm(0xf);
1981 // SREG is implicitly dead.
1982 MI0->getOperand(3).setIsDead();
1983
1984 // Clear upper byte.
1985 auto MIBHI =
1986 buildMI(MBB, MBBI, AVR::EORRdRr)
1987 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1988 .addReg(DstHiReg, getKillRegState(DstIsKill))
1989 .addReg(DstHiReg, getKillRegState(DstIsKill));
1990 if (ImpIsDead)
1991 MIBHI->getOperand(3).setIsDead();
1992
1993 MI.eraseFromParent();
1994 return true;
1995}
1996
1997template <>
1998bool AVRExpandPseudo::expand<AVR::LSRWNRd>(Block &MBB, BlockIt MBBI) {
1999 MachineInstr &MI = *MBBI;
2000 unsigned Imm = MI.getOperand(2).getImm();
2001 switch (Imm) {
2002 case 4:
2003 return expandLSRW4Rd(MBB, MBBI);
2004 case 8:
2005 return expandLSRW8Rd(MBB, MBBI);
2006 case 12:
2007 return expandLSRW12Rd(MBB, MBBI);
2008 default:
2009 llvm_unreachable("unimplemented lsrwn");
2010 return false;
2011 }
2012}
2013
2014template <>
2015bool AVRExpandPseudo::expand<AVR::RORWRd>(Block &MBB, BlockIt MBBI) {
2016 llvm_unreachable("RORW unimplemented");
2017 return false;
2018}
2019
2020template <>
2021bool AVRExpandPseudo::expand<AVR::ROLWRd>(Block &MBB, BlockIt MBBI) {
2022 llvm_unreachable("ROLW unimplemented");
2023 return false;
2024}
2025
2026template <>
2027bool AVRExpandPseudo::expand<AVR::ASRWRd>(Block &MBB, BlockIt MBBI) {
2028 MachineInstr &MI = *MBBI;
2029 Register DstLoReg, DstHiReg;
2030 Register DstReg = MI.getOperand(0).getReg();
2031 bool DstIsDead = MI.getOperand(0).isDead();
2032 bool DstIsKill = MI.getOperand(1).isKill();
2033 bool ImpIsDead = MI.getOperand(2).isDead();
2034 unsigned OpLo = AVR::RORRd;
2035 unsigned OpHi = AVR::ASRRd;
2036 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2037
2038 // High part
2039 buildMI(MBB, MBBI, OpHi)
2040 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
2041 .addReg(DstHiReg, getKillRegState(DstIsKill));
2042
2043 auto MIBLO =
2044 buildMI(MBB, MBBI, OpLo)
2045 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
2046 .addReg(DstLoReg, getKillRegState(DstIsKill));
2047
2048 if (ImpIsDead)
2049 MIBLO->getOperand(2).setIsDead();
2050
2051 // SREG is always implicitly killed
2052 MIBLO->getOperand(3).setIsKill();
2053
2054 MI.eraseFromParent();
2055 return true;
2056}
2057
2058template <>
2059bool AVRExpandPseudo::expand<AVR::ASRWLoRd>(Block &MBB, BlockIt MBBI) {
2060 MachineInstr &MI = *MBBI;
2061 Register DstLoReg, DstHiReg;
2062 Register DstReg = MI.getOperand(0).getReg();
2063 bool DstIsDead = MI.getOperand(0).isDead();
2064 bool DstIsKill = MI.getOperand(1).isKill();
2065 bool ImpIsDead = MI.getOperand(2).isDead();
2066 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2067
2068 // asr loreg
2069 auto MIASR =
2070 buildMI(MBB, MBBI, AVR::ASRRd)
2071 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
2072 .addReg(DstLoReg, getKillRegState(DstIsKill));
2073
2074 if (ImpIsDead)
2075 MIASR->getOperand(2).setIsDead();
2076
2077 MI.eraseFromParent();
2078 return true;
2079}
2080
2081bool AVRExpandPseudo::expandASRW7Rd(Block &MBB, BlockIt MBBI) {
2082 MachineInstr &MI = *MBBI;
2083 Register DstLoReg, DstHiReg;
2084 Register DstReg = MI.getOperand(0).getReg();
2085 bool DstIsDead = MI.getOperand(0).isDead();
2086 bool DstIsKill = MI.getOperand(1).isKill();
2087 bool ImpIsDead = MI.getOperand(3).isDead();
2088 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2089
2090 // lsl r24
2091 // mov r24,r25
2092 // rol r24
2093 // sbc r25,r25
2094
2095 // lsl r24 <=> add r24, r24
2096 buildMI(MBB, MBBI, AVR::ADDRdRr)
2097 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
2098 .addReg(DstLoReg, RegState::Kill)
2099 .addReg(DstLoReg, RegState::Kill);
2100
2101 // mov r24, r25
2102 buildMI(MBB, MBBI, AVR::MOVRdRr)
2103 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
2104 .addReg(DstHiReg);
2105
2106 // rol r24 <=> adc r24, r24
2107 buildMI(MBB, MBBI, AVR::ADCRdRr)
2108 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
2109 .addReg(DstLoReg, getKillRegState(DstIsKill))
2110 .addReg(DstLoReg, getKillRegState(DstIsKill));
2111
2112 // sbc r25, r25
2113 auto MISBC =
2114 buildMI(MBB, MBBI, AVR::SBCRdRr)
2115 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
2116 .addReg(DstHiReg, getKillRegState(DstIsKill))
2117 .addReg(DstHiReg, getKillRegState(DstIsKill));
2118
2119 if (ImpIsDead)
2120 MISBC->getOperand(3).setIsDead();
2121 // SREG is always implicitly killed
2122 MISBC->getOperand(4).setIsKill();
2123
2124 MI.eraseFromParent();
2125 return true;
2126}
2127
2128bool AVRExpandPseudo::expandASRW8Rd(Block &MBB, BlockIt MBBI) {
2129 MachineInstr &MI = *MBBI;
2130 Register DstLoReg, DstHiReg;
2131 Register DstReg = MI.getOperand(0).getReg();
2132 bool DstIsDead = MI.getOperand(0).isDead();
2133 bool DstIsKill = MI.getOperand(1).isKill();
2134 bool ImpIsDead = MI.getOperand(3).isDead();
2135 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2136
2137 // Move upper byte to lower byte.
2138 buildMI(MBB, MBBI, AVR::MOVRdRr)
2139 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
2140 .addReg(DstHiReg);
2141
2142 // Move the sign bit to the C flag.
2143 buildMI(MBB, MBBI, AVR::ADDRdRr)
2144 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
2145 .addReg(DstHiReg, RegState::Kill)
2146 .addReg(DstHiReg, RegState::Kill);
2147
2148 // Set upper byte to 0 or -1.
2149 auto MIBHI =
2150 buildMI(MBB, MBBI, AVR::SBCRdRr)
2151 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
2152 .addReg(DstHiReg, getKillRegState(DstIsKill))
2153 .addReg(DstHiReg, getKillRegState(DstIsKill));
2154
2155 if (ImpIsDead)
2156 MIBHI->getOperand(3).setIsDead();
2157 // SREG is always implicitly killed
2158 MIBHI->getOperand(4).setIsKill();
2159
2160 MI.eraseFromParent();
2161 return true;
2162}
2163bool AVRExpandPseudo::expandASRW14Rd(Block &MBB, BlockIt MBBI) {
2164 MachineInstr &MI = *MBBI;
2165 Register DstLoReg, DstHiReg;
2166 Register DstReg = MI.getOperand(0).getReg();
2167 bool DstIsDead = MI.getOperand(0).isDead();
2168 bool DstIsKill = MI.getOperand(1).isKill();
2169 bool ImpIsDead = MI.getOperand(3).isDead();
2170 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2171
2172 // lsl r25
2173 // sbc r24, r24
2174 // lsl r25
2175 // mov r25, r24
2176 // rol r24
2177
2178 // lsl r25 <=> add r25, r25
2179 buildMI(MBB, MBBI, AVR::ADDRdRr)
2180 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
2181 .addReg(DstHiReg, RegState::Kill)
2182 .addReg(DstHiReg, RegState::Kill);
2183
2184 // sbc r24, r24
2185 buildMI(MBB, MBBI, AVR::SBCRdRr)
2186 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
2187 .addReg(DstLoReg, RegState::Kill)
2188 .addReg(DstLoReg, RegState::Kill);
2189
2190 // lsl r25 <=> add r25, r25
2191 buildMI(MBB, MBBI, AVR::ADDRdRr)
2192 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
2193 .addReg(DstHiReg, RegState::Kill)
2194 .addReg(DstHiReg, RegState::Kill);
2195
2196 // mov r25, r24
2197 buildMI(MBB, MBBI, AVR::MOVRdRr)
2198 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
2199 .addReg(DstLoReg);
2200
2201 // rol r24 <=> adc r24, r24
2202 auto MIROL =
2203 buildMI(MBB, MBBI, AVR::ADCRdRr)
2204 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
2205 .addReg(DstLoReg, getKillRegState(DstIsKill))
2206 .addReg(DstLoReg, getKillRegState(DstIsKill));
2207
2208 if (ImpIsDead)
2209 MIROL->getOperand(3).setIsDead();
2210 // SREG is always implicitly killed
2211 MIROL->getOperand(4).setIsKill();
2212
2213 MI.eraseFromParent();
2214 return false;
2215}
2216
2217bool AVRExpandPseudo::expandASRW15Rd(Block &MBB, BlockIt MBBI) {
2218 MachineInstr &MI = *MBBI;
2219 Register DstLoReg, DstHiReg;
2220 Register DstReg = MI.getOperand(0).getReg();
2221 bool DstIsDead = MI.getOperand(0).isDead();
2222 bool ImpIsDead = MI.getOperand(3).isDead();
2223 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2224
2225 // lsl r25
2226 // sbc r25, r25
2227 // mov r24, r25
2228
2229 // lsl r25 <=> add r25, r25
2230 buildMI(MBB, MBBI, AVR::ADDRdRr)
2231 .addReg(DstHiReg, RegState::Define)
2232 .addReg(DstHiReg, RegState::Kill)
2233 .addReg(DstHiReg, RegState::Kill);
2234
2235 // sbc r25, r25
2236 auto MISBC =
2237 buildMI(MBB, MBBI, AVR::SBCRdRr)
2238 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
2239 .addReg(DstHiReg, RegState::Kill)
2240 .addReg(DstHiReg, RegState::Kill);
2241 if (ImpIsDead)
2242 MISBC->getOperand(3).setIsDead();
2243 // SREG is always implicitly killed
2244 MISBC->getOperand(4).setIsKill();
2245
2246 // mov r24, r25
2247 buildMI(MBB, MBBI, AVR::MOVRdRr)
2248 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
2249 .addReg(DstHiReg);
2250
2251 MI.eraseFromParent();
2252 return true;
2253}
2254
2255template <>
2256bool AVRExpandPseudo::expand<AVR::ASRWNRd>(Block &MBB, BlockIt MBBI) {
2257 MachineInstr &MI = *MBBI;
2258 unsigned Imm = MI.getOperand(2).getImm();
2259 switch (Imm) {
2260 case 7:
2261 return expandASRW7Rd(MBB, MBBI);
2262 case 8:
2263 return expandASRW8Rd(MBB, MBBI);
2264 case 14:
2265 return expandASRW14Rd(MBB, MBBI);
2266 case 15:
2267 return expandASRW15Rd(MBB, MBBI);
2268 default:
2269 llvm_unreachable("unimplemented asrwn");
2270 return false;
2271 }
2272}
2273
2274bool AVRExpandPseudo::expandLSLB7Rd(Block &MBB, BlockIt MBBI) {
2275 MachineInstr &MI = *MBBI;
2276 Register DstReg = MI.getOperand(0).getReg();
2277 bool DstIsDead = MI.getOperand(0).isDead();
2278 bool DstIsKill = MI.getOperand(1).isKill();
2279 bool ImpIsDead = MI.getOperand(3).isDead();
2280
2281 // ror r24
2282 // clr r24
2283 // ror r24
2284
2285 buildMI(MBB, MBBI, AVR::RORRd)
2286 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
2287 .addReg(DstReg, RegState::Kill)
2288 ->getOperand(3)
2289 .setIsUndef(true);
2290
2291 buildMI(MBB, MBBI, AVR::EORRdRr)
2292 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
2293 .addReg(DstReg, RegState::Kill)
2294 .addReg(DstReg, RegState::Kill);
2295
2296 auto MIRRC =
2297 buildMI(MBB, MBBI, AVR::RORRd)
2298 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
2299 .addReg(DstReg, getKillRegState(DstIsKill));
2300
2301 if (ImpIsDead)
2302 MIRRC->getOperand(2).setIsDead();
2303
2304 // SREG is always implicitly killed
2305 MIRRC->getOperand(3).setIsKill();
2306
2307 MI.eraseFromParent();
2308 return true;
2309}
2310
2311template <>
2312bool AVRExpandPseudo::expand<AVR::LSLBNRd>(Block &MBB, BlockIt MBBI) {
2313 MachineInstr &MI = *MBBI;
2314 unsigned Imm = MI.getOperand(2).getImm();
2315 switch (Imm) {
2316 case 7:
2317 return expandLSLB7Rd(MBB, MBBI);
2318 default:
2319 llvm_unreachable("unimplemented lslbn");
2320 return false;
2321 }
2322}
2323
2324bool AVRExpandPseudo::expandLSRB7Rd(Block &MBB, BlockIt MBBI) {
2325 MachineInstr &MI = *MBBI;
2326 Register DstReg = MI.getOperand(0).getReg();
2327 bool DstIsDead = MI.getOperand(0).isDead();
2328 bool DstIsKill = MI.getOperand(1).isKill();
2329 bool ImpIsDead = MI.getOperand(3).isDead();
2330
2331 // rol r24
2332 // clr r24
2333 // rol r24
2334
2335 buildMI(MBB, MBBI, AVR::ADCRdRr)
2336 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
2337 .addReg(DstReg, RegState::Kill)
2338 .addReg(DstReg, RegState::Kill)
2339 ->getOperand(4)
2340 .setIsUndef(true);
2341
2342 buildMI(MBB, MBBI, AVR::EORRdRr)
2343 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
2344 .addReg(DstReg, RegState::Kill)
2345 .addReg(DstReg, RegState::Kill);
2346
2347 auto MIRRC =
2348 buildMI(MBB, MBBI, AVR::ADCRdRr)
2349 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
2350 .addReg(DstReg, getKillRegState(DstIsKill))
2351 .addReg(DstReg, getKillRegState(DstIsKill));
2352
2353 if (ImpIsDead)
2354 MIRRC->getOperand(3).setIsDead();
2355
2356 // SREG is always implicitly killed
2357 MIRRC->getOperand(4).setIsKill();
2358
2359 MI.eraseFromParent();
2360 return true;
2361}
2362
2363template <>
2364bool AVRExpandPseudo::expand<AVR::LSRBNRd>(Block &MBB, BlockIt MBBI) {
2365 MachineInstr &MI = *MBBI;
2366 unsigned Imm = MI.getOperand(2).getImm();
2367 switch (Imm) {
2368 case 7:
2369 return expandLSRB7Rd(MBB, MBBI);
2370 default:
2371 llvm_unreachable("unimplemented lsrbn");
2372 return false;
2373 }
2374}
2375
2376bool AVRExpandPseudo::expandASRB6Rd(Block &MBB, BlockIt MBBI) {
2377 MachineInstr &MI = *MBBI;
2378 Register DstReg = MI.getOperand(0).getReg();
2379 bool DstIsDead = MI.getOperand(0).isDead();
2380 bool DstIsKill = MI.getOperand(1).isKill();
2381
2382 // bst r24, 6
2383 // lsl r24
2384 // sbc r24, r24
2385 // bld r24, 0
2386
2387 buildMI(MBB, MBBI, AVR::BST)
2388 .addReg(DstReg)
2389 .addImm(6)
2390 ->getOperand(2)
2391 .setIsUndef(true);
2392
2393 buildMI(MBB, MBBI, AVR::ADDRdRr) // LSL Rd <==> ADD Rd, Rd
2394 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
2395 .addReg(DstReg, RegState::Kill)
2396 .addReg(DstReg, RegState::Kill);
2397
2398 buildMI(MBB, MBBI, AVR::SBCRdRr)
2399 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
2400 .addReg(DstReg, RegState::Kill)
2401 .addReg(DstReg, RegState::Kill);
2402
2403 buildMI(MBB, MBBI, AVR::BLD)
2404 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
2405 .addReg(DstReg, getKillRegState(DstIsKill))
2406 .addImm(0)
2407 ->getOperand(3)
2408 .setIsKill();
2409
2410 MI.eraseFromParent();
2411 return true;
2412}
2413
2414bool AVRExpandPseudo::expandASRB7Rd(Block &MBB, BlockIt MBBI) {
2415 MachineInstr &MI = *MBBI;
2416 Register DstReg = MI.getOperand(0).getReg();
2417 bool DstIsDead = MI.getOperand(0).isDead();
2418 bool DstIsKill = MI.getOperand(1).isKill();
2419 bool ImpIsDead = MI.getOperand(3).isDead();
2420
2421 // lsl r24
2422 // sbc r24, r24
2423
2424 buildMI(MBB, MBBI, AVR::ADDRdRr)
2425 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
2426 .addReg(DstReg, RegState::Kill)
2427 .addReg(DstReg, RegState::Kill);
2428
2429 auto MIRRC =
2430 buildMI(MBB, MBBI, AVR::SBCRdRr)
2431 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
2432 .addReg(DstReg, getKillRegState(DstIsKill))
2433 .addReg(DstReg, getKillRegState(DstIsKill));
2434
2435 if (ImpIsDead)
2436 MIRRC->getOperand(3).setIsDead();
2437
2438 // SREG is always implicitly killed
2439 MIRRC->getOperand(4).setIsKill();
2440
2441 MI.eraseFromParent();
2442 return true;
2443}
2444
2445template <>
2446bool AVRExpandPseudo::expand<AVR::ASRBNRd>(Block &MBB, BlockIt MBBI) {
2447 MachineInstr &MI = *MBBI;
2448 unsigned Imm = MI.getOperand(2).getImm();
2449 switch (Imm) {
2450 case 6:
2451 return expandASRB6Rd(MBB, MBBI);
2452 case 7:
2453 return expandASRB7Rd(MBB, MBBI);
2454 default:
2455 llvm_unreachable("unimplemented asrbn");
2456 return false;
2457 }
2458}
2459
2460template <> bool AVRExpandPseudo::expand<AVR::SEXT>(Block &MBB, BlockIt MBBI) {
2461 MachineInstr &MI = *MBBI;
2462 Register DstLoReg, DstHiReg;
2463 // sext R17:R16, R17
2464 // mov r16, r17
2465 // lsl r17
2466 // sbc r17, r17
2467 // sext R17:R16, R13
2468 // mov r16, r13
2469 // mov r17, r13
2470 // lsl r17
2471 // sbc r17, r17
2472 // sext R17:R16, R16
2473 // mov r17, r16
2474 // lsl r17
2475 // sbc r17, r17
2476 Register DstReg = MI.getOperand(0).getReg();
2477 Register SrcReg = MI.getOperand(1).getReg();
2478 bool DstIsDead = MI.getOperand(0).isDead();
2479 bool SrcIsKill = MI.getOperand(1).isKill();
2480 bool ImpIsDead = MI.getOperand(2).isDead();
2481 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2482
2483 if (SrcReg != DstLoReg)
2484 buildMI(MBB, MBBI, AVR::MOVRdRr)
2485 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
2486 .addReg(SrcReg);
2487
2488 if (SrcReg != DstHiReg) {
2489 auto MOV = buildMI(MBB, MBBI, AVR::MOVRdRr)
2490 .addReg(DstHiReg, RegState::Define)
2491 .addReg(SrcReg);
2492 if (SrcReg != DstLoReg && SrcIsKill)
2493 MOV->getOperand(1).setIsKill();
2494 }
2495
2496 buildMI(MBB, MBBI, AVR::ADDRdRr) // LSL Rd <==> ADD Rd, Rr
2497 .addReg(DstHiReg, RegState::Define)
2498 .addReg(DstHiReg, RegState::Kill)
2499 .addReg(DstHiReg, RegState::Kill);
2500
2501 auto SBC =
2502 buildMI(MBB, MBBI, AVR::SBCRdRr)
2503 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
2504 .addReg(DstHiReg, RegState::Kill)
2505 .addReg(DstHiReg, RegState::Kill);
2506
2507 if (ImpIsDead)
2508 SBC->getOperand(3).setIsDead();
2509
2510 // SREG is always implicitly killed
2511 SBC->getOperand(4).setIsKill();
2512
2513 MI.eraseFromParent();
2514 return true;
2515}
2516
2517template <> bool AVRExpandPseudo::expand<AVR::ZEXT>(Block &MBB, BlockIt MBBI) {
2518 MachineInstr &MI = *MBBI;
2519 Register DstLoReg, DstHiReg;
2520 // zext R25:R24, R20
2521 // mov R24, R20
2522 // eor R25, R25
2523 // zext R25:R24, R24
2524 // eor R25, R25
2525 // zext R25:R24, R25
2526 // mov R24, R25
2527 // eor R25, R25
2528 Register DstReg = MI.getOperand(0).getReg();
2529 Register SrcReg = MI.getOperand(1).getReg();
2530 bool DstIsDead = MI.getOperand(0).isDead();
2531 bool SrcIsKill = MI.getOperand(1).isKill();
2532 bool ImpIsDead = MI.getOperand(2).isDead();
2533 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2534
2535 if (SrcReg != DstLoReg) {
2536 buildMI(MBB, MBBI, AVR::MOVRdRr)
2537 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
2538 .addReg(SrcReg, getKillRegState(SrcIsKill));
2539 }
2540
2541 auto EOR =
2542 buildMI(MBB, MBBI, AVR::EORRdRr)
2543 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
2544 .addReg(DstHiReg, RegState::Kill | RegState::Undef)
2545 .addReg(DstHiReg, RegState::Kill | RegState::Undef);
2546
2547 if (ImpIsDead)
2548 EOR->getOperand(3).setIsDead();
2549
2550 MI.eraseFromParent();
2551 return true;
2552}
2553
2554template <>
2555bool AVRExpandPseudo::expand<AVR::SPREAD>(Block &MBB, BlockIt MBBI) {
2556 const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
2557 MachineInstr &MI = *MBBI;
2558 Register DstLoReg, DstHiReg;
2559 Register DstReg = MI.getOperand(0).getReg();
2560 bool DstIsDead = MI.getOperand(0).isDead();
2561 unsigned Flags = MI.getFlags();
2562 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
2563
2564 // Low part
2565 buildMI(MBB, MBBI, AVR::INRdA)
2566 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
2567 .addImm(STI.getIORegSPL())
2568 .setMIFlags(Flags);
2569
2570 // High part
2571 if (STI.getIORegSPH() != -1) {
2572 buildMI(MBB, MBBI, AVR::INRdA)
2573 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
2574 .addImm(STI.getIORegSPH())
2575 .setMIFlags(Flags);
2576 } else {
2577 // Clear the upper byte if there is no SPH.
2578 auto MI0 =
2579 buildMI(MBB, MBBI, AVR::EORRdRr)
2580 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
2581 .addReg(DstHiReg, RegState::Kill)
2582 .addReg(DstHiReg);
2583 // SREG is implicitly dead.
2584 MI0->getOperand(3).setIsDead();
2585 }
2586
2587 MI.eraseFromParent();
2588 return true;
2589}
2590
2591template <>
2592bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
2593 const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
2594 MachineInstr &MI = *MBBI;
2595 Register SrcLoReg, SrcHiReg;
2596 Register SrcReg = MI.getOperand(1).getReg();
2597 bool SrcIsKill = MI.getOperand(1).isKill();
2598 unsigned Flags = MI.getFlags();
2599 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
2600
2601 // From the XMEGA series manual:
2602 // To prevent corruption when updating the stack pointer from software,
2603 // a write to SPL will automatically disable interrupts
2604 // for up to four instructions or until the next I/O memory write.
2605 if (STI.getELFArch() >= 102) { // An XMEGA device
2606 buildMI(MBB, MBBI, AVR::OUTARr)
2607 .addImm(STI.getIORegSPL())
2608 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
2609 .setMIFlags(Flags);
2610
2611 buildMI(MBB, MBBI, AVR::OUTARr)
2612 .addImm(STI.getIORegSPH())
2613 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
2614 .setMIFlags(Flags);
2615 } else { // Disable interrupts for older devices with SPH (3 extra
2616 // instructions)
2617 if (STI.getIORegSPH() != -1) {
2618 buildMI(MBB, MBBI, AVR::INRdA)
2619 .addReg(STI.getTmpRegister(), RegState::Define)
2620 .addImm(STI.getIORegSREG())
2621 .setMIFlags(Flags);
2622
2623 buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
2624
2625 buildMI(MBB, MBBI, AVR::OUTARr)
2626 .addImm(STI.getIORegSPH())
2627 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
2628 .setMIFlags(Flags);
2629
2630 buildMI(MBB, MBBI, AVR::OUTARr)
2631 .addImm(STI.getIORegSREG())
2632 .addReg(STI.getTmpRegister(), RegState::Kill)
2633 .setMIFlags(Flags);
2634 }
2635
2636 buildMI(MBB, MBBI, AVR::OUTARr)
2637 .addImm(STI.getIORegSPL())
2638 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
2639 .setMIFlags(Flags);
2640 }
2641
2642 MI.eraseFromParent();
2643 return true;
2644}
2645
2646template <> bool AVRExpandPseudo::expand<AVR::FRMSP>(Block &MBB, BlockIt MBBI) {
2647 MachineInstr &MI = *MBBI;
2648 MachineFunction &MF = *MI.getMF();
2650 DebugLoc DL;
2651 Register ASOPointer = MI.getOperand(0).getReg();
2652 int64_t ASOAlignment = MI.getOperand(1).getImm();
2653
2654 // Note: `FrameReg` is an out-param here - passing `ASOPointer` instead would
2655 // overwrite the register we are supposed to write the aligned stack address
2656 // into.
2657 Register FrameReg;
2658
2659 StackOffset ASOOffset =
2661 .getFrameLowering()
2662 ->getFrameIndexReference(MF, AFI->AlignedStackObjectIdx, FrameReg);
2663
2664 TII->copyPhysReg(MBB, MI, DL, ASOPointer, AVR::R29R28, false, false, false);
2665
2666 buildMI(MBB, MI, AVR::ADIWRdKP)
2667 .addReg(ASOPointer, RegState::Define)
2668 .addReg(ASOPointer, RegState::Kill)
2669 .addImm(ASOOffset.getFixed() + ASOAlignment - 1)
2670 .setOperandDead(3); // implicit-def $sreg
2671
2672 buildMI(MBB, MI, AVR::ANDIWRdK)
2673 .addReg(ASOPointer, RegState::Define)
2674 .addReg(ASOPointer, RegState::Kill)
2675 .addImm(-ASOAlignment)
2676 .setOperandDead(3); // implicit-def $sreg
2677
2678 MI.eraseFromParent();
2679 return true;
2680}
2681
2682bool AVRExpandPseudo::expandMI(Block &MBB, BlockIt MBBI) {
2683 MachineInstr &MI = *MBBI;
2684 int Opcode = MBBI->getOpcode();
2685
2686#define EXPAND(Op) \
2687 case Op: \
2688 return expand<Op>(MBB, MI)
2689
2690 switch (Opcode) {
2691 EXPAND(AVR::ADDWRdRr);
2692 EXPAND(AVR::ADCWRdRr);
2693 EXPAND(AVR::ADIWRdKP);
2694 EXPAND(AVR::SUBWRdRr);
2695 EXPAND(AVR::SUBIWRdK);
2696 EXPAND(AVR::SBCWRdRr);
2697 EXPAND(AVR::SBCIWRdK);
2698 EXPAND(AVR::ANDWRdRr);
2699 EXPAND(AVR::ANDIWRdK);
2700 EXPAND(AVR::ORWRdRr);
2701 EXPAND(AVR::ORIWRdK);
2702 EXPAND(AVR::EORWRdRr);
2703 EXPAND(AVR::COMWRd);
2704 EXPAND(AVR::NEGWRd);
2705 EXPAND(AVR::CPWRdRr);
2706 EXPAND(AVR::CPCWRdRr);
2707 EXPAND(AVR::LDIWRdK);
2708 EXPAND(AVR::LDSWRdK);
2709 EXPAND(AVR::LDWRdPtr);
2710 EXPAND(AVR::LDWRdPtrPi);
2711 EXPAND(AVR::LDWRdPtrPd);
2712 case AVR::LDDWRdYQ: // FIXME: Remove this once PR13375 gets fixed.
2713 EXPAND(AVR::LDDWRdPtrQ);
2714 EXPAND(AVR::LPMBRdZ);
2715 EXPAND(AVR::LPMWRdZ);
2716 EXPAND(AVR::LPMWRdZPi);
2717 EXPAND(AVR::ELPMBRdZ);
2718 EXPAND(AVR::ELPMWRdZ);
2719 EXPAND(AVR::ELPMBRdZPi);
2720 EXPAND(AVR::ELPMWRdZPi);
2721 EXPAND(AVR::AtomicLoad8);
2722 EXPAND(AVR::AtomicLoad16);
2723 EXPAND(AVR::AtomicStore8);
2724 EXPAND(AVR::AtomicStore16);
2725 EXPAND(AVR::AtomicFence);
2726 EXPAND(AVR::STSWKRr);
2727 EXPAND(AVR::STWPtrRr);
2728 EXPAND(AVR::STWPtrPiRr);
2729 EXPAND(AVR::STWPtrPdRr);
2730 EXPAND(AVR::STDWPtrQRr);
2731 EXPAND(AVR::STDSPQRr);
2732 EXPAND(AVR::STDWSPQRr);
2733 EXPAND(AVR::INWRdA);
2734 EXPAND(AVR::OUTWARr);
2735 EXPAND(AVR::PUSHWRr);
2736 EXPAND(AVR::POPWRd);
2737 EXPAND(AVR::ROLBRdR1);
2738 EXPAND(AVR::ROLBRdR17);
2739 EXPAND(AVR::RORBRd);
2740 EXPAND(AVR::LSLWRd);
2741 EXPAND(AVR::LSRWRd);
2742 EXPAND(AVR::RORWRd);
2743 EXPAND(AVR::ROLWRd);
2744 EXPAND(AVR::ASRWRd);
2745 EXPAND(AVR::LSLWHiRd);
2746 EXPAND(AVR::LSRWLoRd);
2747 EXPAND(AVR::ASRWLoRd);
2748 EXPAND(AVR::LSLWNRd);
2749 EXPAND(AVR::LSRWNRd);
2750 EXPAND(AVR::ASRWNRd);
2751 EXPAND(AVR::LSLBNRd);
2752 EXPAND(AVR::LSRBNRd);
2753 EXPAND(AVR::ASRBNRd);
2754 EXPAND(AVR::SEXT);
2755 EXPAND(AVR::ZEXT);
2756 EXPAND(AVR::SPREAD);
2757 EXPAND(AVR::SPWRITE);
2758 EXPAND(AVR::FRMSP);
2759 }
2760#undef EXPAND
2761 return false;
2762}
2763
2764} // end of anonymous namespace
2765
2766INITIALIZE_PASS(AVRExpandPseudo, "avr-expand-pseudo", AVR_EXPAND_PSEUDO_NAME,
2767 false, false)
2768
2770 return new AVRExpandPseudo();
2771}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t Imm
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
#define EXPAND(Op)
#define AVR_EXPAND_PSEUDO_NAME
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Expected< BitVector > expand(StringRef S, StringRef Original)
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
Contains AVR-specific information for each MachineFunction.
Utilities relating to AVR registers.
A specific AVR target MCU.
Register getTmpRegister() const
unsigned getELFArch() const
Gets the ELF architecture for the e_flags field of an ELF object file.
const TargetFrameLowering * getFrameLowering() const override
int getIORegRAMPZ() const
Get I/O register addresses.
int getIORegSPL() const
const AVRInstrInfo * getInstrInfo() const override
int getIORegSREG() const
int getIORegSPH() const
const AVRRegisterInfo * getRegisterInfo() const override
The address of a basic block.
Definition Constants.h:1088
A debug info location.
Definition DebugLoc.h:126
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
static MachineOperand CreateBA(const BlockAddress *BA, int64_t Offset, unsigned TargetFlags=0)
@ MO_Immediate
Immediate operand.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
Definition Register.h:20
StackOffset holds a fixed and a scalable offset in bytes.
Definition TypeSize.h:31
static StackOffset getFixed(int64_t Fixed)
Definition TypeSize.h:40
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
virtual bool hasReservedCallFrame(const MachineFunction &MF) const
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
TargetInstrInfo - Interface to description of machine instruction set.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MO_HI
On a symbol operand, this represents the hi part.
@ MO_NEG
On a symbol operand, this represents it has to be negated.
@ MO_LO
On a symbol operand, this represents the lo part.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Kill
The last use of a register.
@ Undef
Value of the register doesn't matter.
@ Define
Register definition.
constexpr RegState getKillRegState(bool B)
constexpr RegState getDeadRegState(bool B)
FunctionPass * createAVRExpandPseudoPass()
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
DWARFExpression::Operation Op
constexpr RegState getUndefRegState(bool B)