LLVM 19.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
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.
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
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
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
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
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
494 I++;
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
510 const MCInstrDesc &Desc, bool IsPush) const {
512 I++;
514 MachineOperand MO = MIB->getOperand(0);
515 DebugLoc DL = MIB->getDebugLoc();
516 if (IsPush)
518 else
520
521 MIB->eraseFromParent();
522 return true;
523}
524
525bool 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
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)
574 .copyImplicitOps(*MIB);
575 } else {
576 BuildMI(MBB, MI, DL, Desc)
577 .addImm(Offset)
578 .addReg(Base)
579 .addImm(Mask)
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///
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.
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
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
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
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.
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
732namespace {
733unsigned 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
755unsigned getStoreRegOpcode(unsigned SrcReg, const TargetRegisterClass *RC,
756 const TargetRegisterInfo *TRI,
757 const M68kSubtarget &STI) {
758 return getLoadStoreRegOpcode(SrcReg, RC, TRI, STI, false);
759}
760
761unsigned 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
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
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);
789 // (0,FrameIndex) <- $reg
790 M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIndex)
791 .addReg(SrcReg, getKillRegState(IsKill));
792}
793
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);
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.
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
836std::pair<unsigned, unsigned>
838 return std::make_pair(TF, 0u);
839}
840
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
864namespace {
865/// This initializes the PIC global base register
866struct M68kGlobalBaseReg : public MachineFunctionPass {
867 static char ID;
868 M68kGlobalBaseReg() : MachineFunctionPass(ID) {}
869
870 bool runOnMachineFunction(MachineFunction &MF) override {
871 const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>();
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();
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
893 void getAnalysisUsage(AnalysisUsage &AU) const override {
894 AU.setPreservesCFG();
896 }
897};
898char M68kGlobalBaseReg::ID = 0;
899} // namespace
900
901INITIALIZE_PASS(M68kGlobalBaseReg, DEBUG_TYPE, PASS_NAME, false, false)
902
904 return new M68kGlobalBaseReg();
905}
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
AMDGPU Mark last scratch load
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:469
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 ExpandMOVI(MachineInstrBuilder &MIB, MVT MVTSize) const
Move immediate to register.
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:69
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:341
void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:487
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:568
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:586
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:456
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.