#ifndef LLVM_LIB_TARGET_M68K_M68KINSTRINFO_H
#define LLVM_LIB_TARGET_M68K_M68KINSTRINFO_H
#include "M68k.h"
#include "M68kRegisterInfo.h"
#include "MCTargetDesc/M68kBaseInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#define GET_INSTRINFO_HEADER
#include "M68kGenInstrInfo.inc"
namespace llvm {
class M68kSubtarget;
namespace M68k {
enum CondCode {
COND_T = 0, COND_F = 1, COND_HI = 2, COND_LS = 3, COND_CC = 4, COND_CS = 5, COND_NE = 6, COND_EQ = 7, COND_VC = 8, COND_VS = 9, COND_PL = 10, COND_MI = 11, COND_GE = 12, COND_LT = 13, COND_GT = 14, COND_LE = 15, LAST_VALID_COND = COND_LE,
COND_INVALID
};
static inline M68k::CondCode GetOppositeBranchCondition(M68k::CondCode CC) {
switch (CC) {
default:
llvm_unreachable("Illegal condition code!");
case M68k::COND_T:
return M68k::COND_F;
case M68k::COND_F:
return M68k::COND_T;
case M68k::COND_HI:
return M68k::COND_LS;
case M68k::COND_LS:
return M68k::COND_HI;
case M68k::COND_CC:
return M68k::COND_CS;
case M68k::COND_CS:
return M68k::COND_CC;
case M68k::COND_NE:
return M68k::COND_EQ;
case M68k::COND_EQ:
return M68k::COND_NE;
case M68k::COND_VC:
return M68k::COND_VS;
case M68k::COND_VS:
return M68k::COND_VC;
case M68k::COND_PL:
return M68k::COND_MI;
case M68k::COND_MI:
return M68k::COND_PL;
case M68k::COND_GE:
return M68k::COND_LT;
case M68k::COND_LT:
return M68k::COND_GE;
case M68k::COND_GT:
return M68k::COND_LE;
case M68k::COND_LE:
return M68k::COND_GT;
}
}
static inline unsigned GetCondBranchFromCond(M68k::CondCode CC) {
switch (CC) {
default:
llvm_unreachable("Illegal condition code!");
case M68k::COND_EQ:
return M68k::Beq8;
case M68k::COND_NE:
return M68k::Bne8;
case M68k::COND_LT:
return M68k::Blt8;
case M68k::COND_LE:
return M68k::Ble8;
case M68k::COND_GT:
return M68k::Bgt8;
case M68k::COND_GE:
return M68k::Bge8;
case M68k::COND_CS:
return M68k::Bcs8;
case M68k::COND_LS:
return M68k::Bls8;
case M68k::COND_HI:
return M68k::Bhi8;
case M68k::COND_CC:
return M68k::Bcc8;
case M68k::COND_MI:
return M68k::Bmi8;
case M68k::COND_PL:
return M68k::Bpl8;
case M68k::COND_VS:
return M68k::Bvs8;
case M68k::COND_VC:
return M68k::Bvc8;
}
}
static inline M68k::CondCode GetCondFromBranchOpc(unsigned Opcode) {
switch (Opcode) {
default:
return M68k::COND_INVALID;
case M68k::Beq8:
return M68k::COND_EQ;
case M68k::Bne8:
return M68k::COND_NE;
case M68k::Blt8:
return M68k::COND_LT;
case M68k::Ble8:
return M68k::COND_LE;
case M68k::Bgt8:
return M68k::COND_GT;
case M68k::Bge8:
return M68k::COND_GE;
case M68k::Bcs8:
return M68k::COND_CS;
case M68k::Bls8:
return M68k::COND_LS;
case M68k::Bhi8:
return M68k::COND_HI;
case M68k::Bcc8:
return M68k::COND_CC;
case M68k::Bmi8:
return M68k::COND_MI;
case M68k::Bpl8:
return M68k::COND_PL;
case M68k::Bvs8:
return M68k::COND_VS;
case M68k::Bvc8:
return M68k::COND_VC;
}
}
static inline unsigned IsCMP(unsigned Op) {
switch (Op) {
default:
return false;
case M68k::CMP8dd:
case M68k::CMP8df:
case M68k::CMP8di:
case M68k::CMP8dj:
case M68k::CMP8dp:
case M68k::CMP16dr:
case M68k::CMP16df:
case M68k::CMP16di:
case M68k::CMP16dj:
case M68k::CMP16dp:
return true;
}
}
static inline bool IsSETCC(unsigned SETCC) {
switch (SETCC) {
default:
return false;
case M68k::SETd8eq:
case M68k::SETd8ne:
case M68k::SETd8lt:
case M68k::SETd8ge:
case M68k::SETd8le:
case M68k::SETd8gt:
case M68k::SETd8cs:
case M68k::SETd8cc:
case M68k::SETd8ls:
case M68k::SETd8hi:
case M68k::SETd8pl:
case M68k::SETd8mi:
case M68k::SETd8vc:
case M68k::SETd8vs:
case M68k::SETj8eq:
case M68k::SETj8ne:
case M68k::SETj8lt:
case M68k::SETj8ge:
case M68k::SETj8le:
case M68k::SETj8gt:
case M68k::SETj8cs:
case M68k::SETj8cc:
case M68k::SETj8ls:
case M68k::SETj8hi:
case M68k::SETj8pl:
case M68k::SETj8mi:
case M68k::SETj8vc:
case M68k::SETj8vs:
case M68k::SETp8eq:
case M68k::SETp8ne:
case M68k::SETp8lt:
case M68k::SETp8ge:
case M68k::SETp8le:
case M68k::SETp8gt:
case M68k::SETp8cs:
case M68k::SETp8cc:
case M68k::SETp8ls:
case M68k::SETp8hi:
case M68k::SETp8pl:
case M68k::SETp8mi:
case M68k::SETp8vc:
case M68k::SETp8vs:
return true;
}
}
}
class M68kInstrInfo : public M68kGenInstrInfo {
virtual void anchor();
protected:
const M68kSubtarget &Subtarget;
const M68kRegisterInfo RI;
public:
explicit M68kInstrInfo(const M68kSubtarget &STI);
static const M68kInstrInfo *create(M68kSubtarget &STI);
const M68kRegisterInfo &getRegisterInfo() const { return RI; };
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const override;
bool AnalyzeBranchImpl(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify) const;
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 MI,
const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
bool KillSrc) const override;
bool getStackSlotRange(const TargetRegisterClass *RC, unsigned SubIdx,
unsigned &Size, unsigned &Offset,
const MachineFunction &MF) const override;
void storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, Register SrcReg,
bool IsKill, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const override;
void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, Register DestReg,
int FrameIndex, const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const override;
bool expandPostRAPseudo(MachineInstr &MI) const override;
bool isPCRelRegisterOperandLegal(const MachineOperand &MO) const override;
void AddSExt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
DebugLoc DL, unsigned Reg, MVT From, MVT To) const;
void AddZExt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
DebugLoc DL, unsigned Reg, MVT From, MVT To) const;
bool ExpandMOVX_RR(MachineInstrBuilder &MIB, MVT MVTDst, MVT MVTSrc) const;
bool ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned, MVT MVTDst,
MVT MVTSrc) const;
bool ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned,
const MCInstrDesc &Desc, MVT MVTDst, MVT MVTSrc) const;
bool ExpandPUSH_POP(MachineInstrBuilder &MIB, const MCInstrDesc &Desc,
bool IsPush) const;
bool ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const;
bool ExpandMOVEM(MachineInstrBuilder &MIB, const MCInstrDesc &Desc,
bool IsRM) const;
unsigned getGlobalBaseReg(MachineFunction *MF) const;
std::pair<unsigned, unsigned>
decomposeMachineOperandsTargetFlags(unsigned TF) const override;
ArrayRef<std::pair<unsigned, const char *>>
getSerializableDirectMachineOperandTargetFlags() const override;
};
}
#endif