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