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 (void)RCSrc; 365 366 // We need to find the super source register that matches the size of Dst 367 unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst); 368 assert(SSrc && "No viable MEGA register available"); 369 370 DebugLoc DL = MIB->getDebugLoc(); 371 372 // If it happens to that super source register is the destination register 373 // we do nothing 374 if (Dst == SSrc) { 375 LLVM_DEBUG(dbgs() << "Remove " << *MIB.getInstr() << '\n'); 376 MIB->eraseFromParent(); 377 } else { // otherwise we need to MOV 378 LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to MOV\n"); 379 MIB->setDesc(get(Move)); 380 MIB->getOperand(1).setReg(SSrc); 381 } 382 383 return true; 384 } 385 386 /// Expand SExt MOVE pseudos into a MOV and a EXT if the operands are two 387 /// different registers or just EXT if it is the same register 388 bool M68kInstrInfo::ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned, 389 MVT MVTDst, MVT MVTSrc) const { 390 LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to "); 391 392 unsigned Move; 393 394 if (MVTDst == MVT::i16) 395 Move = M68k::MOV16rr; 396 else // i32 397 Move = M68k::MOV32rr; 398 399 Register Dst = MIB->getOperand(0).getReg(); 400 Register Src = MIB->getOperand(1).getReg(); 401 402 assert(Dst != Src && "You cannot use the same Regs with MOVSX_RR"); 403 404 const auto &TRI = getRegisterInfo(); 405 406 const auto *RCDst = TRI.getMaximalPhysRegClass(Dst, MVTDst); 407 const auto *RCSrc = TRI.getMaximalPhysRegClass(Src, MVTSrc); 408 409 assert(RCDst && RCSrc && "Wrong use of MOVSX_RR"); 410 assert(RCDst != RCSrc && "You cannot use the same Reg Classes with MOVSX_RR"); 411 (void)RCSrc; 412 413 // We need to find the super source register that matches the size of Dst 414 unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst); 415 assert(SSrc && "No viable MEGA register available"); 416 417 MachineBasicBlock &MBB = *MIB->getParent(); 418 DebugLoc DL = MIB->getDebugLoc(); 419 420 if (Dst != SSrc) { 421 LLVM_DEBUG(dbgs() << "Move and " << '\n'); 422 BuildMI(MBB, MIB.getInstr(), DL, get(Move), Dst).addReg(SSrc); 423 } 424 425 if (IsSigned) { 426 LLVM_DEBUG(dbgs() << "Sign Extend" << '\n'); 427 AddSExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst); 428 } else { 429 LLVM_DEBUG(dbgs() << "Zero Extend" << '\n'); 430 AddZExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst); 431 } 432 433 MIB->eraseFromParent(); 434 435 return true; 436 } 437 438 bool M68kInstrInfo::ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned, 439 const MCInstrDesc &Desc, MVT MVTDst, 440 MVT MVTSrc) const { 441 LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to LOAD and "); 442 443 Register Dst = MIB->getOperand(0).getReg(); 444 445 // We need the subreg of Dst to make instruction verifier happy because the 446 // real machine instruction consumes and produces values of the same size and 447 // the registers the will be used here fall into different classes and this 448 // makes IV cry. We could use a bigger operation, but this will put some 449 // pressure on cache and memory, so no. 450 unsigned SubDst = 451 RI.getSubReg(Dst, MVTSrc == MVT::i8 ? M68k::MxSubRegIndex8Lo 452 : M68k::MxSubRegIndex16Lo); 453 assert(SubDst && "No viable SUB register available"); 454 455 // Make this a plain move 456 MIB->setDesc(Desc); 457 MIB->getOperand(0).setReg(SubDst); 458 459 MachineBasicBlock::iterator I = MIB.getInstr(); 460 I++; 461 MachineBasicBlock &MBB = *MIB->getParent(); 462 DebugLoc DL = MIB->getDebugLoc(); 463 464 if (IsSigned) { 465 LLVM_DEBUG(dbgs() << "Sign Extend" << '\n'); 466 AddSExt(MBB, I, DL, Dst, MVTSrc, MVTDst); 467 } else { 468 LLVM_DEBUG(dbgs() << "Zero Extend" << '\n'); 469 AddZExt(MBB, I, DL, Dst, MVTSrc, MVTDst); 470 } 471 472 return true; 473 } 474 475 bool M68kInstrInfo::ExpandPUSH_POP(MachineInstrBuilder &MIB, 476 const MCInstrDesc &Desc, bool IsPush) const { 477 MachineBasicBlock::iterator I = MIB.getInstr(); 478 I++; 479 MachineBasicBlock &MBB = *MIB->getParent(); 480 MachineOperand MO = MIB->getOperand(0); 481 DebugLoc DL = MIB->getDebugLoc(); 482 if (IsPush) 483 BuildMI(MBB, I, DL, Desc).addReg(RI.getStackRegister()).add(MO); 484 else 485 BuildMI(MBB, I, DL, Desc, MO.getReg()).addReg(RI.getStackRegister()); 486 487 MIB->eraseFromParent(); 488 return true; 489 } 490 491 bool M68kInstrInfo::ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const { 492 493 // Replace the pseudo instruction with the real one 494 if (IsToCCR) 495 MIB->setDesc(get(M68k::MOV16cd)); 496 else 497 // FIXME M68010 or later is required 498 MIB->setDesc(get(M68k::MOV16dc)); 499 500 // Promote used register to the next class 501 auto &Opd = MIB->getOperand(1); 502 Opd.setReg(getRegisterInfo().getMatchingSuperReg( 503 Opd.getReg(), M68k::MxSubRegIndex8Lo, &M68k::DR16RegClass)); 504 505 return true; 506 } 507 508 bool M68kInstrInfo::ExpandMOVEM(MachineInstrBuilder &MIB, 509 const MCInstrDesc &Desc, bool IsRM) const { 510 int Reg = 0, Offset = 0, Base = 0; 511 auto XR32 = RI.getRegClass(M68k::XR32RegClassID); 512 auto DL = MIB->getDebugLoc(); 513 auto MI = MIB.getInstr(); 514 auto &MBB = *MIB->getParent(); 515 516 if (IsRM) { 517 Reg = MIB->getOperand(0).getReg(); 518 Offset = MIB->getOperand(1).getImm(); 519 Base = MIB->getOperand(2).getReg(); 520 } else { 521 Offset = MIB->getOperand(0).getImm(); 522 Base = MIB->getOperand(1).getReg(); 523 Reg = MIB->getOperand(2).getReg(); 524 } 525 526 // If the register is not in XR32 then it is smaller than 32 bit, we 527 // implicitly promote it to 32 528 if (!XR32->contains(Reg)) { 529 Reg = RI.getMatchingMegaReg(Reg, XR32); 530 assert(Reg && "Has not meaningful MEGA register"); 531 } 532 533 unsigned Mask = 1 << RI.getSpillRegisterOrder(Reg); 534 if (IsRM) { 535 BuildMI(MBB, MI, DL, Desc) 536 .addImm(Mask) 537 .addImm(Offset) 538 .addReg(Base) 539 .addReg(Reg, RegState::ImplicitDefine) 540 .copyImplicitOps(*MIB); 541 } else { 542 BuildMI(MBB, MI, DL, Desc) 543 .addImm(Offset) 544 .addReg(Base) 545 .addImm(Mask) 546 .addReg(Reg, RegState::Implicit) 547 .copyImplicitOps(*MIB); 548 } 549 550 MIB->eraseFromParent(); 551 552 return true; 553 } 554 555 /// Expand a single-def pseudo instruction to a two-addr 556 /// instruction with two undef reads of the register being defined. 557 /// This is used for mapping: 558 /// %d0 = SETCS_C32d 559 /// to: 560 /// %d0 = SUBX32dd %d0<undef>, %d0<undef> 561 /// 562 static bool Expand2AddrUndef(MachineInstrBuilder &MIB, 563 const MCInstrDesc &Desc) { 564 assert(Desc.getNumOperands() == 3 && "Expected two-addr instruction."); 565 Register Reg = MIB->getOperand(0).getReg(); 566 MIB->setDesc(Desc); 567 568 // MachineInstr::addOperand() will insert explicit operands before any 569 // implicit operands. 570 MIB.addReg(Reg, RegState::Undef).addReg(Reg, RegState::Undef); 571 // But we don't trust that. 572 assert(MIB->getOperand(1).getReg() == Reg && 573 MIB->getOperand(2).getReg() == Reg && "Misplaced operand"); 574 return true; 575 } 576 577 bool M68kInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { 578 MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI); 579 switch (MI.getOpcode()) { 580 case M68k::PUSH8d: 581 return ExpandPUSH_POP(MIB, get(M68k::MOV8ed), true); 582 case M68k::PUSH16d: 583 return ExpandPUSH_POP(MIB, get(M68k::MOV16er), true); 584 case M68k::PUSH32r: 585 return ExpandPUSH_POP(MIB, get(M68k::MOV32er), true); 586 587 case M68k::POP8d: 588 return ExpandPUSH_POP(MIB, get(M68k::MOV8do), false); 589 case M68k::POP16d: 590 return ExpandPUSH_POP(MIB, get(M68k::MOV16ro), false); 591 case M68k::POP32r: 592 return ExpandPUSH_POP(MIB, get(M68k::MOV32ro), false); 593 594 case M68k::SETCS_C8d: 595 return Expand2AddrUndef(MIB, get(M68k::SUBX8dd)); 596 case M68k::SETCS_C16d: 597 return Expand2AddrUndef(MIB, get(M68k::SUBX16dd)); 598 case M68k::SETCS_C32d: 599 return Expand2AddrUndef(MIB, get(M68k::SUBX32dd)); 600 } 601 return false; 602 } 603 604 bool M68kInstrInfo::isPCRelRegisterOperandLegal( 605 const MachineOperand &MO) const { 606 assert(MO.isReg()); 607 608 // Check whether this MO belongs to an instruction with addressing mode 'k', 609 // Refer to TargetInstrInfo.h for more information about this function. 610 611 const MachineInstr *MI = MO.getParent(); 612 const unsigned NameIndices = M68kInstrNameIndices[MI->getOpcode()]; 613 StringRef InstrName(&M68kInstrNameData[NameIndices]); 614 const unsigned OperandNo = MO.getOperandNo(); 615 616 // If this machine operand is the 2nd operand, then check 617 // whether the instruction has destination addressing mode 'k'. 618 if (OperandNo == 1) 619 return Regex("[A-Z]+(8|16|32)k[a-z](_TC)?$").match(InstrName); 620 621 // If this machine operand is the last one, then check 622 // whether the instruction has source addressing mode 'k'. 623 if (OperandNo == MI->getNumExplicitOperands() - 1) 624 return Regex("[A-Z]+(8|16|32)[a-z]k(_TC)?$").match(InstrName); 625 626 return false; 627 } 628 629 void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 630 MachineBasicBlock::iterator MI, 631 const DebugLoc &DL, MCRegister DstReg, 632 MCRegister SrcReg, bool KillSrc) const { 633 unsigned Opc = 0; 634 635 // First deal with the normal symmetric copies. 636 if (M68k::XR32RegClass.contains(DstReg, SrcReg)) 637 Opc = M68k::MOV32rr; 638 else if (M68k::XR16RegClass.contains(DstReg, SrcReg)) 639 Opc = M68k::MOV16rr; 640 else if (M68k::DR8RegClass.contains(DstReg, SrcReg)) 641 Opc = M68k::MOV8dd; 642 643 if (Opc) { 644 BuildMI(MBB, MI, DL, get(Opc), DstReg) 645 .addReg(SrcReg, getKillRegState(KillSrc)); 646 return; 647 } 648 649 // Now deal with asymmetrically sized copies. The cases that follow are upcast 650 // moves. 651 // 652 // NOTE 653 // These moves are not aware of type nature of these values and thus 654 // won't do any SExt or ZExt and upper bits will basically contain garbage. 655 MachineInstrBuilder MIB(*MBB.getParent(), MI); 656 if (M68k::DR8RegClass.contains(SrcReg)) { 657 if (M68k::XR16RegClass.contains(DstReg)) 658 Opc = M68k::MOVXd16d8; 659 else if (M68k::XR32RegClass.contains(DstReg)) 660 Opc = M68k::MOVXd32d8; 661 } else if (M68k::XR16RegClass.contains(SrcReg) && 662 M68k::XR32RegClass.contains(DstReg)) 663 Opc = M68k::MOVXd32d16; 664 665 if (Opc) { 666 BuildMI(MBB, MI, DL, get(Opc), DstReg) 667 .addReg(SrcReg, getKillRegState(KillSrc)); 668 return; 669 } 670 671 bool FromCCR = SrcReg == M68k::CCR; 672 bool FromSR = SrcReg == M68k::SR; 673 bool ToCCR = DstReg == M68k::CCR; 674 bool ToSR = DstReg == M68k::SR; 675 676 if (FromCCR) { 677 assert(M68k::DR8RegClass.contains(DstReg) && 678 "Need DR8 register to copy CCR"); 679 Opc = M68k::MOV8dc; 680 } else if (ToCCR) { 681 assert(M68k::DR8RegClass.contains(SrcReg) && 682 "Need DR8 register to copy CCR"); 683 Opc = M68k::MOV8cd; 684 } else if (FromSR || ToSR) 685 llvm_unreachable("Cannot emit SR copy instruction"); 686 687 if (Opc) { 688 BuildMI(MBB, MI, DL, get(Opc), DstReg) 689 .addReg(SrcReg, getKillRegState(KillSrc)); 690 return; 691 } 692 693 LLVM_DEBUG(dbgs() << "Cannot copy " << RI.getName(SrcReg) << " to " 694 << RI.getName(DstReg) << '\n'); 695 llvm_unreachable("Cannot emit physreg copy instruction"); 696 } 697 698 namespace { 699 unsigned getLoadStoreRegOpcode(unsigned Reg, const TargetRegisterClass *RC, 700 const TargetRegisterInfo *TRI, 701 const M68kSubtarget &STI, bool load) { 702 switch (TRI->getRegSizeInBits(*RC)) { 703 default: 704 llvm_unreachable("Unknown spill size"); 705 case 8: 706 if (M68k::DR8RegClass.hasSubClassEq(RC)) 707 return load ? M68k::MOV8dp : M68k::MOV8pd; 708 if (M68k::CCRCRegClass.hasSubClassEq(RC)) 709 return load ? M68k::MOV16cp : M68k::MOV16pc; 710 711 llvm_unreachable("Unknown 1-byte regclass"); 712 case 16: 713 assert(M68k::XR16RegClass.hasSubClassEq(RC) && "Unknown 2-byte regclass"); 714 return load ? M68k::MOVM16mp_P : M68k::MOVM16pm_P; 715 case 32: 716 assert(M68k::XR32RegClass.hasSubClassEq(RC) && "Unknown 4-byte regclass"); 717 return load ? M68k::MOVM32mp_P : M68k::MOVM32pm_P; 718 } 719 } 720 721 unsigned getStoreRegOpcode(unsigned SrcReg, const TargetRegisterClass *RC, 722 const TargetRegisterInfo *TRI, 723 const M68kSubtarget &STI) { 724 return getLoadStoreRegOpcode(SrcReg, RC, TRI, STI, false); 725 } 726 727 unsigned getLoadRegOpcode(unsigned DstReg, const TargetRegisterClass *RC, 728 const TargetRegisterInfo *TRI, 729 const M68kSubtarget &STI) { 730 return getLoadStoreRegOpcode(DstReg, RC, TRI, STI, true); 731 } 732 } // end anonymous namespace 733 734 bool M68kInstrInfo::getStackSlotRange(const TargetRegisterClass *RC, 735 unsigned SubIdx, unsigned &Size, 736 unsigned &Offset, 737 const MachineFunction &MF) const { 738 // The slot size must be the maximum size so we can easily use MOVEM.L 739 Size = 4; 740 Offset = 0; 741 return true; 742 } 743 744 void M68kInstrInfo::storeRegToStackSlot( 745 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg, 746 bool IsKill, int FrameIndex, const TargetRegisterClass *RC, 747 const TargetRegisterInfo *TRI, Register VReg) const { 748 const MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo(); 749 assert(MFI.getObjectSize(FrameIndex) >= TRI->getSpillSize(*RC) && 750 "Stack slot is too small to store"); 751 (void)MFI; 752 753 unsigned Opc = getStoreRegOpcode(SrcReg, RC, TRI, Subtarget); 754 DebugLoc DL = MBB.findDebugLoc(MI); 755 // (0,FrameIndex) <- $reg 756 M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIndex) 757 .addReg(SrcReg, getKillRegState(IsKill)); 758 } 759 760 void M68kInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 761 MachineBasicBlock::iterator MI, 762 Register DstReg, int FrameIndex, 763 const TargetRegisterClass *RC, 764 const TargetRegisterInfo *TRI, 765 Register VReg) const { 766 const MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo(); 767 assert(MFI.getObjectSize(FrameIndex) >= TRI->getSpillSize(*RC) && 768 "Stack slot is too small to load"); 769 (void)MFI; 770 771 unsigned Opc = getLoadRegOpcode(DstReg, RC, TRI, Subtarget); 772 DebugLoc DL = MBB.findDebugLoc(MI); 773 M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DstReg), FrameIndex); 774 } 775 776 /// Return a virtual register initialized with the global base register 777 /// value. Output instructions required to initialize the register in the 778 /// function entry block, if necessary. 779 /// 780 /// TODO Move this function to M68kMachineFunctionInfo. 781 unsigned M68kInstrInfo::getGlobalBaseReg(MachineFunction *MF) const { 782 M68kMachineFunctionInfo *MxFI = MF->getInfo<M68kMachineFunctionInfo>(); 783 unsigned GlobalBaseReg = MxFI->getGlobalBaseReg(); 784 if (GlobalBaseReg != 0) 785 return GlobalBaseReg; 786 787 // Create the register. The code to initialize it is inserted later, 788 // by the M68kGlobalBaseReg pass (below). 789 // 790 // NOTE 791 // Normally M68k uses A5 register as global base pointer but this will 792 // create unnecessary spill if we use less then 4 registers in code; since A5 793 // is callee-save anyway we could try to allocate caller-save first and if 794 // lucky get one, otherwise it does not really matter which callee-save to 795 // use. 796 MachineRegisterInfo &RegInfo = MF->getRegInfo(); 797 GlobalBaseReg = RegInfo.createVirtualRegister(&M68k::AR32_NOSPRegClass); 798 MxFI->setGlobalBaseReg(GlobalBaseReg); 799 return GlobalBaseReg; 800 } 801 802 std::pair<unsigned, unsigned> 803 M68kInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const { 804 return std::make_pair(TF, 0u); 805 } 806 807 ArrayRef<std::pair<unsigned, const char *>> 808 M68kInstrInfo::getSerializableDirectMachineOperandTargetFlags() const { 809 using namespace M68kII; 810 static const std::pair<unsigned, const char *> TargetFlags[] = { 811 {MO_ABSOLUTE_ADDRESS, "m68k-absolute"}, 812 {MO_PC_RELATIVE_ADDRESS, "m68k-pcrel"}, 813 {MO_GOT, "m68k-got"}, 814 {MO_GOTOFF, "m68k-gotoff"}, 815 {MO_GOTPCREL, "m68k-gotpcrel"}, 816 {MO_PLT, "m68k-plt"}, 817 {MO_TLSGD, "m68k-tlsgd"}, 818 {MO_TLSLD, "m68k-tlsld"}, 819 {MO_TLSLDM, "m68k-tlsldm"}, 820 {MO_TLSIE, "m68k-tlsie"}, 821 {MO_TLSLE, "m68k-tlsle"}}; 822 return ArrayRef(TargetFlags); 823 } 824 825 #undef DEBUG_TYPE 826 #define DEBUG_TYPE "m68k-create-global-base-reg" 827 828 #define PASS_NAME "M68k PIC Global Base Reg Initialization" 829 830 namespace { 831 /// This initializes the PIC global base register 832 struct M68kGlobalBaseReg : public MachineFunctionPass { 833 static char ID; 834 M68kGlobalBaseReg() : MachineFunctionPass(ID) {} 835 836 bool runOnMachineFunction(MachineFunction &MF) override { 837 const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>(); 838 M68kMachineFunctionInfo *MxFI = MF.getInfo<M68kMachineFunctionInfo>(); 839 840 unsigned GlobalBaseReg = MxFI->getGlobalBaseReg(); 841 842 // If we didn't need a GlobalBaseReg, don't insert code. 843 if (GlobalBaseReg == 0) 844 return false; 845 846 // Insert the set of GlobalBaseReg into the first MBB of the function 847 MachineBasicBlock &FirstMBB = MF.front(); 848 MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 849 DebugLoc DL = FirstMBB.findDebugLoc(MBBI); 850 const M68kInstrInfo *TII = STI.getInstrInfo(); 851 852 // Generate lea (__GLOBAL_OFFSET_TABLE_,%PC), %A5 853 BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::LEA32q), GlobalBaseReg) 854 .addExternalSymbol("_GLOBAL_OFFSET_TABLE_", M68kII::MO_GOTPCREL); 855 856 return true; 857 } 858 859 void getAnalysisUsage(AnalysisUsage &AU) const override { 860 AU.setPreservesCFG(); 861 MachineFunctionPass::getAnalysisUsage(AU); 862 } 863 }; 864 char M68kGlobalBaseReg::ID = 0; 865 } // namespace 866 867 INITIALIZE_PASS(M68kGlobalBaseReg, DEBUG_TYPE, PASS_NAME, false, false) 868 869 FunctionPass *llvm::createM68kGlobalBaseRegPass() { 870 return new M68kGlobalBaseReg(); 871 } 872