#ifndef LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H
#define LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/Support/Casting.h"
namespace llvm {
class GenericMachineInstr : public MachineInstr {
public:
GenericMachineInstr() = delete;
Register getReg(unsigned Idx) const { return getOperand(Idx).getReg(); }
static bool classof(const MachineInstr *MI) {
return isPreISelGenericOpcode(MI->getOpcode());
}
};
class GLoadStore : public GenericMachineInstr {
public:
Register getPointerReg() const { return getOperand(1).getReg(); }
MachineMemOperand &getMMO() const { return **memoperands_begin(); }
bool isAtomic() const { return getMMO().isAtomic(); }
bool isVolatile() const { return getMMO().isVolatile(); }
bool isSimple() const { return !isAtomic() && !isVolatile(); }
bool isUnordered() const { return getMMO().isUnordered(); }
uint64_t getMemSize() const { return getMMO().getSize();
} uint64_t getMemSizeInBits() const { return getMMO().getSizeInBits(); }
static bool classof(const MachineInstr *MI) {
switch (MI->getOpcode()) {
case TargetOpcode::G_LOAD:
case TargetOpcode::G_STORE:
case TargetOpcode::G_ZEXTLOAD:
case TargetOpcode::G_SEXTLOAD:
return true;
default:
return false;
}
}
};
class GAnyLoad : public GLoadStore {
public:
Register getDstReg() const { return getOperand(0).getReg(); }
static bool classof(const MachineInstr *MI) {
switch (MI->getOpcode()) {
case TargetOpcode::G_LOAD:
case TargetOpcode::G_ZEXTLOAD:
case TargetOpcode::G_SEXTLOAD:
return true;
default:
return false;
}
}
};
class GLoad : public GAnyLoad {
public:
static bool classof(const MachineInstr *MI) {
return MI->getOpcode() == TargetOpcode::G_LOAD;
}
};
class GExtLoad : public GAnyLoad {
public:
static bool classof(const MachineInstr *MI) {
return MI->getOpcode() == TargetOpcode::G_SEXTLOAD ||
MI->getOpcode() == TargetOpcode::G_ZEXTLOAD;
}
};
class GSExtLoad : public GExtLoad {
public:
static bool classof(const MachineInstr *MI) {
return MI->getOpcode() == TargetOpcode::G_SEXTLOAD;
}
};
class GZExtLoad : public GExtLoad {
public:
static bool classof(const MachineInstr *MI) {
return MI->getOpcode() == TargetOpcode::G_ZEXTLOAD;
}
};
class GStore : public GLoadStore {
public:
Register getValueReg() const { return getOperand(0).getReg(); }
static bool classof(const MachineInstr *MI) {
return MI->getOpcode() == TargetOpcode::G_STORE;
}
};
class GUnmerge : public GenericMachineInstr {
public:
unsigned getNumDefs() const { return getNumOperands() - 1; }
Register getSourceReg() const { return getOperand(getNumDefs()).getReg(); }
static bool classof(const MachineInstr *MI) {
return MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES;
}
};
class GMergeLikeOp : public GenericMachineInstr {
public:
unsigned getNumSources() const { return getNumOperands() - 1; }
Register getSourceReg(unsigned I) const { return getReg(I + 1); }
static bool classof(const MachineInstr *MI) {
switch (MI->getOpcode()) {
case TargetOpcode::G_MERGE_VALUES:
case TargetOpcode::G_CONCAT_VECTORS:
case TargetOpcode::G_BUILD_VECTOR:
return true;
default:
return false;
}
}
};
class GMerge : public GMergeLikeOp {
public:
static bool classof(const MachineInstr *MI) {
return MI->getOpcode() == TargetOpcode::G_MERGE_VALUES;
}
};
class GConcatVectors : public GMergeLikeOp {
public:
static bool classof(const MachineInstr *MI) {
return MI->getOpcode() == TargetOpcode::G_CONCAT_VECTORS;
}
};
class GBuildVector : public GMergeLikeOp {
public:
static bool classof(const MachineInstr *MI) {
return MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR;
}
};
class GPtrAdd : public GenericMachineInstr {
public:
Register getBaseReg() const { return getReg(1); }
Register getOffsetReg() const { return getReg(2); }
static bool classof(const MachineInstr *MI) {
return MI->getOpcode() == TargetOpcode::G_PTR_ADD;
}
};
class GImplicitDef : public GenericMachineInstr {
public:
static bool classof(const MachineInstr *MI) {
return MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF;
}
};
class GSelect : public GenericMachineInstr {
public:
Register getCondReg() const { return getReg(1); }
Register getTrueReg() const { return getReg(2); }
Register getFalseReg() const { return getReg(3); }
static bool classof(const MachineInstr *MI) {
return MI->getOpcode() == TargetOpcode::G_SELECT;
}
};
}
#endif