20#define DEBUG_TYPE "csky-instr-info"
24#define GET_INSTRINFO_CTOR_DTOR
25#include "CSKYGenInstrInfo.inc"
39 "Unknown conditional branch");
49 bool AllowModify)
const {
55 if (
I ==
MBB.
end() || !isUnpredicatedTerminator(*
I))
61 int NumTerminators = 0;
62 for (
auto J =
I.getReverse(); J !=
MBB.
rend() && isUnpredicatedTerminator(*J);
65 if (J->getDesc().isUnconditionalBranch() ||
66 J->getDesc().isIndirectBranch()) {
73 if (AllowModify && FirstUncondOrIndirectBr !=
MBB.
end()) {
74 while (std::next(FirstUncondOrIndirectBr) !=
MBB.
end()) {
75 std::next(FirstUncondOrIndirectBr)->eraseFromParent();
78 I = FirstUncondOrIndirectBr;
82 if (
I->getDesc().isIndirectBranch())
86 if (NumTerminators > 2)
90 if (NumTerminators == 1 &&
I->getDesc().isUnconditionalBranch()) {
96 if (NumTerminators == 1 &&
I->getDesc().isConditionalBranch()) {
102 if (NumTerminators == 2 && std::prev(
I)->getDesc().isConditionalBranch() &&
103 I->getDesc().isUnconditionalBranch()) {
114 int *BytesRemoved)
const {
121 if (!
I->getDesc().isUnconditionalBranch() &&
122 !
I->getDesc().isConditionalBranch())
128 I->eraseFromParent();
135 if (!
I->getDesc().isConditionalBranch())
141 I->eraseFromParent();
147 assert(
MI.getDesc().isBranch() &&
"Unexpected opcode!");
149 int NumOp =
MI.getNumExplicitOperands();
150 assert(
MI.getOperand(NumOp - 1).isMBB() &&
"Expected MBB!");
151 return MI.getOperand(NumOp - 1).getMBB();
161 assert(
TBB &&
"insertBranch must not be told to insert a fallthrough");
163 "CSKY branch conditions have two components!");
174 unsigned Opc =
Cond[0].getImm();
219 assert((
Cond.size() == 2) &&
"Invalid branch condition!");
235 DstReg =
MRI.createVirtualRegister(&CSKY::GPRRegClass);
237 if (isUInt<16>(Val)) {
241 }
else if (isShiftedUInt<16, 16>(Val)) {
243 .
addImm((Val >> 16) & 0xFFFF)
247 .
addImm((Val >> 16) & 0xFFFF)
256 DstReg =
MRI.createVirtualRegister(&CSKY::mGPRRegClass);
257 if (isUInt<8>(Val)) {
261 }
else if (isUInt<16>(Val)) {
263 .
addImm((Val >> 8) & 0xFF)
269 if ((Val & 0xFF) != 0)
274 }
else if (isUInt<24>(Val)) {
276 .
addImm((Val >> 16) & 0xFF)
282 if (((Val >> 8) & 0xFF) != 0)
285 .
addImm((Val >> 8) & 0xFF)
291 if ((Val & 0xFF) != 0)
298 .
addImm((Val >> 24) & 0xFF)
304 if (((Val >> 16) & 0xFF) != 0)
307 .
addImm((Val >> 16) & 0xFF)
313 if (((Val >> 8) & 0xFF) != 0)
316 .
addImm((Val >> 8) & 0xFF)
322 if ((Val & 0xFF) != 0)
334 int &FrameIndex)
const {
335 switch (
MI.getOpcode()) {
350 case CSKY::RESTORE_CARRY:
354 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
355 MI.getOperand(2).getImm() == 0) {
356 FrameIndex =
MI.getOperand(1).getIndex();
357 return MI.getOperand(0).getReg();
364 int &FrameIndex)
const {
365 switch (
MI.getOpcode()) {
378 case CSKY::SPILL_CARRY:
382 if (
MI.getOperand(1).isFI() &&
MI.getOperand(2).isImm() &&
383 MI.getOperand(2).getImm() == 0) {
384 FrameIndex =
MI.getOperand(1).getIndex();
385 return MI.getOperand(0).getReg();
393 Register SrcReg,
bool IsKill,
int FI,
399 DL =
I->getDebugLoc();
407 if (CSKY::GPRRegClass.hasSubClassEq(RC)) {
408 Opcode = CSKY::ST32W;
409 }
else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) {
410 Opcode = CSKY::SPILL_CARRY;
412 }
else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC))
413 Opcode = CSKY::FST_S;
414 else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC))
415 Opcode = CSKY::FST_D;
416 else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC))
417 Opcode = CSKY::f2FST_S;
418 else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC))
419 Opcode = CSKY::f2FST_D;
426 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 if (CSKY::GPRRegClass.
contains(SrcReg) &&
483 CSKY::CARRYRegClass.
contains(DestReg)) {
489 assert(SrcReg < CSKY::R8);
497 if (CSKY::CARRYRegClass.
contains(SrcReg) &&
498 CSKY::GPRRegClass.
contains(DestReg)) {
504 assert(DestReg < CSKY::R16);
505 assert(DestReg < CSKY::R8);
522 if (CSKY::GPRRegClass.
contains(DestReg, SrcReg))
523 Opcode =
STI.
hasE2() ? CSKY::MOV32 : CSKY::MOV16;
524 else if (v2sf && CSKY::sFPR32RegClass.
contains(DestReg, SrcReg))
525 Opcode = CSKY::FMOV_S;
526 else if (v3sf && CSKY::FPR32RegClass.
contains(DestReg, SrcReg))
527 Opcode = CSKY::f2FMOV_S;
528 else if (v2df && CSKY::sFPR64RegClass.
contains(DestReg, SrcReg))
529 Opcode = CSKY::FMOV_D;
530 else if (v3df && CSKY::FPR64RegClass.
contains(DestReg, SrcReg))
531 Opcode = CSKY::f2FMOV_D;
532 else if (v2sf && CSKY::sFPR32RegClass.
contains(SrcReg) &&
533 CSKY::GPRRegClass.
contains(DestReg))
534 Opcode = CSKY::FMFVRL;
535 else if (v3sf && CSKY::FPR32RegClass.
contains(SrcReg) &&
536 CSKY::GPRRegClass.
contains(DestReg))
537 Opcode = CSKY::f2FMFVRL;
538 else if (v2df && CSKY::sFPR64RegClass.
contains(SrcReg) &&
539 CSKY::GPRRegClass.
contains(DestReg))
540 Opcode = CSKY::FMFVRL_D;
541 else if (v3df && CSKY::FPR64RegClass.
contains(SrcReg) &&
542 CSKY::GPRRegClass.
contains(DestReg))
543 Opcode = CSKY::f2FMFVRL_D;
544 else if (v2sf && CSKY::GPRRegClass.
contains(SrcReg) &&
545 CSKY::sFPR32RegClass.
contains(DestReg))
546 Opcode = CSKY::FMTVRL;
547 else if (v3sf && CSKY::GPRRegClass.
contains(SrcReg) &&
548 CSKY::FPR32RegClass.
contains(DestReg))
549 Opcode = CSKY::f2FMTVRL;
550 else if (v2df && CSKY::GPRRegClass.
contains(SrcReg) &&
551 CSKY::sFPR64RegClass.
contains(DestReg))
552 Opcode = CSKY::FMTVRL_D;
553 else if (v3df && CSKY::GPRRegClass.
contains(SrcReg) &&
554 CSKY::FPR64RegClass.
contains(DestReg))
555 Opcode = CSKY::f2FMTVRL_D;
557 LLVM_DEBUG(
dbgs() <<
"src = " << SrcReg <<
", dst = " << DestReg);
572 if (GlobalBaseReg != 0)
573 return GlobalBaseReg;
585 unsigned CPI = MCP->getConstantPoolIndex(CPV,
Align(4));
594 GlobalBaseReg =
MRI.createVirtualRegister(&CSKY::GPRRegClass);
599 return GlobalBaseReg;
603 switch (
MI.getOpcode()) {
605 return MI.getDesc().getSize();
606 case CSKY::CONSTPOOL_ENTRY:
607 return MI.getOperand(2).getImm();
608 case CSKY::SPILL_CARRY:
609 case CSKY::RESTORE_CARRY:
610 case CSKY::PseudoTLSLA32:
612 case TargetOpcode::INLINEASM_BR:
613 case TargetOpcode::INLINEASM: {
615 const char *AsmStr =
MI.getOperand(0).getSymbolName();
unsigned const MachineRegisterInfo * MRI
static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static unsigned getOppositeBranchOpc(unsigned Opcode)
unsigned const TargetRegisterInfo * TRI
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)
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
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg, bool IsKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) 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 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
const CSKYSubtarget & STI
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) 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
CSKYInstrInfo(CSKYSubtarget &STI)
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
Register getGlobalBaseReg() const
void setGlobalBaseReg(Register Reg)
bool hasFPUv2SingleFloat() const
bool hasFPUv3SingleFloat() const
bool hasFPUv2DoubleFloat() const
bool hasFPUv3DoubleFloat() const
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...
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.
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.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
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 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 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.
unsigned getDeadRegState(bool B)
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.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
unsigned getKillRegState(bool B)
This struct is a compact representation of a valid (non-zero power of two) alignment.
static MachinePointerInfo getConstantPool(MachineFunction &MF)
Return a MachinePointerInfo record that refers to the constant pool.
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.