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