FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

命令セットシミュレータにおける命令のデコードと実行(C++における関数ポインタ)

msyksphinz.hatenablog.com

結局、クラスのメンバとして関数ポインタを指定して、そこでどのようにして所望の関数の実装を呼べば良いかというと、

            m_inst_env->RISCV_Inst_Exec (inst_idx, inst_hex);
            // m_inst_env->*m_inst_exec_func[inst_idx]) (inst_hex);

実体の実装としては、

class InstEnv {

private:
    RiscvEnv *m_env;

public:
    InstEnv (RiscvEnv *env);

    typedef void (InstEnv::*InstFunc) (Word_t inst_hex);
    static const InstFunc m_inst_exec_func[];

    void RISCV_Inst_Exec (uint32_t index, Word_t inst_hex);

 ...

ここでは、RISCV_Inst_Execというラッパを噛まして関数を呼ぶようにする。実体は、

void InstEnv::RISCV_Inst_Exec (uint32_t index, Word_t inst_hex)
{
    (this->*m_inst_exec_func[index]) (inst_hex);

    return;
}

これだけの実装だけど、要点としてはthisポインタを使ってアクセスしているのが重要。

thisポインタを経由して関数ポインタにアクセスしないといけないルールのようで、呼び出し側も、

            // m_inst_env->RISCV_Inst_Exec (inst_idx, inst_hex);
            m_inst_env->*m_inst_exec_func[inst_idx]) (inst_hex);

では失敗する。