Path: blob/main/contrib/llvm-project/llvm/lib/Target/M68k/M68kInstrInfo.cpp
35266 views
//===-- M68kInstrInfo.cpp - M68k Instruction Information --------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7///8/// \file9/// This file contains the M68k declaration of the TargetInstrInfo class.10///11//===----------------------------------------------------------------------===//1213#include "M68kInstrInfo.h"1415#include "M68kInstrBuilder.h"16#include "M68kMachineFunction.h"17#include "M68kTargetMachine.h"18#include "MCTargetDesc/M68kMCCodeEmitter.h"1920#include "llvm/ADT/STLExtras.h"21#include "llvm/ADT/ScopeExit.h"22#include "llvm/CodeGen/LivePhysRegs.h"23#include "llvm/CodeGen/LiveVariables.h"24#include "llvm/CodeGen/MachineInstrBuilder.h"25#include "llvm/CodeGen/MachineRegisterInfo.h"26#include "llvm/MC/TargetRegistry.h"27#include "llvm/Support/ErrorHandling.h"28#include "llvm/Support/Regex.h"2930#include <functional>3132using namespace llvm;3334#define DEBUG_TYPE "M68k-instr-info"3536#define GET_INSTRINFO_CTOR_DTOR37#include "M68kGenInstrInfo.inc"3839// Pin the vtable to this file.40void M68kInstrInfo::anchor() {}4142M68kInstrInfo::M68kInstrInfo(const M68kSubtarget &STI)43: M68kGenInstrInfo(M68k::ADJCALLSTACKDOWN, M68k::ADJCALLSTACKUP, 0,44M68k::RET),45Subtarget(STI), RI(STI) {}4647static M68k::CondCode getCondFromBranchOpc(unsigned BrOpc) {48switch (BrOpc) {49default:50return M68k::COND_INVALID;51case M68k::Beq8:52return M68k::COND_EQ;53case M68k::Bne8:54return M68k::COND_NE;55case M68k::Blt8:56return M68k::COND_LT;57case M68k::Ble8:58return M68k::COND_LE;59case M68k::Bgt8:60return M68k::COND_GT;61case M68k::Bge8:62return M68k::COND_GE;63case M68k::Bcs8:64return M68k::COND_CS;65case M68k::Bls8:66return M68k::COND_LS;67case M68k::Bhi8:68return M68k::COND_HI;69case M68k::Bcc8:70return M68k::COND_CC;71case M68k::Bmi8:72return M68k::COND_MI;73case M68k::Bpl8:74return M68k::COND_PL;75case M68k::Bvs8:76return M68k::COND_VS;77case M68k::Bvc8:78return M68k::COND_VC;79}80}8182bool M68kInstrInfo::AnalyzeBranchImpl(MachineBasicBlock &MBB,83MachineBasicBlock *&TBB,84MachineBasicBlock *&FBB,85SmallVectorImpl<MachineOperand> &Cond,86bool AllowModify) const {8788auto UncondBranch =89std::pair<MachineBasicBlock::reverse_iterator, MachineBasicBlock *>{90MBB.rend(), nullptr};9192// Erase any instructions if allowed at the end of the scope.93std::vector<std::reference_wrapper<llvm::MachineInstr>> EraseList;94auto FinalizeOnReturn = llvm::make_scope_exit([&EraseList] {95std::for_each(EraseList.begin(), EraseList.end(),96[](auto &ref) { ref.get().eraseFromParent(); });97});9899// Start from the bottom of the block and work up, examining the100// terminator instructions.101for (auto iter = MBB.rbegin(); iter != MBB.rend(); iter = std::next(iter)) {102103unsigned Opcode = iter->getOpcode();104105if (iter->isDebugInstr())106continue;107108// Working from the bottom, when we see a non-terminator instruction, we're109// done.110if (!isUnpredicatedTerminator(*iter))111break;112113// A terminator that isn't a branch can't easily be handled by this114// analysis.115if (!iter->isBranch())116return true;117118// Handle unconditional branches.119if (Opcode == M68k::BRA8 || Opcode == M68k::BRA16) {120if (!iter->getOperand(0).isMBB())121return true;122UncondBranch = {iter, iter->getOperand(0).getMBB()};123124// TBB is used to indicate the unconditional destination.125TBB = UncondBranch.second;126127if (!AllowModify)128continue;129130// If the block has any instructions after a JMP, erase them.131EraseList.insert(EraseList.begin(), MBB.rbegin(), iter);132133Cond.clear();134FBB = nullptr;135136// Erase the JMP if it's equivalent to a fall-through.137if (MBB.isLayoutSuccessor(UncondBranch.second)) {138TBB = nullptr;139EraseList.push_back(*iter);140UncondBranch = {MBB.rend(), nullptr};141}142143continue;144}145146// Handle conditional branches.147auto BranchCode = M68k::GetCondFromBranchOpc(Opcode);148149// Can't handle indirect branch.150if (BranchCode == M68k::COND_INVALID)151return true;152153// In practice we should never have an undef CCR operand, if we do154// abort here as we are not prepared to preserve the flag.155// ??? Is this required?156// if (iter->getOperand(1).isUndef())157// return true;158159// Working from the bottom, handle the first conditional branch.160if (Cond.empty()) {161if (!iter->getOperand(0).isMBB())162return true;163MachineBasicBlock *CondBranchTarget = iter->getOperand(0).getMBB();164165// If we see something like this:166//167// bcc l1168// bra l2169// ...170// l1:171// ...172// l2:173if (UncondBranch.first != MBB.rend()) {174175assert(std::next(UncondBranch.first) == iter && "Wrong block layout.");176177// And we are allowed to modify the block and the target block of the178// conditional branch is the direct successor of this block:179//180// bcc l1181// bra l2182// l1:183// ...184// l2:185//186// we change it to this if allowed:187//188// bncc l2189// l1:190// ...191// l2:192//193// Which is a bit more efficient.194if (AllowModify && MBB.isLayoutSuccessor(CondBranchTarget)) {195196BranchCode = GetOppositeBranchCondition(BranchCode);197unsigned BNCC = GetCondBranchFromCond(BranchCode);198199BuildMI(MBB, *UncondBranch.first, MBB.rfindDebugLoc(iter), get(BNCC))200.addMBB(UncondBranch.second);201202EraseList.push_back(*iter);203EraseList.push_back(*UncondBranch.first);204205TBB = UncondBranch.second;206FBB = nullptr;207Cond.push_back(MachineOperand::CreateImm(BranchCode));208209// Otherwise preserve TBB, FBB and Cond as requested210} else {211TBB = CondBranchTarget;212FBB = UncondBranch.second;213Cond.push_back(MachineOperand::CreateImm(BranchCode));214}215216UncondBranch = {MBB.rend(), nullptr};217continue;218}219220TBB = CondBranchTarget;221FBB = nullptr;222Cond.push_back(MachineOperand::CreateImm(BranchCode));223224continue;225}226227// Handle subsequent conditional branches. Only handle the case where all228// conditional branches branch to the same destination and their condition229// opcodes fit one of the special multi-branch idioms.230assert(Cond.size() == 1);231assert(TBB);232233// If the conditions are the same, we can leave them alone.234auto OldBranchCode = static_cast<M68k::CondCode>(Cond[0].getImm());235if (!iter->getOperand(0).isMBB())236return true;237auto NewTBB = iter->getOperand(0).getMBB();238if (OldBranchCode == BranchCode && TBB == NewTBB)239continue;240241// If they differ we cannot do much here.242return true;243}244245return false;246}247248bool M68kInstrInfo::analyzeBranch(MachineBasicBlock &MBB,249MachineBasicBlock *&TBB,250MachineBasicBlock *&FBB,251SmallVectorImpl<MachineOperand> &Cond,252bool AllowModify) const {253return AnalyzeBranchImpl(MBB, TBB, FBB, Cond, AllowModify);254}255256unsigned M68kInstrInfo::removeBranch(MachineBasicBlock &MBB,257int *BytesRemoved) const {258assert(!BytesRemoved && "code size not handled");259260MachineBasicBlock::iterator I = MBB.end();261unsigned Count = 0;262263while (I != MBB.begin()) {264--I;265if (I->isDebugValue())266continue;267if (I->getOpcode() != M68k::BRA8 &&268getCondFromBranchOpc(I->getOpcode()) == M68k::COND_INVALID)269break;270// Remove the branch.271I->eraseFromParent();272I = MBB.end();273++Count;274}275276return Count;277}278279unsigned M68kInstrInfo::insertBranch(280MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,281ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {282// Shouldn't be a fall through.283assert(TBB && "InsertBranch must not be told to insert a fallthrough");284assert((Cond.size() == 1 || Cond.size() == 0) &&285"M68k branch conditions have one component!");286assert(!BytesAdded && "code size not handled");287288if (Cond.empty()) {289// Unconditional branch?290assert(!FBB && "Unconditional branch with multiple successors!");291BuildMI(&MBB, DL, get(M68k::BRA8)).addMBB(TBB);292return 1;293}294295// If FBB is null, it is implied to be a fall-through block.296bool FallThru = FBB == nullptr;297298// Conditional branch.299unsigned Count = 0;300M68k::CondCode CC = (M68k::CondCode)Cond[0].getImm();301unsigned Opc = GetCondBranchFromCond(CC);302BuildMI(&MBB, DL, get(Opc)).addMBB(TBB);303++Count;304if (!FallThru) {305// Two-way Conditional branch. Insert the second branch.306BuildMI(&MBB, DL, get(M68k::BRA8)).addMBB(FBB);307++Count;308}309return Count;310}311312void M68kInstrInfo::AddSExt(MachineBasicBlock &MBB,313MachineBasicBlock::iterator I, DebugLoc DL,314unsigned Reg, MVT From, MVT To) const {315if (From == MVT::i8) {316unsigned R = Reg;317// EXT16 requires i16 register318if (To == MVT::i32) {319R = RI.getSubReg(Reg, M68k::MxSubRegIndex16Lo);320assert(R && "No viable SUB register available");321}322BuildMI(MBB, I, DL, get(M68k::EXT16), R).addReg(R);323}324325if (To == MVT::i32)326BuildMI(MBB, I, DL, get(M68k::EXT32), Reg).addReg(Reg);327}328329void M68kInstrInfo::AddZExt(MachineBasicBlock &MBB,330MachineBasicBlock::iterator I, DebugLoc DL,331unsigned Reg, MVT From, MVT To) const {332333unsigned Mask, And;334if (From == MVT::i8)335Mask = 0xFF;336else337Mask = 0xFFFF;338339if (To == MVT::i16)340And = M68k::AND16di;341else // i32342And = M68k::AND32di;343344// TODO use xor r,r to decrease size345BuildMI(MBB, I, DL, get(And), Reg).addReg(Reg).addImm(Mask);346}347348// Convert MOVI to MOVQ if the target is a data register and the immediate349// fits in a sign-extended i8, otherwise emit a plain MOV.350bool M68kInstrInfo::ExpandMOVI(MachineInstrBuilder &MIB, MVT MVTSize) const {351Register Reg = MIB->getOperand(0).getReg();352int64_t Imm = MIB->getOperand(1).getImm();353bool IsAddressReg = false;354355const auto *DR32 = RI.getRegClass(M68k::DR32RegClassID);356const auto *AR32 = RI.getRegClass(M68k::AR32RegClassID);357const auto *AR16 = RI.getRegClass(M68k::AR16RegClassID);358359if (AR16->contains(Reg) || AR32->contains(Reg))360IsAddressReg = true;361362LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to ");363364if (MVTSize == MVT::i8 || (!IsAddressReg && Imm >= -128 && Imm <= 127)) {365LLVM_DEBUG(dbgs() << "MOVEQ\n");366367// We need to assign to the full register to make IV happy368Register SReg =369MVTSize == MVT::i32 ? Reg : Register(RI.getMatchingMegaReg(Reg, DR32));370assert(SReg && "No viable MEGA register available");371372MIB->setDesc(get(M68k::MOVQ));373MIB->getOperand(0).setReg(SReg);374} else {375LLVM_DEBUG(dbgs() << "MOVE\n");376MIB->setDesc(get(MVTSize == MVT::i16 ? M68k::MOV16ri : M68k::MOV32ri));377}378379return true;380}381382bool M68kInstrInfo::ExpandMOVX_RR(MachineInstrBuilder &MIB, MVT MVTDst,383MVT MVTSrc) const {384unsigned Move = MVTDst == MVT::i16 ? M68k::MOV16rr : M68k::MOV32rr;385Register Dst = MIB->getOperand(0).getReg();386Register Src = MIB->getOperand(1).getReg();387388assert(Dst != Src && "You cannot use the same Regs with MOVX_RR");389390const auto &TRI = getRegisterInfo();391392const auto *RCDst = TRI.getMaximalPhysRegClass(Dst, MVTDst);393const auto *RCSrc = TRI.getMaximalPhysRegClass(Src, MVTSrc);394395assert(RCDst && RCSrc && "Wrong use of MOVX_RR");396assert(RCDst != RCSrc && "You cannot use the same Reg Classes with MOVX_RR");397(void)RCSrc;398399// We need to find the super source register that matches the size of Dst400unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst);401assert(SSrc && "No viable MEGA register available");402403DebugLoc DL = MIB->getDebugLoc();404405// If it happens to that super source register is the destination register406// we do nothing407if (Dst == SSrc) {408LLVM_DEBUG(dbgs() << "Remove " << *MIB.getInstr() << '\n');409MIB->eraseFromParent();410} else { // otherwise we need to MOV411LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to MOV\n");412MIB->setDesc(get(Move));413MIB->getOperand(1).setReg(SSrc);414}415416return true;417}418419/// Expand SExt MOVE pseudos into a MOV and a EXT if the operands are two420/// different registers or just EXT if it is the same register421bool M68kInstrInfo::ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned,422MVT MVTDst, MVT MVTSrc) const {423LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to ");424425unsigned Move;426427if (MVTDst == MVT::i16)428Move = M68k::MOV16rr;429else // i32430Move = M68k::MOV32rr;431432Register Dst = MIB->getOperand(0).getReg();433Register Src = MIB->getOperand(1).getReg();434435assert(Dst != Src && "You cannot use the same Regs with MOVSX_RR");436437const auto &TRI = getRegisterInfo();438439const auto *RCDst = TRI.getMaximalPhysRegClass(Dst, MVTDst);440const auto *RCSrc = TRI.getMaximalPhysRegClass(Src, MVTSrc);441442assert(RCDst && RCSrc && "Wrong use of MOVSX_RR");443assert(RCDst != RCSrc && "You cannot use the same Reg Classes with MOVSX_RR");444(void)RCSrc;445446// We need to find the super source register that matches the size of Dst447unsigned SSrc = RI.getMatchingMegaReg(Src, RCDst);448assert(SSrc && "No viable MEGA register available");449450MachineBasicBlock &MBB = *MIB->getParent();451DebugLoc DL = MIB->getDebugLoc();452453if (Dst != SSrc) {454LLVM_DEBUG(dbgs() << "Move and " << '\n');455BuildMI(MBB, MIB.getInstr(), DL, get(Move), Dst).addReg(SSrc);456}457458if (IsSigned) {459LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');460AddSExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);461} else {462LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');463AddZExt(MBB, MIB.getInstr(), DL, Dst, MVTSrc, MVTDst);464}465466MIB->eraseFromParent();467468return true;469}470471bool M68kInstrInfo::ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned,472const MCInstrDesc &Desc, MVT MVTDst,473MVT MVTSrc) const {474LLVM_DEBUG(dbgs() << "Expand " << *MIB.getInstr() << " to LOAD and ");475476Register Dst = MIB->getOperand(0).getReg();477478// We need the subreg of Dst to make instruction verifier happy because the479// real machine instruction consumes and produces values of the same size and480// the registers the will be used here fall into different classes and this481// makes IV cry. We could use a bigger operation, but this will put some482// pressure on cache and memory, so no.483unsigned SubDst =484RI.getSubReg(Dst, MVTSrc == MVT::i8 ? M68k::MxSubRegIndex8Lo485: M68k::MxSubRegIndex16Lo);486assert(SubDst && "No viable SUB register available");487488// Make this a plain move489MIB->setDesc(Desc);490MIB->getOperand(0).setReg(SubDst);491492MachineBasicBlock::iterator I = MIB.getInstr();493I++;494MachineBasicBlock &MBB = *MIB->getParent();495DebugLoc DL = MIB->getDebugLoc();496497if (IsSigned) {498LLVM_DEBUG(dbgs() << "Sign Extend" << '\n');499AddSExt(MBB, I, DL, Dst, MVTSrc, MVTDst);500} else {501LLVM_DEBUG(dbgs() << "Zero Extend" << '\n');502AddZExt(MBB, I, DL, Dst, MVTSrc, MVTDst);503}504505return true;506}507508bool M68kInstrInfo::ExpandPUSH_POP(MachineInstrBuilder &MIB,509const MCInstrDesc &Desc, bool IsPush) const {510MachineBasicBlock::iterator I = MIB.getInstr();511I++;512MachineBasicBlock &MBB = *MIB->getParent();513MachineOperand MO = MIB->getOperand(0);514DebugLoc DL = MIB->getDebugLoc();515if (IsPush)516BuildMI(MBB, I, DL, Desc).addReg(RI.getStackRegister()).add(MO);517else518BuildMI(MBB, I, DL, Desc, MO.getReg()).addReg(RI.getStackRegister());519520MIB->eraseFromParent();521return true;522}523524bool M68kInstrInfo::ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const {525526// Replace the pseudo instruction with the real one527if (IsToCCR)528MIB->setDesc(get(M68k::MOV16cd));529else530// FIXME M68010 or later is required531MIB->setDesc(get(M68k::MOV16dc));532533// Promote used register to the next class534auto &Opd = MIB->getOperand(1);535Opd.setReg(getRegisterInfo().getMatchingSuperReg(536Opd.getReg(), M68k::MxSubRegIndex8Lo, &M68k::DR16RegClass));537538return true;539}540541bool M68kInstrInfo::ExpandMOVEM(MachineInstrBuilder &MIB,542const MCInstrDesc &Desc, bool IsRM) const {543int Reg = 0, Offset = 0, Base = 0;544auto XR32 = RI.getRegClass(M68k::XR32RegClassID);545auto DL = MIB->getDebugLoc();546auto MI = MIB.getInstr();547auto &MBB = *MIB->getParent();548549if (IsRM) {550Reg = MIB->getOperand(0).getReg();551Offset = MIB->getOperand(1).getImm();552Base = MIB->getOperand(2).getReg();553} else {554Offset = MIB->getOperand(0).getImm();555Base = MIB->getOperand(1).getReg();556Reg = MIB->getOperand(2).getReg();557}558559// If the register is not in XR32 then it is smaller than 32 bit, we560// implicitly promote it to 32561if (!XR32->contains(Reg)) {562Reg = RI.getMatchingMegaReg(Reg, XR32);563assert(Reg && "Has not meaningful MEGA register");564}565566unsigned Mask = 1 << RI.getSpillRegisterOrder(Reg);567if (IsRM) {568BuildMI(MBB, MI, DL, Desc)569.addImm(Mask)570.addImm(Offset)571.addReg(Base)572.addReg(Reg, RegState::ImplicitDefine)573.copyImplicitOps(*MIB);574} else {575BuildMI(MBB, MI, DL, Desc)576.addImm(Offset)577.addReg(Base)578.addImm(Mask)579.addReg(Reg, RegState::Implicit)580.copyImplicitOps(*MIB);581}582583MIB->eraseFromParent();584585return true;586}587588/// Expand a single-def pseudo instruction to a two-addr589/// instruction with two undef reads of the register being defined.590/// This is used for mapping:591/// %d0 = SETCS_C32d592/// to:593/// %d0 = SUBX32dd %d0<undef>, %d0<undef>594///595static bool Expand2AddrUndef(MachineInstrBuilder &MIB,596const MCInstrDesc &Desc) {597assert(Desc.getNumOperands() == 3 && "Expected two-addr instruction.");598Register Reg = MIB->getOperand(0).getReg();599MIB->setDesc(Desc);600601// MachineInstr::addOperand() will insert explicit operands before any602// implicit operands.603MIB.addReg(Reg, RegState::Undef).addReg(Reg, RegState::Undef);604// But we don't trust that.605assert(MIB->getOperand(1).getReg() == Reg &&606MIB->getOperand(2).getReg() == Reg && "Misplaced operand");607return true;608}609610bool M68kInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {611MachineInstrBuilder MIB(*MI.getParent()->getParent(), MI);612switch (MI.getOpcode()) {613case M68k::PUSH8d:614return ExpandPUSH_POP(MIB, get(M68k::MOV8ed), true);615case M68k::PUSH16d:616return ExpandPUSH_POP(MIB, get(M68k::MOV16er), true);617case M68k::PUSH32r:618return ExpandPUSH_POP(MIB, get(M68k::MOV32er), true);619620case M68k::POP8d:621return ExpandPUSH_POP(MIB, get(M68k::MOV8do), false);622case M68k::POP16d:623return ExpandPUSH_POP(MIB, get(M68k::MOV16ro), false);624case M68k::POP32r:625return ExpandPUSH_POP(MIB, get(M68k::MOV32ro), false);626627case M68k::SETCS_C8d:628return Expand2AddrUndef(MIB, get(M68k::SUBX8dd));629case M68k::SETCS_C16d:630return Expand2AddrUndef(MIB, get(M68k::SUBX16dd));631case M68k::SETCS_C32d:632return Expand2AddrUndef(MIB, get(M68k::SUBX32dd));633}634return false;635}636637bool M68kInstrInfo::isPCRelRegisterOperandLegal(638const MachineOperand &MO) const {639assert(MO.isReg());640641// Check whether this MO belongs to an instruction with addressing mode 'k',642// Refer to TargetInstrInfo.h for more information about this function.643644const MachineInstr *MI = MO.getParent();645const unsigned NameIndices = M68kInstrNameIndices[MI->getOpcode()];646StringRef InstrName(&M68kInstrNameData[NameIndices]);647const unsigned OperandNo = MO.getOperandNo();648649// If this machine operand is the 2nd operand, then check650// whether the instruction has destination addressing mode 'k'.651if (OperandNo == 1)652return Regex("[A-Z]+(8|16|32)k[a-z](_TC)?$").match(InstrName);653654// If this machine operand is the last one, then check655// whether the instruction has source addressing mode 'k'.656if (OperandNo == MI->getNumExplicitOperands() - 1)657return Regex("[A-Z]+(8|16|32)[a-z]k(_TC)?$").match(InstrName);658659return false;660}661662void M68kInstrInfo::copyPhysReg(MachineBasicBlock &MBB,663MachineBasicBlock::iterator MI,664const DebugLoc &DL, MCRegister DstReg,665MCRegister SrcReg, bool KillSrc) const {666unsigned Opc = 0;667668// First deal with the normal symmetric copies.669if (M68k::XR32RegClass.contains(DstReg, SrcReg))670Opc = M68k::MOV32rr;671else if (M68k::XR16RegClass.contains(DstReg, SrcReg))672Opc = M68k::MOV16rr;673else if (M68k::DR8RegClass.contains(DstReg, SrcReg))674Opc = M68k::MOV8dd;675676if (Opc) {677BuildMI(MBB, MI, DL, get(Opc), DstReg)678.addReg(SrcReg, getKillRegState(KillSrc));679return;680}681682// Now deal with asymmetrically sized copies. The cases that follow are upcast683// moves.684//685// NOTE686// These moves are not aware of type nature of these values and thus687// won't do any SExt or ZExt and upper bits will basically contain garbage.688MachineInstrBuilder MIB(*MBB.getParent(), MI);689if (M68k::DR8RegClass.contains(SrcReg)) {690if (M68k::XR16RegClass.contains(DstReg))691Opc = M68k::MOVXd16d8;692else if (M68k::XR32RegClass.contains(DstReg))693Opc = M68k::MOVXd32d8;694} else if (M68k::XR16RegClass.contains(SrcReg) &&695M68k::XR32RegClass.contains(DstReg))696Opc = M68k::MOVXd32d16;697698if (Opc) {699BuildMI(MBB, MI, DL, get(Opc), DstReg)700.addReg(SrcReg, getKillRegState(KillSrc));701return;702}703704bool FromCCR = SrcReg == M68k::CCR;705bool FromSR = SrcReg == M68k::SR;706bool ToCCR = DstReg == M68k::CCR;707bool ToSR = DstReg == M68k::SR;708709if (FromCCR) {710assert(M68k::DR8RegClass.contains(DstReg) &&711"Need DR8 register to copy CCR");712Opc = M68k::MOV8dc;713} else if (ToCCR) {714assert(M68k::DR8RegClass.contains(SrcReg) &&715"Need DR8 register to copy CCR");716Opc = M68k::MOV8cd;717} else if (FromSR || ToSR)718llvm_unreachable("Cannot emit SR copy instruction");719720if (Opc) {721BuildMI(MBB, MI, DL, get(Opc), DstReg)722.addReg(SrcReg, getKillRegState(KillSrc));723return;724}725726LLVM_DEBUG(dbgs() << "Cannot copy " << RI.getName(SrcReg) << " to "727<< RI.getName(DstReg) << '\n');728llvm_unreachable("Cannot emit physreg copy instruction");729}730731namespace {732unsigned getLoadStoreRegOpcode(unsigned Reg, const TargetRegisterClass *RC,733const TargetRegisterInfo *TRI,734const M68kSubtarget &STI, bool load) {735switch (TRI->getRegSizeInBits(*RC)) {736default:737llvm_unreachable("Unknown spill size");738case 8:739if (M68k::DR8RegClass.hasSubClassEq(RC))740return load ? M68k::MOV8dp : M68k::MOV8pd;741if (M68k::CCRCRegClass.hasSubClassEq(RC))742return load ? M68k::MOV16cp : M68k::MOV16pc;743744llvm_unreachable("Unknown 1-byte regclass");745case 16:746assert(M68k::XR16RegClass.hasSubClassEq(RC) && "Unknown 2-byte regclass");747return load ? M68k::MOVM16mp_P : M68k::MOVM16pm_P;748case 32:749assert(M68k::XR32RegClass.hasSubClassEq(RC) && "Unknown 4-byte regclass");750return load ? M68k::MOVM32mp_P : M68k::MOVM32pm_P;751}752}753754unsigned getStoreRegOpcode(unsigned SrcReg, const TargetRegisterClass *RC,755const TargetRegisterInfo *TRI,756const M68kSubtarget &STI) {757return getLoadStoreRegOpcode(SrcReg, RC, TRI, STI, false);758}759760unsigned getLoadRegOpcode(unsigned DstReg, const TargetRegisterClass *RC,761const TargetRegisterInfo *TRI,762const M68kSubtarget &STI) {763return getLoadStoreRegOpcode(DstReg, RC, TRI, STI, true);764}765} // end anonymous namespace766767bool M68kInstrInfo::getStackSlotRange(const TargetRegisterClass *RC,768unsigned SubIdx, unsigned &Size,769unsigned &Offset,770const MachineFunction &MF) const {771// The slot size must be the maximum size so we can easily use MOVEM.L772Size = 4;773Offset = 0;774return true;775}776777void M68kInstrInfo::storeRegToStackSlot(778MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg,779bool IsKill, int FrameIndex, const TargetRegisterClass *RC,780const TargetRegisterInfo *TRI, Register VReg) const {781const MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();782assert(MFI.getObjectSize(FrameIndex) >= TRI->getSpillSize(*RC) &&783"Stack slot is too small to store");784(void)MFI;785786unsigned Opc = getStoreRegOpcode(SrcReg, RC, TRI, Subtarget);787DebugLoc DL = MBB.findDebugLoc(MI);788// (0,FrameIndex) <- $reg789M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc)), FrameIndex)790.addReg(SrcReg, getKillRegState(IsKill));791}792793void M68kInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,794MachineBasicBlock::iterator MI,795Register DstReg, int FrameIndex,796const TargetRegisterClass *RC,797const TargetRegisterInfo *TRI,798Register VReg) const {799const MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();800assert(MFI.getObjectSize(FrameIndex) >= TRI->getSpillSize(*RC) &&801"Stack slot is too small to load");802(void)MFI;803804unsigned Opc = getLoadRegOpcode(DstReg, RC, TRI, Subtarget);805DebugLoc DL = MBB.findDebugLoc(MI);806M68k::addFrameReference(BuildMI(MBB, MI, DL, get(Opc), DstReg), FrameIndex);807}808809/// Return a virtual register initialized with the global base register810/// value. Output instructions required to initialize the register in the811/// function entry block, if necessary.812///813/// TODO Move this function to M68kMachineFunctionInfo.814unsigned M68kInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {815M68kMachineFunctionInfo *MxFI = MF->getInfo<M68kMachineFunctionInfo>();816unsigned GlobalBaseReg = MxFI->getGlobalBaseReg();817if (GlobalBaseReg != 0)818return GlobalBaseReg;819820// Create the register. The code to initialize it is inserted later,821// by the M68kGlobalBaseReg pass (below).822//823// NOTE824// Normally M68k uses A5 register as global base pointer but this will825// create unnecessary spill if we use less then 4 registers in code; since A5826// is callee-save anyway we could try to allocate caller-save first and if827// lucky get one, otherwise it does not really matter which callee-save to828// use.829MachineRegisterInfo &RegInfo = MF->getRegInfo();830GlobalBaseReg = RegInfo.createVirtualRegister(&M68k::AR32_NOSPRegClass);831MxFI->setGlobalBaseReg(GlobalBaseReg);832return GlobalBaseReg;833}834835std::pair<unsigned, unsigned>836M68kInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {837return std::make_pair(TF, 0u);838}839840ArrayRef<std::pair<unsigned, const char *>>841M68kInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {842using namespace M68kII;843static const std::pair<unsigned, const char *> TargetFlags[] = {844{MO_ABSOLUTE_ADDRESS, "m68k-absolute"},845{MO_PC_RELATIVE_ADDRESS, "m68k-pcrel"},846{MO_GOT, "m68k-got"},847{MO_GOTOFF, "m68k-gotoff"},848{MO_GOTPCREL, "m68k-gotpcrel"},849{MO_PLT, "m68k-plt"},850{MO_TLSGD, "m68k-tlsgd"},851{MO_TLSLD, "m68k-tlsld"},852{MO_TLSLDM, "m68k-tlsldm"},853{MO_TLSIE, "m68k-tlsie"},854{MO_TLSLE, "m68k-tlsle"}};855return ArrayRef(TargetFlags);856}857858#undef DEBUG_TYPE859#define DEBUG_TYPE "m68k-create-global-base-reg"860861#define PASS_NAME "M68k PIC Global Base Reg Initialization"862863namespace {864/// This initializes the PIC global base register865struct M68kGlobalBaseReg : public MachineFunctionPass {866static char ID;867M68kGlobalBaseReg() : MachineFunctionPass(ID) {}868869bool runOnMachineFunction(MachineFunction &MF) override {870const M68kSubtarget &STI = MF.getSubtarget<M68kSubtarget>();871M68kMachineFunctionInfo *MxFI = MF.getInfo<M68kMachineFunctionInfo>();872873unsigned GlobalBaseReg = MxFI->getGlobalBaseReg();874875// If we didn't need a GlobalBaseReg, don't insert code.876if (GlobalBaseReg == 0)877return false;878879// Insert the set of GlobalBaseReg into the first MBB of the function880MachineBasicBlock &FirstMBB = MF.front();881MachineBasicBlock::iterator MBBI = FirstMBB.begin();882DebugLoc DL = FirstMBB.findDebugLoc(MBBI);883const M68kInstrInfo *TII = STI.getInstrInfo();884885// Generate lea (__GLOBAL_OFFSET_TABLE_,%PC), %A5886BuildMI(FirstMBB, MBBI, DL, TII->get(M68k::LEA32q), GlobalBaseReg)887.addExternalSymbol("_GLOBAL_OFFSET_TABLE_", M68kII::MO_GOTPCREL);888889return true;890}891892void getAnalysisUsage(AnalysisUsage &AU) const override {893AU.setPreservesCFG();894MachineFunctionPass::getAnalysisUsage(AU);895}896};897char M68kGlobalBaseReg::ID = 0;898} // namespace899900INITIALIZE_PASS(M68kGlobalBaseReg, DEBUG_TYPE, PASS_NAME, false, false)901902FunctionPass *llvm::createM68kGlobalBaseRegPass() {903return new M68kGlobalBaseReg();904}905906907