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