blob: 400e9bd8fdca89562b3c04db453755f42944b631 [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"
Dylan McKay5c90b8c2016-12-10 10:51:55 +000024#include "llvm/CodeGen/RegisterScavenging.h"
Dylan McKaya789f402016-11-16 21:58:04 +000025#include "llvm/Target/TargetRegisterInfo.h"
26
27using namespace llvm;
28
Dylan McKay8cec7eb2016-12-07 11:08:56 +000029#define AVR_EXPAND_PSEUDO_NAME "AVR pseudo instruction expansion pass"
30
Dylan McKaya789f402016-11-16 21:58:04 +000031namespace {
32
33/// Expands "placeholder" instructions marked as pseudo into
34/// actual AVR instructions.
35class AVRExpandPseudo : public MachineFunctionPass {
36public:
37 static char ID;
38
Dylan McKay8cec7eb2016-12-07 11:08:56 +000039 AVRExpandPseudo() : MachineFunctionPass(ID) {
40 initializeAVRExpandPseudoPass(*PassRegistry::getPassRegistry());
41 }
Dylan McKaya789f402016-11-16 21:58:04 +000042
43 bool runOnMachineFunction(MachineFunction &MF) override;
44
Dylan McKay8cec7eb2016-12-07 11:08:56 +000045 StringRef getPassName() const override { return AVR_EXPAND_PSEUDO_NAME; }
Dylan McKaya789f402016-11-16 21:58:04 +000046
47private:
48 typedef MachineBasicBlock Block;
49 typedef Block::iterator BlockIt;
50
51 const AVRRegisterInfo *TRI;
52 const TargetInstrInfo *TII;
53
54 /// The register to be used for temporary storage.
55 const unsigned SCRATCH_REGISTER = AVR::R0;
56 /// The IO address of the status register.
57 const unsigned SREG_ADDR = 0x3f;
58
59 bool expandMBB(Block &MBB);
60 bool expandMI(Block &MBB, BlockIt MBBI);
61 template <unsigned OP> bool expand(Block &MBB, BlockIt MBBI);
62
63 MachineInstrBuilder buildMI(Block &MBB, BlockIt MBBI, unsigned Opcode) {
64 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opcode));
65 }
66
67 MachineInstrBuilder buildMI(Block &MBB, BlockIt MBBI, unsigned Opcode,
68 unsigned DstReg) {
69 return BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(Opcode), DstReg);
70 }
71
72 MachineRegisterInfo &getRegInfo(Block &MBB) { return MBB.getParent()->getRegInfo(); }
73
74 bool expandArith(unsigned OpLo, unsigned OpHi, Block &MBB, BlockIt MBBI);
75 bool expandLogic(unsigned Op, Block &MBB, BlockIt MBBI);
76 bool expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI);
Dylan McKay453d0422016-12-30 00:21:56 +000077 bool isLogicImmOpRedundant(unsigned Op, unsigned ImmVal) const;
Dylan McKaya789f402016-11-16 21:58:04 +000078
79 template<typename Func>
80 bool expandAtomic(Block &MBB, BlockIt MBBI, Func f);
81
82 template<typename Func>
83 bool expandAtomicBinaryOp(unsigned Opcode, Block &MBB, BlockIt MBBI, Func f);
84
85 bool expandAtomicBinaryOp(unsigned Opcode, Block &MBB, BlockIt MBBI);
86
87 bool expandAtomicArithmeticOp(unsigned MemOpcode,
88 unsigned ArithOpcode,
89 Block &MBB,
90 BlockIt MBBI);
Dylan McKay8f515b12017-04-25 15:09:04 +000091
92 /// Scavenges a free GPR8 register for use.
93 unsigned scavengeGPR8(MachineInstr &MI);
Dylan McKaya789f402016-11-16 21:58:04 +000094};
95
96char AVRExpandPseudo::ID = 0;
97
Dylan McKaya789f402016-11-16 21:58:04 +000098bool AVRExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
99 bool Modified = false;
100
101 BlockIt MBBI = MBB.begin(), E = MBB.end();
102 while (MBBI != E) {
103 BlockIt NMBBI = std::next(MBBI);
104 Modified |= expandMI(MBB, MBBI);
105 MBBI = NMBBI;
106 }
107
108 return Modified;
109}
110
111bool AVRExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
112 bool Modified = false;
113
114 const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
115 TRI = STI.getRegisterInfo();
116 TII = STI.getInstrInfo();
117
Dylan McKay5c90b8c2016-12-10 10:51:55 +0000118 // We need to track liveness in order to use register scavenging.
119 MF.getProperties().set(MachineFunctionProperties::Property::TracksLiveness);
120
Dylan McKaya789f402016-11-16 21:58:04 +0000121 for (Block &MBB : MF) {
122 bool ContinueExpanding = true;
123 unsigned ExpandCount = 0;
124
125 // Continue expanding the block until all pseudos are expanded.
126 do {
127 assert(ExpandCount < 10 && "pseudo expand limit reached");
128
129 bool BlockModified = expandMBB(MBB);
130 Modified |= BlockModified;
131 ExpandCount++;
132
133 ContinueExpanding = BlockModified;
134 } while (ContinueExpanding);
135 }
136
137 return Modified;
138}
139
140bool AVRExpandPseudo::
141expandArith(unsigned OpLo, unsigned OpHi, Block &MBB, BlockIt MBBI) {
142 MachineInstr &MI = *MBBI;
143 unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
144 unsigned DstReg = MI.getOperand(0).getReg();
145 unsigned SrcReg = MI.getOperand(2).getReg();
146 bool DstIsDead = MI.getOperand(0).isDead();
147 bool DstIsKill = MI.getOperand(1).isKill();
148 bool SrcIsKill = MI.getOperand(2).isKill();
149 bool ImpIsDead = MI.getOperand(3).isDead();
150 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
151 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
152
153 buildMI(MBB, MBBI, OpLo)
154 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
155 .addReg(DstLoReg, getKillRegState(DstIsKill))
156 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
157
158 auto MIBHI = buildMI(MBB, MBBI, OpHi)
159 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
160 .addReg(DstHiReg, getKillRegState(DstIsKill))
161 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
162
163 if (ImpIsDead)
164 MIBHI->getOperand(3).setIsDead();
165
166 // SREG is always implicitly killed
167 MIBHI->getOperand(4).setIsKill();
168
169 MI.eraseFromParent();
170 return true;
171}
172
173bool AVRExpandPseudo::
174expandLogic(unsigned Op, Block &MBB, BlockIt MBBI) {
175 MachineInstr &MI = *MBBI;
176 unsigned SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
177 unsigned DstReg = MI.getOperand(0).getReg();
178 unsigned SrcReg = MI.getOperand(2).getReg();
179 bool DstIsDead = MI.getOperand(0).isDead();
180 bool DstIsKill = MI.getOperand(1).isKill();
181 bool SrcIsKill = MI.getOperand(2).isKill();
182 bool ImpIsDead = MI.getOperand(3).isDead();
183 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
184 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
185
186 auto MIBLO = buildMI(MBB, MBBI, Op)
187 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
188 .addReg(DstLoReg, getKillRegState(DstIsKill))
189 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
190
191 // SREG is always implicitly dead
192 MIBLO->getOperand(3).setIsDead();
193
194 auto MIBHI = buildMI(MBB, MBBI, Op)
195 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
196 .addReg(DstHiReg, getKillRegState(DstIsKill))
197 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
198
199 if (ImpIsDead)
200 MIBHI->getOperand(3).setIsDead();
201
202 MI.eraseFromParent();
203 return true;
204}
205
206bool AVRExpandPseudo::
Dylan McKay453d0422016-12-30 00:21:56 +0000207 isLogicImmOpRedundant(unsigned Op, unsigned ImmVal) const {
208
Dylan McKay97cf8372016-12-31 01:07:14 +0000209 // ANDI Rd, 0xff is redundant.
210 if (Op == AVR::ANDIRdK && ImmVal == 0xff)
211 return true;
212
Dylan McKay453d0422016-12-30 00:21:56 +0000213 // ORI Rd, 0x0 is redundant.
214 if (Op == AVR::ORIRdK && ImmVal == 0x0)
215 return true;
216
217 return false;
218}
219
220bool AVRExpandPseudo::
Dylan McKaya789f402016-11-16 21:58:04 +0000221expandLogicImm(unsigned Op, Block &MBB, BlockIt MBBI) {
222 MachineInstr &MI = *MBBI;
223 unsigned DstLoReg, DstHiReg;
224 unsigned DstReg = MI.getOperand(0).getReg();
225 bool DstIsDead = MI.getOperand(0).isDead();
226 bool SrcIsKill = MI.getOperand(1).isKill();
227 bool ImpIsDead = MI.getOperand(3).isDead();
228 unsigned Imm = MI.getOperand(2).getImm();
229 unsigned Lo8 = Imm & 0xff;
230 unsigned Hi8 = (Imm >> 8) & 0xff;
231 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
232
Dylan McKay453d0422016-12-30 00:21:56 +0000233 if (!isLogicImmOpRedundant(Op, Lo8)) {
234 auto MIBLO = buildMI(MBB, MBBI, Op)
235 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
236 .addReg(DstLoReg, getKillRegState(SrcIsKill))
237 .addImm(Lo8);
Dylan McKaya789f402016-11-16 21:58:04 +0000238
Dylan McKay453d0422016-12-30 00:21:56 +0000239 // SREG is always implicitly dead
240 MIBLO->getOperand(3).setIsDead();
241 }
Dylan McKaya789f402016-11-16 21:58:04 +0000242
Dylan McKay453d0422016-12-30 00:21:56 +0000243 if (!isLogicImmOpRedundant(Op, Hi8)) {
244 auto MIBHI = buildMI(MBB, MBBI, Op)
245 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
246 .addReg(DstHiReg, getKillRegState(SrcIsKill))
247 .addImm(Hi8);
Dylan McKaya789f402016-11-16 21:58:04 +0000248
Dylan McKay453d0422016-12-30 00:21:56 +0000249 if (ImpIsDead)
250 MIBHI->getOperand(3).setIsDead();
251 }
Dylan McKaya789f402016-11-16 21:58:04 +0000252
253 MI.eraseFromParent();
254 return true;
255}
256
257template <>
258bool AVRExpandPseudo::expand<AVR::ADDWRdRr>(Block &MBB, BlockIt MBBI) {
259 return expandArith(AVR::ADDRdRr, AVR::ADCRdRr, MBB, MBBI);
260}
261
262template <>
263bool AVRExpandPseudo::expand<AVR::ADCWRdRr>(Block &MBB, BlockIt MBBI) {
264 return expandArith(AVR::ADCRdRr, AVR::ADCRdRr, MBB, MBBI);
265}
266
267template <>
268bool AVRExpandPseudo::expand<AVR::SUBWRdRr>(Block &MBB, BlockIt MBBI) {
269 return expandArith(AVR::SUBRdRr, AVR::SBCRdRr, MBB, MBBI);
270}
271
272template <>
273bool AVRExpandPseudo::expand<AVR::SUBIWRdK>(Block &MBB, BlockIt MBBI) {
274 MachineInstr &MI = *MBBI;
275 unsigned DstLoReg, DstHiReg;
276 unsigned DstReg = MI.getOperand(0).getReg();
277 bool DstIsDead = MI.getOperand(0).isDead();
278 bool SrcIsKill = MI.getOperand(1).isKill();
279 bool ImpIsDead = MI.getOperand(3).isDead();
280 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
281
282 auto MIBLO = buildMI(MBB, MBBI, AVR::SUBIRdK)
283 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
284 .addReg(DstLoReg, getKillRegState(SrcIsKill));
285
286 auto MIBHI = buildMI(MBB, MBBI, AVR::SBCIRdK)
287 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
288 .addReg(DstHiReg, getKillRegState(SrcIsKill));
289
290 switch (MI.getOperand(2).getType()) {
291 case MachineOperand::MO_GlobalAddress: {
292 const GlobalValue *GV = MI.getOperand(2).getGlobal();
293 int64_t Offs = MI.getOperand(2).getOffset();
294 unsigned TF = MI.getOperand(2).getTargetFlags();
295 MIBLO.addGlobalAddress(GV, Offs, TF | AVRII::MO_NEG | AVRII::MO_LO);
296 MIBHI.addGlobalAddress(GV, Offs, TF | AVRII::MO_NEG | AVRII::MO_HI);
297 break;
298 }
299 case MachineOperand::MO_Immediate: {
300 unsigned Imm = MI.getOperand(2).getImm();
301 MIBLO.addImm(Imm & 0xff);
302 MIBHI.addImm((Imm >> 8) & 0xff);
303 break;
304 }
305 default:
306 llvm_unreachable("Unknown operand type!");
307 }
308
309 if (ImpIsDead)
310 MIBHI->getOperand(3).setIsDead();
311
312 // SREG is always implicitly killed
313 MIBHI->getOperand(4).setIsKill();
314
315 MI.eraseFromParent();
316 return true;
317}
318
319template <>
320bool AVRExpandPseudo::expand<AVR::SBCWRdRr>(Block &MBB, BlockIt MBBI) {
321 return expandArith(AVR::SBCRdRr, AVR::SBCRdRr, MBB, MBBI);
322}
323
324template <>
325bool AVRExpandPseudo::expand<AVR::SBCIWRdK>(Block &MBB, BlockIt MBBI) {
326 MachineInstr &MI = *MBBI;
327 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
328 unsigned DstReg = MI.getOperand(0).getReg();
329 bool DstIsDead = MI.getOperand(0).isDead();
330 bool SrcIsKill = MI.getOperand(1).isKill();
331 bool ImpIsDead = MI.getOperand(3).isDead();
332 unsigned Imm = MI.getOperand(2).getImm();
333 unsigned Lo8 = Imm & 0xff;
334 unsigned Hi8 = (Imm >> 8) & 0xff;
335 OpLo = AVR::SBCIRdK;
336 OpHi = AVR::SBCIRdK;
337 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
338
339 auto MIBLO = buildMI(MBB, MBBI, OpLo)
340 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
341 .addReg(DstLoReg, getKillRegState(SrcIsKill))
342 .addImm(Lo8);
343
344 // SREG is always implicitly killed
345 MIBLO->getOperand(4).setIsKill();
346
347 auto MIBHI = buildMI(MBB, MBBI, OpHi)
348 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
349 .addReg(DstHiReg, getKillRegState(SrcIsKill))
350 .addImm(Hi8);
351
352 if (ImpIsDead)
353 MIBHI->getOperand(3).setIsDead();
354
355 // SREG is always implicitly killed
356 MIBHI->getOperand(4).setIsKill();
357
358 MI.eraseFromParent();
359 return true;
360}
361
362template <>
363bool AVRExpandPseudo::expand<AVR::ANDWRdRr>(Block &MBB, BlockIt MBBI) {
364 return expandLogic(AVR::ANDRdRr, MBB, MBBI);
365}
366
367template <>
368bool AVRExpandPseudo::expand<AVR::ANDIWRdK>(Block &MBB, BlockIt MBBI) {
369 return expandLogicImm(AVR::ANDIRdK, MBB, MBBI);
370}
371
372template <>
373bool AVRExpandPseudo::expand<AVR::ORWRdRr>(Block &MBB, BlockIt MBBI) {
374 return expandLogic(AVR::ORRdRr, MBB, MBBI);
375}
376
377template <>
378bool AVRExpandPseudo::expand<AVR::ORIWRdK>(Block &MBB, BlockIt MBBI) {
379 return expandLogicImm(AVR::ORIRdK, MBB, MBBI);
380}
381
382template <>
383bool AVRExpandPseudo::expand<AVR::EORWRdRr>(Block &MBB, BlockIt MBBI) {
384 return expandLogic(AVR::EORRdRr, MBB, MBBI);
385}
386
387template <>
388bool AVRExpandPseudo::expand<AVR::COMWRd>(Block &MBB, BlockIt MBBI) {
389 MachineInstr &MI = *MBBI;
390 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
391 unsigned DstReg = MI.getOperand(0).getReg();
392 bool DstIsDead = MI.getOperand(0).isDead();
393 bool DstIsKill = MI.getOperand(1).isKill();
394 bool ImpIsDead = MI.getOperand(2).isDead();
395 OpLo = AVR::COMRd;
396 OpHi = AVR::COMRd;
397 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
398
399 auto MIBLO = buildMI(MBB, MBBI, OpLo)
400 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
401 .addReg(DstLoReg, getKillRegState(DstIsKill));
402
403 // SREG is always implicitly dead
404 MIBLO->getOperand(2).setIsDead();
405
406 auto MIBHI = buildMI(MBB, MBBI, OpHi)
407 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
408 .addReg(DstHiReg, getKillRegState(DstIsKill));
409
410 if (ImpIsDead)
411 MIBHI->getOperand(2).setIsDead();
412
413 MI.eraseFromParent();
414 return true;
415}
416
417template <>
418bool AVRExpandPseudo::expand<AVR::CPWRdRr>(Block &MBB, BlockIt MBBI) {
419 MachineInstr &MI = *MBBI;
420 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
421 unsigned DstReg = MI.getOperand(0).getReg();
422 unsigned SrcReg = MI.getOperand(1).getReg();
423 bool DstIsKill = MI.getOperand(0).isKill();
424 bool SrcIsKill = MI.getOperand(1).isKill();
425 bool ImpIsDead = MI.getOperand(2).isDead();
426 OpLo = AVR::CPRdRr;
427 OpHi = AVR::CPCRdRr;
428 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
429 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
430
431 // Low part
432 buildMI(MBB, MBBI, OpLo)
433 .addReg(DstLoReg, getKillRegState(DstIsKill))
434 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
435
436 auto MIBHI = buildMI(MBB, MBBI, OpHi)
437 .addReg(DstHiReg, getKillRegState(DstIsKill))
438 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
439
440 if (ImpIsDead)
441 MIBHI->getOperand(2).setIsDead();
442
443 // SREG is always implicitly killed
444 MIBHI->getOperand(3).setIsKill();
445
446 MI.eraseFromParent();
447 return true;
448}
449
450template <>
451bool AVRExpandPseudo::expand<AVR::CPCWRdRr>(Block &MBB, BlockIt MBBI) {
452 MachineInstr &MI = *MBBI;
453 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg, DstLoReg, DstHiReg;
454 unsigned DstReg = MI.getOperand(0).getReg();
455 unsigned SrcReg = MI.getOperand(1).getReg();
456 bool DstIsKill = MI.getOperand(0).isKill();
457 bool SrcIsKill = MI.getOperand(1).isKill();
458 bool ImpIsDead = MI.getOperand(2).isDead();
459 OpLo = AVR::CPCRdRr;
460 OpHi = AVR::CPCRdRr;
461 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
462 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
463
464 auto MIBLO = buildMI(MBB, MBBI, OpLo)
465 .addReg(DstLoReg, getKillRegState(DstIsKill))
466 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
467
468 // SREG is always implicitly killed
469 MIBLO->getOperand(3).setIsKill();
470
471 auto MIBHI = buildMI(MBB, MBBI, OpHi)
472 .addReg(DstHiReg, getKillRegState(DstIsKill))
473 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
474
475 if (ImpIsDead)
476 MIBHI->getOperand(2).setIsDead();
477
478 // SREG is always implicitly killed
479 MIBHI->getOperand(3).setIsKill();
480
481 MI.eraseFromParent();
482 return true;
483}
484
485template <>
486bool AVRExpandPseudo::expand<AVR::LDIWRdK>(Block &MBB, BlockIt MBBI) {
487 MachineInstr &MI = *MBBI;
488 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
489 unsigned DstReg = MI.getOperand(0).getReg();
490 bool DstIsDead = MI.getOperand(0).isDead();
491 OpLo = AVR::LDIRdK;
492 OpHi = AVR::LDIRdK;
493 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
494
495 auto MIBLO = buildMI(MBB, MBBI, OpLo)
496 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead));
497
498 auto MIBHI = buildMI(MBB, MBBI, OpHi)
499 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead));
500
501 switch (MI.getOperand(1).getType()) {
502 case MachineOperand::MO_GlobalAddress: {
503 const GlobalValue *GV = MI.getOperand(1).getGlobal();
504 int64_t Offs = MI.getOperand(1).getOffset();
505 unsigned TF = MI.getOperand(1).getTargetFlags();
506
507 MIBLO.addGlobalAddress(GV, Offs, TF | AVRII::MO_LO);
508 MIBHI.addGlobalAddress(GV, Offs, TF | AVRII::MO_HI);
509 break;
510 }
511 case MachineOperand::MO_BlockAddress: {
512 const BlockAddress *BA = MI.getOperand(1).getBlockAddress();
513 unsigned TF = MI.getOperand(1).getTargetFlags();
514
Diana Picus116bbab2017-01-13 09:58:52 +0000515 MIBLO.add(MachineOperand::CreateBA(BA, TF | AVRII::MO_LO));
516 MIBHI.add(MachineOperand::CreateBA(BA, TF | AVRII::MO_HI));
Dylan McKaya789f402016-11-16 21:58:04 +0000517 break;
518 }
519 case MachineOperand::MO_Immediate: {
520 unsigned Imm = MI.getOperand(1).getImm();
521
522 MIBLO.addImm(Imm & 0xff);
523 MIBHI.addImm((Imm >> 8) & 0xff);
524 break;
525 }
526 default:
527 llvm_unreachable("Unknown operand type!");
528 }
529
530 MI.eraseFromParent();
531 return true;
532}
533
534template <>
535bool AVRExpandPseudo::expand<AVR::LDSWRdK>(Block &MBB, BlockIt MBBI) {
536 MachineInstr &MI = *MBBI;
537 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
538 unsigned DstReg = MI.getOperand(0).getReg();
539 bool DstIsDead = MI.getOperand(0).isDead();
540 OpLo = AVR::LDSRdK;
541 OpHi = AVR::LDSRdK;
542 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
543
544 auto MIBLO = buildMI(MBB, MBBI, OpLo)
545 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead));
546
547 auto MIBHI = buildMI(MBB, MBBI, OpHi)
548 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead));
549
550 switch (MI.getOperand(1).getType()) {
551 case MachineOperand::MO_GlobalAddress: {
552 const GlobalValue *GV = MI.getOperand(1).getGlobal();
553 int64_t Offs = MI.getOperand(1).getOffset();
554 unsigned TF = MI.getOperand(1).getTargetFlags();
555
556 MIBLO.addGlobalAddress(GV, Offs, TF);
557 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
558 break;
559 }
560 case MachineOperand::MO_Immediate: {
561 unsigned Imm = MI.getOperand(1).getImm();
562
563 MIBLO.addImm(Imm);
564 MIBHI.addImm(Imm + 1);
565 break;
566 }
567 default:
568 llvm_unreachable("Unknown operand type!");
569 }
570
571 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
572 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
573
574 MI.eraseFromParent();
575 return true;
576}
577
578template <>
579bool AVRExpandPseudo::expand<AVR::LDWRdPtr>(Block &MBB, BlockIt MBBI) {
580 MachineInstr &MI = *MBBI;
581 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
582 unsigned DstReg = MI.getOperand(0).getReg();
Dylan McKay8f515b12017-04-25 15:09:04 +0000583 unsigned TmpReg = 0; // 0 for no temporary register
Dylan McKaya789f402016-11-16 21:58:04 +0000584 unsigned SrcReg = MI.getOperand(1).getReg();
Dylan McKaya789f402016-11-16 21:58:04 +0000585 bool SrcIsKill = MI.getOperand(1).isKill();
586 OpLo = AVR::LDRdPtr;
587 OpHi = AVR::LDDRdPtrQ;
588 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
589
Dylan McKay8f515b12017-04-25 15:09:04 +0000590 // Use a temporary register if src and dst registers are the same.
591 if (DstReg == SrcReg)
592 TmpReg = scavengeGPR8(MI);
Dylan McKaya789f402016-11-16 21:58:04 +0000593
Dylan McKay8f515b12017-04-25 15:09:04 +0000594 unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
595 unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
596
597 // Load low byte.
Dylan McKaya789f402016-11-16 21:58:04 +0000598 auto MIBLO = buildMI(MBB, MBBI, OpLo)
Dylan McKay8f515b12017-04-25 15:09:04 +0000599 .addReg(CurDstLoReg, RegState::Define)
Dylan McKaya789f402016-11-16 21:58:04 +0000600 .addReg(SrcReg);
601
Dylan McKay8f515b12017-04-25 15:09:04 +0000602 // Push low byte onto stack if necessary.
603 if (TmpReg)
604 buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
605
606 // Load high byte.
Dylan McKaya789f402016-11-16 21:58:04 +0000607 auto MIBHI = buildMI(MBB, MBBI, OpHi)
Dylan McKay8f515b12017-04-25 15:09:04 +0000608 .addReg(CurDstHiReg, RegState::Define)
Dylan McKaya789f402016-11-16 21:58:04 +0000609 .addReg(SrcReg, getKillRegState(SrcIsKill))
610 .addImm(1);
611
Dylan McKay8f515b12017-04-25 15:09:04 +0000612 if (TmpReg) {
613 // Move the high byte into the final destination.
614 buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
615
616 // Move the low byte from the scratch space into the final destination.
617 buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
618 }
619
Dylan McKaya789f402016-11-16 21:58:04 +0000620 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
621 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
622
623 MI.eraseFromParent();
624 return true;
625}
626
627template <>
628bool AVRExpandPseudo::expand<AVR::LDWRdPtrPi>(Block &MBB, BlockIt MBBI) {
629 MachineInstr &MI = *MBBI;
630 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
631 unsigned DstReg = MI.getOperand(0).getReg();
632 unsigned SrcReg = MI.getOperand(1).getReg();
633 bool DstIsDead = MI.getOperand(0).isDead();
634 bool SrcIsDead = MI.getOperand(1).isKill();
635 OpLo = AVR::LDRdPtrPi;
636 OpHi = AVR::LDRdPtrPi;
637 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
638
639 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
640
641 auto MIBLO = buildMI(MBB, MBBI, OpLo)
642 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
643 .addReg(SrcReg, RegState::Define)
644 .addReg(SrcReg, RegState::Kill);
645
646 auto MIBHI = buildMI(MBB, MBBI, OpHi)
647 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
648 .addReg(SrcReg, RegState::Define | getDeadRegState(SrcIsDead))
649 .addReg(SrcReg, RegState::Kill);
650
651 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
652 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
653
654 MI.eraseFromParent();
655 return true;
656}
657
658template <>
659bool AVRExpandPseudo::expand<AVR::LDWRdPtrPd>(Block &MBB, BlockIt MBBI) {
660 MachineInstr &MI = *MBBI;
661 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
662 unsigned DstReg = MI.getOperand(0).getReg();
663 unsigned SrcReg = MI.getOperand(1).getReg();
664 bool DstIsDead = MI.getOperand(0).isDead();
665 bool SrcIsDead = MI.getOperand(1).isKill();
666 OpLo = AVR::LDRdPtrPd;
667 OpHi = AVR::LDRdPtrPd;
668 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
669
670 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
671
672 auto MIBHI = buildMI(MBB, MBBI, OpHi)
673 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
674 .addReg(SrcReg, RegState::Define)
675 .addReg(SrcReg, RegState::Kill);
676
677 auto MIBLO = buildMI(MBB, MBBI, OpLo)
678 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
679 .addReg(SrcReg, RegState::Define | getDeadRegState(SrcIsDead))
680 .addReg(SrcReg, RegState::Kill);
681
682 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
683 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
684
685 MI.eraseFromParent();
686 return true;
687}
688
689template <>
690bool AVRExpandPseudo::expand<AVR::LDDWRdPtrQ>(Block &MBB, BlockIt MBBI) {
691 MachineInstr &MI = *MBBI;
692 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
693 unsigned DstReg = MI.getOperand(0).getReg();
Dylan McKay8f515b12017-04-25 15:09:04 +0000694 unsigned TmpReg = 0; // 0 for no temporary register
Dylan McKaya789f402016-11-16 21:58:04 +0000695 unsigned SrcReg = MI.getOperand(1).getReg();
696 unsigned Imm = MI.getOperand(2).getImm();
Dylan McKaya789f402016-11-16 21:58:04 +0000697 bool SrcIsKill = MI.getOperand(1).isKill();
698 OpLo = AVR::LDDRdPtrQ;
699 OpHi = AVR::LDDRdPtrQ;
700 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
701
Dylan McKayc4b002b2017-10-04 09:51:21 +0000702 // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value
703 // allowed for the instruction, 62 is the limit here.
704 assert(Imm <= 62 && "Offset is out of range");
Dylan McKay8cec7eb2016-12-07 11:08:56 +0000705
Dylan McKay8f515b12017-04-25 15:09:04 +0000706 // Use a temporary register if src and dst registers are the same.
707 if (DstReg == SrcReg)
708 TmpReg = scavengeGPR8(MI);
Dylan McKay8cec7eb2016-12-07 11:08:56 +0000709
Dylan McKay8f515b12017-04-25 15:09:04 +0000710 unsigned CurDstLoReg = (DstReg == SrcReg) ? TmpReg : DstLoReg;
711 unsigned CurDstHiReg = (DstReg == SrcReg) ? TmpReg : DstHiReg;
Dylan McKaya789f402016-11-16 21:58:04 +0000712
Dylan McKay8f515b12017-04-25 15:09:04 +0000713 // Load low byte.
714 auto MIBLO = buildMI(MBB, MBBI, OpLo)
715 .addReg(CurDstLoReg, RegState::Define)
716 .addReg(SrcReg)
717 .addImm(Imm);
Dylan McKaya789f402016-11-16 21:58:04 +0000718
Dylan McKay8f515b12017-04-25 15:09:04 +0000719 // Push low byte onto stack if necessary.
720 if (TmpReg)
721 buildMI(MBB, MBBI, AVR::PUSHRr).addReg(TmpReg);
Dylan McKay8cec7eb2016-12-07 11:08:56 +0000722
Dylan McKay8f515b12017-04-25 15:09:04 +0000723 // Load high byte.
724 auto MIBHI = buildMI(MBB, MBBI, OpHi)
725 .addReg(CurDstHiReg, RegState::Define)
726 .addReg(SrcReg, getKillRegState(SrcIsKill))
727 .addImm(Imm + 1);
Dylan McKaya789f402016-11-16 21:58:04 +0000728
Dylan McKay8f515b12017-04-25 15:09:04 +0000729 if (TmpReg) {
730 // Move the high byte into the final destination.
Dylan McKay5c90b8c2016-12-10 10:51:55 +0000731 buildMI(MBB, MBBI, AVR::MOVRdRr).addReg(DstHiReg).addReg(TmpReg);
Dylan McKay5c90b8c2016-12-10 10:51:55 +0000732
Dylan McKay8f515b12017-04-25 15:09:04 +0000733 // Move the low byte from the scratch space into the final destination.
734 buildMI(MBB, MBBI, AVR::POPRd).addReg(DstLoReg);
Dylan McKay8cec7eb2016-12-07 11:08:56 +0000735 }
736
Dylan McKaya789f402016-11-16 21:58:04 +0000737 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
738 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
739
740 MI.eraseFromParent();
741 return true;
742}
743
Dylan McKaya5d49df2016-12-09 07:49:04 +0000744template <>
745bool AVRExpandPseudo::expand<AVR::LPMWRdZ>(Block &MBB, BlockIt MBBI) {
746 llvm_unreachable("wide LPM is unimplemented");
747}
748
749template <>
750bool AVRExpandPseudo::expand<AVR::LPMWRdZPi>(Block &MBB, BlockIt MBBI) {
751 llvm_unreachable("wide LPMPi is unimplemented");
752}
753
Dylan McKaya789f402016-11-16 21:58:04 +0000754template<typename Func>
755bool AVRExpandPseudo::expandAtomic(Block &MBB, BlockIt MBBI, Func f) {
756 // Remove the pseudo instruction.
757 MachineInstr &MI = *MBBI;
758
759 // Store the SREG.
760 buildMI(MBB, MBBI, AVR::INRdA)
761 .addReg(SCRATCH_REGISTER, RegState::Define)
762 .addImm(SREG_ADDR);
763
764 // Disable exceptions.
765 buildMI(MBB, MBBI, AVR::BCLRs).addImm(7); // CLI
766
767 f(MI);
768
769 // Restore the status reg.
770 buildMI(MBB, MBBI, AVR::OUTARr)
771 .addImm(SREG_ADDR)
772 .addReg(SCRATCH_REGISTER);
773
774 MI.eraseFromParent();
775 return true;
776}
777
778template<typename Func>
779bool AVRExpandPseudo::expandAtomicBinaryOp(unsigned Opcode,
780 Block &MBB,
781 BlockIt MBBI,
782 Func f) {
783 return expandAtomic(MBB, MBBI, [&](MachineInstr &MI) {
784 auto Op1 = MI.getOperand(0);
785 auto Op2 = MI.getOperand(1);
786
Diana Picus116bbab2017-01-13 09:58:52 +0000787 MachineInstr &NewInst =
788 *buildMI(MBB, MBBI, Opcode).add(Op1).add(Op2).getInstr();
Dylan McKaya789f402016-11-16 21:58:04 +0000789 f(NewInst);
790 });
791}
792
793bool AVRExpandPseudo::expandAtomicBinaryOp(unsigned Opcode,
794 Block &MBB,
795 BlockIt MBBI) {
796 return expandAtomicBinaryOp(Opcode, MBB, MBBI, [](MachineInstr &MI) {});
797}
798
799bool AVRExpandPseudo::expandAtomicArithmeticOp(unsigned Width,
800 unsigned ArithOpcode,
801 Block &MBB,
802 BlockIt MBBI) {
803 return expandAtomic(MBB, MBBI, [&](MachineInstr &MI) {
804 auto Op1 = MI.getOperand(0);
805 auto Op2 = MI.getOperand(1);
806
807 unsigned LoadOpcode = (Width == 8) ? AVR::LDRdPtr : AVR::LDWRdPtr;
808 unsigned StoreOpcode = (Width == 8) ? AVR::STPtrRr : AVR::STWPtrRr;
809
810 // Create the load
Diana Picus116bbab2017-01-13 09:58:52 +0000811 buildMI(MBB, MBBI, LoadOpcode).add(Op1).add(Op2);
Dylan McKaya789f402016-11-16 21:58:04 +0000812
813 // Create the arithmetic op
Diana Picus116bbab2017-01-13 09:58:52 +0000814 buildMI(MBB, MBBI, ArithOpcode).add(Op1).add(Op1).add(Op2);
Dylan McKaya789f402016-11-16 21:58:04 +0000815
816 // Create the store
Diana Picus116bbab2017-01-13 09:58:52 +0000817 buildMI(MBB, MBBI, StoreOpcode).add(Op2).add(Op1);
Dylan McKaya789f402016-11-16 21:58:04 +0000818 });
819}
820
Dylan McKay8f515b12017-04-25 15:09:04 +0000821unsigned AVRExpandPseudo::scavengeGPR8(MachineInstr &MI) {
822 MachineBasicBlock &MBB = *MI.getParent();
823 RegScavenger RS;
824
825 RS.enterBasicBlock(MBB);
826 RS.forward(MI);
827
828 BitVector Candidates =
829 TRI->getAllocatableSet
830 (*MBB.getParent(), &AVR::GPR8RegClass);
831
832 // Exclude all the registers being used by the instruction.
833 for (MachineOperand &MO : MI.operands()) {
834 if (MO.isReg() && MO.getReg() != 0 && !MO.isDef() &&
835 !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
836 Candidates.reset(MO.getReg());
837 }
838
839 BitVector Available = RS.getRegsAvailable(&AVR::GPR8RegClass);
840 Available &= Candidates;
841
842 signed Reg = Available.find_first();
843 assert(Reg != -1 && "ran out of registers");
844 return Reg;
845}
846
Dylan McKaya789f402016-11-16 21:58:04 +0000847template<>
848bool AVRExpandPseudo::expand<AVR::AtomicLoad8>(Block &MBB, BlockIt MBBI) {
849 return expandAtomicBinaryOp(AVR::LDRdPtr, MBB, MBBI);
850}
851
852template<>
853bool AVRExpandPseudo::expand<AVR::AtomicLoad16>(Block &MBB, BlockIt MBBI) {
854 return expandAtomicBinaryOp(AVR::LDWRdPtr, MBB, MBBI);
855}
856
857template<>
858bool AVRExpandPseudo::expand<AVR::AtomicStore8>(Block &MBB, BlockIt MBBI) {
859 return expandAtomicBinaryOp(AVR::STPtrRr, MBB, MBBI);
860}
861
862template<>
863bool AVRExpandPseudo::expand<AVR::AtomicStore16>(Block &MBB, BlockIt MBBI) {
864 return expandAtomicBinaryOp(AVR::STWPtrRr, MBB, MBBI);
865}
866
867template<>
868bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd8>(Block &MBB, BlockIt MBBI) {
869 return expandAtomicArithmeticOp(8, AVR::ADDRdRr, MBB, MBBI);
870}
871
872template<>
873bool AVRExpandPseudo::expand<AVR::AtomicLoadAdd16>(Block &MBB, BlockIt MBBI) {
874 return expandAtomicArithmeticOp(16, AVR::ADDWRdRr, MBB, MBBI);
875}
876
877template<>
878bool AVRExpandPseudo::expand<AVR::AtomicLoadSub8>(Block &MBB, BlockIt MBBI) {
879 return expandAtomicArithmeticOp(8, AVR::SUBRdRr, MBB, MBBI);
880}
881
882template<>
883bool AVRExpandPseudo::expand<AVR::AtomicLoadSub16>(Block &MBB, BlockIt MBBI) {
884 return expandAtomicArithmeticOp(16, AVR::SUBWRdRr, MBB, MBBI);
885}
886
887template<>
888bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd8>(Block &MBB, BlockIt MBBI) {
889 return expandAtomicArithmeticOp(8, AVR::ANDRdRr, MBB, MBBI);
890}
891
892template<>
893bool AVRExpandPseudo::expand<AVR::AtomicLoadAnd16>(Block &MBB, BlockIt MBBI) {
894 return expandAtomicArithmeticOp(16, AVR::ANDWRdRr, MBB, MBBI);
895}
896
897template<>
898bool AVRExpandPseudo::expand<AVR::AtomicLoadOr8>(Block &MBB, BlockIt MBBI) {
899 return expandAtomicArithmeticOp(8, AVR::ORRdRr, MBB, MBBI);
900}
901
902template<>
903bool AVRExpandPseudo::expand<AVR::AtomicLoadOr16>(Block &MBB, BlockIt MBBI) {
904 return expandAtomicArithmeticOp(16, AVR::ORWRdRr, MBB, MBBI);
905}
906
907template<>
908bool AVRExpandPseudo::expand<AVR::AtomicLoadXor8>(Block &MBB, BlockIt MBBI) {
909 return expandAtomicArithmeticOp(8, AVR::EORRdRr, MBB, MBBI);
910}
911
912template<>
913bool AVRExpandPseudo::expand<AVR::AtomicLoadXor16>(Block &MBB, BlockIt MBBI) {
914 return expandAtomicArithmeticOp(16, AVR::EORWRdRr, MBB, MBBI);
915}
916
917template<>
918bool AVRExpandPseudo::expand<AVR::AtomicFence>(Block &MBB, BlockIt MBBI) {
919 // On AVR, there is only one core and so atomic fences do nothing.
920 MBBI->eraseFromParent();
921 return true;
922}
923
924template <>
925bool AVRExpandPseudo::expand<AVR::STSWKRr>(Block &MBB, BlockIt MBBI) {
926 MachineInstr &MI = *MBBI;
927 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
928 unsigned SrcReg = MI.getOperand(1).getReg();
929 bool SrcIsKill = MI.getOperand(1).isKill();
930 OpLo = AVR::STSKRr;
931 OpHi = AVR::STSKRr;
932 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
933
934 // Write the high byte first in case this address belongs to a special
935 // I/O address with a special temporary register.
936 auto MIBHI = buildMI(MBB, MBBI, OpHi);
937 auto MIBLO = buildMI(MBB, MBBI, OpLo);
938
939 switch (MI.getOperand(0).getType()) {
940 case MachineOperand::MO_GlobalAddress: {
941 const GlobalValue *GV = MI.getOperand(0).getGlobal();
942 int64_t Offs = MI.getOperand(0).getOffset();
943 unsigned TF = MI.getOperand(0).getTargetFlags();
944
945 MIBLO.addGlobalAddress(GV, Offs, TF);
946 MIBHI.addGlobalAddress(GV, Offs + 1, TF);
947 break;
948 }
949 case MachineOperand::MO_Immediate: {
950 unsigned Imm = MI.getOperand(0).getImm();
951
952 MIBLO.addImm(Imm);
953 MIBHI.addImm(Imm + 1);
954 break;
955 }
956 default:
957 llvm_unreachable("Unknown operand type!");
958 }
959
960 MIBLO.addReg(SrcLoReg, getKillRegState(SrcIsKill));
961 MIBHI.addReg(SrcHiReg, getKillRegState(SrcIsKill));
962
963 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
964 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
965
966 MI.eraseFromParent();
967 return true;
968}
969
970template <>
971bool AVRExpandPseudo::expand<AVR::STWPtrRr>(Block &MBB, BlockIt MBBI) {
972 MachineInstr &MI = *MBBI;
973 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
974 unsigned DstReg = MI.getOperand(0).getReg();
975 unsigned SrcReg = MI.getOperand(1).getReg();
Dylan McKaya789f402016-11-16 21:58:04 +0000976 bool SrcIsKill = MI.getOperand(1).isKill();
977 OpLo = AVR::STPtrRr;
978 OpHi = AVR::STDPtrQRr;
979 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
980
981 //:TODO: need to reverse this order like inw and stsw?
982 auto MIBLO = buildMI(MBB, MBBI, OpLo)
983 .addReg(DstReg)
984 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
985
986 auto MIBHI = buildMI(MBB, MBBI, OpHi)
Dylan McKayff49a052017-04-25 23:58:20 +0000987 .addReg(DstReg)
Dylan McKaya789f402016-11-16 21:58:04 +0000988 .addImm(1)
989 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
990
991 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
992 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
993
994 MI.eraseFromParent();
995 return true;
996}
997
998template <>
999bool AVRExpandPseudo::expand<AVR::STWPtrPiRr>(Block &MBB, BlockIt MBBI) {
1000 MachineInstr &MI = *MBBI;
1001 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1002 unsigned DstReg = MI.getOperand(0).getReg();
1003 unsigned SrcReg = MI.getOperand(2).getReg();
1004 unsigned Imm = MI.getOperand(3).getImm();
1005 bool DstIsDead = MI.getOperand(0).isDead();
1006 bool SrcIsKill = MI.getOperand(2).isKill();
1007 OpLo = AVR::STPtrPiRr;
1008 OpHi = AVR::STPtrPiRr;
1009 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1010
1011 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
1012
1013 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1014 .addReg(DstReg, RegState::Define)
1015 .addReg(DstReg, RegState::Kill)
1016 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1017 .addImm(Imm);
1018
1019 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1020 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
1021 .addReg(DstReg, RegState::Kill)
1022 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1023 .addImm(Imm);
1024
1025 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1026 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1027
1028 MI.eraseFromParent();
1029 return true;
1030}
1031
1032template <>
1033bool AVRExpandPseudo::expand<AVR::STWPtrPdRr>(Block &MBB, BlockIt MBBI) {
1034 MachineInstr &MI = *MBBI;
1035 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1036 unsigned DstReg = MI.getOperand(0).getReg();
1037 unsigned SrcReg = MI.getOperand(2).getReg();
1038 unsigned Imm = MI.getOperand(3).getImm();
1039 bool DstIsDead = MI.getOperand(0).isDead();
1040 bool SrcIsKill = MI.getOperand(2).isKill();
1041 OpLo = AVR::STPtrPdRr;
1042 OpHi = AVR::STPtrPdRr;
1043 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1044
1045 assert(DstReg != SrcReg && "SrcReg and DstReg cannot be the same");
1046
1047 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1048 .addReg(DstReg, RegState::Define)
1049 .addReg(DstReg, RegState::Kill)
1050 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1051 .addImm(Imm);
1052
1053 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1054 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
1055 .addReg(DstReg, RegState::Kill)
1056 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1057 .addImm(Imm);
1058
1059 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1060 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1061
1062 MI.eraseFromParent();
1063 return true;
1064}
1065
1066template <>
1067bool AVRExpandPseudo::expand<AVR::STDWPtrQRr>(Block &MBB, BlockIt MBBI) {
1068 MachineInstr &MI = *MBBI;
1069 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1070 unsigned DstReg = MI.getOperand(0).getReg();
1071 unsigned SrcReg = MI.getOperand(2).getReg();
1072 unsigned Imm = MI.getOperand(1).getImm();
1073 bool DstIsKill = MI.getOperand(0).isKill();
1074 bool SrcIsKill = MI.getOperand(2).isKill();
1075 OpLo = AVR::STDPtrQRr;
1076 OpHi = AVR::STDPtrQRr;
1077 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1078
Dylan McKayc4b002b2017-10-04 09:51:21 +00001079 // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value
1080 // allowed for the instruction, 62 is the limit here.
1081 assert(Imm <= 62 && "Offset is out of range");
Dylan McKaya789f402016-11-16 21:58:04 +00001082
1083 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1084 .addReg(DstReg)
1085 .addImm(Imm)
1086 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
1087
1088 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1089 .addReg(DstReg, getKillRegState(DstIsKill))
1090 .addImm(Imm + 1)
1091 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
1092
1093 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1094 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1095
1096 MI.eraseFromParent();
1097 return true;
1098}
1099
1100template <>
1101bool AVRExpandPseudo::expand<AVR::INWRdA>(Block &MBB, BlockIt MBBI) {
1102 MachineInstr &MI = *MBBI;
1103 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1104 unsigned Imm = MI.getOperand(1).getImm();
1105 unsigned DstReg = MI.getOperand(0).getReg();
1106 bool DstIsDead = MI.getOperand(0).isDead();
1107 OpLo = AVR::INRdA;
1108 OpHi = AVR::INRdA;
1109 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1110
Dylan McKayc4b002b2017-10-04 09:51:21 +00001111 // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value
1112 // allowed for the instruction, 62 is the limit here.
1113 assert(Imm <= 62 && "Address is out of range");
Dylan McKaya789f402016-11-16 21:58:04 +00001114
1115 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1116 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1117 .addImm(Imm);
1118
1119 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1120 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1121 .addImm(Imm + 1);
1122
1123 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1124 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1125
1126 MI.eraseFromParent();
1127 return true;
1128}
1129
1130template <>
1131bool AVRExpandPseudo::expand<AVR::OUTWARr>(Block &MBB, BlockIt MBBI) {
1132 MachineInstr &MI = *MBBI;
1133 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1134 unsigned Imm = MI.getOperand(0).getImm();
1135 unsigned SrcReg = MI.getOperand(1).getReg();
1136 bool SrcIsKill = MI.getOperand(1).isKill();
1137 OpLo = AVR::OUTARr;
1138 OpHi = AVR::OUTARr;
1139 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1140
Dylan McKayc4b002b2017-10-04 09:51:21 +00001141 // Since we add 1 to the Imm value for the high byte below, and 63 is the highest Imm value
1142 // allowed for the instruction, 62 is the limit here.
1143 assert(Imm <= 62 && "Address is out of range");
Dylan McKaya789f402016-11-16 21:58:04 +00001144
1145 // 16 bit I/O writes need the high byte first
1146 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1147 .addImm(Imm + 1)
1148 .addReg(SrcHiReg, getKillRegState(SrcIsKill));
1149
1150 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1151 .addImm(Imm)
1152 .addReg(SrcLoReg, getKillRegState(SrcIsKill));
1153
1154 MIBLO->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1155 MIBHI->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1156
1157 MI.eraseFromParent();
1158 return true;
1159}
1160
1161template <>
1162bool AVRExpandPseudo::expand<AVR::PUSHWRr>(Block &MBB, BlockIt MBBI) {
1163 MachineInstr &MI = *MBBI;
1164 unsigned OpLo, OpHi, SrcLoReg, SrcHiReg;
1165 unsigned SrcReg = MI.getOperand(0).getReg();
1166 bool SrcIsKill = MI.getOperand(0).isKill();
1167 unsigned Flags = MI.getFlags();
1168 OpLo = AVR::PUSHRr;
1169 OpHi = AVR::PUSHRr;
1170 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1171
1172 // Low part
1173 buildMI(MBB, MBBI, OpLo)
1174 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1175 .setMIFlags(Flags);
1176
1177 // High part
1178 buildMI(MBB, MBBI, OpHi)
1179 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1180 .setMIFlags(Flags);
1181
1182 MI.eraseFromParent();
1183 return true;
1184}
1185
1186template <>
1187bool AVRExpandPseudo::expand<AVR::POPWRd>(Block &MBB, BlockIt MBBI) {
1188 MachineInstr &MI = *MBBI;
1189 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1190 unsigned DstReg = MI.getOperand(0).getReg();
1191 unsigned Flags = MI.getFlags();
1192 OpLo = AVR::POPRd;
1193 OpHi = AVR::POPRd;
1194 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1195
1196 buildMI(MBB, MBBI, OpHi, DstHiReg).setMIFlags(Flags); // High
1197 buildMI(MBB, MBBI, OpLo, DstLoReg).setMIFlags(Flags); // Low
1198
1199 MI.eraseFromParent();
1200 return true;
1201}
1202
1203template <>
1204bool AVRExpandPseudo::expand<AVR::LSLWRd>(Block &MBB, BlockIt MBBI) {
1205 MachineInstr &MI = *MBBI;
1206 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1207 unsigned DstReg = MI.getOperand(0).getReg();
1208 bool DstIsDead = MI.getOperand(0).isDead();
1209 bool DstIsKill = MI.getOperand(1).isKill();
1210 bool ImpIsDead = MI.getOperand(2).isDead();
1211 OpLo = AVR::LSLRd;
1212 OpHi = AVR::ROLRd;
1213 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1214
1215 // Low part
1216 buildMI(MBB, MBBI, OpLo)
1217 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1218 .addReg(DstLoReg, getKillRegState(DstIsKill));
1219
1220 auto MIBHI = buildMI(MBB, MBBI, OpHi)
1221 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1222 .addReg(DstHiReg, getKillRegState(DstIsKill));
1223
1224 if (ImpIsDead)
1225 MIBHI->getOperand(2).setIsDead();
1226
1227 // SREG is always implicitly killed
1228 MIBHI->getOperand(3).setIsKill();
1229
1230 MI.eraseFromParent();
1231 return true;
1232}
1233
1234template <>
1235bool AVRExpandPseudo::expand<AVR::LSRWRd>(Block &MBB, BlockIt MBBI) {
1236 MachineInstr &MI = *MBBI;
1237 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1238 unsigned DstReg = MI.getOperand(0).getReg();
1239 bool DstIsDead = MI.getOperand(0).isDead();
1240 bool DstIsKill = MI.getOperand(1).isKill();
1241 bool ImpIsDead = MI.getOperand(2).isDead();
1242 OpLo = AVR::RORRd;
1243 OpHi = AVR::LSRRd;
1244 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1245
1246 // High part
1247 buildMI(MBB, MBBI, OpHi)
1248 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1249 .addReg(DstHiReg, getKillRegState(DstIsKill));
1250
1251 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1252 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1253 .addReg(DstLoReg, getKillRegState(DstIsKill));
1254
1255 if (ImpIsDead)
1256 MIBLO->getOperand(2).setIsDead();
1257
1258 // SREG is always implicitly killed
1259 MIBLO->getOperand(3).setIsKill();
1260
1261 MI.eraseFromParent();
1262 return true;
1263}
1264
1265template <>
1266bool AVRExpandPseudo::expand<AVR::RORWRd>(Block &MBB, BlockIt MBBI) {
1267 llvm_unreachable("RORW unimplemented");
1268 return false;
1269}
1270
1271template <>
1272bool AVRExpandPseudo::expand<AVR::ROLWRd>(Block &MBB, BlockIt MBBI) {
1273 llvm_unreachable("ROLW unimplemented");
1274 return false;
1275}
1276
1277template <>
1278bool AVRExpandPseudo::expand<AVR::ASRWRd>(Block &MBB, BlockIt MBBI) {
1279 MachineInstr &MI = *MBBI;
1280 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1281 unsigned DstReg = MI.getOperand(0).getReg();
1282 bool DstIsDead = MI.getOperand(0).isDead();
1283 bool DstIsKill = MI.getOperand(1).isKill();
1284 bool ImpIsDead = MI.getOperand(2).isDead();
1285 OpLo = AVR::RORRd;
1286 OpHi = AVR::ASRRd;
1287 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1288
1289 // High part
1290 buildMI(MBB, MBBI, OpHi)
1291 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1292 .addReg(DstHiReg, getKillRegState(DstIsKill));
1293
1294 auto MIBLO = buildMI(MBB, MBBI, OpLo)
1295 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1296 .addReg(DstLoReg, getKillRegState(DstIsKill));
1297
1298 if (ImpIsDead)
1299 MIBLO->getOperand(2).setIsDead();
1300
1301 // SREG is always implicitly killed
1302 MIBLO->getOperand(3).setIsKill();
1303
1304 MI.eraseFromParent();
1305 return true;
1306}
1307
1308template <> bool AVRExpandPseudo::expand<AVR::SEXT>(Block &MBB, BlockIt MBBI) {
1309 MachineInstr &MI = *MBBI;
1310 unsigned DstLoReg, DstHiReg;
1311 // sext R17:R16, R17
1312 // mov r16, r17
1313 // lsl r17
1314 // sbc r17, r17
1315 // sext R17:R16, R13
1316 // mov r16, r13
1317 // mov r17, r13
1318 // lsl r17
1319 // sbc r17, r17
1320 // sext R17:R16, R16
1321 // mov r17, r16
1322 // lsl r17
1323 // sbc r17, r17
1324 unsigned DstReg = MI.getOperand(0).getReg();
1325 unsigned SrcReg = MI.getOperand(1).getReg();
1326 bool DstIsDead = MI.getOperand(0).isDead();
1327 bool SrcIsKill = MI.getOperand(1).isKill();
1328 bool ImpIsDead = MI.getOperand(2).isDead();
1329 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1330
1331 if (SrcReg != DstLoReg) {
1332 auto MOV = buildMI(MBB, MBBI, AVR::MOVRdRr)
1333 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1334 .addReg(SrcReg);
1335
1336 if (SrcReg == DstHiReg) {
1337 MOV->getOperand(1).setIsKill();
1338 }
1339 }
1340
1341 if (SrcReg != DstHiReg) {
1342 buildMI(MBB, MBBI, AVR::MOVRdRr)
1343 .addReg(DstHiReg, RegState::Define)
1344 .addReg(SrcReg, getKillRegState(SrcIsKill));
1345 }
1346
1347 buildMI(MBB, MBBI, AVR::LSLRd)
1348 .addReg(DstHiReg, RegState::Define)
1349 .addReg(DstHiReg, RegState::Kill);
1350
1351 auto SBC = buildMI(MBB, MBBI, AVR::SBCRdRr)
1352 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1353 .addReg(DstHiReg, RegState::Kill)
1354 .addReg(DstHiReg, RegState::Kill);
1355
1356 if (ImpIsDead)
1357 SBC->getOperand(3).setIsDead();
1358
1359 // SREG is always implicitly killed
1360 SBC->getOperand(4).setIsKill();
1361
1362 MI.eraseFromParent();
1363 return true;
1364}
1365
1366template <> bool AVRExpandPseudo::expand<AVR::ZEXT>(Block &MBB, BlockIt MBBI) {
1367 MachineInstr &MI = *MBBI;
1368 unsigned DstLoReg, DstHiReg;
1369 // zext R25:R24, R20
1370 // mov R24, R20
1371 // eor R25, R25
1372 // zext R25:R24, R24
1373 // eor R25, R25
1374 // zext R25:R24, R25
1375 // mov R24, R25
1376 // eor R25, R25
1377 unsigned DstReg = MI.getOperand(0).getReg();
1378 unsigned SrcReg = MI.getOperand(1).getReg();
1379 bool DstIsDead = MI.getOperand(0).isDead();
1380 bool SrcIsKill = MI.getOperand(1).isKill();
1381 bool ImpIsDead = MI.getOperand(2).isDead();
1382 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1383
1384 if (SrcReg != DstLoReg) {
1385 buildMI(MBB, MBBI, AVR::MOVRdRr)
1386 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1387 .addReg(SrcReg, getKillRegState(SrcIsKill));
1388 }
1389
1390 auto EOR = buildMI(MBB, MBBI, AVR::EORRdRr)
1391 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1392 .addReg(DstHiReg, RegState::Kill)
1393 .addReg(DstHiReg, RegState::Kill);
1394
1395 if (ImpIsDead)
1396 EOR->getOperand(3).setIsDead();
1397
1398 MI.eraseFromParent();
1399 return true;
1400}
1401
1402template <>
1403bool AVRExpandPseudo::expand<AVR::SPREAD>(Block &MBB, BlockIt MBBI) {
1404 MachineInstr &MI = *MBBI;
1405 unsigned OpLo, OpHi, DstLoReg, DstHiReg;
1406 unsigned DstReg = MI.getOperand(0).getReg();
1407 bool DstIsDead = MI.getOperand(0).isDead();
1408 unsigned Flags = MI.getFlags();
1409 OpLo = AVR::INRdA;
1410 OpHi = AVR::INRdA;
1411 TRI->splitReg(DstReg, DstLoReg, DstHiReg);
1412
1413 // Low part
1414 buildMI(MBB, MBBI, OpLo)
1415 .addReg(DstLoReg, RegState::Define | getDeadRegState(DstIsDead))
1416 .addImm(0x3d)
1417 .setMIFlags(Flags);
1418
1419 // High part
1420 buildMI(MBB, MBBI, OpHi)
1421 .addReg(DstHiReg, RegState::Define | getDeadRegState(DstIsDead))
1422 .addImm(0x3e)
1423 .setMIFlags(Flags);
1424
1425 MI.eraseFromParent();
1426 return true;
1427}
1428
1429template <>
1430bool AVRExpandPseudo::expand<AVR::SPWRITE>(Block &MBB, BlockIt MBBI) {
1431 MachineInstr &MI = *MBBI;
1432 unsigned SrcLoReg, SrcHiReg;
1433 unsigned SrcReg = MI.getOperand(1).getReg();
1434 bool SrcIsKill = MI.getOperand(1).isKill();
1435 unsigned Flags = MI.getFlags();
1436 TRI->splitReg(SrcReg, SrcLoReg, SrcHiReg);
1437
1438 buildMI(MBB, MBBI, AVR::INRdA)
1439 .addReg(AVR::R0, RegState::Define)
1440 .addImm(SREG_ADDR)
1441 .setMIFlags(Flags);
1442
1443 buildMI(MBB, MBBI, AVR::BCLRs).addImm(0x07).setMIFlags(Flags);
1444
1445 buildMI(MBB, MBBI, AVR::OUTARr)
1446 .addImm(0x3e)
1447 .addReg(SrcHiReg, getKillRegState(SrcIsKill))
1448 .setMIFlags(Flags);
1449
1450 buildMI(MBB, MBBI, AVR::OUTARr)
1451 .addImm(SREG_ADDR)
1452 .addReg(AVR::R0, RegState::Kill)
1453 .setMIFlags(Flags);
1454
1455 buildMI(MBB, MBBI, AVR::OUTARr)
1456 .addImm(0x3d)
1457 .addReg(SrcLoReg, getKillRegState(SrcIsKill))
1458 .setMIFlags(Flags);
1459
1460 MI.eraseFromParent();
1461 return true;
1462}
1463
1464bool AVRExpandPseudo::expandMI(Block &MBB, BlockIt MBBI) {
1465 MachineInstr &MI = *MBBI;
1466 int Opcode = MBBI->getOpcode();
1467
1468#define EXPAND(Op) \
1469 case Op: \
1470 return expand<Op>(MBB, MI)
1471
1472 switch (Opcode) {
1473 EXPAND(AVR::ADDWRdRr);
1474 EXPAND(AVR::ADCWRdRr);
1475 EXPAND(AVR::SUBWRdRr);
1476 EXPAND(AVR::SUBIWRdK);
1477 EXPAND(AVR::SBCWRdRr);
1478 EXPAND(AVR::SBCIWRdK);
1479 EXPAND(AVR::ANDWRdRr);
1480 EXPAND(AVR::ANDIWRdK);
1481 EXPAND(AVR::ORWRdRr);
1482 EXPAND(AVR::ORIWRdK);
1483 EXPAND(AVR::EORWRdRr);
1484 EXPAND(AVR::COMWRd);
1485 EXPAND(AVR::CPWRdRr);
1486 EXPAND(AVR::CPCWRdRr);
1487 EXPAND(AVR::LDIWRdK);
1488 EXPAND(AVR::LDSWRdK);
1489 EXPAND(AVR::LDWRdPtr);
1490 EXPAND(AVR::LDWRdPtrPi);
1491 EXPAND(AVR::LDWRdPtrPd);
1492 case AVR::LDDWRdYQ: //:FIXME: remove this once PR13375 gets fixed
1493 EXPAND(AVR::LDDWRdPtrQ);
Dylan McKaya5d49df2016-12-09 07:49:04 +00001494 EXPAND(AVR::LPMWRdZ);
1495 EXPAND(AVR::LPMWRdZPi);
Dylan McKaya789f402016-11-16 21:58:04 +00001496 EXPAND(AVR::AtomicLoad8);
1497 EXPAND(AVR::AtomicLoad16);
1498 EXPAND(AVR::AtomicStore8);
1499 EXPAND(AVR::AtomicStore16);
1500 EXPAND(AVR::AtomicLoadAdd8);
1501 EXPAND(AVR::AtomicLoadAdd16);
1502 EXPAND(AVR::AtomicLoadSub8);
1503 EXPAND(AVR::AtomicLoadSub16);
1504 EXPAND(AVR::AtomicLoadAnd8);
1505 EXPAND(AVR::AtomicLoadAnd16);
1506 EXPAND(AVR::AtomicLoadOr8);
1507 EXPAND(AVR::AtomicLoadOr16);
1508 EXPAND(AVR::AtomicLoadXor8);
1509 EXPAND(AVR::AtomicLoadXor16);
1510 EXPAND(AVR::AtomicFence);
1511 EXPAND(AVR::STSWKRr);
1512 EXPAND(AVR::STWPtrRr);
1513 EXPAND(AVR::STWPtrPiRr);
1514 EXPAND(AVR::STWPtrPdRr);
1515 EXPAND(AVR::STDWPtrQRr);
1516 EXPAND(AVR::INWRdA);
1517 EXPAND(AVR::OUTWARr);
1518 EXPAND(AVR::PUSHWRr);
1519 EXPAND(AVR::POPWRd);
1520 EXPAND(AVR::LSLWRd);
1521 EXPAND(AVR::LSRWRd);
1522 EXPAND(AVR::RORWRd);
1523 EXPAND(AVR::ROLWRd);
1524 EXPAND(AVR::ASRWRd);
1525 EXPAND(AVR::SEXT);
1526 EXPAND(AVR::ZEXT);
1527 EXPAND(AVR::SPREAD);
1528 EXPAND(AVR::SPWRITE);
1529 }
1530#undef EXPAND
1531 return false;
1532}
1533
Dylan McKay017a55b2016-11-16 23:06:14 +00001534} // end of anonymous namespace
1535
Dylan McKay8cec7eb2016-12-07 11:08:56 +00001536INITIALIZE_PASS(AVRExpandPseudo, "avr-expand-pseudo",
1537 AVR_EXPAND_PSEUDO_NAME, false, false)
Dylan McKaya789f402016-11-16 21:58:04 +00001538namespace llvm {
1539
1540FunctionPass *createAVRExpandPseudoPass() { return new AVRExpandPseudo(); }
1541
1542} // end of namespace llvm