blob: 3dc32576014cd091ed9219de97bc7858a4c988dc [file] [log] [blame]
Dylan McKaya789f402016-11-16 21:58:04 +00001//===-- AVRExpandPseudoInsts.cpp - Expand pseudo instructions -------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains a pass that expands pseudo instructions into target
11// instructions. This pass should be run after register allocation but before
12// the post-regalloc scheduling pass.
13//
14//===----------------------------------------------------------------------===//
15
16#include "AVR.h"
17#include "AVRInstrInfo.h"
18#include "AVRTargetMachine.h"
19#include "MCTargetDesc/AVRMCTargetDesc.h"
20
21#include "llvm/CodeGen/MachineFunctionPass.h"
22#include "llvm/CodeGen/MachineInstrBuilder.h"
23#include "llvm/CodeGen/MachineRegisterInfo.h"
24#include "llvm/Target/TargetRegisterInfo.h"
25
26using namespace llvm;
27
Dylan McKay8cec7eb2016-12-07 11:08:56 +000028#define AVR_EXPAND_PSEUDO_NAME "AVR pseudo instruction expansion pass"
29
Dylan McKaya789f402016-11-16 21:58:04 +000030namespace {
31
32/// Expands "placeholder" instructions marked as pseudo into
33/// actual AVR instructions.
34class AVRExpandPseudo : public MachineFunctionPass {
35public:
36 static char ID;
37
Dylan McKay8cec7eb2016-12-07 11:08:56 +000038 AVRExpandPseudo() : MachineFunctionPass(ID) {
39 initializeAVRExpandPseudoPass(*PassRegistry::getPassRegistry());
40 }
Dylan McKaya789f402016-11-16 21:58:04 +000041
42 bool runOnMachineFunction(MachineFunction &MF) override;
43
Dylan McKay8cec7eb2016-12-07 11:08:56 +000044 StringRef getPassName() const override { return AVR_EXPAND_PSEUDO_NAME; }
Dylan McKaya789f402016-11-16 21:58:04 +000045
46private:
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 unsigned SCRATCH_REGISTER = AVR::R0;
55 /// The IO address of the status register.
56 const unsigned SREG_ADDR = 0x3f;
57
58 bool expandMBB(Block &MBB);
59 bool expandMI(Block &MBB, BlockIt MBBI);
60 template <unsigned OP> bool expand(Block &MBB, BlockIt MBBI);
61
62 MachineInstrBuilder buildMI(Block &MBB, BlockIt MBBI, unsigned Opcode) {
63 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opcode));
64 }
65
66 MachineInstrBuilder buildMI(Block &MBB, BlockIt MBBI, unsigned Opcode,
67 unsigned DstReg) {
68 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opcode), DstReg);
69 }
70
71 MachineRegisterInfo &getRegInfo(Block &MBB) { return MBB.getParent()->getRegInfo(); }
72
73 bool expandArith(unsigned OpLo, unsigned OpHi, Block &MBB, BlockIt MBBI);
74 bool expandLogic(unsigned Op, Block &MBB, BlockIt MBBI);
75 bool expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI);
76
77 template<typename Func>
78 bool expandAtomic(Block &MBB, BlockIt MBBI, Func f);
79
80 template<typename Func>
81 bool expandAtomicBinaryOp(unsigned Opcode, Block &MBB, BlockIt MBBI, Func f);
82
83 bool expandAtomicBinaryOp(unsigned Opcode, Block &MBB, BlockIt MBBI);
84
85 bool expandAtomicArithmeticOp(unsigned MemOpcode,
86 unsigned ArithOpcode,
87 Block &MBB,
88 BlockIt MBBI);
89};
90
91char AVRExpandPseudo::ID = 0;
92
Dylan McKaya789f402016-11-16 21:58:04 +000093bool AVRExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
94 bool Modified = false;
95
96 BlockIt MBBI = MBB.begin(), E = MBB.end();
97 while (MBBI != E) {
98 BlockIt NMBBI = std::next(MBBI);
99 Modified |= expandMI(MBB, MBBI);
100 MBBI = NMBBI;
101 }
102
103 return Modified;
104}
105
106bool AVRExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
107 bool Modified = false;
108
109 const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
110 TRI = STI.getRegisterInfo();
111 TII = STI.getInstrInfo();
112
113 for (Block &MBB : MF) {
114 bool ContinueExpanding = true;
115 unsigned ExpandCount = 0;
116
117 // Continue expanding the block until all pseudos are expanded.
118 do {
119 assert(ExpandCount < 10 && "pseudo expand limit reached");
120
121 bool BlockModified = expandMBB(MBB);
122 Modified |= BlockModified;
123 ExpandCount++;
124
125 ContinueExpanding = BlockModified;
126 } while (ContinueExpanding);
127 }
128
129 return Modified;
130}
131
132bool AVRExpandPseudo::
133expandArith(unsigned OpLo, unsigned OpHi, Block &MBB, BlockIt MBBI) {
134 MachineInstr &MI = *MBBI;
135 unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
136 unsigned DstReg = MI.getOperand(0).getReg();
137 unsigned SrcReg = MI.getOperand(2).getReg();
138 bool DstIsDead = MI.getOperand(0).isDead();
139 bool DstIsKill = MI.getOperand(1).isKill();
140 bool SrcIsKill = MI.getOperand(2).isKill();
141 bool ImpIsDead = MI.getOperand(3).isDead();
142 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
143 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
144
145 buildMI(MBB, MBBI, OpLo)
146 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
147 .addReg(DstLoReg, getKillRegState(DstIsKill))
148 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
149
150 auto MIBHI = buildMI(MBB, MBBI, OpHi)
151 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
152 .addReg(DstHiReg, getKillRegState(DstIsKill))
153 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
154
155 if (ImpIsDead)
156 MIBHI->getOperand(3).setIsDead();
157
158 // SREG is always implicitly killed
159 MIBHI->getOperand(4).setIsKill();
160
161 MI.eraseFromParent();
162 return true;
163}
164
165bool AVRExpandPseudo::
166expandLogic(unsigned Op, Block &MBB, BlockIt MBBI) {
167 MachineInstr &MI = *MBBI;
168 unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
169 unsigned DstReg = MI.getOperand(0).getReg();
170 unsigned SrcReg = MI.getOperand(2).getReg();
171 bool DstIsDead = MI.getOperand(0).isDead();
172 bool DstIsKill = MI.getOperand(1).isKill();
173 bool SrcIsKill = MI.getOperand(2).isKill();
174 bool ImpIsDead = MI.getOperand(3).isDead();
175 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
176 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
177
178 auto MIBLO = buildMI(MBB, MBBI, Op)
179 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
180 .addReg(DstLoReg, getKillRegState(DstIsKill))
181 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
182
183 // SREG is always implicitly dead
184 MIBLO->getOperand(3).setIsDead();
185
186 auto MIBHI = buildMI(MBB, MBBI, Op)
187 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
188 .addReg(DstHiReg, getKillRegState(DstIsKill))
189 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
190
191 if (ImpIsDead)
192 MIBHI->getOperand(3).setIsDead();
193
194 MI.eraseFromParent();
195 return true;
196}
197
198bool AVRExpandPseudo::
199expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI) {
200 MachineInstr &MI = *MBBI;
201 unsigned DstLoReg, DstHiReg;
202 unsigned DstReg = MI.getOperand(0).getReg();
203 bool DstIsDead = MI.getOperand(0).isDead();
204 bool SrcIsKill = MI.getOperand(1).isKill();
205 bool ImpIsDead = MI.getOperand(3).isDead();
206 unsigned Imm = MI.getOperand(2).getImm();
207 unsigned Lo8 = Imm & 0xff;
208 unsigned Hi8 = (Imm >> 8) & 0xff;
209 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
210
211 auto MIBLO = buildMI(MBB, MBBI, Op)
212 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
213 .addReg(DstLoReg, getKillRegState(SrcIsKill))
214 .addImm(Lo8);
215
216 // SREG is always implicitly dead
217 MIBLO->getOperand(3).setIsDead();
218
219 auto MIBHI = buildMI(MBB, MBBI, Op)
220 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
221 .addReg(DstHiReg, getKillRegState(SrcIsKill))
222 .addImm(Hi8);
223
224 if (ImpIsDead)
225 MIBHI->getOperand(3).setIsDead();
226
227 MI.eraseFromParent();
228 return true;
229}
230
231template <>
232bool AVRExpandPseudo::expand<AVR::ADDWRdRr>(Block &MBB, BlockIt MBBI) {
233 return expandArith(AVR::ADDRdRr, AVR::ADCRdRr, MBB, MBBI);
234}
235
236template <>
237bool AVRExpandPseudo::expand<AVR::ADCWRdRr>(Block &MBB, BlockIt MBBI) {
238 return expandArith(AVR::ADCRdRr, AVR::ADCRdRr, MBB, MBBI);
239}
240
241template <>
242bool AVRExpandPseudo::expand<AVR::SUBWRdRr>(Block &MBB, BlockIt MBBI) {
243 return expandArith(AVR::SUBRdRr, AVR::SBCRdRr, MBB, MBBI);
244}
245
246template <>
247bool AVRExpandPseudo::expand<AVR::SUBIWRdK>(Block &MBB, BlockIt MBBI) {
248 MachineInstr &MI = *MBBI;
249 unsigned DstLoReg, DstHiReg;
250 unsigned DstReg = MI.getOperand(0).getReg();
251 bool DstIsDead = MI.getOperand(0).isDead();
252 bool SrcIsKill = MI.getOperand(1).isKill();
253 bool ImpIsDead = MI.getOperand(3).isDead();
254 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
255
256 auto MIBLO = buildMI(MBB, MBBI, AVR::SUBIRdK)
257 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
258 .addReg(DstLoReg, getKillRegState(SrcIsKill));
259
260 auto MIBHI = buildMI(MBB, MBBI, AVR::SBCIRdK)
261 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
262 .addReg(DstHiReg, getKillRegState(SrcIsKill));
263
264 switch (MI.getOperand(2).getType()) {
265 case MachineOperand::MO_GlobalAddress: {
266 const GlobalValue *GV = MI.getOperand(2).getGlobal();
267 int64_t Offs = MI.getOperand(2).getOffset();
268 unsigned TF = MI.getOperand(2).getTargetFlags();
269 MIBLO.addGlobalAddress(GV, Offs, TF | AVRII::MO_NEG | AVRII::MO_LO);
270 MIBHI.addGlobalAddress(GV, Offs, TF | AVRII::MO_NEG | AVRII::MO_HI);
271 break;
272 }
273 case MachineOperand::MO_Immediate: {
274 unsigned Imm = MI.getOperand(2).getImm();
275 MIBLO.addImm(Imm & 0xff);
276 MIBHI.addImm((Imm >> 8) & 0xff);
277 break;
278 }
279 default:
280 llvm_unreachable("Unknown operand type!");
281 }
282
283 if (ImpIsDead)
284 MIBHI->getOperand(3).setIsDead();
285
286 // SREG is always implicitly killed
287 MIBHI->getOperand(4).setIsKill();
288
289 MI.eraseFromParent();
290 return true;
291}
292
293template <>
294bool AVRExpandPseudo::expand<AVR::SBCWRdRr>(Block &MBB, BlockIt MBBI) {
295 return expandArith(AVR::SBCRdRr, AVR::SBCRdRr, MBB, MBBI);
296}
297
298template <>
299bool AVRExpandPseudo::expand<AVR::SBCIWRdK>(Block &MBB, BlockIt MBBI) {
300 MachineInstr &MI = *MBBI;
301 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
302 unsigned DstReg = MI.getOperand(0).getReg();
303 bool DstIsDead = MI.getOperand(0).isDead();
304 bool SrcIsKill = MI.getOperand(1).isKill();
305 bool ImpIsDead = MI.getOperand(3).isDead();
306 unsigned Imm = MI.getOperand(2).getImm();
307 unsigned Lo8 = Imm & 0xff;
308 unsigned Hi8 = (Imm >> 8) & 0xff;
309 OpLo = AVR::SBCIRdK;
310 OpHi = AVR::SBCIRdK;
311 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
312
313 auto MIBLO = buildMI(MBB, MBBI, OpLo)
314 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
315 .addReg(DstLoReg, getKillRegState(SrcIsKill))
316 .addImm(Lo8);
317
318 // SREG is always implicitly killed
319 MIBLO->getOperand(4).setIsKill();
320
321 auto MIBHI = buildMI(MBB, MBBI, OpHi)
322 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
323 .addReg(DstHiReg, getKillRegState(SrcIsKill))
324 .addImm(Hi8);
325
326 if (ImpIsDead)
327 MIBHI->getOperand(3).setIsDead();
328
329 // SREG is always implicitly killed
330 MIBHI->getOperand(4).setIsKill();
331
332 MI.eraseFromParent();
333 return true;
334}
335
336template <>
337bool AVRExpandPseudo::expand<AVR::ANDWRdRr>(Block &MBB, BlockIt MBBI) {
338 return expandLogic(AVR::ANDRdRr, MBB, MBBI);
339}
340
341template <>
342bool AVRExpandPseudo::expand<AVR::ANDIWRdK>(Block &MBB, BlockIt MBBI) {
343 return expandLogicImm(AVR::ANDIRdK, MBB, MBBI);
344}
345
346template <>
347bool AVRExpandPseudo::expand<AVR::ORWRdRr>(Block &MBB, BlockIt MBBI) {
348 return expandLogic(AVR::ORRdRr, MBB, MBBI);
349}
350
351template <>
352bool AVRExpandPseudo::expand<AVR::ORIWRdK>(Block &MBB, BlockIt MBBI) {
353 return expandLogicImm(AVR::ORIRdK, MBB, MBBI);
354}
355
356template <>
357bool AVRExpandPseudo::expand<AVR::EORWRdRr>(Block &MBB, BlockIt MBBI) {
358 return expandLogic(AVR::EORRdRr, MBB, MBBI);
359}
360
361template <>
362bool AVRExpandPseudo::expand<AVR::COMWRd>(Block &MBB, BlockIt MBBI) {
363 MachineInstr &MI = *MBBI;
364 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
365 unsigned DstReg = MI.getOperand(0).getReg();
366 bool DstIsDead = MI.getOperand(0).isDead();
367 bool DstIsKill = MI.getOperand(1).isKill();
368 bool ImpIsDead = MI.getOperand(2).isDead();
369 OpLo = AVR::COMRd;
370 OpHi = AVR::COMRd;
371 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
372
373 auto MIBLO = buildMI(MBB, MBBI, OpLo)
374 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
375 .addReg(DstLoReg, getKillRegState(DstIsKill));
376
377 // SREG is always implicitly dead
378 MIBLO->getOperand(2).setIsDead();
379
380 auto MIBHI = buildMI(MBB, MBBI, OpHi)
381 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
382 .addReg(DstHiReg, getKillRegState(DstIsKill));
383
384 if (ImpIsDead)
385 MIBHI->getOperand(2).setIsDead();
386
387 MI.eraseFromParent();
388 return true;
389}
390
391template <>
392bool AVRExpandPseudo::expand<AVR::CPWRdRr>(Block &MBB, BlockIt MBBI) {
393 MachineInstr &MI = *MBBI;
394 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
395 unsigned DstReg = MI.getOperand(0).getReg();
396 unsigned SrcReg = MI.getOperand(1).getReg();
397 bool DstIsKill = MI.getOperand(0).isKill();
398 bool SrcIsKill = MI.getOperand(1).isKill();
399 bool ImpIsDead = MI.getOperand(2).isDead();
400 OpLo = AVR::CPRdRr;
401 OpHi = AVR::CPCRdRr;
402 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
403 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
404
405 // Low part
406 buildMI(MBB, MBBI, OpLo)
407 .addReg(DstLoReg, getKillRegState(DstIsKill))
408 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
409
410 auto MIBHI = buildMI(MBB, MBBI, OpHi)
411 .addReg(DstHiReg, getKillRegState(DstIsKill))
412 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
413
414 if (ImpIsDead)
415 MIBHI->getOperand(2).setIsDead();
416
417 // SREG is always implicitly killed
418 MIBHI->getOperand(3).setIsKill();
419
420 MI.eraseFromParent();
421 return true;
422}
423
424template <>
425bool AVRExpandPseudo::expand<AVR::CPCWRdRr>(Block &MBB, BlockIt MBBI) {
426 MachineInstr &MI = *MBBI;
427 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
428 unsigned DstReg = MI.getOperand(0).getReg();
429 unsigned SrcReg = MI.getOperand(1).getReg();
430 bool DstIsKill = MI.getOperand(0).isKill();
431 bool SrcIsKill = MI.getOperand(1).isKill();
432 bool ImpIsDead = MI.getOperand(2).isDead();
433 OpLo = AVR::CPCRdRr;
434 OpHi = AVR::CPCRdRr;
435 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
436 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
437
438 auto MIBLO = buildMI(MBB, MBBI, OpLo)
439 .addReg(DstLoReg, getKillRegState(DstIsKill))
440 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
441
442 // SREG is always implicitly killed
443 MIBLO->getOperand(3).setIsKill();
444
445 auto MIBHI = buildMI(MBB, MBBI, OpHi)
446 .addReg(DstHiReg, getKillRegState(DstIsKill))
447 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
448
449 if (ImpIsDead)
450 MIBHI->getOperand(2).setIsDead();
451
452 // SREG is always implicitly killed
453 MIBHI->getOperand(3).setIsKill();
454
455 MI.eraseFromParent();
456 return true;
457}
458
459template <>
460bool AVRExpandPseudo::expand<AVR::LDIWRdK>(Block &MBB, BlockIt MBBI) {
461 MachineInstr &MI = *MBBI;
462 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
463 unsigned DstReg = MI.getOperand(0).getReg();
464 bool DstIsDead = MI.getOperand(0).isDead();
465 OpLo = AVR::LDIRdK;
466 OpHi = AVR::LDIRdK;
467 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
468
469 auto MIBLO = buildMI(MBB, MBBI, OpLo)
470 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead));
471
472 auto MIBHI = buildMI(MBB, MBBI, OpHi)
473 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead));
474
475 switch (MI.getOperand(1).getType()) {
476 case MachineOperand::MO_GlobalAddress: {
477 const GlobalValue *GV = MI.getOperand(1).getGlobal();
478 int64_t Offs = MI.getOperand(1).getOffset();
479 unsigned TF = MI.getOperand(1).getTargetFlags();
480
481 MIBLO.addGlobalAddress(GV, Offs, TF | AVRII::MO_LO);
482 MIBHI.addGlobalAddress(GV, Offs, TF | AVRII::MO_HI);
483 break;
484 }
485 case MachineOperand::MO_BlockAddress: {
486 const BlockAddress *BA = MI.getOperand(1).getBlockAddress();
487 unsigned TF = MI.getOperand(1).getTargetFlags();
488
489 MIBLO.addOperand(MachineOperand::CreateBA(BA, TF | AVRII::MO_LO));
490 MIBHI.addOperand(MachineOperand::CreateBA(BA, TF | AVRII::MO_HI));
491 break;
492 }
493 case MachineOperand::MO_Immediate: {
494 unsigned Imm = MI.getOperand(1).getImm();
495
496 MIBLO.addImm(Imm & 0xff);
497 MIBHI.addImm((Imm >> 8) & 0xff);
498 break;
499 }
500 default:
501 llvm_unreachable("Unknown operand type!");
502 }
503
504 MI.eraseFromParent();
505 return true;
506}
507
508template <>
509bool AVRExpandPseudo::expand<AVR::LDSWRdK>(Block &MBB, BlockIt MBBI) {
510 MachineInstr &MI = *MBBI;
511 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
512 unsigned DstReg = MI.getOperand(0).getReg();
513 bool DstIsDead = MI.getOperand(0).isDead();
514 OpLo = AVR::LDSRdK;
515 OpHi = AVR::LDSRdK;
516 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
517
518 auto MIBLO = buildMI(MBB, MBBI, OpLo)
519 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead));
520
521 auto MIBHI = buildMI(MBB, MBBI, OpHi)
522 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead));
523
524 switch (MI.getOperand(1).getType()) {
525 case MachineOperand::MO_GlobalAddress: {
526 const GlobalValue *GV = MI.getOperand(1).getGlobal();
527 int64_t Offs = MI.getOperand(1).getOffset();
528 unsigned TF = MI.getOperand(1).getTargetFlags();
529
530 MIBLO.addGlobalAddress(GV, Offs, TF);
531 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
532 break;
533 }
534 case MachineOperand::MO_Immediate: {
535 unsigned Imm = MI.getOperand(1).getImm();
536
537 MIBLO.addImm(Imm);
538 MIBHI.addImm(Imm + 1);
539 break;
540 }
541 default:
542 llvm_unreachable("Unknown operand type!");
543 }
544
545 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
546 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
547
548 MI.eraseFromParent();
549 return true;
550}
551
552template <>
553bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) {
554 MachineInstr &MI = *MBBI;
555 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
556 unsigned DstReg = MI.getOperand(0).getReg();
557 unsigned SrcReg = MI.getOperand(1).getReg();
558 bool DstIsDead = MI.getOperand(0).isDead();
559 bool SrcIsKill = MI.getOperand(1).isKill();
560 OpLo = AVR::LDRdPtr;
561 OpHi = AVR::LDDRdPtrQ;
562 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
563
564 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
565
566 auto MIBLO = buildMI(MBB, MBBI, OpLo)
567 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
568 .addReg(SrcReg);
569
570 auto MIBHI = buildMI(MBB, MBBI, OpHi)
571 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
572 .addReg(SrcReg, getKillRegState(SrcIsKill))
573 .addImm(1);
574
575 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
576 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
577
578 MI.eraseFromParent();
579 return true;
580}
581
582template <>
583bool AVRExpandPseudo::expand<AVR::LDWRdPtrPi>(Block &MBB, BlockIt MBBI) {
584 MachineInstr &MI = *MBBI;
585 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
586 unsigned DstReg = MI.getOperand(0).getReg();
587 unsigned SrcReg = MI.getOperand(1).getReg();
588 bool DstIsDead = MI.getOperand(0).isDead();
589 bool SrcIsDead = MI.getOperand(1).isKill();
590 OpLo = AVR::LDRdPtrPi;
591 OpHi = AVR::LDRdPtrPi;
592 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
593
594 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
595
596 auto MIBLO = buildMI(MBB, MBBI, OpLo)
597 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
598 .addReg(SrcReg, RegState::Define)
599 .addReg(SrcReg, RegState::Kill);
600
601 auto MIBHI = buildMI(MBB, MBBI, OpHi)
602 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
603 .addReg(SrcReg, RegState::Define | getDeadRegState(SrcIsDead))
604 .addReg(SrcReg, RegState::Kill);
605
606 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
607 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
608
609 MI.eraseFromParent();
610 return true;
611}
612
613template <>
614bool AVRExpandPseudo::expand<AVR::LDWRdPtrPd>(Block &MBB, BlockIt MBBI) {
615 MachineInstr &MI = *MBBI;
616 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
617 unsigned DstReg = MI.getOperand(0).getReg();
618 unsigned SrcReg = MI.getOperand(1).getReg();
619 bool DstIsDead = MI.getOperand(0).isDead();
620 bool SrcIsDead = MI.getOperand(1).isKill();
621 OpLo = AVR::LDRdPtrPd;
622 OpHi = AVR::LDRdPtrPd;
623 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
624
625 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
626
627 auto MIBHI = buildMI(MBB, MBBI, OpHi)
628 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
629 .addReg(SrcReg, RegState::Define)
630 .addReg(SrcReg, RegState::Kill);
631
632 auto MIBLO = buildMI(MBB, MBBI, OpLo)
633 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
634 .addReg(SrcReg, RegState::Define | getDeadRegState(SrcIsDead))
635 .addReg(SrcReg, RegState::Kill);
636
637 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
638 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
639
640 MI.eraseFromParent();
641 return true;
642}
643
644template <>
645bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
646 MachineInstr &MI = *MBBI;
647 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
648 unsigned DstReg = MI.getOperand(0).getReg();
649 unsigned SrcReg = MI.getOperand(1).getReg();
650 unsigned Imm = MI.getOperand(2).getImm();
651 bool DstIsDead = MI.getOperand(0).isDead();
652 bool SrcIsKill = MI.getOperand(1).isKill();
653 OpLo = AVR::LDDRdPtrQ;
654 OpHi = AVR::LDDRdPtrQ;
655 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
656
657 assert(Imm < 63 && "Offset is out of range");
Dylan McKay8cec7eb2016-12-07 11:08:56 +0000658
659 unsigned TmpLoReg = DstLoReg;
660 unsigned TmpHiReg = DstHiReg;
661
662 // HACK: We shouldn't have instances of this instruction
663 // where src==dest because the instruction itself is
664 // marked earlyclobber. We do however get this instruction when
665 // loading from stack slots where the earlyclobber isn't useful.
666 //
667 // In this case, just use a temporary register.
668 if (DstReg == SrcReg) {
669 TmpLoReg = SCRATCH_REGISTER;
670 TmpHiReg = SCRATCH_REGISTER;
671 }
Dylan McKaya789f402016-11-16 21:58:04 +0000672
673 auto MIBLO = buildMI(MBB, MBBI, OpLo)
Dylan McKay8cec7eb2016-12-07 11:08:56 +0000674 .addReg(TmpLoReg, RegState::Define | getDeadRegState(DstIsDead))
Dylan McKaya789f402016-11-16 21:58:04 +0000675 .addReg(SrcReg)
676 .addImm(Imm);
677
Dylan McKay8cec7eb2016-12-07 11:08:56 +0000678 // Push the low part of the temporary register to the stack.
679 if (TmpLoReg != DstLoReg)
680 buildMI(MBB, MBBI, AVR::PUSHRr)
681 .addReg(AVR::R0);
682
Dylan McKaya789f402016-11-16 21:58:04 +0000683 auto MIBHI = buildMI(MBB, MBBI, OpHi)
Dylan McKay8cec7eb2016-12-07 11:08:56 +0000684 .addReg(TmpHiReg, RegState::Define | getDeadRegState(DstIsDead))
Dylan McKaya789f402016-11-16 21:58:04 +0000685 .addReg(SrcReg, getKillRegState(SrcIsKill))
686 .addImm(Imm + 1);
687
Dylan McKay8cec7eb2016-12-07 11:08:56 +0000688 // If we need to use a temporary register.
689 if (TmpHiReg != DstHiReg) {
690 // Move the hi result from the tmp register to the destination.
691 buildMI(MBB, MBBI, AVR::MOVRdRr)
692 .addReg(DstHiReg).addReg(SCRATCH_REGISTER);
693
694 // Pop the lo result calculated previously and put it into
695 // the lo destination.
696 buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
697 }
698
Dylan McKaya789f402016-11-16 21:58:04 +0000699 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
700 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
701
702 MI.eraseFromParent();
703 return true;
704}
705
706template<typename Func>
707bool AVRExpandPseudo::expandAtomic(Block &MBB, BlockIt MBBI, Func f) {
708 // Remove the pseudo instruction.
709 MachineInstr &MI = *MBBI;
710
711 // Store the SREG.
712 buildMI(MBB, MBBI, AVR::INRdA)
713 .addReg(SCRATCH_REGISTER, RegState::Define)
714 .addImm(SREG_ADDR);
715
716 // Disable exceptions.
717 buildMI(MBB, MBBI, AVR::BCLRs).addImm(7); // CLI
718
719 f(MI);
720
721 // Restore the status reg.
722 buildMI(MBB, MBBI, AVR::OUTARr)
723 .addImm(SREG_ADDR)
724 .addReg(SCRATCH_REGISTER);
725
726 MI.eraseFromParent();
727 return true;
728}
729
730template<typename Func>
731bool AVRExpandPseudo::expandAtomicBinaryOp(unsigned Opcode,
732 Block &MBB,
733 BlockIt MBBI,
734 Func f) {
735 return expandAtomic(MBB, MBBI, [&](MachineInstr &MI) {
736 auto Op1 = MI.getOperand(0);
737 auto Op2 = MI.getOperand(1);
738
739 MachineInstr &NewInst = *buildMI(MBB, MBBI, Opcode)
740 .addOperand(Op1).addOperand(Op2)
741 .getInstr();
742 f(NewInst);
743 });
744}
745
746bool AVRExpandPseudo::expandAtomicBinaryOp(unsigned Opcode,
747 Block &MBB,
748 BlockIt MBBI) {
749 return expandAtomicBinaryOp(Opcode, MBB, MBBI, [](MachineInstr &MI) {});
750}
751
752bool AVRExpandPseudo::expandAtomicArithmeticOp(unsigned Width,
753 unsigned ArithOpcode,
754 Block &MBB,
755 BlockIt MBBI) {
756 return expandAtomic(MBB, MBBI, [&](MachineInstr &MI) {
757 auto Op1 = MI.getOperand(0);
758 auto Op2 = MI.getOperand(1);
759
760 unsigned LoadOpcode = (Width == 8) ? AVR::LDRdPtr : AVR::LDWRdPtr;
761 unsigned StoreOpcode = (Width == 8) ? AVR::STPtrRr : AVR::STWPtrRr;
762
763 // Create the load
764 buildMI(MBB, MBBI, LoadOpcode).addOperand(Op1).addOperand(Op2);
765
766 // Create the arithmetic op
767 buildMI(MBB, MBBI, ArithOpcode)
768 .addOperand(Op1).addOperand(Op1)
769 .addOperand(Op2);
770
771 // Create the store
772 buildMI(MBB, MBBI, StoreOpcode).addOperand(Op2).addOperand(Op1);
773 });
774}
775
776template<>
777bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(Block &MBB, BlockIt MBBI) {
778 return expandAtomicBinaryOp(AVR::LDRdPtr, MBB, MBBI);
779}
780
781template<>
782bool AVRExpandPseudo::expand<AVR::AtomicLoad16>(Block &MBB, BlockIt MBBI) {
783 return expandAtomicBinaryOp(AVR::LDWRdPtr, MBB, MBBI);
784}
785
786template<>
787bool AVRExpandPseudo::expand<AVR::AtomicStore8>(Block &MBB, BlockIt MBBI) {
788 return expandAtomicBinaryOp(AVR::STPtrRr, MBB, MBBI);
789}
790
791template<>
792bool AVRExpandPseudo::expand<AVR::AtomicStore16>(Block &MBB, BlockIt MBBI) {
793 return expandAtomicBinaryOp(AVR::STWPtrRr, MBB, MBBI);
794}
795
796template<>
797bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd8>(Block &MBB, BlockIt MBBI) {
798 return expandAtomicArithmeticOp(8, AVR::ADDRdRr, MBB, MBBI);
799}
800
801template<>
802bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd16>(Block &MBB, BlockIt MBBI) {
803 return expandAtomicArithmeticOp(16, AVR::ADDWRdRr, MBB, MBBI);
804}
805
806template<>
807bool AVRExpandPseudo::expand<AVR::AtomicLoadSub8>(Block &MBB, BlockIt MBBI) {
808 return expandAtomicArithmeticOp(8, AVR::SUBRdRr, MBB, MBBI);
809}
810
811template<>
812bool AVRExpandPseudo::expand<AVR::AtomicLoadSub16>(Block &MBB, BlockIt MBBI) {
813 return expandAtomicArithmeticOp(16, AVR::SUBWRdRr, MBB, MBBI);
814}
815
816template<>
817bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd8>(Block &MBB, BlockIt MBBI) {
818 return expandAtomicArithmeticOp(8, AVR::ANDRdRr, MBB, MBBI);
819}
820
821template<>
822bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd16>(Block &MBB, BlockIt MBBI) {
823 return expandAtomicArithmeticOp(16, AVR::ANDWRdRr, MBB, MBBI);
824}
825
826template<>
827bool AVRExpandPseudo::expand<AVR::AtomicLoadOr8>(Block &MBB, BlockIt MBBI) {
828 return expandAtomicArithmeticOp(8, AVR::ORRdRr, MBB, MBBI);
829}
830
831template<>
832bool AVRExpandPseudo::expand<AVR::AtomicLoadOr16>(Block &MBB, BlockIt MBBI) {
833 return expandAtomicArithmeticOp(16, AVR::ORWRdRr, MBB, MBBI);
834}
835
836template<>
837bool AVRExpandPseudo::expand<AVR::AtomicLoadXor8>(Block &MBB, BlockIt MBBI) {
838 return expandAtomicArithmeticOp(8, AVR::EORRdRr, MBB, MBBI);
839}
840
841template<>
842bool AVRExpandPseudo::expand<AVR::AtomicLoadXor16>(Block &MBB, BlockIt MBBI) {
843 return expandAtomicArithmeticOp(16, AVR::EORWRdRr, MBB, MBBI);
844}
845
846template<>
847bool AVRExpandPseudo::expand<AVR::AtomicFence>(Block &MBB, BlockIt MBBI) {
848 // On AVR, there is only one core and so atomic fences do nothing.
849 MBBI->eraseFromParent();
850 return true;
851}
852
853template <>
854bool AVRExpandPseudo::expand<AVR::STSWKRr>(Block &MBB, BlockIt MBBI) {
855 MachineInstr &MI = *MBBI;
856 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
857 unsigned SrcReg = MI.getOperand(1).getReg();
858 bool SrcIsKill = MI.getOperand(1).isKill();
859 OpLo = AVR::STSKRr;
860 OpHi = AVR::STSKRr;
861 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
862
863 // Write the high byte first in case this address belongs to a special
864 // I/O address with a special temporary register.
865 auto MIBHI = buildMI(MBB, MBBI, OpHi);
866 auto MIBLO = buildMI(MBB, MBBI, OpLo);
867
868 switch (MI.getOperand(0).getType()) {
869 case MachineOperand::MO_GlobalAddress: {
870 const GlobalValue *GV = MI.getOperand(0).getGlobal();
871 int64_t Offs = MI.getOperand(0).getOffset();
872 unsigned TF = MI.getOperand(0).getTargetFlags();
873
874 MIBLO.addGlobalAddress(GV, Offs, TF);
875 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
876 break;
877 }
878 case MachineOperand::MO_Immediate: {
879 unsigned Imm = MI.getOperand(0).getImm();
880
881 MIBLO.addImm(Imm);
882 MIBHI.addImm(Imm + 1);
883 break;
884 }
885 default:
886 llvm_unreachable("Unknown operand type!");
887 }
888
889 MIBLO.addReg(SrcLoReg, getKillRegState(SrcIsKill));
890 MIBHI.addReg(SrcHiReg, getKillRegState(SrcIsKill));
891
892 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
893 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
894
895 MI.eraseFromParent();
896 return true;
897}
898
899template <>
900bool AVRExpandPseudo::expand<AVR::STWPtrRr>(Block &MBB, BlockIt MBBI) {
901 MachineInstr &MI = *MBBI;
902 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
903 unsigned DstReg = MI.getOperand(0).getReg();
904 unsigned SrcReg = MI.getOperand(1).getReg();
905 bool DstIsKill = MI.getOperand(0).isKill();
906 bool SrcIsKill = MI.getOperand(1).isKill();
907 OpLo = AVR::STPtrRr;
908 OpHi = AVR::STDPtrQRr;
909 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
910
911 //:TODO: need to reverse this order like inw and stsw?
912 auto MIBLO = buildMI(MBB, MBBI, OpLo)
913 .addReg(DstReg)
914 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
915
916 auto MIBHI = buildMI(MBB, MBBI, OpHi)
917 .addReg(DstReg, getKillRegState(DstIsKill))
918 .addImm(1)
919 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
920
921 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
922 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
923
924 MI.eraseFromParent();
925 return true;
926}
927
928template <>
929bool AVRExpandPseudo::expand<AVR::STWPtrPiRr>(Block &MBB, BlockIt MBBI) {
930 MachineInstr &MI = *MBBI;
931 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
932 unsigned DstReg = MI.getOperand(0).getReg();
933 unsigned SrcReg = MI.getOperand(2).getReg();
934 unsigned Imm = MI.getOperand(3).getImm();
935 bool DstIsDead = MI.getOperand(0).isDead();
936 bool SrcIsKill = MI.getOperand(2).isKill();
937 OpLo = AVR::STPtrPiRr;
938 OpHi = AVR::STPtrPiRr;
939 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
940
941 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
942
943 auto MIBLO = buildMI(MBB, MBBI, OpLo)
944 .addReg(DstReg, RegState::Define)
945 .addReg(DstReg, RegState::Kill)
946 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
947 .addImm(Imm);
948
949 auto MIBHI = buildMI(MBB, MBBI, OpHi)
950 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
951 .addReg(DstReg, RegState::Kill)
952 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
953 .addImm(Imm);
954
955 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
956 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
957
958 MI.eraseFromParent();
959 return true;
960}
961
962template <>
963bool AVRExpandPseudo::expand<AVR::STWPtrPdRr>(Block &MBB, BlockIt MBBI) {
964 MachineInstr &MI = *MBBI;
965 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
966 unsigned DstReg = MI.getOperand(0).getReg();
967 unsigned SrcReg = MI.getOperand(2).getReg();
968 unsigned Imm = MI.getOperand(3).getImm();
969 bool DstIsDead = MI.getOperand(0).isDead();
970 bool SrcIsKill = MI.getOperand(2).isKill();
971 OpLo = AVR::STPtrPdRr;
972 OpHi = AVR::STPtrPdRr;
973 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
974
975 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
976
977 auto MIBHI = buildMI(MBB, MBBI, OpHi)
978 .addReg(DstReg, RegState::Define)
979 .addReg(DstReg, RegState::Kill)
980 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
981 .addImm(Imm);
982
983 auto MIBLO = buildMI(MBB, MBBI, OpLo)
984 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
985 .addReg(DstReg, RegState::Kill)
986 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
987 .addImm(Imm);
988
989 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
990 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
991
992 MI.eraseFromParent();
993 return true;
994}
995
996template <>
997bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(Block &MBB, BlockIt MBBI) {
998 MachineInstr &MI = *MBBI;
999 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1000 unsigned DstReg = MI.getOperand(0).getReg();
1001 unsigned SrcReg = MI.getOperand(2).getReg();
1002 unsigned Imm = MI.getOperand(1).getImm();
1003 bool DstIsKill = MI.getOperand(0).isKill();
1004 bool SrcIsKill = MI.getOperand(2).isKill();
1005 OpLo = AVR::STDPtrQRr;
1006 OpHi = AVR::STDPtrQRr;
1007 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1008
1009 assert(Imm < 63 && "Offset is out of range");
1010
1011 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1012 .addReg(DstReg)
1013 .addImm(Imm)
1014 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
1015
1016 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1017 .addReg(DstReg, getKillRegState(DstIsKill))
1018 .addImm(Imm + 1)
1019 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
1020
1021 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1022 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1023
1024 MI.eraseFromParent();
1025 return true;
1026}
1027
1028template <>
1029bool AVRExpandPseudo::expand<AVR::INWRdA>(Block &MBB, BlockIt MBBI) {
1030 MachineInstr &MI = *MBBI;
1031 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1032 unsigned Imm = MI.getOperand(1).getImm();
1033 unsigned DstReg = MI.getOperand(0).getReg();
1034 bool DstIsDead = MI.getOperand(0).isDead();
1035 OpLo = AVR::INRdA;
1036 OpHi = AVR::INRdA;
1037 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1038
1039 assert(Imm < 63 && "Address is out of range");
1040
1041 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1042 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1043 .addImm(Imm);
1044
1045 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1046 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1047 .addImm(Imm + 1);
1048
1049 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1050 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1051
1052 MI.eraseFromParent();
1053 return true;
1054}
1055
1056template <>
1057bool AVRExpandPseudo::expand<AVR::OUTWARr>(Block &MBB, BlockIt MBBI) {
1058 MachineInstr &MI = *MBBI;
1059 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1060 unsigned Imm = MI.getOperand(0).getImm();
1061 unsigned SrcReg = MI.getOperand(1).getReg();
1062 bool SrcIsKill = MI.getOperand(1).isKill();
1063 OpLo = AVR::OUTARr;
1064 OpHi = AVR::OUTARr;
1065 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1066
1067 assert(Imm < 63 && "Address is out of range");
1068
1069 // 16 bit I/O writes need the high byte first
1070 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1071 .addImm(Imm + 1)
1072 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
1073
1074 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1075 .addImm(Imm)
1076 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
1077
1078 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1079 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1080
1081 MI.eraseFromParent();
1082 return true;
1083}
1084
1085template <>
1086bool AVRExpandPseudo::expand<AVR::PUSHWRr>(Block &MBB, BlockIt MBBI) {
1087 MachineInstr &MI = *MBBI;
1088 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1089 unsigned SrcReg = MI.getOperand(0).getReg();
1090 bool SrcIsKill = MI.getOperand(0).isKill();
1091 unsigned Flags = MI.getFlags();
1092 OpLo = AVR::PUSHRr;
1093 OpHi = AVR::PUSHRr;
1094 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1095
1096 // Low part
1097 buildMI(MBB, MBBI, OpLo)
1098 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1099 .setMIFlags(Flags);
1100
1101 // High part
1102 buildMI(MBB, MBBI, OpHi)
1103 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1104 .setMIFlags(Flags);
1105
1106 MI.eraseFromParent();
1107 return true;
1108}
1109
1110template <>
1111bool AVRExpandPseudo::expand<AVR::POPWRd>(Block &MBB, BlockIt MBBI) {
1112 MachineInstr &MI = *MBBI;
1113 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1114 unsigned DstReg = MI.getOperand(0).getReg();
1115 unsigned Flags = MI.getFlags();
1116 OpLo = AVR::POPRd;
1117 OpHi = AVR::POPRd;
1118 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1119
1120 buildMI(MBB, MBBI, OpHi, DstHiReg).setMIFlags(Flags); // High
1121 buildMI(MBB, MBBI, OpLo, DstLoReg).setMIFlags(Flags); // Low
1122
1123 MI.eraseFromParent();
1124 return true;
1125}
1126
1127template <>
1128bool AVRExpandPseudo::expand<AVR::LSLWRd>(Block &MBB, BlockIt MBBI) {
1129 MachineInstr &MI = *MBBI;
1130 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1131 unsigned DstReg = MI.getOperand(0).getReg();
1132 bool DstIsDead = MI.getOperand(0).isDead();
1133 bool DstIsKill = MI.getOperand(1).isKill();
1134 bool ImpIsDead = MI.getOperand(2).isDead();
1135 OpLo = AVR::LSLRd;
1136 OpHi = AVR::ROLRd;
1137 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1138
1139 // Low part
1140 buildMI(MBB, MBBI, OpLo)
1141 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1142 .addReg(DstLoReg, getKillRegState(DstIsKill));
1143
1144 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1145 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1146 .addReg(DstHiReg, getKillRegState(DstIsKill));
1147
1148 if (ImpIsDead)
1149 MIBHI->getOperand(2).setIsDead();
1150
1151 // SREG is always implicitly killed
1152 MIBHI->getOperand(3).setIsKill();
1153
1154 MI.eraseFromParent();
1155 return true;
1156}
1157
1158template <>
1159bool AVRExpandPseudo::expand<AVR::LSRWRd>(Block &MBB, BlockIt MBBI) {
1160 MachineInstr &MI = *MBBI;
1161 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1162 unsigned DstReg = MI.getOperand(0).getReg();
1163 bool DstIsDead = MI.getOperand(0).isDead();
1164 bool DstIsKill = MI.getOperand(1).isKill();
1165 bool ImpIsDead = MI.getOperand(2).isDead();
1166 OpLo = AVR::RORRd;
1167 OpHi = AVR::LSRRd;
1168 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1169
1170 // High part
1171 buildMI(MBB, MBBI, OpHi)
1172 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1173 .addReg(DstHiReg, getKillRegState(DstIsKill));
1174
1175 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1176 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1177 .addReg(DstLoReg, getKillRegState(DstIsKill));
1178
1179 if (ImpIsDead)
1180 MIBLO->getOperand(2).setIsDead();
1181
1182 // SREG is always implicitly killed
1183 MIBLO->getOperand(3).setIsKill();
1184
1185 MI.eraseFromParent();
1186 return true;
1187}
1188
1189template <>
1190bool AVRExpandPseudo::expand<AVR::RORWRd>(Block &MBB, BlockIt MBBI) {
1191 llvm_unreachable("RORW unimplemented");
1192 return false;
1193}
1194
1195template <>
1196bool AVRExpandPseudo::expand<AVR::ROLWRd>(Block &MBB, BlockIt MBBI) {
1197 llvm_unreachable("ROLW unimplemented");
1198 return false;
1199}
1200
1201template <>
1202bool AVRExpandPseudo::expand<AVR::ASRWRd>(Block &MBB, BlockIt MBBI) {
1203 MachineInstr &MI = *MBBI;
1204 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1205 unsigned DstReg = MI.getOperand(0).getReg();
1206 bool DstIsDead = MI.getOperand(0).isDead();
1207 bool DstIsKill = MI.getOperand(1).isKill();
1208 bool ImpIsDead = MI.getOperand(2).isDead();
1209 OpLo = AVR::RORRd;
1210 OpHi = AVR::ASRRd;
1211 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1212
1213 // High part
1214 buildMI(MBB, MBBI, OpHi)
1215 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1216 .addReg(DstHiReg, getKillRegState(DstIsKill));
1217
1218 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1219 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1220 .addReg(DstLoReg, getKillRegState(DstIsKill));
1221
1222 if (ImpIsDead)
1223 MIBLO->getOperand(2).setIsDead();
1224
1225 // SREG is always implicitly killed
1226 MIBLO->getOperand(3).setIsKill();
1227
1228 MI.eraseFromParent();
1229 return true;
1230}
1231
1232template <> bool AVRExpandPseudo::expand<AVR::SEXT>(Block &MBB, BlockIt MBBI) {
1233 MachineInstr &MI = *MBBI;
1234 unsigned DstLoReg, DstHiReg;
1235 // sext R17:R16, R17
1236 // mov r16, r17
1237 // lsl r17
1238 // sbc r17, r17
1239 // sext R17:R16, R13
1240 // mov r16, r13
1241 // mov r17, r13
1242 // lsl r17
1243 // sbc r17, r17
1244 // sext R17:R16, R16
1245 // mov r17, r16
1246 // lsl r17
1247 // sbc r17, r17
1248 unsigned DstReg = MI.getOperand(0).getReg();
1249 unsigned SrcReg = MI.getOperand(1).getReg();
1250 bool DstIsDead = MI.getOperand(0).isDead();
1251 bool SrcIsKill = MI.getOperand(1).isKill();
1252 bool ImpIsDead = MI.getOperand(2).isDead();
1253 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1254
1255 if (SrcReg != DstLoReg) {
1256 auto MOV = buildMI(MBB, MBBI, AVR::MOVRdRr)
1257 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1258 .addReg(SrcReg);
1259
1260 if (SrcReg == DstHiReg) {
1261 MOV->getOperand(1).setIsKill();
1262 }
1263 }
1264
1265 if (SrcReg != DstHiReg) {
1266 buildMI(MBB, MBBI, AVR::MOVRdRr)
1267 .addReg(DstHiReg, RegState::Define)
1268 .addReg(SrcReg, getKillRegState(SrcIsKill));
1269 }
1270
1271 buildMI(MBB, MBBI, AVR::LSLRd)
1272 .addReg(DstHiReg, RegState::Define)
1273 .addReg(DstHiReg, RegState::Kill);
1274
1275 auto SBC = buildMI(MBB, MBBI, AVR::SBCRdRr)
1276 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1277 .addReg(DstHiReg, RegState::Kill)
1278 .addReg(DstHiReg, RegState::Kill);
1279
1280 if (ImpIsDead)
1281 SBC->getOperand(3).setIsDead();
1282
1283 // SREG is always implicitly killed
1284 SBC->getOperand(4).setIsKill();
1285
1286 MI.eraseFromParent();
1287 return true;
1288}
1289
1290template <> bool AVRExpandPseudo::expand<AVR::ZEXT>(Block &MBB, BlockIt MBBI) {
1291 MachineInstr &MI = *MBBI;
1292 unsigned DstLoReg, DstHiReg;
1293 // zext R25:R24, R20
1294 // mov R24, R20
1295 // eor R25, R25
1296 // zext R25:R24, R24
1297 // eor R25, R25
1298 // zext R25:R24, R25
1299 // mov R24, R25
1300 // eor R25, R25
1301 unsigned DstReg = MI.getOperand(0).getReg();
1302 unsigned SrcReg = MI.getOperand(1).getReg();
1303 bool DstIsDead = MI.getOperand(0).isDead();
1304 bool SrcIsKill = MI.getOperand(1).isKill();
1305 bool ImpIsDead = MI.getOperand(2).isDead();
1306 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1307
1308 if (SrcReg != DstLoReg) {
1309 buildMI(MBB, MBBI, AVR::MOVRdRr)
1310 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1311 .addReg(SrcReg, getKillRegState(SrcIsKill));
1312 }
1313
1314 auto EOR = buildMI(MBB, MBBI, AVR::EORRdRr)
1315 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1316 .addReg(DstHiReg, RegState::Kill)
1317 .addReg(DstHiReg, RegState::Kill);
1318
1319 if (ImpIsDead)
1320 EOR->getOperand(3).setIsDead();
1321
1322 MI.eraseFromParent();
1323 return true;
1324}
1325
1326template <>
1327bool AVRExpandPseudo::expand<AVR::SPREAD>(Block &MBB, BlockIt MBBI) {
1328 MachineInstr &MI = *MBBI;
1329 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1330 unsigned DstReg = MI.getOperand(0).getReg();
1331 bool DstIsDead = MI.getOperand(0).isDead();
1332 unsigned Flags = MI.getFlags();
1333 OpLo = AVR::INRdA;
1334 OpHi = AVR::INRdA;
1335 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1336
1337 // Low part
1338 buildMI(MBB, MBBI, OpLo)
1339 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1340 .addImm(0x3d)
1341 .setMIFlags(Flags);
1342
1343 // High part
1344 buildMI(MBB, MBBI, OpHi)
1345 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1346 .addImm(0x3e)
1347 .setMIFlags(Flags);
1348
1349 MI.eraseFromParent();
1350 return true;
1351}
1352
1353template <>
1354bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
1355 MachineInstr &MI = *MBBI;
1356 unsigned SrcLoReg, SrcHiReg;
1357 unsigned SrcReg = MI.getOperand(1).getReg();
1358 bool SrcIsKill = MI.getOperand(1).isKill();
1359 unsigned Flags = MI.getFlags();
1360 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1361
1362 buildMI(MBB, MBBI, AVR::INRdA)
1363 .addReg(AVR::R0, RegState::Define)
1364 .addImm(SREG_ADDR)
1365 .setMIFlags(Flags);
1366
1367 buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
1368
1369 buildMI(MBB, MBBI, AVR::OUTARr)
1370 .addImm(0x3e)
1371 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1372 .setMIFlags(Flags);
1373
1374 buildMI(MBB, MBBI, AVR::OUTARr)
1375 .addImm(SREG_ADDR)
1376 .addReg(AVR::R0, RegState::Kill)
1377 .setMIFlags(Flags);
1378
1379 buildMI(MBB, MBBI, AVR::OUTARr)
1380 .addImm(0x3d)
1381 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1382 .setMIFlags(Flags);
1383
1384 MI.eraseFromParent();
1385 return true;
1386}
1387
1388bool AVRExpandPseudo::expandMI(Block &MBB, BlockIt MBBI) {
1389 MachineInstr &MI = *MBBI;
1390 int Opcode = MBBI->getOpcode();
1391
1392#define EXPAND(Op) \
1393 case Op: \
1394 return expand<Op>(MBB, MI)
1395
1396 switch (Opcode) {
1397 EXPAND(AVR::ADDWRdRr);
1398 EXPAND(AVR::ADCWRdRr);
1399 EXPAND(AVR::SUBWRdRr);
1400 EXPAND(AVR::SUBIWRdK);
1401 EXPAND(AVR::SBCWRdRr);
1402 EXPAND(AVR::SBCIWRdK);
1403 EXPAND(AVR::ANDWRdRr);
1404 EXPAND(AVR::ANDIWRdK);
1405 EXPAND(AVR::ORWRdRr);
1406 EXPAND(AVR::ORIWRdK);
1407 EXPAND(AVR::EORWRdRr);
1408 EXPAND(AVR::COMWRd);
1409 EXPAND(AVR::CPWRdRr);
1410 EXPAND(AVR::CPCWRdRr);
1411 EXPAND(AVR::LDIWRdK);
1412 EXPAND(AVR::LDSWRdK);
1413 EXPAND(AVR::LDWRdPtr);
1414 EXPAND(AVR::LDWRdPtrPi);
1415 EXPAND(AVR::LDWRdPtrPd);
1416 case AVR::LDDWRdYQ: //:FIXME: remove this once PR13375 gets fixed
1417 EXPAND(AVR::LDDWRdPtrQ);
1418 EXPAND(AVR::AtomicLoad8);
1419 EXPAND(AVR::AtomicLoad16);
1420 EXPAND(AVR::AtomicStore8);
1421 EXPAND(AVR::AtomicStore16);
1422 EXPAND(AVR::AtomicLoadAdd8);
1423 EXPAND(AVR::AtomicLoadAdd16);
1424 EXPAND(AVR::AtomicLoadSub8);
1425 EXPAND(AVR::AtomicLoadSub16);
1426 EXPAND(AVR::AtomicLoadAnd8);
1427 EXPAND(AVR::AtomicLoadAnd16);
1428 EXPAND(AVR::AtomicLoadOr8);
1429 EXPAND(AVR::AtomicLoadOr16);
1430 EXPAND(AVR::AtomicLoadXor8);
1431 EXPAND(AVR::AtomicLoadXor16);
1432 EXPAND(AVR::AtomicFence);
1433 EXPAND(AVR::STSWKRr);
1434 EXPAND(AVR::STWPtrRr);
1435 EXPAND(AVR::STWPtrPiRr);
1436 EXPAND(AVR::STWPtrPdRr);
1437 EXPAND(AVR::STDWPtrQRr);
1438 EXPAND(AVR::INWRdA);
1439 EXPAND(AVR::OUTWARr);
1440 EXPAND(AVR::PUSHWRr);
1441 EXPAND(AVR::POPWRd);
1442 EXPAND(AVR::LSLWRd);
1443 EXPAND(AVR::LSRWRd);
1444 EXPAND(AVR::RORWRd);
1445 EXPAND(AVR::ROLWRd);
1446 EXPAND(AVR::ASRWRd);
1447 EXPAND(AVR::SEXT);
1448 EXPAND(AVR::ZEXT);
1449 EXPAND(AVR::SPREAD);
1450 EXPAND(AVR::SPWRITE);
1451 }
1452#undef EXPAND
1453 return false;
1454}
1455
Dylan McKay017a55b2016-11-16 23:06:14 +00001456} // end of anonymous namespace
1457
Dylan McKay8cec7eb2016-12-07 11:08:56 +00001458INITIALIZE_PASS(AVRExpandPseudo, "avr-expand-pseudo",
1459 AVR_EXPAND_PSEUDO_NAME, false, false)
Dylan McKaya789f402016-11-16 21:58:04 +00001460namespace llvm {
1461
1462FunctionPass *createAVRExpandPseudoPass() { return new AVRExpandPseudo(); }
1463
1464} // end of namespace llvm