【指令仿真】仿真一条指令
新增一条求立方的指令 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指令仿真
查看7道真题和解析