1 //===-- M68kInstrInfo.cpp - M68k Instruction Information --------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// This file contains the M68k declaration of the TargetInstrInfo class. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "M68kInstrInfo.h" 15 16 #include "M68kInstrBuilder.h" 17 #include "M68kMachineFunction.h" 18 #include "M68kTargetMachine.h" 19 #include "MCTargetDesc/M68kMCCodeEmitter.h" 20 21 #include "llvm/ADT/STLExtras.h" 22 #include "llvm/ADT/ScopeExit.h" 23 #include "llvm/CodeGen/LivePhysRegs.h" 24 #include "llvm/CodeGen/LiveVariables.h" 25 #include "llvm/CodeGen/MachineInstrBuilder.h" 26 #include "llvm/CodeGen/MachineRegisterInfo.h" 27 #include "llvm/MC/TargetRegistry.h" 28 #include "llvm/Support/ErrorHandling.h" 29 #include "llvm/Support/Regex.h" 30 31 #include <functional> 32 33 using namespace llvm; 34 35 #define DEBUG_TYPE "M68k-instr-info" 36 37 #define GET_INSTRINFO_CTOR_DTOR 38 #include "M68kGenInstrInfo.inc" 39 40 // Pin the vtable to this file. 41 void M68kInstrInfo::anchor() {} 42 43 M68kInstrInfo::M68kInstrInfo(const M68kSubtarget &STI) 44 : M68kGenInstrInfo(M68k::ADJCALLSTACKDOWN, M68k::ADJCALLSTACKUP, 0, 45 M68k::RET), 46 Subtarget(STI), RI(STI) {} 47 48 static M68k::CondCode getCondFromBranchOpc(unsigned BrOpc) { 49 switch (BrOpc) { 50 default: 51 return M68k::COND_INVALID; 52 case M68k::Beq8: 53 return M68k::COND_EQ; 54 case M68k::Bne8: 55 return M68k::COND_NE; 56 case M68k::Blt8: 57 return M68k::COND_LT; 58 case M68k::Ble8: 59 return M68k::COND_LE; 60 case M68k::Bgt8: 61 return M68k::COND_GT; 62 case M68k::Bge8: 63 return M68k::COND_GE; 64 case M68k::Bcs8: 65 return M68k::COND_CS; 66 case M68k::Bls8: 67 return M68k::COND_LS; 68 case M68k::Bhi8: 69 return M68k::COND_HI; 70 case M68k::Bcc8: 71 return M68k::COND_CC; 72 case M68k::Bmi8: 73 return M68k::COND_MI; 74 case M68k::Bpl8: 75 return M68k::COND_PL; 76 case M68k::Bvs8: 77 return M68k::COND_VS; 78 case M68k::Bvc8: 79 return M68k::COND_VC; 80 } 81 } 82 83 bool M68kInstrInfo::AnalyzeBranchImpl(MachineBasicBlock &MBB, 84 MachineBasicBlock *&TBB, 85 MachineBasicBlock *&FBB, 86 SmallVectorImpl<MachineOperand> &Cond, 87 bool AllowModify) const { 88 89 auto UncondBranch = 90 std::pair<MachineBasicBlock::reverse_iterator, MachineBasicBlock *>{ 91 MBB.rend(), nullptr}; 92 93 // Erase any instructions if allowed at the end of the scope. 94 std::vector<std::reference_wrapper<llvm::MachineInstr>> EraseList; 95 auto FinalizeOnReturn = llvm::make_scope_exit([&EraseList] { 96 std::for_each(EraseList.begin(), EraseList.end(), 97 [](auto &ref) { ref.get().eraseFromParent(); }); 98 }); 99 100 // Start from the bottom of the block and work up, examining the 101 // terminator instructions. 102 for (auto iter = MBB.rbegin(); iter != MBB.rend(); iter = std::next(iter)) { 103 104 unsigned Opcode = iter->getOpcode(); 105 106 if (iter->isDebugInstr()) 107 continue; 108 109 // Working from the bottom, when we see a non-terminator instruction, we're 110 // done. 111 if (!isUnpredicatedTerminator(*iter)) 112 break; 113 114 // A terminator that isn't a branch can't easily be handled by this 115 // analysis. 116 if (!iter->isBranch()) 117 return true; 118 119 // Handle unconditional branches. 120 if (Opcode == M68k::BRA8 || Opcode == M68k::BRA16) { 121 if (!iter->getOperand(0).isMBB()) 122 return true; 123 UncondBranch = {iter, iter->getOperand(0).getMBB()}; 124 125 // TBB is used to indicate the unconditional destination. 126 TBB = UncondBranch.second; 127 128 if (!AllowModify) 129 continue; 130 131 // If the block has any instructions after a JMP, erase them. 132 EraseList.insert(EraseList.begin(), MBB.rbegin(), iter); 133 134 Cond.clear(); 135 FBB = nullptr; 136 137 // Erase the JMP if it's equivalent to a fall-through. 138 if (MBB.isLayoutSuccessor(UncondBranch.second)) { 139 TBB = nullptr; 140 EraseList.push_back(*iter); 141 UncondBranch = {MBB.rend(), nullptr}; 142 } 143 144 continue; 145 } 146 147 // Handle conditional branches. 148 auto BranchCode = M68k::GetCondFromBranchOpc(Opcode); 149 150 // Can't handle indirect branch. 151 if (BranchCode == M68k::COND_INVALID) 152 return true; 153 154 // In practice we should never have an undef CCR operand, if we do 155 // abort here as we are not prepared to preserve the flag. 156 // ??? Is this required? 157 // if (iter->getOperand(1).isUndef()) 158 // return true; 159 160 // Working from the bottom, handle the first conditional branch. 161 if (Cond.empty()) { 162 if (!iter->getOperand(0).isMBB()) 163 return true; 164 MachineBasicBlock *CondBranchTarget = iter->getOperand(0).getMBB(); 165 166 // If we see something like this: 167 // 168 // bcc l1 169 // bra l2 170 // ... 171 // l1: 172 // ... 173 // l2: 174 if (UncondBranch.first != MBB.rend()) { 175 176 assert(std::next(UncondBranch.first) == iter && "Wrong block layout."); 177 178 // And we are allowed to modify the block and the target block of the 179 // conditional branch is the direct successor of this block: 180 // 181 // bcc l1 182 // bra l2 183 // l1: 184 // ... 185 // l2: 186 // 187 // we change it to this if allowed: 188 // 189 // bncc l2 190 // l1: 191 // ... 192 // l2: 193 // 194 // Which is a bit more efficient. 195 if (AllowModify && MBB.isLayoutSuccessor(CondBranchTarget)) { 196 197 BranchCode = GetOppositeBranchCondition(BranchCode); 198 unsigned BNCC = GetCondBranchFromCond(BranchCode); 199 200 BuildMI(MBB, *UncondBranch.first, MBB.rfindDebugLoc(iter), get(BNCC)) 201 .addMBB(UncondBranch.second); 202 203 EraseList.push_back(*iter); 204 EraseList.push_back(*UncondBranch.first); 205 206 TBB = UncondBranch.second; 207 FBB = nullptr; 208 Cond.push_back(MachineOperand::CreateImm(BranchCode)); 209 210 // Otherwise preserve TBB, FBB and Cond as requested 211 } else { 212 TBB = CondBranchTarget; 213 FBB = UncondBranch.second; 214 Cond.push_back(MachineOperand::CreateImm(BranchCode)); 215 } 216 217 UncondBranch = {MBB.rend(), nullptr}; 218 continue; 219 } 220 221 TBB = CondBranchTarget; 222 FBB = nullptr; 223 Cond.push_back(MachineOperand::CreateImm(BranchCode)); 224 225 continue; 226 } 227 228 // Handle subsequent conditional branches. Only handle the case where all 229 // conditional branches branch to the same destination and their condition 230 // opcodes fit one of the special multi-branch idioms. 231 assert(Cond.size() == 1); 232 assert(TBB); 233 234 // If the conditions are the same, we can leave them alone. 235 auto OldBranchCode = static_cast<M68k::CondCode>(Cond[0].getImm()); 236 if (!iter->getOperand(0).isMBB()) 237 return true; 238 auto NewTBB = iter->getOperand(0).getMBB(); 239 if (OldBranchCode == BranchCode && TBB == NewTBB) 240 continue; 241 242 // If they differ we cannot do much here. 243 return true; 244 } 245 246 return false; 247 } 248 249 bool M68kInstrInfo::analyzeBranch(MachineBasicBlock &MBB, 250 MachineBasicBlock *&TBB, 251 MachineBasicBlock *&FBB, 252 SmallVectorImpl<MachineOperand> &Cond, 253 bool AllowModify) const { 254 return AnalyzeBranchImpl(MBB, TBB, FBB, Cond, AllowModify); 255 } 256 257 unsigned M68kInstrInfo::removeBranch(MachineBasicBlock &MBB, 258 int *BytesRemoved) const { 259 assert(!BytesRemoved && "code size not handled"); 260 261 MachineBasicBlock::iterator I = MBB.end(); 262 unsigned Count = 0; 263 264 while (I != MBB.begin()) { 265 --I; 266 if (I->isDebugValue()) 267 continue; 268 if (I->getOpcode() != M68k::BRA8 && 269 getCondFromBranchOpc(I->getOpcode()) == M68k::COND_INVALID) 270 break; 271 // Remove the branch. 272 I->eraseFromParent(); 273 I = MBB.end(); 274 ++Count; 275 } 276 277 return Count; 278 } 279 280 unsigned M68kInstrInfo::insertBranch( 281 MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, 282 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const { 283 // Shouldn't be a fall through. 284 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 285 assert((Cond.size() == 1 || Cond.size() == 0) && 286 "M68k branch conditions have one component!"); 287 assert(!BytesAdded && "code size not handled"); 288 289 if (Cond.empty()) { 290 // Unconditional branch? 291 assert(!FBB && "Unconditional branch with multiple successors!"); 292 BuildMI(&MBB, DL, get(M68k::BRA8)).addMBB(TBB); 293 return 1; 294 } 295 296 // If FBB is null, it is implied to be a fall-through block. 297 bool FallThru = FBB == nullptr; 298 299 // Conditional branch. 300 unsigned Count = 0; 301 M68k::CondCode CC = (M68k::CondCode)Cond[0].getImm(); 302 unsigned Opc = GetCondBranchFromCond(CC); 303 BuildMI(&MBB, DL, get(Opc)).addMBB(TBB); 304 ++Count; 305 if (!FallThru) { 306 // Two-way Conditional branch. Insert the second branch. 307 BuildMI(&MBB, DL, get(M68k::BRA8)).addMBB(FBB); 308 ++Count; 309 } 310 return Count; 311 } 312 313 void M68kInstrInfo::AddSExt(MachineBasicBlock &MBB, 314 MachineBasicBlock::iterator I, DebugLoc DL, 315 unsigned Reg, MVT From, MVT To) const { 316 if (From == MVT::i8) { 317 unsigned R = Reg; 318 // EXT16 requires i16 register 319 if (To == MVT::i32) { 320 R = RI.getSubReg(Reg, M68k::MxSubRegIndex16Lo); 321 assert(R && "No viable SUB register available"); 322 } 323 BuildMI(MBB, I, DL, get(M68k::EXT16), R).addReg(R); 324 } 325 326 if (To == MVT::i32) 327 BuildMI(MBB, I, DL, get(M68k::EXT32), Reg).addReg(Reg); 328 } 329 330 void M68kInstrInfo::AddZExt(MachineBasicBlock &MBB, 331 MachineBasicBlock::iterator I, DebugLoc DL, 332 unsigned Reg, MVT From, MVT To) const { 333 334 unsigned Mask, And; 335 if (From == MVT::i8) 336 Mask = 0xFF; 337 else 338 Mask = 0xFFFF; 339 340 if (To == MVT::i16) 341 And = M68k::AND16di; 342 else // i32 343 And = M68k::AND32di; 344 345 // TODO use xor r,r to decrease size 346 BuildMI(MBB, I, DL, get(And), Reg).addReg(Reg).addImm(Mask); 347 } 348 349 bool M68kInstrInfo::ExpandMOVX_RR(MachineInstrBuilder &MIB, MVT MVTDst, 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 387 bool M68kInstrInfo::ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned, 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 415 MachineBasicBlock &MBB = *MIB->getParent(); 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 436 bool M68kInstrInfo::ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned, 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 457 MachineBasicBlock::iterator I = MIB.getInstr(); 458 I++; 459 MachineBasicBlock &MBB = *MIB->getParent(); 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 473 bool M68kInstrInfo::ExpandPUSH_POP(MachineInstrBuilder &MIB, 474 const MCInstrDesc &Desc, bool IsPush) const { 475 MachineBasicBlock::iterator I = MIB.getInstr(); 476 I++; 477 MachineBasicBlock &MBB = *MIB->getParent(); 478 MachineOperand MO = MIB->getOperand(0); 479 DebugLoc DL = MIB->getDebugLoc(); 480 if (IsPush) 481 BuildMI(MBB, I, DL, Desc).addReg(RI.getStackRegister()).add(MO); 482 else 483 BuildMI(MBB, I, DL, Desc, MO.getReg()).addReg(RI.getStackRegister()); 484 485 MIB->eraseFromParent(); 486 return true; 487 } 488 489 bool 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 506 bool M68kInstrInfo::ExpandMOVEM(MachineInstrBuilder &MIB, 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) 537 .addReg(Reg, RegState::ImplicitDefine) 538 .copyImplicitOps(*MIB); 539 } else { 540 BuildMI(MBB, MI, DL, Desc) 541 .addImm(Offset) 542 .addReg(Base) 543 .addImm(Mask) 544 .addReg(Reg, RegState::Implicit) 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 /// 560 static bool Expand2AddrUndef(MachineInstrBuilder &MIB, 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. 568 MIB.addReg(Reg, RegState::Undef).addReg(Reg, RegState::Undef); 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 575 bool M68kInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { 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 602 bool M68kInstrInfo::isPCRelRegisterOperandLegal( 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 627 void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 628 MachineBasicBlock::iterator MI, 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. 653 MachineInstrBuilder MIB(*MBB.getParent(), MI); 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 696 namespace { 697 unsigned 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 719 unsigned getStoreRegOpcode(unsigned SrcReg, const TargetRegisterClass *RC, 720 const TargetRegisterInfo *TRI, 721 const M68kSubtarget &STI) { 722 return getLoadStoreRegOpcode(SrcReg, RC, TRI, STI, false); 723 } 724 725 unsigned 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 732 bool M68kInstrInfo::getStackSlotRange(const TargetRegisterClass *RC, 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 742 void M68kInstrInfo::storeRegToStackSlot( 743 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg, 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); 751 DebugLoc DL = MBB.findDebugLoc(MI); 752 // (0,FrameIndex) <- $reg 753 M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIndex) 754 .addReg(SrcReg, getKillRegState(IsKill)); 755 } 756 757 void M68kInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 758 MachineBasicBlock::iterator MI, 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); 768 DebugLoc DL = MBB.findDebugLoc(MI); 769 M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DstReg), FrameIndex); 770 } 771 772 /// Return a virtual register initialized with the 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. 777 unsigned M68kInstrInfo::getGlobalBaseReg(MachineFunction *MF) const { 778 M68kMachineFunctionInfo *MxFI = MF->getInfo<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 798 std::pair<unsigned, unsigned> 799 M68kInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const { 800 return std::make_pair(TF, 0u); 801 } 802 803 ArrayRef<std::pair<unsigned, const char *>> 804 M68kInstrInfo::getSerializableDirectMachineOperandTargetFlags() const { 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 826 namespace { 827 /// This initializes the PIC global base register 828 struct 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>(); 834 M68kMachineFunctionInfo *MxFI = MF.getInfo<M68kMachineFunctionInfo>(); 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(); 844 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 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(); 857 MachineFunctionPass::getAnalysisUsage(AU); 858 } 859 }; 860 char M68kGlobalBaseReg::ID = 0; 861 } // namespace 862 863 INITIALIZE_PASS(M68kGlobalBaseReg, DEBUG_TYPE, PASS_NAME, false, false) 864 865 FunctionPass *llvm::createM68kGlobalBaseRegPass() { 866 return new M68kGlobalBaseReg(); 867 } 868