LLVM 23.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"
31#include "llvm/Support/Regex.h"
32
33#include <functional>
34
35using namespace llvm;
36
37#define DEBUG_TYPE "M68k-instr-info"
38
39#define GET_INSTRINFO_CTOR_DTOR
40#include "M68kGenInstrInfo.inc"
41
42// Pin the vtable to this file.
43void M68kInstrInfo::anchor() {}
44
46 : M68kGenInstrInfo(STI, RI, M68k::ADJCALLSTACKDOWN, M68k::ADJCALLSTACKUP, 0,
47 M68k::RET),
48 Subtarget(STI), RI(STI) {}
49
50static M68k::CondCode getCondFromBranchOpc(unsigned BrOpc) {
51 switch (BrOpc) {
52 default:
53 return M68k::COND_INVALID;
54 case M68k::Beq8:
55 return M68k::COND_EQ;
56 case M68k::Bne8:
57 return M68k::COND_NE;
58 case M68k::Blt8:
59 return M68k::COND_LT;
60 case M68k::Ble8:
61 return M68k::COND_LE;
62 case M68k::Bgt8:
63 return M68k::COND_GT;
64 case M68k::Bge8:
65 return M68k::COND_GE;
66 case M68k::Bcs8:
67 return M68k::COND_CS;
68 case M68k::Bls8:
69 return M68k::COND_LS;
70 case M68k::Bhi8:
71 return M68k::COND_HI;
72 case M68k::Bcc8:
73 return M68k::COND_CC;
74 case M68k::Bmi8:
75 return M68k::COND_MI;
76 case M68k::Bpl8:
77 return M68k::COND_PL;
78 case M68k::Bvs8:
79 return M68k::COND_VS;
80 case M68k::Bvc8:
81 return M68k::COND_VC;
82 }
83}
84
89 bool AllowModify) const {
90
91 auto UncondBranch =
92 std::pair<MachineBasicBlock::reverse_iterator, MachineBasicBlock *>{
93 MBB.rend(), nullptr};
94
95 // Erase any instructions if allowed at the end of the scope.
96 std::vector<std::reference_wrapper<llvm::MachineInstr>> EraseList;
97 llvm::scope_exit FinalizeOnReturn([&EraseList] {
98 for (auto &Ref : EraseList)
99 Ref.get().eraseFromParent();
100 });
101
102 // Start from the bottom of the block and work up, examining the
103 // terminator instructions.
104 for (auto iter = MBB.rbegin(); iter != MBB.rend(); iter = std::next(iter)) {
105
106 unsigned Opcode = iter->getOpcode();
107
108 if (iter->isDebugInstr())
109 continue;
110
111 // Working from the bottom, when we see a non-terminator instruction, we're
112 // done.
113 if (!isUnpredicatedTerminator(*iter))
114 break;
115
116 // A terminator that isn't a branch can't easily be handled by this
117 // analysis.
118 if (!iter->isBranch())
119 return true;
120
121 // Handle unconditional branches.
122 if (Opcode == M68k::BRA8 || Opcode == M68k::BRA16) {
123 if (!iter->getOperand(0).isMBB())
124 return true;
125 UncondBranch = {iter, iter->getOperand(0).getMBB()};
126
127 // TBB is used to indicate the unconditional destination.
128 TBB = UncondBranch.second;
129
130 if (!AllowModify)
131 continue;
132
133 // If the block has any instructions after a JMP, erase them.
134 EraseList.insert(EraseList.begin(), MBB.rbegin(), iter);
135
136 Cond.clear();
137 FBB = nullptr;
138
139 // Erase the JMP if it's equivalent to a fall-through.
140 if (MBB.isLayoutSuccessor(UncondBranch.second)) {
141 TBB = nullptr;
142 EraseList.push_back(*iter);
143 UncondBranch = {MBB.rend(), nullptr};
144 }
145
146 continue;
147 }
148
149 // Handle conditional branches.
150 auto BranchCode = M68k::GetCondFromBranchOpc(Opcode);
151
152 // Can't handle indirect branch.
153 if (BranchCode == M68k::COND_INVALID)
154 return true;
155
156 // In practice we should never have an undef CCR operand, if we do
157 // abort here as we are not prepared to preserve the flag.
158 // ??? Is this required?
159 // if (iter->getOperand(1).isUndef())
160 // return true;
161
162 // Working from the bottom, handle the first conditional branch.
163 if (Cond.empty()) {
164 if (!iter->getOperand(0).isMBB())
165 return true;
166 MachineBasicBlock *CondBranchTarget = iter->getOperand(0).getMBB();
167
168 // If we see something like this:
169 //
170 // bcc l1
171 // bra l2
172 // ...
173 // l1:
174 // ...
175 // l2:
176 if (UncondBranch.first != MBB.rend()) {
177
178 assert(std::next(UncondBranch.first) == iter && "Wrong block layout.");
179
180 // And we are allowed to modify the block and the target block of the
181 // conditional branch is the direct successor of this block:
182 //
183 // bcc l1
184 // bra l2
185 // l1:
186 // ...
187 // l2:
188 //
189 // we change it to this if allowed:
190 //
191 // bncc l2
192 // l1:
193 // ...
194 // l2:
195 //
196 // Which is a bit more efficient.
197 if (AllowModify && MBB.isLayoutSuccessor(CondBranchTarget)) {
198
199 BranchCode = GetOppositeBranchCondition(BranchCode);
200 unsigned BNCC = GetCondBranchFromCond(BranchCode);
201
202 BuildMI(MBB, *UncondBranch.first, MBB.rfindDebugLoc(iter), get(BNCC))
203 .addMBB(UncondBranch.second);
204
205 EraseList.push_back(*iter);
206 EraseList.push_back(*UncondBranch.first);
207
208 TBB = UncondBranch.second;
209 FBB = nullptr;
210 Cond.push_back(MachineOperand::CreateImm(BranchCode));
211
212 // Otherwise preserve TBB, FBB and Cond as requested
213 } else {
214 TBB = CondBranchTarget;
215 FBB = UncondBranch.second;
216 Cond.push_back(MachineOperand::CreateImm(BranchCode));
217 }
218
219 UncondBranch = {MBB.rend(), nullptr};
220 continue;
221 }
222
223 TBB = CondBranchTarget;
224 FBB = nullptr;
225 Cond.push_back(MachineOperand::CreateImm(BranchCode));
226
227 continue;
228 }
229
230 // Handle subsequent conditional branches. Only handle the case where all
231 // conditional branches branch to the same destination and their condition
232 // opcodes fit one of the special multi-branch idioms.
233 assert(Cond.size() == 1);
234 assert(TBB);
235
236 // If the conditions are the same, we can leave them alone.
237 auto OldBranchCode = static_cast<M68k::CondCode>(Cond[0].getImm());
238 if (!iter->getOperand(0).isMBB())
239 return true;
240 auto NewTBB = iter->getOperand(0).getMBB();
241 if (OldBranchCode == BranchCode && TBB == NewTBB)
242 continue;
243
244 // If they differ we cannot do much here.
245 return true;
246 }
247
248 return false;
249}
250
253 MachineBasicBlock *&FBB,
255 bool AllowModify) const {
256 return AnalyzeBranchImpl(MBB, TBB, FBB, Cond, AllowModify);
257}
258
260 int *BytesRemoved) const {
261 assert(!BytesRemoved && "code size not handled");
262
264 unsigned Count = 0;
265
266 while (I != MBB.begin()) {
267 --I;
268 if (I->isDebugValue())
269 continue;
270 if (I->getOpcode() != M68k::BRA8 &&
272 break;
273 // Remove the branch.
274 I->eraseFromParent();
275 I = MBB.end();
276 ++Count;
277 }
278
279 return Count;
280}
281
284 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
285 // Shouldn't be a fall through.
286 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
287 assert((Cond.size() == 1 || Cond.size() == 0) &&
288 "M68k branch conditions have one component!");
289 assert(!BytesAdded && "code size not handled");
290
291 if (Cond.empty()) {
292 // Unconditional branch?
293 assert(!FBB && "Unconditional branch with multiple successors!");
294 BuildMI(&MBB, DL, get(M68k::BRA8)).addMBB(TBB);
295 return 1;
296 }
297
298 // If FBB is null, it is implied to be a fall-through block.
299 bool FallThru = FBB == nullptr;
300
301 // Conditional branch.
302 unsigned Count = 0;
304 unsigned Opc = GetCondBranchFromCond(CC);
305 BuildMI(&MBB, DL, get(Opc)).addMBB(TBB);
306 ++Count;
307 if (!FallThru) {
308 // Two-way Conditional branch. Insert the second branch.
309 BuildMI(&MBB, DL, get(M68k::BRA8)).addMBB(FBB);
310 ++Count;
311 }
312 return Count;
313}
314
317 unsigned Reg, MVT From, MVT To) const {
318 if (From == MVT::i8) {
319 unsigned R = Reg;
320 // EXT16 requires i16 register
321 if (To == MVT::i32) {
322 R = RI.getSubReg(Reg, M68k::MxSubRegIndex16Lo);
323 assert(R && "No viable SUB register available");
324 }
325 BuildMI(MBB, I, DL, get(M68k::EXT16), R).addReg(R);
326 }
327
328 if (To == MVT::i32)
329 BuildMI(MBB, I, DL, get(M68k::EXT32), Reg).addReg(Reg);
330}
331
334 unsigned Reg, MVT From, MVT To) const {
335
336 unsigned Mask, And;
337 if (From == MVT::i8)
338 Mask = 0xFF;
339 else
340 Mask = 0xFFFF;
341
342 if (To == MVT::i16)
343 And = M68k::AND16di;
344 else // i32
345 And = M68k::AND32di;
346
347 // TODO use xor r,r to decrease size
348 BuildMI(MBB, I, DL, get(And), Reg).addReg(Reg).addImm(Mask);
349}
350
351// Convert MOVI to the appropriate instruction (sequence) for setting
352// the register to an immediate value.
354 Register Reg = MIB->getOperand(0).getReg();
355 int64_t Imm = MIB->getOperand(1).getImm();
356 bool IsAddressReg = false;
357
358 const auto *DR32 = RI.getRegClass(M68k::DR32RegClassID);
359 const auto *AR32 = RI.getRegClass(M68k::AR32RegClassID);
360 const auto *AR16 = RI.getRegClass(M68k::AR16RegClassID);
361
362 if (AR16->contains(Reg) || AR32->contains(Reg))
363 IsAddressReg = true;
364
365 // We need to assign to the full register to make IV happy
366 Register SReg =
367 MVTSize == MVT::i32
368 ? Reg
369 : Register(RI.getMatchingMegaReg(Reg, IsAddressReg ? AR32 : DR32));
370 assert(SReg && "No viable MEGA register available");
371
372 LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to ");
373
374 // Sign extention doesn't matter if we only use the bottom 8 bits
375 if (MVTSize == MVT::i8 || (!IsAddressReg && Imm >= -128 && Imm <= 127)) {
376 LLVM_DEBUG(dbgs() << "MOVEQ\n");
377
378 MIB->setDesc(get(M68k::MOVQ));
379 MIB->getOperand(0).setReg(SReg);
380
381 // Counter the effects of sign-extension with a bitwise not.
382 // This is only faster and smaller for 32 bit values.
383 } else if (DR32->contains(Reg) && isUInt<8>(Imm)) {
384 LLVM_DEBUG(dbgs() << "MOVEQ and NOT\n");
385
387 DebugLoc DL = MIB->getDebugLoc();
388
389 unsigned SubReg = RI.getSubReg(Reg, M68k::MxSubRegIndex8Lo);
390 assert(SubReg && "No viable SUB register available");
391
392 BuildMI(MBB, MIB.getInstr(), DL, get(M68k::MOVQ), SReg).addImm(~Imm & 0xFF);
393 BuildMI(MBB, MIB.getInstr(), DL, get(M68k::NOT8d), SubReg).addReg(SubReg);
394
395 MIB->removeFromParent();
396
397 // Special case for setting address register to NULL (0)
398 } else if (IsAddressReg && Imm == 0) {
399 LLVM_DEBUG(dbgs() << "SUBA\n");
400
402 DebugLoc DL = MIB->getDebugLoc();
403
404 BuildMI(MBB, MIB.getInstr(), DL, get(M68k::SUB32ar), SReg)
405 .addReg(SReg, RegState::Undef)
406 .addReg(SReg, RegState::Undef);
407
408 MIB->removeFromParent();
409
410 // movea.w implicitly sign extends to the full register width,
411 // so exploit that if the immediate fits in the correct range.
412 //
413 // TODO: use lea imm.w, %an for further constants when 16-bit
414 // absolute addressing is implemented.
415 } else if (AR32->contains(Reg) && isUInt<16>(Imm)) {
416 LLVM_DEBUG(dbgs() << "MOVEA w/ implicit extend\n");
417
418 unsigned SubReg = RI.getSubReg(Reg, M68k::MxSubRegIndex16Lo);
419 assert(SubReg && "No viable SUB register available");
420
421 MIB->setDesc(get(M68k::MOV16ai));
422 MIB->getOperand(0).setReg(SubReg);
423
424 // Fall back to a move with immediate
425 } else {
426 LLVM_DEBUG(dbgs() << "MOVE\n");
427 MIB->setDesc(get(MVTSize == MVT::i16 ? M68k::MOV16ri : M68k::MOV32ri));
428 }
429
430 return true;
431}
432
434 MVT MVTSrc) const {
435 unsigned Move = MVTDst == MVT::i16 ? M68k::MOV16rr : M68k::MOV32rr;
436 Register Dst = MIB->getOperand(0).getReg();
437 Register Src = MIB->getOperand(1).getReg();
438
439 assert(Dst != Src && "You cannot use the same Regs with MOVX_RR");
440
441 const auto &TRI = getRegisterInfo();
442
443 const auto *RCDst = TRI.getMaximalPhysRegClass(Dst, MVTDst);
444 const auto *RCSrc = TRI.getMaximalPhysRegClass(Src, MVTSrc);
445
446 assert(RCDst && RCSrc && "Wrong use of MOVX_RR");
447 assert(RCDst != RCSrc && "You cannot use the same Reg Classes with MOVX_RR");
448 (void)RCSrc;
449
450 // We need to find the super source register that matches the size of Dst
451 unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst);
452 assert(SSrc && "No viable MEGA register available");
453
454 // If it happens to that super source register is the destination register
455 // we do nothing
456 if (Dst == SSrc) {
457 LLVM_DEBUG(dbgs() << "Remove " << *MIB.getInstr() << '\n');
458 MIB->eraseFromParent();
459 } else { // otherwise we need to MOV
460 LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to MOV\n");
461 MIB->setDesc(get(Move));
462 MIB->getOperand(1).setReg(SSrc);
463 }
464
465 return true;
466}
467
468/// Expand SExt MOVE pseudos into a MOV and a EXT if the operands are two
469/// different registers or just EXT if it is the same register
471 MVT MVTDst, MVT MVTSrc) const {
472 LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to ");
473
474 unsigned Move;
475
476 if (MVTDst == MVT::i16)
477 Move = M68k::MOV16rr;
478 else // i32
479 Move = M68k::MOV32rr;
480
481 Register Dst = MIB->getOperand(0).getReg();
482 Register Src = MIB->getOperand(1).getReg();
483
484 assert(Dst != Src && "You cannot use the same Regs with MOVSX_RR");
485
486 const auto &TRI = getRegisterInfo();
487
488 const auto *RCDst = TRI.getMaximalPhysRegClass(Dst, MVTDst);
489 const auto *RCSrc = TRI.getMaximalPhysRegClass(Src, MVTSrc);
490
491 assert(RCDst && RCSrc && "Wrong use of MOVSX_RR");
492 assert(RCDst != RCSrc && "You cannot use the same Reg Classes with MOVSX_RR");
493 (void)RCSrc;
494
495 // We need to find the super source register that matches the size of Dst
496 unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst);
497 assert(SSrc && "No viable MEGA register available");
498
500 DebugLoc DL = MIB->getDebugLoc();
501
502 if (Dst != SSrc) {
503 LLVM_DEBUG(dbgs() << "Move and " << '\n');
504 BuildMI(MBB, MIB.getInstr(), DL, get(Move), Dst).addReg(SSrc);
505 }
506
507 if (IsSigned) {
508 LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');
509 AddSExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
510 } else {
511 LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
512 AddZExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);
513 }
514
515 MIB->eraseFromParent();
516
517 return true;
518}
519
521 const MCInstrDesc &Desc, MVT MVTDst,
522 MVT MVTSrc) const {
523 LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to LOAD and ");
524
525 Register Dst = MIB->getOperand(0).getReg();
526
527 // We need the subreg of Dst to make instruction verifier happy because the
528 // real machine instruction consumes and produces values of the same size and
529 // the registers the will be used here fall into different classes and this
530 // makes IV cry. We could use a bigger operation, but this will put some
531 // pressure on cache and memory, so no.
532 unsigned SubDst =
533 RI.getSubReg(Dst, MVTSrc == MVT::i8 ? M68k::MxSubRegIndex8Lo
534 : M68k::MxSubRegIndex16Lo);
535 assert(SubDst && "No viable SUB register available");
536
537 // Make this a plain move
538 MIB->setDesc(Desc);
539 MIB->getOperand(0).setReg(SubDst);
540
542 I++;
544 DebugLoc DL = MIB->getDebugLoc();
545
546 if (IsSigned) {
547 LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');
548 AddSExt(MBB, I, DL, Dst, MVTSrc, MVTDst);
549 } else {
550 LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');
551 AddZExt(MBB, I, DL, Dst, MVTSrc, MVTDst);
552 }
553
554 return true;
555}
556
558 const MCInstrDesc &Desc, bool IsPush) const {
560 I++;
562 MachineOperand MO = MIB->getOperand(0);
563 DebugLoc DL = MIB->getDebugLoc();
564 if (IsPush)
565 BuildMI(MBB, I, DL, Desc).addReg(RI.getStackRegister()).add(MO);
566 else
567 BuildMI(MBB, I, DL, Desc, MO.getReg()).addReg(RI.getStackRegister());
568
569 MIB->eraseFromParent();
570 return true;
571}
572
574 const MCInstrDesc &Desc, bool IsRM) const {
575 int Reg = 0, Offset = 0, Base = 0;
576 auto DL = MIB->getDebugLoc();
577 auto MI = MIB.getInstr();
578 auto &MBB = *MIB->getParent();
579
580 if (IsRM) {
581 Reg = MIB->getOperand(0).getReg();
582 Offset = MIB->getOperand(1).getImm();
583 Base = MIB->getOperand(2).getReg();
584 } else {
585 Offset = MIB->getOperand(0).getImm();
586 Base = MIB->getOperand(1).getReg();
587 Reg = MIB->getOperand(2).getReg();
588 }
589
590 unsigned Mask = 1 << RI.getSpillRegisterOrder(Reg);
591 if (IsRM) {
592 BuildMI(MBB, MI, DL, Desc)
593 .addImm(Mask)
594 .addImm(Offset)
595 .addReg(Base)
597 .copyImplicitOps(*MIB);
598 } else {
599 BuildMI(MBB, MI, DL, Desc)
600 .addImm(Offset)
601 .addReg(Base)
602 .addImm(Mask)
604 .copyImplicitOps(*MIB);
605 }
606
607 MIB->eraseFromParent();
608
609 return true;
610}
611
612/// Expand a single-def pseudo instruction to a two-addr
613/// instruction with two undef reads of the register being defined.
614/// This is used for mapping:
615/// %d0 = SETCS_C32d
616/// to:
617/// %d0 = SUBX32dd %d0<undef>, %d0<undef>
618///
620 const MCInstrDesc &Desc) {
621 assert(Desc.getNumOperands() == 3 && "Expected two-addr instruction.");
622 Register Reg = MIB->getOperand(0).getReg();
623 MIB->setDesc(Desc);
624
625 // MachineInstr::addOperand() will insert explicit operands before any
626 // implicit operands.
628 // But we don't trust that.
629 assert(MIB->getOperand(1).getReg() == Reg &&
630 MIB->getOperand(2).getReg() == Reg && "Misplaced operand");
631 return true;
632}
633
635 MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI);
636 switch (MI.getOpcode()) {
637 case M68k::PUSH8d:
638 return ExpandPUSH_POP(MIB, get(M68k::MOV8ed), true);
639 case M68k::PUSH16d:
640 return ExpandPUSH_POP(MIB, get(M68k::MOV16er), true);
641 case M68k::PUSH32r:
642 return ExpandPUSH_POP(MIB, get(M68k::MOV32er), true);
643
644 case M68k::POP8d:
645 return ExpandPUSH_POP(MIB, get(M68k::MOV8do), false);
646 case M68k::POP16d:
647 return ExpandPUSH_POP(MIB, get(M68k::MOV16ro), false);
648 case M68k::POP32r:
649 return ExpandPUSH_POP(MIB, get(M68k::MOV32ro), false);
650
651 case M68k::SETCS_C8d:
652 return Expand2AddrUndef(MIB, get(M68k::SUBX8dd));
653 case M68k::SETCS_C16d:
654 return Expand2AddrUndef(MIB, get(M68k::SUBX16dd));
655 case M68k::SETCS_C32d:
656 return Expand2AddrUndef(MIB, get(M68k::SUBX32dd));
657 }
658 return false;
659}
660
662 const MachineOperand &MO) const {
663 assert(MO.isReg());
664
665 // Check whether this MO belongs to an instruction with addressing mode 'k',
666 // Refer to TargetInstrInfo.h for more information about this function.
667
668 const MachineInstr *MI = MO.getParent();
669 const unsigned NameIndices = M68kInstrNameIndices[MI->getOpcode()];
670 StringRef InstrName(&M68kInstrNameData[NameIndices]);
671 const unsigned OperandNo = MO.getOperandNo();
672
673 // If this machine operand is the 2nd operand, then check
674 // whether the instruction has destination addressing mode 'k'.
675 if (OperandNo == 1)
676 return Regex("[A-Z]+(8|16|32)k[a-z](_TC)?$").match(InstrName);
677
678 // If this machine operand is the last one, then check
679 // whether the instruction has source addressing mode 'k'.
680 if (OperandNo == MI->getNumExplicitOperands() - 1)
681 return Regex("[A-Z]+(8|16|32)[a-z]k(_TC)?$").match(InstrName);
682
683 return false;
684}
685
688 const DebugLoc &DL, Register DstReg,
689 Register SrcReg, bool KillSrc,
690 bool RenamableDest, bool RenamableSrc) const {
691 const auto &Subtarget = MBB.getParent()->getSubtarget<M68kSubtarget>();
692 unsigned Opc = 0;
693
694 // First deal with the normal symmetric copies.
695 if (M68k::XR32RegClass.contains(DstReg, SrcReg))
696 Opc = M68k::MOV32rr;
697 else if (M68k::XR16RegClass.contains(DstReg, SrcReg))
698 Opc = M68k::MOV16rr;
699 else if (M68k::DR8RegClass.contains(DstReg, SrcReg))
700 Opc = M68k::MOV8dd;
701
702 if (Opc) {
703 BuildMI(MBB, MI, DL, get(Opc), DstReg)
704 .addReg(SrcReg, getKillRegState(KillSrc));
705 return;
706 }
707
708 // Now deal with asymmetrically sized copies. The cases that follow are upcast
709 // moves.
710 //
711 // NOTE
712 // These moves are not aware of type nature of these values and thus
713 // won't do any SExt or ZExt and upper bits will basically contain garbage.
714 MachineInstrBuilder MIB(*MBB.getParent(), MI);
715 if (M68k::DR8RegClass.contains(SrcReg)) {
716 if (M68k::XR16RegClass.contains(DstReg))
717 Opc = M68k::MOVXd16d8;
718 else if (M68k::XR32RegClass.contains(DstReg))
719 Opc = M68k::MOVXd32d8;
720 } else if (M68k::XR16RegClass.contains(SrcReg) &&
721 M68k::XR32RegClass.contains(DstReg))
722 Opc = M68k::MOVXd32d16;
723
724 if (Opc) {
725 BuildMI(MBB, MI, DL, get(Opc), DstReg)
726 .addReg(SrcReg, getKillRegState(KillSrc));
727 return;
728 }
729
730 bool FromCCR = SrcReg == M68k::CCR;
731 bool FromSR = SrcReg == M68k::SR;
732 bool ToCCR = DstReg == M68k::CCR;
733 bool ToSR = DstReg == M68k::SR;
734
735 if (FromCCR) {
736 Opc = M68k::MOV16dc;
737 if (!Subtarget.atLeastM68010()) {
738 Opc = M68k::MOV16ds;
739 SrcReg = M68k::SR;
740 }
741 if (!M68k::DR8RegClass.contains(DstReg) &&
742 !M68k::DR16RegClass.contains(DstReg) &&
743 !M68k::DR32RegClass.contains(DstReg)) {
744 LLVM_DEBUG(dbgs() << "Cannot copy CCR to " << RI.getName(DstReg) << '\n');
745 llvm_unreachable("Invalid register for MOVE from CCR");
746 }
747 } else if (ToCCR) {
748 Opc = M68k::MOV16cd;
749 if (M68k::DR8RegClass.contains(SrcReg)) {
750 // Promote used register to the next class
751 SrcReg = getRegisterInfo().getMatchingSuperReg(
752 SrcReg, M68k::MxSubRegIndex8Lo, &M68k::DR16RegClass);
753 } else if (!M68k::DR16RegClass.contains(SrcReg) &&
754 !M68k::DR32RegClass.contains(SrcReg)) {
755 LLVM_DEBUG(dbgs() << "Cannot copy " << RI.getName(SrcReg) << " to CCR\n");
756 llvm_unreachable("Invalid register for MOVE to CCR");
757 }
758 } else if (FromSR || ToSR) {
759 llvm_unreachable("Cannot emit SR copy instruction");
760 }
761
762 if (Opc) {
763 BuildMI(MBB, MI, DL, get(Opc), DstReg)
764 .addReg(SrcReg, getKillRegState(KillSrc));
765 return;
766 }
767
768 LLVM_DEBUG(dbgs() << "Cannot copy " << RI.getName(SrcReg) << " to "
769 << RI.getName(DstReg) << '\n');
770 llvm_unreachable("Cannot emit physreg copy instruction");
771}
772
773namespace {
774unsigned getLoadStoreRegOpcode(unsigned Reg, const TargetRegisterClass *RC,
775 const TargetRegisterInfo *TRI,
776 const M68kSubtarget &STI, bool load) {
777 switch (TRI->getSpillSize(*RC)) {
778 default:
780 dbgs() << "Cannot determine appropriate opcode for load/store to/from "
781 << TRI->getName(Reg) << " of class " << TRI->getRegClassName(RC)
782 << " with spill size " << TRI->getSpillSize(*RC) << '\n');
783 llvm_unreachable("Unknown spill size");
784 case 2:
785 if (M68k::XR16RegClass.hasSubClassEq(RC))
786 return load ? M68k::MOVM16mp_P : M68k::MOVM16pm_P;
787 if (M68k::DR8RegClass.hasSubClassEq(RC))
788 return load ? M68k::MOVM16mp_P : M68k::MOVM16pm_P;
789 if (M68k::CCRCRegClass.hasSubClassEq(RC))
790 return load ? M68k::MOVM16mp_P : M68k::MOVM16pm_P;
791 llvm_unreachable("Unknown 2-byte regclass");
792 case 4:
793 if (M68k::XR32RegClass.hasSubClassEq(RC))
794 return load ? M68k::MOVM32mp_P : M68k::MOVM32pm_P;
795 llvm_unreachable("Unknown 4-byte regclass");
796 }
797}
798
799unsigned getStoreRegOpcode(unsigned SrcReg, const TargetRegisterClass *RC,
800 const TargetRegisterInfo *TRI,
801 const M68kSubtarget &STI) {
802 return getLoadStoreRegOpcode(SrcReg, RC, TRI, STI, false);
803}
804
805unsigned getLoadRegOpcode(unsigned DstReg, const TargetRegisterClass *RC,
806 const TargetRegisterInfo *TRI,
807 const M68kSubtarget &STI) {
808 return getLoadStoreRegOpcode(DstReg, RC, TRI, STI, true);
809}
810} // end anonymous namespace
811
813 unsigned SubIdx, unsigned &Size,
814 unsigned &Offset,
815 const MachineFunction &MF) const {
816 // The slot size must be the maximum size so we can easily use MOVEM.L
817 Size = 4;
818 Offset = 0;
819 return true;
820}
821
824 bool IsKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg,
825 MachineInstr::MIFlag Flags) const {
826 const MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
827 assert(MFI.getObjectSize(FrameIndex) >= TRI.getSpillSize(*RC) &&
828 "Stack slot is too small to store");
829 (void)MFI;
830
831 unsigned Opc = getStoreRegOpcode(SrcReg, RC, &TRI, Subtarget);
832 DebugLoc DL = MBB.findDebugLoc(MI);
833 // (0,FrameIndex) <- $reg
834 M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIndex)
835 .addReg(SrcReg, getKillRegState(IsKill));
836}
837
840 Register DstReg, int FrameIndex,
841 const TargetRegisterClass *RC,
842 Register VReg, unsigned SubReg,
843 MachineInstr::MIFlag Flags) const {
844 const MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
845 assert(MFI.getObjectSize(FrameIndex) >= TRI.getSpillSize(*RC) &&
846 "Stack slot is too small to load");
847 (void)MFI;
848
849 unsigned Opc = getLoadRegOpcode(DstReg, RC, &TRI, Subtarget);
850 DebugLoc DL = MBB.findDebugLoc(MI);
851 M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DstReg), FrameIndex);
852}
853
854/// Return a virtual register initialized with the global base register
855/// value. Output instructions required to initialize the register in the
856/// function entry block, if necessary.
857///
858/// TODO Move this function to M68kMachineFunctionInfo.
861 unsigned GlobalBaseReg = MxFI->getGlobalBaseReg();
862 if (GlobalBaseReg != 0)
863 return GlobalBaseReg;
864
865 // Create the register. The code to initialize it is inserted later,
866 // by the M68kGlobalBaseReg pass (below).
867 //
868 // NOTE
869 // Normally M68k uses A5 register as global base pointer but this will
870 // create unnecessary spill if we use less then 4 registers in code; since A5
871 // is callee-save anyway we could try to allocate caller-save first and if
872 // lucky get one, otherwise it does not really matter which callee-save to
873 // use.
874 MachineRegisterInfo &RegInfo = MF->getRegInfo();
875 GlobalBaseReg = RegInfo.createVirtualRegister(&M68k::AR32_NOSPRegClass);
876 MxFI->setGlobalBaseReg(GlobalBaseReg);
877 return GlobalBaseReg;
878}
879
880std::pair<unsigned, unsigned>
882 return std::make_pair(TF, 0u);
883}
884
887 using namespace M68kII;
888 static const std::pair<unsigned, const char *> TargetFlags[] = {
889 {MO_ABSOLUTE_ADDRESS, "m68k-absolute"},
890 {MO_PC_RELATIVE_ADDRESS, "m68k-pcrel"},
891 {MO_GOT, "m68k-got"},
892 {MO_GOTOFF, "m68k-gotoff"},
893 {MO_GOTPCREL, "m68k-gotpcrel"},
894 {MO_PLT, "m68k-plt"},
895 {MO_TLSGD, "m68k-tlsgd"},
896 {MO_TLSLD, "m68k-tlsld"},
897 {MO_TLSLDM, "m68k-tlsldm"},
898 {MO_TLSIE, "m68k-tlsie"},
899 {MO_TLSLE, "m68k-tlsle"}};
900 return ArrayRef(TargetFlags);
901}
902
903#undef DEBUG_TYPE
904#define DEBUG_TYPE "m68k-create-global-base-reg"
905
906#define PASS_NAME "M68k PIC Global Base Reg Initialization"
907
908namespace {
909/// This initializes the PIC global base register
910struct M68kGlobalBaseReg : public MachineFunctionPass {
911 static char ID;
912 M68kGlobalBaseReg() : MachineFunctionPass(ID) {}
913
914 bool runOnMachineFunction(MachineFunction &MF) override {
915 const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>();
917
918 unsigned GlobalBaseReg = MxFI->getGlobalBaseReg();
919
920 // If we didn't need a GlobalBaseReg, don't insert code.
921 if (GlobalBaseReg == 0)
922 return false;
923
924 // Insert the set of GlobalBaseReg into the first MBB of the function
925 MachineBasicBlock &FirstMBB = MF.front();
927 DebugLoc DL = FirstMBB.findDebugLoc(MBBI);
928 const M68kInstrInfo *TII = STI.getInstrInfo();
929
930 // Generate lea (__GLOBAL_OFFSET_TABLE_,%PC), %A5
931 BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::LEA32q), GlobalBaseReg)
932 .addExternalSymbol("_GLOBAL_OFFSET_TABLE_", M68kII::MO_GOTPCREL);
933
934 return true;
935 }
936
937 void getAnalysisUsage(AnalysisUsage &AU) const override {
938 AU.setPreservesCFG();
940 }
941};
942char M68kGlobalBaseReg::ID = 0;
943} // namespace
944
945INITIALIZE_PASS(M68kGlobalBaseReg, DEBUG_TYPE, PASS_NAME, false, false)
946
948 return new M68kGlobalBaseReg();
949}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Mark last scratch load
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
#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:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file contains some templates that are useful if you are working with the STL at all.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:483
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 LLVM_DEBUG(...)
Definition Debug.h:119
#define PASS_NAME
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.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:275
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
A debug info location.
Definition DebugLoc.h:124
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
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 copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) 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.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
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.
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.
const M68kInstrInfo * getInstrInfo() const override
Describe properties that are true of each instruction in the target description file.
Machine Value Type.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
MachineInstrBundleIterator< MachineInstr > iterator
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.
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 & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
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.
LLVM_ABI MachineInstr * removeFromParent()
Unlink 'this' from the containing basic block, and return it without deleting it.
const MachineBasicBlock * getParent() const
LLVM_ABI 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.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI 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.
LLVM_ABI 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,...
LLVM_ABI 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:20
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
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
This namespace holds all of the target specific flags that instruction info tracks.
@ MO_GOTPCREL
On a symbol operand this indicates that the immediate is offset to the GOT entry for the symbol name ...
Define some predicates that are used for node matching.
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)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:558
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Undef
Value of the register doesn't matter.
constexpr RegState getKillRegState(bool B)
Op::Description Desc
FunctionPass * createM68kGlobalBaseRegPass()
This pass initializes a global base register for PIC on M68k.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:189
@ Ref
The access may reference the value stored in memory.
Definition ModRef.h:32
ArrayRef(const T &OneElt) -> ArrayRef< T >
Matching combinators.