#ifndef GPU_INTEL_JIT_EMULATED_GENERATOR_HPP
#define GPU_INTEL_JIT_EMULATED_GENERATOR_HPP
#include "ngen.hpp"
#include "gpu/intel/compute/device_info.hpp"
#include "gpu/intel/jit/generator.hpp"
#include "ngen_core.hpp"
#include "ngen_emulation.hpp"
#include "ngen_register_allocator.hpp"
namespace dnnl {
namespace impl {
namespace gpu {
namespace intel {
namespace jit {
template <gpu_gen_t hw>
class emulated_generator_t : public generator_t<hw> {
friend struct ngen::EmulationImplementation;
protected:
NGEN_FORWARD_ELF(hw)
public:
emulated_generator_t(const compute::device_info_t &device_info,
const debug_config_t &debug_config)
: generator_t<hw>(debug_config)
, ra_(hw)
, emu_strategy(hw, device_info.stepping_id()) {}
protected:
ngen::RegisterAllocator ra_;
private:
ngen::EmulationStrategy emu_strategy;
protected:
ngen::RegisterAllocator &ra() { return ra_; }
void emov(const ngen::InstructionModifier &mod, const ngen::RegData &dst,
const ngen::RegData &src0);
void emov(const ngen::InstructionModifier &mod, const ngen::RegData &dst,
const ngen::Immediate &src0);
void emul(const ngen::InstructionModifier &mod, const ngen::RegData &dst,
const ngen::RegData &src0, const ngen::RegData &src1);
void emul(const ngen::InstructionModifier &mod, const ngen::RegData &dst,
const ngen::RegData &src0, const ngen::Immediate &src1);
void eadd(const ngen::InstructionModifier &mod, const ngen::RegData &dst,
const ngen::RegData &src0, const ngen::RegData &src1);
void eadd(const ngen::InstructionModifier &mod, const ngen::RegData &dst,
const ngen::RegData &src0, const ngen::Immediate &src1);
void emad(const ngen::InstructionModifier &mod, const ngen::RegData &dst,
const ngen::RegData &src0, const ngen::RegData &src1,
const ngen::RegData &src2);
void emad(const ngen::InstructionModifier &mod, const ngen::RegData &dst,
const ngen::RegData &src0, const ngen::RegData &src1,
const ngen::Immediate &src2);
void eadd3(const ngen::InstructionModifier &mod, const ngen::RegData &dst,
const ngen::RegData &src0, const ngen::RegData &src1,
const ngen::Immediate &src2);
void eadd3(const ngen::InstructionModifier &mod, const ngen::RegData &dst,
const ngen::RegData &src0, const ngen::RegData &src1,
const ngen::RegData &src2);
private:
enum class OperandType { dst, src0, src1, src2 };
bool supports_operand(const ngen::InstructionModifier &mod,
const ngen::RegData &rd, OperandType op_type);
ngen::DataType exec_type(const ngen::DataType &src);
ngen::DataType exec_type(
const ngen::DataType &src, const ngen::DataType &src1);
ngen::DataType exec_type(const ngen::DataType &src,
const ngen::DataType &src1, const ngen::DataType &src2);
bool supports_exectype(
const ngen::RegData &dst, const ngen::DataType &execType);
bool supports_signature(const ngen::InstructionModifier &mod,
const ngen::RegData &dst, const ngen::RegData &src);
bool supports_signature(const ngen::InstructionModifier &mod,
const ngen::RegData &dst, const ngen::Immediate &src);
bool supports_signature(const ngen::InstructionModifier &mod,
const ngen::RegData &dst, const ngen::RegData &src0,
const ngen::RegData &src1);
bool supports_signature(const ngen::InstructionModifier &mod,
const ngen::RegData &dst, const ngen::RegData &src0,
const ngen::Immediate &src1);
bool supports_signature(const ngen::InstructionModifier &mod,
const ngen::RegData &dst, const ngen::RegData &src0,
const ngen::RegData &src1, const ngen::RegData &src2);
bool supports_signature(const ngen::InstructionModifier &mod,
const ngen::RegData &dst, const ngen::RegData &src0,
const ngen::RegData &src1, const ngen::Immediate &src2);
};
#define FORWARD_EMULATION(hw) \
ngen::RegisterAllocator &ra() { return emulated_generator_t<hw>::ra(); } \
void emov(const ngen::InstructionModifier &mod, const ngen::RegData &dst, const ngen::RegData &src0) { emulated_generator_t<hw>::emov(mod, dst, src0); } \
void emov(const ngen::InstructionModifier &mod, const ngen::RegData &dst, const ngen::Immediate &src0) { emulated_generator_t<hw>::emov(mod, dst, src0); } \
void emul(const ngen::InstructionModifier &mod, const ngen::RegData &dst, const ngen::RegData &src0, const ngen::RegData &src1) { emulated_generator_t<hw>::emul(mod, dst, src0, src1); } \
void emul(const ngen::InstructionModifier &mod, const ngen::RegData &dst, const ngen::RegData &src0, const ngen::Immediate &src1) { emulated_generator_t<hw>::emul(mod, dst, src0, src1); } \
void eadd(const ngen::InstructionModifier &mod, const ngen::RegData &dst, const ngen::RegData &src0, const ngen::RegData &src1) { emulated_generator_t<hw>::eadd(mod, dst, src0, src1); } \
void eadd(const ngen::InstructionModifier &mod, const ngen::RegData &dst, const ngen::RegData &src0, const ngen::Immediate &src1) { emulated_generator_t<hw>::eadd(mod, dst, src0, src1); } \
void emad(const ngen::InstructionModifier &mod, const ngen::RegData &dst, const ngen::RegData &src0, const ngen::RegData &src1, const ngen::RegData &src2) { emulated_generator_t<hw>::emad(mod, dst, src0, src1, src2); } \
void emad(const ngen::InstructionModifier &mod, const ngen::RegData &dst, const ngen::RegData &src0, const ngen::RegData &src1, const ngen::Immediate &src2) { emulated_generator_t<hw>::emad(mod, dst, src0, src1, src2); } \
void eadd3(const ngen::InstructionModifier &mod, const ngen::RegData &dst, const ngen::RegData &src0, const ngen::RegData &src1, const ngen::RegData &src2) { emulated_generator_t<hw>::eadd3(mod, dst, src0, src1, src2); } \
void eadd3(const ngen::InstructionModifier &mod, const ngen::RegData &dst, const ngen::RegData &src0, const ngen::RegData &src1, const ngen::Immediate &src2) { emulated_generator_t<hw>::eadd3(mod, dst, src0, src1, src2); }
} } } } }
#endif