aboutsummaryrefslogtreecommitdiff
path: root/disas/riscv.c
diff options
context:
space:
mode:
Diffstat (limited to 'disas/riscv.c')
-rw-r--r--disas/riscv.c139
1 files changed, 139 insertions, 0 deletions
diff --git a/disas/riscv.c b/disas/riscv.c
index 9f0195b..cd7b6e8 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -829,6 +829,39 @@ typedef enum {
rv_op_fsh = 798,
rv_op_fmv_h_x = 799,
rv_op_fmv_x_h = 800,
+ rv_op_fli_s = 801,
+ rv_op_fli_d = 802,
+ rv_op_fli_q = 803,
+ rv_op_fli_h = 804,
+ rv_op_fminm_s = 805,
+ rv_op_fmaxm_s = 806,
+ rv_op_fminm_d = 807,
+ rv_op_fmaxm_d = 808,
+ rv_op_fminm_q = 809,
+ rv_op_fmaxm_q = 810,
+ rv_op_fminm_h = 811,
+ rv_op_fmaxm_h = 812,
+ rv_op_fround_s = 813,
+ rv_op_froundnx_s = 814,
+ rv_op_fround_d = 815,
+ rv_op_froundnx_d = 816,
+ rv_op_fround_q = 817,
+ rv_op_froundnx_q = 818,
+ rv_op_fround_h = 819,
+ rv_op_froundnx_h = 820,
+ rv_op_fcvtmod_w_d = 821,
+ rv_op_fmvh_x_d = 822,
+ rv_op_fmvp_d_x = 823,
+ rv_op_fmvh_x_q = 824,
+ rv_op_fmvp_q_x = 825,
+ rv_op_fleq_s = 826,
+ rv_op_fltq_s = 827,
+ rv_op_fleq_d = 828,
+ rv_op_fltq_d = 829,
+ rv_op_fleq_q = 830,
+ rv_op_fltq_q = 831,
+ rv_op_fleq_h = 832,
+ rv_op_fltq_h = 833,
} rv_op;
/* register names */
@@ -854,6 +887,23 @@ static const char rv_vreg_name_sym[32][4] = {
"v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
};
+/* The FLI.[HSDQ] numeric constants (0.0 for symbolic constants).
+ * The constants use the hex floating-point literal representation
+ * that is printed when using the printf %a format specifier,
+ * which matches the output that is generated by the disassembler.
+ */
+static const char rv_fli_name_const[32][9] =
+{
+ "0x1p+0", "min", "0x1p-16", "0x1p-15",
+ "0x1p-8", "0x1p-7", "0x1p-4", "0x1p-3",
+ "0x1p-2", "0x1.4p-2", "0x1.8p-2", "0x1.cp-2",
+ "0x1p-1", "0x1.4p-1", "0x1.8p-1", "0x1.cp-1",
+ "0x1p+0", "0x1.4p+0", "0x1.8p+0", "0x1.cp+0",
+ "0x1p+1", "0x1.4p+1", "0x1.8p+1", "0x1p+2",
+ "0x1p+3", "0x1p+4", "0x1p+7", "0x1p+8",
+ "0x1p+15", "0x1p+16", "inf", "nan"
+};
+
/* pseudo-instruction constraints */
static const rvc_constraint rvcc_jal[] = { rvc_rd_eq_ra, rvc_end };
@@ -1925,6 +1975,39 @@ const rv_opcode_data rvi_opcode_data[] = {
{ "fsh", rv_codec_s, rv_fmt_frs2_offset_rs1, NULL, 0, 0, 0 },
{ "fmv.h.x", rv_codec_r, rv_fmt_frd_rs1, NULL, 0, 0, 0 },
{ "fmv.x.h", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
+ { "fli.s", rv_codec_fli, rv_fmt_fli, NULL, 0, 0, 0 },
+ { "fli.d", rv_codec_fli, rv_fmt_fli, NULL, 0, 0, 0 },
+ { "fli.q", rv_codec_fli, rv_fmt_fli, NULL, 0, 0, 0 },
+ { "fli.h", rv_codec_fli, rv_fmt_fli, NULL, 0, 0, 0 },
+ { "fminm.s", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
+ { "fmaxm.s", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
+ { "fminm.d", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
+ { "fmaxm.d", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
+ { "fminm.q", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
+ { "fmaxm.q", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
+ { "fminm.h", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
+ { "fmaxm.h", rv_codec_r, rv_fmt_frd_frs1_frs2, NULL, 0, 0, 0 },
+ { "fround.s", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
+ { "froundnx.s", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
+ { "fround.d", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
+ { "froundnx.d", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
+ { "fround.q", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
+ { "froundnx.q", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
+ { "fround.h", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
+ { "froundnx.h", rv_codec_r_m, rv_fmt_rm_frd_frs1, NULL, 0, 0, 0 },
+ { "fcvtmod.w.d", rv_codec_r_m, rv_fmt_rm_rd_frs1, NULL, 0, 0, 0 },
+ { "fmvh.x.d", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
+ { "fmvp.d.x", rv_codec_r, rv_fmt_frd_rs1_rs2, NULL, 0, 0, 0 },
+ { "fmvh.x.q", rv_codec_r, rv_fmt_rd_frs1, NULL, 0, 0, 0 },
+ { "fmvp.q.x", rv_codec_r, rv_fmt_frd_rs1_rs2, NULL, 0, 0, 0 },
+ { "fleq.s", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
+ { "fltq.s", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
+ { "fleq.d", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
+ { "fltq.d", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
+ { "fleq.q", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
+ { "fltq.q", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
+ { "fleq.h", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
+ { "fltq.h", rv_codec_r, rv_fmt_rd_frs1_frs2, NULL, 0, 0, 0 },
};
/* CSR names */
@@ -2864,24 +2947,38 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_fmin_s; break;
case 1: op = rv_op_fmax_s; break;
+ case 2: op = rv_op_fminm_s; break;
+ case 3: op = rv_op_fmaxm_s; break;
}
break;
case 21:
switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_fmin_d; break;
case 1: op = rv_op_fmax_d; break;
+ case 2: op = rv_op_fminm_d; break;
+ case 3: op = rv_op_fmaxm_d; break;
+ }
+ break;
+ case 22:
+ switch (((inst >> 12) & 0b111)) {
+ case 2: op = rv_op_fminm_h; break;
+ case 3: op = rv_op_fmaxm_h; break;
}
break;
case 23:
switch ((inst >> 12) & 0b111) {
case 0: op = rv_op_fmin_q; break;
case 1: op = rv_op_fmax_q; break;
+ case 2: op = rv_op_fminm_q; break;
+ case 3: op = rv_op_fmaxm_q; break;
}
break;
case 32:
switch ((inst >> 20) & 0b11111) {
case 1: op = rv_op_fcvt_s_d; break;
case 3: op = rv_op_fcvt_s_q; break;
+ case 4: op = rv_op_fround_s; break;
+ case 5: op = rv_op_froundnx_s; break;
case 6: op = rv_op_fcvt_s_bf16; break;
}
break;
@@ -2889,10 +2986,14 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_fcvt_d_s; break;
case 3: op = rv_op_fcvt_d_q; break;
+ case 4: op = rv_op_fround_d; break;
+ case 5: op = rv_op_froundnx_d; break;
}
break;
case 34:
switch (((inst >> 20) & 0b11111)) {
+ case 4: op = rv_op_fround_h; break;
+ case 5: op = rv_op_froundnx_h; break;
case 8: op = rv_op_fcvt_bf16_s; break;
}
break;
@@ -2900,6 +3001,8 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
switch ((inst >> 20) & 0b11111) {
case 0: op = rv_op_fcvt_q_s; break;
case 1: op = rv_op_fcvt_q_d; break;
+ case 4: op = rv_op_fround_q; break;
+ case 5: op = rv_op_froundnx_q; break;
}
break;
case 44:
@@ -2922,6 +3025,8 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 0: op = rv_op_fle_s; break;
case 1: op = rv_op_flt_s; break;
case 2: op = rv_op_feq_s; break;
+ case 4: op = rv_op_fleq_s; break;
+ case 5: op = rv_op_fltq_s; break;
}
break;
case 81:
@@ -2929,6 +3034,14 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 0: op = rv_op_fle_d; break;
case 1: op = rv_op_flt_d; break;
case 2: op = rv_op_feq_d; break;
+ case 4: op = rv_op_fleq_d; break;
+ case 5: op = rv_op_fltq_d; break;
+ }
+ break;
+ case 82:
+ switch (((inst >> 12) & 0b111)) {
+ case 4: op = rv_op_fleq_h; break;
+ case 5: op = rv_op_fltq_h; break;
}
break;
case 83:
@@ -2936,6 +3049,18 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 0: op = rv_op_fle_q; break;
case 1: op = rv_op_flt_q; break;
case 2: op = rv_op_feq_q; break;
+ case 4: op = rv_op_fleq_q; break;
+ case 5: op = rv_op_fltq_q; break;
+ }
+ break;
+ case 89:
+ switch (((inst >> 12) & 0b111)) {
+ case 0: op = rv_op_fmvp_d_x; break;
+ }
+ break;
+ case 91:
+ switch (((inst >> 12) & 0b111)) {
+ case 0: op = rv_op_fmvp_q_x; break;
}
break;
case 96:
@@ -2952,6 +3077,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
case 1: op = rv_op_fcvt_wu_d; break;
case 2: op = rv_op_fcvt_l_d; break;
case 3: op = rv_op_fcvt_lu_d; break;
+ case 8: op = rv_op_fcvtmod_w_d; break;
}
break;
case 99:
@@ -2998,6 +3124,7 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
((inst >> 12) & 0b00000111)) {
case 0: op = rv_op_fmv_x_d; break;
case 1: op = rv_op_fclass_d; break;
+ case 8: op = rv_op_fmvh_x_d; break;
}
break;
case 114:
@@ -3011,30 +3138,35 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
((inst >> 12) & 0b00000111)) {
case 0: op = rv_op_fmv_x_q; break;
case 1: op = rv_op_fclass_q; break;
+ case 8: op = rv_op_fmvh_x_q; break;
}
break;
case 120:
switch (((inst >> 17) & 0b11111000) |
((inst >> 12) & 0b00000111)) {
case 0: op = rv_op_fmv_s_x; break;
+ case 8: op = rv_op_fli_s; break;
}
break;
case 121:
switch (((inst >> 17) & 0b11111000) |
((inst >> 12) & 0b00000111)) {
case 0: op = rv_op_fmv_d_x; break;
+ case 8: op = rv_op_fli_d; break;
}
break;
case 122:
switch (((inst >> 17) & 0b11111000) |
((inst >> 12) & 0b00000111)) {
case 0: op = rv_op_fmv_h_x; break;
+ case 8: op = rv_op_fli_h; break;
}
break;
case 123:
switch (((inst >> 17) & 0b11111000) |
((inst >> 12) & 0b00000111)) {
case 0: op = rv_op_fmv_q_x; break;
+ case 8: op = rv_op_fli_q; break;
}
break;
}
@@ -4298,6 +4430,10 @@ static void decode_inst_operands(rv_decode *dec, rv_isa isa)
break;
case rv_codec_zcmt_jt:
dec->imm = operand_tbl_index(inst);
+ break;
+ case rv_codec_fli:
+ dec->rd = operand_rd(inst);
+ dec->imm = operand_rs1(inst);
break;
case rv_codec_r2_imm5:
dec->rd = operand_rd(inst);
@@ -4708,6 +4844,9 @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec)
append(buf, tmp, buflen);
break;
}
+ case 'h':
+ append(buf, rv_fli_name_const[dec->imm], buflen);
+ break;
default:
break;
}