【指令仿真】仿真一条指令

新增一条求立方的指令 cube(4)=64,设计一条 RISC-V 的算数指令 cube,指令编码格式遵循 R-type,语义为:rd = [rs1] * [rs1] * [rs1]

一、仿真

1、定义参数类型

定义cube格式参数有rs1,rd

# Argument sets:
&empty
&b    imm rs2 rs1
&i    imm rs1 rd
&j    imm rd
&r    rd rs1 rs2
&r2   rd rs1
&r2_s rs1 rs2
&s    imm rs1 rs2
&u    imm rd
&cube      rs1 rd
&shift     shamt rs1 rd

2、定义format

使用cube格式定义一个cube指令

参数分别是%rs1, %rd

# Formats 
@cube      ...... ...... ..... ... ..... ....... &cube       %rs1 %rd

3、定义pattern

根据r-type的格式,填写pattern

4.1、填写cube指令的trans函数(非helper实现)

拿到rs1的值,进行立方乘法,把结果放入到rd中

static bool trans_cube(DisasContext *ctx, arg_cube *a)
{
    TCGv tmp_rs1 = get_gpr(ctx, a->rs1, EXT_NONE);
    TCGv tmp_rs2 = tcg_temp_new();
    TCGv tmp_rd = dest_gpr(ctx, a->rd);

    tcg_gen_mul_tl(tmp_rs2, tmp_rs1, tmp_rs1);
    tcg_gen_mul_tl(tmp_rd, tmp_rs2, tmp_rs1);

    return true;
}

4.2、填写cube指令的trans函数(helper实现)

// target/riscv/helper.h
DEF_HELPER_3(cube, void, env, tl, tl)

// target/riscv/op_helper.c
void helper_cube(CPURISCVState *env, target_ulong rd, target_ulong rs1)
{
    MemOpIdx oi = make_memop_idx(MO_TEUQ, 0);
    target_ulong val = cpu_ldq_mmu(env, env->gpr[rs1], oi, GETPC());
    env->gpr[rd] = val * val * val;
}

// target/riscv/insn_trans/trans_rvi.c.inc
static bool trans_cube(DisasContext *ctx, arg_cube *a)
{
    gen_helper_cube(tcg_env, tcg_constant_tl(a->rd), tcg_constant_tl(a->rs1));
    return true;
}

二、使用

5、调整guest代码

    int rd;
    int cube = 3;
    __asm__ __volatile__ (
        ".insn r 0x7b, 6 ,6, %0, %1, x0" : "=r"(rd) : "r"(cube)
    );
QEMU指令仿真 文章被收录于专栏

riscv指令仿真

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务