xref: /freebsd/contrib/llvm-project/llvm/lib/Target/M68k/M68kInstrInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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