20#define DEBUG_TYPE "csky-instr-info"
24#define GET_INSTRINFO_CTOR_DTOR
25#include "CSKYGenInstrInfo.inc"
30 v2sf =
STI.hasFPUv2SingleFloat();
31 v2df =
STI.hasFPUv2DoubleFloat();
32 v3sf =
STI.hasFPUv3SingleFloat();
33 v3df =
STI.hasFPUv3DoubleFloat();
40 "Unknown conditional branch");
50 bool AllowModify)
const {
56 if (
I ==
MBB.end() || !isUnpredicatedTerminator(*
I))
62 int NumTerminators = 0;
63 for (
auto J =
I.getReverse(); J !=
MBB.rend() && isUnpredicatedTerminator(*J);
66 if (J->getDesc().isUnconditionalBranch() ||
67 J->getDesc().isIndirectBranch()) {
74 if (AllowModify && FirstUncondOrIndirectBr !=
MBB.end()) {
75 while (std::next(FirstUncondOrIndirectBr) !=
MBB.end()) {
76 std::next(FirstUncondOrIndirectBr)->eraseFromParent();
79 I = FirstUncondOrIndirectBr;
83 if (
I->getDesc().isIndirectBranch())
87 if (NumTerminators > 2)
91 if (NumTerminators == 1 &&
I->getDesc().isUnconditionalBranch()) {
97 if (NumTerminators == 1 &&
I->getDesc().isConditionalBranch()) {
103 if (NumTerminators == 2 && std::prev(
I)->getDesc().isConditionalBranch() &&
104 I->getDesc().isUnconditionalBranch()) {
115 int *BytesRemoved)
const {
122 if (!
I->getDesc().isUnconditionalBranch() &&
123 !
I->getDesc().isConditionalBranch())
129 I->eraseFromParent();
133 if (
I ==
MBB.begin())
136 if (!
I->getDesc().isConditionalBranch())
142 I->eraseFromParent();
148 assert(
MI.getDesc().isBranch() &&
"Unexpected opcode!");
150 int NumOp =
MI.getNumExplicitOperands();
151 assert(
MI.getOperand(NumOp - 1).isMBB() &&
"Expected MBB!");
152 return MI.getOperand(NumOp - 1).getMBB();
162 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
164 "CSKY branch conditions have two components!");
175 unsigned Opc =
Cond[0].getImm();
220 assert((
Cond.size() == 2) &&
"Invalid branch condition!");
236 DstReg =
MRI.createVirtualRegister(&CSKY::GPRRegClass);
244 .
addImm((Val >> 16) & 0xFFFF)
248 .
addImm((Val >> 16) & 0xFFFF)
257 DstReg =
MRI.createVirtualRegister(&CSKY::mGPRRegClass);
264 .
addImm((Val >> 8) & 0xFF)
270 if ((Val & 0xFF) != 0)
277 .
addImm((Val >> 16) & 0xFF)
283 if (((Val >> 8) & 0xFF) != 0)
286 .
addImm((Val >> 8) & 0xFF)
292 if ((Val & 0xFF) != 0)
299 .
addImm((Val >> 24) & 0xFF)
305 if (((Val >> 16) & 0xFF) != 0)
308 .
addImm((Val >> 16) & 0xFF)
314 if (((Val >> 8) & 0xFF) != 0)
317 .
addImm((Val >> 8) & 0xFF)
323 if ((Val & 0xFF) != 0)
335 int &FrameIndex)
const {
336 switch (
MI.getOpcode()) {
351 case CSKY::RESTORE_CARRY:
355 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
356 MI.getOperand(2).getImm() == 0) {
357 FrameIndex =
MI.getOperand(1).getIndex();
358 return MI.getOperand(0).getReg();
365 int &FrameIndex)
const {
366 switch (
MI.getOpcode()) {
379 case CSKY::SPILL_CARRY:
383 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
384 MI.getOperand(2).getImm() == 0) {
385 FrameIndex =
MI.getOperand(1).getIndex();
386 return MI.getOperand(0).getReg();
394 Register SrcReg,
bool IsKill,
int FI,
401 DL =
I->getDebugLoc();
409 if (CSKY::GPRRegClass.hasSubClassEq(RC)) {
410 Opcode = CSKY::ST32W;
411 }
else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) {
412 Opcode = CSKY::SPILL_CARRY;
414 }
else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC))
415 Opcode = CSKY::FST_S;
416 else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC))
417 Opcode = CSKY::FST_D;
418 else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC))
419 Opcode = CSKY::f2FST_S;
420 else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC))
421 Opcode = CSKY::f2FST_D;
428 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
443 DL =
I->getDebugLoc();
451 if (CSKY::GPRRegClass.hasSubClassEq(RC)) {
452 Opcode = CSKY::LD32W;
453 }
else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) {
454 Opcode = CSKY::RESTORE_CARRY;
456 }
else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC))
457 Opcode = CSKY::FLD_S;
458 else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC))
459 Opcode = CSKY::FLD_D;
460 else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC))
461 Opcode = CSKY::f2FLD_S;
462 else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC))
463 Opcode = CSKY::f2FLD_D;
470 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
482 bool RenamableDest,
bool RenamableSrc)
const {
483 if (CSKY::GPRRegClass.
contains(SrcReg) &&
484 CSKY::CARRYRegClass.
contains(DestReg)) {
490 assert(SrcReg < CSKY::R8);
498 if (CSKY::CARRYRegClass.
contains(SrcReg) &&
499 CSKY::GPRRegClass.
contains(DestReg)) {
505 assert(DestReg < CSKY::R16);
506 assert(DestReg < CSKY::R8);
523 if (CSKY::GPRRegClass.
contains(DestReg, SrcReg))
524 Opcode =
STI.hasE2() ? CSKY::MOV32 : CSKY::MOV16;
525 else if (v2sf && CSKY::sFPR32RegClass.
contains(DestReg, SrcReg))
526 Opcode = CSKY::FMOV_S;
527 else if (v3sf && CSKY::FPR32RegClass.
contains(DestReg, SrcReg))
528 Opcode = CSKY::f2FMOV_S;
529 else if (v2df && CSKY::sFPR64RegClass.
contains(DestReg, SrcReg))
530 Opcode = CSKY::FMOV_D;
531 else if (v3df && CSKY::FPR64RegClass.
contains(DestReg, SrcReg))
532 Opcode = CSKY::f2FMOV_D;
533 else if (v2sf && CSKY::sFPR32RegClass.
contains(SrcReg) &&
534 CSKY::GPRRegClass.
contains(DestReg))
535 Opcode = CSKY::FMFVRL;
536 else if (v3sf && CSKY::FPR32RegClass.
contains(SrcReg) &&
537 CSKY::GPRRegClass.
contains(DestReg))
538 Opcode = CSKY::f2FMFVRL;
539 else if (v2df && CSKY::sFPR64RegClass.
contains(SrcReg) &&
540 CSKY::GPRRegClass.
contains(DestReg))
541 Opcode = CSKY::FMFVRL_D;
542 else if (v3df && CSKY::FPR64RegClass.
contains(SrcReg) &&
543 CSKY::GPRRegClass.
contains(DestReg))
544 Opcode = CSKY::f2FMFVRL_D;
545 else if (v2sf && CSKY::GPRRegClass.
contains(SrcReg) &&
546 CSKY::sFPR32RegClass.
contains(DestReg))
547 Opcode = CSKY::FMTVRL;
548 else if (v3sf && CSKY::GPRRegClass.
contains(SrcReg) &&
549 CSKY::FPR32RegClass.
contains(DestReg))
550 Opcode = CSKY::f2FMTVRL;
551 else if (v2df && CSKY::GPRRegClass.
contains(SrcReg) &&
552 CSKY::sFPR64RegClass.
contains(DestReg))
553 Opcode = CSKY::FMTVRL_D;
554 else if (v3df && CSKY::GPRRegClass.
contains(SrcReg) &&
555 CSKY::FPR64RegClass.
contains(DestReg))
556 Opcode = CSKY::f2FMTVRL_D;
558 LLVM_DEBUG(
dbgs() <<
"src = " << SrcReg <<
", dst = " << DestReg);
573 if (GlobalBaseReg != 0)
574 return GlobalBaseReg;
586 unsigned CPI = MCP->getConstantPoolIndex(CPV,
Align(4));
595 GlobalBaseReg =
MRI.createVirtualRegister(&CSKY::GPRRegClass);
600 return GlobalBaseReg;
604 switch (
MI.getOpcode()) {
606 return MI.getDesc().getSize();
607 case CSKY::CONSTPOOL_ENTRY:
608 return MI.getOperand(2).getImm();
609 case CSKY::SPILL_CARRY:
610 case CSKY::RESTORE_CARRY:
611 case CSKY::PseudoTLSLA32:
613 case TargetOpcode::INLINEASM_BR:
614 case TargetOpcode::INLINEASM: {
616 const char *AsmStr =
MI.getOperand(0).getSymbolName();
unsigned const MachineRegisterInfo * MRI
static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static unsigned getOppositeBranchOpc(unsigned Opcode)
Register const TargetRegisterInfo * TRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
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),...
static CSKYConstantPoolSymbol * Create(Type *Ty, const char *S, unsigned PCAdjust, CSKYCP::CSKYCPModifier Modifier)
CSKYConstantPoolValue - CSKY specific constantpool value.
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) 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
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
const CSKYSubtarget & STI
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
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
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override
Register movImm(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, uint64_t Val, MachineInstr::MIFlag Flag=MachineInstr::NoFlags) const
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
Register getGlobalBaseReg(MachineFunction &MF) const
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
CSKYInstrInfo(const CSKYSubtarget &STI)
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
Register getGlobalBaseReg() const
void setGlobalBaseReg(Register Reg)
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool isConditionalBranch() const
Return true if this is a branch which may fall through to the next instruction or may transfer contro...
MachineInstrBundleIterator< MachineInstr > iterator
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.
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 MachineBasicBlock & front() const
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 & add(const MachineOperand &MO) const
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 & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor 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.
MachineBasicBlock * getMBB() const
static MachineOperand CreateImm(int64_t Val)
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...
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Target - Wrapper for Target specific information.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Define
Register definition.
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 isInt(int64_t x)
Checks if an integer fits into the given bit width.
unsigned getDeadRegState(bool B)
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
unsigned getKillRegState(bool B)
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.