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