37#define DEBUG_TYPE "M68k-instr-info"
39#define GET_INSTRINFO_CTOR_DTOR
40#include "M68kGenInstrInfo.inc"
43void M68kInstrInfo::anchor() {}
48 Subtarget(STI), RI(STI) {}
89 bool AllowModify)
const {
92 std::pair<MachineBasicBlock::reverse_iterator, MachineBasicBlock *>{
96 std::vector<std::reference_wrapper<llvm::MachineInstr>> EraseList;
98 std::for_each(EraseList.begin(), EraseList.end(),
99 [](
auto &ref) { ref.get().eraseFromParent(); });
104 for (
auto iter =
MBB.
rbegin(); iter !=
MBB.
rend(); iter = std::next(iter)) {
106 unsigned Opcode = iter->getOpcode();
108 if (iter->isDebugInstr())
113 if (!isUnpredicatedTerminator(*iter))
118 if (!iter->isBranch())
122 if (Opcode == M68k::BRA8 || Opcode == M68k::BRA16) {
123 if (!iter->getOperand(0).isMBB())
125 UncondBranch = {iter, iter->getOperand(0).getMBB()};
128 TBB = UncondBranch.second;
143 UncondBranch = {
MBB.
rend(),
nullptr};
164 if (!iter->getOperand(0).isMBB())
176 if (UncondBranch.first !=
MBB.
rend()) {
178 assert(std::next(UncondBranch.first) == iter &&
"Wrong block layout.");
203 .
addMBB(UncondBranch.second);
205 EraseList.push_back(*iter);
206 EraseList.push_back(*UncondBranch.first);
208 TBB = UncondBranch.second;
214 TBB = CondBranchTarget;
215 FBB = UncondBranch.second;
219 UncondBranch = {
MBB.
rend(),
nullptr};
223 TBB = CondBranchTarget;
238 if (!iter->getOperand(0).isMBB())
240 auto NewTBB = iter->getOperand(0).getMBB();
241 if (OldBranchCode == BranchCode &&
TBB == NewTBB)
255 bool AllowModify)
const {
260 int *BytesRemoved)
const {
261 assert(!BytesRemoved &&
"code size not handled");
268 if (
I->isDebugValue())
270 if (
I->getOpcode() != M68k::BRA8 &&
274 I->eraseFromParent();
286 assert(
TBB &&
"InsertBranch must not be told to insert a fallthrough");
288 "M68k branch conditions have one component!");
289 assert(!BytesAdded &&
"code size not handled");
293 assert(!FBB &&
"Unconditional branch with multiple successors!");
299 bool FallThru = FBB ==
nullptr;
318 if (
From == MVT::i8) {
321 if (To == MVT::i32) {
322 R =
RI.getSubReg(Reg, M68k::MxSubRegIndex16Lo);
323 assert(R &&
"No viable SUB register available");
356 bool IsAddressReg =
false;
358 const auto *DR32 =
RI.getRegClass(M68k::DR32RegClassID);
359 const auto *AR32 =
RI.getRegClass(M68k::AR32RegClassID);
360 const auto *AR16 =
RI.getRegClass(M68k::AR16RegClassID);
362 if (AR16->contains(Reg) || AR32->contains(Reg))
370 assert(SReg &&
"No viable MEGA register available");
375 if (MVTSize == MVT::i8 || (!IsAddressReg && Imm >= -128 && Imm <= 127)) {
383 }
else if (DR32->contains(Reg) && isUInt<8>(Imm)) {
389 unsigned SubReg =
RI.getSubReg(Reg, M68k::MxSubRegIndex8Lo);
398 }
else if (IsAddressReg && Imm == 0) {
415 }
else if (AR32->contains(Reg) && isUInt<16>(Imm)) {
418 unsigned SubReg =
RI.getSubReg(Reg, M68k::MxSubRegIndex16Lo);
427 MIB->
setDesc(
get(MVTSize == MVT::i16 ? M68k::MOV16ri : M68k::MOV32ri));
435 unsigned Move = MVTDst == MVT::i16 ? M68k::MOV16rr : M68k::MOV32rr;
439 assert(Dst != Src &&
"You cannot use the same Regs with MOVX_RR");
443 const auto *RCDst =
TRI.getMaximalPhysRegClass(Dst, MVTDst);
444 const auto *RCSrc =
TRI.getMaximalPhysRegClass(Src, MVTSrc);
446 assert(RCDst && RCSrc &&
"Wrong use of MOVX_RR");
447 assert(RCDst != RCSrc &&
"You cannot use the same Reg Classes with MOVX_RR");
452 assert(SSrc &&
"No viable MEGA register available");
473 MVT MVTDst,
MVT MVTSrc)
const {
478 if (MVTDst == MVT::i16)
479 Move = M68k::MOV16rr;
481 Move = M68k::MOV32rr;
486 assert(Dst != Src &&
"You cannot use the same Regs with MOVSX_RR");
490 const auto *RCDst =
TRI.getMaximalPhysRegClass(Dst, MVTDst);
491 const auto *RCSrc =
TRI.getMaximalPhysRegClass(Src, MVTSrc);
493 assert(RCDst && RCSrc &&
"Wrong use of MOVSX_RR");
494 assert(RCDst != RCSrc &&
"You cannot use the same Reg Classes with MOVSX_RR");
499 assert(SSrc &&
"No viable MEGA register available");
535 RI.getSubReg(Dst, MVTSrc == MVT::i8 ? M68k::MxSubRegIndex8Lo
536 : M68k::MxSubRegIndex16Lo);
537 assert(SubDst &&
"No viable SUB register available");
580 Opd.
getReg(), M68k::MxSubRegIndex8Lo, &M68k::DR16RegClass));
596 auto XR32 =
RI.getRegClass(M68k::XR32RegClassID);
613 if (!XR32->contains(Reg)) {
615 assert(Reg &&
"Has not meaningful MEGA register");
649 assert(
Desc.getNumOperands() == 3 &&
"Expected two-addr instruction.");
664 switch (
MI.getOpcode()) {
679 case M68k::SETCS_C8d:
681 case M68k::SETCS_C16d:
683 case M68k::SETCS_C32d:
697 const unsigned NameIndices = M68kInstrNameIndices[
MI->getOpcode()];
698 StringRef InstrName(&M68kInstrNameData[NameIndices]);
704 return Regex(
"[A-Z]+(8|16|32)k[a-z](_TC)?$").
match(InstrName);
708 if (OperandNo ==
MI->getNumExplicitOperands() - 1)
709 return Regex(
"[A-Z]+(8|16|32)[a-z]k(_TC)?$").
match(InstrName);
718 bool RenamableDest,
bool RenamableSrc)
const {
722 if (M68k::XR32RegClass.
contains(DstReg, SrcReg))
724 else if (M68k::XR16RegClass.
contains(DstReg, SrcReg))
726 else if (M68k::DR8RegClass.
contains(DstReg, SrcReg))
742 if (M68k::DR8RegClass.
contains(SrcReg)) {
743 if (M68k::XR16RegClass.
contains(DstReg))
744 Opc = M68k::MOVXd16d8;
745 else if (M68k::XR32RegClass.
contains(DstReg))
746 Opc = M68k::MOVXd32d8;
747 }
else if (M68k::XR16RegClass.
contains(SrcReg) &&
748 M68k::XR32RegClass.
contains(DstReg))
749 Opc = M68k::MOVXd32d16;
757 bool FromCCR = SrcReg == M68k::CCR;
758 bool FromSR = SrcReg == M68k::SR;
759 bool ToCCR = DstReg == M68k::CCR;
760 bool ToSR = DstReg == M68k::SR;
763 if (M68k::DR8RegClass.
contains(DstReg)) {
765 }
else if (M68k::DR16RegClass.
contains(DstReg)) {
767 }
else if (M68k::DR32RegClass.
contains(DstReg)) {
774 if (M68k::DR8RegClass.
contains(SrcReg)) {
776 }
else if (M68k::DR16RegClass.
contains(SrcReg)) {
778 }
else if (M68k::DR32RegClass.
contains(SrcReg)) {
784 }
else if (FromSR || ToSR)
794 <<
RI.getName(DstReg) <<
'\n');
802 switch (
TRI->getRegSizeInBits(*RC)) {
806 if (M68k::DR8RegClass.hasSubClassEq(RC))
807 return load ? M68k::MOV8dp : M68k::MOV8pd;
808 if (M68k::CCRCRegClass.hasSubClassEq(RC))
809 return load ? M68k::MOV16cp : M68k::MOV16pc;
813 assert(M68k::XR16RegClass.hasSubClassEq(RC) &&
"Unknown 2-byte regclass");
814 return load ? M68k::MOVM16mp_P : M68k::MOVM16pm_P;
816 assert(M68k::XR32RegClass.hasSubClassEq(RC) &&
"Unknown 4-byte regclass");
817 return load ? M68k::MOVM32mp_P : M68k::MOVM32pm_P;
835 unsigned SubIdx,
unsigned &
Size,
850 "Stack slot is too small to store");
868 "Stack slot is too small to load");
884 if (GlobalBaseReg != 0)
885 return GlobalBaseReg;
899 return GlobalBaseReg;
902std::pair<unsigned, unsigned>
904 return std::make_pair(TF, 0u);
909 using namespace M68kII;
910 static const std::pair<unsigned, const char *> TargetFlags[] = {
911 {MO_ABSOLUTE_ADDRESS,
"m68k-absolute"},
912 {MO_PC_RELATIVE_ADDRESS,
"m68k-pcrel"},
913 {MO_GOT,
"m68k-got"},
914 {MO_GOTOFF,
"m68k-gotoff"},
915 {MO_GOTPCREL,
"m68k-gotpcrel"},
916 {MO_PLT,
"m68k-plt"},
917 {MO_TLSGD,
"m68k-tlsgd"},
918 {MO_TLSLD,
"m68k-tlsld"},
919 {MO_TLSLDM,
"m68k-tlsldm"},
920 {MO_TLSIE,
"m68k-tlsie"},
921 {MO_TLSLE,
"m68k-tlsle"}};
926#define DEBUG_TYPE "m68k-create-global-base-reg"
928#define PASS_NAME "M68k PIC Global Base Reg Initialization"
940 unsigned GlobalBaseReg = MxFI->getGlobalBaseReg();
943 if (GlobalBaseReg == 0)
964char M68kGlobalBaseReg::ID = 0;
970 return new M68kGlobalBaseReg();
AMDGPU Mark last scratch load
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
BlockVerifier::State From
const HexagonInstrInfo * TII
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.
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC)
static unsigned getStoreRegOpcode(Register SrcReg, const TargetRegisterClass *RC, bool IsStackAligned, const X86Subtarget &STI)
static unsigned getLoadRegOpcode(Register DestReg, const TargetRegisterClass *RC, bool IsStackAligned, const X86Subtarget &STI)
static unsigned getLoadStoreRegOpcode(Register Reg, const TargetRegisterClass *RC, bool IsStackAligned, const X86Subtarget &STI, bool Load)
static unsigned GetCondBranchFromCond(XCore::CondCode CC)
GetCondBranchFromCond - Return the Branch instruction opcode that matches the cc.
Represent the analysis usage information of a pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
FunctionPass class - This class is used to implement most global optimizations.
unsigned getGlobalBaseReg(MachineFunction *MF) const
Return a virtual register initialized with the global base register value.
const M68kSubtarget & Subtarget
bool ExpandMOVI(MachineInstrBuilder &MIB, MVT MVTSize) const
Move immediate to register.
bool ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned, MVT MVTDst, MVT MVTSrc) const
Move from register and extend.
const M68kRegisterInfo & getRegisterInfo() const
TargetInstrInfo is a superset of MRegister info.
const M68kRegisterInfo RI
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override
bool expandPostRAPseudo(MachineInstr &MI) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override
bool AnalyzeBranchImpl(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const
bool isPCRelRegisterOperandLegal(const MachineOperand &MO) const override
bool ExpandMOVX_RR(MachineInstrBuilder &MIB, MVT MVTDst, MVT MVTSrc) const
Move across register classes without extension.
bool ExpandMOVEM(MachineInstrBuilder &MIB, const MCInstrDesc &Desc, bool IsRM) const
Expand all MOVEM pseudos into real MOVEMs.
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
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 ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const
Moves to/from CCR.
bool ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned, const MCInstrDesc &Desc, MVT MVTDst, MVT MVTSrc) const
Move from memory and extend.
bool getStackSlotRange(const TargetRegisterClass *RC, unsigned SubIdx, unsigned &Size, unsigned &Offset, const MachineFunction &MF) const override
void AddSExt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned Reg, MVT From, MVT To) const
Add appropriate SExt nodes.
void setGlobalBaseReg(unsigned Reg)
unsigned getGlobalBaseReg() const
unsigned getMatchingMegaReg(unsigned Reg, const TargetRegisterClass *RC) const
Return a mega-register of the specified register Reg so its sub-register of index SubIdx is Reg,...
int getSpillRegisterOrder(unsigned Reg) const
Return spill order index of a register, if there is none then trap.
unsigned getStackRegister() const
const M68kInstrInfo * getInstrInfo() const override
Describe properties that are true of each instruction in the target description file.
Wrapper class representing physical registers. Should be passed by value.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
void push_back(MachineInstr *MI)
DebugLoc rfindDebugLoc(reverse_instr_iterator MBBI)
Has exact same behavior as findDebugLoc (it also searches towards the end of this MBB) except that th...
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
reverse_iterator rbegin()
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
MachineInstr * removeFromParent()
Unlink 'this' from the containing basic block, and return it without deleting it.
const MachineBasicBlock * getParent() const
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.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
unsigned getOperandNo() const
Returns the index of this operand in the instruction that it belongs to.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setReg(Register Reg)
Change the register this operand corresponds to.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
bool match(StringRef String, SmallVectorImpl< StringRef > *Matches=nullptr, std::string *Error=nullptr) const
matches - Match the regex against a given String.
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
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.
@ MO_GOTPCREL
On a symbol operand this indicates that the immediate is offset to the GOT entry for the symbol name ...
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
static M68k::CondCode GetCondFromBranchOpc(unsigned Opcode)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Undef
Value of the register doesn't matter.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
FunctionPass * createM68kGlobalBaseRegPass()
This pass initializes a global base register for PIC on M68k.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
@ And
Bitwise or logical AND of integers.
unsigned getKillRegState(bool B)
Description of the encoding of one expression Op.