1 //===-- M68kInstrInfo.cpp - M68k Instruction Information --------*- C++ -*-===//
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 /// \file
10 /// This file contains the M68k declaration of the TargetInstrInfo class.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "M68kInstrInfo.h"
15
16 #include "M68kInstrBuilder.h"
17 #include "M68kMachineFunction.h"
18 #include "M68kTargetMachine.h"
19 #include "MCTargetDesc/M68kMCCodeEmitter.h"
20
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/ADT/ScopeExit.h"
23 #include "llvm/CodeGen/LivePhysRegs.h"
24 #include "llvm/CodeGen/LiveVariables.h"
25 #include "llvm/CodeGen/MachineInstrBuilder.h"
26 #include "llvm/CodeGen/MachineRegisterInfo.h"
27 #include "llvm/MC/TargetRegistry.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/Regex.h"
30
31 #include <functional>
32
33 using namespace llvm;
34
35 #define DEBUG_TYPE "M68k-instr-info"
36
37 #define GET_INSTRINFO_CTOR_DTOR
38 #include "M68kGenInstrInfo.inc"
39
40 // Pin the vtable to this file.
anchor()41 void M68kInstrInfo::anchor() {}
42
M68kInstrInfo(const M68kSubtarget & STI)43 M68kInstrInfo::M68kInstrInfo(const M68kSubtarget &STI)
44 : M68kGenInstrInfo(M68k::ADJCALLSTACKDOWN, M68k::ADJCALLSTACKUP, 0,
45 M68k::RET),
46 Subtarget(STI), RI(STI) {}
47
getCondFromBranchOpc(unsigned BrOpc)48 static M68k::CondCode getCondFromBranchOpc(unsigned BrOpc) {
49 switch (BrOpc) {
50 default:
51 return M68k::COND_INVALID;
52 case M68k::Beq8:
53 return M68k::COND_EQ;
54 case M68k::Bne8:
55 return M68k::COND_NE;
56 case M68k::Blt8:
57 return M68k::COND_LT;
58 case M68k::Ble8:
59 return M68k::COND_LE;
60 case M68k::Bgt8:
61 return M68k::COND_GT;
62 case M68k::Bge8:
63 return M68k::COND_GE;
64 case M68k::Bcs8:
65 return M68k::COND_CS;
66 case M68k::Bls8:
67 return M68k::COND_LS;
68 case M68k::Bhi8:
69 return M68k::COND_HI;
70 case M68k::Bcc8:
71 return M68k::COND_CC;
72 case M68k::Bmi8:
73 return M68k::COND_MI;
74 case M68k::Bpl8:
75 return M68k::COND_PL;
76 case M68k::Bvs8:
77 return M68k::COND_VS;
78 case M68k::Bvc8:
79 return M68k::COND_VC;
80 }
81 }
82
AnalyzeBranchImpl(MachineBasicBlock & MBB,MachineBasicBlock * & TBB,MachineBasicBlock * & FBB,SmallVectorImpl<MachineOperand> & Cond,bool AllowModify) const83 bool M68kInstrInfo::AnalyzeBranchImpl(MachineBasicBlock &MBB,
84 MachineBasicBlock *&TBB,
85 MachineBasicBlock *&FBB,
86 SmallVectorImpl<MachineOperand> &Cond,
87 bool AllowModify) const {
88
89 auto UncondBranch =
90 std::pair<MachineBasicBlock::reverse_iterator, MachineBasicBlock *>{
91 MBB.rend(), nullptr};
92
93 // Erase any instructions if allowed at the end of the scope.
94 std::vector<std::reference_wrapper<llvm::MachineInstr>> EraseList;
95 auto FinalizeOnReturn = llvm::make_scope_exit([&EraseList] {
96 std::for_each(EraseList.begin(), EraseList.end(),
97 [](auto &ref) { ref.get().eraseFromParent(); });
98 });
99
100 // Start from the bottom of the block and work up, examining the
101 // terminator instructions.
102 for (auto iter = MBB.rbegin(); iter != MBB.rend(); iter = std::next(iter)) {
103
104 unsigned Opcode = iter->getOpcode();
105
106 if (iter->isDebugInstr())
107 continue;
108
109 // Working from the bottom, when we see a non-terminator instruction, we're
110 // done.
111 if (!isUnpredicatedTerminator(*iter))
112 break;
113
114 // A terminator that isn't a branch can't easily be handled by this
115 // analysis.
116 if (!iter->isBranch())
117 return true;
118
119 // Handle unconditional branches.
120 if (Opcode == M68k::BRA8 || Opcode == M68k::BRA16) {
121 if (!iter->getOperand(0).isMBB())
122 return true;
123 UncondBranch = {iter, iter->getOperand(0).getMBB()};
124
125 // TBB is used to indicate the unconditional destination.
126 TBB = UncondBranch.second;
127
128 if (!AllowModify)
129 continue;
130
131 // If the block has any instructions after a JMP, erase them.
132 EraseList.insert(EraseList.begin(), MBB.rbegin(), iter);
133
134 Cond.clear();
135 FBB = nullptr;
136
137 // Erase the JMP if it's equivalent to a fall-through.
138 if (MBB.isLayoutSuccessor(UncondBranch.second)) {
139 TBB = nullptr;
140 EraseList.push_back(*iter);
141 UncondBranch = {MBB.rend(), nullptr};
142 }
143
144 continue;
145 }
146
147 // Handle conditional branches.
148 auto BranchCode = M68k::GetCondFromBranchOpc(Opcode);
149
150 // Can't handle indirect branch.
151 if (BranchCode == M68k::COND_INVALID)
152 return true;
153
154 // In practice we should never have an undef CCR operand, if we do
155 // abort here as we are not prepared to preserve the flag.
156 // ??? Is this required?
157 // if (iter->getOperand(1).isUndef())
158 // return true;
159
160 // Working from the bottom, handle the first conditional branch.
161 if (Cond.empty()) {
162 if (!iter->getOperand(0).isMBB())
163 return true;
164 MachineBasicBlock *CondBranchTarget = iter->getOperand(0).getMBB();
165
166 // If we see something like this:
167 //
168 // bcc l1
169 // bra l2
170 // ...
171 // l1:
172 // ...
173 // l2:
174 if (UncondBranch.first != MBB.rend()) {
175
176 assert(std::next(UncondBranch.first) == iter && "Wrong block layout.");
177
178 // And we are allowed to modify the block and the target block of the
179 // conditional branch is the direct successor of this block:
180 //
181 // bcc l1
182 // bra l2
183 // l1:
184 // ...
185 // l2:
186 //
187 // we change it to this if allowed:
188 //
189 // bncc l2
190 // l1:
191 // ...
192 // l2:
193 //
194 // Which is a bit more efficient.
195 if (AllowModify && MBB.isLayoutSuccessor(CondBranchTarget)) {
196
197 BranchCode = GetOppositeBranchCondition(BranchCode);
198 unsigned BNCC = GetCondBranchFromCond(BranchCode);
199
200 BuildMI(MBB, *UncondBranch.first, MBB.rfindDebugLoc(iter), get(BNCC))
201 .addMBB(UncondBranch.second);
202
203 EraseList.push_back(*iter);
204 EraseList.push_back(*UncondBranch.first);
205
206 TBB = UncondBranch.second;
207 FBB = nullptr;
208 Cond.push_back(MachineOperand::CreateImm(BranchCode));
209
210 // Otherwise preserve TBB, FBB and Cond as requested
211 } else {
212 TBB = CondBranchTarget;
213 FBB = UncondBranch.second;
214 Cond.push_back(MachineOperand::CreateImm(BranchCode));
215 }
216
217 UncondBranch = {MBB.rend(), nullptr};
218 continue;
219 }
220
221 TBB = CondBranchTarget;
222 FBB = nullptr;
223 Cond.push_back(MachineOperand::CreateImm(BranchCode));
224
225 continue;
226 }
227
228 // Handle subsequent conditional branches. Only handle the case where all
229 // conditional branches branch to the same destination and their condition
230 // opcodes fit one of the special multi-branch idioms.
231 assert(Cond.size() == 1);
232 assert(TBB);
233
234 // If the conditions are the same, we can leave them alone.
235 auto OldBranchCode = static_cast<M68k::CondCode>(Cond[0].getImm());
236 if (!iter->getOperand(0).isMBB())
237 return true;
238 auto NewTBB = iter->getOperand(0).getMBB();
239 if (OldBranchCode == BranchCode && TBB == NewTBB)
240 continue;
241
242 // If they differ we cannot do much here.
243 return true;
244 }
245
246 return false;
247 }
248
analyzeBranch(MachineBasicBlock & MBB,MachineBasicBlock * & TBB,MachineBasicBlock * & FBB,SmallVectorImpl<MachineOperand> & Cond,bool AllowModify) const249 bool M68kInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
250 MachineBasicBlock *&TBB,
251 MachineBasicBlock *&FBB,
252 SmallVectorImpl<MachineOperand> &Cond,
253 bool AllowModify) const {
254 return AnalyzeBranchImpl(MBB, TBB, FBB, Cond, AllowModify);
255 }
256
removeBranch(MachineBasicBlock & MBB,int * BytesRemoved) const257 unsigned M68kInstrInfo::removeBranch(MachineBasicBlock &MBB,
258 int *BytesRemoved) const {
259 assert(!BytesRemoved && "code size not handled");
260
261 MachineBasicBlock::iterator I = MBB.end();
262 unsigned Count = 0;
263
264 while (I != MBB.begin()) {
265 --I;
266 if (I->isDebugValue())
267 continue;
268 if (I->getOpcode() != M68k::BRA8 &&
269 getCondFromBranchOpc(I->getOpcode()) == M68k::COND_INVALID)
270 break;
271 // Remove the branch.
272 I->eraseFromParent();
273 I = MBB.end();
274 ++Count;
275 }
276
277 return Count;
278 }
279
insertBranch(MachineBasicBlock & MBB,MachineBasicBlock * TBB,MachineBasicBlock * FBB,ArrayRef<MachineOperand> Cond,const DebugLoc & DL,int * BytesAdded) const280 unsigned M68kInstrInfo::insertBranch(
281 MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
282 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
283 // Shouldn't be a fall through.
284 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
285 assert((Cond.size() == 1 || Cond.size() == 0) &&
286 "M68k branch conditions have one component!");
287 assert(!BytesAdded && "code size not handled");
288
289 if (Cond.empty()) {
290 // Unconditional branch?
291 assert(!FBB && "Unconditional branch with multiple successors!");
292 BuildMI(&MBB, DL, get(M68k::BRA8)).addMBB(TBB);
293 return 1;
294 }
295
296 // If FBB is null, it is implied to be a fall-through block.
297 bool FallThru = FBB == nullptr;
298
299 // Conditional branch.
300 unsigned Count = 0;
301 M68k::CondCode CC = (M68k::CondCode)Cond[0].getImm();
302 unsigned Opc = GetCondBranchFromCond(CC);
303 BuildMI(&MBB, DL, get(Opc)).addMBB(TBB);
304 ++Count;
305 if (!FallThru) {
306 // Two-way Conditional branch. Insert the second branch.
307 BuildMI(&MBB, DL, get(M68k::BRA8)).addMBB(FBB);
308 ++Count;
309 }
310 return Count;
311 }
312
AddSExt(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,DebugLoc DL,unsigned Reg,MVT From,MVT To) const313 void M68kInstrInfo::AddSExt(MachineBasicBlock &MBB,
314 MachineBasicBlock::iterator I, DebugLoc DL,
315 unsigned Reg, MVT From, MVT To) const {
316 if (From == MVT::i8) {
317 unsigned R = Reg;
318 // EXT16 requires i16 register
319 if (To == MVT::i32) {
320 R = RI.getSubReg(Reg, M68k::MxSubRegIndex16Lo);
321 assert(R && "No viable SUB register available");
322 }
323 BuildMI(MBB, I, DL, get(M68k::EXT16), R).addReg(R);
324 }
325
326 if (To == MVT::i32)
327 BuildMI(MBB, I, DL, get(M68k::EXT32), Reg).addReg(Reg);
328 }
329
AddZExt(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,DebugLoc DL,unsigned Reg,MVT From,MVT To) const330 void M68kInstrInfo::AddZExt(MachineBasicBlock &MBB,
331 MachineBasicBlock::iterator I, DebugLoc DL,
332 unsigned Reg, MVT From, MVT To) const {
333
334 unsigned Mask, And;
335 if (From == MVT::i8)
336 Mask = 0xFF;
337 else
338 Mask = 0xFFFF;
339
340 if (To == MVT::i16)
341 And = M68k::AND16di;
342 else // i32
343 And = M68k::AND32di;
344
345 // TODO use xor r,r to decrease size
346 BuildMI(MBB, I, DL, get(And), Reg).addReg(Reg).addImm(Mask);
347 }
348
349 // Convert MOVI to MOVQ if the target is a data register and the immediate
350 // fits in a sign-extended i8, otherwise emit a plain MOV.
ExpandMOVI(MachineInstrBuilder & MIB,MVT MVTSize) const351 bool M68kInstrInfo::ExpandMOVI(MachineInstrBuilder &MIB, MVT MVTSize) const {
352 Register Reg = MIB->getOperand(0).getReg();
353 int64_t Imm = MIB->getOperand(1).getImm();
354 bool IsAddressReg = false;
355
356 const auto *DR32 = RI.getRegClass(M68k::DR32RegClassID);
357 const auto *AR32 = RI.getRegClass(M68k::AR32RegClassID);
358 const auto *AR16 = RI.getRegClass(M68k::AR16RegClassID);
359
360 if (AR16->contains(Reg) || AR32->contains(Reg))
361 IsAddressReg = true;
362
363 LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to ");
364
365 if (MVTSize == MVT::i8 || (!IsAddressReg && Imm >= -128 && Imm <= 127)) {
366 LLVM_DEBUG(dbgs() << "MOVEQ\n");
367
368 // We need to assign to the full register to make IV happy
369 Register SReg =
370 MVTSize == MVT::i32 ? Reg : Register(RI.getMatchingMegaReg(Reg, DR32));
371 assert(SReg && "No viable MEGA register available");
372
373 MIB->setDesc(get(M68k::MOVQ));
374 MIB->getOperand(0).setReg(SReg);
375 } else {
376 LLVM_DEBUG(dbgs() << "MOVE\n");
377 MIB->setDesc(get(MVTSize == MVT::i16 ? M68k::MOV16ri : M68k::MOV32ri));
378 }
379
380 return true;
381 }
382
ExpandMOVX_RR(MachineInstrBuilder & MIB,MVT MVTDst,MVT MVTSrc) const383 bool M68kInstrInfo::ExpandMOVX_RR(MachineInstrBuilder &MIB, MVT MVTDst,
384 MVT MVTSrc) const {
385 unsigned Move = MVTDst == MVT::i16 ? M68k::MOV16rr : M68k::MOV32rr;
386 Register Dst = MIB->getOperand(0).getReg();
387 Register Src = MIB->getOperand(1).getReg();
388
389 assert(Dst != Src && "You cannot use the same Regs with MOVX_RR");
390
391 const auto &TRI = getRegisterInfo();
392
393 const auto *RCDst = TRI.getMaximalPhysRegClass(Dst, MVTDst);
394 const auto *RCSrc = TRI.getMaximalPhysRegClass(Src, MVTSrc);
395
396 assert(RCDst && RCSrc && "Wrong use of MOVX_RR");
397 assert(RCDst != RCSrc && "You cannot use the same Reg Classes with MOVX_RR");
398 (void)RCSrc;
399
400 // We need to find the super source register that matches the size of Dst
401 unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst);
402 assert(SSrc && "No viable MEGA register available");
403
404 DebugLoc DL = MIB->getDebugLoc();
405
406 // If it happens to that super source register is the destination register
407 // we do nothing
408 if (Dst == SSrc) {
409 LLVM_DEBUG(dbgs() << "Remove " << *MIB.getInstr() << '\n');
410 MIB->eraseFromParent();
411 } else { // otherwise we need to MOV
412 LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to MOV\n");
413 MIB->setDesc(get(Move));
414 MIB->getOperand(1).setReg(SSrc);
415 }
416
417 return true;
418 }
419
420 /// Expand SExt MOVE pseudos into a MOV and a EXT if the operands are two
421 /// different registers or just EXT if it is the same register
ExpandMOVSZX_RR(MachineInstrBuilder & MIB,bool IsSigned,MVT MVTDst,MVT MVTSrc) const422 bool M68kInstrInfo::ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned,
423 MVT MVTDst, MVT MVTSrc) const {
424 LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to ");
425
426 unsigned Move;
427
428 if (MVTDst == MVT::i16)
429 Move = M68k::MOV16rr;
430 else // i32
431 Move = M68k::MOV32rr;
432
433 Register Dst = MIB->getOperand(0).getReg();
434 Register Src = MIB->getOperand(1).getReg();
435
436 assert(Dst != Src && "You cannot use the same Regs with MOVSX_RR");
437
438 const auto &TRI = getRegisterInfo();
439
440 const auto *RCDst = TRI.getMaximalPhysRegClass(Dst, MVTDst);
441 const auto *RCSrc = TRI.getMaximalPhysRegClass(Src, MVTSrc);
442
443 assert(RCDst && RCSrc && "Wrong use of MOVSX_RR");
444 assert(RCDst != RCSrc && "You cannot use the same Reg Classes with MOVSX_RR");
445 (void)RCSrc;
446
447 // We need to find the super source register that matches the size of Dst
448 unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst);
449 assert(SSrc && "No viable MEGA register available");
450
451 MachineBasicBlock &MBB = *MIB->getParent();
452 DebugLoc DL = MIB->getDebugLoc();
453
454 if (Dst != SSrc) {
455 LLVM_DEBUG(dbgs() << "Move and " << '\n');
456 BuildMI(MBB, MIB.getInstr(), DL, get(Move), Dst).addReg(SSrc);
457 }
458
459 if (IsSigned) {
460 LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');
461 AddSExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
462 } else {
463 LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
464 AddZExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
465 }
466
467 MIB->eraseFromParent();
468
469 return true;
470 }
471
ExpandMOVSZX_RM(MachineInstrBuilder & MIB,bool IsSigned,const MCInstrDesc & Desc,MVT MVTDst,MVT MVTSrc) const472 bool M68kInstrInfo::ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned,
473 const MCInstrDesc &Desc, MVT MVTDst,
474 MVT MVTSrc) const {
475 LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to LOAD and ");
476
477 Register Dst = MIB->getOperand(0).getReg();
478
479 // We need the subreg of Dst to make instruction verifier happy because the
480 // real machine instruction consumes and produces values of the same size and
481 // the registers the will be used here fall into different classes and this
482 // makes IV cry. We could use a bigger operation, but this will put some
483 // pressure on cache and memory, so no.
484 unsigned SubDst =
485 RI.getSubReg(Dst, MVTSrc == MVT::i8 ? M68k::MxSubRegIndex8Lo
486 : M68k::MxSubRegIndex16Lo);
487 assert(SubDst && "No viable SUB register available");
488
489 // Make this a plain move
490 MIB->setDesc(Desc);
491 MIB->getOperand(0).setReg(SubDst);
492
493 MachineBasicBlock::iterator I = MIB.getInstr();
494 I++;
495 MachineBasicBlock &MBB = *MIB->getParent();
496 DebugLoc DL = MIB->getDebugLoc();
497
498 if (IsSigned) {
499 LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');
500 AddSExt(MBB, I, DL, Dst, MVTSrc, MVTDst);
501 } else {
502 LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
503 AddZExt(MBB, I, DL, Dst, MVTSrc, MVTDst);
504 }
505
506 return true;
507 }
508
ExpandPUSH_POP(MachineInstrBuilder & MIB,const MCInstrDesc & Desc,bool IsPush) const509 bool M68kInstrInfo::ExpandPUSH_POP(MachineInstrBuilder &MIB,
510 const MCInstrDesc &Desc, bool IsPush) const {
511 MachineBasicBlock::iterator I = MIB.getInstr();
512 I++;
513 MachineBasicBlock &MBB = *MIB->getParent();
514 MachineOperand MO = MIB->getOperand(0);
515 DebugLoc DL = MIB->getDebugLoc();
516 if (IsPush)
517 BuildMI(MBB, I, DL, Desc).addReg(RI.getStackRegister()).add(MO);
518 else
519 BuildMI(MBB, I, DL, Desc, MO.getReg()).addReg(RI.getStackRegister());
520
521 MIB->eraseFromParent();
522 return true;
523 }
524
ExpandCCR(MachineInstrBuilder & MIB,bool IsToCCR) const525 bool M68kInstrInfo::ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const {
526
527 // Replace the pseudo instruction with the real one
528 if (IsToCCR)
529 MIB->setDesc(get(M68k::MOV16cd));
530 else
531 // FIXME M68010 or later is required
532 MIB->setDesc(get(M68k::MOV16dc));
533
534 // Promote used register to the next class
535 auto &Opd = MIB->getOperand(1);
536 Opd.setReg(getRegisterInfo().getMatchingSuperReg(
537 Opd.getReg(), M68k::MxSubRegIndex8Lo, &M68k::DR16RegClass));
538
539 return true;
540 }
541
ExpandMOVEM(MachineInstrBuilder & MIB,const MCInstrDesc & Desc,bool IsRM) const542 bool M68kInstrInfo::ExpandMOVEM(MachineInstrBuilder &MIB,
543 const MCInstrDesc &Desc, bool IsRM) const {
544 int Reg = 0, Offset = 0, Base = 0;
545 auto XR32 = RI.getRegClass(M68k::XR32RegClassID);
546 auto DL = MIB->getDebugLoc();
547 auto MI = MIB.getInstr();
548 auto &MBB = *MIB->getParent();
549
550 if (IsRM) {
551 Reg = MIB->getOperand(0).getReg();
552 Offset = MIB->getOperand(1).getImm();
553 Base = MIB->getOperand(2).getReg();
554 } else {
555 Offset = MIB->getOperand(0).getImm();
556 Base = MIB->getOperand(1).getReg();
557 Reg = MIB->getOperand(2).getReg();
558 }
559
560 // If the register is not in XR32 then it is smaller than 32 bit, we
561 // implicitly promote it to 32
562 if (!XR32->contains(Reg)) {
563 Reg = RI.getMatchingMegaReg(Reg, XR32);
564 assert(Reg && "Has not meaningful MEGA register");
565 }
566
567 unsigned Mask = 1 << RI.getSpillRegisterOrder(Reg);
568 if (IsRM) {
569 BuildMI(MBB, MI, DL, Desc)
570 .addImm(Mask)
571 .addImm(Offset)
572 .addReg(Base)
573 .addReg(Reg, RegState::ImplicitDefine)
574 .copyImplicitOps(*MIB);
575 } else {
576 BuildMI(MBB, MI, DL, Desc)
577 .addImm(Offset)
578 .addReg(Base)
579 .addImm(Mask)
580 .addReg(Reg, RegState::Implicit)
581 .copyImplicitOps(*MIB);
582 }
583
584 MIB->eraseFromParent();
585
586 return true;
587 }
588
589 /// Expand a single-def pseudo instruction to a two-addr
590 /// instruction with two undef reads of the register being defined.
591 /// This is used for mapping:
592 /// %d0 = SETCS_C32d
593 /// to:
594 /// %d0 = SUBX32dd %d0<undef>, %d0<undef>
595 ///
Expand2AddrUndef(MachineInstrBuilder & MIB,const MCInstrDesc & Desc)596 static bool Expand2AddrUndef(MachineInstrBuilder &MIB,
597 const MCInstrDesc &Desc) {
598 assert(Desc.getNumOperands() == 3 && "Expected two-addr instruction.");
599 Register Reg = MIB->getOperand(0).getReg();
600 MIB->setDesc(Desc);
601
602 // MachineInstr::addOperand() will insert explicit operands before any
603 // implicit operands.
604 MIB.addReg(Reg, RegState::Undef).addReg(Reg, RegState::Undef);
605 // But we don't trust that.
606 assert(MIB->getOperand(1).getReg() == Reg &&
607 MIB->getOperand(2).getReg() == Reg && "Misplaced operand");
608 return true;
609 }
610
expandPostRAPseudo(MachineInstr & MI) const611 bool M68kInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
612 MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI);
613 switch (MI.getOpcode()) {
614 case M68k::PUSH8d:
615 return ExpandPUSH_POP(MIB, get(M68k::MOV8ed), true);
616 case M68k::PUSH16d:
617 return ExpandPUSH_POP(MIB, get(M68k::MOV16er), true);
618 case M68k::PUSH32r:
619 return ExpandPUSH_POP(MIB, get(M68k::MOV32er), true);
620
621 case M68k::POP8d:
622 return ExpandPUSH_POP(MIB, get(M68k::MOV8do), false);
623 case M68k::POP16d:
624 return ExpandPUSH_POP(MIB, get(M68k::MOV16ro), false);
625 case M68k::POP32r:
626 return ExpandPUSH_POP(MIB, get(M68k::MOV32ro), false);
627
628 case M68k::SETCS_C8d:
629 return Expand2AddrUndef(MIB, get(M68k::SUBX8dd));
630 case M68k::SETCS_C16d:
631 return Expand2AddrUndef(MIB, get(M68k::SUBX16dd));
632 case M68k::SETCS_C32d:
633 return Expand2AddrUndef(MIB, get(M68k::SUBX32dd));
634 }
635 return false;
636 }
637
isPCRelRegisterOperandLegal(const MachineOperand & MO) const638 bool M68kInstrInfo::isPCRelRegisterOperandLegal(
639 const MachineOperand &MO) const {
640 assert(MO.isReg());
641
642 // Check whether this MO belongs to an instruction with addressing mode 'k',
643 // Refer to TargetInstrInfo.h for more information about this function.
644
645 const MachineInstr *MI = MO.getParent();
646 const unsigned NameIndices = M68kInstrNameIndices[MI->getOpcode()];
647 StringRef InstrName(&M68kInstrNameData[NameIndices]);
648 const unsigned OperandNo = MO.getOperandNo();
649
650 // If this machine operand is the 2nd operand, then check
651 // whether the instruction has destination addressing mode 'k'.
652 if (OperandNo == 1)
653 return Regex("[A-Z]+(8|16|32)k[a-z](_TC)?$").match(InstrName);
654
655 // If this machine operand is the last one, then check
656 // whether the instruction has source addressing mode 'k'.
657 if (OperandNo == MI->getNumExplicitOperands() - 1)
658 return Regex("[A-Z]+(8|16|32)[a-z]k(_TC)?$").match(InstrName);
659
660 return false;
661 }
662
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,const DebugLoc & DL,MCRegister DstReg,MCRegister SrcReg,bool KillSrc) const663 void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
664 MachineBasicBlock::iterator MI,
665 const DebugLoc &DL, MCRegister DstReg,
666 MCRegister SrcReg, bool KillSrc) const {
667 unsigned Opc = 0;
668
669 // First deal with the normal symmetric copies.
670 if (M68k::XR32RegClass.contains(DstReg, SrcReg))
671 Opc = M68k::MOV32rr;
672 else if (M68k::XR16RegClass.contains(DstReg, SrcReg))
673 Opc = M68k::MOV16rr;
674 else if (M68k::DR8RegClass.contains(DstReg, SrcReg))
675 Opc = M68k::MOV8dd;
676
677 if (Opc) {
678 BuildMI(MBB, MI, DL, get(Opc), DstReg)
679 .addReg(SrcReg, getKillRegState(KillSrc));
680 return;
681 }
682
683 // Now deal with asymmetrically sized copies. The cases that follow are upcast
684 // moves.
685 //
686 // NOTE
687 // These moves are not aware of type nature of these values and thus
688 // won't do any SExt or ZExt and upper bits will basically contain garbage.
689 MachineInstrBuilder MIB(*MBB.getParent(), MI);
690 if (M68k::DR8RegClass.contains(SrcReg)) {
691 if (M68k::XR16RegClass.contains(DstReg))
692 Opc = M68k::MOVXd16d8;
693 else if (M68k::XR32RegClass.contains(DstReg))
694 Opc = M68k::MOVXd32d8;
695 } else if (M68k::XR16RegClass.contains(SrcReg) &&
696 M68k::XR32RegClass.contains(DstReg))
697 Opc = M68k::MOVXd32d16;
698
699 if (Opc) {
700 BuildMI(MBB, MI, DL, get(Opc), DstReg)
701 .addReg(SrcReg, getKillRegState(KillSrc));
702 return;
703 }
704
705 bool FromCCR = SrcReg == M68k::CCR;
706 bool FromSR = SrcReg == M68k::SR;
707 bool ToCCR = DstReg == M68k::CCR;
708 bool ToSR = DstReg == M68k::SR;
709
710 if (FromCCR) {
711 assert(M68k::DR8RegClass.contains(DstReg) &&
712 "Need DR8 register to copy CCR");
713 Opc = M68k::MOV8dc;
714 } else if (ToCCR) {
715 assert(M68k::DR8RegClass.contains(SrcReg) &&
716 "Need DR8 register to copy CCR");
717 Opc = M68k::MOV8cd;
718 } else if (FromSR || ToSR)
719 llvm_unreachable("Cannot emit SR copy instruction");
720
721 if (Opc) {
722 BuildMI(MBB, MI, DL, get(Opc), DstReg)
723 .addReg(SrcReg, getKillRegState(KillSrc));
724 return;
725 }
726
727 LLVM_DEBUG(dbgs() << "Cannot copy " << RI.getName(SrcReg) << " to "
728 << RI.getName(DstReg) << '\n');
729 llvm_unreachable("Cannot emit physreg copy instruction");
730 }
731
732 namespace {
getLoadStoreRegOpcode(unsigned Reg,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI,const M68kSubtarget & STI,bool load)733 unsigned getLoadStoreRegOpcode(unsigned Reg, const TargetRegisterClass *RC,
734 const TargetRegisterInfo *TRI,
735 const M68kSubtarget &STI, bool load) {
736 switch (TRI->getRegSizeInBits(*RC)) {
737 default:
738 llvm_unreachable("Unknown spill size");
739 case 8:
740 if (M68k::DR8RegClass.hasSubClassEq(RC))
741 return load ? M68k::MOV8dp : M68k::MOV8pd;
742 if (M68k::CCRCRegClass.hasSubClassEq(RC))
743 return load ? M68k::MOV16cp : M68k::MOV16pc;
744
745 llvm_unreachable("Unknown 1-byte regclass");
746 case 16:
747 assert(M68k::XR16RegClass.hasSubClassEq(RC) && "Unknown 2-byte regclass");
748 return load ? M68k::MOVM16mp_P : M68k::MOVM16pm_P;
749 case 32:
750 assert(M68k::XR32RegClass.hasSubClassEq(RC) && "Unknown 4-byte regclass");
751 return load ? M68k::MOVM32mp_P : M68k::MOVM32pm_P;
752 }
753 }
754
getStoreRegOpcode(unsigned SrcReg,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI,const M68kSubtarget & STI)755 unsigned getStoreRegOpcode(unsigned SrcReg, const TargetRegisterClass *RC,
756 const TargetRegisterInfo *TRI,
757 const M68kSubtarget &STI) {
758 return getLoadStoreRegOpcode(SrcReg, RC, TRI, STI, false);
759 }
760
getLoadRegOpcode(unsigned DstReg,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI,const M68kSubtarget & STI)761 unsigned getLoadRegOpcode(unsigned DstReg, const TargetRegisterClass *RC,
762 const TargetRegisterInfo *TRI,
763 const M68kSubtarget &STI) {
764 return getLoadStoreRegOpcode(DstReg, RC, TRI, STI, true);
765 }
766 } // end anonymous namespace
767
getStackSlotRange(const TargetRegisterClass * RC,unsigned SubIdx,unsigned & Size,unsigned & Offset,const MachineFunction & MF) const768 bool M68kInstrInfo::getStackSlotRange(const TargetRegisterClass *RC,
769 unsigned SubIdx, unsigned &Size,
770 unsigned &Offset,
771 const MachineFunction &MF) const {
772 // The slot size must be the maximum size so we can easily use MOVEM.L
773 Size = 4;
774 Offset = 0;
775 return true;
776 }
777
storeRegToStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,Register SrcReg,bool IsKill,int FrameIndex,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI,Register VReg) const778 void M68kInstrInfo::storeRegToStackSlot(
779 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg,
780 bool IsKill, int FrameIndex, const TargetRegisterClass *RC,
781 const TargetRegisterInfo *TRI, Register VReg) const {
782 const MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
783 assert(MFI.getObjectSize(FrameIndex) >= TRI->getSpillSize(*RC) &&
784 "Stack slot is too small to store");
785 (void)MFI;
786
787 unsigned Opc = getStoreRegOpcode(SrcReg, RC, TRI, Subtarget);
788 DebugLoc DL = MBB.findDebugLoc(MI);
789 // (0,FrameIndex) <- $reg
790 M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIndex)
791 .addReg(SrcReg, getKillRegState(IsKill));
792 }
793
loadRegFromStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,Register DstReg,int FrameIndex,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI,Register VReg) const794 void M68kInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
795 MachineBasicBlock::iterator MI,
796 Register DstReg, int FrameIndex,
797 const TargetRegisterClass *RC,
798 const TargetRegisterInfo *TRI,
799 Register VReg) const {
800 const MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
801 assert(MFI.getObjectSize(FrameIndex) >= TRI->getSpillSize(*RC) &&
802 "Stack slot is too small to load");
803 (void)MFI;
804
805 unsigned Opc = getLoadRegOpcode(DstReg, RC, TRI, Subtarget);
806 DebugLoc DL = MBB.findDebugLoc(MI);
807 M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DstReg), FrameIndex);
808 }
809
810 /// Return a virtual register initialized with the global base register
811 /// value. Output instructions required to initialize the register in the
812 /// function entry block, if necessary.
813 ///
814 /// TODO Move this function to M68kMachineFunctionInfo.
getGlobalBaseReg(MachineFunction * MF) const815 unsigned M68kInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
816 M68kMachineFunctionInfo *MxFI = MF->getInfo<M68kMachineFunctionInfo>();
817 unsigned GlobalBaseReg = MxFI->getGlobalBaseReg();
818 if (GlobalBaseReg != 0)
819 return GlobalBaseReg;
820
821 // Create the register. The code to initialize it is inserted later,
822 // by the M68kGlobalBaseReg pass (below).
823 //
824 // NOTE
825 // Normally M68k uses A5 register as global base pointer but this will
826 // create unnecessary spill if we use less then 4 registers in code; since A5
827 // is callee-save anyway we could try to allocate caller-save first and if
828 // lucky get one, otherwise it does not really matter which callee-save to
829 // use.
830 MachineRegisterInfo &RegInfo = MF->getRegInfo();
831 GlobalBaseReg = RegInfo.createVirtualRegister(&M68k::AR32_NOSPRegClass);
832 MxFI->setGlobalBaseReg(GlobalBaseReg);
833 return GlobalBaseReg;
834 }
835
836 std::pair<unsigned, unsigned>
decomposeMachineOperandsTargetFlags(unsigned TF) const837 M68kInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
838 return std::make_pair(TF, 0u);
839 }
840
841 ArrayRef<std::pair<unsigned, const char *>>
getSerializableDirectMachineOperandTargetFlags() const842 M68kInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
843 using namespace M68kII;
844 static const std::pair<unsigned, const char *> TargetFlags[] = {
845 {MO_ABSOLUTE_ADDRESS, "m68k-absolute"},
846 {MO_PC_RELATIVE_ADDRESS, "m68k-pcrel"},
847 {MO_GOT, "m68k-got"},
848 {MO_GOTOFF, "m68k-gotoff"},
849 {MO_GOTPCREL, "m68k-gotpcrel"},
850 {MO_PLT, "m68k-plt"},
851 {MO_TLSGD, "m68k-tlsgd"},
852 {MO_TLSLD, "m68k-tlsld"},
853 {MO_TLSLDM, "m68k-tlsldm"},
854 {MO_TLSIE, "m68k-tlsie"},
855 {MO_TLSLE, "m68k-tlsle"}};
856 return ArrayRef(TargetFlags);
857 }
858
859 #undef DEBUG_TYPE
860 #define DEBUG_TYPE "m68k-create-global-base-reg"
861
862 #define PASS_NAME "M68k PIC Global Base Reg Initialization"
863
864 namespace {
865 /// This initializes the PIC global base register
866 struct M68kGlobalBaseReg : public MachineFunctionPass {
867 static char ID;
M68kGlobalBaseReg__anon942b497d0411::M68kGlobalBaseReg868 M68kGlobalBaseReg() : MachineFunctionPass(ID) {}
869
runOnMachineFunction__anon942b497d0411::M68kGlobalBaseReg870 bool runOnMachineFunction(MachineFunction &MF) override {
871 const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>();
872 M68kMachineFunctionInfo *MxFI = MF.getInfo<M68kMachineFunctionInfo>();
873
874 unsigned GlobalBaseReg = MxFI->getGlobalBaseReg();
875
876 // If we didn't need a GlobalBaseReg, don't insert code.
877 if (GlobalBaseReg == 0)
878 return false;
879
880 // Insert the set of GlobalBaseReg into the first MBB of the function
881 MachineBasicBlock &FirstMBB = MF.front();
882 MachineBasicBlock::iterator MBBI = FirstMBB.begin();
883 DebugLoc DL = FirstMBB.findDebugLoc(MBBI);
884 const M68kInstrInfo *TII = STI.getInstrInfo();
885
886 // Generate lea (__GLOBAL_OFFSET_TABLE_,%PC), %A5
887 BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::LEA32q), GlobalBaseReg)
888 .addExternalSymbol("_GLOBAL_OFFSET_TABLE_", M68kII::MO_GOTPCREL);
889
890 return true;
891 }
892
getAnalysisUsage__anon942b497d0411::M68kGlobalBaseReg893 void getAnalysisUsage(AnalysisUsage &AU) const override {
894 AU.setPreservesCFG();
895 MachineFunctionPass::getAnalysisUsage(AU);
896 }
897 };
898 char M68kGlobalBaseReg::ID = 0;
899 } // namespace
900
INITIALIZE_PASS(M68kGlobalBaseReg,DEBUG_TYPE,PASS_NAME,false,false)901 INITIALIZE_PASS(M68kGlobalBaseReg, DEBUG_TYPE, PASS_NAME, false, false)
902
903 FunctionPass *llvm::createM68kGlobalBaseRegPass() {
904 return new M68kGlobalBaseReg();
905 }
906