[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] riscv/disas: Fix disas output of upper immediates
From: |
Alistair Francis |
Subject: |
Re: [PATCH] riscv/disas: Fix disas output of upper immediates |
Date: |
Fri, 14 Jul 2023 12:50:53 +1000 |
On Tue, Jul 11, 2023 at 5:52 PM Christoph Muellner
<christoph.muellner@vrull.eu> wrote:
>
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> The GNU assembler produces the following output for instructions
> with upper immediates:
> 00002597 auipc a1,0x2
> 000024b7 lui s1,0x2
> 6409 lui s0,0x2 # c.lui
>
> The immediate operands of upper immediates are not shifted.
>
> However, the QEMU disassembler prints them shifted:
> 00002597 auipc a1,8192
> 000024b7 lui s1,8192
> 6409 lui s0,8192 # c.lui
>
> The current implementation extracts the immediate bits and shifts the by 12,
> so the internal representation of the immediate is the actual immediate.
> However, the immediates are later printed using rv_fmt_rd_imm or
> rv_fmt_rd_offset, which don't undo the shift.
>
> Let's fix this by using specific output formats for instructions
> with upper immediates, that take care of the shift.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Alistair
> ---
> disas/riscv.c | 19 ++++++++++++++++---
> disas/riscv.h | 2 ++
> 2 files changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/disas/riscv.c b/disas/riscv.c
> index cd7b6e86a7..3873a69157 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -1135,8 +1135,8 @@ static const rv_comp_data rvcp_fsgnjx_q[] = {
>
> const rv_opcode_data rvi_opcode_data[] = {
> { "illegal", rv_codec_illegal, rv_fmt_none, NULL, 0, 0, 0 },
> - { "lui", rv_codec_u, rv_fmt_rd_imm, NULL, 0, 0, 0 },
> - { "auipc", rv_codec_u, rv_fmt_rd_offset, NULL, 0, 0, 0 },
> + { "lui", rv_codec_u, rv_fmt_rd_uimm, NULL, 0, 0, 0 },
> + { "auipc", rv_codec_u, rv_fmt_rd_uoffset, NULL, 0, 0, 0 },
> { "jal", rv_codec_uj, rv_fmt_rd_offset, rvcp_jal, 0, 0, 0 },
> { "jalr", rv_codec_i, rv_fmt_rd_rs1_offset, rvcp_jalr, 0, 0, 0 },
> { "beq", rv_codec_sb, rv_fmt_rs1_rs2_offset, rvcp_beq, 0, 0, 0 },
> @@ -1382,7 +1382,7 @@ const rv_opcode_data rvi_opcode_data[] = {
> rv_op_addi },
> { "c.addi16sp", rv_codec_ci_16sp, rv_fmt_rd_rs1_imm, NULL, rv_op_addi,
> rv_op_addi, rv_op_addi, rvcd_imm_nz },
> - { "c.lui", rv_codec_ci_lui, rv_fmt_rd_imm, NULL, rv_op_lui, rv_op_lui,
> + { "c.lui", rv_codec_ci_lui, rv_fmt_rd_uimm, NULL, rv_op_lui, rv_op_lui,
> rv_op_lui, rvcd_imm_nz },
> { "c.srli", rv_codec_cb_sh6, rv_fmt_rd_rs1_imm, NULL, rv_op_srli,
> rv_op_srli, rv_op_srli, rvcd_imm_nz },
> @@ -4694,6 +4694,19 @@ static void format_inst(char *buf, size_t buflen,
> size_t tab, rv_decode *dec)
> dec->pc + dec->imm);
> append(buf, tmp, buflen);
> break;
> + case 'U':
> + fmt++;
> + snprintf(tmp, sizeof(tmp), "%d", dec->imm >> 12);
> + append(buf, tmp, buflen);
> + if (*fmt == 'o') {
> + while (strlen(buf) < tab * 2) {
> + append(buf, " ", buflen);
> + }
> + snprintf(tmp, sizeof(tmp), "# 0x%" PRIx64,
> + dec->pc + dec->imm);
> + append(buf, tmp, buflen);
> + }
> + break;
> case 'c': {
> const char *name = csr_name(dec->imm & 0xfff);
> if (name) {
> diff --git a/disas/riscv.h b/disas/riscv.h
> index 9cf901fc1e..8abb578b51 100644
> --- a/disas/riscv.h
> +++ b/disas/riscv.h
> @@ -227,7 +227,9 @@ enum {
> #define rv_fmt_pred_succ "O\tp,s"
> #define rv_fmt_rs1_rs2 "O\t1,2"
> #define rv_fmt_rd_imm "O\t0,i"
> +#define rv_fmt_rd_uimm "O\t0,Ui"
> #define rv_fmt_rd_offset "O\t0,o"
> +#define rv_fmt_rd_uoffset "O\t0,Uo"
> #define rv_fmt_rd_rs1_rs2 "O\t0,1,2"
> #define rv_fmt_frd_rs1 "O\t3,1"
> #define rv_fmt_frd_rs1_rs2 "O\t3,1,2"
> --
> 2.41.0
>
>