#ifndef LLVM_LIB_TARGET_LANAI_LANAIINSTRINFO_H
#define LLVM_LIB_TARGET_LANAI_LANAIINSTRINFO_H
#include "LanaiRegisterInfo.h"
#include "MCTargetDesc/LanaiMCTargetDesc.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#define GET_INSTRINFO_HEADER
#include "LanaiGenInstrInfo.inc"
namespace llvm {
class LanaiInstrInfo : public LanaiGenInstrInfo {
const LanaiRegisterInfo RegisterInfo;
public:
LanaiInstrInfo();
virtual const LanaiRegisterInfo &getRegisterInfo() const {
return RegisterInfo;
}
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
const MachineInstr &MIb) const override;
unsigned isLoadFromStackSlot(const MachineInstr &MI,
int &FrameIndex) const override;
unsigned isLoadFromStackSlotPostFE(const MachineInstr &MI,
int &FrameIndex) const override;
unsigned isStoreToStackSlot(const MachineInstr &MI,
int &FrameIndex) const override;
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
const DebugLoc &DL, MCRegister DestinationRegister,
MCRegister SourceRegister, bool KillSource) const override;
void
storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator Position,
Register SourceRegister, bool IsKill, int FrameIndex,
const TargetRegisterClass *RegisterClass,
const TargetRegisterInfo *RegisterInfo) const override;
void
loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator Position,
Register DestinationRegister, int FrameIndex,
const TargetRegisterClass *RegisterClass,
const TargetRegisterInfo *RegisterInfo) const override;
bool expandPostRAPseudo(MachineInstr &MI) const override;
bool getMemOperandsWithOffsetWidth(
const MachineInstr &LdSt,
SmallVectorImpl<const MachineOperand *> &BaseOps, int64_t &Offset,
bool &OffsetIsScalable, unsigned &Width,
const TargetRegisterInfo *TRI) const override;
bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt,
const MachineOperand *&BaseOp,
int64_t &Offset, unsigned &Width,
const TargetRegisterInfo *TRI) const;
std::pair<unsigned, unsigned>
decomposeMachineOperandsTargetFlags(unsigned TF) const override;
ArrayRef<std::pair<unsigned, const char *>>
getSerializableDirectMachineOperandTargetFlags() const override;
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TrueBlock,
MachineBasicBlock *&FalseBlock,
SmallVectorImpl<MachineOperand> &Condition,
bool AllowModify) const override;
unsigned removeBranch(MachineBasicBlock &MBB,
int *BytesRemoved = nullptr) const override;
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg,
Register &SrcReg2, int64_t &CmpMask,
int64_t &CmpValue) const override;
bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
Register SrcReg2, int64_t CmpMask, int64_t CmpValue,
const MachineRegisterInfo *MRI) const override;
bool analyzeSelect(const MachineInstr &MI,
SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp,
unsigned &FalseOp, bool &Optimizable) const override;
MachineInstr *optimizeSelect(MachineInstr &MI,
SmallPtrSetImpl<MachineInstr *> &SeenMIs,
bool PreferFalse) const override;
bool reverseBranchCondition(
SmallVectorImpl<MachineOperand> &Condition) const override;
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TrueBlock,
MachineBasicBlock *FalseBlock,
ArrayRef<MachineOperand> Condition,
const DebugLoc &DL,
int *BytesAdded = nullptr) const override;
};
static inline bool isSPLSOpcode(unsigned Opcode) {
switch (Opcode) {
case Lanai::LDBs_RI:
case Lanai::LDBz_RI:
case Lanai::LDHs_RI:
case Lanai::LDHz_RI:
case Lanai::STB_RI:
case Lanai::STH_RI:
return true;
default:
return false;
}
}
static inline bool isRMOpcode(unsigned Opcode) {
switch (Opcode) {
case Lanai::LDW_RI:
case Lanai::SW_RI:
return true;
default:
return false;
}
}
static inline bool isRRMOpcode(unsigned Opcode) {
switch (Opcode) {
case Lanai::LDBs_RR:
case Lanai::LDBz_RR:
case Lanai::LDHs_RR:
case Lanai::LDHz_RR:
case Lanai::LDWz_RR:
case Lanai::LDW_RR:
case Lanai::STB_RR:
case Lanai::STH_RR:
case Lanai::SW_RR:
return true;
default:
return false;
}
}
}
#endif