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