Re: [Qemu-devel] [PATCH RFC v8 04/12] target/rx: RX disassembler

2019-05-03 Thread Richard Henderson
On 5/2/19 7:34 AM, Yoshinori Sato wrote:
> +static int32_t li(DisasContext *ctx, int sz)
> +{
> +int32_t addr;
> +bfd_byte buf[4];
> +addr = ctx->addr;
> +
> +switch (sz) {
> +case 1:
> +ctx->addr += 1;
> +ctx->dis->read_memory_func(addr, buf, 1, ctx->dis);
> +return buf[0];
> +case 2:
> +ctx->addr += 2;
> +ctx->dis->read_memory_func(addr, buf, 2, ctx->dis);
> +return buf[1] << 8 | buf[0];
> +case 3:
> +ctx->addr += 3;
> +ctx->dis->read_memory_func(addr, buf, 3, ctx->dis);
> +return buf[2] << 16 | buf[1] << 8 | buf[0];
> +case 0:
> +ctx->addr += 4;
> +ctx->dis->read_memory_func(addr, buf, 4, ctx->dis);
> +return buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
> +default:
> +g_assert_not_reached();
> +}
> +}

These should be computing signed values.  This is already correct over in
translate.c.  Also, we can make use of some endian-specific unaligned load
functions from .  So for the 4 cases:

  return (int8_t)buf[0];

  return ldsw_le_p(buf);

  return (int8_t)buf[2] << 16 | buf[1] << 8 | buf[0];

  return ldl_le_p(buf);


r~



Re: [Qemu-devel] [PATCH RFC v8 04/12] target/rx: RX disassembler

2019-05-03 Thread Alex Bennée


Yoshinori Sato  writes:

> Signed-off-by: Yoshinori Sato 
> ---
>  include/disas/dis-asm.h |5 +
>  target/rx/disas.c   | 1481 
> +++
>  2 files changed, 1486 insertions(+)
>  create mode 100644 target/rx/disas.c
>
> diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
> index 9240ec32c2..de17792e88 100644
> --- a/include/disas/dis-asm.h
> +++ b/include/disas/dis-asm.h
> @@ -226,6 +226,10 @@ enum bfd_architecture
>  #define bfd_mach_nios2r22
>bfd_arch_lm32,   /* Lattice Mico32 */
>  #define bfd_mach_lm32 1
> +  bfd_arch_rx,   /* Renesas RX */
> +#define bfd_mach_rx0x75
> +#define bfd_mach_rx_v2 0x76
> +#define bfd_mach_rx_v3 0x77
>bfd_arch_last
>};
>  #define bfd_mach_s390_31 31
> @@ -433,6 +437,7 @@ int print_insn_little_nios2 (bfd_vma, 
> disassemble_info*);
>  int print_insn_xtensa   (bfd_vma, disassemble_info*);
>  int print_insn_riscv32  (bfd_vma, disassemble_info*);
>  int print_insn_riscv64  (bfd_vma, disassemble_info*);
> +int print_insn_rx(bfd_vma, disassemble_info *);
>
>  #if 0
>  /* Fetch the disassembler for a given BFD, if that support is available.  */
> diff --git a/target/rx/disas.c b/target/rx/disas.c
> new file mode 100644
> index 00..014fadfca3
> --- /dev/null
> +++ b/target/rx/disas.c
> @@ -0,0 +1,1481 @@
> +/*
> + * Renesas RX Disassembler
> + *
> + * Copyright (c) 2019 Yoshinori Sato 
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along 
> with
> + * this program.  If not, see .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "disas/dis-asm.h"
> +#include "qemu/bitops.h"
> +#include "cpu.h"
> +
> +typedef struct DisasContext {
> +disassemble_info *dis;
> +uint32_t addr;
> +uint32_t pc;
> +} DisasContext;
> +
> +
> +static uint32_t decode_load_bytes(DisasContext *ctx, uint32_t insn,
> +   int i, int n)
> +{
> +bfd_byte buf;
> +while (++i <= n) {
> +ctx->dis->read_memory_func(ctx->addr++, &buf, 1, ctx->dis);
> +insn |= buf << (32 - i * 8);
> +}
> +return insn;
> +}
> +
> +static int32_t li(DisasContext *ctx, int sz)
> +{
> +int32_t addr;
> +bfd_byte buf[4];
> +addr = ctx->addr;
> +
> +switch (sz) {
> +case 1:
> +ctx->addr += 1;
> +ctx->dis->read_memory_func(addr, buf, 1, ctx->dis);
> +return buf[0];
> +case 2:
> +ctx->addr += 2;
> +ctx->dis->read_memory_func(addr, buf, 2, ctx->dis);
> +return buf[1] << 8 | buf[0];
> +case 3:
> +ctx->addr += 3;
> +ctx->dis->read_memory_func(addr, buf, 3, ctx->dis);
> +return buf[2] << 16 | buf[1] << 8 | buf[0];
> +case 0:
> +ctx->addr += 4;
> +ctx->dis->read_memory_func(addr, buf, 4, ctx->dis);
> +return buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
> +default:
> +g_assert_not_reached();
> +}
> +}
> +
> +static int bdsp_s(DisasContext *ctx, int d)
> +{
> +/*
> + * 0 -> 8
> + * 1 -> 9
> + * 2 -> 10
> + * 3 -> 3
> + * :
> + * 7 -> 7
> + */
> +if (d < 3) {
> +d += 8;
> +}
> +return d;
> +}
> +
> +/* Include the auto-generated decoder.  */
> +#include "decode.inc.c"

This introduces a dependency on a generated file so you'll need:

target/rx/disas.o: target/rx/decode.inc.c

in Makefile.objs

--
Alex Bennée



[Qemu-devel] [PATCH RFC v8 04/12] target/rx: RX disassembler

2019-05-02 Thread Yoshinori Sato
Signed-off-by: Yoshinori Sato 
---
 include/disas/dis-asm.h |5 +
 target/rx/disas.c   | 1481 +++
 2 files changed, 1486 insertions(+)
 create mode 100644 target/rx/disas.c

diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
index 9240ec32c2..de17792e88 100644
--- a/include/disas/dis-asm.h
+++ b/include/disas/dis-asm.h
@@ -226,6 +226,10 @@ enum bfd_architecture
 #define bfd_mach_nios2r22
   bfd_arch_lm32,   /* Lattice Mico32 */
 #define bfd_mach_lm32 1
+  bfd_arch_rx,   /* Renesas RX */
+#define bfd_mach_rx0x75
+#define bfd_mach_rx_v2 0x76
+#define bfd_mach_rx_v3 0x77
   bfd_arch_last
   };
 #define bfd_mach_s390_31 31
@@ -433,6 +437,7 @@ int print_insn_little_nios2 (bfd_vma, 
disassemble_info*);
 int print_insn_xtensa   (bfd_vma, disassemble_info*);
 int print_insn_riscv32  (bfd_vma, disassemble_info*);
 int print_insn_riscv64  (bfd_vma, disassemble_info*);
+int print_insn_rx(bfd_vma, disassemble_info *);
 
 #if 0
 /* Fetch the disassembler for a given BFD, if that support is available.  */
diff --git a/target/rx/disas.c b/target/rx/disas.c
new file mode 100644
index 00..014fadfca3
--- /dev/null
+++ b/target/rx/disas.c
@@ -0,0 +1,1481 @@
+/*
+ * Renesas RX Disassembler
+ *
+ * Copyright (c) 2019 Yoshinori Sato 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "disas/dis-asm.h"
+#include "qemu/bitops.h"
+#include "cpu.h"
+
+typedef struct DisasContext {
+disassemble_info *dis;
+uint32_t addr;
+uint32_t pc;
+} DisasContext;
+
+
+static uint32_t decode_load_bytes(DisasContext *ctx, uint32_t insn,
+   int i, int n)
+{
+bfd_byte buf;
+while (++i <= n) {
+ctx->dis->read_memory_func(ctx->addr++, &buf, 1, ctx->dis);
+insn |= buf << (32 - i * 8);
+}
+return insn;
+}
+
+static int32_t li(DisasContext *ctx, int sz)
+{
+int32_t addr;
+bfd_byte buf[4];
+addr = ctx->addr;
+
+switch (sz) {
+case 1:
+ctx->addr += 1;
+ctx->dis->read_memory_func(addr, buf, 1, ctx->dis);
+return buf[0];
+case 2:
+ctx->addr += 2;
+ctx->dis->read_memory_func(addr, buf, 2, ctx->dis);
+return buf[1] << 8 | buf[0];
+case 3:
+ctx->addr += 3;
+ctx->dis->read_memory_func(addr, buf, 3, ctx->dis);
+return buf[2] << 16 | buf[1] << 8 | buf[0];
+case 0:
+ctx->addr += 4;
+ctx->dis->read_memory_func(addr, buf, 4, ctx->dis);
+return buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0];
+default:
+g_assert_not_reached();
+}
+}
+
+static int bdsp_s(DisasContext *ctx, int d)
+{
+/*
+ * 0 -> 8
+ * 1 -> 9
+ * 2 -> 10
+ * 3 -> 3
+ * :
+ * 7 -> 7
+ */
+if (d < 3) {
+d += 8;
+}
+return d;
+}
+
+/* Include the auto-generated decoder.  */
+#include "decode.inc.c"
+
+#define prt(...) (ctx->dis->fprintf_func)((ctx->dis->stream), __VA_ARGS__)
+
+#define RX_MEMORY_BYTE 0
+#define RX_MEMORY_WORD 1
+#define RX_MEMORY_LONG 2
+
+#define RX_IM_BYTE 0
+#define RX_IM_WORD 1
+#define RX_IM_LONG 2
+#define RX_IM_UWORD 3
+
+static const char size[] = {'b', 'w', 'l'};
+static const char cond[][4] = {
+"eq", "ne", "c", "nc", "gtu", "leu", "pz", "n",
+"ge", "lt", "gt", "le", "o", "no", "ra", "f"
+};
+static const char psw[] = {
+'c', 'z', 's', 'o', 0, 0, 0, 0,
+'i', 'u', 0, 0, 0, 0, 0, 0,
+};
+
+static uint32_t rx_index_addr(int ld, int size, DisasContext *ctx)
+{
+bfd_byte buf[2];
+switch (ld) {
+case 0:
+return 0;
+case 1:
+ctx->dis->read_memory_func(ctx->addr, buf, 1, ctx->dis);
+ctx->addr += 1;
+return buf[0];
+case 2:
+ctx->dis->read_memory_func(ctx->addr, buf, 2, ctx->dis);
+ctx->addr += 2;
+return buf[1] << 8 | buf[0];
+}
+g_assert_not_reached();
+}
+
+static void operand(DisasContext *ctx, int ld, int mi, int rs, int rd)
+{
+int dsp;
+static const char sizes[][4] = {".b", ".w", ".l", ".uw", ".ub"};
+if (ld < 3) {
+switch (mi) {
+case 4:
+/* dsp[rs].ub */
+dsp = rx_index_addr(ld, RX_MEMORY_BYTE, ctx);
+break;
+case 3:
+/* dsp[rs].uw */
+dsp = rx_index_addr(ld, RX_MEMORY_WORD, ctx);
+