FPGA開発日記

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

Binary Translation型エミュレータを作る(Compressed命令の実装1)

前回Compressed命令のフレームワークは完成したので後はひたすら命令を追加していくだけとなる。今日は以下の命令を実装。

  • C.LW
  • C.LD
  • C.SW
  • C.SD
  • C.ADDI
  • C.ADDI16SP

メモリアクセス系はあまり気にせずに実装した。というかこれまでの32ビット版の実装があるのでそれにあわせるだけとなる。

    pub fn translate_c_lw   (&mut self, inst: &InstrInfo) -> Vec<TCGOp> { 
        let imm = extend_sign((((((inst.inst >> 10) & 0x7) << 3) |
                                (((inst.inst >>  6) & 0x1) << 2) |
                                (((inst.inst >>  5) & 0x1) << 6))) as u64, 6);

        self.translate_raw_load(get_c_reg_addr!((inst.inst >> 7) & 0x7), imm as u64, get_c_reg_addr!((inst.inst >> 2) & 0x7), inst, TCGOpcode::LOAD_32BIT, CALL_HELPER_IDX::CALL_LOAD32_IDX)
    }

    pub fn translate_c_ld   (&mut self, inst: &InstrInfo) -> Vec<TCGOp> { 
        let imm = extend_sign((((((inst.inst >> 10) & 0x7) << 3) |
                                (((inst.inst >>  5) & 0x3) << 6))) as u64, 6);

        self.translate_raw_load(get_c_reg_addr!((inst.inst >> 7) & 0x7), imm as u64, get_c_reg_addr!((inst.inst >> 2) & 0x7), inst, TCGOpcode::LOAD_64BIT, CALL_HELPER_IDX::CALL_LOAD32_IDX)
    }
    pub fn translate_c_sw   (&mut self, inst: &InstrInfo) -> Vec<TCGOp> { 
        let imm = extend_sign((((((inst.inst >> 10) & 0x7) << 3) |
                                (((inst.inst >>  6) & 0x1) << 2) |
                                (((inst.inst >>  5) & 0x1) << 6))) as u64, 6);

        self.translate_raw_store(get_c_reg_addr!((inst.inst >> 7) & 0x7), imm as u64, get_c_reg_addr!((inst.inst >> 2) & 0x7), inst, TCGOpcode::STORE_32BIT, CALL_HELPER_IDX::CALL_STORE32_IDX)
    }

    pub fn translate_c_sd   (&mut self, inst: &InstrInfo) -> Vec<TCGOp> { 
        let imm = extend_sign((((((inst.inst >> 10) & 0x7) << 3) |
                                (((inst.inst >>  5) & 0x3) << 6))) as u64, 6);

        self.translate_raw_store(get_c_reg_addr!((inst.inst >> 7) & 0x7), imm as u64, get_c_reg_addr!((inst.inst >> 2) & 0x7), inst, TCGOpcode::STORE_64BIT, CALL_HELPER_IDX::CALL_STORE32_IDX)
    }

とりあえずrv64uc-p-rvcの途中までは動くようになった。まだまだ実装をしていかなければならない。