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