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