From 9217b0a86a804a9f40a408a6e2a68b28ed55549f Mon Sep 17 00:00:00 2001 From: NOT XVilka Date: Fri, 19 Jun 2026 04:37:30 +0800 Subject: [PATCH] librz/arch/sh: add SuperH-3 support via asm.cpu (#6531) Co-authored-by agent: Claude/Claude-Opus-4.8 Co-authored-by: Anton Kochkov --- librz/arch/isa/sh/assembler.c | 10 +- librz/arch/isa/sh/assembler.h | 2 +- librz/arch/isa/sh/common.h | 1 + librz/arch/isa/sh/disassembler.c | 30 ++- librz/arch/isa/sh/disassembler.h | 32 ++- librz/arch/isa/sh/lookup.c | 340 ++++++++++++++-------------- librz/arch/isa/sh/sh_il.c | 10 +- librz/arch/p/analysis/analysis_sh.c | 20 +- librz/arch/p/asm/asm_sh.c | 9 +- test/db/analysis/sh3 | 67 ++++++ test/db/asm/sh | 6 +- test/db/asm/sh_sh3_32 | 40 ++++ test/db/cmd/cmd_aL | 2 +- test/db/cmd/cmd_list | 24 +- test/db/rzil/sh3 | 16 ++ 15 files changed, 407 insertions(+), 202 deletions(-) create mode 100644 test/db/analysis/sh3 create mode 100644 test/db/asm/sh_sh3_32 create mode 100644 test/db/rzil/sh3 diff --git a/librz/arch/isa/sh/assembler.c b/librz/arch/isa/sh/assembler.c index 9b943cc6bc..bfdd3041bd 100644 --- a/librz/arch/isa/sh/assembler.c +++ b/librz/arch/isa/sh/assembler.c @@ -391,15 +391,16 @@ static bool sh_op_compare(SHOpRaw raw, const char *mnem, SHAddrHelper modes[]) { } /** - * \brief Assemble instruction from SuperH-4 ISA + * \brief Assemble instruction from SuperH ISA * FPU instructions not implemented yet * * \param buffer Instruction string buffer * \param pc Current value of program counter * \param success Store bool whether the assembler succeeded or not (RZ_NULLABLE) + * \param cpu SuperH CPU model to assemble for (instructions not available on it will fail) * \return ut16 Opcode for the given instruction */ -RZ_IPI ut16 sh_assembler(RZ_NONNULL const char *buffer, ut64 pc, RZ_NULLABLE bool *success) { +RZ_IPI ut16 sh_assembler(RZ_NONNULL const char *buffer, ut64 pc, RZ_NULLABLE bool *success, SHCpu cpu) { rz_return_val_if_fail(buffer, -1); if (success) { *success = true; @@ -434,10 +435,15 @@ RZ_IPI ut16 sh_assembler(RZ_NONNULL const char *buffer, ut64 pc, RZ_NULLABLE boo j++; } + SHArch want = (cpu == SH_CPU_SH3) ? SH_ARCH_SH3 : SH_ARCH_SH4; for (ut16 i = 0; i < OPCODE_NUM; i++) { if (!sh_op_compare(sh_op_lookup[i], mnem, sham)) { continue; } + if (!(sh_op_lookup[i].arch & want)) { + // instruction is not available on the selected CPU + continue; + } SHOpRaw raw = sh_op_lookup[i]; opcode = raw.opcode ^ raw.mask; diff --git a/librz/arch/isa/sh/assembler.h b/librz/arch/isa/sh/assembler.h index 8fa49acd15..54a66ac9c5 100644 --- a/librz/arch/isa/sh/assembler.h +++ b/librz/arch/isa/sh/assembler.h @@ -7,6 +7,6 @@ #include "common.h" #include "disassembler.h" -RZ_IPI ut16 sh_assembler(RZ_NONNULL const char *buffer, ut64 pc, RZ_NULLABLE bool *success); +RZ_IPI ut16 sh_assembler(RZ_NONNULL const char *buffer, ut64 pc, RZ_NULLABLE bool *success, SHCpu cpu); #endif // RZ_SH_ASSEMBLER_H diff --git a/librz/arch/isa/sh/common.h b/librz/arch/isa/sh/common.h index 47383a2499..9413ff41c2 100644 --- a/librz/arch/isa/sh/common.h +++ b/librz/arch/isa/sh/common.h @@ -28,6 +28,7 @@ typedef struct sh_op_raw_t { ut16 mask; ///< mask for opcode to mask out param bits SHScaling scaling; ///< scaling for the opcode SHParamBuilder param_builder[2]; ///< param builders for the params + SHArch arch; ///< set of SuperH CPU models on which this instruction is available } SHOpRaw; // xxxx used to denote param fields in the opcode diff --git a/librz/arch/isa/sh/disassembler.c b/librz/arch/isa/sh/disassembler.c index f68ca70ca0..b8a084c79a 100644 --- a/librz/arch/isa/sh/disassembler.c +++ b/librz/arch/isa/sh/disassembler.c @@ -121,17 +121,44 @@ static SHParam sh_op_get_param_movl(ut16 opcode, bool m) { } } +/** + * \brief Resolve the SuperH CPU model from its "asm.cpu" name + * + * \param name CPU name (e.g. "sh3", "sh4"), may be NULL or empty + * \return SHCpu the matching CPU model, defaulting to \ref SH_CPU_SH4 + */ +RZ_IPI SHCpu sh_cpu_by_name(RZ_NULLABLE const char *name) { + if (RZ_STR_ISEMPTY(name)) { + return SH_CPU_SH4; + } + if (RZ_STR_EQ(name, "sh3")) { + return SH_CPU_SH3; + } + // SuperH-4 is the default and keeps backward compatibility + return SH_CPU_SH4; +} + /** * \brief Disassemble \p opcode and return a SHOp * + * Instructions which do not belong to \p cpu are not decoded (NULL is + * returned), so that e.g. SuperH-4 only instructions are treated as invalid + * when disassembling for SuperH-3. + * * \param opcode 16 bit wide opcode + * \param cpu SuperH CPU model to disassemble for * \return SHOp object corresponding to the opcode */ -RZ_IPI RZ_OWN SHOp *sh_disassembler(ut16 opcode) { +RZ_IPI RZ_OWN SHOp *sh_disassembler(ut16 opcode, SHCpu cpu) { + SHArch want = (cpu == SH_CPU_SH3) ? SH_ARCH_SH3 : SH_ARCH_SH4; for (ut16 i = 0; i < OPCODE_NUM; i++) { if ((opcode | sh_op_lookup[i].mask) != sh_op_lookup[i].opcode) { continue; } + if (!(sh_op_lookup[i].arch & want)) { + // instruction is not available on the selected CPU + continue; + } SHOpRaw raw = sh_op_lookup[i]; SHOp *op = RZ_NEW(SHOp); @@ -139,6 +166,7 @@ RZ_IPI RZ_OWN SHOp *sh_disassembler(ut16 opcode) { op->mnemonic = raw.mnemonic; op->scaling = raw.scaling; op->str_mnem = raw.str_mnem; + op->arch = raw.arch; // check for "weird" mov.l if (raw.opcode == MOVL) { op->param[0] = sh_op_get_param_movl(opcode, true); diff --git a/librz/arch/isa/sh/disassembler.h b/librz/arch/isa/sh/disassembler.h index 60d2bfdaa5..f96c54a6ce 100644 --- a/librz/arch/isa/sh/disassembler.h +++ b/librz/arch/isa/sh/disassembler.h @@ -14,6 +14,33 @@ #define SH_BANKED_REG_COUNT 8 #define SH_REG_COUNT 61 +/** + * \brief SuperH CPU model + * + * Selected through the "asm.cpu" option. SuperH-4 is the default since it is a + * superset (at the instruction set level) of all the currently supported + * instructions, so it keeps backward compatibility with the previous behavior. + */ +typedef enum sh_cpu_t { + SH_CPU_SH4 = 0, ///< SuperH-4 (default) + SH_CPU_SH3, ///< SuperH-3 +} SHCpu; + +/** + * \brief Set of SuperH CPU models on which an instruction is available + * + * Used to tag each entry of the opcode lookup table so that the disassembler + * can reject instructions which do not belong to the selected \ref SHCpu. The + * SuperH instruction set is upward compatible (SH-1 through SH-4 at the + * instruction set level), so the only currently tracked distinction is whether + * an instruction was introduced with SuperH-4 or is shared with SuperH-3. + */ +typedef enum sh_arch_t { + SH_ARCH_SH3 = 1 << 0, ///< available on SuperH-3 + SH_ARCH_SH4 = 1 << 1, ///< available on SuperH-4 + SH_ARCH_COMMON = SH_ARCH_SH3 | SH_ARCH_SH4, ///< available on both SuperH-3 and SuperH-4 +} SHArch; + typedef enum sh_addr_mode_t { SH_ADDR_INVALID = 0, SH_REG_DIRECT, @@ -245,9 +272,12 @@ typedef struct sh_opcode_t { SHOpMnem mnemonic; SHParam param[2]; SHScaling scaling; + SHArch arch; ///< set of SuperH CPU models on which this instruction is available } SHOp; -RZ_IPI RZ_OWN SHOp *sh_disassembler(ut16 opcode); +RZ_IPI RZ_OWN SHOp *sh_disassembler(ut16 opcode, SHCpu cpu); + +RZ_IPI SHCpu sh_cpu_by_name(RZ_NULLABLE const char *name); RZ_IPI RZ_OWN char *sh_op_param_to_str(SHParam param, SHScaling scaling, ut64 pc); RZ_IPI RZ_OWN char *sh_op_to_str(RZ_NONNULL const SHOp *op, ut64 pc); diff --git a/librz/arch/isa/sh/lookup.c b/librz/arch/isa/sh/lookup.c index 5b6f97a75e..85d57ffd52 100644 --- a/librz/arch/isa/sh/lookup.c +++ b/librz/arch/isa/sh/lookup.c @@ -6,187 +6,187 @@ // Opcode lookup list const SHOpRaw sh_op_lookup[] = { /* fixed-point transfer instructions */ - { "mov", SH_OP_MOV, OPCODE(e, N, I, I), 0x0fff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_U), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mov.w", SH_OP_MOV, OPCODE(9, N, D, D), 0x0fff, SH_SCALING_W, { ADDR(NIB0, SH_PC_RELATIVE_DISP), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mov.l", SH_OP_MOV, OPCODE(d, N, D, D), 0x0fff, SH_SCALING_L, { ADDR(NIB0, SH_PC_RELATIVE_DISP), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mov", SH_OP_MOV, OPCODE(6, N, M, 3), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mov.b", SH_OP_MOV, OPCODE(2, N, M, 0), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT) } }, - { "mov.w", SH_OP_MOV, OPCODE(2, N, M, 1), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT) } }, - { "mov.l", SH_OP_MOV, OPCODE(2, N, M, 2), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT) } }, - { "mov.b", SH_OP_MOV, OPCODE(6, N, M, 0), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_INDIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mov.w", SH_OP_MOV, OPCODE(6, N, M, 1), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_INDIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mov.l", SH_OP_MOV, OPCODE(6, N, M, 2), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_INDIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mov.b", SH_OP_MOV, OPCODE(2, N, M, 4), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) } }, - { "mov.w", SH_OP_MOV, OPCODE(2, N, M, 5), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) } }, - { "mov.l", SH_OP_MOV, OPCODE(2, N, M, 6), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) } }, - { "mov.b", SH_OP_MOV, OPCODE(6, N, M, 4), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_INDIRECT_I), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mov.w", SH_OP_MOV, OPCODE(6, N, M, 5), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_INDIRECT_I), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mov.l", SH_OP_MOV, OPCODE(6, N, M, 6), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_INDIRECT_I), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mov.b", SH_OP_MOV, OPCODE(8, 0, N, D), 0x00ff, SH_SCALING_B, { PARAM(R0, SH_REG_DIRECT), ADDR(NIB0, SH_REG_INDIRECT_DISP) } }, - { "mov.w", SH_OP_MOV, OPCODE(8, 1, N, D), 0x00ff, SH_SCALING_W, { PARAM(R0, SH_REG_DIRECT), ADDR(NIB0, SH_REG_INDIRECT_DISP) } }, - { "mov.l", SH_OP_MOV, OPCODE(1, N, M, D), 0x0fff, SH_SCALING_L, { /*dummy values*/ ADDR(NIB0, SH_REG_DIRECT), ADDR(NIB0, SH_REG_INDIRECT_DISP) } }, + { "mov", SH_OP_MOV, OPCODE(e, N, I, I), 0x0fff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_S), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.w", SH_OP_MOV, OPCODE(9, N, D, D), 0x0fff, SH_SCALING_W, { ADDR(NIB0, SH_PC_RELATIVE_DISP), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.l", SH_OP_MOV, OPCODE(d, N, D, D), 0x0fff, SH_SCALING_L, { ADDR(NIB0, SH_PC_RELATIVE_DISP), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov", SH_OP_MOV, OPCODE(6, N, M, 3), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.b", SH_OP_MOV, OPCODE(2, N, M, 0), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT) }, SH_ARCH_COMMON }, + { "mov.w", SH_OP_MOV, OPCODE(2, N, M, 1), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT) }, SH_ARCH_COMMON }, + { "mov.l", SH_OP_MOV, OPCODE(2, N, M, 2), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT) }, SH_ARCH_COMMON }, + { "mov.b", SH_OP_MOV, OPCODE(6, N, M, 0), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_INDIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.w", SH_OP_MOV, OPCODE(6, N, M, 1), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_INDIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.l", SH_OP_MOV, OPCODE(6, N, M, 2), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_INDIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.b", SH_OP_MOV, OPCODE(2, N, M, 4), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) }, SH_ARCH_COMMON }, + { "mov.w", SH_OP_MOV, OPCODE(2, N, M, 5), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) }, SH_ARCH_COMMON }, + { "mov.l", SH_OP_MOV, OPCODE(2, N, M, 6), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) }, SH_ARCH_COMMON }, + { "mov.b", SH_OP_MOV, OPCODE(6, N, M, 4), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_INDIRECT_I), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.w", SH_OP_MOV, OPCODE(6, N, M, 5), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_INDIRECT_I), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.l", SH_OP_MOV, OPCODE(6, N, M, 6), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_INDIRECT_I), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.b", SH_OP_MOV, OPCODE(8, 0, N, D), 0x00ff, SH_SCALING_B, { PARAM(R0, SH_REG_DIRECT), ADDR(NIB0, SH_REG_INDIRECT_DISP) }, SH_ARCH_COMMON }, + { "mov.w", SH_OP_MOV, OPCODE(8, 1, N, D), 0x00ff, SH_SCALING_W, { PARAM(R0, SH_REG_DIRECT), ADDR(NIB0, SH_REG_INDIRECT_DISP) }, SH_ARCH_COMMON }, + { "mov.l", SH_OP_MOV, OPCODE(1, N, M, D), 0x0fff, SH_SCALING_L, { /*dummy values*/ ADDR(NIB0, SH_REG_DIRECT), ADDR(NIB0, SH_REG_INDIRECT_DISP) }, SH_ARCH_COMMON }, // ^ Just this instruction is kinda weird, so needs to be taken care of specially - { "mov.b", SH_OP_MOV, OPCODE(8, 4, M, D), 0x00ff, SH_SCALING_B, { ADDR(NIB0, SH_REG_INDIRECT_DISP), PARAM(R0, SH_REG_DIRECT) } }, - { "mov.w", SH_OP_MOV, OPCODE(8, 5, M, D), 0x00ff, SH_SCALING_W, { ADDR(NIB0, SH_REG_INDIRECT_DISP), PARAM(R0, SH_REG_DIRECT) } }, - { "mov.l", SH_OP_MOV, OPCODE(5, N, M, D), 0x0fff, SH_SCALING_L, { ADDR(NIB0, SH_REG_INDIRECT_DISP), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mov.b", SH_OP_MOV, OPCODE(0, N, M, 4), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_INDEXED) } }, - { "mov.w", SH_OP_MOV, OPCODE(0, N, M, 5), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_INDEXED) } }, - { "mov.l", SH_OP_MOV, OPCODE(0, N, M, 6), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_INDEXED) } }, - { "mov.b", SH_OP_MOV, OPCODE(0, N, M, c), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_INDIRECT_INDEXED), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mov.w", SH_OP_MOV, OPCODE(0, N, M, d), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_INDIRECT_INDEXED), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mov.l", SH_OP_MOV, OPCODE(0, N, M, e), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_INDIRECT_INDEXED), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mov.b", SH_OP_MOV, OPCODE(c, 0, D, D), 0x00ff, SH_SCALING_B, { PARAM(R0, SH_REG_DIRECT), ADDR(NIB0, SH_GBR_INDIRECT_DISP) } }, - { "mov.w", SH_OP_MOV, OPCODE(c, 1, D, D), 0x00ff, SH_SCALING_W, { PARAM(R0, SH_REG_DIRECT), ADDR(NIB0, SH_GBR_INDIRECT_DISP) } }, - { "mov.l", SH_OP_MOV, OPCODE(c, 2, D, D), 0x00ff, SH_SCALING_L, { PARAM(R0, SH_REG_DIRECT), ADDR(NIB0, SH_GBR_INDIRECT_DISP) } }, - { "mov.b", SH_OP_MOV, OPCODE(c, 4, D, D), 0x00ff, SH_SCALING_B, { ADDR(NIB0, SH_GBR_INDIRECT_DISP), PARAM(R0, SH_REG_DIRECT) } }, - { "mov.w", SH_OP_MOV, OPCODE(c, 5, D, D), 0x00ff, SH_SCALING_W, { ADDR(NIB0, SH_GBR_INDIRECT_DISP), PARAM(R0, SH_REG_DIRECT) } }, - { "mov.l", SH_OP_MOV, OPCODE(c, 6, D, D), 0x00ff, SH_SCALING_L, { ADDR(NIB0, SH_GBR_INDIRECT_DISP), PARAM(R0, SH_REG_DIRECT) } }, - { "mova", SH_OP_MOV, OPCODE(c, 7, D, D), 0x00ff, SH_SCALING_L, { ADDR(NIB0, SH_PC_RELATIVE_DISP), PARAM(R0, SH_REG_DIRECT) } }, - { "movt", SH_OP_MOVT, OPCODE(0, N, 2, 9), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "swap.b", SH_OP_SWAP, OPCODE(6, N, M, 8), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "swap.w", SH_OP_SWAP, OPCODE(6, N, M, 9), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "xtrct", SH_OP_XTRCT, OPCODE(2, N, M, d), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, + { "mov.b", SH_OP_MOV, OPCODE(8, 4, M, D), 0x00ff, SH_SCALING_B, { ADDR(NIB0, SH_REG_INDIRECT_DISP), PARAM(R0, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.w", SH_OP_MOV, OPCODE(8, 5, M, D), 0x00ff, SH_SCALING_W, { ADDR(NIB0, SH_REG_INDIRECT_DISP), PARAM(R0, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.l", SH_OP_MOV, OPCODE(5, N, M, D), 0x0fff, SH_SCALING_L, { ADDR(NIB0, SH_REG_INDIRECT_DISP), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.b", SH_OP_MOV, OPCODE(0, N, M, 4), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_INDEXED) }, SH_ARCH_COMMON }, + { "mov.w", SH_OP_MOV, OPCODE(0, N, M, 5), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_INDEXED) }, SH_ARCH_COMMON }, + { "mov.l", SH_OP_MOV, OPCODE(0, N, M, 6), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_INDEXED) }, SH_ARCH_COMMON }, + { "mov.b", SH_OP_MOV, OPCODE(0, N, M, c), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_INDIRECT_INDEXED), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.w", SH_OP_MOV, OPCODE(0, N, M, d), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_INDIRECT_INDEXED), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.l", SH_OP_MOV, OPCODE(0, N, M, e), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_INDIRECT_INDEXED), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.b", SH_OP_MOV, OPCODE(c, 0, D, D), 0x00ff, SH_SCALING_B, { PARAM(R0, SH_REG_DIRECT), ADDR(NIB0, SH_GBR_INDIRECT_DISP) }, SH_ARCH_COMMON }, + { "mov.w", SH_OP_MOV, OPCODE(c, 1, D, D), 0x00ff, SH_SCALING_W, { PARAM(R0, SH_REG_DIRECT), ADDR(NIB0, SH_GBR_INDIRECT_DISP) }, SH_ARCH_COMMON }, + { "mov.l", SH_OP_MOV, OPCODE(c, 2, D, D), 0x00ff, SH_SCALING_L, { PARAM(R0, SH_REG_DIRECT), ADDR(NIB0, SH_GBR_INDIRECT_DISP) }, SH_ARCH_COMMON }, + { "mov.b", SH_OP_MOV, OPCODE(c, 4, D, D), 0x00ff, SH_SCALING_B, { ADDR(NIB0, SH_GBR_INDIRECT_DISP), PARAM(R0, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.w", SH_OP_MOV, OPCODE(c, 5, D, D), 0x00ff, SH_SCALING_W, { ADDR(NIB0, SH_GBR_INDIRECT_DISP), PARAM(R0, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mov.l", SH_OP_MOV, OPCODE(c, 6, D, D), 0x00ff, SH_SCALING_L, { ADDR(NIB0, SH_GBR_INDIRECT_DISP), PARAM(R0, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mova", SH_OP_MOV, OPCODE(c, 7, D, D), 0x00ff, SH_SCALING_L, { ADDR(NIB0, SH_PC_RELATIVE_DISP), PARAM(R0, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "movt", SH_OP_MOVT, OPCODE(0, N, 2, 9), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "swap.b", SH_OP_SWAP, OPCODE(6, N, M, 8), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "swap.w", SH_OP_SWAP, OPCODE(6, N, M, 9), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "xtrct", SH_OP_XTRCT, OPCODE(2, N, M, d), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, /* arithmetic operation instructions */ - { "add", SH_OP_ADD, OPCODE(3, N, M, c), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "add", SH_OP_ADD, OPCODE(7, N, I, I), 0x0fff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_S), ADDR(NIB2, SH_REG_DIRECT) } }, - { "addc", SH_OP_ADDC, OPCODE(3, N, M, e), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "addv", SH_OP_ADDV, OPCODE(3, N, M, f), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "cmp/eq", SH_OP_CMP_EQ, OPCODE(8, 8, I, I), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_S), PARAM(R0, SH_REG_DIRECT) } }, - { "cmp/eq", SH_OP_CMP_EQ, OPCODE(3, N, M, 0), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "cmp/hs", SH_OP_CMP_HS, OPCODE(3, N, M, 2), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "cmp/ge", SH_OP_CMP_GE, OPCODE(3, N, M, 3), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "cmp/hi", SH_OP_CMP_HI, OPCODE(3, N, M, 6), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "cmp/gt", SH_OP_CMP_GT, OPCODE(3, N, M, 7), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "cmp/pz", SH_OP_CMP_PZ, OPCODE(4, N, 1, 1), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "cmp/pl", SH_OP_CMP_PL, OPCODE(4, N, 1, 5), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "cmp/str", SH_OP_CMP_STR, OPCODE(2, N, M, c), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "div1", SH_OP_DIV1, OPCODE(3, N, M, 4), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "div0s", SH_OP_DIV0S, OPCODE(2, N, M, 7), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "div0u", SH_OP_DIV0U, OPCODE(0, 0, 1, 9), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM } }, - { "dmuls.l", SH_OP_DMULS, OPCODE(3, N, M, d), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "dmulu.l", SH_OP_DMULU, OPCODE(3, N, M, 5), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "dt", SH_OP_DT, OPCODE(4, N, 1, 0), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "exts.b", SH_OP_EXTS, OPCODE(6, N, M, e), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "exts.w", SH_OP_EXTS, OPCODE(6, N, M, f), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "extu.b", SH_OP_EXTU, OPCODE(6, N, M, c), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "extu.w", SH_OP_EXTU, OPCODE(6, N, M, d), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mac.l", SH_OP_MAC, OPCODE(0, N, M, f), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_INDIRECT_I), ADDR(NIB2, SH_REG_INDIRECT_I) } }, - { "mac.w", SH_OP_MAC, OPCODE(4, N, M, f), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_INDIRECT_I), ADDR(NIB2, SH_REG_INDIRECT_I) } }, - { "mul.l", SH_OP_MUL, OPCODE(0, N, M, 7), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "muls.w", SH_OP_MULS, OPCODE(2, N, M, f), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "mulu.w", SH_OP_MULU, OPCODE(2, N, M, e), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "neg", SH_OP_NEG, OPCODE(6, N, M, b), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "negc", SH_OP_NEGC, OPCODE(6, N, M, a), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "sub", SH_OP_SUB, OPCODE(3, N, M, 8), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "subc", SH_OP_SUBC, OPCODE(3, N, M, a), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "subv", SH_OP_SUBV, OPCODE(3, N, M, b), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, + { "add", SH_OP_ADD, OPCODE(3, N, M, c), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "add", SH_OP_ADD, OPCODE(7, N, I, I), 0x0fff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_S), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "addc", SH_OP_ADDC, OPCODE(3, N, M, e), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "addv", SH_OP_ADDV, OPCODE(3, N, M, f), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "cmp/eq", SH_OP_CMP_EQ, OPCODE(8, 8, I, I), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_S), PARAM(R0, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "cmp/eq", SH_OP_CMP_EQ, OPCODE(3, N, M, 0), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "cmp/hs", SH_OP_CMP_HS, OPCODE(3, N, M, 2), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "cmp/ge", SH_OP_CMP_GE, OPCODE(3, N, M, 3), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "cmp/hi", SH_OP_CMP_HI, OPCODE(3, N, M, 6), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "cmp/gt", SH_OP_CMP_GT, OPCODE(3, N, M, 7), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "cmp/pz", SH_OP_CMP_PZ, OPCODE(4, N, 1, 1), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "cmp/pl", SH_OP_CMP_PL, OPCODE(4, N, 1, 5), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "cmp/str", SH_OP_CMP_STR, OPCODE(2, N, M, c), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "div1", SH_OP_DIV1, OPCODE(3, N, M, 4), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "div0s", SH_OP_DIV0S, OPCODE(2, N, M, 7), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "div0u", SH_OP_DIV0U, OPCODE(0, 0, 1, 9), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM }, SH_ARCH_COMMON }, + { "dmuls.l", SH_OP_DMULS, OPCODE(3, N, M, d), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "dmulu.l", SH_OP_DMULU, OPCODE(3, N, M, 5), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "dt", SH_OP_DT, OPCODE(4, N, 1, 0), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "exts.b", SH_OP_EXTS, OPCODE(6, N, M, e), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "exts.w", SH_OP_EXTS, OPCODE(6, N, M, f), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "extu.b", SH_OP_EXTU, OPCODE(6, N, M, c), 0x0ff0, SH_SCALING_B, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "extu.w", SH_OP_EXTU, OPCODE(6, N, M, d), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mac.l", SH_OP_MAC, OPCODE(0, N, M, f), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_INDIRECT_I), ADDR(NIB2, SH_REG_INDIRECT_I) }, SH_ARCH_COMMON }, + { "mac.w", SH_OP_MAC, OPCODE(4, N, M, f), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_INDIRECT_I), ADDR(NIB2, SH_REG_INDIRECT_I) }, SH_ARCH_COMMON }, + { "mul.l", SH_OP_MUL, OPCODE(0, N, M, 7), 0x0ff0, SH_SCALING_L, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "muls.w", SH_OP_MULS, OPCODE(2, N, M, f), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "mulu.w", SH_OP_MULU, OPCODE(2, N, M, e), 0x0ff0, SH_SCALING_W, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "neg", SH_OP_NEG, OPCODE(6, N, M, b), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "negc", SH_OP_NEGC, OPCODE(6, N, M, a), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "sub", SH_OP_SUB, OPCODE(3, N, M, 8), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "subc", SH_OP_SUBC, OPCODE(3, N, M, a), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "subv", SH_OP_SUBV, OPCODE(3, N, M, b), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, /* logic operation instructions */ - { "and", SH_OP_AND, OPCODE(2, N, M, 9), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "and", SH_OP_AND, OPCODE(c, 9, I, I), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_REG_DIRECT) } }, - { "and.b", SH_OP_AND, OPCODE(c, d, I, I), 0x00ff, SH_SCALING_B, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_GBR_INDIRECT_INDEXED) } }, - { "not", SH_OP_NOT, OPCODE(6, N, M, 7), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "or", SH_OP_OR, OPCODE(2, N, M, b), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "or", SH_OP_OR, OPCODE(c, b, I, I), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_REG_DIRECT) } }, - { "or.b", SH_OP_OR, OPCODE(c, f, I, I), 0x00ff, SH_SCALING_B, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_GBR_INDIRECT_INDEXED) } }, - { "tas.b", SH_OP_TAS, OPCODE(4, N, 1, b), 0x0f00, SH_SCALING_B, { ADDR(NIB2, SH_REG_INDIRECT), NOPARAM } }, - { "tst", SH_OP_TST, OPCODE(2, N, M, 8), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "tst", SH_OP_TST, OPCODE(c, 8, I, I), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_REG_DIRECT) } }, - { "tst.b", SH_OP_TST, OPCODE(c, c, I, I), 0x00ff, SH_SCALING_B, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_GBR_INDIRECT_INDEXED) } }, - { "xor", SH_OP_XOR, OPCODE(2, N, M, a), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "xor", SH_OP_XOR, OPCODE(c, a, I, I), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_REG_DIRECT) } }, - { "xor.b", SH_OP_XOR, OPCODE(c, e, I, I), 0x00ff, SH_SCALING_B, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_GBR_INDIRECT_INDEXED) } }, + { "and", SH_OP_AND, OPCODE(2, N, M, 9), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "and", SH_OP_AND, OPCODE(c, 9, I, I), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "and.b", SH_OP_AND, OPCODE(c, d, I, I), 0x00ff, SH_SCALING_B, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_GBR_INDIRECT_INDEXED) }, SH_ARCH_COMMON }, + { "not", SH_OP_NOT, OPCODE(6, N, M, 7), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "or", SH_OP_OR, OPCODE(2, N, M, b), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "or", SH_OP_OR, OPCODE(c, b, I, I), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "or.b", SH_OP_OR, OPCODE(c, f, I, I), 0x00ff, SH_SCALING_B, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_GBR_INDIRECT_INDEXED) }, SH_ARCH_COMMON }, + { "tas.b", SH_OP_TAS, OPCODE(4, N, 1, b), 0x0f00, SH_SCALING_B, { ADDR(NIB2, SH_REG_INDIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "tst", SH_OP_TST, OPCODE(2, N, M, 8), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "tst", SH_OP_TST, OPCODE(c, 8, I, I), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "tst.b", SH_OP_TST, OPCODE(c, c, I, I), 0x00ff, SH_SCALING_B, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_GBR_INDIRECT_INDEXED) }, SH_ARCH_COMMON }, + { "xor", SH_OP_XOR, OPCODE(2, N, M, a), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "xor", SH_OP_XOR, OPCODE(c, a, I, I), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "xor.b", SH_OP_XOR, OPCODE(c, e, I, I), 0x00ff, SH_SCALING_B, { ADDR(NIB0, SH_IMM_U), PARAM(R0, SH_GBR_INDIRECT_INDEXED) }, SH_ARCH_COMMON }, /* shift instructions */ - { "rotl", SH_OP_ROTL, OPCODE(4, N, 0, 4), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "rotr", SH_OP_ROTR, OPCODE(4, N, 0, 5), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "rotcl", SH_OP_ROTCL, OPCODE(4, N, 2, 4), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "rotcr", SH_OP_ROTCR, OPCODE(4, N, 2, 5), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "shad", SH_OP_SHAD, OPCODE(4, N, M, c), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "shal", SH_OP_SHAL, OPCODE(4, N, 2, 0), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "shar", SH_OP_SHAR, OPCODE(4, N, 2, 1), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "shld", SH_OP_SHLD, OPCODE(4, N, M, d), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "shll", SH_OP_SHLL, OPCODE(4, N, 0, 0), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "shlr", SH_OP_SHLR, OPCODE(4, N, 0, 1), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "shll2", SH_OP_SHLL2, OPCODE(4, N, 0, 8), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "shlr2", SH_OP_SHLR2, OPCODE(4, N, 0, 9), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "shll8", SH_OP_SHLL8, OPCODE(4, N, 1, 8), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "shlr8", SH_OP_SHLR8, OPCODE(4, N, 1, 9), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "shll16", SH_OP_SHLL16, OPCODE(4, N, 2, 8), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, - { "shlr16", SH_OP_SHLR16, OPCODE(4, N, 2, 9), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM } }, + { "rotl", SH_OP_ROTL, OPCODE(4, N, 0, 4), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "rotr", SH_OP_ROTR, OPCODE(4, N, 0, 5), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "rotcl", SH_OP_ROTCL, OPCODE(4, N, 2, 4), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "rotcr", SH_OP_ROTCR, OPCODE(4, N, 2, 5), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "shad", SH_OP_SHAD, OPCODE(4, N, M, c), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "shal", SH_OP_SHAL, OPCODE(4, N, 2, 0), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "shar", SH_OP_SHAR, OPCODE(4, N, 2, 1), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "shld", SH_OP_SHLD, OPCODE(4, N, M, d), 0x0ff0, SH_SCALING_INVALID, { ADDR(NIB1, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "shll", SH_OP_SHLL, OPCODE(4, N, 0, 0), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "shlr", SH_OP_SHLR, OPCODE(4, N, 0, 1), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "shll2", SH_OP_SHLL2, OPCODE(4, N, 0, 8), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "shlr2", SH_OP_SHLR2, OPCODE(4, N, 0, 9), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "shll8", SH_OP_SHLL8, OPCODE(4, N, 1, 8), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "shlr8", SH_OP_SHLR8, OPCODE(4, N, 1, 9), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "shll16", SH_OP_SHLL16, OPCODE(4, N, 2, 8), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "shlr16", SH_OP_SHLR16, OPCODE(4, N, 2, 9), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), NOPARAM }, SH_ARCH_COMMON }, /* branch instructions */ - { "bf", SH_OP_BF, OPCODE(8, b, D, D), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_PC_RELATIVE8), NOPARAM } }, - { "bf/s", SH_OP_BFS, OPCODE(8, f, D, D), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_PC_RELATIVE8), NOPARAM } }, - { "bt", SH_OP_BT, OPCODE(8, 9, D, D), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_PC_RELATIVE8), NOPARAM } }, - { "bt/s", SH_OP_BTS, OPCODE(8, d, D, D), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_PC_RELATIVE8), NOPARAM } }, - { "bra", SH_OP_BRA, OPCODE(a, D, D, D), 0x0fff, SH_SCALING_INVALID, { ADDR(NIB0, SH_PC_RELATIVE12), NOPARAM } }, - { "braf", SH_OP_BRAF, OPCODE(0, N, 2, 3), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_PC_RELATIVE_REG), NOPARAM } }, - { "bsr", SH_OP_BSR, OPCODE(b, D, D, D), 0x0fff, SH_SCALING_INVALID, { ADDR(NIB0, SH_PC_RELATIVE12), NOPARAM } }, - { "bsrf", SH_OP_BSRF, OPCODE(0, N, 0, 3), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_PC_RELATIVE_REG), NOPARAM } }, - { "jmp", SH_OP_JMP, OPCODE(4, N, 2, b), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_INDIRECT), NOPARAM } }, - { "jsr", SH_OP_JSR, OPCODE(4, N, 0, b), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_INDIRECT), NOPARAM } }, - { "rts", SH_OP_RTS, OPCODE(0, 0, 0, b), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM } }, + { "bf", SH_OP_BF, OPCODE(8, b, D, D), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_PC_RELATIVE8), NOPARAM }, SH_ARCH_COMMON }, + { "bf/s", SH_OP_BFS, OPCODE(8, f, D, D), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_PC_RELATIVE8), NOPARAM }, SH_ARCH_COMMON }, + { "bt", SH_OP_BT, OPCODE(8, 9, D, D), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_PC_RELATIVE8), NOPARAM }, SH_ARCH_COMMON }, + { "bt/s", SH_OP_BTS, OPCODE(8, d, D, D), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_PC_RELATIVE8), NOPARAM }, SH_ARCH_COMMON }, + { "bra", SH_OP_BRA, OPCODE(a, D, D, D), 0x0fff, SH_SCALING_INVALID, { ADDR(NIB0, SH_PC_RELATIVE12), NOPARAM }, SH_ARCH_COMMON }, + { "braf", SH_OP_BRAF, OPCODE(0, N, 2, 3), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_PC_RELATIVE_REG), NOPARAM }, SH_ARCH_COMMON }, + { "bsr", SH_OP_BSR, OPCODE(b, D, D, D), 0x0fff, SH_SCALING_INVALID, { ADDR(NIB0, SH_PC_RELATIVE12), NOPARAM }, SH_ARCH_COMMON }, + { "bsrf", SH_OP_BSRF, OPCODE(0, N, 0, 3), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_PC_RELATIVE_REG), NOPARAM }, SH_ARCH_COMMON }, + { "jmp", SH_OP_JMP, OPCODE(4, N, 2, b), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_INDIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "jsr", SH_OP_JSR, OPCODE(4, N, 0, b), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_INDIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "rts", SH_OP_RTS, OPCODE(0, 0, 0, b), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM }, SH_ARCH_COMMON }, /* system control instructions */ - { "clrmac", SH_OP_CLRMAC, OPCODE(0, 0, 2, 8), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM } }, - { "clrs", SH_OP_CLRS, OPCODE(0, 0, 4, 8), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM } }, - { "clrt", SH_OP_CLRT, OPCODE(0, 0, 0, 8), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM } }, - { "ldc", SH_OP_LDC, OPCODE(4, M, 0, e), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(SR, SH_REG_DIRECT) } }, - { "ldc", SH_OP_LDC, OPCODE(4, M, 1, e), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(GBR, SH_REG_DIRECT) } }, - { "ldc", SH_OP_LDC, OPCODE(4, M, 2, e), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(VBR, SH_REG_DIRECT) } }, - { "ldc", SH_OP_LDC, OPCODE(4, M, 3, e), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(SSR, SH_REG_DIRECT) } }, - { "ldc", SH_OP_LDC, OPCODE(4, M, 4, e), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(SPC, SH_REG_DIRECT) } }, - { "ldc", SH_OP_LDC, OPCODE(4, M, f, a), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(DBR, SH_REG_DIRECT) } }, - { "ldc", SH_OP_LDC, OPCODE(4, M, N, e), 0x0f70, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), ADDRBITS(NIB1, SH_REG_DIRECT, 3) } }, - { "ldc.l", SH_OP_LDC, OPCODE(4, M, 0, 7), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(SR, SH_REG_DIRECT) } }, - { "ldc.l", SH_OP_LDC, OPCODE(4, M, 1, 7), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(GBR, SH_REG_DIRECT) } }, - { "ldc.l", SH_OP_LDC, OPCODE(4, M, 2, 7), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(VBR, SH_REG_DIRECT) } }, - { "ldc.l", SH_OP_LDC, OPCODE(4, M, 3, 7), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(SSR, SH_REG_DIRECT) } }, - { "ldc.l", SH_OP_LDC, OPCODE(4, M, 4, 7), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(SPC, SH_REG_DIRECT) } }, - { "ldc.l", SH_OP_LDC, OPCODE(4, M, f, 6), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(DBR, SH_REG_DIRECT) } }, - { "ldc.l", SH_OP_LDC, OPCODE(4, M, N, 7), 0x0f70, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), ADDRBITS(NIB1, SH_REG_DIRECT, 3) } }, - { "lds", SH_OP_LDS, OPCODE(4, M, 0, a), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(MACH, SH_REG_DIRECT) } }, - { "lds", SH_OP_LDS, OPCODE(4, M, 1, a), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(MACL, SH_REG_DIRECT) } }, - { "lds", SH_OP_LDS, OPCODE(4, M, 2, a), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(PR, SH_REG_DIRECT) } }, - { "lds.l", SH_OP_LDS, OPCODE(4, M, 0, 6), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(MACH, SH_REG_DIRECT) } }, - { "lds.l", SH_OP_LDS, OPCODE(4, M, 1, 6), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(MACL, SH_REG_DIRECT) } }, - { "lds.l", SH_OP_LDS, OPCODE(4, M, 2, 6), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(PR, SH_REG_DIRECT) } }, - { "ldtlb", SH_OP_UNIMPL, OPCODE(0, 0, 3, 8), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM } }, - { "movca.l", SH_OP_MOVCA, OPCODE(0, N, c, 3), 0x0f00, SH_SCALING_L, { PARAM(R0, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT) } }, - { "nop", SH_OP_NOP, OPCODE(0, 0, 0, 9), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM } }, - { "ocbi", SH_OP_UNIMPL, OPCODE(0, N, 9, 3), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_INDIRECT), NOPARAM } }, - { "ocbp", SH_OP_UNIMPL, OPCODE(0, N, a, 3), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_INDIRECT), NOPARAM } }, - { "ocbwb", SH_OP_UNIMPL, OPCODE(0, N, b, 3), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_INDIRECT), NOPARAM } }, - { "pref", SH_OP_UNIMPL, OPCODE(0, N, 8, 3), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_INDIRECT), NOPARAM } }, - { "rte", SH_OP_RTE, OPCODE(0, 0, 2, b), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM } }, - { "sets", SH_OP_SETS, OPCODE(0, 0, 5, 8), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM } }, - { "sett", SH_OP_SETT, OPCODE(0, 0, 1, 8), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM } }, - { "sleep", SH_OP_SLEEP, OPCODE(0, 0, 1, b), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM } }, - { "stc", SH_OP_STC, OPCODE(0, M, 0, 2), 0x0f00, SH_SCALING_INVALID, { PARAM(SR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "stc", SH_OP_STC, OPCODE(0, M, 1, 2), 0x0f00, SH_SCALING_INVALID, { PARAM(GBR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "stc", SH_OP_STC, OPCODE(0, M, 2, 2), 0x0f00, SH_SCALING_INVALID, { PARAM(VBR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "stc", SH_OP_STC, OPCODE(0, M, 3, 2), 0x0f00, SH_SCALING_INVALID, { PARAM(SSR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "stc", SH_OP_STC, OPCODE(0, M, 4, 2), 0x0f00, SH_SCALING_INVALID, { PARAM(SPC, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "stc", SH_OP_STC, OPCODE(0, M, 3, a), 0x0f00, SH_SCALING_INVALID, { PARAM(SGR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "stc", SH_OP_STC, OPCODE(0, M, f, a), 0x0f00, SH_SCALING_INVALID, { PARAM(DBR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "stc", SH_OP_STC, OPCODE(0, N, M, 2), 0x0f70, SH_SCALING_INVALID, { ADDRBITS(NIB1, SH_REG_DIRECT, 3), ADDR(NIB2, SH_REG_DIRECT) } }, - { "stc.l", SH_OP_STC, OPCODE(4, M, 0, 3), 0x0f00, SH_SCALING_L, { PARAM(SR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) } }, - { "stc.l", SH_OP_STC, OPCODE(4, M, 1, 3), 0x0f00, SH_SCALING_L, { PARAM(GBR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) } }, - { "stc.l", SH_OP_STC, OPCODE(4, M, 2, 3), 0x0f00, SH_SCALING_L, { PARAM(VBR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) } }, - { "stc.l", SH_OP_STC, OPCODE(4, M, 3, 3), 0x0f00, SH_SCALING_L, { PARAM(SSR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) } }, - { "stc.l", SH_OP_STC, OPCODE(4, M, 4, 3), 0x0f00, SH_SCALING_L, { PARAM(SPC, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) } }, - { "stc.l", SH_OP_STC, OPCODE(4, M, 3, 2), 0x0f00, SH_SCALING_L, { PARAM(SGR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) } }, - { "stc.l", SH_OP_STC, OPCODE(4, M, f, 2), 0x0f00, SH_SCALING_L, { PARAM(DBR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) } }, - { "stc.l", SH_OP_STC, OPCODE(4, N, M, 3), 0x0f70, SH_SCALING_L, { ADDRBITS(NIB1, SH_REG_DIRECT, 3), ADDR(NIB2, SH_REG_INDIRECT_D) } }, - { "sts", SH_OP_STS, OPCODE(0, N, 0, a), 0x0f00, SH_SCALING_INVALID, { PARAM(MACH, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "sts", SH_OP_STS, OPCODE(0, N, 1, a), 0x0f00, SH_SCALING_INVALID, { PARAM(MACL, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "sts", SH_OP_STS, OPCODE(0, N, 2, a), 0x0f00, SH_SCALING_INVALID, { PARAM(PR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) } }, - { "sts.l", SH_OP_STS, OPCODE(4, N, 0, 2), 0x0f00, SH_SCALING_L, { PARAM(MACH, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) } }, - { "sts.l", SH_OP_STS, OPCODE(4, N, 1, 2), 0x0f00, SH_SCALING_L, { PARAM(MACL, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) } }, - { "sts.l", SH_OP_STS, OPCODE(4, N, 2, 2), 0x0f00, SH_SCALING_L, { PARAM(PR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) } }, - { "trapa", SH_OP_UNIMPL, OPCODE(c, 3, I, I), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_U), NOPARAM } } + { "clrmac", SH_OP_CLRMAC, OPCODE(0, 0, 2, 8), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM }, SH_ARCH_COMMON }, + { "clrs", SH_OP_CLRS, OPCODE(0, 0, 4, 8), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM }, SH_ARCH_COMMON }, + { "clrt", SH_OP_CLRT, OPCODE(0, 0, 0, 8), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM }, SH_ARCH_COMMON }, + { "ldc", SH_OP_LDC, OPCODE(4, M, 0, e), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(SR, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "ldc", SH_OP_LDC, OPCODE(4, M, 1, e), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(GBR, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "ldc", SH_OP_LDC, OPCODE(4, M, 2, e), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(VBR, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "ldc", SH_OP_LDC, OPCODE(4, M, 3, e), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(SSR, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "ldc", SH_OP_LDC, OPCODE(4, M, 4, e), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(SPC, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "ldc", SH_OP_LDC, OPCODE(4, M, f, a), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(DBR, SH_REG_DIRECT) }, SH_ARCH_SH4 }, + { "ldc", SH_OP_LDC, OPCODE(4, M, N, e), 0x0f70, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), ADDRBITS(NIB1, SH_REG_DIRECT, 3) }, SH_ARCH_COMMON }, + { "ldc.l", SH_OP_LDC, OPCODE(4, M, 0, 7), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(SR, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "ldc.l", SH_OP_LDC, OPCODE(4, M, 1, 7), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(GBR, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "ldc.l", SH_OP_LDC, OPCODE(4, M, 2, 7), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(VBR, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "ldc.l", SH_OP_LDC, OPCODE(4, M, 3, 7), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(SSR, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "ldc.l", SH_OP_LDC, OPCODE(4, M, 4, 7), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(SPC, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "ldc.l", SH_OP_LDC, OPCODE(4, M, f, 6), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(DBR, SH_REG_DIRECT) }, SH_ARCH_SH4 }, + { "ldc.l", SH_OP_LDC, OPCODE(4, M, N, 7), 0x0f70, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), ADDRBITS(NIB1, SH_REG_DIRECT, 3) }, SH_ARCH_COMMON }, + { "lds", SH_OP_LDS, OPCODE(4, M, 0, a), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(MACH, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "lds", SH_OP_LDS, OPCODE(4, M, 1, a), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(MACL, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "lds", SH_OP_LDS, OPCODE(4, M, 2, a), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_DIRECT), PARAM(PR, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "lds.l", SH_OP_LDS, OPCODE(4, M, 0, 6), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(MACH, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "lds.l", SH_OP_LDS, OPCODE(4, M, 1, 6), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(MACL, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "lds.l", SH_OP_LDS, OPCODE(4, M, 2, 6), 0x0f00, SH_SCALING_L, { ADDR(NIB2, SH_REG_INDIRECT_I), PARAM(PR, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "ldtlb", SH_OP_UNIMPL, OPCODE(0, 0, 3, 8), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM }, SH_ARCH_COMMON }, + { "movca.l", SH_OP_MOVCA, OPCODE(0, N, c, 3), 0x0f00, SH_SCALING_L, { PARAM(R0, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT) }, SH_ARCH_SH4 }, + { "nop", SH_OP_NOP, OPCODE(0, 0, 0, 9), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM }, SH_ARCH_COMMON }, + { "ocbi", SH_OP_UNIMPL, OPCODE(0, N, 9, 3), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_INDIRECT), NOPARAM }, SH_ARCH_SH4 }, + { "ocbp", SH_OP_UNIMPL, OPCODE(0, N, a, 3), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_INDIRECT), NOPARAM }, SH_ARCH_SH4 }, + { "ocbwb", SH_OP_UNIMPL, OPCODE(0, N, b, 3), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_INDIRECT), NOPARAM }, SH_ARCH_SH4 }, + { "pref", SH_OP_UNIMPL, OPCODE(0, N, 8, 3), 0x0f00, SH_SCALING_INVALID, { ADDR(NIB2, SH_REG_INDIRECT), NOPARAM }, SH_ARCH_COMMON }, + { "rte", SH_OP_RTE, OPCODE(0, 0, 2, b), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM }, SH_ARCH_COMMON }, + { "sets", SH_OP_SETS, OPCODE(0, 0, 5, 8), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM }, SH_ARCH_COMMON }, + { "sett", SH_OP_SETT, OPCODE(0, 0, 1, 8), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM }, SH_ARCH_COMMON }, + { "sleep", SH_OP_SLEEP, OPCODE(0, 0, 1, b), 0x0000, SH_SCALING_INVALID, { NOPARAM, NOPARAM }, SH_ARCH_COMMON }, + { "stc", SH_OP_STC, OPCODE(0, M, 0, 2), 0x0f00, SH_SCALING_INVALID, { PARAM(SR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "stc", SH_OP_STC, OPCODE(0, M, 1, 2), 0x0f00, SH_SCALING_INVALID, { PARAM(GBR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "stc", SH_OP_STC, OPCODE(0, M, 2, 2), 0x0f00, SH_SCALING_INVALID, { PARAM(VBR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "stc", SH_OP_STC, OPCODE(0, M, 3, 2), 0x0f00, SH_SCALING_INVALID, { PARAM(SSR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "stc", SH_OP_STC, OPCODE(0, M, 4, 2), 0x0f00, SH_SCALING_INVALID, { PARAM(SPC, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "stc", SH_OP_STC, OPCODE(0, M, 3, a), 0x0f00, SH_SCALING_INVALID, { PARAM(SGR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_SH4 }, + { "stc", SH_OP_STC, OPCODE(0, M, f, a), 0x0f00, SH_SCALING_INVALID, { PARAM(DBR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_SH4 }, + { "stc", SH_OP_STC, OPCODE(0, N, M, 2), 0x0f70, SH_SCALING_INVALID, { ADDRBITS(NIB1, SH_REG_DIRECT, 3), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "stc.l", SH_OP_STC, OPCODE(4, M, 0, 3), 0x0f00, SH_SCALING_L, { PARAM(SR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) }, SH_ARCH_COMMON }, + { "stc.l", SH_OP_STC, OPCODE(4, M, 1, 3), 0x0f00, SH_SCALING_L, { PARAM(GBR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) }, SH_ARCH_COMMON }, + { "stc.l", SH_OP_STC, OPCODE(4, M, 2, 3), 0x0f00, SH_SCALING_L, { PARAM(VBR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) }, SH_ARCH_COMMON }, + { "stc.l", SH_OP_STC, OPCODE(4, M, 3, 3), 0x0f00, SH_SCALING_L, { PARAM(SSR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) }, SH_ARCH_COMMON }, + { "stc.l", SH_OP_STC, OPCODE(4, M, 4, 3), 0x0f00, SH_SCALING_L, { PARAM(SPC, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) }, SH_ARCH_COMMON }, + { "stc.l", SH_OP_STC, OPCODE(4, M, 3, 2), 0x0f00, SH_SCALING_L, { PARAM(SGR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) }, SH_ARCH_SH4 }, + { "stc.l", SH_OP_STC, OPCODE(4, M, f, 2), 0x0f00, SH_SCALING_L, { PARAM(DBR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) }, SH_ARCH_SH4 }, + { "stc.l", SH_OP_STC, OPCODE(4, N, M, 3), 0x0f70, SH_SCALING_L, { ADDRBITS(NIB1, SH_REG_DIRECT, 3), ADDR(NIB2, SH_REG_INDIRECT_D) }, SH_ARCH_COMMON }, + { "sts", SH_OP_STS, OPCODE(0, N, 0, a), 0x0f00, SH_SCALING_INVALID, { PARAM(MACH, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "sts", SH_OP_STS, OPCODE(0, N, 1, a), 0x0f00, SH_SCALING_INVALID, { PARAM(MACL, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "sts", SH_OP_STS, OPCODE(0, N, 2, a), 0x0f00, SH_SCALING_INVALID, { PARAM(PR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_DIRECT) }, SH_ARCH_COMMON }, + { "sts.l", SH_OP_STS, OPCODE(4, N, 0, 2), 0x0f00, SH_SCALING_L, { PARAM(MACH, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) }, SH_ARCH_COMMON }, + { "sts.l", SH_OP_STS, OPCODE(4, N, 1, 2), 0x0f00, SH_SCALING_L, { PARAM(MACL, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) }, SH_ARCH_COMMON }, + { "sts.l", SH_OP_STS, OPCODE(4, N, 2, 2), 0x0f00, SH_SCALING_L, { PARAM(PR, SH_REG_DIRECT), ADDR(NIB2, SH_REG_INDIRECT_D) }, SH_ARCH_COMMON }, + { "trapa", SH_OP_UNIMPL, OPCODE(c, 3, I, I), 0x00ff, SH_SCALING_INVALID, { ADDR(NIB0, SH_IMM_U), NOPARAM }, SH_ARCH_COMMON } /* floating-point single-precision instructions */ // TODO diff --git a/librz/arch/isa/sh/sh_il.c b/librz/arch/isa/sh/sh_il.c index dbf8b3866b..ddcb90c019 100644 --- a/librz/arch/isa/sh/sh_il.c +++ b/librz/arch/isa/sh/sh_il.c @@ -382,7 +382,9 @@ static SHParamHelper sh_il_get_param_pc_ctx(SHParam param, SHScaling scaling, ut ret.pure = UN(sh_scaling_size[scaling] * BITS_PER_BYTE, param.param[0]); break; case SH_IMM_S: - ret.pure = SN(sh_scaling_size[scaling] * BITS_PER_BYTE, param.param[0]); + // the immediate is an 8 bit field which must be sign-extended to the + // operation width (e.g. `add #imm, Rn` and `mov #imm, Rn`) + ret.pure = SN(sh_scaling_size[scaling] * BITS_PER_BYTE, (st8)param.param[0]); break; default: RZ_LOG_ERROR("RzIL: SuperH: Invalid addressing mode\n"); @@ -1353,7 +1355,8 @@ static RzILOpEffect *sh_il_shlr16(const SHOp *op, ut64 pc, RzAnalysis *analysis, */ static RzILOpEffect *sh_il_bf(const SHOp *op, ut64 pc, RzAnalysis *analysis, SHILContext *ctx) { RzILOpPure *new_pc = sh_il_get_effective_addr_param(0); - return BRANCH(VARG(SH_SR_T), JMP(new_pc), NOP()); + // BF branches when T = 0, so the jump is the false-branch of the condition + return BRANCH(VARG(SH_SR_T), NOP(), JMP(new_pc)); } /** @@ -1364,7 +1367,8 @@ static RzILOpEffect *sh_il_bf(const SHOp *op, ut64 pc, RzAnalysis *analysis, SHI */ static RzILOpEffect *sh_il_bfs(const SHOp *op, ut64 pc, RzAnalysis *analysis, SHILContext *ctx) { RzILOpPure *new_pc = sh_il_get_effective_addr_param(0); - return BRANCH(VARG(SH_SR_T), JMP(new_pc), NOP()); + // BF/S branches when T = 0, so the jump is the false-branch of the condition + return BRANCH(VARG(SH_SR_T), NOP(), JMP(new_pc)); } /** diff --git a/librz/arch/p/analysis/analysis_sh.c b/librz/arch/p/analysis/analysis_sh.c index 86b9798213..cd509dea34 100644 --- a/librz/arch/p/analysis/analysis_sh.c +++ b/librz/arch/p/analysis/analysis_sh.c @@ -1101,13 +1101,23 @@ static int sh_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *d ret = first_nibble_decode[(op_MSB >> 4) & 0x0F](analysis, op, opcode); // RzIL uplifting - SHOp *ilop = sh_disassembler(opcode); - SHILContext *ctx = RZ_NEW0(SHILContext); - ctx->use_banked = true; + SHCpu cpu = sh_cpu_by_name(rz_analysis_get_cpu(analysis)); + SHOp *ilop = sh_disassembler(opcode, cpu); if (ilop) { + SHILContext *ctx = RZ_NEW0(SHILContext); + ctx->use_banked = true; rz_sh_il_opcode(analysis, op, addr, ilop, ctx); + RZ_FREE(ctx); + } else if (cpu != SH_CPU_SH4) { + // The instruction may belong to a more capable CPU (e.g. an + // SuperH-4 only instruction decoded while targeting SuperH-3). + // In that case it is illegal for the selected CPU. + SHOp *sh4op = sh_disassembler(opcode, SH_CPU_SH4); + if (sh4op) { + op->type = RZ_ANALYSIS_OP_TYPE_ILL; + RZ_FREE(sh4op); + } } - RZ_FREE(ctx); RZ_FREE(ilop); return ret; @@ -1193,7 +1203,7 @@ static int sh_archinfo(RzAnalysis *a, RzAnalysisInfoType query) { RzAnalysisPlugin rz_analysis_plugin_sh = { .name = "sh", - .desc = "SH-4 code analysis plugin", + .desc = "SH-4/SH-3 code analysis plugin", .license = "LGPL3", .arch = "sh", .archinfo = sh_archinfo, diff --git a/librz/arch/p/asm/asm_sh.c b/librz/arch/p/asm/asm_sh.c index a1ecd153cc..e3f919096e 100644 --- a/librz/arch/p/asm/asm_sh.c +++ b/librz/arch/p/asm/asm_sh.c @@ -10,7 +10,8 @@ #include "sh/assembler.h" static int disassemble(const RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { - SHOp *dis_op = sh_disassembler(rz_read_ble16(buf, a->big_endian)); + SHCpu cpu = sh_cpu_by_name(a->cpu); + SHOp *dis_op = sh_disassembler(rz_read_ble16(buf, a->big_endian), cpu); op->size = 2; if (!dis_op) { rz_strbuf_set(&op->buf_asm, "invalid"); @@ -25,7 +26,8 @@ static int disassemble(const RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { static int assemble(const RzAsm *a, RzAsmOp *ao, const char *str) { bool success; - ut16 opcode = sh_assembler(str, a->pc, &success); + SHCpu cpu = sh_cpu_by_name(a->cpu); + ut16 opcode = sh_assembler(str, a->pc, &success, cpu); if (!success) { return -1; } @@ -50,7 +52,8 @@ RzAsmPlugin rz_asm_plugin_sh = { .license = "LGPL3", .bits = 32, .endian = RZ_SYS_ENDIAN_LITTLE | RZ_SYS_ENDIAN_BIG, - .desc = "Hitachi/Renesas SuperH-4 disassembler", + .cpus = "sh4,sh3", + .desc = "Hitachi/Renesas SuperH-4/SuperH-3 disassembler", .disassemble = &disassemble, .assemble = &assemble, .sw_breakpoint = sh_sw_breakpoint, diff --git a/test/db/analysis/sh3 b/test/db/analysis/sh3 new file mode 100644 index 0000000000..df585b5bf3 --- /dev/null +++ b/test/db/analysis/sh3 @@ -0,0 +1,67 @@ +NAME=SuperH-3 asm.cpu disassembly and control flow +FILE=malloc://32 +CMDS=<> (var r13) (bv 32 0x10) false)) # Branch instructions -adE "bf 0x00000072" 8b27 0x20 (branch (var sr_t) (jmp (+ (+ (bv 32 0x20) (bv 32 0x4)) (<< (bv 32 0x27) (bv 32 0x1) false))) nop) -adE "bf/s 0x00000072" 8f27 0x20 (branch (var sr_t) (jmp (+ (+ (bv 32 0x20) (bv 32 0x4)) (<< (bv 32 0x27) (bv 32 0x1) false))) nop) +adE "bf 0x00000072" 8b27 0x20 (branch (var sr_t) nop (jmp (+ (+ (bv 32 0x20) (bv 32 0x4)) (<< (bv 32 0x27) (bv 32 0x1) false)))) +adE "bf/s 0x00000072" 8f27 0x20 (branch (var sr_t) nop (jmp (+ (+ (bv 32 0x20) (bv 32 0x4)) (<< (bv 32 0x27) (bv 32 0x1) false)))) adE "bt 0x00000004" 8900 0x0 (branch (var sr_t) (jmp (+ (+ (bv 32 0x0) (bv 32 0x4)) (<< (bv 32 0x0) (bv 32 0x1) false))) nop) adE "bt/s 0xd3adb008" 8dfe 0xd3adb008 (branch (var sr_t) (jmp (+ (+ (bv 32 0xd3adb008) (bv 32 0x4)) (<< (bv 32 0xfffffffe) (bv 32 0x1) false))) nop) adE "bra 0x00000004" a000 0x0 (jmp (+ (+ (bv 32 0x0) (bv 32 0x4)) (<< (bv 32 0x0) (bv 32 0x1) false))) diff --git a/test/db/asm/sh_sh3_32 b/test/db/asm/sh_sh3_32 new file mode 100644 index 0000000000..9e55442a6c --- /dev/null +++ b/test/db/asm/sh_sh3_32 @@ -0,0 +1,40 @@ +# SuperH-3 (asm.cpu=sh3) +# SuperH-4 only instructions must be rejected when targeting SuperH-3 +dE "invalid" 01c3 # movca.l r0, @r1 (SH-4) +dE "invalid" 0293 # ocbi @r2 (SH-4) +dE "invalid" 03a3 # ocbp @r3 (SH-4) +dE "invalid" 04b3 # ocbwb @r4 (SH-4) +dE "invalid" 053a # stc sgr, r5 (SH-4) +dE "invalid" 06fa # stc dbr, r6 (SH-4) +dE "invalid" 47fa # ldc r7, dbr (SH-4) +dE "invalid" 4832 # stc.l sgr, @-r8 (SH-4) +dE "invalid" 49f2 # stc.l dbr, @-r9 (SH-4) +dE "invalid" 4af6 # ldc.l @r10+, dbr (SH-4) + +# SuperH-3 specific instructions (shared with SuperH-4) +adE "shad r1, r2" 421c 0x0 (seq (set _priv (&& (var sr_d) (var sr_r))) (set shift_ (cast 5 false (ite (var _priv) (var r1b) (var r1)))) (branch (|| (! (sle (ite (var _priv) (var r1b) (var r1)) (bv 32 0x0))) (== (ite (var _priv) (var r1b) (var r1)) (bv 32 0x0))) (seq (set _regv (<< (ite (var _priv) (var r2b) (var r2)) (var shift_) false)) (branch (var _priv) (set r2b (var _regv)) (set r2 (var _regv)))) (seq (set _regv (>> (ite (var _priv) (var r2b) (var r2)) (~- (var shift_)) (msb (ite (var _priv) (var r2b) (var r2))))) (branch (var _priv) (set r2b (var _regv)) (set r2 (var _regv)))))) +adE "shld r3, r4" 443d 0x0 (seq (set _priv (&& (var sr_d) (var sr_r))) (set shift_ (cast 5 false (ite (var _priv) (var r3b) (var r3)))) (branch (|| (! (sle (ite (var _priv) (var r3b) (var r3)) (bv 32 0x0))) (== (ite (var _priv) (var r3b) (var r3)) (bv 32 0x0))) (seq (set _regv (<< (ite (var _priv) (var r4b) (var r4)) (var shift_) false)) (branch (var _priv) (set r4b (var _regv)) (set r4 (var _regv)))) (seq (set _regv (>> (ite (var _priv) (var r4b) (var r4)) (~- (var shift_)) false)) (branch (var _priv) (set r4b (var _regv)) (set r4 (var _regv)))))) +adE "clrs" 0048 0x0 (set sr_s false) +adE "sets" 0058 0x0 (set sr_s true) +adE "ldc r6, ssr" 463e 0x0 (seq (set _priv (&& (var sr_d) (var sr_r))) (branch (var _priv) (set ssr (var r6)) empty)) +adE "stc ssr, r7" 0732 0x0 (seq (set _priv (&& (var sr_d) (var sr_r))) (branch (var _priv) (set r7 (var ssr)) empty)) +adE "ldc r8, spc" 484e 0x0 (seq (set _priv (&& (var sr_d) (var sr_r))) (branch (var _priv) (set spc (var r8)) empty)) +adE "stc spc, r9" 0942 0x0 (seq (set _priv (&& (var sr_d) (var sr_r))) (branch (var _priv) (set r9 (var spc)) empty)) +adE "ldc r10, r0b" 4a8e 0x0 (seq (set _priv (&& (var sr_d) (var sr_r))) (branch (var _priv) (set r0b (var r10)) empty)) +adE "ldc.l @r10+, r0b" 4a87 0x0 (seq (set _priv (&& (var sr_d) (var sr_r))) (branch (var _priv) (seq (set r0b (loadw 0 32 (var r10))) (set r10 (+ (var r10) (bv 32 0x4)))) empty)) +adE "pref @r5" 0583 0x0 +adE "ldtlb" 0038 0x0 + +# A sample of common instructions must keep working under SuperH-3 +adE "nop" 0009 0x0 nop +adE "mov 0x27, r7" e727 0x0 (seq (set _priv (&& (var sr_d) (var sr_r))) (set _regv (bv 32 0x27)) (branch (var _priv) (set r7b (var _regv)) (set r7 (var _regv)))) +adE "add 0x01, r3" 7301 0x0 (seq (set _priv (&& (var sr_d) (var sr_r))) (set _regv (+ (bv 32 0x1) (ite (var _priv) (var r3b) (var r3)))) (branch (var _priv) (set r3b (var _regv)) (set r3 (var _regv)))) +adE "add r0, r0" 300c 0x0 (seq (set _priv (&& (var sr_d) (var sr_r))) (set _regv (+ (ite (var _priv) (var r0b) (var r0)) (ite (var _priv) (var r0b) (var r0)))) (branch (var _priv) (set r0b (var _regv)) (set r0 (var _regv)))) +adE "tst r0, r0" 2008 0x0 (seq (set _priv (&& (var sr_d) (var sr_r))) (set sr_t (is_zero (& (ite (var _priv) (var r0b) (var r0)) (ite (var _priv) (var r0b) (var r0)))))) +adE "bf 0x00000024" 8b10 0x0 (branch (var sr_t) nop (jmp (+ (+ (bv 32 0x0) (bv 32 0x4)) (<< (bv 32 0x10) (bv 32 0x1) false)))) +adE "rts" 000b 0x0 (jmp (var pr)) +adE "jmp @r0" 402b 0x0 (seq (set _priv (&& (var sr_d) (var sr_r))) (jmp (ite (var _priv) (var r0b) (var r0)))) + +# 8 bit immediates of mov/add/cmp-eq are sign-extended in the IL +adE "mov 0xff, r0" e0ff 0x0 (seq (set _priv (&& (var sr_d) (var sr_r))) (set _regv (bv 32 0xffffffff)) (branch (var _priv) (set r0b (var _regv)) (set r0 (var _regv)))) +adE "add 0xc0, r5" 75c0 0x0 (seq (set _priv (&& (var sr_d) (var sr_r))) (set _regv (+ (bv 32 0xffffffc0) (ite (var _priv) (var r5b) (var r5)))) (branch (var _priv) (set r5b (var _regv)) (set r5 (var _regv)))) diff --git a/test/db/cmd/cmd_aL b/test/db/cmd/cmd_aL index 2d77205aad..891249440f 100644 --- a/test/db/cmd/cmd_aL +++ b/test/db/cmd/cmd_aL @@ -52,7 +52,7 @@ _dA__ 32 64 riscv BSD RISC-V Capstone-based disassembler adA__ 32 rl78 LGPL3 Renesas RL78 disassembler (by Bastian Engel) _dA__ 32 rsp LGPL3 Nintendo N64 Reality Signal Processor disassembler _dA__ 32 rx LGPL3 Renesas RX Family disassembler (by Heersin) -adAeI 32 sh LGPL3 Hitachi/Renesas SuperH-4 disassembler (by DMaroo) +adAeI 32 sh LGPL3 Hitachi/Renesas SuperH-4/SuperH-3 disassembler (by DMaroo) _dA__ 8 16 snes LGPL3 SuperNES CPU disassembler _dA_I 32 64 sparc BSD Sun SPARC Capstone-based disassembler _dA__ 16 spc700 LGPL3 Sony SPC700 (Nintendo SuperNES sound-chip) disassembler diff --git a/test/db/cmd/cmd_list b/test/db/cmd/cmd_list index 60f719d717..0a4830e78d 100644 --- a/test/db/cmd/cmd_list +++ b/test/db/cmd/cmd_list @@ -779,7 +779,7 @@ _dA__ 32 64 riscv BSD RISC-V Capstone-based disassembler adA__ 32 rl78 LGPL3 Renesas RL78 disassembler (by Bastian Engel) _dA__ 32 rsp LGPL3 Nintendo N64 Reality Signal Processor disassembler _dA__ 32 rx LGPL3 Renesas RX Family disassembler (by Heersin) -adAeI 32 sh LGPL3 Hitachi/Renesas SuperH-4 disassembler (by DMaroo) +adAeI 32 sh LGPL3 Hitachi/Renesas SuperH-4/SuperH-3 disassembler (by DMaroo) _dA__ 8 16 snes LGPL3 SuperNES CPU disassembler _dA_I 32 64 sparc BSD Sun SPARC Capstone-based disassembler _dA__ 16 spc700 LGPL3 Sony SPC700 (Nintendo SuperNES sound-chip) disassembler @@ -798,7 +798,7 @@ _dA__ 16 xap PD Cambridge Consultants XAP4 RISC (CSR) disas _dA__ 32 xcore BSD XCore Capstone-based disassembler (by pancake) _dAeI 32 xtensa LGPL3 Tensilica Xtensa Capstone-based disassembler (by billow) adA__ 8 z80 GPL3 Zilog Z80 disassembler (by condret) -["6502":{"bits":"8 16 ","license":"LGPL3","description":"6502/NES/C64/Tamagotchi/T-1000 CPU","features":"_dAeI"},"8051":{"bits":"8 ","license":"PD","description":"Intel 8051 disassembler","features":"adAeI"},"alpha":{"bits":"32 64","license":"LGPL3","description":"DEC Alpha Capstone-based disassembler","features":"_dA__"},"amd29k":{"bits":"32 ","license":"LGPL3","description":"AMD 29k RISC disassembler","features":"_dA__","author":"deroad"},"arc":{"bits":"16 32 ","license":"GPL3","description":"Argonaut RISC Core","features":"_dA__"},"arm":{"bits":"16 32 64","license":"BSD","description":"ARM Capstone-based disassembler","features":"adAeI"},"arm.as":{"bits":"16 32 64","license":"LGPL3","description":"as ARM Assembler (use RZ_ARM32_AS and RZ_ARM64_AS environment)","features":"a____","author":"pancake"},"avr":{"bits":"8 16 ","license":"LGPL3","description":"Atmel AVR disassembler","features":"adAeI"},"bf":{"bits":"16 32 64","license":"LGPL3","description":"Brainfuck","features":"adA_I","author":"pancake, nibble","version":"4.0.0"},"c166":{"bits":"16 ","license":"LGPL3","description":"Siemens/Infineon C166 microcontroller disassembler","features":"_dA__"},"cbpf":{"bits":"32 ","license":"LGPL3","description":"CBPF disassembly plugin","features":"_dA__"},"chip8":{"bits":"32 ","license":"LGPL3","description":"Chip8 disassembler","features":"_dA__"},"cil":{"bits":"16 32 64","license":"LGPL3","description":".NET CIL/MSIL (Common Intermediate Language) bytecode disassembler","features":"_dA__"},"cr16":{"bits":"16 ","license":"LGPL3","description":"CompactRISC CR16 disassembler","features":"_dA__"},"cris":{"bits":"32 ","license":"GPL3","description":"Axis Communications 32-bit embedded processor disassembler","features":"_dA__","author":"pancake"},"dalvik":{"bits":"32 64","license":"LGPL3","description":"Dalvik (Android VM) bytecode disassembler","features":"adA__"},"dcpu16":{"bits":"16 ","license":"PD","description":"Mojang's DCPU-16 disassembler","features":"ad___"},"ebc":{"bits":"32 64","license":"LGPL3","description":"EFI bytecode disassembler","features":"_dA__","author":"Fedor Sakharov"},"gb":{"bits":"16 ","license":"LGPL3","description":"GameBoy(TM) (z80-like)","features":"adAeI","author":"condret"},"h8300":{"bits":"16 ","license":"LGPL3","description":"Hitachi/Renesas H8/300 disassembly plugin","features":"_dAeI"},"h8500":{"bits":"16 ","license":"LGPL3","description":"Hitachi/Renesas H8/500 disassembler","features":"_dA__","author":"billow"},"hexagon":{"bits":"32 ","license":"LGPL3","description":"Qualcomm Hexagon (QDSP6) V6","features":"_dA_I","author":"Rot127"},"hppa":{"bits":"32 64","license":"LGPL3","description":"HP PA-RISC Capstone-based disassembler","features":"_dA__","author":"xvilka"},"i4004":{"bits":"4 ","license":"LGPL3","description":"Intel 4004 disassembler","features":"_dA__"},"i8080":{"bits":"8 ","license":"BSD","description":"Intel 8080 disassembler","features":"_dA__"},"java":{"bits":"32 ","license":"LGPL-3","description":"Java bytecode disassembler","features":"adA__","author":"deroad"},"lanai":{"bits":"32 ","license":"GPL3","description":"Google LANAI disassembler","features":"_d___"},"lh5801":{"bits":"8 ","license":"LGPL3","description":"SHARP LH5801 disassembler","features":"_d___"},"lm32":{"bits":"32 ","license":"BSD","description":"Lattice Micro 32 ISA disassembler","features":"_d___","author":"Felix Held"},"loongarch":{"bits":"32 64","license":"LGPL3","description":"Loongson LoongArch disassembler","features":"_dA__"},"luac":{"bits":"32 ","license":"LGPL3","description":"Lua bytecode (LUAC) disassembler","features":"adA__"},"m680x":{"bits":"8 32 ","license":"BSD","description":"Motorola 680X Capstone-based disassembler","features":"_dA__"},"m68k":{"bits":"32 ","license":"BSD","description":"Motorola 68K Capstone-based disassembler","features":"_dA__"},"malbolge":{"bits":"32 ","license":"LGPL3","description":"Malbolge Ternary VM bytecode disassembler","features":"_dA__","author":"condret"},"mcore":{"bits":"32 ","license":"LGPL3","description":"Motorola MCORE disassembler","features":"_dA__"},"mcs96":{"bits":"16 ","license":"LGPL3","description":"Intel MCS-96 disassembler","features":"_dA__","author":"condret"},"milstd1750":{"bits":"8 ","license":"MIT","description":"MIL-STD 1750 ISA disassembler","features":"_dA__"},"mips":{"bits":"16 32 64","license":"BSD","description":"MIPS Capstone-based disassembler","features":"adAeI"},"msp430":{"bits":"16 ","license":"LGPL3","description":"Texas Instruments MSP430 disassembler","features":"_dA_I"},"null":{"bits":"16 32 64","license":"MIT","description":"NULL (empty) disassembler","features":"adA__","author":"pancake","version":"1.0.0"},"or1k":{"bits":"32 ","license":"LGPL3","description":"OpenRISC 1000 disassembler","features":"_dA__"},"pic":{"bits":"16 32 ","license":"LGPL3","description":"Microchip PIC disassembler","features":"_dAeI"},"ppc":{"bits":"32 64","license":"BSD","description":"PowerPC Capstone-based disassembler","features":"_dAeI","author":"pancake"},"ppc.as":{"bits":"32 64","license":"LGPL3","description":"as PPC Assembler (use RZ_PPC_AS environment)","features":"a____","author":"eagleoflqj"},"propeller":{"bits":"32 ","license":"LGPL3","description":"Parallax Propeller disassembler","features":"_dA__"},"pyc":{"bits":"8 16 ","license":"LGPL3","description":"Python bytecode (PYC) disassembler","features":"_dA__"},"riscv":{"bits":"32 64","license":"BSD","description":"RISC-V Capstone-based disassembler","features":"_dA__"},"rl78":{"bits":"32 ","license":"LGPL3","description":"Renesas RL78 disassembler","features":"adA__","author":"Bastian Engel"},"rsp":{"bits":"32 ","license":"LGPL3","description":"Nintendo N64 Reality Signal Processor disassembler","features":"_dA__"},"rx":{"bits":"32 ","license":"LGPL3","description":"Renesas RX Family disassembler","features":"_dA__","author":"Heersin"},"sh":{"bits":"32 ","license":"LGPL3","description":"Hitachi/Renesas SuperH-4 disassembler","features":"adAeI","author":"DMaroo"},"snes":{"bits":"8 16 ","license":"LGPL3","description":"SuperNES CPU disassembler","features":"_dA__"},"sparc":{"bits":"32 64","license":"BSD","description":"Sun SPARC Capstone-based disassembler","features":"_dA_I"},"spc700":{"bits":"16 ","license":"LGPL3","description":"Sony SPC700 (Nintendo SuperNES sound-chip) disassembler","features":"_dA__"},"sysz":{"bits":"32 64","license":"BSD","description":"IBM SystemZ (S/390) Capstone-based disassembler","features":"_dA__"},"tms320":{"bits":"32 ","license":"LGPL3","description":"Texas Instruments TMS320 DSP family (c54x,c55x,c55x+,c64x) disassembler","features":"_dA_I"},"tricore":{"bits":"32 ","license":"BSD","description":"Siemens TriCore Capstone-based disassembler","features":"_dA_I","author":"billow"},"v810":{"bits":"32 ","license":"LGPL3","description":"NEC V810 disassembler","features":"_dAeI","author":"pancake"},"v850":{"bits":"32 ","license":"LGPL3","description":"NEC/Renesas V850 disassembler","features":"_dAeI"},"vax":{"bits":"32 ","license":"LGPL3","description":"DEC VAX-11 disassembler","features":"_dA__","author":"xvilka"},"wasm":{"bits":"32 ","license":"MIT","description":"WebAssembly disassembler","features":"adA__","author":"cgvwzq","version":"0.1.0"},"x86":{"bits":"16 32 64","license":"MIT","description":"X86/X86_64 Zydis-based disassembler","features":"_dAeI"},"x86.as":{"bits":"16 32 64","license":"LGPL3","description":"Intel X86 GNU Assembler (Use RZ_X86_AS env)","features":"a____"},"x86.nasm":{"bits":"16 32 64","license":"LGPL3","description":"X86 nasm assembler","features":"a____"},"x86.nz":{"bits":"16 32 64","license":"LGPL3","description":"x86 handmade assembler","features":"a____"},"xap":{"bits":"16 ","license":"PD","description":"Cambridge Consultants XAP4 RISC (CSR) disassembler","features":"_dA__"},"xcore":{"bits":"32 ","license":"BSD","description":"XCore Capstone-based disassembler","features":"_dA__","author":"pancake"},"xtensa":{"bits":"32 ","license":"LGPL3","description":"Tensilica Xtensa Capstone-based disassembler","features":"_dAeI","author":"billow"},"z80":{"bits":"8 ","license":"GPL3","description":"Zilog Z80 disassembler","features":"adA__","author":"condret"}] +["6502":{"bits":"8 16 ","license":"LGPL3","description":"6502/NES/C64/Tamagotchi/T-1000 CPU","features":"_dAeI"},"8051":{"bits":"8 ","license":"PD","description":"Intel 8051 disassembler","features":"adAeI"},"alpha":{"bits":"32 64","license":"LGPL3","description":"DEC Alpha Capstone-based disassembler","features":"_dA__"},"amd29k":{"bits":"32 ","license":"LGPL3","description":"AMD 29k RISC disassembler","features":"_dA__","author":"deroad"},"arc":{"bits":"16 32 ","license":"GPL3","description":"Argonaut RISC Core","features":"_dA__"},"arm":{"bits":"16 32 64","license":"BSD","description":"ARM Capstone-based disassembler","features":"adAeI"},"arm.as":{"bits":"16 32 64","license":"LGPL3","description":"as ARM Assembler (use RZ_ARM32_AS and RZ_ARM64_AS environment)","features":"a____","author":"pancake"},"avr":{"bits":"8 16 ","license":"LGPL3","description":"Atmel AVR disassembler","features":"adAeI"},"bf":{"bits":"16 32 64","license":"LGPL3","description":"Brainfuck","features":"adA_I","author":"pancake, nibble","version":"4.0.0"},"c166":{"bits":"16 ","license":"LGPL3","description":"Siemens/Infineon C166 microcontroller disassembler","features":"_dA__"},"cbpf":{"bits":"32 ","license":"LGPL3","description":"CBPF disassembly plugin","features":"_dA__"},"chip8":{"bits":"32 ","license":"LGPL3","description":"Chip8 disassembler","features":"_dA__"},"cil":{"bits":"16 32 64","license":"LGPL3","description":".NET CIL/MSIL (Common Intermediate Language) bytecode disassembler","features":"_dA__"},"cr16":{"bits":"16 ","license":"LGPL3","description":"CompactRISC CR16 disassembler","features":"_dA__"},"cris":{"bits":"32 ","license":"GPL3","description":"Axis Communications 32-bit embedded processor disassembler","features":"_dA__","author":"pancake"},"dalvik":{"bits":"32 64","license":"LGPL3","description":"Dalvik (Android VM) bytecode disassembler","features":"adA__"},"dcpu16":{"bits":"16 ","license":"PD","description":"Mojang's DCPU-16 disassembler","features":"ad___"},"ebc":{"bits":"32 64","license":"LGPL3","description":"EFI bytecode disassembler","features":"_dA__","author":"Fedor Sakharov"},"gb":{"bits":"16 ","license":"LGPL3","description":"GameBoy(TM) (z80-like)","features":"adAeI","author":"condret"},"h8300":{"bits":"16 ","license":"LGPL3","description":"Hitachi/Renesas H8/300 disassembly plugin","features":"_dAeI"},"h8500":{"bits":"16 ","license":"LGPL3","description":"Hitachi/Renesas H8/500 disassembler","features":"_dA__","author":"billow"},"hexagon":{"bits":"32 ","license":"LGPL3","description":"Qualcomm Hexagon (QDSP6) V6","features":"_dA_I","author":"Rot127"},"hppa":{"bits":"32 64","license":"LGPL3","description":"HP PA-RISC Capstone-based disassembler","features":"_dA__","author":"xvilka"},"i4004":{"bits":"4 ","license":"LGPL3","description":"Intel 4004 disassembler","features":"_dA__"},"i8080":{"bits":"8 ","license":"BSD","description":"Intel 8080 disassembler","features":"_dA__"},"java":{"bits":"32 ","license":"LGPL-3","description":"Java bytecode disassembler","features":"adA__","author":"deroad"},"lanai":{"bits":"32 ","license":"GPL3","description":"Google LANAI disassembler","features":"_d___"},"lh5801":{"bits":"8 ","license":"LGPL3","description":"SHARP LH5801 disassembler","features":"_d___"},"lm32":{"bits":"32 ","license":"BSD","description":"Lattice Micro 32 ISA disassembler","features":"_d___","author":"Felix Held"},"loongarch":{"bits":"32 64","license":"LGPL3","description":"Loongson LoongArch disassembler","features":"_dA__"},"luac":{"bits":"32 ","license":"LGPL3","description":"Lua bytecode (LUAC) disassembler","features":"adA__"},"m680x":{"bits":"8 32 ","license":"BSD","description":"Motorola 680X Capstone-based disassembler","features":"_dA__"},"m68k":{"bits":"32 ","license":"BSD","description":"Motorola 68K Capstone-based disassembler","features":"_dA__"},"malbolge":{"bits":"32 ","license":"LGPL3","description":"Malbolge Ternary VM bytecode disassembler","features":"_dA__","author":"condret"},"mcore":{"bits":"32 ","license":"LGPL3","description":"Motorola MCORE disassembler","features":"_dA__"},"mcs96":{"bits":"16 ","license":"LGPL3","description":"Intel MCS-96 disassembler","features":"_dA__","author":"condret"},"milstd1750":{"bits":"8 ","license":"MIT","description":"MIL-STD 1750 ISA disassembler","features":"_dA__"},"mips":{"bits":"16 32 64","license":"BSD","description":"MIPS Capstone-based disassembler","features":"adAeI"},"msp430":{"bits":"16 ","license":"LGPL3","description":"Texas Instruments MSP430 disassembler","features":"_dA_I"},"null":{"bits":"16 32 64","license":"MIT","description":"NULL (empty) disassembler","features":"adA__","author":"pancake","version":"1.0.0"},"or1k":{"bits":"32 ","license":"LGPL3","description":"OpenRISC 1000 disassembler","features":"_dA__"},"pic":{"bits":"16 32 ","license":"LGPL3","description":"Microchip PIC disassembler","features":"_dAeI"},"ppc":{"bits":"32 64","license":"BSD","description":"PowerPC Capstone-based disassembler","features":"_dAeI","author":"pancake"},"ppc.as":{"bits":"32 64","license":"LGPL3","description":"as PPC Assembler (use RZ_PPC_AS environment)","features":"a____","author":"eagleoflqj"},"propeller":{"bits":"32 ","license":"LGPL3","description":"Parallax Propeller disassembler","features":"_dA__"},"pyc":{"bits":"8 16 ","license":"LGPL3","description":"Python bytecode (PYC) disassembler","features":"_dA__"},"riscv":{"bits":"32 64","license":"BSD","description":"RISC-V Capstone-based disassembler","features":"_dA__"},"rl78":{"bits":"32 ","license":"LGPL3","description":"Renesas RL78 disassembler","features":"adA__","author":"Bastian Engel"},"rsp":{"bits":"32 ","license":"LGPL3","description":"Nintendo N64 Reality Signal Processor disassembler","features":"_dA__"},"rx":{"bits":"32 ","license":"LGPL3","description":"Renesas RX Family disassembler","features":"_dA__","author":"Heersin"},"sh":{"bits":"32 ","license":"LGPL3","description":"Hitachi/Renesas SuperH-4/SuperH-3 disassembler","features":"adAeI","author":"DMaroo"},"snes":{"bits":"8 16 ","license":"LGPL3","description":"SuperNES CPU disassembler","features":"_dA__"},"sparc":{"bits":"32 64","license":"BSD","description":"Sun SPARC Capstone-based disassembler","features":"_dA_I"},"spc700":{"bits":"16 ","license":"LGPL3","description":"Sony SPC700 (Nintendo SuperNES sound-chip) disassembler","features":"_dA__"},"sysz":{"bits":"32 64","license":"BSD","description":"IBM SystemZ (S/390) Capstone-based disassembler","features":"_dA__"},"tms320":{"bits":"32 ","license":"LGPL3","description":"Texas Instruments TMS320 DSP family (c54x,c55x,c55x+,c64x) disassembler","features":"_dA_I"},"tricore":{"bits":"32 ","license":"BSD","description":"Siemens TriCore Capstone-based disassembler","features":"_dA_I","author":"billow"},"v810":{"bits":"32 ","license":"LGPL3","description":"NEC V810 disassembler","features":"_dAeI","author":"pancake"},"v850":{"bits":"32 ","license":"LGPL3","description":"NEC/Renesas V850 disassembler","features":"_dAeI"},"vax":{"bits":"32 ","license":"LGPL3","description":"DEC VAX-11 disassembler","features":"_dA__","author":"xvilka"},"wasm":{"bits":"32 ","license":"MIT","description":"WebAssembly disassembler","features":"adA__","author":"cgvwzq","version":"0.1.0"},"x86":{"bits":"16 32 64","license":"MIT","description":"X86/X86_64 Zydis-based disassembler","features":"_dAeI"},"x86.as":{"bits":"16 32 64","license":"LGPL3","description":"Intel X86 GNU Assembler (Use RZ_X86_AS env)","features":"a____"},"x86.nasm":{"bits":"16 32 64","license":"LGPL3","description":"X86 nasm assembler","features":"a____"},"x86.nz":{"bits":"16 32 64","license":"LGPL3","description":"x86 handmade assembler","features":"a____"},"xap":{"bits":"16 ","license":"PD","description":"Cambridge Consultants XAP4 RISC (CSR) disassembler","features":"_dA__"},"xcore":{"bits":"32 ","license":"BSD","description":"XCore Capstone-based disassembler","features":"_dA__","author":"pancake"},"xtensa":{"bits":"32 ","license":"LGPL3","description":"Tensilica Xtensa Capstone-based disassembler","features":"_dAeI","author":"billow"},"z80":{"bits":"8 ","license":"GPL3","description":"Zilog Z80 disassembler","features":"adA__","author":"condret"}] name bits features license version author description ---------------------------------------------------------------------------------------------------------------------------------- _dAeI 8 16 6502 LGPL3 6502/NES/C64/Tamagotchi/T-1000 CPU @@ -851,7 +851,7 @@ _dA__ 32 64 riscv BSD RISC-V Capstone-based adA__ 32 rl78 LGPL3 Bastian Engel Renesas RL78 disassembler _dA__ 32 rsp LGPL3 Nintendo N64 Reality Signal Processor disassembler _dA__ 32 rx LGPL3 Heersin Renesas RX Family disassembler -adAeI 32 sh LGPL3 DMaroo Hitachi/Renesas SuperH-4 disassembler +adAeI 32 sh LGPL3 DMaroo Hitachi/Renesas SuperH-4/SuperH-3 disassembler _dA__ 8 16 snes LGPL3 SuperNES CPU disassembler _dA_I 32 64 sparc BSD Sun SPARC Capstone-based disassembler _dA__ 16 spc700 LGPL3 Sony SPC700 (Nintendo SuperNES sound-chip) disassembler @@ -964,7 +964,7 @@ adAeI 16 32 64 mips BSD MIPS Capstone-based disassembler adA__ 16 32 64 null MIT NULL (empty) disassembler (by pancake) v1.0.0 a____ 32 64 ppc.as LGPL3 as PPC Assembler (use RZ_PPC_AS environment) (by eagleoflqj) adA__ 32 rl78 LGPL3 Renesas RL78 disassembler (by Bastian Engel) -adAeI 32 sh LGPL3 Hitachi/Renesas SuperH-4 disassembler (by DMaroo) +adAeI 32 sh LGPL3 Hitachi/Renesas SuperH-4/SuperH-3 disassembler (by DMaroo) adA__ 32 wasm MIT WebAssembly disassembler (by cgvwzq) v0.1.0 a____ 16 32 64 x86.as LGPL3 Intel X86 GNU Assembler (Use RZ_X86_AS env) a____ 16 32 64 x86.nasm LGPL3 X86 nasm assembler @@ -982,7 +982,7 @@ adAeI 16 32 64 mips BSD MIPS Capstone-based disassembler _dA_I 16 msp430 LGPL3 Texas Instruments MSP430 disassembler _dAeI 16 32 pic LGPL3 Microchip PIC disassembler _dAeI 32 64 ppc BSD PowerPC Capstone-based disassembler (by pancake) -adAeI 32 sh LGPL3 Hitachi/Renesas SuperH-4 disassembler (by DMaroo) +adAeI 32 sh LGPL3 Hitachi/Renesas SuperH-4/SuperH-3 disassembler (by DMaroo) _dA_I 32 64 sparc BSD Sun SPARC Capstone-based disassembler _dA_I 32 tms320 LGPL3 Texas Instruments TMS320 DSP family (c54x,c55x,c55x+,c64x) disassembler _dA_I 32 tricore BSD Siemens TriCore Capstone-based disassembler (by billow) @@ -999,7 +999,7 @@ _dAeI 16 h8300 LGPL3 Hitachi/Renesas H8/300 disassembly plugin adAeI 16 32 64 mips BSD MIPS Capstone-based disassembler _dAeI 16 32 pic LGPL3 Microchip PIC disassembler _dAeI 32 64 ppc BSD PowerPC Capstone-based disassembler (by pancake) -adAeI 32 sh LGPL3 Hitachi/Renesas SuperH-4 disassembler (by DMaroo) +adAeI 32 sh LGPL3 Hitachi/Renesas SuperH-4/SuperH-3 disassembler (by DMaroo) _dAeI 32 v810 LGPL3 NEC V810 disassembler (by pancake) _dAeI 32 v850 LGPL3 NEC/Renesas V850 disassembler _dAeI 16 32 64 x86 MIT X86/X86_64 Zydis-based disassembler @@ -1106,15 +1106,15 @@ adAeI 16 32 64 mips BSD MIPS Capstone-based disassembler adA__ 16 32 64 null MIT NULL (empty) disassembler (by pancake) v1.0.0 a____ 32 64 ppc.as LGPL3 as PPC Assembler (use RZ_PPC_AS environment) (by eagleoflqj) adA__ 32 rl78 LGPL3 Renesas RL78 disassembler (by Bastian Engel) -adAeI 32 sh LGPL3 Hitachi/Renesas SuperH-4 disassembler (by DMaroo) +adAeI 32 sh LGPL3 Hitachi/Renesas SuperH-4/SuperH-3 disassembler (by DMaroo) adA__ 32 wasm MIT WebAssembly disassembler (by cgvwzq) v0.1.0 a____ 16 32 64 x86.as LGPL3 Intel X86 GNU Assembler (Use RZ_X86_AS env) a____ 16 32 64 x86.nasm LGPL3 X86 nasm assembler a____ 16 32 64 x86.nz LGPL3 x86 handmade assembler adA__ 8 z80 GPL3 Zilog Z80 disassembler (by condret) -["6502":{"bits":"8 16 ","license":"LGPL3","description":"6502/NES/C64/Tamagotchi/T-1000 CPU","features":"_dAeI"},"8051":{"bits":"8 ","license":"PD","description":"Intel 8051 disassembler","features":"adAeI"},"arm":{"bits":"16 32 64","license":"BSD","description":"ARM Capstone-based disassembler","features":"adAeI"},"avr":{"bits":"8 16 ","license":"LGPL3","description":"Atmel AVR disassembler","features":"adAeI"},"bf":{"bits":"16 32 64","license":"LGPL3","description":"Brainfuck","features":"adA_I","author":"pancake, nibble","version":"4.0.0"},"gb":{"bits":"16 ","license":"LGPL3","description":"GameBoy(TM) (z80-like)","features":"adAeI","author":"condret"},"h8300":{"bits":"16 ","license":"LGPL3","description":"Hitachi/Renesas H8/300 disassembly plugin","features":"_dAeI"},"hexagon":{"bits":"32 ","license":"LGPL3","description":"Qualcomm Hexagon (QDSP6) V6","features":"_dA_I","author":"Rot127"},"mips":{"bits":"16 32 64","license":"BSD","description":"MIPS Capstone-based disassembler","features":"adAeI"},"msp430":{"bits":"16 ","license":"LGPL3","description":"Texas Instruments MSP430 disassembler","features":"_dA_I"},"pic":{"bits":"16 32 ","license":"LGPL3","description":"Microchip PIC disassembler","features":"_dAeI"},"ppc":{"bits":"32 64","license":"BSD","description":"PowerPC Capstone-based disassembler","features":"_dAeI","author":"pancake"},"sh":{"bits":"32 ","license":"LGPL3","description":"Hitachi/Renesas SuperH-4 disassembler","features":"adAeI","author":"DMaroo"},"sparc":{"bits":"32 64","license":"BSD","description":"Sun SPARC Capstone-based disassembler","features":"_dA_I"},"tms320":{"bits":"32 ","license":"LGPL3","description":"Texas Instruments TMS320 DSP family (c54x,c55x,c55x+,c64x) disassembler","features":"_dA_I"},"tricore":{"bits":"32 ","license":"BSD","description":"Siemens TriCore Capstone-based disassembler","features":"_dA_I","author":"billow"},"v810":{"bits":"32 ","license":"LGPL3","description":"NEC V810 disassembler","features":"_dAeI","author":"pancake"},"v850":{"bits":"32 ","license":"LGPL3","description":"NEC/Renesas V850 disassembler","features":"_dAeI"},"x86":{"bits":"16 32 64","license":"MIT","description":"X86/X86_64 Zydis-based disassembler","features":"_dAeI"},"xtensa":{"bits":"32 ","license":"LGPL3","description":"Tensilica Xtensa Capstone-based disassembler","features":"_dAeI","author":"billow"}] -name bits features license version author description ---------------------------------------------------------------------------------------------- +["6502":{"bits":"8 16 ","license":"LGPL3","description":"6502/NES/C64/Tamagotchi/T-1000 CPU","features":"_dAeI"},"8051":{"bits":"8 ","license":"PD","description":"Intel 8051 disassembler","features":"adAeI"},"arm":{"bits":"16 32 64","license":"BSD","description":"ARM Capstone-based disassembler","features":"adAeI"},"avr":{"bits":"8 16 ","license":"LGPL3","description":"Atmel AVR disassembler","features":"adAeI"},"bf":{"bits":"16 32 64","license":"LGPL3","description":"Brainfuck","features":"adA_I","author":"pancake, nibble","version":"4.0.0"},"gb":{"bits":"16 ","license":"LGPL3","description":"GameBoy(TM) (z80-like)","features":"adAeI","author":"condret"},"h8300":{"bits":"16 ","license":"LGPL3","description":"Hitachi/Renesas H8/300 disassembly plugin","features":"_dAeI"},"hexagon":{"bits":"32 ","license":"LGPL3","description":"Qualcomm Hexagon (QDSP6) V6","features":"_dA_I","author":"Rot127"},"mips":{"bits":"16 32 64","license":"BSD","description":"MIPS Capstone-based disassembler","features":"adAeI"},"msp430":{"bits":"16 ","license":"LGPL3","description":"Texas Instruments MSP430 disassembler","features":"_dA_I"},"pic":{"bits":"16 32 ","license":"LGPL3","description":"Microchip PIC disassembler","features":"_dAeI"},"ppc":{"bits":"32 64","license":"BSD","description":"PowerPC Capstone-based disassembler","features":"_dAeI","author":"pancake"},"sh":{"bits":"32 ","license":"LGPL3","description":"Hitachi/Renesas SuperH-4/SuperH-3 disassembler","features":"adAeI","author":"DMaroo"},"sparc":{"bits":"32 64","license":"BSD","description":"Sun SPARC Capstone-based disassembler","features":"_dA_I"},"tms320":{"bits":"32 ","license":"LGPL3","description":"Texas Instruments TMS320 DSP family (c54x,c55x,c55x+,c64x) disassembler","features":"_dA_I"},"tricore":{"bits":"32 ","license":"BSD","description":"Siemens TriCore Capstone-based disassembler","features":"_dA_I","author":"billow"},"v810":{"bits":"32 ","license":"LGPL3","description":"NEC V810 disassembler","features":"_dAeI","author":"pancake"},"v850":{"bits":"32 ","license":"LGPL3","description":"NEC/Renesas V850 disassembler","features":"_dAeI"},"x86":{"bits":"16 32 64","license":"MIT","description":"X86/X86_64 Zydis-based disassembler","features":"_dAeI"},"xtensa":{"bits":"32 ","license":"LGPL3","description":"Tensilica Xtensa Capstone-based disassembler","features":"_dAeI","author":"billow"}] +name bits features license version author description +----------------------------------------------------------------------------------------------- _dAeI 8 16 6502 LGPL3 6502/NES/C64/Tamagotchi/T-1000 CPU adAeI 8 8051 PD Intel 8051 disassembler adAeI 16 32 64 arm BSD ARM Capstone-based disassembler @@ -1124,7 +1124,7 @@ _dAeI 16 h8300 LGPL3 Hitachi/Renesas H8/300 disassemb adAeI 16 32 64 mips BSD MIPS Capstone-based disassembler _dAeI 16 32 pic LGPL3 Microchip PIC disassembler _dAeI 32 64 ppc BSD pancake PowerPC Capstone-based disassembler -adAeI 32 sh LGPL3 DMaroo Hitachi/Renesas SuperH-4 disassembler +adAeI 32 sh LGPL3 DMaroo Hitachi/Renesas SuperH-4/SuperH-3 disassembler _dAeI 32 v810 LGPL3 pancake NEC V810 disassembler _dAeI 32 v850 LGPL3 NEC/Renesas V850 disassembler _dAeI 16 32 64 x86 MIT X86/X86_64 Zydis-based disassembler @@ -1150,7 +1150,7 @@ NAME=Print the asm/analysis plugins in JSON FILE== CMDS=Laj EXPECT=<