mirror of
https://github.com/rizinorg/rizin
synced 2026-08-22 20:26:16 -04:00
Disassembler arch for RX microcontroller (MCU) family (#4198)
* Basic framework of rx implemented * Add match and parse flow * Add part of description for RxV1 instruction set * Add datasheet for rxv1 * Implement stringify op for rx * Add missing TST instruction in datasheet * Test to div instruction and fix bugs * Test known rxv1 instruction set * Fix bugs in rx disasm plugin and add SPDX * Add rz_analysis for renesas rx * Fix rz_analysis bug for renesas rx * Add rz_asm test and fix bug in datasheet * Add analysis test and fix bugs for renesas rx
This commit is contained in:
parent
f98ab29273
commit
5c79c42a56
18 changed files with 2533 additions and 1 deletions
9
librz/analysis/d/cc-rx-32.sdb.txt
Normal file
9
librz/analysis/d/cc-rx-32.sdb.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
default.cc=rx
|
||||
|
||||
rx=cc
|
||||
cc.rx.arg0=r1
|
||||
cc.rx.arg1=r2
|
||||
cc.rx.arg2=r3
|
||||
cc.rx.arg3=r4
|
||||
cc.rx.argn=stack_rev
|
||||
cc.rx.ret=r1
|
||||
|
|
@ -30,6 +30,7 @@ analysis_plugins_list = [
|
|||
'propeller',
|
||||
'pyc',
|
||||
'rl78',
|
||||
'rx',
|
||||
'rsp',
|
||||
'snes',
|
||||
'sparc_cs',
|
||||
|
|
@ -142,6 +143,7 @@ rz_analysis_sources = [
|
|||
'p/analysis_pyc.c',
|
||||
'p/analysis_rl78.c',
|
||||
'p/analysis_rsp.c',
|
||||
'p/analysis_rx.c',
|
||||
'p/analysis_snes.c',
|
||||
'p/analysis_sparc_cs.c',
|
||||
'p/analysis_spc700.c',
|
||||
|
|
|
|||
256
librz/analysis/p/analysis_rx.c
Normal file
256
librz/analysis/p/analysis_rx.c
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
// SPDX-FileCopyrightText: 2024 heersin <teablearcher@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <asm/arch/rx/rx.h>
|
||||
#include <rz_types.h>
|
||||
#include <rz_util.h>
|
||||
#include <rz_lib.h>
|
||||
#include <rz_asm.h>
|
||||
#include <rz_analysis.h>
|
||||
|
||||
static void calculate_jmp_addr(RxInst *inst, RzAnalysisOp *op) {
|
||||
if (inst->v0.kind == RX_OPERAND_COND) {
|
||||
ut8 pcdsp_l = inst->v0.v.cond.pc_dsp_len;
|
||||
ut32 pcdsp_val = inst->v0.v.cond.pc_dsp_val;
|
||||
ut64 addr_inc = pcdsp_val;
|
||||
if (pcdsp_l >= 8) {
|
||||
// as SIMM, use signed extend
|
||||
ut8 shift = pcdsp_l - 1;
|
||||
if ((1 << shift) & pcdsp_val) {
|
||||
// as negative
|
||||
ut32 mask = 0xffffffff << shift;
|
||||
addr_inc = abs((st32)(pcdsp_val | mask));
|
||||
op->jump = op->addr - addr_inc;
|
||||
return;
|
||||
}
|
||||
}
|
||||
op->jump = op->addr + addr_inc;
|
||||
}
|
||||
op->fail = op->addr + op->size;
|
||||
}
|
||||
|
||||
static int analysis_rx_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr,
|
||||
const ut8 *buf, int len, RzAnalysisOpMask mask) {
|
||||
op->addr = addr;
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_ILL;
|
||||
|
||||
RxInst inst = { 0 };
|
||||
st32 bytes_read = 0;
|
||||
if (!rx_dis(&inst, &bytes_read, buf, len)) {
|
||||
return bytes_read;
|
||||
} else {
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_UNK;
|
||||
}
|
||||
|
||||
op->size = bytes_read;
|
||||
switch (inst.op) {
|
||||
// jump related instructions
|
||||
case RX_OP_RTS:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_RET;
|
||||
break;
|
||||
case RX_OP_BSR_A:
|
||||
case RX_OP_BSR_L:
|
||||
case RX_OP_BSR_W:
|
||||
case RX_OP_JSR:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_CALL;
|
||||
calculate_jmp_addr(&inst, op);
|
||||
break;
|
||||
case RX_OP_BCND_W:
|
||||
case RX_OP_BCND_B:
|
||||
case RX_OP_BCND_S:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_CJMP;
|
||||
calculate_jmp_addr(&inst, op);
|
||||
break;
|
||||
case RX_OP_BRA_L:
|
||||
case RX_OP_BRA_A:
|
||||
case RX_OP_BRA_B:
|
||||
case RX_OP_BRA_S:
|
||||
case RX_OP_BRA_W:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_JMP;
|
||||
calculate_jmp_addr(&inst, op);
|
||||
break;
|
||||
case RX_OP_JMP:
|
||||
// use register
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_JMP;
|
||||
break;
|
||||
// normal instruction
|
||||
case RX_OP_ADD:
|
||||
case RX_OP_ADD_UB:
|
||||
case RX_OP_ADC:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_ADD;
|
||||
break;
|
||||
case RX_OP_SUB:
|
||||
case RX_OP_SUB_UB:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_SUB;
|
||||
break;
|
||||
case RX_OP_DIV:
|
||||
case RX_OP_DIV_UB:
|
||||
case RX_OP_DIVU:
|
||||
case RX_OP_DIVU_UB:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_DIV;
|
||||
break;
|
||||
case RX_OP_MUL:
|
||||
case RX_OP_MULLO:
|
||||
case RX_OP_EMUL:
|
||||
case RX_OP_EMULU:
|
||||
case RX_OP_EMULU_UB:
|
||||
case RX_OP_EMUL_UB:
|
||||
case RX_OP_MUL_UB:
|
||||
case RX_OP_MULHI:
|
||||
case RX_OP_MACHI:
|
||||
case RX_OP_MACLO:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_MUL;
|
||||
break;
|
||||
case RX_OP_AND:
|
||||
case RX_OP_AND_UB:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_AND;
|
||||
break;
|
||||
case RX_OP_OR:
|
||||
case RX_OP_OR_UB:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_OR;
|
||||
break;
|
||||
case RX_OP_NOT:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_NOT;
|
||||
break;
|
||||
case RX_OP_NOP:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_NOP;
|
||||
break;
|
||||
case RX_OP_CMP:
|
||||
case RX_OP_CMP_UB:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_CMP;
|
||||
break;
|
||||
case RX_OP_PUSH:
|
||||
case RX_OP_PUSHM:
|
||||
case RX_OP_PUSHC:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_PUSH;
|
||||
break;
|
||||
case RX_OP_POP:
|
||||
case RX_OP_POPM:
|
||||
case RX_OP_POPC:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_POP;
|
||||
break;
|
||||
case RX_OP_ROTL:
|
||||
case RX_OP_ROLC:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_ROL;
|
||||
break;
|
||||
case RX_OP_ROTR:
|
||||
case RX_OP_RORC:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_ROR;
|
||||
break;
|
||||
case RX_OP_SHAR:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_SAR;
|
||||
break;
|
||||
case RX_OP_SHLR:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_SHR;
|
||||
break;
|
||||
case RX_OP_SHLL:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_SHL;
|
||||
break;
|
||||
case RX_OP_XCHG_UB:
|
||||
case RX_OP_XCHG:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_XCHG;
|
||||
break;
|
||||
case RX_OP_XOR:
|
||||
case RX_OP_XOR_UB:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_XOR;
|
||||
break;
|
||||
case RX_OP_ITOF:
|
||||
case RX_OP_FTOI:
|
||||
case RX_OP_ITOF_UB:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_CAST;
|
||||
break;
|
||||
case RX_OP_INT:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_SWI;
|
||||
break;
|
||||
case RX_OP_MOV:
|
||||
case RX_OP_MOVU:
|
||||
case RX_OP_MVTIPL:
|
||||
case RX_OP_MVTC:
|
||||
case RX_OP_MVTACLO:
|
||||
case RX_OP_MVTACHI:
|
||||
case RX_OP_MVFACMI:
|
||||
case RX_OP_MVFACHI:
|
||||
case RX_OP_MVFC:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return op->size;
|
||||
}
|
||||
|
||||
static char *analysis_rx_reg_profile(RzAnalysis *analysis) {
|
||||
// check librz/reg/profile for register profile description
|
||||
const char *p =
|
||||
"=PC pc\n"
|
||||
"=SP r0\n"
|
||||
"=ZF zf\n"
|
||||
"=CF cf\n"
|
||||
"=SF sf\n"
|
||||
"=OF of\n"
|
||||
// ABI: https://www.renesas.com/us/en/document/mat/cc-rx-compiler-users-manual
|
||||
"=R0 r1\n"
|
||||
"=A0 r1\n"
|
||||
"=A1 r2\n"
|
||||
"=A2 r3\n"
|
||||
"=A3 r4\n"
|
||||
// general
|
||||
"gpr r0 .32 0 0\n"
|
||||
"gpr r1 .32 4 0\n"
|
||||
"gpr r2 .32 8 0\n"
|
||||
"gpr r3 .32 12 0\n"
|
||||
"gpr r4 .32 16 0\n"
|
||||
"gpr r5 .32 20 0\n"
|
||||
"gpr r6 .32 24 0\n"
|
||||
"gpr r7 .32 28 0\n"
|
||||
"gpr r8 .32 32 0\n"
|
||||
"gpr r9 .32 36 0\n"
|
||||
"gpr r10 .32 40 0\n"
|
||||
"gpr r11 .32 44 0\n"
|
||||
"gpr r12 .32 48 0\n"
|
||||
"gpr r13 .32 52 0\n"
|
||||
"gpr r14 .32 56 0\n"
|
||||
"gpr r15 .32 60 0\n"
|
||||
// control register
|
||||
"gpr isp .32 64 0\n"
|
||||
"gpr usp .32 68 0\n"
|
||||
"gpr intb .32 72 0\n"
|
||||
"gpr pc .32 76 0\n"
|
||||
|
||||
// psw
|
||||
"gpr psw .32 80 0\n"
|
||||
"flg ipl .4 .644 0\n"
|
||||
"flg pm .1 .651 0\n"
|
||||
"flg u .1 .654 0\n"
|
||||
"flg i .1 .655 0\n"
|
||||
"flg of .1 .668 0\n"
|
||||
"flg sf .1 .669 0\n"
|
||||
"flg zf .1 .670 0\n"
|
||||
"flg cf .1 .671 0\n"
|
||||
|
||||
"gpr bpc .32 84 0\n"
|
||||
"gpr bpsw .32 88 0\n"
|
||||
"gpr fintv .32 92 0\n"
|
||||
|
||||
// fpsw, contains multiple flags but ignore now
|
||||
"gpr fpsw .32 96 0\n"
|
||||
"flg fsf .1 .768 0\n"
|
||||
"flg fxf .1 .769 0\n"
|
||||
"flg fuf .1 .770 0\n"
|
||||
"flg fzf .1 .771 0\n"
|
||||
"flg fof .1 .772 0\n"
|
||||
"flg fvf .1 .773 0\n"
|
||||
"flg rmode .2 .798 0\n";
|
||||
return strdup(p);
|
||||
}
|
||||
|
||||
RzAnalysisPlugin rz_analysis_plugin_rx = {
|
||||
.name = "rx",
|
||||
.arch = "rx",
|
||||
.desc = "Renesas RX Family analysis",
|
||||
.license = "LGPL3",
|
||||
.bits = 32,
|
||||
.op = &analysis_rx_op,
|
||||
.get_reg_profile = &analysis_rx_reg_profile,
|
||||
};
|
||||
166
librz/asm/arch/rx/rx.c
Normal file
166
librz/asm/arch/rx/rx.c
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
// SPDX-FileCopyrightText: 2024 heersin <teablearcher@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include "rx.h"
|
||||
#include "rx_str.inc"
|
||||
|
||||
static ut64 prefetch_bytes(const ut8 *buf, size_t buf_len) {
|
||||
ut64 result = 0;
|
||||
size_t i;
|
||||
size_t end = buf_len < 8 ? buf_len : 8; // Determine end based on buf_len
|
||||
for (i = 0; i < end; i++) {
|
||||
result |= ((ut64)buf[i]) << ((7 - i) * 8); // Shift and combine
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool rx_operand_stringify(RxInst *inst, RxOperand *opr, RZ_OUT RzStrBuf *buf) {
|
||||
// construct string output to RzStrBuf
|
||||
if (opr->kind == RX_OPERAND_NULL) {
|
||||
// ignore
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opr->kind == RX_OPERAND_COND) {
|
||||
if (opr->v.cond.pc_dsp_len) {
|
||||
rz_strbuf_appendf(buf, " #0x%" PFMT32x, opr->v.cond.pc_dsp_val);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (opr->kind == RX_OPERAND_FLAG) {
|
||||
rz_strf(buf->buf, "%s", RxNameFlag(opr->v.flag));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (opr->kind == RX_OPERAND_IMM) {
|
||||
rz_strf(buf->buf, "#0x%" PFMT32x,
|
||||
opr->v.imm.imm);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (opr->kind == RX_OPERAND_REG) {
|
||||
if (opr->v.reg.dsp_width) {
|
||||
// dsp value
|
||||
rz_strbuf_appendf(buf, "0x%" PFMT32x,
|
||||
opr->v.reg.dsp_val);
|
||||
}
|
||||
|
||||
if (opr->v.reg.as_indirect) {
|
||||
rz_strbuf_append(buf, "[");
|
||||
}
|
||||
if (opr->v.reg.fix_mode == RX_FIXOP_PRE_DEC) {
|
||||
rz_strbuf_append(buf, "-");
|
||||
}
|
||||
|
||||
if (opr->v.reg.as_base) {
|
||||
rz_strbuf_appendf(buf, "%s,%s",
|
||||
RxNameReg(opr->v.reg.ri),
|
||||
RxNameReg(opr->v.reg.reg));
|
||||
} else {
|
||||
rz_strbuf_appendf(buf, "%s", RxNameReg(opr->v.reg.reg));
|
||||
}
|
||||
|
||||
if (opr->v.reg.fix_mode == RX_FIXOP_POST_INC) {
|
||||
rz_strbuf_append(buf, "+");
|
||||
}
|
||||
if (opr->v.reg.as_indirect) {
|
||||
rz_strbuf_append(buf, "]");
|
||||
}
|
||||
|
||||
if (opr->v.reg.memex != RX_EXT_NON) {
|
||||
rz_strbuf_appendf(buf, ".%s", RxNameExt(opr->v.reg.memex));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rx_inst_stringify(RxInst *inst, RzStrBuf *buf) {
|
||||
// construct string output to RzStrBuf
|
||||
if (inst->op == RX_OP_INVALID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RzStrBuf opr0_buf, opr1_buf, opr2_buf;
|
||||
rz_strbuf_init(&opr0_buf);
|
||||
rz_strbuf_init(&opr1_buf);
|
||||
rz_strbuf_init(&opr2_buf);
|
||||
|
||||
bool has_opr0 = inst->v0.kind != RX_OPERAND_NULL &&
|
||||
rx_operand_stringify(inst, &inst->v0, &opr0_buf);
|
||||
bool has_opr1 = inst->v1.kind != RX_OPERAND_NULL &&
|
||||
rx_operand_stringify(inst, &inst->v1, &opr1_buf);
|
||||
bool has_opr2 = inst->v2.kind != RX_OPERAND_NULL &&
|
||||
rx_operand_stringify(inst, &inst->v2, &opr2_buf);
|
||||
|
||||
if (inst->op == RX_OP_BCND_W || inst->op == RX_OP_BCND_B || inst->op == RX_OP_BCND_S ||
|
||||
inst->op == RX_OP_BMCND || inst->op == RX_OP_SCCOND) {
|
||||
if (has_opr0 && inst->v0.kind == RX_OPERAND_COND) {
|
||||
// build b[cnd]
|
||||
RzStrBuf cond_buf;
|
||||
rz_strbuf_init(&cond_buf);
|
||||
rz_strf(cond_buf.buf, "%s", RxNameCond(inst->v0.v.cond.cond));
|
||||
rz_strbuf_appendf(buf, RxNameOp(inst->op), cond_buf.buf);
|
||||
|
||||
if (!inst->v0.v.cond.pc_dsp_len) {
|
||||
has_opr0 = false;
|
||||
}
|
||||
} else {
|
||||
rz_strbuf_appendf(buf, "%s[invalid]",
|
||||
RxNameOp(inst->op));
|
||||
}
|
||||
} else {
|
||||
rz_strbuf_appendf(buf, "%s", RxNameOp(inst->op));
|
||||
}
|
||||
|
||||
if (inst->sz_mark != RX_EXT_NON) {
|
||||
rz_strbuf_appendf(buf, ".%s ", RxNameExt(inst->sz_mark));
|
||||
} else {
|
||||
rz_strbuf_append(buf, " ");
|
||||
}
|
||||
|
||||
if (has_opr0) {
|
||||
rz_strbuf_appendf(buf, "%s, ", opr0_buf.buf);
|
||||
}
|
||||
if (has_opr1) {
|
||||
rz_strbuf_appendf(buf, "%s, ", opr1_buf.buf);
|
||||
}
|
||||
if (has_opr2) {
|
||||
rz_strbuf_appendf(buf, "%s", opr2_buf.buf);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Parse binary data to RxInst according to RxDesc
|
||||
* \details RX instruction can be 1-8 Bytes, consisted by 2 main parts: [(code) (code data)],
|
||||
* in rizin rx plugin, we defined an `RX instruction description` as an array of tokens, with RxEnd as the end mark.
|
||||
* The parser will fetch 8Bytes, and try to match a predefined instruction description to get a valid interpretation.
|
||||
* \param inst RxInst to be filled
|
||||
* \param bytes_read count bytes read from buf
|
||||
* \param buf rz raw binary data, provided by rizin
|
||||
* \param buf_len length of buf, provided by rizin
|
||||
* \return true if parse success, false otherwise
|
||||
*/
|
||||
RZ_API bool rx_dis(RZ_NONNULL RxInst RZ_OUT *inst, RZ_NONNULL st32 RZ_OUT *bytes_read, RZ_NONNULL const ut8 *buf, size_t buf_len) {
|
||||
rz_return_val_if_fail(inst && bytes_read && buf, false);
|
||||
// rx instruction length vary from 1 to 8 Bytes
|
||||
ut64 prefetched_bytes = prefetch_bytes(buf, buf_len);
|
||||
RxInst current_inst = { 0 };
|
||||
st32 bytes_read_real = 0;
|
||||
for (ut32 desc_id = 0; desc_id < RX_DESC_SIZE; ++desc_id) {
|
||||
memset(¤t_inst, 0, sizeof(RxInst));
|
||||
bool is_valid = rx_try_match_and_parse(¤t_inst, &rx_inst_descs[desc_id],
|
||||
&bytes_read_real, prefetched_bytes);
|
||||
if (is_valid) {
|
||||
*inst = current_inst;
|
||||
*bytes_read = bytes_read_real;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// nothing matched known instruction
|
||||
return false;
|
||||
}
|
||||
13
librz/asm/arch/rx/rx.h
Normal file
13
librz/asm/arch/rx/rx.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// SPDX-FileCopyrightText: 2024 heersin <teablearcher@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#ifndef RZ_ARCH_RX_H
|
||||
#define RZ_ARCH_RX_H
|
||||
|
||||
#include <rz_util.h>
|
||||
#include "rx_inst.h"
|
||||
|
||||
RZ_API bool rx_dis(RZ_NONNULL RxInst RZ_OUT *inst, RZ_NONNULL st32 RZ_OUT *bytes_read, RZ_NONNULL const ut8 *buf, size_t buf_len);
|
||||
bool rx_inst_stringify(RxInst *inst, RzStrBuf *buf);
|
||||
|
||||
#endif
|
||||
605
librz/asm/arch/rx/rx_inst.c
Normal file
605
librz/asm/arch/rx/rx_inst.c
Normal file
|
|
@ -0,0 +1,605 @@
|
|||
// SPDX-FileCopyrightText: 2024 heersin <teablearcher@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include "rx_inst.h"
|
||||
|
||||
#define AssignOpVar(vid, field, expr) \
|
||||
{ \
|
||||
switch (vid) { \
|
||||
case 0: inst->v0.field = (expr); break; \
|
||||
case 1: inst->v1.field = (expr); break; \
|
||||
default: inst->v2.field = (expr); break; \
|
||||
} \
|
||||
}
|
||||
|
||||
RxOperandFlag rx_cb_map[16] = {
|
||||
RX_FLAG_C,
|
||||
RX_FLAG_Z,
|
||||
RX_FLAG_S,
|
||||
RX_FLAG_O,
|
||||
RX_FLAG_RESERVED,
|
||||
RX_FLAG_RESERVED,
|
||||
RX_FLAG_RESERVED,
|
||||
RX_FLAG_RESERVED,
|
||||
RX_FLAG_I,
|
||||
RX_FLAG_U,
|
||||
RX_FLAG_RESERVED,
|
||||
RX_FLAG_RESERVED,
|
||||
RX_FLAG_RESERVED,
|
||||
RX_FLAG_RESERVED,
|
||||
RX_FLAG_RESERVED,
|
||||
RX_FLAG_RESERVED,
|
||||
};
|
||||
|
||||
RxReg rx_cr_map[32] = {
|
||||
RX_REG_PSW,
|
||||
RX_REG_PC,
|
||||
RX_REG_USP,
|
||||
RX_REG_FPSW,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_BPSW,
|
||||
RX_REG_BPC,
|
||||
RX_REG_ISP,
|
||||
RX_REG_FINTV,
|
||||
RX_REG_INTB,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
RX_REG_RESERVED,
|
||||
};
|
||||
|
||||
static inline ut64 getbits(ut64 bytes, ut8 s, ut8 l) {
|
||||
return (bytes >> (64 - s - l)) & ((1ULL << l) - 1);
|
||||
}
|
||||
|
||||
bool match_code(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.inst.tk_len;
|
||||
ut64 bits = getbits(bytes, s, l);
|
||||
if (bits == token->tk.inst.detail) {
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
RxOpExtMark bits2mark(ut64 bits) {
|
||||
// 00 - B, 01 - W, 10 - L, 11 - UW
|
||||
return RX_EXT_B + bits;
|
||||
}
|
||||
|
||||
bool match_mi(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.mi.tk_len;
|
||||
RxOpCode op = inst->op;
|
||||
ut64 bits = getbits(bytes, s, l);
|
||||
if (op == RX_OP_ADC) {
|
||||
if (bits != 2) {
|
||||
// only 10 - L allowed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inst->v0.v.reg.memex = bits2mark(bits);
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_ld(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.ld.tk_len;
|
||||
ut64 ld_bits = getbits(bytes, s, l);
|
||||
ut8 dsp_len;
|
||||
|
||||
// 11 - Rs
|
||||
switch (ld_bits) {
|
||||
case 3:
|
||||
*bits_read += l;
|
||||
return true;
|
||||
case 0:
|
||||
dsp_len = 0;
|
||||
break;
|
||||
case 1:
|
||||
dsp_len = 8;
|
||||
break;
|
||||
case 2:
|
||||
dsp_len = 16;
|
||||
break;
|
||||
default:
|
||||
rz_warn_if_reached();
|
||||
return 0;
|
||||
}
|
||||
|
||||
AssignOpVar(token->tk.ld.vid, v.reg.as_indirect, true);
|
||||
AssignOpVar(token->tk.ld.vid, v.reg.dsp_width, dsp_len);
|
||||
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_ld_part(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.ld_part.tk_len;
|
||||
ut8 ldr = getbits(bytes, s, l);
|
||||
ut8 dsp_width;
|
||||
// 00 - None, 01 - dsp:8, 10 - dsp:16, 11 - invalid
|
||||
switch (ldr) {
|
||||
case 3:
|
||||
// invalid 11
|
||||
return false;
|
||||
case 0:
|
||||
dsp_width = 0;
|
||||
break;
|
||||
case 1:
|
||||
dsp_width = 8;
|
||||
break;
|
||||
case 2:
|
||||
dsp_width = 16;
|
||||
break;
|
||||
default:
|
||||
rz_warn_if_reached();
|
||||
return false;
|
||||
}
|
||||
|
||||
AssignOpVar(token->tk.ld_part.vid, v.reg.dsp_width, dsp_width);
|
||||
AssignOpVar(token->tk.ld_part.vid, v.reg.as_indirect, true);
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
ut8 bits2immlen(ut64 bits) {
|
||||
// 01 - SIMM: 8, 10 - SIMM: 16
|
||||
// 11 - SIMM: 24, 00 - IMM: 32
|
||||
switch (bits) {
|
||||
case 0:
|
||||
return 32;
|
||||
case 1:
|
||||
return 8;
|
||||
case 2:
|
||||
return 16;
|
||||
case 3:
|
||||
return 24;
|
||||
default:
|
||||
rz_warn_if_reached();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool match_li(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.li.tk_len;
|
||||
AssignOpVar(token->tk.li.vid, v.imm.imm_width, bits2immlen(getbits(bytes, s, l)));
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_reg(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.reg.tk_len;
|
||||
ut8 operand_id = token->tk.reg.vid;
|
||||
AssignOpVar(operand_id, v.reg.reg, RX_REG_R0 + getbits(bytes, s, l));
|
||||
AssignOpVar(operand_id, kind, RX_OPERAND_REG);
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_reg_patched(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.reg.tk_len;
|
||||
ut8 operand_id = token->tk.reg.vid;
|
||||
ut64 reg_bits = getbits(bytes, s, l);
|
||||
RxOpCode op = inst->op;
|
||||
RxReg reg = RX_REG_R0 + reg_bits;
|
||||
|
||||
if (op == RX_OP_PUSHM || op == RX_OP_POPM) {
|
||||
if (operand_id == 0) {
|
||||
// for opr0, R1 -> R14
|
||||
if (reg < RX_REG_R1 || reg > RX_REG_R14) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (operand_id == 1) {
|
||||
// for opr1
|
||||
if (reg < RX_REG_R2 || reg > RX_REG_R15) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (op == RX_OP_EMUL || op == RX_OP_EMULU) {
|
||||
if (operand_id == 1) {
|
||||
// dest reg limit: R0 -> R14
|
||||
if (reg > RX_REG_R14) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (op == RX_OP_RTSD) {
|
||||
if (reg < RX_REG_R1 || reg > RX_REG_R15) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
AssignOpVar(operand_id, v.reg.reg, RX_REG_R0 + reg_bits);
|
||||
AssignOpVar(operand_id, kind, RX_OPERAND_REG);
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_ri(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.reg.tk_len;
|
||||
ut8 operand_id = token->tk.reg.vid;
|
||||
ut64 reg_bits = getbits(bytes, s, l);
|
||||
AssignOpVar(operand_id, v.reg.as_indirect, true);
|
||||
AssignOpVar(operand_id, v.reg.as_base, true);
|
||||
AssignOpVar(operand_id, v.reg.ri, RX_REG_R0 + reg_bits);
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_cr(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.cr.tk_len;
|
||||
ut8 operand_id = token->tk.cr.vid;
|
||||
AssignOpVar(operand_id, v.reg.reg, rx_cr_map[(getbits(bytes, s, l))]);
|
||||
AssignOpVar(operand_id, kind, RX_OPERAND_REG);
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_imm(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.imm.tk_len;
|
||||
ut8 operand_id = token->tk.imm.vid;
|
||||
AssignOpVar(operand_id, v.imm.imm, getbits(bytes, s, l));
|
||||
AssignOpVar(operand_id, v.imm.imm_width, l);
|
||||
AssignOpVar(operand_id, kind, RX_OPERAND_IMM);
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_cond(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.cond.tk_len;
|
||||
ut8 operand_id = token->tk.cond.vid;
|
||||
ut64 cond_bits = getbits(bytes, s, l);
|
||||
RxOpCondMark cond_mark;
|
||||
if (inst->op == RX_OP_BMCND) {
|
||||
if (cond_bits >= 0xe) {
|
||||
// reserved val for cond
|
||||
return false;
|
||||
}
|
||||
cond_mark = RX_COND_EQ + cond_bits;
|
||||
} else {
|
||||
cond_mark = RX_COND_EQ + cond_bits;
|
||||
}
|
||||
AssignOpVar(operand_id, v.cond.cond, cond_mark);
|
||||
AssignOpVar(operand_id, kind, RX_OPERAND_COND);
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_jump(RZ_OUT RxInst *inst, RxToken *token) {
|
||||
// judge as a unconditional jump
|
||||
inst->v0.kind = RX_OPERAND_COND;
|
||||
inst->v0.v.cond.cond = RX_COND_JUMP;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_cb(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.cb.tk_len;
|
||||
ut8 control_bits = getbits(bytes, s, l);
|
||||
|
||||
inst->v0.v.flag = rx_cb_map[control_bits];
|
||||
inst->v0.kind = RX_OPERAND_FLAG;
|
||||
|
||||
if (inst->v0.v.flag == RX_FLAG_RESERVED) {
|
||||
// TODO: should we use strict policy ?
|
||||
return false;
|
||||
}
|
||||
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_dsp(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
// DSP mark should follow a jump
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.dsp.tk_len;
|
||||
ut8 dsp_bits = getbits(bytes, s, l);
|
||||
|
||||
// for condition dsp
|
||||
if (dsp_bits > 10 || dsp_bits < 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inst->v0.v.cond.pc_dsp_len = 3;
|
||||
inst->v0.v.cond.pc_dsp_val = dsp_bits;
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_dsp_split(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.dsp_sp.tk_len;
|
||||
ut8 interval = token->tk.dsp_sp.interval;
|
||||
ut8 ll = token->tk.dsp_sp.tk_len_more;
|
||||
|
||||
// | dsp_A | interval_bits | dsp_B |
|
||||
// dsp_bits = concat(dsp_A, dsp_B)
|
||||
ut8 dsp_bits = (getbits(bytes, s, l) << ll) | getbits(bytes, s + l + interval, ll);
|
||||
ut8 operand_id = token->tk.dsp_sp.vid;
|
||||
AssignOpVar(operand_id, v.reg.dsp_val, dsp_bits);
|
||||
AssignOpVar(operand_id, v.reg.dsp_width, l + ll);
|
||||
AssignOpVar(operand_id, v.reg.as_indirect, true);
|
||||
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_ignore(RxToken *token, RZ_OUT ut8 *bits_read) {
|
||||
ut8 l = token->tk.reserved.tk_len;
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_sz(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.sz.tk_len;
|
||||
ut8 sz = getbits(bytes, s, l);
|
||||
if (sz == 3) {
|
||||
// invalid 11
|
||||
return false;
|
||||
}
|
||||
inst->sz_mark = RX_EXT_B + sz;
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool match_ad(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 l = token->tk.ad.tk_len;
|
||||
ut8 addr_bits = getbits(bytes, s, l);
|
||||
|
||||
if (inst->op == RX_OP_MOVU) {
|
||||
// 10 [Rs+] and 11 [-Rs] is allowed
|
||||
if (addr_bits < 2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 00 Rs, [Rd+], 01: Rs, [-Rd], inc/dec on Rd
|
||||
// 10 [Rs+], Rd, 11: [-Rs], Rd, inc/dec on Rs
|
||||
switch (addr_bits) {
|
||||
case 0:
|
||||
inst->v1.v.reg.as_indirect = true;
|
||||
inst->v1.v.reg.fix_mode = RX_FIXOP_POST_INC;
|
||||
break;
|
||||
case 1:
|
||||
inst->v1.v.reg.as_indirect = true;
|
||||
inst->v1.v.reg.fix_mode = RX_FIXOP_PRE_DEC;
|
||||
break;
|
||||
case 2:
|
||||
inst->v0.v.reg.as_indirect = true;
|
||||
inst->v0.v.reg.fix_mode = RX_FIXOP_POST_INC;
|
||||
break;
|
||||
case 3:
|
||||
inst->v0.v.reg.as_indirect = true;
|
||||
inst->v0.v.reg.fix_mode = RX_FIXOP_PRE_DEC;
|
||||
break;
|
||||
default:
|
||||
rz_warn_if_reached();
|
||||
return false;
|
||||
}
|
||||
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
static ut32 pack_big(ut32 raw_data, ut8 len_in_bytes) {
|
||||
ut32 result = 0;
|
||||
for (int i = 0; i < len_in_bytes; i++) {
|
||||
ut32 byte = (raw_data >> (8 * i)) & 0xFF;
|
||||
result = (result << 8) | byte;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool pack_data(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
ut8 s = *bits_read;
|
||||
ut8 vid = token->tk.data.vid;
|
||||
ut8 l;
|
||||
ut32 follow_data;
|
||||
|
||||
RxOperand *opr = vid == 0 ? &(inst->v0) : vid == 1 ? &(inst->v1)
|
||||
: &(inst->v2);
|
||||
|
||||
ut8 data_type = token->tk.data.data_type;
|
||||
if (data_type == 2) {
|
||||
// pack dsp
|
||||
l = opr->v.reg.dsp_width;
|
||||
follow_data = getbits(bytes, s, l);
|
||||
opr->v.reg.dsp_val = pack_big(follow_data, l / 8);
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (data_type == 1) {
|
||||
// pack imm
|
||||
if (token->tk.data.fixed_len) {
|
||||
l = token->tk.data.fixed_len;
|
||||
opr->v.imm.imm_width = l;
|
||||
} else {
|
||||
l = opr->v.imm.imm_width;
|
||||
}
|
||||
opr->kind = RX_OPERAND_IMM;
|
||||
follow_data = getbits(bytes, s, l);
|
||||
opr->v.imm.imm = pack_big(follow_data, l / 8);
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (data_type == 3) {
|
||||
// pack pcdsp
|
||||
if (token->tk.data.fixed_len) {
|
||||
l = token->tk.data.fixed_len;
|
||||
opr->v.cond.pc_dsp_len = l;
|
||||
} else {
|
||||
l = opr->v.cond.pc_dsp_len;
|
||||
}
|
||||
follow_data = getbits(bytes, s, l);
|
||||
opr->v.cond.pc_dsp_val = pack_big(follow_data, l / 8);
|
||||
*bits_read += l;
|
||||
return true;
|
||||
}
|
||||
|
||||
rz_warn_if_reached();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool check_some(RZ_OUT RxInst *inst, RxToken *token, RZ_OUT ut8 *bits_read, ut64 bytes) {
|
||||
// a token hook for parser loop
|
||||
if (inst->op == RX_OP_MOV) {
|
||||
// check order of src and dest
|
||||
// for ad[1:0], if 00 or 01, mov dst, src
|
||||
// for ad[0:1], if 10 or 11, mov src, dst
|
||||
if (inst->v1.kind == RX_OPERAND_REG) {
|
||||
// parse RegBist[3:0] as dest(V1)
|
||||
if (inst->v0.v.reg.fix_mode != RX_FIXOP_NON) {
|
||||
// but set src fixed, parse failed
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (inst->v0.kind == RX_OPERAND_REG) {
|
||||
if (inst->v1.v.reg.fix_mode != RX_FIXOP_NON) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Parse bytes according to the given RX instruction description to see if it matches
|
||||
* \param inst an empty RxInst to be filled
|
||||
* \param desc an RxDesc to be matched
|
||||
* \param bytes_read bytes read
|
||||
* \param bytes prefetched bytes
|
||||
* \return true if parse success, false otherwise
|
||||
*/
|
||||
bool rx_try_match_and_parse(RZ_OUT RxInst *inst, RxDesc *desc, st32 RZ_OUT *bytes_read, ut64 bytes) {
|
||||
ut8 read_bits = 0;
|
||||
bool is_valid = true;
|
||||
inst->op = desc->op;
|
||||
for (int tki = 0; tki < MAX_TOKEN; ++tki) {
|
||||
if (!is_valid) {
|
||||
return false;
|
||||
}
|
||||
RxTokenType tk_type = desc->tks[tki].type;
|
||||
RxToken *token = &(desc->tks[tki]);
|
||||
|
||||
if (tk_type == RX_TOKEN_NON) {
|
||||
// break the loop
|
||||
break;
|
||||
}
|
||||
|
||||
switch (tk_type) {
|
||||
case RX_TOKEN_INST:
|
||||
is_valid = match_code(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_LD:
|
||||
is_valid = match_ld(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_LD_PART:
|
||||
is_valid = match_ld_part(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_LI:
|
||||
is_valid = match_li(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_MI:
|
||||
is_valid = match_mi(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_DSP:
|
||||
is_valid = match_dsp(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_DSP_SPLIT:
|
||||
is_valid = match_dsp_split(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_SZ:
|
||||
is_valid = match_sz(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_AD:
|
||||
is_valid = match_ad(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_REG:
|
||||
is_valid = match_reg(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_CR:
|
||||
is_valid = match_cr(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_CB:
|
||||
is_valid = match_cb(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_IMM:
|
||||
is_valid = match_imm(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_COND:
|
||||
is_valid = match_cond(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_IGNORE:
|
||||
match_ignore(token, &read_bits);
|
||||
break;
|
||||
case RX_TOKEN_JMP:
|
||||
is_valid = match_jump(inst, token);
|
||||
break;
|
||||
case RX_TOKEN_REG_LIMIT:
|
||||
is_valid = match_reg_patched(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_HOOK:
|
||||
is_valid = check_some(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_RI:
|
||||
is_valid = match_ri(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
case RX_TOKEN_DATA:
|
||||
pack_data(inst, token, &read_bits, bytes);
|
||||
break;
|
||||
default:
|
||||
rz_warn_if_reached();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// assume bits / 8 = bytes should be integer
|
||||
if ((read_bits & 7)) {
|
||||
// instruction are defined as bytes
|
||||
rz_warn_if_reached();
|
||||
return false;
|
||||
}
|
||||
|
||||
*bytes_read = (st32)read_bits / 8;
|
||||
return true;
|
||||
}
|
||||
100
librz/asm/arch/rx/rx_inst.h
Normal file
100
librz/asm/arch/rx/rx_inst.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
// SPDX-FileCopyrightText: 2024 heersin <teablearcher@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#ifndef RX_ARCH_INST_H
|
||||
#define RX_ARCH_INST_H
|
||||
|
||||
#include "rx_opcode_detail.h"
|
||||
|
||||
typedef enum rx_operand_kind_enum {
|
||||
RX_OPERAND_NULL,
|
||||
RX_OPERAND_IMM,
|
||||
RX_OPERAND_REG,
|
||||
RX_OPERAND_FLAG,
|
||||
RX_OPERAND_COND,
|
||||
} RxOperandKind;
|
||||
|
||||
typedef enum {
|
||||
RX_FIXOP_NON,
|
||||
RX_FIXOP_POST_INC,
|
||||
RX_FIXOP_PRE_DEC
|
||||
} RxOpFixMark;
|
||||
|
||||
typedef enum {
|
||||
RX_FLAG_C,
|
||||
RX_FLAG_Z,
|
||||
RX_FLAG_S,
|
||||
RX_FLAG_O,
|
||||
RX_FLAG_I,
|
||||
RX_FLAG_U,
|
||||
RX_FLAG_RESERVED
|
||||
} RxOperandFlag;
|
||||
|
||||
typedef enum {
|
||||
RX_COND_EQ, // BZ
|
||||
RX_COND_NE, // BNZ
|
||||
RX_COND_GEU, // BC
|
||||
RX_COND_LTU, // BNC
|
||||
RX_COND_GTU,
|
||||
RX_COND_LEU,
|
||||
RX_COND_PZ,
|
||||
RX_COND_N,
|
||||
RX_COND_GE,
|
||||
RX_COND_LT,
|
||||
RX_COND_GT,
|
||||
RX_COND_LE,
|
||||
RX_COND_O,
|
||||
RX_COND_NO,
|
||||
RX_COND_RA,
|
||||
RX_COND_JUMP,
|
||||
RX_COND_RESERVED,
|
||||
} RxOpCondMark;
|
||||
|
||||
typedef struct {
|
||||
RxOpCondMark cond;
|
||||
ut8 pc_dsp_len;
|
||||
ut32 pc_dsp_val;
|
||||
} RxOperandCond;
|
||||
|
||||
typedef struct {
|
||||
bool as_indirect;
|
||||
bool as_base;
|
||||
ut8 dsp_width;
|
||||
RxOpExtMark memex;
|
||||
RxReg ri;
|
||||
RxReg reg;
|
||||
RxOpFixMark fix_mode;
|
||||
ut32 dsp_val;
|
||||
} RxOperandReg;
|
||||
|
||||
typedef struct {
|
||||
ut8 imm_width;
|
||||
ut32 imm;
|
||||
} RxOperandImm;
|
||||
|
||||
typedef struct rx_operand_t {
|
||||
RxOperandKind kind;
|
||||
union {
|
||||
RxOperandReg reg;
|
||||
RxOperandImm imm;
|
||||
RxOperandFlag flag;
|
||||
RxOperandCond cond;
|
||||
} v;
|
||||
} RxOperand;
|
||||
|
||||
typedef struct rx_inst_t {
|
||||
RxOpCode op;
|
||||
RxOperand v0;
|
||||
RxOperand v1;
|
||||
RxOperand v2;
|
||||
RxOpExtMark sz_mark;
|
||||
} RxInst;
|
||||
|
||||
// TODO make them into function, not static defined here
|
||||
// TODO: call in init
|
||||
extern RxOperandFlag rx_cb_map[16];
|
||||
extern RxReg rx_cr_map[32];
|
||||
|
||||
bool rx_try_match_and_parse(RZ_OUT RxInst *inst, RxDesc *desc, st32 RZ_OUT *bytes_read, ut64 bytes);
|
||||
|
||||
#endif
|
||||
307
librz/asm/arch/rx/rx_opcode_detail.c
Normal file
307
librz/asm/arch/rx/rx_opcode_detail.c
Normal file
|
|
@ -0,0 +1,307 @@
|
|||
// SPDX-FileCopyrightText: 2024 heersin <teablearcher@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include "rx_opcode_detail.h"
|
||||
#define RxCode(x, y) \
|
||||
{ \
|
||||
.type = RX_TOKEN_INST, .tk.inst = {.tk_len = (x), \
|
||||
.detail = (y) } \
|
||||
}
|
||||
#define RxReg(x, v) \
|
||||
{ .type = RX_TOKEN_REG, .tk.reg.tk_len = (x), .tk.reg.vid = (v) }
|
||||
#define RxLi(x, v) \
|
||||
{ .type = RX_TOKEN_LI, .tk.li.tk_len = (x), .tk.li.vid = (v) }
|
||||
#define RxImm(x, v) \
|
||||
{ .type = RX_TOKEN_IMM, .tk.imm.tk_len = (x), .tk.imm.vid = (v) }
|
||||
#define RxMi(x) \
|
||||
{ .type = RX_TOKEN_MI, .tk.mi.tk_len = (x) }
|
||||
#define RxLd(x, v) \
|
||||
{ .type = RX_TOKEN_LD, .tk.ld.tk_len = (x), .tk.ld.vid = (v) }
|
||||
#define RxLdPart(x, v) \
|
||||
{ .type = RX_TOKEN_LD_PART, .tk.ld_part.tk_len = (x), .tk.ld_part.vid = (v) }
|
||||
#define RxCond(x, v) \
|
||||
{ .type = RX_TOKEN_COND, .tk.cond.tk_len = (x), .tk.cond.vid = (v) }
|
||||
#define RxDsp(x) \
|
||||
{ .type = RX_TOKEN_DSP, .tk.dsp.tk_len = (x) }
|
||||
#define RxSz(x) \
|
||||
{ .type = RX_TOKEN_SZ, .tk.sz.tk_len = (x) }
|
||||
#define RxAd(x) \
|
||||
{ .type = RX_TOKEN_AD, .tk.ad.tk_len = (x) }
|
||||
#define RxCr(x, v) \
|
||||
{ .type = RX_TOKEN_CR, .tk.cr.tk_len = (x), .tk.cr.vid = (v) }
|
||||
#define RxCb(x) \
|
||||
{ .type = RX_TOKEN_CB, .tk.cb.tk_len = (x) }
|
||||
#define RxDspSplit(x, v, it, xx) \
|
||||
{ .type = RX_TOKEN_DSP_SPLIT, \
|
||||
.tk.dsp_sp.tk_len = (x), .tk.dsp_sp.vid = (v), .tk.dsp_sp.tk_len_more = (xx), .tk.dsp_sp.interval = (it) }
|
||||
#define RxIgnore(x) \
|
||||
{ .type = RX_TOKEN_IGNORE, .tk.reserved.tk_len = (x) }
|
||||
|
||||
#define RxRi(x, bind_v) \
|
||||
{ .type = RX_TOKEN_RI, .tk.reg.tk_len = (x), .tk.reg.vid = (bind_v) }
|
||||
|
||||
// TODO: Jmp maybe removed or an empty mark
|
||||
#define RxJmp \
|
||||
{ .type = RX_TOKEN_JMP }
|
||||
|
||||
#define RxRegLimit(x, v) \
|
||||
{ .type = RX_TOKEN_REG_LIMIT, .tk.reg_li.tk_len = (x), .tk.reg_li.vid = (v) }
|
||||
|
||||
#define ImmData(v) \
|
||||
{ .type = RX_TOKEN_DATA, .tk.data.vid = (v), .tk.data.data_type = 1 }
|
||||
#define DspData(v) \
|
||||
{ .type = RX_TOKEN_DATA, .tk.data.vid = (v), .tk.data.data_type = 2 }
|
||||
#define PcDspData(v, l) \
|
||||
{ .type = RX_TOKEN_DATA, .tk.data.vid = (v), .tk.data.fixed_len = (l), .tk.data.data_type = 3 }
|
||||
#define ImmFixedData(v, l) \
|
||||
{ .type = RX_TOKEN_DATA, .tk.data.vid = (v), .tk.data.fixed_len = (l), .tk.data.data_type = 1 }
|
||||
#define RxHook \
|
||||
{ .type = RX_TOKEN_HOOK }
|
||||
#define RxEnd \
|
||||
{ .type = RX_TOKEN_NON }
|
||||
|
||||
#define V0 0
|
||||
#define V1 1
|
||||
#define V2 2
|
||||
|
||||
RxDesc rx_inst_descs[RX_DESC_SIZE] = {
|
||||
{ .op = RX_OP_ABS, .tks = { RxCode(12, 0x07e2), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_ABS, .tks = { RxCode(16, 0xfc0f), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_ADC, .tks = { RxCode(12, 0x0fd7), RxLi(2, V0), RxCode(6, 0x02), RxReg(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_ADC, .tks = { RxCode(16, 0xfc0b), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_ADC, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x08), RxLdPart(2, V0), RxCode(8, 0x02), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_ADD, .tks = { RxCode(8, 0x62), RxImm(4, V0), RxReg(4, V1), RxEnd } },
|
||||
// { .op = RX_OP_ADD, .tks = { RxCode(6, 0x1c), RxLi(2, V0), RxReg(4, V1), RxReg(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_ADD_UB, .tks = { RxCode(6, 0x12), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_ADD, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x02), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_ADD, .tks = { RxCode(6, 0x1c), RxLi(2, V0), RxReg(4, V1), RxReg(4, V2), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_ADD, .tks = { RxCode(12, 0x0ff2), RxReg(4, V2), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_AND, .tks = { RxCode(8, 0x64), RxImm(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_AND, .tks = { RxCode(6, 0x1d), RxLi(2, V0), RxCode(4, 0x02), RxReg(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_AND_UB, .tks = { RxCode(6, 0x14), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_AND, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x04), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_AND, .tks = { RxCode(12, 0xff4), RxReg(4, V2), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_BCLR, .tks = { RxCode(6, 0x3c), RxLdPart(2, V1), RxReg(4, V1), RxCode(1, 0x1), RxImm(3, V0), DspData(V1), RxEnd } },
|
||||
{ .op = RX_OP_BCLR, .tks = { RxCode(14, 0x3f19), RxLdPart(2, V1), RxReg(4, V1), RxReg(4, V0), DspData(V1), RxEnd } },
|
||||
{ .op = RX_OP_BCLR, .tks = { RxCode(7, 0x3d), RxImm(5, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_BCLR, .tks = { RxCode(16, 0xfc67), RxReg(4, V1), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_BCND_S, .tks = { RxCode(4, 0x1), RxCond(1, V0), RxDsp(3), RxEnd } },
|
||||
{ .op = RX_OP_BCND_B, .tks = { RxCode(4, 0x2), RxCond(4, V0), PcDspData(V0, 8), RxEnd } },
|
||||
{ .op = RX_OP_BCND_W, .tks = { RxCode(7, 0x1d), RxCond(1, V0), PcDspData(V0, 16), RxEnd } },
|
||||
{ .op = RX_OP_BMCND, .tks = { RxCode(11, 0x7e7), RxImm(3, V1), RxLdPart(2, V2), RxReg(4, V2), RxCond(4, V0), DspData(V2), RxEnd } },
|
||||
{ .op = RX_OP_BMCND, .tks = { RxCode(11, 0x7ef), RxImm(5, V1), RxCond(4, V0), RxReg(4, V2), RxEnd } },
|
||||
{ .op = RX_OP_BNOT, .tks = { RxCode(11, 0x7e7), RxImm(3, V0), RxLdPart(2, V1), RxReg(4, V1), RxCode(4, 0xf), DspData(V1), RxEnd } },
|
||||
{ .op = RX_OP_BNOT, .tks = { RxCode(14, 0x3f1b), RxLdPart(2, V1), RxReg(4, V1), RxReg(4, V0), DspData(V1), RxEnd } },
|
||||
{ .op = RX_OP_BNOT, .tks = { RxCode(11, 0x7ef), RxImm(5, V0), RxCode(4, 0xf), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_BNOT, .tks = { RxCode(16, 0xfc6f), RxReg(4, V1), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_BRA_S, .tks = { RxCode(5, 0x1), RxJmp, RxDsp(3), RxEnd } },
|
||||
{ .op = RX_OP_BRA_B, .tks = { RxCode(8, 0x2e), RxJmp, PcDspData(V0, 8), RxEnd } },
|
||||
{ .op = RX_OP_BRA_W, .tks = { RxCode(8, 0x38), RxJmp, PcDspData(V0, 16), RxEnd } },
|
||||
{ .op = RX_OP_BRA_A, .tks = { RxCode(8, 0x04), RxJmp, PcDspData(V0, 24), RxEnd } },
|
||||
{ .op = RX_OP_BRA_L, .tks = { RxCode(12, 0x7f4), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_BRK, .tks = { RxCode(8, 0x0), RxEnd } },
|
||||
{ .op = RX_OP_BSET, .tks = { RxCode(6, 0x3c), RxLdPart(2, V1), RxReg(4, V1), RxCode(1, 0x0), RxImm(3, V0), DspData(V1), RxEnd } },
|
||||
{ .op = RX_OP_BSET, .tks = { RxCode(14, 0x3f18), RxLdPart(2, V1), RxReg(4, V1), RxReg(4, V0), DspData(V1), RxEnd } },
|
||||
{ .op = RX_OP_BSET, .tks = { RxCode(7, 0x3c), RxImm(5, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_BSET, .tks = { RxCode(16, 0xfc63), RxReg(4, V1), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_BSR_W, .tks = { RxCode(8, 0x39), RxJmp, PcDspData(V0, 16), RxEnd } },
|
||||
{ .op = RX_OP_BSR_A, .tks = { RxCode(8, 0x05), RxJmp, PcDspData(V0, 24), RxEnd } },
|
||||
{ .op = RX_OP_BSR_L, .tks = { RxCode(12, 0x07f5), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_BTST, .tks = { RxCode(6, 0x3d), RxLdPart(2, V1), RxReg(4, V1), RxCode(1, 0x0), RxImm(3, V0), DspData(V1), RxEnd } },
|
||||
{ .op = RX_OP_BTST, .tks = { RxCode(14, 0x3f1a), RxLdPart(2, V1), RxReg(4, V1), RxReg(4, V0), DspData(V1), RxEnd } },
|
||||
{ .op = RX_OP_BTST, .tks = { RxCode(7, 0x3e), RxImm(5, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_BTST, .tks = { RxCode(16, 0xfc6b), RxReg(4, V1), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_CLRPSW, .tks = { RxCode(12, 0x07fb), RxCb(4), RxEnd } },
|
||||
|
||||
{ .op = RX_OP_CMP, .tks = { RxCode(8, 0x61), RxImm(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_CMP, .tks = { RxCode(12, 0x0755), RxReg(4, V1), ImmFixedData(V0, 8), RxEnd } },
|
||||
{ .op = RX_OP_CMP, .tks = { RxCode(6, 0x1d), RxLi(2, V0), RxCode(4, 0x0), RxReg(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_CMP_UB, .tks = { RxCode(6, 0x11), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_CMP, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x1), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
|
||||
{ .op = RX_OP_DIV, .tks = { RxCode(12, 0xfd7), RxLi(2, V0), RxCode(6, 0x08), RxReg(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_DIV_UB, .tks = { RxCode(14, 0x3f08), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_DIV, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x08), RxLd(2, V0), RxCode(8, 0x08), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_DIVU, .tks = { RxCode(12, 0xfd7), RxLi(2, V0), RxCode(6, 0x9), RxReg(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_DIVU_UB, .tks = { RxCode(14, 0x3f09), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_DIVU, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x8), RxLd(2, V0), RxCode(8, 0x09), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
// EMUL family special Rd Range
|
||||
{ .op = RX_OP_EMUL, .tks = { RxCode(12, 0xfd7), RxLi(2, V0), RxCode(6, 0x06), RxRegLimit(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_EMUL_UB, .tks = { RxCode(14, 0x3f06), RxLd(2, V0), RxReg(4, V0), RxRegLimit(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_EMUL, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x08), RxLd(2, V0), RxCode(8, 0x06), RxReg(4, V0), RxRegLimit(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_EMULU, .tks = { RxCode(12, 0xfd7), RxLi(2, V0), RxCode(6, 0x07), RxRegLimit(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_EMULU_UB, .tks = { RxCode(14, 0x3f07), RxLd(2, V0), RxReg(4, V0), RxRegLimit(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_EMULU, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x8), RxLd(2, V0), RxCode(8, 0x07), RxReg(4, V0), RxRegLimit(4, V1), DspData(V0), RxEnd } },
|
||||
|
||||
{ .op = RX_OP_FADD, .tks = { RxCode(20, 0xfd722), RxReg(4, V1), ImmFixedData(V0, 32), RxEnd } },
|
||||
{ .op = RX_OP_FADD, .tks = { RxCode(14, 0x3f22), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_FCMP, .tks = { RxCode(20, 0xfd721), RxReg(4, V1), ImmFixedData(V0, 32), RxEnd } },
|
||||
{ .op = RX_OP_FCMP, .tks = { RxCode(14, 0x3f21), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_FDIV, .tks = { RxCode(20, 0xfd724), RxReg(4, V1), ImmFixedData(V0, 32), RxEnd } },
|
||||
{ .op = RX_OP_FDIV, .tks = { RxCode(14, 0x3f24), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_FMUL, .tks = { RxCode(20, 0xfd723), RxReg(4, V1), ImmFixedData(V0, 32), RxEnd } },
|
||||
{ .op = RX_OP_FMUL, .tks = { RxCode(14, 0x3f23), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_FSUB, .tks = { RxCode(20, 0xfd720), RxReg(4, V1), ImmFixedData(V0, 32), RxEnd } },
|
||||
{ .op = RX_OP_FSUB, .tks = { RxCode(14, 0x3f20), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
|
||||
{ .op = RX_OP_FTOI, .tks = { RxCode(14, 0x3f25), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_INT, .tks = { RxCode(16, 0x7560), ImmFixedData(V0, 8), RxEnd } },
|
||||
{ .op = RX_OP_ITOF_UB, .tks = { RxCode(14, 0x3f11), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_ITOF, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x8), RxLd(2, V0), RxCode(8, 0x11), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_JMP, .tks = { RxCode(12, 0x07f0), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_JSR, .tks = { RxCode(12, 0x07f1), RxReg(4, V0), RxEnd } },
|
||||
|
||||
// Mov family
|
||||
{ .op = RX_OP_MOV, .tks = { RxCode(2, 0x2), RxSz(2), RxCode(1, 0x0), RxDspSplit(4, V1, 3, 1), RxReg(3, V1), RxIgnore(1), RxReg(3, V0), RxEnd } },
|
||||
{ .op = RX_OP_MOV, .tks = { RxCode(2, 0x2), RxSz(2), RxCode(1, 0x1), RxDspSplit(4, V0, 3, 1), RxReg(3, V0), RxIgnore(1), RxReg(3, V1), RxEnd } },
|
||||
{ .op = RX_OP_MOV, .tks = { RxCode(8, 0x66), RxImm(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_MOV, .tks = { RxCode(6, 0x0f), RxSz(2), RxDspSplit(1, V1, 3, 4), RxReg(3, V1), RxIgnore(4), ImmFixedData(V0, 8), RxEnd } },
|
||||
{ .op = RX_OP_MOV, .tks = { RxCode(12, 0x0754), RxReg(4, V1), ImmFixedData(V0, 8) } },
|
||||
{ .op = RX_OP_MOV, .tks = { RxCode(8, 0xfb), RxReg(4, V1), RxLi(2, V0), RxCode(2, 0x02), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_MOV, .tks = { RxCode(2, 0x3), RxSz(2), RxCode(4, 0xf), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
// ld are limited to 0-2
|
||||
{ .op = RX_OP_MOV, .tks = { RxCode(6, 0x3e), RxLdPart(2, V1), RxReg(4, V1), RxLi(2, V0), RxSz(2), DspData(V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_MOV, .tks = { RxCode(2, 0x3), RxSz(2), RxCode(2, 0x3), RxLdPart(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_MOV, .tks = { RxCode(10, 0x03f9), RxSz(2), RxRi(4, V0), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_MOV, .tks = { RxCode(2, 0x3), RxSz(2), RxLdPart(2, V1), RxCode(2, 0x3), RxReg(4, V1), RxReg(4, V0), DspData(V1), RxEnd } },
|
||||
{ .op = RX_OP_MOV, .tks = { RxCode(10, 0x03f8), RxSz(2), RxRi(4, V1), RxReg(4, V1), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_MOV, .tks = { RxCode(2, 0x3), RxSz(2), RxLdPart(2, V1), RxLdPart(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), DspData(V1), RxEnd } },
|
||||
{ .op = RX_OP_MOV, .tks = { RxCode(12, 0xfd2), RxAd(2), RxSz(2), RxReg(4, V1), RxHook, RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_MOV, .tks = { RxCode(12, 0xfd2), RxAd(2), RxSz(2), RxReg(4, V0), RxHook, RxReg(4, V1), RxEnd } },
|
||||
|
||||
{ .op = RX_OP_MOVU, .tks = { RxCode(4, 0xb), RxSz(1), RxDspSplit(4, V0, 3, 1), RxReg(3, V0), RxIgnore(1), RxReg(3, V1), RxEnd } },
|
||||
{ .op = RX_OP_MOVU, .tks = { RxCode(5, 0x0b), RxSz(1), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_MOVU, .tks = { RxCode(11, 0x07f6), RxSz(1), RxRi(4, V0), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_MOVU, .tks = { RxCode(12, 0x0fd3), RxAd(2), RxCode(1, 0x0), RxSz(1), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
|
||||
{ .op = RX_OP_MACHI, .tks = { RxCode(16, 0xfd04), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_MACLO, .tks = { RxCode(16, 0xfd05), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_MAX, .tks = { RxCode(12, 0xfd7), RxLi(2, V0), RxCode(6, 0x4), RxReg(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_MAX_UB, .tks = { RxCode(14, 0x3f04), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_MAX, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x8), RxLd(2, V0), RxCode(8, 0x04), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_MIN, .tks = { RxCode(12, 0xfd7), RxLi(2, V0), RxCode(6, 0x5), RxReg(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_MIN_UB, .tks = { RxCode(14, 0x3f05), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_MIN, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x8), RxLd(2, V0), RxCode(8, 0x05), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_MUL, .tks = { RxCode(8, 0x63), RxImm(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_MUL, .tks = { RxCode(6, 0x1d), RxLi(2, V0), RxCode(4, 0x01), RxReg(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_MUL_UB, .tks = { RxCode(6, 0x13), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_MUL, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x3), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_MUL, .tks = { RxCode(12, 0xff3), RxReg(4, V2), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_MULHI, .tks = { RxCode(16, 0xfd00), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_MULLO, .tks = { RxCode(16, 0xfd01), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_NOP, .tks = { RxCode(8, 0x03), RxEnd } },
|
||||
{ .op = RX_OP_NEG, .tks = { RxCode(12, 0x07e1), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_NEG, .tks = { RxCode(16, 0xfc07), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_NOT, .tks = { RxCode(12, 0x07e0), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_NOT, .tks = { RxCode(16, 0xfc3b), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_OR, .tks = { RxCode(8, 0x65), RxImm(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_OR, .tks = { RxCode(6, 0x1d), RxLi(2, V0), RxCode(4, 0x03), RxReg(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_OR_UB, .tks = { RxCode(6, 0x15), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_OR, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x5), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_OR, .tks = { RxCode(12, 0xff5), RxReg(4, V2), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_MVFACHI, .tks = { RxCode(20, 0xfd1f0), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_MVFACMI, .tks = { RxCode(20, 0xfd1f2), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_MVFC, .tks = { RxCode(16, 0xfd6a), RxCr(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_MVTACHI, .tks = { RxCode(20, 0xfd170), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_MVTACLO, .tks = { RxCode(20, 0xfd171), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_MVTC, .tks = { RxCode(12, 0xfd7), RxLi(2, V0), RxCode(6, 0x30), RxCr(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_MVTC, .tks = { RxCode(16, 0xfd68), RxReg(4, V0), RxCr(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_MVTIPL, .tks = { RxCode(20, 0x75700), RxImm(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_POP, .tks = { RxCode(12, 0x7eb), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_POPC, .tks = { RxCode(12, 0x7ee), RxCr(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_POPM, .tks = { RxCode(8, 0x6f), RxRegLimit(4, V0), RxRegLimit(4, V1), RxEnd } }, // special rn
|
||||
{ .op = RX_OP_PUSH, .tks = { RxCode(10, 0x1fa), RxSz(2), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_PUSH, .tks = { RxCode(6, 0x3d), RxLdPart(2, V0), RxReg(4, V0), RxCode(2, 0x2), RxSz(2), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_PUSHC, .tks = { RxCode(12, 0x7ec), RxCr(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_PUSHM, .tks = { RxCode(8, 0x6e), RxRegLimit(4, V0), RxRegLimit(4, V1), RxEnd } }, // special rn
|
||||
{ .op = RX_OP_RACW, .tks = { RxCode(19, 0x7e8c0), RxImm(1, V0), RxCode(4, 0x0), RxEnd } },
|
||||
{ .op = RX_OP_REVL, .tks = { RxCode(16, 0xfd67), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_REVW, .tks = { RxCode(16, 0xfd65), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_RMPA, .tks = { RxCode(14, 0x1fe3), RxSz(2), RxEnd } },
|
||||
{ .op = RX_OP_ROLC, .tks = { RxCode(12, 0x7e5), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_RORC, .tks = { RxCode(12, 0x7e4), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_ROTL, .tks = { RxCode(15, 0x7eb7), RxImm(5, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_ROTL, .tks = { RxCode(16, 0xfd66), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_ROTR, .tks = { RxCode(15, 0x7eb6), RxImm(5, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_ROTR, .tks = { RxCode(16, 0xfd64), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_ROUND, .tks = { RxCode(14, 0x3f26), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_RTE, .tks = { RxCode(16, 0x7f95), RxEnd } },
|
||||
{ .op = RX_OP_RTFI, .tks = { RxCode(16, 0x7f94), RxEnd } },
|
||||
{ .op = RX_OP_RTS, .tks = { RxCode(8, 0x02), RxEnd } },
|
||||
{ .op = RX_OP_RTE, .tks = { RxCode(16, 0x7f94), RxEnd } },
|
||||
{ .op = RX_OP_RTSD, .tks = { RxCode(8, 0x67), ImmFixedData(V0, 8), RxEnd } },
|
||||
{ .op = RX_OP_RTSD, .tks = { RxCode(8, 0x3f), RxRegLimit(4, V0), RxRegLimit(4, V1), ImmFixedData(V0, 8), RxEnd } }, // special rn
|
||||
{ .op = RX_OP_SAT, .tks = { RxCode(12, 0x7e3), RxReg(4, V0), RxEnd } },
|
||||
{ .op = RX_OP_SATR, .tks = { RxCode(16, 0x7f93), RxEnd } },
|
||||
{ .op = RX_OP_WAIT, .tks = { RxCode(16, 0x7f96), RxEnd } },
|
||||
{ .op = RX_OP_SCCOND, .tks = { RxCode(12, 0xfcd), RxSz(2), RxLd(2, V1), RxReg(4, V1), RxCond(4, V0), DspData(V1), RxEnd } },
|
||||
{ .op = RX_OP_SCMPU, .tks = { RxCode(16, 0x7f83), RxEnd } },
|
||||
{ .op = RX_OP_SETPSW, .tks = { RxCode(12, 0x7fa), RxCb(4), RxEnd } },
|
||||
{ .op = RX_OP_SHAR, .tks = { RxCode(7, 0x35), RxImm(5, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_SHAR, .tks = { RxCode(16, 0xfd61), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_SHAR, .tks = { RxCode(11, 0x07ed), RxImm(5, V0), RxReg(4, V1), RxReg(4, V2), RxEnd } },
|
||||
|
||||
{ .op = RX_OP_SHLL, .tks = { RxCode(7, 0x36), RxImm(5, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_SHLL, .tks = { RxCode(16, 0xfd62), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_SHLL, .tks = { RxCode(11, 0x07ee), RxImm(5, V0), RxReg(4, V1), RxReg(4, V2), RxEnd } },
|
||||
|
||||
{ .op = RX_OP_SHLR, .tks = { RxCode(7, 0x34), RxImm(5, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_SHLR, .tks = { RxCode(16, 0xfd60), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_SHLR, .tks = { RxCode(11, 0x07ec), RxImm(5, V0), RxReg(4, V1), RxReg(4, V2), RxEnd } },
|
||||
|
||||
{ .op = RX_OP_SBB, .tks = { RxCode(16, 0xfc03), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_SBB, .tks = { RxCode(14, 0x01a8), RxLdPart(2, V0), RxCode(8, 0x00), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
|
||||
{ .op = RX_OP_SUB, .tks = { RxCode(8, 0x60), RxImm(4, V0), RxReg(4, V1), RxEnd } },
|
||||
{ .op = RX_OP_SUB_UB, .tks = { RxCode(6, 0x10), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_SUB, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x0), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_SUB, .tks = { RxCode(12, 0xff0), RxReg(4, V2), RxReg(4, V0), RxReg(4, V1), RxEnd } },
|
||||
|
||||
{ .op = RX_OP_SMOVB, .tks = { RxCode(16, 0x7f8b), RxEnd } },
|
||||
{ .op = RX_OP_SMOVF, .tks = { RxCode(16, 0x7f8f), RxEnd } },
|
||||
{ .op = RX_OP_SMOVU, .tks = { RxCode(16, 0x7f87), RxEnd } },
|
||||
{ .op = RX_OP_SSTR, .tks = { RxCode(14, 0x1fe2), RxSz(2), RxEnd } },
|
||||
{ .op = RX_OP_STNZ, .tks = { RxCode(12, 0x0fd7), RxLi(2, V0), RxCode(6, 0x0f), RxReg(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_STZ, .tks = { RxCode(12, 0x0fd7), RxLi(2, V0), RxCode(6, 0x0e), RxReg(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_SUNTIL, .tks = { RxCode(14, 0x1fe0), RxSz(2), RxEnd } },
|
||||
{ .op = RX_OP_SWHILE, .tks = { RxCode(14, 0x1fe1), RxSz(2), RxEnd } },
|
||||
|
||||
{ .op = RX_OP_TST, .tks = { RxCode(12, 0xfd7), RxLi(2, V0), RxCode(6, 0x0c), RxReg(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_TST_UB, .tks = { RxCode(14, 0x3f0c), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_TST, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x8), RxLd(2, V0), RxCode(8, 0x0c), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
|
||||
{ .op = RX_OP_XCHG_UB, .tks = { RxCode(14, 0x3f10), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_XCHG, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x8), RxLd(2, V0), RxCode(8, 0x10), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_XOR, .tks = { RxCode(12, 0xfd7), RxLi(2, V0), RxCode(6, 0x0d), RxReg(4, V1), ImmData(V0), RxEnd } },
|
||||
{ .op = RX_OP_XOR, .tks = { RxCode(8, 0x06), RxMi(2), RxCode(4, 0x08), RxLd(2, V0), RxCode(8, 0x0d), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
{ .op = RX_OP_XOR_UB, .tks = { RxCode(14, 0x3f0d), RxLd(2, V0), RxReg(4, V0), RxReg(4, V1), DspData(V0), RxEnd } },
|
||||
};
|
||||
|
||||
#undef RxCode
|
||||
#undef RxReg
|
||||
#undef RxLi
|
||||
#undef RxIm
|
||||
#undef RxMi
|
||||
#undef RxLd
|
||||
#undef RxLds
|
||||
#undef RxLdd
|
||||
#undef RxCond
|
||||
#undef RxDsp
|
||||
#undef RxSz
|
||||
#undef RxAd
|
||||
#undef RxCr
|
||||
#undef RxCb
|
||||
#undef RxDspSplit
|
||||
#undef RxIgnore
|
||||
#undef RxJmp
|
||||
#undef RxHook
|
||||
#undef RxEnd
|
||||
#undef ImmData
|
||||
#undef DspData
|
||||
#undef PcDspData
|
||||
#undef ImmFixedData
|
||||
#undef RxRi
|
||||
|
||||
#undef V0
|
||||
#undef V1
|
||||
#undef V2
|
||||
281
librz/asm/arch/rx/rx_opcode_detail.h
Normal file
281
librz/asm/arch/rx/rx_opcode_detail.h
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
// SPDX-FileCopyrightText: 2024 heersin <teablearcher@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#ifndef RX_OPCODE_DETAIL_H
|
||||
#define RX_OPCODE_DETAIL_H
|
||||
|
||||
#include <rz_util.h>
|
||||
|
||||
typedef enum {
|
||||
RX_OP_INVALID,
|
||||
RX_OP_ABS,
|
||||
RX_OP_ADC,
|
||||
RX_OP_ADD,
|
||||
RX_OP_ADD_UB,
|
||||
RX_OP_AND,
|
||||
RX_OP_AND_UB,
|
||||
RX_OP_BCLR,
|
||||
RX_OP_BCND_S,
|
||||
RX_OP_BCND_B,
|
||||
RX_OP_BCND_W,
|
||||
RX_OP_BMCND,
|
||||
RX_OP_BNOT,
|
||||
RX_OP_BRA_S,
|
||||
RX_OP_BRA_B,
|
||||
RX_OP_BRA_W,
|
||||
RX_OP_BRA_A,
|
||||
RX_OP_BRA_L,
|
||||
RX_OP_BRK,
|
||||
RX_OP_BSET,
|
||||
RX_OP_BSR_W,
|
||||
RX_OP_BSR_A,
|
||||
RX_OP_BSR_L,
|
||||
RX_OP_BTST,
|
||||
RX_OP_CLRPSW,
|
||||
RX_OP_CMP,
|
||||
RX_OP_CMP_UB,
|
||||
RX_OP_DIV,
|
||||
RX_OP_DIV_UB,
|
||||
RX_OP_DIVU,
|
||||
RX_OP_DIVU_UB,
|
||||
RX_OP_EMUL,
|
||||
RX_OP_EMUL_UB,
|
||||
RX_OP_EMULU,
|
||||
RX_OP_EMULU_UB,
|
||||
RX_OP_FADD,
|
||||
RX_OP_FCMP,
|
||||
RX_OP_FDIV,
|
||||
RX_OP_FMUL,
|
||||
RX_OP_FSUB,
|
||||
RX_OP_FTOI,
|
||||
RX_OP_INT,
|
||||
RX_OP_ITOF,
|
||||
RX_OP_ITOF_UB,
|
||||
RX_OP_JMP,
|
||||
RX_OP_JSR,
|
||||
RX_OP_MACHI,
|
||||
RX_OP_MACLO,
|
||||
RX_OP_MAX,
|
||||
RX_OP_MAX_UB,
|
||||
RX_OP_MIN,
|
||||
RX_OP_MIN_UB,
|
||||
RX_OP_MOV,
|
||||
RX_OP_MOVU,
|
||||
RX_OP_MUL,
|
||||
RX_OP_MUL_UB,
|
||||
RX_OP_MULHI,
|
||||
RX_OP_MULLO,
|
||||
RX_OP_MVFACHI,
|
||||
RX_OP_MVFACMI,
|
||||
RX_OP_MVFC,
|
||||
RX_OP_MVTACHI,
|
||||
RX_OP_MVTACLO,
|
||||
RX_OP_MVTC,
|
||||
RX_OP_MVTIPL,
|
||||
RX_OP_NEG,
|
||||
RX_OP_NOP,
|
||||
RX_OP_NOT,
|
||||
RX_OP_OR,
|
||||
RX_OP_OR_UB,
|
||||
RX_OP_POP,
|
||||
RX_OP_POPC,
|
||||
RX_OP_POPM,
|
||||
RX_OP_PUSH,
|
||||
RX_OP_PUSHC,
|
||||
RX_OP_PUSHM,
|
||||
RX_OP_RACW,
|
||||
RX_OP_REVL,
|
||||
RX_OP_REVW,
|
||||
RX_OP_RMPA,
|
||||
RX_OP_ROLC,
|
||||
RX_OP_RORC,
|
||||
RX_OP_ROTL,
|
||||
RX_OP_ROTR,
|
||||
RX_OP_ROUND,
|
||||
RX_OP_RTE,
|
||||
RX_OP_RTFI,
|
||||
RX_OP_RTS,
|
||||
RX_OP_RTSD,
|
||||
RX_OP_SAT,
|
||||
RX_OP_SATR,
|
||||
RX_OP_SBB,
|
||||
RX_OP_SCCOND,
|
||||
RX_OP_SCMPU,
|
||||
RX_OP_SETPSW,
|
||||
RX_OP_SHAR,
|
||||
RX_OP_SHLL,
|
||||
RX_OP_SHLR,
|
||||
RX_OP_SMOVB,
|
||||
RX_OP_SMOVF,
|
||||
RX_OP_SMOVU,
|
||||
RX_OP_SSTR,
|
||||
RX_OP_STNZ,
|
||||
RX_OP_STZ,
|
||||
RX_OP_SUB,
|
||||
RX_OP_SUB_UB,
|
||||
RX_OP_SUNTIL,
|
||||
RX_OP_SWHILE,
|
||||
RX_OP_TST,
|
||||
RX_OP_TST_UB,
|
||||
RX_OP_WAIT,
|
||||
RX_OP_XCHG,
|
||||
RX_OP_XCHG_UB,
|
||||
RX_OP_XOR,
|
||||
RX_OP_XOR_UB,
|
||||
_RX_OP_COUNT,
|
||||
} RxOpCode;
|
||||
|
||||
typedef enum {
|
||||
// General Purpose Register
|
||||
// R0 as SP
|
||||
RX_REG_R0,
|
||||
RX_REG_R1,
|
||||
RX_REG_R2,
|
||||
RX_REG_R3,
|
||||
RX_REG_R4,
|
||||
RX_REG_R5,
|
||||
RX_REG_R6,
|
||||
RX_REG_R7,
|
||||
RX_REG_R8,
|
||||
RX_REG_R9,
|
||||
RX_REG_R10,
|
||||
RX_REG_R11,
|
||||
RX_REG_R12,
|
||||
RX_REG_R13,
|
||||
RX_REG_R14,
|
||||
RX_REG_R15,
|
||||
// Control Register
|
||||
RX_REG_ISP,
|
||||
RX_REG_USP,
|
||||
RX_REG_INTB,
|
||||
RX_REG_PC,
|
||||
RX_REG_PSW,
|
||||
RX_REG_BPC,
|
||||
RX_REG_BPSW,
|
||||
RX_REG_FINTV,
|
||||
RX_REG_FPSW,
|
||||
RX_REG_ACC, // dsp
|
||||
RX_REG_RESERVED
|
||||
} RxReg;
|
||||
|
||||
typedef enum {
|
||||
RX_EXT_NON,
|
||||
RX_EXT_UB,
|
||||
RX_EXT_B,
|
||||
RX_EXT_W,
|
||||
RX_EXT_L,
|
||||
RX_EXT_UW,
|
||||
_RX_EXT_COUNT,
|
||||
} RxOpExtMark;
|
||||
|
||||
typedef enum {
|
||||
RX_TOKEN_NON,
|
||||
RX_TOKEN_INST,
|
||||
RX_TOKEN_LD,
|
||||
RX_TOKEN_LI,
|
||||
RX_TOKEN_LD_PART,
|
||||
RX_TOKEN_MI,
|
||||
RX_TOKEN_IMM,
|
||||
RX_TOKEN_REG,
|
||||
RX_TOKEN_COND,
|
||||
RX_TOKEN_DSP,
|
||||
RX_TOKEN_DSP_SPLIT,
|
||||
RX_TOKEN_IGNORE,
|
||||
RX_TOKEN_SZ,
|
||||
RX_TOKEN_AD,
|
||||
RX_TOKEN_CR,
|
||||
RX_TOKEN_CB,
|
||||
RX_TOKEN_JMP,
|
||||
RX_TOKEN_DATA,
|
||||
RX_TOKEN_RI,
|
||||
RX_TOKEN_REG_LIMIT,
|
||||
RX_TOKEN_HOOK, // for validation at the end of token
|
||||
} RxTokenType;
|
||||
|
||||
struct rx_inst_token_t {
|
||||
ut8 tk_len;
|
||||
ut32 detail;
|
||||
};
|
||||
typedef struct rx_inst_token_t RxInstToken;
|
||||
|
||||
struct rx_oprand_related_token_t {
|
||||
ut8 tk_len;
|
||||
ut8 vid;
|
||||
};
|
||||
typedef struct rx_oprand_related_token_t RxDispLenToken;
|
||||
typedef struct rx_oprand_related_token_t RxImmLenToken;
|
||||
typedef struct rx_oprand_related_token_t RxVarDispLenToken;
|
||||
typedef struct rx_oprand_related_token_t RxRegToken;
|
||||
typedef struct rx_oprand_related_token_t RxImmToken;
|
||||
typedef struct rx_oprand_related_token_t RxControlRegToken;
|
||||
typedef struct rx_oprand_related_token_t RxCondToken;
|
||||
|
||||
typedef struct {
|
||||
ut8 fixed_len;
|
||||
ut8 vid;
|
||||
ut8 data_type;
|
||||
} RxDataToken;
|
||||
|
||||
typedef struct {
|
||||
ut8 tk_len;
|
||||
ut8 vid;
|
||||
ut8 interval;
|
||||
ut8 tk_len_more;
|
||||
} RxDspSplitToken;
|
||||
|
||||
struct rx_simple_token_t {
|
||||
ut8 tk_len;
|
||||
};
|
||||
typedef struct rx_simple_token_t RxMemexToken;
|
||||
typedef struct rx_simple_token_t RxSizeToken;
|
||||
typedef struct rx_simple_token_t RxFlagToken;
|
||||
typedef struct rx_simple_token_t RxAddrToken;
|
||||
typedef struct rx_simple_token_t RxSimpleToken;
|
||||
typedef struct rx_simple_token_t RxDispToken;
|
||||
|
||||
typedef union rx_token_union {
|
||||
RxInstToken inst;
|
||||
RxDispLenToken ld;
|
||||
RxImmLenToken li;
|
||||
RxVarDispLenToken ld_part; // ld for partial valid bits range
|
||||
RxMemexToken mi;
|
||||
RxImmToken imm;
|
||||
RxRegToken reg;
|
||||
RxRegToken reg_li; // reg for limited range
|
||||
RxRegToken ri;
|
||||
RxCondToken cond;
|
||||
RxDispToken dsp;
|
||||
RxDspSplitToken dsp_sp;
|
||||
RxSizeToken sz;
|
||||
RxAddrToken ad;
|
||||
RxControlRegToken cr;
|
||||
RxFlagToken cb;
|
||||
RxSimpleToken jmp;
|
||||
RxDataToken data;
|
||||
RxSimpleToken reserved;
|
||||
} RxTokenUnion;
|
||||
|
||||
struct rx_token_t {
|
||||
RxTokenType type;
|
||||
RxTokenUnion tk;
|
||||
};
|
||||
typedef struct rx_token_t RxToken;
|
||||
|
||||
#define MAX_TOKEN 10
|
||||
#define RX_SET_V1_SZ 90
|
||||
#define RX_SET_V2_SZ (RX_SET_V1_SZ + 19)
|
||||
#define RX_SET_V3_SZ (RX_SET_V2_SZ + 4)
|
||||
#define RX_SET_SIZE RX_SET_V3_SZ
|
||||
|
||||
// todo: accurate num
|
||||
#define RX_DESC_SIZE (RX_SET_SIZE * 3)
|
||||
|
||||
struct rx_desc_t {
|
||||
RxOpCode op;
|
||||
RxToken tks[MAX_TOKEN];
|
||||
};
|
||||
typedef struct rx_desc_t RxDesc;
|
||||
|
||||
extern RxDesc rx_inst_descs[RX_DESC_SIZE];
|
||||
|
||||
#endif
|
||||
171
librz/asm/arch/rx/rx_str.inc
Normal file
171
librz/asm/arch/rx/rx_str.inc
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
// SPDX-FileCopyrightText: 2024 heersin <teablearcher@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
const char *opnames[_RX_OP_COUNT] = {
|
||||
"invalid",
|
||||
"abs",
|
||||
"adc",
|
||||
"add",
|
||||
"add.UB",
|
||||
"and",
|
||||
"and.UB",
|
||||
"bclr",
|
||||
// bcnd.s, cnd provided by cond_names
|
||||
"b%s.S",
|
||||
"b%s.B",
|
||||
"b%s.W",
|
||||
"bm%s",
|
||||
"bnot",
|
||||
"bra.S",
|
||||
"bra.B",
|
||||
"bra.W",
|
||||
"bra.A",
|
||||
"bra.L",
|
||||
"brk",
|
||||
"bset",
|
||||
"bsr.W",
|
||||
"bsr.A",
|
||||
"bsr.L",
|
||||
"btst",
|
||||
"clrpsw",
|
||||
"cmp",
|
||||
"cmp.UB",
|
||||
"div",
|
||||
"div.UB",
|
||||
"divu",
|
||||
"divu.UB",
|
||||
"emul",
|
||||
"emul.UB",
|
||||
"emulu",
|
||||
"emulu.UB",
|
||||
"fadd",
|
||||
"fcmp",
|
||||
"fdiv",
|
||||
"fmul",
|
||||
"fsub",
|
||||
"ftoi",
|
||||
"int",
|
||||
"itof",
|
||||
"itof.UB",
|
||||
"jmp",
|
||||
"jsr",
|
||||
"machi",
|
||||
"maclo",
|
||||
"max",
|
||||
"max.UB",
|
||||
"min",
|
||||
"min.UB",
|
||||
"mov",
|
||||
"movu",
|
||||
"mul",
|
||||
"mul.UB",
|
||||
"mulhi",
|
||||
"mullo",
|
||||
"mvfachi",
|
||||
"mvfacmi",
|
||||
"mvfc",
|
||||
"mvtachi",
|
||||
"mvtaclo",
|
||||
"mvtc",
|
||||
"mvtipl",
|
||||
"neg",
|
||||
"nop",
|
||||
"not",
|
||||
"or",
|
||||
"or.UB",
|
||||
"pop",
|
||||
"popc",
|
||||
"popm",
|
||||
"push",
|
||||
"pushc",
|
||||
"pushm",
|
||||
"racw",
|
||||
"revl",
|
||||
"revw",
|
||||
"rmpa",
|
||||
"rolc",
|
||||
"rorc",
|
||||
"rotl",
|
||||
"rotr",
|
||||
"round",
|
||||
"rte",
|
||||
"rtfi",
|
||||
"rts",
|
||||
"rtsd",
|
||||
"sat",
|
||||
"satr",
|
||||
"sbb",
|
||||
"sc%s",
|
||||
"scmpu",
|
||||
"setpsw",
|
||||
"shar",
|
||||
"shll",
|
||||
"shlr",
|
||||
"smovb",
|
||||
"smovf",
|
||||
"smovu",
|
||||
"sstr",
|
||||
"stnz",
|
||||
"stz",
|
||||
"sub",
|
||||
"sub.UB",
|
||||
"suntil",
|
||||
"swhile",
|
||||
"tst",
|
||||
"tst.UB",
|
||||
"wait",
|
||||
"xchg",
|
||||
"xchg.UB",
|
||||
"xor",
|
||||
"xor.UB"
|
||||
};
|
||||
|
||||
const char *extmark_names[_RX_EXT_COUNT] = {
|
||||
"B",
|
||||
"W",
|
||||
"L",
|
||||
"UW",
|
||||
};
|
||||
|
||||
const char *reg_names[RX_REG_RESERVED] = {
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
|
||||
"isp", "usp", "intb", "pc",
|
||||
"psw", "bpc", "bpsw", "fintv",
|
||||
"fpsw", "acc"
|
||||
};
|
||||
|
||||
const char *flag_names[7] = {
|
||||
"C",
|
||||
"Z",
|
||||
"S",
|
||||
"O",
|
||||
"I",
|
||||
"U",
|
||||
"",
|
||||
};
|
||||
|
||||
const char *cond_names[RX_COND_RESERVED] = {
|
||||
"eq",
|
||||
"ne",
|
||||
"geu",
|
||||
"ltu",
|
||||
"gtu",
|
||||
"leu",
|
||||
"pz",
|
||||
"n",
|
||||
"ge",
|
||||
"lt",
|
||||
"gt",
|
||||
"le",
|
||||
"o",
|
||||
"no",
|
||||
"ra",
|
||||
"jump",
|
||||
};
|
||||
|
||||
#define RxNameOp(op) ((op) < _RX_OP_COUNT ? opnames[(op)] : "invalid")
|
||||
#define RxNameExt(ext) ((ext) < _RX_EXT_COUNT ? extmark_names[((ext)-RX_EXT_B)] : "invalid")
|
||||
#define RxNameReg(reg) ((reg) < RX_REG_RESERVED ? reg_names[(reg)-RX_REG_R0] : "invalid")
|
||||
#define RxNameFlag(flag) ((flag) < 7 ? flag_names[(flag)] : "invalid")
|
||||
#define RxNameCond(cond) ((cond) < RX_COND_RESERVED ? cond_names[(cond)] : "invalid")
|
||||
|
|
@ -37,6 +37,7 @@ asm_plugins_list = [
|
|||
'pyc',
|
||||
'rl78',
|
||||
'rsp',
|
||||
'rx',
|
||||
'sh',
|
||||
'snes',
|
||||
'sparc_cs',
|
||||
|
|
@ -124,6 +125,7 @@ rz_asm_sources = [
|
|||
'p/asm_propeller.c',
|
||||
'p/asm_pyc.c',
|
||||
'p/asm_rl78.c',
|
||||
'p/asm_rx.c',
|
||||
'p/asm_rsp.c',
|
||||
'p/asm_sh.c',
|
||||
'p/asm_snes.c',
|
||||
|
|
@ -220,6 +222,9 @@ rz_asm_sources = [
|
|||
'arch/rl78/rl78_maps.c',
|
||||
'arch/rl78/rl78_operand.c',
|
||||
'arch/rl78/rl78.c',
|
||||
'arch/rx/rx.c',
|
||||
'arch/rx/rx_opcode_detail.c',
|
||||
'arch/rx/rx_inst.c',
|
||||
'arch/rsp/rsp_idec.c',
|
||||
'arch/sh/disassembler.c',
|
||||
'arch/sh/assembler.c',
|
||||
|
|
|
|||
41
librz/asm/p/asm_rx.c
Normal file
41
librz/asm/p/asm_rx.c
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// SPDX-FileCopyrightText: 2024 Heersin <teablearcher@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include <rz_types.h>
|
||||
#include <rz_util.h>
|
||||
#include <rz_lib.h>
|
||||
#include <rz_asm.h>
|
||||
#include <asm/arch/rx/rx.h>
|
||||
|
||||
static int disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) {
|
||||
RxInst inst = { 0 };
|
||||
st32 bytes_read;
|
||||
|
||||
if (!rx_dis(&inst, &bytes_read, buf, len)) {
|
||||
rz_asm_op_set_asm(op, "(invalid)");
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
rx_inst_stringify(&inst, &op->buf_asm);
|
||||
op->size = bytes_read;
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
RzAsmPlugin rz_asm_plugin_rx = {
|
||||
.name = "rx",
|
||||
.arch = "rx",
|
||||
.desc = "Renesas RX Family disassembler",
|
||||
.author = "Heersin",
|
||||
.license = "LGPL3",
|
||||
.bits = 32,
|
||||
.endian = RZ_SYS_ENDIAN_LITTLE | RZ_SYS_ENDIAN_BIG,
|
||||
.disassemble = &disassemble
|
||||
};
|
||||
|
||||
#ifndef RZ_PLUGIN_INCORE
|
||||
RZ_API RzLibStruct rizin_plugin = {
|
||||
.type = RZ_LIB_TYPE_ASM,
|
||||
.data = &rz_asm_plugin_rx,
|
||||
.version = RZ_VERSION
|
||||
};
|
||||
#endif
|
||||
|
|
@ -269,6 +269,7 @@ static const struct arch_translation arch_translation_table[] = {
|
|||
{ EM_MICROBLAZE, "microblaze.gnu" },
|
||||
{ EM_RISCV, "riscv" },
|
||||
{ EM_RL78, "rl78" },
|
||||
{ EM_RX, "rx" },
|
||||
{ EM_VAX, "vax" },
|
||||
{ EM_XTENSA, "xtensa" },
|
||||
{ EM_LANAI, "lanai" },
|
||||
|
|
|
|||
|
|
@ -2459,6 +2459,7 @@ extern RzAnalysisPlugin rz_analysis_plugin_riscv;
|
|||
extern RzAnalysisPlugin rz_analysis_plugin_riscv_cs;
|
||||
extern RzAnalysisPlugin rz_analysis_plugin_rl78;
|
||||
extern RzAnalysisPlugin rz_analysis_plugin_rsp;
|
||||
extern RzAnalysisPlugin rz_analysis_plugin_rx;
|
||||
extern RzAnalysisPlugin rz_analysis_plugin_sh;
|
||||
extern RzAnalysisPlugin rz_analysis_plugin_snes;
|
||||
extern RzAnalysisPlugin rz_analysis_plugin_sparc_cs;
|
||||
|
|
|
|||
|
|
@ -261,6 +261,7 @@ extern RzAsmPlugin rz_asm_plugin_riscv;
|
|||
extern RzAsmPlugin rz_asm_plugin_riscv_cs;
|
||||
extern RzAsmPlugin rz_asm_plugin_rl78;
|
||||
extern RzAsmPlugin rz_asm_plugin_rsp;
|
||||
extern RzAsmPlugin rz_asm_plugin_rx;
|
||||
extern RzAsmPlugin rz_asm_plugin_sh;
|
||||
extern RzAsmPlugin rz_asm_plugin_snes;
|
||||
extern RzAsmPlugin rz_asm_plugin_sparc_cs;
|
||||
|
|
|
|||
367
test/db/analysis/rx
Normal file
367
test/db/analysis/rx
Normal file
|
|
@ -0,0 +1,367 @@
|
|||
NAME=RX morse info
|
||||
FILE=bins/rx/morse
|
||||
ARGS=
|
||||
CMDS=<<EOF
|
||||
pd 4 @ entry0
|
||||
iI
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
;-- entry0:
|
||||
;-- section..text:
|
||||
;-- segment.LOAD0:
|
||||
;-- segment.ehdr:
|
||||
;-- .text:
|
||||
;-- L0:
|
||||
;-- .LFB2:
|
||||
;-- _start:
|
||||
0xfff40000 mvtc #0x0, psw, ; crt0.S:36 ; [00] -r-x section size 20866 named .text
|
||||
0xfff40004 mvtc #0x100, fpsw, ; crt0.S:39
|
||||
0xfff40009 mov #loc.__stack, r0, ; crt0.S:40
|
||||
0xfff4000f mvtc #loc.__vectors, intb, ; crt0.S:41
|
||||
arch rx
|
||||
cpu N/A
|
||||
baddr 0xfff40000
|
||||
binsz 0x0000a623
|
||||
bintype elf
|
||||
bits 32
|
||||
class ELF32
|
||||
compiler GCC: (GCC_Build_20231120) 8.3.0.202311-GNURX 20190222
|
||||
dbg_file N/A
|
||||
endian LE
|
||||
hdr.csum N/A
|
||||
guid N/A
|
||||
intrp N/A
|
||||
laddr 0x00000000
|
||||
lang c
|
||||
machine Renesas RX family
|
||||
minopsz 1
|
||||
os linux
|
||||
cc N/A
|
||||
rpath NONE
|
||||
subsys linux
|
||||
stripped false
|
||||
crypto false
|
||||
havecode true
|
||||
va true
|
||||
sanitiz false
|
||||
static true
|
||||
linenum true
|
||||
lsyms true
|
||||
canary false
|
||||
PIE false
|
||||
RELROCS true
|
||||
NX false
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=RX morse function
|
||||
FILE=bins/rx/morse
|
||||
ARGS=
|
||||
CMDS=<<EOF
|
||||
aaa
|
||||
pdf @ sym._main
|
||||
pdf @ sym._text_to_morse
|
||||
pdf @ sym._morse_to_text
|
||||
pdf @ sym._exit
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
/ int sym._main(int argc, char **argv, char **envp);
|
||||
| 0xfff40257 push.L r10,
|
||||
| 0xfff40259 add #0xc8, r0, r10
|
||||
| 0xfff4025c mov.L r10, r0,
|
||||
| 0xfff4025e mov.L r10, r5,
|
||||
| 0xfff40260 mov.L #0x6c6c6548, [r5],
|
||||
| 0xfff40266 add #0x4, r5,
|
||||
| 0xfff40268 mov.L #0x6f57206f, [r5],
|
||||
| 0xfff4026e add #0x4, r5,
|
||||
| 0xfff40270 mov.L #0x646c72, [r5],
|
||||
| 0xfff40275 add #0x4, r5,
|
||||
| 0xfff40277 mov.L r10, r1,
|
||||
| 0xfff40279 bsr.A #0xfffecf, ; sym._text_to_morse
|
||||
| 0xfff4027d mov #loc..LC28, r3,
|
||||
| 0xfff40283 mov #0x2c, r4,
|
||||
| 0xfff40286 add #0xc, r10, r5
|
||||
| 0xfff40289 mov.L r5, r1,
|
||||
| 0xfff4028b mov.L r3, r2,
|
||||
| 0xfff4028d mov.L r4, r3,
|
||||
| 0xfff4028f smovf
|
||||
| 0xfff40291 add #0xc, r10, r5
|
||||
| 0xfff40294 mov.L r5, r1,
|
||||
| 0xfff40296 bsr.A #0xffff4a, ; sym._morse_to_text
|
||||
| 0xfff4029a mov #0x0, r5,
|
||||
| 0xfff4029c mov.L r5, r1,
|
||||
\ 0xfff4029e rtsd #0xf, r10,
|
||||
; CALL XREF from sym._main @ 0xfff40279
|
||||
/ sym._text_to_morse();
|
||||
| 0xfff40148 push.L r10,
|
||||
| 0xfff4014a add #0xfc, r0, r10
|
||||
| 0xfff4014d add #0xf8, r10, r0
|
||||
| 0xfff40150 mov.L r1, [r10],
|
||||
| ,=< 0xfff40152 bra.B #0x7a,
|
||||
| .--> 0xfff40154 mov.L [r10], r5,
|
||||
| :| 0xfff40156 mov.B [r5], r5,
|
||||
| :| 0xfff40158 movu.B r5, r5,
|
||||
| :| 0xfff4015a cmp #0x60, r5,
|
||||
| ,===< 0xfff4015d bleu.B #0x2d,
|
||||
| |:| 0xfff4015f mov.L [r10], r5,
|
||||
| |:| 0xfff40161 mov.B [r5], r5,
|
||||
| |:| 0xfff40163 movu.B r5, r5,
|
||||
| |:| 0xfff40165 cmp #0x7a, r5,
|
||||
| ,====< 0xfff40168 bgtu.B #0x22,
|
||||
| ||:| 0xfff4016a mov.L [r10], r5,
|
||||
| ||:| 0xfff4016c mov.B [r5], r5,
|
||||
| ||:| 0xfff4016e movu.B r5, r5,
|
||||
| ||:| 0xfff40170 add #0x9f, r5, r5
|
||||
| ||:| 0xfff40173 mov #0x10, r4,
|
||||
| ||:| 0xfff40179 mov.L [r5,r4], r5,
|
||||
| ||:| 0xfff4017c mov.L r5, 0x1[r0],
|
||||
| ||:| 0xfff4017e mov.L #loc..LC26, [r0],
|
||||
| ||:| 0xfff40184 bsr.A #0x14d, ; sym._printf ; int printf(const char *format)
|
||||
| ,=====< 0xfff40188 bra.B #0x3e,
|
||||
| |``---> 0xfff4018a mov.L [r10], r5,
|
||||
| | :| 0xfff4018c mov.B [r5], r5,
|
||||
| | :| 0xfff4018e movu.B r5, r5,
|
||||
| | :| 0xfff40190 cmp #0x40, r5,
|
||||
| | ,===< 0xfff40193 bleu.B #0x2c,
|
||||
| | |:| 0xfff40195 mov.L [r10], r5,
|
||||
| | |:| 0xfff40197 mov.B [r5], r5,
|
||||
| | |:| 0xfff40199 movu.B r5, r5,
|
||||
| | |:| 0xfff4019b cmp #0x5a, r5,
|
||||
| |,====< 0xfff4019e bgtu.B #0x21,
|
||||
| |||:| 0xfff401a0 mov.L [r10], r5,
|
||||
| |||:| 0xfff401a2 mov.B [r5], r5,
|
||||
| |||:| 0xfff401a4 movu.B r5, r5,
|
||||
| |||:| 0xfff401a6 add #0xbf, r5, r5
|
||||
| |||:| 0xfff401a9 mov #0x10, r4,
|
||||
| |||:| 0xfff401af mov.L [r5,r4], r5,
|
||||
| |||:| 0xfff401b2 mov.L r5, 0x1[r0],
|
||||
| |||:| 0xfff401b4 mov.L #loc..LC26, [r0],
|
||||
| |||:| 0xfff401ba bsr.A #0x117, ; sym._printf ; int printf(const char *format)
|
||||
..
|
||||
| |``---> 0xfff401bf mov #0x20, r1,
|
||||
| | :| 0xfff401c2 bsr.A #0x12e, ; sym._putchar ; int putchar(int c)
|
||||
| `-----> 0xfff401c6 mov.L [r10], r5,
|
||||
| :| 0xfff401c8 add #0x1, r5,
|
||||
| :| 0xfff401ca mov.L r5, [r10],
|
||||
| :`-> 0xfff401cc mov.L [r10], r5,
|
||||
| : 0xfff401ce mov.B [r5], r5,
|
||||
| : 0xfff401d0 movu.B r5, r5,
|
||||
| : 0xfff401d2 cmp #0x0, r5,
|
||||
\ `==< 0xfff401d4 bne.B #0x80,
|
||||
; CALL XREF from sym._main @ 0xfff40296
|
||||
/ sym._morse_to_text();
|
||||
| 0xfff401e0 push.L r10,
|
||||
| 0xfff401e2 add #0xf4, r0, r10
|
||||
| 0xfff401e5 mov.L r10, r0,
|
||||
| 0xfff401e7 mov.L r1, 0x2[r10],
|
||||
| 0xfff401ea mov #loc..LC27, r2,
|
||||
| 0xfff401f0 mov.L 0x2[r10], r1,
|
||||
| 0xfff401f3 bsr.A #0x178, ; sym._strtok ; char *strtok(char *s1, const char *s2)
|
||||
| 0xfff401f7 mov.L r1, [r10],
|
||||
| ,=< 0xfff401f9 bra.B #0x4e,
|
||||
| .--> 0xfff401fb mov.L #0x0, 0x1[r10],
|
||||
| ,===< 0xfff401ff bra.B #0x32,
|
||||
| .----> 0xfff40201 mov #0x10, r5,
|
||||
| :|:| 0xfff40207 mov.L 0x1[r10], r4,
|
||||
| :|:| 0xfff4020a mov.L [r4,r5], r5,
|
||||
| :|:| 0xfff4020d mov.L r5, r2,
|
||||
| :|:| 0xfff4020f mov.L [r10], r1,
|
||||
| :|:| 0xfff40211 bsr.A #0x14b, ; sym._strcmp ; int strcmp(const char *s1, const char *s2)
|
||||
| :|:| 0xfff40215 mov.L r1, r5,
|
||||
| :|:| 0xfff40217 cmp #0x0, r5,
|
||||
| ,=====< 0xfff40219 bne.B #0x10,
|
||||
| |:|:| 0xfff4021b mov.L 0x1[r10], r5,
|
||||
| |:|:| 0xfff4021e add #0x41, r5, r5
|
||||
| |:|:| 0xfff40221 mov.L r5, r1,
|
||||
| |:|:| 0xfff40223 bsr.A #0xcd, ; sym._putchar ; int putchar(int c)
|
||||
| ,======< 0xfff40227 bra.B #0x12,
|
||||
| |`-----> 0xfff40229 mov.L 0x1[r10], r5,
|
||||
| | :|:| 0xfff4022c add #0x1, r5,
|
||||
| | :|:| 0xfff4022e mov.L r5, 0x1[r10],
|
||||
| | :`---> 0xfff40231 mov.L 0x1[r10], r5,
|
||||
| | : :| 0xfff40234 cmp #0x19, r5,
|
||||
| | `====< 0xfff40237 ble.B #0xca,
|
||||
| `------> 0xfff40239 mov #loc..LC27, r2,
|
||||
| :| 0xfff4023f mov #0x0, r1,
|
||||
| :| 0xfff40241 bsr.A #0x12a, ; sym._strtok ; char *strtok(char *s1, const char *s2)
|
||||
| :| 0xfff40245 mov.L r1, [r10],
|
||||
| :`-> 0xfff40247 mov.L [r10], r5,
|
||||
| : 0xfff40249 cmp #0x0, r5,
|
||||
\ `==< 0xfff4024b bne.B #0xb0,
|
||||
/ void sym._exit(int status);
|
||||
| 0xfff402a1 push.L r7,
|
||||
| 0xfff402a3 mov.L r1, r7,
|
||||
| 0xfff402a5 mov #0x0, r2,
|
||||
| 0xfff402a7 bsr.A #0x132b, ; sym.___call_exitprocs
|
||||
| 0xfff402ab mov #obj.__global_impure_ptr, r5,
|
||||
| 0xfff402b1 mov.L [r5], r1,
|
||||
| 0xfff402b3 mov.L 0xf[r1], r5,
|
||||
| 0xfff402b5 cmp #0x0, r5,
|
||||
| ,=< 0xfff402b7 beq.S #0x3,
|
||||
| | 0xfff402b8 jsr r5,
|
||||
| `-> 0xfff402ba mov.L r7, r1,
|
||||
\ 0xfff402bc bsr.A #0x471c, ; sym.__exit ; void _exit(int status)
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=RX morse function list
|
||||
FILE=bins/rx/morse
|
||||
ARGS=
|
||||
CMDS=<<EOF
|
||||
aaa
|
||||
afl
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
0xfff40000 1 94 entry0
|
||||
0xfff4005e 7 75 -> 42 sym._rx_run_preinit_array
|
||||
0xfff4006e 1 18 sym._rx_run_init_array
|
||||
0xfff40080 1 15 sym._rx_run_fini_array
|
||||
0xfff400b0 3 32 -> 23 sym._deregister_tm_clones
|
||||
0xfff400d0 4 43 sym._register_tm_clones
|
||||
0xfff400fb 5 43 sym.___do_global_dtors_aux
|
||||
0xfff40126 1 1 sym._call___do_global_dtors_aux
|
||||
0xfff40127 3 28 sym._frame_dummy
|
||||
0xfff40143 1 1 sym._call_frame_dummy
|
||||
0xfff40148 10 142 -> 141 sym._text_to_morse
|
||||
0xfff401e0 8 109 sym._morse_to_text
|
||||
0xfff40257 1 74 sym._main
|
||||
0xfff402a1 3 31 sym._exit
|
||||
0xfff402c0 1 17 sym.__printf_r
|
||||
0xfff402d1 1 25 sym._printf
|
||||
0xfff402ea 1 6 sym.__putchar_r
|
||||
0xfff402f0 1 18 sym._putchar
|
||||
0xfff40302 8 74 sym.__putc_r
|
||||
0xfff4034c 1 16 sym._putc
|
||||
0xfff4035c 1 15 sym._strcmp
|
||||
0xfff4036b 1 17 sym._strtok
|
||||
0xfff4037c 13 103 -> 81 sym.___strtok_r
|
||||
0xfff403e3 1 6 sym._strtok_r
|
||||
0xfff403e9 35 4023 -> 411 sym.__vfprintf_r
|
||||
0xfff413ee 1 18 sym._vfprintf
|
||||
0xfff41400 5 119 sym.___sbprintf
|
||||
0xfff41477 1 10 sym.___swbuf_r
|
||||
0xfff41511 1 16 sym.___swbuf
|
||||
0xfff41521 1 16 sym.___swsetup_r
|
||||
0xfff415d2 11 112 -> 79 sym.___call_exitprocs
|
||||
0xfff41657 11 263 -> 215 sym._quorem
|
||||
0xfff4175e 33 2479 -> 400 sym.__dtoa_r
|
||||
0xfff4210d 6 223 -> 53 sym.___sflush_r
|
||||
0xfff42229 5 43 -> 34 sym.__fflush_r
|
||||
0xfff42254 3 35 sym._fflush
|
||||
0xfff42277 1 3 sym.___fp_lock
|
||||
0xfff4227a 1 73 sym._std
|
||||
0xfff422c3 1 10 sym.__cleanup_r
|
||||
0xfff422cd 1 3 sym.___fp_unlock
|
||||
0xfff422d0 3 46 sym.___sfmoreglue
|
||||
0xfff422fe 1 12 sym.__cleanup
|
||||
0xfff4230a 3 69 sym.___sinit
|
||||
0xfff4234f 11 132 sym.___sfp
|
||||
0xfff423d8 1 1 sym.___sfp_lock_acquire
|
||||
0xfff423d9 1 1 sym.___sfp_lock_release
|
||||
0xfff423da 1 1 sym.___sinit_lock_acquire
|
||||
0xfff423db 1 1 sym.___sinit_lock_release
|
||||
0xfff423dc 1 18 sym.___fp_lock_all
|
||||
0xfff423ee 1 18 sym.___fp_unlock_all
|
||||
0xfff42400 3 74 sym.__malloc_trim_r
|
||||
0xfff424a3 19 392 -> 214 sym.__free_r
|
||||
0xfff4262b 10 57 sym.__fwalk
|
||||
0xfff42664 9 61 -> 52 sym.__fwalk_reent
|
||||
0xfff426a1 1 5 sym.___localeconv_l
|
||||
0xfff426a6 1 7 sym.__localeconv_r
|
||||
0xfff426ad 1 7 sym._localeconv
|
||||
0xfff426b4 4 40 sym.__setlocale_r
|
||||
0xfff42700 1 11 sym.___locale_mb_cur_max
|
||||
0xfff4270b 1 16 sym._setlocale
|
||||
0xfff4271b 6 76 -> 51 sym.___swhatbuf_r
|
||||
0xfff42767 8 123 -> 104 sym.___smakebuf_r
|
||||
0xfff427e2 5 34 sym.__malloc_r
|
||||
0xfff42c16 1 18 sym.__mbtowc_r
|
||||
0xfff42c28 8 37 sym.___ascii_mbtowc
|
||||
0xfff42c4d 1 11 sym._memchr
|
||||
0xfff42c58 1 7 sym._memcpy
|
||||
0xfff42c5f 1 7 sym._memset
|
||||
0xfff42c66 1 1 sym.___malloc_lock
|
||||
0xfff42c67 1 1 sym.___malloc_unlock
|
||||
0xfff42c68 9 84 sym.__Balloc
|
||||
0xfff42cbc 3 17 sym.__Bfree
|
||||
0xfff42ccd 2 59 sym.___multadd
|
||||
0xfff42d60 13 156 -> 151 sym.___s2b
|
||||
0xfff42dfc 12 72 sym.___hi0bits
|
||||
0xfff42e44 18 100 -> 85 sym.___lo0bits
|
||||
0xfff42ea8 3 44 sym.___i2b
|
||||
0xfff42ed4 22 291 -> 287 sym.___multiply
|
||||
0xfff42ffc 13 122 -> 98 sym.___pow5mult
|
||||
0xfff43076 12 179 -> 153 sym.___lshift
|
||||
0xfff4312b 7 45 sym.___mcmp
|
||||
0xfff4315a 12 190 sym.___mdiff
|
||||
0xfff43251 3 37 -> 25 sym.___ulp
|
||||
0xfff43276 7 86 -> 71 sym.___b2d
|
||||
0xfff432cc 8 124 sym.___d2b
|
||||
0xfff43348 4 69 sym.___ratio
|
||||
0xfff4338d 4 34 sym.__mprec_log10
|
||||
0xfff433b0 6 50 sym.___copybits
|
||||
0xfff433e2 10 59 sym.___any_on
|
||||
0xfff4341d 1 22 sym.__sbrk_r
|
||||
0xfff4343e 7 50 sym.___fpclassifyf
|
||||
0xfff43470 4 31 sym.___sread
|
||||
0xfff4348f 1 3 sym.___seofread
|
||||
0xfff43492 3 48 sym.___swrite
|
||||
0xfff434c2 1 15 sym.___sseek
|
||||
0xfff434e1 1 6 sym.___sclose
|
||||
0xfff434e7 1 13 sym._strlen
|
||||
0xfff434f4 1 9 sym.___sprint_r
|
||||
0xfff43554 139 2076 -> 1058 sym.__vfiprintf_r
|
||||
0xfff43d70 1 18 sym._vfiprintf
|
||||
0xfff43d82 5 119 sym.___sbprintf_0xfff43d82
|
||||
0xfff43df9 1 12 sym.__wctomb_r
|
||||
0xfff43e05 5 25 sym.___ascii_wctomb
|
||||
0xfff43e1e 1 26 sym.__write_r
|
||||
0xfff43e43 4 60 sym.___assert_func
|
||||
0xfff43e7f 1 8 sym.___assert
|
||||
0xfff43e87 4 32 sym.__calloc_r
|
||||
0xfff43efa 1 22 sym.__close_r
|
||||
0xfff43f1b 1 9 sym.___errno
|
||||
0xfff43f24 1 4 sym.__fclose_r
|
||||
0xfff43fa1 1 14 sym._fclose
|
||||
0xfff43faf 1 15 sym.__fiprintf_r
|
||||
0xfff43fbe 1 25 sym._fiprintf
|
||||
0xfff43fd7 13 115 -> 109 sym.___fputwc
|
||||
0xfff4404c 3 26 sym.__fputwc_r
|
||||
0xfff44066 4 41 sym._fputwc
|
||||
0xfff4408f 1 24 sym.__fstat_r
|
||||
0xfff440b2 39 671 -> 320 sym.___sfvwrite_r
|
||||
0xfff44351 1 22 sym.__isatty_r
|
||||
0xfff44372 1 26 sym.__lseek_r
|
||||
0xfff44397 3 24 sym._memmove
|
||||
0xfff443af 1 26 sym.__read_r
|
||||
0xfff443d4 1 10 sym.__realloc_r
|
||||
0xfff446f8 3 25 sym._cleanup_glue
|
||||
0xfff44711 18 151 -> 129 sym.__reclaim_reent
|
||||
0xfff447a8 3 29 sym.__wcrtomb_r
|
||||
0xfff447d0 1 18 sym._wcrtomb
|
||||
0xfff447e2 1 12 sym._abort
|
||||
0xfff447ee 7 52 -> 50 sym.__init_signal_r
|
||||
0xfff44822 6 50 sym.__signal_r
|
||||
0xfff44856 9 81 -> 75 sym.__raise_r
|
||||
0xfff448a7 12 81 -> 78 sym.___sigtramp_r
|
||||
0xfff448f8 1 14 sym._raise
|
||||
0xfff44906 1 16 sym._signal
|
||||
0xfff44916 1 12 sym.__init_signal
|
||||
0xfff44922 1 14 sym.___sigtramp
|
||||
0xfff44930 1 24 sym.__kill_r
|
||||
0xfff44953 1 4 sym.__getpid_r
|
||||
0xfff44957 1 13 sym._close
|
||||
0xfff44964 1 13 sym._fstat
|
||||
0xfff44971 1 13 sym._getpid
|
||||
0xfff4497e 1 12 sym._isatty
|
||||
0xfff4498a 1 13 sym._kill
|
||||
0xfff44997 1 13 sym._lseek
|
||||
0xfff449a4 1 13 sym._read
|
||||
0xfff449b1 3 26 sym._sbrk
|
||||
0xfff449cb 1 13 sym._write
|
||||
0xfff449d8 2 8 sym.__exit
|
||||
0xfff449e0 104 971 -> 944 sym.___udivdi3
|
||||
0xfff44db0 97 938 sym.__COM_MOD64u
|
||||
0xfff45548 1 4 loc..LANCHOR0_0xfff45548
|
||||
EOF
|
||||
RUN
|
||||
204
test/db/asm/rx
Normal file
204
test/db/asm/rx
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
d "itof.UB r1, r2," fc4712
|
||||
d "mov.W [r1], r2," dc12
|
||||
d "bclr r1, r2," fc6721
|
||||
d "itof 0x4[r1].L, r2," 06a1111204
|
||||
d "sub r1, r2, r3" ff0312
|
||||
d "xor.UB r1, r2," fc3712
|
||||
d "sub.UB r1, r2," 4312
|
||||
d "bmgeu #0x7, [r2]" fcfc22
|
||||
d "rts" 02
|
||||
d "emulu 0x4[r1].UW, r2," 06e1071204
|
||||
d "shlr #0x3, r1, r2" fd8312
|
||||
d "bset #0x7, [r2]," f027
|
||||
d "div 0x3[r1].B, r2," 0621081203
|
||||
d "divu.UB 0x3[r1], r2," fc251203
|
||||
d "divu [r1].L, r2," 06a00912
|
||||
d "mvtipl #0x2," 757002
|
||||
d "racw #0x0," fd1800
|
||||
d "mul.UB r1, r2," 4f12
|
||||
d "setpsw C," 7fa0
|
||||
d "add [r1].L, r2," 068812
|
||||
d "bltu.B #0x5," 2305
|
||||
d "mov.W [r1,r2], r3," fe5123
|
||||
d "or #0x8, r1," 6581
|
||||
d "bnot #0x1f, r2," fdfff2
|
||||
d "rmpa.W" 7f8d
|
||||
d "bclr r1, [r2]," fc6421
|
||||
d "cmp #0x7, r2," 6172
|
||||
d "emul #0xa, r2," fd74620a
|
||||
d "max #0xa, r2," fd74420a
|
||||
d "or r1, r2, r3" ff5312
|
||||
d "revw r1, r2," fd6512
|
||||
d "shlr #0x3, r2," 6832
|
||||
d "shar #0x3, r2," 6a32
|
||||
d "rtfi" 7f94
|
||||
d "shar r1, r2," fd6112
|
||||
d "or 0x2[r1].L, r2," 06951202
|
||||
d "smovb" 7f8b
|
||||
d "xor 0x4[r1].L, r2," 06a10d1204
|
||||
d "btst #0x7, [r2]," f427
|
||||
d "emul [r1].L, r2," 06a00612
|
||||
d "push.B r1," 7e81
|
||||
d "setpsw Z," 7fa1
|
||||
d "bra.L r2," 7f42
|
||||
d "mov #0x0, r2," 6602
|
||||
d "mov.W r1, [r2]," d321
|
||||
d "max 0x3[r1].B, r2," 0621041203
|
||||
d "max.UB r1, r2," fc1312
|
||||
d "fmul [r1], r2," fc8c12
|
||||
d "bra.L r1," 7f41
|
||||
d "mullo r1, r2," fd0112
|
||||
d "bsr.L r2," 7f52
|
||||
d "satr" 7f93
|
||||
d "add #0x7f, r1, r2" 71127f
|
||||
d "mov.B [-r1], r2," fd2c12
|
||||
d "and [r1].UW, r2," 06d012
|
||||
d "mvfachi r1," fd1f01
|
||||
d "clrpsw C," 7fb0
|
||||
d "bmeq #0x1f, r2" fdff02
|
||||
d "round [r1], r2," fc9812
|
||||
d "rotl r1, r2," fd6612
|
||||
d "btst r1, r2," fc6b21
|
||||
d "emul 0x4[r1].W, r2," 0661061204
|
||||
d "popc psw," 7ee0
|
||||
d "fdiv [r1], r2," fc9012
|
||||
d "neg r1, r2," fc0712
|
||||
d "emul.UB r1, r2," fc1b12
|
||||
d "mov.L r1, r2," ef12
|
||||
d "bnot r1, [r2]," fc6c21
|
||||
d "or [r1].L, r2," 069412
|
||||
d "movu.W 0x1[r1], r2," b81a
|
||||
d "mul #0xa, r2," 63a2
|
||||
d "bnot r1, r2," fc6f21
|
||||
d "mov.B r1, [r2+]," fd2021
|
||||
d "abs r0," 7e20
|
||||
d "neg r1," 7e11
|
||||
d "min #0xa, r2," fd74520a
|
||||
d "bsr.L r1," 7f51
|
||||
d "div.UB r1, r2," fc2312
|
||||
d "add #0xf, r2," 62f2
|
||||
d "rorc r1," 7e41
|
||||
d "scgeu.L r2," fcdb22
|
||||
d "suntil.W" 7f81
|
||||
d "or.UB r1, r2," 5712
|
||||
d "tst #0x7, r2," fd74c207
|
||||
d "add r1, r2, r3" ff2312
|
||||
d "mvtc r1, usp," fd6812
|
||||
d "divu.UB r1, r2," fc2712
|
||||
d "revl r1, r2," fd6712
|
||||
d "adc [r1].L, r2," 06a00212
|
||||
d "ftoi [r1], r2," fc9412
|
||||
d "machi r1, r2," fd0412
|
||||
d "sat r1," 7e31
|
||||
d "max [r1].L, r2," 06a00412
|
||||
d "mul [r1].L, r2," 068c12
|
||||
d "fsub [r1], r2," fc8012
|
||||
d "tst.UB 0x1[r1], r2," fc311201
|
||||
d "sbb [r1], r2," 06a00012
|
||||
d "sub #0xf, r2," 60f2
|
||||
d "mul r1, r2, r3" ff3312
|
||||
d "bra.W #0xfc8," 38c80f
|
||||
d "and #0xf, r2," 64f2
|
||||
d "btst r1, [r2]," fc6821
|
||||
d "mulhi r0, r0," fd0000
|
||||
d "rolc r1," 7e51
|
||||
d "bnot #0x7, [r2]," fcfc2f
|
||||
d "not r1," 7e01
|
||||
d "adc r1, r2," fc0b12
|
||||
d "emulu.UB r1, r2," fc1f12
|
||||
d "add.UB [r1], r2," 4812
|
||||
d "mul 0x2[r1].W, r2," 064d1202
|
||||
d "adc #0x7f, r2," fd74227f
|
||||
d "fmul r1, r2," fc8f12
|
||||
d "mvfacmi r1," fd1f21
|
||||
d "abs r1, r0," fc0f10
|
||||
d "cmp.UB r1, r2," 4712
|
||||
d "push.L [r1]," f41a
|
||||
d "btst #0x1f, r2," 7df2
|
||||
d "xor #0x8, r1," fd74d108
|
||||
d "maclo r1, r2," fd0512
|
||||
d "popm r4, r8," 6f48
|
||||
d "mov.B [r1+], r2," fd2812
|
||||
d "ftoi r1, r2," fc9712
|
||||
d "mvfc usp, r1," fd6a21
|
||||
d "rotr #0x1, r1," fd6c11
|
||||
d "bra.A #0x0," 04000000
|
||||
d "rtsd #0x1," 6701
|
||||
d "not r1, r2," fc3b12
|
||||
d "stz #0x1, r2," fd74e201
|
||||
d "swhile.W" 7f85
|
||||
d "div #0xa, r2," fd74820a
|
||||
d "fcmp r1, r2," fc8712
|
||||
d "bset r1, [r2]," fc6021
|
||||
d "emulu #0xa, r2," fd74720a
|
||||
d "bset r1, r2," fc6321
|
||||
d "fadd r1, r2," fc8b12
|
||||
d "itof [r1].L, r2," 06a01112
|
||||
d "cmp [r1].L, r2," 068412
|
||||
d "jmp r1," 7f01
|
||||
d "add.UB r1, r2," 4b12
|
||||
d "fcmp [r1], r2," fc8412
|
||||
d "mvtachi r1," fd1701
|
||||
d "clrpsw Z," 7fb1
|
||||
d "scmpu" 7f83
|
||||
d "rte" 7f95
|
||||
d "bclr #0x7, [r2]," f02f
|
||||
d "min 0x3[r1].B, r2," 0621051203
|
||||
d "mov.W r1, [r2,r3]," fe1231
|
||||
d "mvtaclo r1," fd1711
|
||||
d "round r1, r2," fc9b12
|
||||
d "bclr #0x1f, r2," 7bf2
|
||||
d "pushm r4, r8," 6e48
|
||||
d "rotr r1, r2," fd6412
|
||||
d "shar #0x3, r1, r2" fda312
|
||||
d "mov #0x80, r2," fb2680
|
||||
d "shll #0x3, r2," 6c32
|
||||
d "stnz #0x1, r2," fd74f201
|
||||
d "fsub r1, r2," fc8312
|
||||
d "pushm r1, r3," 6e13
|
||||
d "emulu [r1].L, r2," 06a00712
|
||||
d "rtsd #0x4, r7," 3f5704
|
||||
d "smovu" 7f87
|
||||
d "pop r1," 7eb1
|
||||
d "scne.W [r2]," fcd421
|
||||
d "mvtc #0xf000, intb," fd7b0c00f0
|
||||
d "mov #0x80, r2," 754280
|
||||
d "pushc psw," 7ec0
|
||||
d "rotl #0x1, r1," fd6e11
|
||||
d "and [r1].L, r2," 069012
|
||||
d "nop" 03
|
||||
d "shll #0x3, r1, r2" fdc312
|
||||
d "tst [r1].L, r2," 06a00c12
|
||||
d "brk" 00
|
||||
d "sub 0x1[r1].B, r2," 06011201
|
||||
d "wait" 7f96
|
||||
d "fadd [r1], r2," fc8812
|
||||
d "fdiv r1, r2," fc9312
|
||||
d "sstr.W" 7f89
|
||||
d "shll r1, r2," fd6212
|
||||
d "tst.UB r1, r2," fc3312
|
||||
d "sub [r1].L, r2," 068012
|
||||
d "sbb r1, r2," fc0312
|
||||
d "movu.W r1, r2," 5f12
|
||||
d "div [r1].L, r2," 06a00812
|
||||
d "mov.W [r1], [r2]," d012
|
||||
d "bset #0x1f, r2," 79f2
|
||||
d "int #0x0," 756000
|
||||
d "divu #0xa, r2," fd74920a
|
||||
d "smovf" 7f8f
|
||||
d "jsr r1," 7f11
|
||||
d "mulhi r1, r2," fd0012
|
||||
d "xchg.UB r1, r2," fc4312
|
||||
d "racw #0x1," fd1810
|
||||
d "movu.B [-r1], r2," fd3c12
|
||||
d "xchg [r1].W, r2," 06601012
|
||||
d "mov.L #0x0, [r2]," f82600
|
||||
d "xor [r1].L, r2," 06a00d12
|
||||
d "and.UB r1, r2," 5312
|
||||
d "and r1, r2, r3" ff4312
|
||||
d "min [r1].L, r2," 06a00512
|
||||
d "movu.B [r1+], r2," fd3812
|
||||
d "mov.B r1, [-r2]," fd2421
|
||||
d "popm r1, r3," 6f13
|
||||
d "bsr.A #0x0," 05000000
|
||||
d "min.UB r1, r2," fc1712
|
||||
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue