25#define GET_INSTRINFO_CTOR_DTOR
26#include "XtensaGenInstrInfo.inc"
56 int &FrameIndex)
const {
57 if (
MI.getOpcode() == Xtensa::L32I) {
58 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
59 MI.getOperand(2).getImm() == 0) {
60 FrameIndex =
MI.getOperand(1).getIndex();
61 return MI.getOperand(0).getReg();
68 int &FrameIndex)
const {
69 if (
MI.getOpcode() == Xtensa::S32I) {
70 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
71 MI.getOperand(2).getImm() == 0) {
72 FrameIndex =
MI.getOperand(1).getIndex();
73 return MI.getOperand(0).getReg();
92 MCRegister Reg = RegInfo.createVirtualRegister(RC);
104 if (STI.isWindowedABI()) {
117 bool RenamableDest,
bool RenamableSrc)
const {
122 if (Xtensa::ARRegClass.
contains(DestReg, SrcReg)) {
129 if (STI.hasSingleFloat() && Xtensa::FPRRegClass.contains(SrcReg) &&
130 Xtensa::FPRRegClass.contains(DestReg))
131 Opcode = Xtensa::MOV_S;
132 else if (STI.hasSingleFloat() && Xtensa::FPRRegClass.contains(SrcReg) &&
133 Xtensa::ARRegClass.contains(DestReg))
134 Opcode = Xtensa::RFR;
135 else if (STI.hasSingleFloat() && Xtensa::ARRegClass.contains(SrcReg) &&
136 Xtensa::FPRRegClass.contains(DestReg))
137 Opcode = Xtensa::WFR;
151 unsigned LoadOpcode, StoreOpcode;
165 unsigned LoadOpcode, StoreOpcode;
171 unsigned &LoadOpcode,
172 unsigned &StoreOpcode,
173 int64_t offset)
const {
174 if (RC == &Xtensa::ARRegClass) {
175 LoadOpcode = Xtensa::L32I;
176 StoreOpcode = Xtensa::S32I;
177 }
else if (RC == &Xtensa::FPRRegClass) {
178 LoadOpcode = Xtensa::LSI;
179 StoreOpcode = Xtensa::SSI;
193 *Reg = RegInfo.createVirtualRegister(RC);
196 }
else if (
Value >= -32768 &&
Value <= 32767) {
202 }
else if (
Value >= -4294967296LL &&
Value <= 4294967295LL) {
206 const Constant *CVal = ConstantInt::get(
220 switch (
MI.getOpcode()) {
221 case TargetOpcode::INLINEASM: {
223 const char *AsmStr =
MI.getOperand(0).getSymbolName();
227 return MI.getDesc().getSize();
233 assert(
Cond.size() <= 4 &&
"Invalid branch condition!");
237 Cond[0].setImm(Xtensa::BNE);
240 Cond[0].setImm(Xtensa::BEQ);
243 Cond[0].setImm(Xtensa::BGE);
246 Cond[0].setImm(Xtensa::BLT);
249 Cond[0].setImm(Xtensa::BGEU);
252 Cond[0].setImm(Xtensa::BLTU);
255 Cond[0].setImm(Xtensa::BNEI);
258 Cond[0].setImm(Xtensa::BEQI);
261 Cond[0].setImm(Xtensa::BLTI);
264 Cond[0].setImm(Xtensa::BGEI);
267 Cond[0].setImm(Xtensa::BLTUI);
270 Cond[0].setImm(Xtensa::BGEUI);
273 Cond[0].setImm(Xtensa::BNEZ);
276 Cond[0].setImm(Xtensa::BEQZ);
279 Cond[0].setImm(Xtensa::BGEZ);
282 Cond[0].setImm(Xtensa::BLTZ);
285 Cond[0].setImm(Xtensa::BT);
288 Cond[0].setImm(Xtensa::BF);
297 unsigned OpCode =
MI.getOpcode();
303 return MI.getOperand(0).getMBB();
310 return MI.getOperand(2).getMBB();
317 return MI.getOperand(2).getMBB();
322 return MI.getOperand(1).getMBB();
325 return MI.getOperand(1).getMBB();
332 int64_t BrOffset)
const {
336 return isIntN(18, BrOffset);
354 return isIntN(8, BrOffset);
360 return isIntN(12, BrOffset);
364 return isIntN(8, BrOffset);
374 bool AllowModify =
false)
const {
380 while (
I !=
MBB.begin()) {
382 if (
I->isDebugValue())
387 if (!isUnpredicatedTerminator(*
I))
399 if (!ThisTarget->
isMBB())
402 if (ThisCond[0].
getImm() == Xtensa::J) {
410 while (std::next(
I) !=
MBB.end())
411 std::next(
I)->eraseFromParent();
429 for (
unsigned int i = 0; i < (
I->getNumExplicitOperands() - 1); i++)
430 Cond.push_back(
I->getOperand(i));
445 unsigned OldCond =
Cond[0].getImm();
446 if (OldCond == ThisCond[0].
getImm())
454 int *BytesRemoved)
const {
461 while (
I !=
MBB.begin()) {
473 I->eraseFromParent();
507 assert(RS &&
"RegScavenger required for long branching");
509 "new block should be inserted for expanding unconditional branch");
520 "Branch offsets outside of the signed 32-bit range not supported");
522 Register ScratchReg =
MRI.createVirtualRegister(&Xtensa::ARRegClass);
530 RS->enterBasicBlockEnd(
MBB);
532 RS->scavengeRegisterBackwards(Xtensa::ARRegClass, L32R.
getIterator(),
535 if (ScavRegister != Xtensa::NoRegister)
536 RS->setRegUsed(ScavRegister);
540 ScavRegister = Xtensa::A12;
542 int FrameIndex = XtensaFI->getBranchRelaxationScratchFrameIndex();
543 if (FrameIndex == -1)
545 "Unable to properly handle scavenged register for indirect jump, "
546 "function code size is significantly larger than estimated");
550 RI.eliminateFrameIndex(std::prev(L32R.
getIterator()),
555 RI.eliminateFrameIndex(RestoreBB.
back(),
557 JumpToMBB = &RestoreBB;
560 unsigned LabelId = XtensaFI->createCPLabelId();
567 MRI.replaceRegWith(ScratchReg, ScavRegister);
575 "Xtensa branch conditions have less than four components!");
577 if (
Cond.empty() || (
Cond[0].getImm() == Xtensa::J)) {
580 if (BytesAdded &&
MI)
586 unsigned BR_C =
Cond[0].getImm();
624 if (BytesAdded &&
MI)
635 int *BytesAdded)
const {
637 assert(
TBB &&
"InsertBranch must not be told to insert a fallthrough");
639 "Xtensa branch conditions have less than four components!");
641 if (
Cond.empty() || (
Cond[0].getImm() == Xtensa::J)) {
644 if (BytesAdded &&
MI)
650 unsigned BR_C =
Cond[0].getImm();
688 if (BytesAdded &&
MI)
697 unsigned OpCode =
MI->getOpcode();
702 Cond[0].setImm(OpCode);
711 Cond[0].setImm(OpCode);
721 Cond[0].setImm(OpCode);
729 Cond[0].setImm(OpCode);
735 Cond[0].setImm(OpCode);
740 assert(!
MI->getDesc().isBranch() &&
"Unknown branch opcode");
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
uint64_t IntrinsicInst * II
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file declares the machine register scavenger class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
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.
Describe properties that are true of each instruction in the target description file.
Wrapper class representing physical registers. Should be passed by value.
MachineInstrBundleIterator< MachineInstr > iterator
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
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
Representation of each machine instruction.
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
A description of a memory reference used in the backend.
Flags
Flags values. These may be or'd together.
@ 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)
static MachineOperand CreateCPI(unsigned Idx, int Offset, unsigned TargetFlags=0)
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
Target - Wrapper for Target specific information.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM Value Representation.
static XtensaConstantPoolMBB * Create(LLVMContext &C, const MachineBasicBlock *M, unsigned ID)
XtensaConstantPoolValue - Xtensa specific constantpool value.
bool isBranch(const MachineBasicBlock::iterator &MI, SmallVectorImpl< MachineOperand > &Cond, const MachineOperand *&Target) const
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t BrOffset) const override
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
void insertIndirectBranch(MachineBasicBlock &MBB, MachineBasicBlock &DestBB, MachineBasicBlock &RestoreBB, const DebugLoc &DL, int64_t BrOffset=0, RegScavenger *RS=nullptr) const override
void adjustStackPtr(MCRegister SP, int64_t Amount, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const
Adjust SP by Amount bytes.
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIdx, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
unsigned insertConstBranchAtInst(MachineBasicBlock &MBB, MachineInstr *I, int64_t offset, ArrayRef< MachineOperand > Cond, DebugLoc DL, int *BytesAdded) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
unsigned insertBranchAtInst(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, MachineBasicBlock *TBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded) const
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
XtensaInstrInfo(const XtensaSubtarget &STI)
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
void getLoadStoreOpcodes(const TargetRegisterClass *RC, unsigned &LoadOpcode, unsigned &StoreOpcode, int64_t offset) const
void loadImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, MCRegister *Reg, int64_t Value) const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
@ Kill
The last use of a register.
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)
addFrameReference - This function is used to add a reference to the base of an abstract object on the...
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
unsigned getKillRegState(bool B)
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.