mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-22 19:51:10 +00:00
target/riscv: Convert RV64D insns to decodetree
Backports commit 31fe4d35f2608daecb2319c81e0bb4af81b398ae from qemu
This commit is contained in:
parent
71f2ed2959
commit
7475207aba
|
@ -62,3 +62,11 @@ fcvt_l_s 1100000 00010 ..... ... ..... 1010011 @r2_rm
|
||||||
fcvt_lu_s 1100000 00011 ..... ... ..... 1010011 @r2_rm
|
fcvt_lu_s 1100000 00011 ..... ... ..... 1010011 @r2_rm
|
||||||
fcvt_s_l 1101000 00010 ..... ... ..... 1010011 @r2_rm
|
fcvt_s_l 1101000 00010 ..... ... ..... 1010011 @r2_rm
|
||||||
fcvt_s_lu 1101000 00011 ..... ... ..... 1010011 @r2_rm
|
fcvt_s_lu 1101000 00011 ..... ... ..... 1010011 @r2_rm
|
||||||
|
|
||||||
|
# *** RV64D Standard Extension (in addition to RV32D) ***
|
||||||
|
fcvt_l_d 1100001 00010 ..... ... ..... 1010011 @r2_rm
|
||||||
|
fcvt_lu_d 1100001 00011 ..... ... ..... 1010011 @r2_rm
|
||||||
|
fmv_x_d 1110001 00000 ..... 000 ..... 1010011 @r2
|
||||||
|
fcvt_d_l 1101001 00010 ..... ... ..... 1010011 @r2_rm
|
||||||
|
fcvt_d_lu 1101001 00011 ..... ... ..... 1010011 @r2_rm
|
||||||
|
fmv_d_x 1111001 00000 ..... 000 ..... 1010011 @r2
|
||||||
|
|
|
@ -410,3 +410,97 @@ static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a)
|
||||||
mark_fs_dirty(ctx);
|
mark_fs_dirty(ctx);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TARGET_RISCV64
|
||||||
|
|
||||||
|
static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a)
|
||||||
|
{
|
||||||
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
|
|
||||||
|
REQUIRE_FPU;
|
||||||
|
REQUIRE_EXT(ctx, RVD);
|
||||||
|
|
||||||
|
TCGv t0 = tcg_temp_new(tcg_ctx);
|
||||||
|
gen_set_rm(ctx, a->rm);
|
||||||
|
gen_helper_fcvt_l_d(tcg_ctx, t0, tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[a->rs1]);
|
||||||
|
gen_set_gpr(ctx, a->rd, t0);
|
||||||
|
tcg_temp_free(tcg_ctx, t0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a)
|
||||||
|
{
|
||||||
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
|
|
||||||
|
REQUIRE_FPU;
|
||||||
|
REQUIRE_EXT(ctx, RVD);
|
||||||
|
|
||||||
|
TCGv t0 = tcg_temp_new(tcg_ctx);
|
||||||
|
gen_set_rm(ctx, a->rm);
|
||||||
|
gen_helper_fcvt_lu_d(tcg_ctx, t0, tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[a->rs1]);
|
||||||
|
gen_set_gpr(ctx, a->rd, t0);
|
||||||
|
tcg_temp_free(tcg_ctx, t0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool trans_fmv_x_d(DisasContext *ctx, arg_fmv_x_d *a)
|
||||||
|
{
|
||||||
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
|
|
||||||
|
REQUIRE_FPU;
|
||||||
|
REQUIRE_EXT(ctx, RVD);
|
||||||
|
|
||||||
|
gen_set_gpr(ctx, a->rd, tcg_ctx->cpu_fpr_risc[a->rs1]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a)
|
||||||
|
{
|
||||||
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
|
|
||||||
|
REQUIRE_FPU;
|
||||||
|
REQUIRE_EXT(ctx, RVD);
|
||||||
|
|
||||||
|
TCGv t0 = tcg_temp_new(tcg_ctx);
|
||||||
|
gen_get_gpr(ctx, t0, a->rs1);
|
||||||
|
|
||||||
|
gen_set_rm(ctx, a->rm);
|
||||||
|
gen_helper_fcvt_d_l(tcg_ctx, tcg_ctx->cpu_fpr_risc[a->rd], tcg_ctx->cpu_env, t0);
|
||||||
|
tcg_temp_free(tcg_ctx, t0);
|
||||||
|
mark_fs_dirty(ctx);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a)
|
||||||
|
{
|
||||||
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
|
|
||||||
|
REQUIRE_FPU;
|
||||||
|
REQUIRE_EXT(ctx, RVD);
|
||||||
|
|
||||||
|
TCGv t0 = tcg_temp_new(tcg_ctx);
|
||||||
|
gen_get_gpr(ctx, t0, a->rs1);
|
||||||
|
|
||||||
|
gen_set_rm(ctx, a->rm);
|
||||||
|
gen_helper_fcvt_d_lu(tcg_ctx, tcg_ctx->cpu_fpr_risc[a->rd], tcg_ctx->cpu_env, t0);
|
||||||
|
tcg_temp_free(tcg_ctx, t0);
|
||||||
|
mark_fs_dirty(ctx);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a)
|
||||||
|
{
|
||||||
|
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
||||||
|
|
||||||
|
REQUIRE_FPU;
|
||||||
|
REQUIRE_EXT(ctx, RVD);
|
||||||
|
|
||||||
|
TCGv t0 = tcg_temp_new(tcg_ctx);
|
||||||
|
gen_get_gpr(ctx, t0, a->rs1);
|
||||||
|
|
||||||
|
tcg_gen_mov_tl(tcg_ctx, tcg_ctx->cpu_fpr_risc[a->rd], t0);
|
||||||
|
tcg_temp_free(tcg_ctx, t0);
|
||||||
|
mark_fs_dirty(ctx);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -199,47 +199,6 @@ static void gen_mulhsu(const DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2)
|
||||||
tcg_temp_free(tcg_ctx, rh);
|
tcg_temp_free(tcg_ctx, rh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_fsgnj(DisasContext *ctx, uint32_t rd, uint32_t rs1,
|
|
||||||
uint32_t rs2, int rm, uint64_t min)
|
|
||||||
{
|
|
||||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
|
||||||
|
|
||||||
switch (rm) {
|
|
||||||
case 0: /* fsgnj */
|
|
||||||
if (rs1 == rs2) { /* FMOV */
|
|
||||||
tcg_gen_mov_i64(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
} else {
|
|
||||||
tcg_gen_deposit_i64(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd],
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs2], tcg_ctx->cpu_fpr_risc[rs1],
|
|
||||||
0, min == INT32_MIN ? 31 : 63);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1: /* fsgnjn */
|
|
||||||
if (rs1 == rs2) { /* FNEG */
|
|
||||||
tcg_gen_xori_i64(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_fpr_risc[rs1], min);
|
|
||||||
} else {
|
|
||||||
TCGv_i64 t0 = tcg_temp_new_i64(tcg_ctx);
|
|
||||||
tcg_gen_not_i64(tcg_ctx, t0, tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
tcg_gen_deposit_i64(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], t0, tcg_ctx->cpu_fpr_risc[rs1],
|
|
||||||
0, min == INT32_MIN ? 31 : 63);
|
|
||||||
tcg_temp_free_i64(tcg_ctx, t0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2: /* fsgnjx */
|
|
||||||
if (rs1 == rs2) { /* FABS */
|
|
||||||
tcg_gen_andi_i64(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_fpr_risc[rs1], ~min);
|
|
||||||
} else {
|
|
||||||
TCGv_i64 t0 = tcg_temp_new_i64(tcg_ctx);
|
|
||||||
tcg_gen_andi_i64(tcg_ctx, t0, tcg_ctx->cpu_fpr_risc[rs2], min);
|
|
||||||
tcg_gen_xor_i64(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_fpr_risc[rs1], t0);
|
|
||||||
tcg_temp_free_i64(tcg_ctx, t0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
gen_exception_illegal(ctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gen_arith(DisasContext *ctx, uint32_t opc, int rd, int rs1,
|
static void gen_arith(DisasContext *ctx, uint32_t opc, int rd, int rs1,
|
||||||
int rs2)
|
int rs2)
|
||||||
{
|
{
|
||||||
|
@ -835,573 +794,6 @@ static void gen_set_rm(DisasContext *ctx, int rm)
|
||||||
tcg_temp_free_i32(tcg_ctx, t0);
|
tcg_temp_free_i32(tcg_ctx, t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_fp_fmadd(DisasContext *ctx, uint32_t opc, int rd,
|
|
||||||
int rs1, int rs2, int rs3, int rm)
|
|
||||||
{
|
|
||||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
|
||||||
|
|
||||||
switch (opc) {
|
|
||||||
case OPC_RISC_FMADD_S:
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fmadd_s(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd],
|
|
||||||
tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1],
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs2], tcg_ctx->cpu_fpr_risc[rs3]);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FMADD_D:
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fmadd_d(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd],
|
|
||||||
tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1],
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs2], tcg_ctx->cpu_fpr_risc[rs3]);
|
|
||||||
break;
|
|
||||||
do_illegal:
|
|
||||||
default:
|
|
||||||
gen_exception_illegal(ctx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gen_fp_fmsub(DisasContext *ctx, uint32_t opc, int rd,
|
|
||||||
int rs1, int rs2, int rs3, int rm)
|
|
||||||
{
|
|
||||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
|
||||||
|
|
||||||
switch (opc) {
|
|
||||||
case OPC_RISC_FMSUB_S:
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fmsub_s(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd],
|
|
||||||
tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1],
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs2], tcg_ctx->cpu_fpr_risc[rs3]);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FMSUB_D:
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fmsub_d(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd],
|
|
||||||
tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1],
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs2], tcg_ctx->cpu_fpr_risc[rs3]);
|
|
||||||
break;
|
|
||||||
do_illegal:
|
|
||||||
default:
|
|
||||||
gen_exception_illegal(ctx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gen_fp_fnmsub(DisasContext *ctx, uint32_t opc, int rd,
|
|
||||||
int rs1, int rs2, int rs3, int rm)
|
|
||||||
{
|
|
||||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
|
||||||
|
|
||||||
switch (opc) {
|
|
||||||
case OPC_RISC_FNMSUB_S:
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fnmsub_s(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd],
|
|
||||||
tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1],
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs2], tcg_ctx->cpu_fpr_risc[rs3]);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FNMSUB_D:
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fnmsub_d(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd],
|
|
||||||
tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1],
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs2], tcg_ctx->cpu_fpr_risc[rs3]);
|
|
||||||
break;
|
|
||||||
do_illegal:
|
|
||||||
default:
|
|
||||||
gen_exception_illegal(ctx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gen_fp_fnmadd(DisasContext *ctx, uint32_t opc, int rd,
|
|
||||||
int rs1, int rs2, int rs3, int rm)
|
|
||||||
{
|
|
||||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
|
||||||
|
|
||||||
switch (opc) {
|
|
||||||
case OPC_RISC_FNMADD_S:
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fnmadd_s(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd],
|
|
||||||
tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1],
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs2], tcg_ctx->cpu_fpr_risc[rs3]);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FNMADD_D:
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fnmadd_d(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd],
|
|
||||||
tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1],
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs2], tcg_ctx->cpu_fpr_risc[rs3]);
|
|
||||||
break;
|
|
||||||
do_illegal:
|
|
||||||
default:
|
|
||||||
gen_exception_illegal(ctx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gen_fp_arith(DisasContext *ctx, uint32_t opc, int rd,
|
|
||||||
int rs1, int rs2, int rm)
|
|
||||||
{
|
|
||||||
TCGContext *tcg_ctx = ctx->uc->tcg_ctx;
|
|
||||||
TCGv t0 = NULL;
|
|
||||||
bool fp_output = true;
|
|
||||||
|
|
||||||
if (ctx->mstatus_fs == 0) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (opc) {
|
|
||||||
case OPC_RISC_FADD_S:
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fadd_s(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FSUB_S:
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fsub_s(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FMUL_S:
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fmul_s(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FDIV_S:
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fdiv_s(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FSQRT_S:
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fsqrt_s(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd],
|
|
||||||
tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FSGNJ_S:
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_fsgnj(ctx, rd, rs1, rs2, rm, INT32_MIN);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPC_RISC_FMIN_S:
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
/* also handles: OPC_RISC_FMAX_S */
|
|
||||||
switch (rm) {
|
|
||||||
case 0x0:
|
|
||||||
gen_helper_fmin_s(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
case 0x1:
|
|
||||||
gen_helper_fmax_s(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPC_RISC_FEQ_S:
|
|
||||||
/* also handles: OPC_RISC_FLT_S, OPC_RISC_FLE_S */
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
t0 = tcg_temp_new(tcg_ctx);
|
|
||||||
switch (rm) {
|
|
||||||
case 0x0:
|
|
||||||
gen_helper_fle_s(tcg_ctx, t0, tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
case 0x1:
|
|
||||||
gen_helper_flt_s(tcg_ctx, t0, tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
case 0x2:
|
|
||||||
gen_helper_feq_s(tcg_ctx, t0, tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_gpr(ctx, rd, t0);
|
|
||||||
tcg_temp_free(tcg_ctx, t0);
|
|
||||||
fp_output = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPC_RISC_FCVT_W_S:
|
|
||||||
/* also OPC_RISC_FCVT_WU_S, OPC_RISC_FCVT_L_S, OPC_RISC_FCVT_LU_S */
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
t0 = tcg_temp_new(tcg_ctx);
|
|
||||||
switch (rs2) {
|
|
||||||
case 0: /* FCVT_W_S */
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_w_s(tcg_ctx, t0, tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
break;
|
|
||||||
case 1: /* FCVT_WU_S */
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_wu_s(tcg_ctx, t0, tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
break;
|
|
||||||
#if defined(TARGET_RISCV64)
|
|
||||||
case 2: /* FCVT_L_S */
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_l_s(tcg_ctx, t0, tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
break;
|
|
||||||
case 3: /* FCVT_LU_S */
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_lu_s(tcg_ctx, t0, tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_gpr(ctx, rd, t0);
|
|
||||||
tcg_temp_free(tcg_ctx, t0);
|
|
||||||
fp_output = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPC_RISC_FCVT_S_W:
|
|
||||||
/* also OPC_RISC_FCVT_S_WU, OPC_RISC_FCVT_S_L, OPC_RISC_FCVT_S_LU */
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
t0 = tcg_temp_new(tcg_ctx);
|
|
||||||
gen_get_gpr(ctx, t0, rs1);
|
|
||||||
switch (rs2) {
|
|
||||||
case 0: /* FCVT_S_W */
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_s_w(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env, t0);
|
|
||||||
break;
|
|
||||||
case 1: /* FCVT_S_WU */
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_s_wu(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env, t0);
|
|
||||||
break;
|
|
||||||
#if defined(TARGET_RISCV64)
|
|
||||||
case 2: /* FCVT_S_L */
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_s_l(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env, t0);
|
|
||||||
break;
|
|
||||||
case 3: /* FCVT_S_LU */
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_s_lu(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env, t0);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
tcg_temp_free(tcg_ctx, t0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPC_RISC_FMV_X_S:
|
|
||||||
/* also OPC_RISC_FCLASS_S */
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
t0 = tcg_temp_new(tcg_ctx);
|
|
||||||
switch (rm) {
|
|
||||||
case 0: /* FMV */
|
|
||||||
#if defined(TARGET_RISCV64)
|
|
||||||
tcg_gen_ext32s_tl(tcg_ctx, t0, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
#else
|
|
||||||
tcg_gen_extrl_i64_i32(tcg_ctx, t0, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
gen_helper_fclass_s(tcg_ctx, t0, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_gpr(ctx, rd, t0);
|
|
||||||
tcg_temp_free(tcg_ctx, t0);
|
|
||||||
fp_output = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPC_RISC_FMV_S_X:
|
|
||||||
if (!has_ext(ctx, RVF)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
t0 = tcg_temp_new(tcg_ctx);
|
|
||||||
gen_get_gpr(ctx, t0, rs1);
|
|
||||||
#if defined(TARGET_RISCV64)
|
|
||||||
tcg_gen_mov_i64(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], t0);
|
|
||||||
#else
|
|
||||||
tcg_gen_extu_i32_i64(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], t0);
|
|
||||||
#endif
|
|
||||||
tcg_temp_free(tcg_ctx, t0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* double */
|
|
||||||
case OPC_RISC_FADD_D:
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fadd_d(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FSUB_D:
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fsub_d(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FMUL_D:
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fmul_d(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FDIV_D:
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fdiv_d(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FSQRT_D:
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fsqrt_d(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FSGNJ_D:
|
|
||||||
gen_fsgnj(ctx, rd, rs1, rs2, rm, INT64_MIN);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPC_RISC_FMIN_D:
|
|
||||||
/* also OPC_RISC_FMAX_D */
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
switch (rm) {
|
|
||||||
case 0:
|
|
||||||
gen_helper_fmin_d(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
gen_helper_fmax_d(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPC_RISC_FCVT_S_D:
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
switch (rs2) {
|
|
||||||
case 1:
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_s_d(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd],
|
|
||||||
tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPC_RISC_FCVT_D_S:
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
switch (rs2) {
|
|
||||||
case 0:
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_d_s(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd],
|
|
||||||
tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPC_RISC_FEQ_D:
|
|
||||||
/* also OPC_RISC_FLT_D, OPC_RISC_FLE_D */
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
t0 = tcg_temp_new(tcg_ctx);
|
|
||||||
switch (rm) {
|
|
||||||
case 0:
|
|
||||||
gen_helper_fle_d(tcg_ctx, t0, tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
gen_helper_flt_d(tcg_ctx, t0, tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gen_helper_feq_d(tcg_ctx, t0, tcg_ctx->cpu_env,
|
|
||||||
tcg_ctx->cpu_fpr_risc[rs1], tcg_ctx->cpu_fpr_risc[rs2]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_gpr(ctx, rd, t0);
|
|
||||||
tcg_temp_free(tcg_ctx, t0);
|
|
||||||
fp_output = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPC_RISC_FCVT_W_D:
|
|
||||||
/* also OPC_RISC_FCVT_WU_D, OPC_RISC_FCVT_L_D, OPC_RISC_FCVT_LU_D */
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
t0 = tcg_temp_new(tcg_ctx);
|
|
||||||
switch (rs2) {
|
|
||||||
case 0:
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_w_d(tcg_ctx, t0, tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_wu_d(tcg_ctx, t0, tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
break;
|
|
||||||
#if defined(TARGET_RISCV64)
|
|
||||||
case 2:
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_l_d(tcg_ctx, t0, tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_lu_d(tcg_ctx, t0, tcg_ctx->cpu_env, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
gen_set_gpr(ctx, rd, t0);
|
|
||||||
tcg_temp_free(tcg_ctx, t0);
|
|
||||||
fp_output = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPC_RISC_FCVT_D_W:
|
|
||||||
/* also OPC_RISC_FCVT_D_WU, OPC_RISC_FCVT_D_L, OPC_RISC_FCVT_D_LU */
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
t0 = tcg_temp_new(tcg_ctx);
|
|
||||||
gen_get_gpr(ctx, t0, rs1);
|
|
||||||
switch (rs2) {
|
|
||||||
case 0:
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_d_w(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env, t0);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_d_wu(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env, t0);
|
|
||||||
break;
|
|
||||||
#if defined(TARGET_RISCV64)
|
|
||||||
case 2:
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_d_l(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env, t0);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
gen_set_rm(ctx, rm);
|
|
||||||
gen_helper_fcvt_d_lu(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], tcg_ctx->cpu_env, t0);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
tcg_temp_free(tcg_ctx, t0);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OPC_RISC_FMV_X_D:
|
|
||||||
/* also OPC_RISC_FCLASS_D */
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
switch (rm) {
|
|
||||||
#if defined(TARGET_RISCV64)
|
|
||||||
case 0: /* FMV */
|
|
||||||
gen_set_gpr(ctx, rd, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case 1:
|
|
||||||
t0 = tcg_temp_new(tcg_ctx);
|
|
||||||
gen_helper_fclass_d(tcg_ctx, t0, tcg_ctx->cpu_fpr_risc[rs1]);
|
|
||||||
gen_set_gpr(ctx, rd, t0);
|
|
||||||
tcg_temp_free(tcg_ctx, t0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
fp_output = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
#if defined(TARGET_RISCV64)
|
|
||||||
case OPC_RISC_FMV_D_X:
|
|
||||||
if (!has_ext(ctx, RVD)) {
|
|
||||||
goto do_illegal;
|
|
||||||
}
|
|
||||||
t0 = tcg_temp_new(tcg_ctx);
|
|
||||||
gen_get_gpr(ctx, t0, rs1);
|
|
||||||
tcg_gen_mov_tl(tcg_ctx, tcg_ctx->cpu_fpr_risc[rd], t0);
|
|
||||||
tcg_temp_free(tcg_ctx, t0);
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
|
||||||
do_illegal:
|
|
||||||
if (t0) {
|
|
||||||
tcg_temp_free(tcg_ctx, t0);
|
|
||||||
}
|
|
||||||
gen_exception_illegal(ctx);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fp_output) {
|
|
||||||
mark_fs_dirty(ctx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
|
static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
|
||||||
int csr)
|
int csr)
|
||||||
{
|
{
|
||||||
|
@ -1791,11 +1183,8 @@ bool decode_insn32(DisasContext *ctx, uint32_t insn);
|
||||||
|
|
||||||
static void decode_RV32_64G(DisasContext *ctx)
|
static void decode_RV32_64G(DisasContext *ctx)
|
||||||
{
|
{
|
||||||
int rs1;
|
int rs1, rd;
|
||||||
int rs2;
|
|
||||||
int rd;
|
|
||||||
uint32_t op;
|
uint32_t op;
|
||||||
target_long imm;
|
|
||||||
|
|
||||||
/* We do not do misaligned address check here: the address should never be
|
/* We do not do misaligned address check here: the address should never be
|
||||||
* misaligned at this point. Instructions that set PC must do the check,
|
* misaligned at this point. Instructions that set PC must do the check,
|
||||||
|
@ -1804,38 +1193,9 @@ static void decode_RV32_64G(DisasContext *ctx)
|
||||||
|
|
||||||
op = MASK_OP_MAJOR(ctx->opcode);
|
op = MASK_OP_MAJOR(ctx->opcode);
|
||||||
rs1 = GET_RS1(ctx->opcode);
|
rs1 = GET_RS1(ctx->opcode);
|
||||||
rs2 = GET_RS2(ctx->opcode);
|
|
||||||
rd = GET_RD(ctx->opcode);
|
rd = GET_RD(ctx->opcode);
|
||||||
imm = GET_IMM(ctx->opcode);
|
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case OPC_RISC_FP_LOAD:
|
|
||||||
gen_fp_load(ctx, MASK_OP_FP_LOAD(ctx->opcode), rd, rs1, imm);
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FP_STORE:
|
|
||||||
gen_fp_store(ctx, MASK_OP_FP_STORE(ctx->opcode), rs1, rs2,
|
|
||||||
GET_STORE_IMM(ctx->opcode));
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FMADD:
|
|
||||||
gen_fp_fmadd(ctx, MASK_OP_FP_FMADD(ctx->opcode), rd, rs1, rs2,
|
|
||||||
GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FMSUB:
|
|
||||||
gen_fp_fmsub(ctx, MASK_OP_FP_FMSUB(ctx->opcode), rd, rs1, rs2,
|
|
||||||
GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FNMSUB:
|
|
||||||
gen_fp_fnmsub(ctx, MASK_OP_FP_FNMSUB(ctx->opcode), rd, rs1, rs2,
|
|
||||||
GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FNMADD:
|
|
||||||
gen_fp_fnmadd(ctx, MASK_OP_FP_FNMADD(ctx->opcode), rd, rs1, rs2,
|
|
||||||
GET_RS3(ctx->opcode), GET_RM(ctx->opcode));
|
|
||||||
break;
|
|
||||||
case OPC_RISC_FP_ARITH:
|
|
||||||
gen_fp_arith(ctx, MASK_OP_FP_ARITH(ctx->opcode), rd, rs1, rs2,
|
|
||||||
GET_RM(ctx->opcode));
|
|
||||||
break;
|
|
||||||
case OPC_RISC_SYSTEM:
|
case OPC_RISC_SYSTEM:
|
||||||
gen_system(ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
|
gen_system(ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
|
||||||
(ctx->opcode & 0xFFF00000) >> 20);
|
(ctx->opcode & 0xFFF00000) >> 20);
|
||||||
|
|
Loading…
Reference in a new issue