1//===-- XCoreInstrInfo.cpp - XCore Instruction Information ----------------===// 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 7//===----------------------------------------------------------------------===// 9// This file contains the XCore implementation of the TargetInstrInfo class. 11//===----------------------------------------------------------------------===// 26#define GET_INSTRINFO_CTOR_DTOR 27#include "XCoreGenInstrInfo.inc" 32// XCore Condition Codes 41// Pin the vtable to this file. 42void XCoreInstrInfo::anchor() {}
50returnop.isImm() &&
op.getImm() == 0;
53/// isLoadFromStackSlot - If the specified machine instruction is a direct 54/// load from a stack slot, return the virtual or physical register number of 55/// the destination along with the FrameIndex of the loaded stack slot. If 56/// not, return 0. This predicate must return 0 if the instruction has 57/// any side effects other than loading from the stack slot. 59int &FrameIndex)
const{
60int Opcode =
MI.getOpcode();
61if (Opcode == XCore::LDWFI)
63if ((
MI.getOperand(1).isFI()) &&
// is a stack slot 64 (
MI.getOperand(2).isImm()) &&
// the imm is zero 66 FrameIndex =
MI.getOperand(1).getIndex();
67returnMI.getOperand(0).getReg();
73 /// isStoreToStackSlot - If the specified machine instruction is a direct 74 /// store to a stack slot, return the virtual or physical register number of 75 /// the source reg along with the FrameIndex of the loaded stack slot. If 76 /// not, return 0. This predicate must return 0 if the instruction has 77 /// any side effects other than storing to the stack slot. 79int &FrameIndex)
const{
80int Opcode =
MI.getOpcode();
81if (Opcode == XCore::STWFI)
83if ((
MI.getOperand(1).isFI()) &&
// is a stack slot 84 (
MI.getOperand(2).isImm()) &&
// the imm is zero 86 FrameIndex =
MI.getOperand(1).getIndex();
87returnMI.getOperand(0).getReg();
93//===----------------------------------------------------------------------===// 95//===----------------------------------------------------------------------===// 97staticinlineboolIsBRU(
unsigned BrOpc) {
98return BrOpc == XCore::BRFU_u6
99 || BrOpc == XCore::BRFU_lu6
100 || BrOpc == XCore::BRBU_u6
101 || BrOpc == XCore::BRBU_lu6;
104staticinlineboolIsBRT(
unsigned BrOpc) {
105return BrOpc == XCore::BRFT_ru6
106 || BrOpc == XCore::BRFT_lru6
107 || BrOpc == XCore::BRBT_ru6
108 || BrOpc == XCore::BRBT_lru6;
111staticinlineboolIsBRF(
unsigned BrOpc) {
112return BrOpc == XCore::BRFF_ru6
113 || BrOpc == XCore::BRFF_lru6
114 || BrOpc == XCore::BRBF_ru6
115 || BrOpc == XCore::BRBF_lru6;
123return BrOpc == XCore::BR_JT
124 || BrOpc == XCore::BR_JT32;
127/// GetCondFromBranchOpc - Return the XCore CC that matches 128/// the correspondent Branch instruction opcode. 133 }
elseif (
IsBRF(BrOpc)) {
140/// GetCondBranchFromCond - Return the Branch instruction 141/// opcode that matches the cc. 151/// GetOppositeBranchCondition - Return the inverse of the specified 152/// condition, e.g. turning COND_E to COND_NE. 162/// analyzeBranch - Analyze the branching code at the end of MBB, returning 163/// true if it cannot be understood (e.g. it's a switch dispatch or isn't 164/// implemented for a target). Upon success, this returns false and returns 165/// with the following information in various cases: 167/// 1. If this block ends with no branches (it just falls through to its succ) 168/// just return false, leaving TBB/FBB null. 169/// 2. If this block ends with only an unconditional branch, it sets TBB to be 170/// the destination block. 171/// 3. If this block ends with an conditional branch and it falls through to 172/// an successor block, it sets TBB to be the branch destination block and a 173/// list of operands that evaluate the condition. These 174/// operands can be passed to other TargetInstrInfo methods to create new 176/// 4. If this block ends with an conditional branch and an unconditional 177/// block, it returns the 'true' destination in TBB, the 'false' destination 178/// in FBB, and a list of operands that evaluate the condition. These 179/// operands can be passed to other TargetInstrInfo methods to create new 182/// Note that removeBranch and insertBranch must be implemented to support 183/// cases where this method returns success. 189bool AllowModify)
const{
190// If the block has no terminators, it just falls into the block after it. 195if (!isUnpredicatedTerminator(*
I))
198// Get the last instruction in the block. 201// If there is only one terminator instruction, process it. 202if (
I ==
MBB.
begin() || !isUnpredicatedTerminator(*--
I)) {
210returntrue;
// Can't handle indirect branch. 213// Block ends with fall-through condbranch. 221// Get the instruction before it if it's a terminator. 224// If there are three terminators, we don't know what sort of block this is. 225if (SecondLastInst &&
I !=
MBB.
begin() && isUnpredicatedTerminator(*--
I))
228unsigned SecondLastOpc = SecondLastInst->
getOpcode();
231// If the block ends with conditional branch followed by unconditional, 244// If the block ends with two unconditional branches, handle it. The second 245// one is not executed, so remove it. 255// Likewise if it ends with a branch table followed by an unconditional branch. 263// Otherwise, can't handle this. 272int *BytesAdded)
const{
273// Shouldn't be a fall through. 274assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
276"Unexpected number of components!");
277assert(!BytesAdded &&
"code size not handled");
279if (!FBB) {
// One way branch. 281// Unconditional branch 284// Conditional branch. 292// Two-way Conditional branch. 293assert(
Cond.size() == 2 &&
"Unexpected number of components!");
303assert(!BytesRemoved &&
"code size not handled");
331bool RenamableDest,
bool RenamableSrc)
const{
332bool GRDest = XCore::GRRegsRegClass.contains(DestReg);
333bool GRSrc = XCore::GRRegsRegClass.contains(SrcReg);
335if (GRDest && GRSrc) {
342if (GRDest && SrcReg == XCore::SP) {
347if (DestReg == XCore::SP && GRSrc) {
361if (
I !=
MBB.
end() && !
I->isDebugInstr())
384if (
I !=
MBB.
end() && !
I->isDebugInstr())
401"Invalid XCore branch condition!");
407return val < (1 << 6);
411return val < (1 << 16);
419return (
N >= 1 &&
N <= 8) ||
N == 16 ||
N == 24 ||
N == 32;
428 dl =
MI->getDebugLoc();
436int Opcode =
isImmU6(
Value) ? XCore::LDC_ru6 : XCore::LDC_lru6;
static bool isZeroImm(const MachineOperand &Op)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
unsigned const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC)
static bool isImmU16(unsigned val)
static bool isImmU6(unsigned val)
static XCore::CondCode GetCondFromBranchOpc(unsigned BrOpc)
GetCondFromBranchOpc - Return the XCore CC that matches the correspondent Branch instruction opcode.
static bool IsBRU(unsigned BrOpc)
static bool IsBR_JT(unsigned BrOpc)
static bool isImmMskBitp(unsigned val)
static bool IsBRT(unsigned BrOpc)
static bool IsBRF(unsigned BrOpc)
static bool IsCondBranch(unsigned BrOpc)
static unsigned GetCondBranchFromCond(XCore::CondCode CC)
GetCondBranchFromCond - Return the Branch instruction opcode that matches the cc.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
This is an important base class in LLVM.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Wrapper class representing physical registers. Should be passed by value.
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) 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 & addMemOperand(MachineMemOperand *MMO) const
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.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
MachineBasicBlock * getMBB() const
static MachineOperand CreateImm(int64_t Val)
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static IntegerType * getInt32Ty(LLVMContext &C)
LLVM Value Representation.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
analyzeBranch - Analyze the branching code at the end of MBB, returning true if it cannot be understo...
MachineBasicBlock::iterator loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, unsigned Reg, uint64_t Value) const
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
isLoadFromStackSlot - If the specified machine instruction is a direct load from a stack slot,...
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot,...
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
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.
constexpr bool isMask_32(uint32_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
unsigned getKillRegState(bool B)
This struct is a compact representation of a valid (non-zero power of two) alignment.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.