LLVM 18.0.0git
M68kInstrInfo.cpp
Go to the documentation of this file.
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"
20
21#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/ScopeExit.h"
29#include "llvm/Support/Regex.h"
30
31#include <functional>
32
33using 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.
41void M68kInstrInfo::anchor() {}
42
44 : M68kGenInstrInfo(M68k::ADJCALLSTACKDOWN, M68k::ADJCALLSTACKUP, 0,
45 M68k::RET),
46 Subtarget(STI), RI(STI) {}
47
48static 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
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
251 MachineBasicBlock *&FBB,
253 bool AllowModify) const {
254 return AnalyzeBranchImpl(MBB, TBB, FBB, Cond, AllowModify);
255}
256
258 int *BytesRemoved) const {
259 assert(!BytesRemoved && "code size not handled");
260
262 unsigned Count = 0;
263
264 while (I != MBB.begin()) {
265 --I;
266 if (I->isDebugValue())
267 continue;
268 if (I->getOpcode() != M68k::BRA8 &&
270 break;
271 // Remove the branch.
272 I->eraseFromParent();
273 I = MBB.end();
274 ++Count;
275 }
276
277 return Count;
278}
279
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
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
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
350 MVT MVTSrc) const {
351 unsigned Move = MVTDst == MVT::i16 ? M68k::MOV16rr : M68k::MOV32rr;
352 Register Dst = MIB->getOperand(0).getReg();
353 Register Src = MIB->getOperand(1).getReg();
354
355 assert(Dst != Src && "You cannot use the same Regs with MOVX_RR");
356
357 const auto &TRI = getRegisterInfo();
358
359 const auto *RCDst = TRI.getMaximalPhysRegClass(Dst, MVTDst);
360 const auto *RCSrc = TRI.getMaximalPhysRegClass(Src, MVTSrc);
361
362 assert(RCDst && RCSrc && "Wrong use of MOVX_RR");
363 assert(RCDst != RCSrc && "You cannot use the same Reg Classes with MOVX_RR");
364
365 // We need to find the super source register that matches the size of Dst
366 unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst);
367 assert(SSrc && "No viable MEGA register available");
368
369 DebugLoc DL = MIB->getDebugLoc();
370
371 // If it happens to that super source register is the destination register
372 // we do nothing
373 if (Dst == SSrc) {
374 LLVM_DEBUG(dbgs() << "Remove " << *MIB.getInstr() << '\n');
375 MIB->eraseFromParent();
376 } else { // otherwise we need to MOV
377 LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to MOV\n");
378 MIB->setDesc(get(Move));
379 MIB->getOperand(1).setReg(SSrc);
380 }
381
382 return true;
383}
384
385/// Expand SExt MOVE pseudos into a MOV and a EXT if the operands are two
386/// different registers or just EXT if it is the same register
388 MVT MVTDst, MVT MVTSrc) const {
389 LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to ");
390
391 unsigned Move;
392
393 if (MVTDst == MVT::i16)
394 Move = M68k::MOV16rr;
395 else // i32
396 Move = M68k::MOV32rr;
397
398 Register Dst = MIB->getOperand(0).getReg();
399 Register Src = MIB->getOperand(1).getReg();
400
401 assert(Dst != Src && "You cannot use the same Regs with MOVSX_RR");
402
403 const auto &TRI = getRegisterInfo();
404
405 const auto *RCDst = TRI.getMaximalPhysRegClass(Dst, MVTDst);
406 const auto *RCSrc = TRI.getMaximalPhysRegClass(Src, MVTSrc);
407
408 assert(RCDst && RCSrc && "Wrong use of MOVSX_RR");
409 assert(RCDst != RCSrc && "You cannot use the same Reg Classes with MOVSX_RR");
410
411 // We need to find the super source register that matches the size of Dst
412 unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst);
413 assert(SSrc && "No viable MEGA register available");
414
416 DebugLoc DL = MIB->getDebugLoc();
417
418 if (Dst != SSrc) {
419 LLVM_DEBUG(dbgs() << "Move and " << '\n');
420 BuildMI(MBB, MIB.getInstr(), DL, get(Move), Dst).addReg(SSrc);
421 }
422
423 if (IsSigned) {
424 LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');
425 AddSExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
426 } else {
427 LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
428 AddZExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
429 }
430
431 MIB->eraseFromParent();
432
433 return true;
434}
435
437 const MCInstrDesc &Desc, MVT MVTDst,
438 MVT MVTSrc) const {
439 LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to LOAD and ");
440
441 Register Dst = MIB->getOperand(0).getReg();
442
443 // We need the subreg of Dst to make instruction verifier happy because the
444 // real machine instruction consumes and produces values of the same size and
445 // the registers the will be used here fall into different classes and this
446 // makes IV cry. We could use a bigger operation, but this will put some
447 // pressure on cache and memory, so no.
448 unsigned SubDst =
449 RI.getSubReg(Dst, MVTSrc == MVT::i8 ? M68k::MxSubRegIndex8Lo
450 : M68k::MxSubRegIndex16Lo);
451 assert(SubDst && "No viable SUB register available");
452
453 // Make this a plain move
454 MIB->setDesc(Desc);
455 MIB->getOperand(0).setReg(SubDst);
456
458 I++;
460 DebugLoc DL = MIB->getDebugLoc();
461
462 if (IsSigned) {
463 LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');
464 AddSExt(MBB, I, DL, Dst, MVTSrc, MVTDst);
465 } else {
466 LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
467 AddZExt(MBB, I, DL, Dst, MVTSrc, MVTDst);
468 }
469
470 return true;
471}
472
474 const MCInstrDesc &Desc, bool IsPush) const {
476 I++;
478 MachineOperand MO = MIB->getOperand(0);
479 DebugLoc DL = MIB->getDebugLoc();
480 if (IsPush)
482 else
484
485 MIB->eraseFromParent();
486 return true;
487}
488
489bool M68kInstrInfo::ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const {
490
491 // Replace the pseudo instruction with the real one
492 if (IsToCCR)
493 MIB->setDesc(get(M68k::MOV16cd));
494 else
495 // FIXME M68010 or later is required
496 MIB->setDesc(get(M68k::MOV16dc));
497
498 // Promote used register to the next class
499 auto &Opd = MIB->getOperand(1);
500 Opd.setReg(getRegisterInfo().getMatchingSuperReg(
501 Opd.getReg(), M68k::MxSubRegIndex8Lo, &M68k::DR16RegClass));
502
503 return true;
504}
505
507 const MCInstrDesc &Desc, bool IsRM) const {
508 int Reg = 0, Offset = 0, Base = 0;
509 auto XR32 = RI.getRegClass(M68k::XR32RegClassID);
510 auto DL = MIB->getDebugLoc();
511 auto MI = MIB.getInstr();
512 auto &MBB = *MIB->getParent();
513
514 if (IsRM) {
515 Reg = MIB->getOperand(0).getReg();
516 Offset = MIB->getOperand(1).getImm();
517 Base = MIB->getOperand(2).getReg();
518 } else {
519 Offset = MIB->getOperand(0).getImm();
520 Base = MIB->getOperand(1).getReg();
521 Reg = MIB->getOperand(2).getReg();
522 }
523
524 // If the register is not in XR32 then it is smaller than 32 bit, we
525 // implicitly promote it to 32
526 if (!XR32->contains(Reg)) {
527 Reg = RI.getMatchingMegaReg(Reg, XR32);
528 assert(Reg && "Has not meaningful MEGA register");
529 }
530
531 unsigned Mask = 1 << RI.getSpillRegisterOrder(Reg);
532 if (IsRM) {
533 BuildMI(MBB, MI, DL, Desc)
534 .addImm(Mask)
535 .addImm(Offset)
536 .addReg(Base)
538 .copyImplicitOps(*MIB);
539 } else {
540 BuildMI(MBB, MI, DL, Desc)
541 .addImm(Offset)
542 .addReg(Base)
543 .addImm(Mask)
545 .copyImplicitOps(*MIB);
546 }
547
548 MIB->eraseFromParent();
549
550 return true;
551}
552
553/// Expand a single-def pseudo instruction to a two-addr
554/// instruction with two undef reads of the register being defined.
555/// This is used for mapping:
556/// %d0 = SETCS_C32d
557/// to:
558/// %d0 = SUBX32dd %d0<undef>, %d0<undef>
559///
561 const MCInstrDesc &Desc) {
562 assert(Desc.getNumOperands() == 3 && "Expected two-addr instruction.");
563 Register Reg = MIB->getOperand(0).getReg();
564 MIB->setDesc(Desc);
565
566 // MachineInstr::addOperand() will insert explicit operands before any
567 // implicit operands.
569 // But we don't trust that.
570 assert(MIB->getOperand(1).getReg() == Reg &&
571 MIB->getOperand(2).getReg() == Reg && "Misplaced operand");
572 return true;
573}
574
576 MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI);
577 switch (MI.getOpcode()) {
578 case M68k::PUSH8d:
579 return ExpandPUSH_POP(MIB, get(M68k::MOV8ed), true);
580 case M68k::PUSH16d:
581 return ExpandPUSH_POP(MIB, get(M68k::MOV16er), true);
582 case M68k::PUSH32r:
583 return ExpandPUSH_POP(MIB, get(M68k::MOV32er), true);
584
585 case M68k::POP8d:
586 return ExpandPUSH_POP(MIB, get(M68k::MOV8do), false);
587 case M68k::POP16d:
588 return ExpandPUSH_POP(MIB, get(M68k::MOV16ro), false);
589 case M68k::POP32r:
590 return ExpandPUSH_POP(MIB, get(M68k::MOV32ro), false);
591
592 case M68k::SETCS_C8d:
593 return Expand2AddrUndef(MIB, get(M68k::SUBX8dd));
594 case M68k::SETCS_C16d:
595 return Expand2AddrUndef(MIB, get(M68k::SUBX16dd));
596 case M68k::SETCS_C32d:
597 return Expand2AddrUndef(MIB, get(M68k::SUBX32dd));
598 }
599 return false;
600}
601
603 const MachineOperand &MO) const {
604 assert(MO.isReg());
605
606 // Check whether this MO belongs to an instruction with addressing mode 'k',
607 // Refer to TargetInstrInfo.h for more information about this function.
608
609 const MachineInstr *MI = MO.getParent();
610 const unsigned NameIndices = M68kInstrNameIndices[MI->getOpcode()];
611 StringRef InstrName(&M68kInstrNameData[NameIndices]);
612 const unsigned OperandNo = MO.getOperandNo();
613
614 // If this machine operand is the 2nd operand, then check
615 // whether the instruction has destination addressing mode 'k'.
616 if (OperandNo == 1)
617 return Regex("[A-Z]+(8|16|32)k[a-z](_TC)?$").match(InstrName);
618
619 // If this machine operand is the last one, then check
620 // whether the instruction has source addressing mode 'k'.
621 if (OperandNo == MI->getNumExplicitOperands() - 1)
622 return Regex("[A-Z]+(8|16|32)[a-z]k(_TC)?$").match(InstrName);
623
624 return false;
625}
626
629 const DebugLoc &DL, MCRegister DstReg,
630 MCRegister SrcReg, bool KillSrc) const {
631 unsigned Opc = 0;
632
633 // First deal with the normal symmetric copies.
634 if (M68k::XR32RegClass.contains(DstReg, SrcReg))
635 Opc = M68k::MOV32rr;
636 else if (M68k::XR16RegClass.contains(DstReg, SrcReg))
637 Opc = M68k::MOV16rr;
638 else if (M68k::DR8RegClass.contains(DstReg, SrcReg))
639 Opc = M68k::MOV8dd;
640
641 if (Opc) {
642 BuildMI(MBB, MI, DL, get(Opc), DstReg)
643 .addReg(SrcReg, getKillRegState(KillSrc));
644 return;
645 }
646
647 // Now deal with asymmetrically sized copies. The cases that follow are upcast
648 // moves.
649 //
650 // NOTE
651 // These moves are not aware of type nature of these values and thus
652 // won't do any SExt or ZExt and upper bits will basically contain garbage.
654 if (M68k::DR8RegClass.contains(SrcReg)) {
655 if (M68k::XR16RegClass.contains(DstReg))
656 Opc = M68k::MOVXd16d8;
657 else if (M68k::XR32RegClass.contains(DstReg))
658 Opc = M68k::MOVXd32d8;
659 } else if (M68k::XR16RegClass.contains(SrcReg) &&
660 M68k::XR32RegClass.contains(DstReg))
661 Opc = M68k::MOVXd32d16;
662
663 if (Opc) {
664 BuildMI(MBB, MI, DL, get(Opc), DstReg)
665 .addReg(SrcReg, getKillRegState(KillSrc));
666 return;
667 }
668
669 bool FromCCR = SrcReg == M68k::CCR;
670 bool FromSR = SrcReg == M68k::SR;
671 bool ToCCR = DstReg == M68k::CCR;
672 bool ToSR = DstReg == M68k::SR;
673
674 if (FromCCR) {
675 assert(M68k::DR8RegClass.contains(DstReg) &&
676 "Need DR8 register to copy CCR");
677 Opc = M68k::MOV8dc;
678 } else if (ToCCR) {
679 assert(M68k::DR8RegClass.contains(SrcReg) &&
680 "Need DR8 register to copy CCR");
681 Opc = M68k::MOV8cd;
682 } else if (FromSR || ToSR)
683 llvm_unreachable("Cannot emit SR copy instruction");
684
685 if (Opc) {
686 BuildMI(MBB, MI, DL, get(Opc), DstReg)
687 .addReg(SrcReg, getKillRegState(KillSrc));
688 return;
689 }
690
691 LLVM_DEBUG(dbgs() << "Cannot copy " << RI.getName(SrcReg) << " to "
692 << RI.getName(DstReg) << '\n');
693 llvm_unreachable("Cannot emit physreg copy instruction");
694}
695
696namespace {
697unsigned getLoadStoreRegOpcode(unsigned Reg, const TargetRegisterClass *RC,
698 const TargetRegisterInfo *TRI,
699 const M68kSubtarget &STI, bool load) {
700 switch (TRI->getRegSizeInBits(*RC)) {
701 default:
702 llvm_unreachable("Unknown spill size");
703 case 8:
704 if (M68k::DR8RegClass.hasSubClassEq(RC))
705 return load ? M68k::MOV8dp : M68k::MOV8pd;
706 if (M68k::CCRCRegClass.hasSubClassEq(RC))
707 return load ? M68k::MOV16cp : M68k::MOV16pc;
708
709 llvm_unreachable("Unknown 1-byte regclass");
710 case 16:
711 assert(M68k::XR16RegClass.hasSubClassEq(RC) && "Unknown 2-byte regclass");
712 return load ? M68k::MOVM16mp_P : M68k::MOVM16pm_P;
713 case 32:
714 assert(M68k::XR32RegClass.hasSubClassEq(RC) && "Unknown 4-byte regclass");
715 return load ? M68k::MOVM32mp_P : M68k::MOVM32pm_P;
716 }
717}
718
719unsigned getStoreRegOpcode(unsigned SrcReg, const TargetRegisterClass *RC,
720 const TargetRegisterInfo *TRI,
721 const M68kSubtarget &STI) {
722 return getLoadStoreRegOpcode(SrcReg, RC, TRI, STI, false);
723}
724
725unsigned getLoadRegOpcode(unsigned DstReg, const TargetRegisterClass *RC,
726 const TargetRegisterInfo *TRI,
727 const M68kSubtarget &STI) {
728 return getLoadStoreRegOpcode(DstReg, RC, TRI, STI, true);
729}
730} // end anonymous namespace
731
733 unsigned SubIdx, unsigned &Size,
734 unsigned &Offset,
735 const MachineFunction &MF) const {
736 // The slot size must be the maximum size so we can easily use MOVEM.L
737 Size = 4;
738 Offset = 0;
739 return true;
740}
741
744 bool IsKill, int FrameIndex, const TargetRegisterClass *RC,
745 const TargetRegisterInfo *TRI, Register VReg) const {
746 const MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
747 assert(MFI.getObjectSize(FrameIndex) >= TRI->getSpillSize(*RC) &&
748 "Stack slot is too small to store");
749
750 unsigned Opc = getStoreRegOpcode(SrcReg, RC, TRI, Subtarget);
752 // (0,FrameIndex) <- $reg
753 M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIndex)
754 .addReg(SrcReg, getKillRegState(IsKill));
755}
756
759 Register DstReg, int FrameIndex,
760 const TargetRegisterClass *RC,
761 const TargetRegisterInfo *TRI,
762 Register VReg) const {
763 const MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
764 assert(MFI.getObjectSize(FrameIndex) >= TRI->getSpillSize(*RC) &&
765 "Stack slot is too small to load");
766
767 unsigned Opc = getLoadRegOpcode(DstReg, RC, TRI, Subtarget);
769 M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DstReg), FrameIndex);
770}
771
772/// Return a virtual register initialized with the global base register
773/// value. Output instructions required to initialize the register in the
774/// function entry block, if necessary.
775///
776/// TODO Move this function to M68kMachineFunctionInfo.
779 unsigned GlobalBaseReg = MxFI->getGlobalBaseReg();
780 if (GlobalBaseReg != 0)
781 return GlobalBaseReg;
782
783 // Create the register. The code to initialize it is inserted later,
784 // by the M68kGlobalBaseReg pass (below).
785 //
786 // NOTE
787 // Normally M68k uses A5 register as global base pointer but this will
788 // create unnecessary spill if we use less then 4 registers in code; since A5
789 // is callee-save anyway we could try to allocate caller-save first and if
790 // lucky get one, otherwise it does not really matter which callee-save to
791 // use.
792 MachineRegisterInfo &RegInfo = MF->getRegInfo();
793 GlobalBaseReg = RegInfo.createVirtualRegister(&M68k::AR32_NOSPRegClass);
794 MxFI->setGlobalBaseReg(GlobalBaseReg);
795 return GlobalBaseReg;
796}
797
798std::pair<unsigned, unsigned>
800 return std::make_pair(TF, 0u);
801}
802
805 using namespace M68kII;
806 static const std::pair<unsigned, const char *> TargetFlags[] = {
807 {MO_ABSOLUTE_ADDRESS, "m68k-absolute"},
808 {MO_PC_RELATIVE_ADDRESS, "m68k-pcrel"},
809 {MO_GOT, "m68k-got"},
810 {MO_GOTOFF, "m68k-gotoff"},
811 {MO_GOTPCREL, "m68k-gotpcrel"},
812 {MO_PLT, "m68k-plt"},
813 {MO_TLSGD, "m68k-tlsgd"},
814 {MO_TLSLD, "m68k-tlsld"},
815 {MO_TLSLDM, "m68k-tlsldm"},
816 {MO_TLSIE, "m68k-tlsie"},
817 {MO_TLSLE, "m68k-tlsle"}};
818 return ArrayRef(TargetFlags);
819}
820
821#undef DEBUG_TYPE
822#define DEBUG_TYPE "m68k-create-global-base-reg"
823
824#define PASS_NAME "M68k PIC Global Base Reg Initialization"
825
826namespace {
827/// This initializes the PIC global base register
828struct M68kGlobalBaseReg : public MachineFunctionPass {
829 static char ID;
830 M68kGlobalBaseReg() : MachineFunctionPass(ID) {}
831
832 bool runOnMachineFunction(MachineFunction &MF) override {
833 const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>();
835
836 unsigned GlobalBaseReg = MxFI->getGlobalBaseReg();
837
838 // If we didn't need a GlobalBaseReg, don't insert code.
839 if (GlobalBaseReg == 0)
840 return false;
841
842 // Insert the set of GlobalBaseReg into the first MBB of the function
843 MachineBasicBlock &FirstMBB = MF.front();
845 DebugLoc DL = FirstMBB.findDebugLoc(MBBI);
846 const M68kInstrInfo *TII = STI.getInstrInfo();
847
848 // Generate lea (__GLOBAL_OFFSET_TABLE_,%PC), %A5
849 BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::LEA32q), GlobalBaseReg)
850 .addExternalSymbol("_GLOBAL_OFFSET_TABLE_", M68kII::MO_GOTPCREL);
851
852 return true;
853 }
854
855 void getAnalysisUsage(AnalysisUsage &AU) const override {
856 AU.setPreservesCFG();
858 }
859};
860char M68kGlobalBaseReg::ID = 0;
861} // namespace
862
863INITIALIZE_PASS(M68kGlobalBaseReg, DEBUG_TYPE, PASS_NAME, false, false)
864
866 return new M68kGlobalBaseReg();
867}
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
BlockVerifier::State From
#define LLVM_DEBUG(X)
Definition: Debug.h:101
uint64_t Size
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
This file exposes functions that may be used with BuildMI from the MachineInstrBuilder....
static M68k::CondCode getCondFromBranchOpc(unsigned BrOpc)
static bool Expand2AddrUndef(MachineInstrBuilder &MIB, const MCInstrDesc &Desc)
Expand a single-def pseudo instruction to a two-addr instruction with two undef reads of the register...
This file contains the M68k implementation of the TargetInstrInfo class.
This file contains the declarations for the code emitter which are useful outside of the emitter itse...
This file declares the M68k specific subclass of MachineFunctionInfo.
This file declares the M68k specific subclass of TargetMachine.
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC)
#define PASS_NAME
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:470
static unsigned getStoreRegOpcode(Register SrcReg, const TargetRegisterClass *RC, bool IsStackAligned, const X86Subtarget &STI)
static unsigned getLoadRegOpcode(Register DestReg, const TargetRegisterClass *RC, bool IsStackAligned, const X86Subtarget &STI)
static unsigned getLoadStoreRegOpcode(Register Reg, const TargetRegisterClass *RC, bool IsStackAligned, const X86Subtarget &STI, bool Load)
static unsigned GetCondBranchFromCond(XCore::CondCode CC)
GetCondBranchFromCond - Return the Branch instruction opcode that matches the cc.
Represent the analysis usage information of a pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:269
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
A debug info location.
Definition: DebugLoc.h:33
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:311
unsigned getGlobalBaseReg(MachineFunction *MF) const
Return a virtual register initialized with the global base register value.
const M68kSubtarget & Subtarget
bool ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned, MVT MVTDst, MVT MVTSrc) const
Move from register and extend.
const M68kRegisterInfo & getRegisterInfo() const
TargetInstrInfo is a superset of MRegister info.
const M68kRegisterInfo RI
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
bool expandPostRAPseudo(MachineInstr &MI) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
bool AnalyzeBranchImpl(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const
bool isPCRelRegisterOperandLegal(const MachineOperand &MO) const override
bool ExpandMOVX_RR(MachineInstrBuilder &MIB, MVT MVTDst, MVT MVTSrc) const
Move across register classes without extension.
bool ExpandMOVEM(MachineInstrBuilder &MIB, const MCInstrDesc &Desc, bool IsRM) const
Expand all MOVEM pseudos into real MOVEMs.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
bool ExpandPUSH_POP(MachineInstrBuilder &MIB, const MCInstrDesc &Desc, bool IsPush) const
Push/Pop to/from stack.
M68kInstrInfo(const M68kSubtarget &STI)
void AddZExt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned Reg, MVT From, MVT To) const
Add appropriate ZExt nodes.
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const override
bool ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const
Moves to/from CCR.
bool ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned, const MCInstrDesc &Desc, MVT MVTDst, MVT MVTSrc) const
Move from memory and extend.
bool getStackSlotRange(const TargetRegisterClass *RC, unsigned SubIdx, unsigned &Size, unsigned &Offset, const MachineFunction &MF) const override
void AddSExt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned Reg, MVT From, MVT To) const
Add appropriate SExt nodes.
unsigned getMatchingMegaReg(unsigned Reg, const TargetRegisterClass *RC) const
Return a mega-register of the specified register Reg so its sub-register of index SubIdx is Reg,...
int getSpillRegisterOrder(unsigned Reg) const
Return spill order index of a register, if there is none then trap.
unsigned getStackRegister() const
const M68kInstrInfo * getInstrInfo() const override
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
Machine Value Type.
reverse_iterator rend()
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
void push_back(MachineInstr *MI)
DebugLoc rfindDebugLoc(reverse_instr_iterator MBBI)
Has exact same behavior as findDebugLoc (it also searches towards the end of this MBB) except that th...
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
reverse_iterator rbegin()
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
Definition: MachineInstr.h:68
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:326
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:472
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:553
void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
MachineOperand class - Representation of each machine instruction operand.
unsigned getOperandNo() const
Returns the index of this operand in the instruction that it belongs to.
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setReg(Register Reg)
Change the register this operand corresponds to.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool match(StringRef String, SmallVectorImpl< StringRef > *Matches=nullptr, std::string *Error=nullptr) const
matches - Match the regex against a given String.
Definition: Regex.cpp:83
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ MO_GOTPCREL
On a symbol operand this indicates that the immediate is offset to the GOT entry for the symbol name ...
Definition: M68kBaseInfo.h:153
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
static M68k::CondCode GetCondFromBranchOpc(unsigned Opcode)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Undef
Value of the register doesn't matter.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:440
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
Definition: ScopeExit.h:59
FunctionPass * createM68kGlobalBaseRegPass()
This pass initializes a global base register for PIC on M68k.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
@ And
Bitwise or logical AND of integers.
unsigned getKillRegState(bool B)
Description of the encoding of one expression Op.