mirror of
https://github.com/RKX1209/nsemu.git
synced 2025-04-02 10:31:49 -04:00
192 lines
8.8 KiB
C++
192 lines
8.8 KiB
C++
#ifndef _INTERPRETER_HPP
|
|
#define _INTERPRETER_HPP
|
|
|
|
class IntprCallback : public DisasCallback {
|
|
public:
|
|
/* Mov with Immediate value */
|
|
void MoviI64(unsigned int reg_idx, uint64_t imm, bool bit64);
|
|
|
|
/* Deposit (i.e. distination register won't be changed) with Immediate value */
|
|
void DepositI64(unsigned int reg_idx, uint64_t imm, unsigned int pos, unsigned int len, bool bit64);
|
|
void DepositReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64);
|
|
void DepositZeroI64(unsigned int reg_idx, uint64_t imm, unsigned int pos, unsigned int len, bool bit64);
|
|
void DepositZeroReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64);
|
|
|
|
/* Mov between registers */
|
|
void MovReg(unsigned int rd_idx, unsigned int rn_idx, bool bit64);
|
|
|
|
/* Conditional mov between registers */
|
|
void CondMovReg(unsigned int cond, unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx, bool bit64);
|
|
|
|
/* Add/Sub with Immediate value */
|
|
void AddI64(unsigned int rd_idx, unsigned int rn_idx, uint64_t imm, bool setflags, bool bit64);
|
|
void SubI64(unsigned int rd_idx, unsigned int rn_idx, uint64_t imm, bool setflags, bool bit64);
|
|
|
|
/* Add/Sub/Mul/Div between registers */
|
|
void AddReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx, bool setflags, bool bit64);
|
|
void SubReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx, bool setflags, bool bit64);
|
|
void MulReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx, bool sign, bool dst64, bool src64);
|
|
void Mul2Reg(unsigned int rh_idx, unsigned int rl_idx, unsigned int rn_idx, unsigned int rm_idx, bool sign); //64bit * 64bit
|
|
void DivReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx, bool sign, bool bit64);
|
|
void ShiftReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx, unsigned int shift_type, bool bit64) ;
|
|
|
|
/* Add/Sub with carry flag between registers */
|
|
void AddcReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx, bool setflags, bool bit64);
|
|
void SubcReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx, bool setflags, bool bit64);
|
|
|
|
/* AND/OR/EOR/Shift ... with Immediate value */
|
|
void AndI64(unsigned int rd_idx, unsigned int rn_idx, uint64_t wmask, bool setflags, bool bit64);
|
|
void OrrI64(unsigned int rd_idx, unsigned int rn_idx, uint64_t wmask, bool bit64);
|
|
void EorI64(unsigned int rd_idx, unsigned int rn_idx, uint64_t wmask, bool bit64);
|
|
void ShiftI64(unsigned int rd_idx, unsigned int rn_idx, unsigned int shift_type, unsigned int shift_amount, bool bit64);
|
|
|
|
/* AND/OR/EOR/BIC/NOT ... between registers */
|
|
void AndReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx, bool setflags, bool bit64);
|
|
void OrrReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx, bool bit64);
|
|
void EorReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx, bool bit64);
|
|
void BicReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx, bool setflags, bool bit64);
|
|
void NotReg(unsigned int rd_idx, unsigned int rm_idx, bool bit64);
|
|
void ExtendReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int extend_type, bool bit64);
|
|
|
|
/* Load/Store */
|
|
void LoadReg(unsigned int rd_idx, unsigned int base_idx, unsigned int rm_idx, int size, bool is_sign, bool extend, bool post, bool bit64);
|
|
void LoadRegI64(unsigned int rd_idx, unsigned int ad_idx, int size, bool is_sign, bool extend);
|
|
void StoreReg(unsigned int rd_idx, unsigned int base_idx, unsigned int rm_idx, int size, bool is_sign, bool extend, bool post, bool bit64);
|
|
void StoreRegI64(unsigned int rd_idx, unsigned int ad_idx, int size, bool is_sign, bool extend);
|
|
void _LoadReg(unsigned int rd_idx, uint64_t addr, int size, bool is_sign, bool extend);
|
|
void _StoreReg(unsigned int rd_idx, uint64_t addr, int size, bool is_sign, bool extend);
|
|
|
|
/* Bitfield Signed/Unsigned Extract... with Immediate value */
|
|
void SExtractI64(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64);
|
|
void UExtractI64(unsigned int rd_idx, unsigned int rn_idx, unsigned int pos, unsigned int len, bool bit64);
|
|
|
|
/* Signed Extend from 32bit */
|
|
void SExt32(unsigned int rd_idx, unsigned int rn_idx);
|
|
|
|
/* Reverse bit order */
|
|
void RevBit(unsigned int rd_idx, unsigned int rn_idx, bool bit64);
|
|
/* Reverse byte order per 16bit */
|
|
void RevByte16(unsigned int rd_idx, unsigned int rn_idx, bool bit64);
|
|
/* Reverse byte order per 32bit */
|
|
void RevByte32(unsigned int rd_idx, unsigned int rn_idx, bool bit64);
|
|
/* Reverse byte order per 64bit */
|
|
void RevByte64(unsigned int rd_idx, unsigned int rn_idx, bool bit64);
|
|
/* Count Leading Zeros */
|
|
void CntLeadZero(unsigned int rd_idx, unsigned int rn_idx, bool bit64);
|
|
/* Count Leading Signed bits */
|
|
void CntLeadSign(unsigned int rd_idx, unsigned int rn_idx, bool bit64);
|
|
|
|
/* Conditional compare... with Immediate value */
|
|
void CondCmpI64(unsigned int rn_idx, unsigned int imm, unsigned int nzcv, unsigned int cond, unsigned int op, bool bit64);
|
|
/* Conditional compare... between registers */
|
|
void CondCmpReg(unsigned int rn_idx, unsigned int rm_idx, unsigned int nzcv, unsigned int cond, unsigned int op, bool bit64);
|
|
|
|
/* Go to Immediate address */
|
|
void BranchI64(uint64_t imm);
|
|
|
|
/* Conditional Branch with Immediate value and jump to Immediate address */
|
|
void BranchCondiI64(unsigned int cond, unsigned int rt_idx, uint64_t imm, uint64_t addr, bool bit64);
|
|
|
|
/* Conditional Branch with NZCV flags */
|
|
void BranchFlag(unsigned int cond, uint64_t addr);
|
|
|
|
/* Set PC with reg */
|
|
void SetPCReg(unsigned int rt_idx);
|
|
|
|
/* Super Visor Call */
|
|
void SVC(unsigned int svc_num);
|
|
/* Breakpoint exception */
|
|
void BRK(unsigned int memo);
|
|
|
|
/* Read/Write Sysreg */
|
|
void ReadWriteSysReg(unsigned int rd_idx, int offset, bool read);
|
|
/* Read/Write NZCV */
|
|
void ReadWriteNZCV(unsigned int rd_idx, bool read);
|
|
|
|
/* Fp Mov between registers */
|
|
void FMovReg(unsigned int fd_idx, unsigned int fn_idx, int type);
|
|
/* Fp Mov between registers (float <-> int)*/
|
|
void FMovConv(unsigned int rd_idx, unsigned int rn_idx, int type, bool itof);
|
|
|
|
/* ####### Vector ####### */
|
|
|
|
/* Load/Store for vector */
|
|
void LoadVecReg(unsigned int vd_idx, int element, unsigned int rn_idx, int size);
|
|
void StoreVecReg(unsigned int rd_idx, int element, unsigned int vn_idx, int size);
|
|
|
|
/* Load/Store for FP */
|
|
void LoadFpReg(unsigned int rd_idx, unsigned int base_idx, unsigned int rm_idx, int size, bool post, bool bit64);
|
|
void StoreFpReg(unsigned int rd_idx, unsigned int base_idx, unsigned int rm_idx, int size, bool post, bool bit64);
|
|
|
|
/* Load/Store for FP */
|
|
void LoadFpRegI64(unsigned int fd_idx, unsigned int ad_idx, int size);
|
|
void StoreFpRegI64(unsigned int fd_idx, unsigned int ad_idx, int size);
|
|
|
|
/* AND/OR/EOR/BIC/NOT ... between vector registers */
|
|
void AndVecReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx);
|
|
void OrrVecReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx);
|
|
void EorVecReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx);
|
|
void BicVecReg(unsigned int rd_idx, unsigned int rn_idx, unsigned int rm_idx);
|
|
void NotVecReg(unsigned int rd_idx, unsigned int rm_idx);
|
|
|
|
/* Read Vector register to FP register */
|
|
void ReadVecReg(unsigned int fd_idx, unsigned int vn_idx, unsigned int index, int size);
|
|
/* Read Vector register to general register */
|
|
void ReadVecElem(unsigned int rd_idx, unsigned int vn_idx, unsigned int index, int size);
|
|
/* Write general register value tot Vector register */
|
|
void WriteVecElem(unsigned int vd_idx, unsigned int rn_idx, unsigned int index, int size);
|
|
|
|
/* Duplicate an immediate value to vector register */
|
|
void DupVecImmI32(unsigned int vd_idx, uint32_t imm, int size, int dstsize);
|
|
void DupVecImmI64(unsigned int vd_idx, uint64_t imm, int size, int dstsize);
|
|
/* Duplicate an element of vector register to new one */
|
|
void DupVecReg(unsigned int vd_idx, unsigned int vn_idx, unsigned int index, int size, int dstsize);
|
|
/* Duplicate an general register into vector register */
|
|
void DupVecRegFromGen(unsigned int vd_idx, unsigned int rn_idx, int size, int dstsize);
|
|
|
|
/* Compare Bit wise equal */
|
|
void CompareEqualVec(unsigned int vd_idx, unsigned int vn_idx, unsigned int vm_idx, int index, int size);
|
|
|
|
/* Compare Bit wise test bits nonzero */
|
|
void CompareTestBitsVec(unsigned int vd_idx, unsigned int vn_idx, unsigned int vm_idx, int index, int size);
|
|
|
|
};
|
|
|
|
/* Global Interpreter singleton class .*/
|
|
class Interpreter {
|
|
private:
|
|
Interpreter() = default;
|
|
~Interpreter() = default;
|
|
|
|
static Interpreter *inst;
|
|
static IntprCallback *disas_cb;
|
|
public:
|
|
Interpreter(const Interpreter&) = delete;
|
|
Interpreter& operator=(const Interpreter&) = delete;
|
|
Interpreter(Interpreter&&) = delete;
|
|
Interpreter& operator=(Interpreter&&) = delete;
|
|
|
|
void Init();
|
|
|
|
static Interpreter *get_instance() {
|
|
return inst;
|
|
}
|
|
|
|
static void create() {
|
|
if (!inst) {
|
|
inst = new Interpreter;
|
|
inst->disas_cb = new IntprCallback;
|
|
}
|
|
}
|
|
|
|
static void destroy() {
|
|
if (inst) {
|
|
delete inst->disas_cb;
|
|
delete inst;
|
|
inst = nullptr;
|
|
}
|
|
}
|
|
void Run();
|
|
int SingleStep();
|
|
};
|
|
#endif
|