Re: [PATCH v14 16/26] target/loongarch: Add disassembler

2022-01-09 Thread Richard Henderson

On 1/9/22 1:25 AM, WANG Xuerui wrote:

+static inline int shl_2(DisasContext *ctx, int x)
+{
+    return x * 4;
Although "<< 2" has the same effect as "* 4" here, isn't "<< 2" better in matching the 
function name?


Yes, good point.


r~



Re: [PATCH v14 16/26] target/loongarch: Add disassembler

2022-01-09 Thread WANG Xuerui



On 1/6/22 17:41, Song Gao wrote:

This patch adds support for disassembling via option '-d in_asm'.

Signed-off-by: Song Gao
Signed-off-by: Xiaojuan Yang
Reviewed-by: Richard Henderson
---
  include/disas/dis-asm.h  |   2 +
  meson.build  |   1 +
  target/loongarch/disas.c | 612 +++
  3 files changed, 615 insertions(+)
  create mode 100644 target/loongarch/disas.c

diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index 08e1beec85..aeab30f19c 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -253,6 +253,7 @@ enum bfd_architecture
  #define bfd_mach_rx0x75
  #define bfd_mach_rx_v2 0x76
  #define bfd_mach_rx_v3 0x77
+  bfd_arch_loongarch,
bfd_arch_last
};
  #define bfd_mach_s390_31 31
@@ -461,6 +462,7 @@ int print_insn_riscv32  (bfd_vma, 
disassemble_info*);
  int print_insn_riscv64  (bfd_vma, disassemble_info*);
  int print_insn_rx(bfd_vma, disassemble_info *);
  int print_insn_hexagon(bfd_vma, disassemble_info *);
+int print_insn_loongarch(bfd_vma, disassemble_info *);
  
  #ifdef CONFIG_CAPSTONE

  bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size);
diff --git a/meson.build b/meson.build
index 53065e96ec..fa4c6dd241 100644
--- a/meson.build
+++ b/meson.build
@@ -1848,6 +1848,7 @@ disassemblers = {
'sh4' : ['CONFIG_SH4_DIS'],
'sparc' : ['CONFIG_SPARC_DIS'],
'xtensa' : ['CONFIG_XTENSA_DIS'],
+  'loongarch' : ['CONFIG_LOONGARCH_DIS'],
  }
  if link_language == 'cpp'
disassemblers += {
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
new file mode 100644
index 00..45be34de27
--- /dev/null
+++ b/target/loongarch/disas.c
@@ -0,0 +1,612 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch Disassembler
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited.
+ */
+
+#include "qemu/osdep.h"
+#include "disas/dis-asm.h"
+#include "qemu/bitops.h"
+
+typedef struct {
+disassemble_info *info;
+uint64_t pc;
+uint32_t insn;
+} DisasContext;
+
+static inline int plus_1(DisasContext *ctx, int x)
+{
+return x + 1;
+}
+
+static inline int shl_2(DisasContext *ctx, int x)
+{
+return x * 4;
Although "<< 2" has the same effect as "* 4" here, isn't "<< 2" better 
in matching the function name?

+}
+
+#define output(C, INSN, FMT, ...)   \
+{   \
+(C)->info->fprintf_func((C)->info->stream, "%08x   %-9s\t" FMT, \
+(C)->insn, INSN, ##__VA_ARGS__);\
+}
+
+#include "decode-insns.c.inc"
+
+int print_insn_loongarch(bfd_vma memaddr, struct disassemble_info *info)
+{
+bfd_byte buffer[4];
+uint32_t insn;
+int status;
+
+status = (*info->read_memory_func)(memaddr, buffer, 4, info);
+if (status != 0) {
+(*info->memory_error_func)(status, memaddr, info);
+return -1;
+}
+insn = bfd_getl32(buffer);
+DisasContext ctx = {
+.info = info,
+.pc = memaddr,
+.insn = insn
+};
+
+if (!decode(, insn)) {
+output(, "illegal", "");
+}
+return 4;
+}
+
+static void output_r_i(DisasContext *ctx, arg_r_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, %d", a->rd, a->imm);
+}
+
+static void output_rrr(DisasContext *ctx, arg_rrr *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, r%d", a->rd, a->rj, a->rk);
+}
+
+static void output_rr_i(DisasContext *ctx, arg_rr_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, %d", a->rd, a->rj, a->imm);
+}
+
+static void output_rrr_sa(DisasContext *ctx, arg_rrr_sa *a,
+  const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, r%d, %d", a->rd, a->rj, a->rk, a->sa);
+}
+
+static void output_rr(DisasContext *ctx, arg_rr *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d", a->rd, a->rj);
+}
+
+static void output_rr_ms_ls(DisasContext *ctx, arg_rr_ms_ls *a,
+  const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d, %d, %d", a->rd, a->rj, a->ms, a->ls);
+}
+
+static void output_hint_r_i(DisasContext *ctx, arg_hint_r_i *a,
+const char *mnemonic)
+{
+output(ctx, mnemonic, "%d, r%d, %d", a->hint, a->rj, a->imm);
+}
+
+static void output_i(DisasContext *ctx, arg_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "%d", a->imm);
+}
+
+static void output_rr_jk(DisasContext *ctx, arg_rr_jk *a,
+ const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, r%d", a->rj, a->rk);
+}
+
+static void output_ff(DisasContext *ctx, arg_ff *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "f%d, f%d", a->fd, a->fj);
+}
+
+static void output_fff(DisasContext *ctx, arg_fff *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "f%d, f%d, f%d", a->fd, a->fj, a->fk);
+}
+
+static void