mirror of
https://github.com/rizinorg/rizin.git
synced 2026-10-12 02:21:57 +00:00
v810: RzIL support (#4096)
* RzIL v810 support * Fix v810 asm tests * Fix analysis/v810 * v810: move ESIL formation into a separate function * bin/elf: autodetect v810 architecture
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
// SPDX-FileCopyrightText: 2024 billow <[email protected]>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#ifndef RIZIN_V810_H
|
||||
#define RIZIN_V810_H
|
||||
|
||||
#include <rz_analysis.h>
|
||||
#include <v810_disas.h>
|
||||
|
||||
enum {
|
||||
C_BGT = 0b1111,
|
||||
C_BGE = 0b1110,
|
||||
C_BLT = 0b0110,
|
||||
C_BLE = 0b0111,
|
||||
|
||||
C_BH = 0b1011,
|
||||
C_BNL = 0b1001,
|
||||
C_BL = 0b0001,
|
||||
C_BNH = 0b0011,
|
||||
|
||||
C_BE = 0b0010,
|
||||
C_BNE = 0b1010,
|
||||
|
||||
C_BV = 0b000,
|
||||
C_BNV = 0b1000,
|
||||
C_BN = 0b0100,
|
||||
C_BP = 0b1100,
|
||||
C_BC = 0b0001,
|
||||
C_BNC = 0b1001,
|
||||
C_BZ = 0b0010,
|
||||
C_BNZ = 0b1010,
|
||||
C_BR = 0b0101,
|
||||
C_NOP = 0b1101,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
RzAnalysis *a;
|
||||
ut16 w1;
|
||||
ut16 w2;
|
||||
ut32 pc;
|
||||
} V810AnalysisContext;
|
||||
|
||||
RzAnalysisILConfig *v810_il_config(RzAnalysis *a);
|
||||
RzAnalysisLiftedILOp v810_il_op(const V810AnalysisContext *a);
|
||||
|
||||
#endif // RIZIN_V810_H
|
||||
@@ -0,0 +1,684 @@
|
||||
// SPDX-FileCopyrightText: 2024 billow <[email protected]>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
#include "v810.h"
|
||||
#include <rz_il/rz_il_opbuilder_begin.h>
|
||||
|
||||
static const char *registers[] = {
|
||||
"r0",
|
||||
"r1",
|
||||
"r2",
|
||||
"r3",
|
||||
"r4",
|
||||
"r5",
|
||||
"r6",
|
||||
"r7",
|
||||
"r8",
|
||||
"r9",
|
||||
"r10",
|
||||
"r11",
|
||||
"r12",
|
||||
"r13",
|
||||
"r14",
|
||||
"r15",
|
||||
"r16",
|
||||
"r17",
|
||||
"r18",
|
||||
"r19",
|
||||
"r20",
|
||||
"r21",
|
||||
"r22",
|
||||
"r23",
|
||||
"r24",
|
||||
"r25",
|
||||
"r26",
|
||||
"r27",
|
||||
"r28",
|
||||
"r29",
|
||||
"r30",
|
||||
"r31",
|
||||
"EIPC",
|
||||
"EIPSW",
|
||||
"FEPC",
|
||||
"FEPSW",
|
||||
"ECR",
|
||||
"PSW",
|
||||
"PIR",
|
||||
"TKCW",
|
||||
"Reserved_8",
|
||||
"Reserved_9",
|
||||
"Reserved_10",
|
||||
"Reserved_11",
|
||||
"Reserved_12",
|
||||
"Reserved_13",
|
||||
"Reserved_14",
|
||||
"Reserved_15",
|
||||
"Reserved_16",
|
||||
"Reserved_17",
|
||||
"Reserved_18",
|
||||
"Reserved_19",
|
||||
"Reserved_20",
|
||||
"Reserved_21",
|
||||
"Reserved_22",
|
||||
"Reserved_23",
|
||||
"CHCW",
|
||||
"ADTRE",
|
||||
"Reserved_26",
|
||||
"Reserved_27",
|
||||
"Reserved_28",
|
||||
"Reserved_29",
|
||||
"Reserved_30",
|
||||
"Reserved_31",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *GR[] = {
|
||||
"r0",
|
||||
"r1",
|
||||
"r2",
|
||||
"r3",
|
||||
"r4",
|
||||
"r5",
|
||||
"r6",
|
||||
"r7",
|
||||
"r8",
|
||||
"r9",
|
||||
"r10",
|
||||
"r11",
|
||||
"r12",
|
||||
"r13",
|
||||
"r14",
|
||||
"r15",
|
||||
"r16",
|
||||
"r17",
|
||||
"r18",
|
||||
"r19",
|
||||
"r20",
|
||||
"r21",
|
||||
"r22",
|
||||
"r23",
|
||||
"r24",
|
||||
"r25",
|
||||
"r26",
|
||||
"r27",
|
||||
"r28",
|
||||
"r29",
|
||||
"r30",
|
||||
"r31",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char **SR = registers + 32;
|
||||
|
||||
RzAnalysisILConfig *v810_il_config(RzAnalysis *a) {
|
||||
rz_return_val_if_fail(a, NULL);
|
||||
assert(RZ_STR_EQ(SR[0], "EIPC"));
|
||||
|
||||
RzAnalysisILConfig *cfg = rz_analysis_il_config_new(32, false, 32);
|
||||
cfg->reg_bindings = registers;
|
||||
return cfg;
|
||||
}
|
||||
|
||||
static inline int32_t sext32(uint32_t X, unsigned B) {
|
||||
rz_warn_if_fail(B > 0 && B <= 32);
|
||||
return (int32_t)(X << (32 - B)) >> (32 - B);
|
||||
}
|
||||
|
||||
#define COPCODE ((ctx->w1 >> 10) & 0x3F)
|
||||
#define R1 (GR[((ctx->w1) & 0x1F)])
|
||||
#define R2 (GR[(((ctx->w1) >> 5) & 0x1F)])
|
||||
#define I5 REG1((ctx->w1))
|
||||
#define I9 (ctx->w1 & 0X1FF)
|
||||
#define I16 (ctx->w2)
|
||||
#define I26 (ctx->w2 | ((ctx->w1 & 0x3ff) << 16))
|
||||
#define CCOND (((ctx->w1) >> 9) & 0xF)
|
||||
#define SUBOPC (((ctx->w2) >> 10) & 0x3F)
|
||||
|
||||
#define R1V VARG(R1)
|
||||
#define R2V VARG(R2)
|
||||
#define SEXT5 S32(sext32(I5, 5))
|
||||
#define SEXT9 S32(sext32(I9, 9))
|
||||
#define SEXT16 S32(sext32(I16, 16))
|
||||
#define SEXT26 S32(sext32(I26, 26))
|
||||
#define ZEXT5 U32(I5)
|
||||
#define ZEXT9 U32(I9)
|
||||
#define ZEXT16 U32(I16)
|
||||
#define ZEXT26 U32(I26)
|
||||
|
||||
#define R1F FLOATV32(VARG(R1))
|
||||
#define R2F FLOATV32(VARG(R2))
|
||||
|
||||
static RzILOpPure *shl0(RzILOpPure *a, RzILOpPure *b) {
|
||||
return SHIFTL0(a, b);
|
||||
}
|
||||
|
||||
static RzILOpPure *shr0(RzILOpPure *a, RzILOpPure *b) {
|
||||
return SHIFTR0(a, b);
|
||||
}
|
||||
|
||||
static RzILOpPure *fadd_(RzILOpPure *a, RzILOpPure *b) {
|
||||
return FADD(0, a, b);
|
||||
}
|
||||
|
||||
static RzILOpPure *fsub_(RzILOpPure *a, RzILOpPure *b) {
|
||||
return FSUB(0, a, b);
|
||||
}
|
||||
|
||||
static RzILOpPure *fmul_(RzILOpPure *a, RzILOpPure *b) {
|
||||
return FMUL(0, a, b);
|
||||
}
|
||||
|
||||
static RzILOpPure *fdiv_(RzILOpPure *a, RzILOpPure *b) {
|
||||
return FSUB(0, a, b);
|
||||
}
|
||||
|
||||
static RzILOpPure *bv2f32(RzILOpPure *x) {
|
||||
return FLOATV32(x);
|
||||
}
|
||||
|
||||
static RzILOpPure *f32_2int(RzILOpPure *x) {
|
||||
return F2SINT(32, 0, x);
|
||||
}
|
||||
|
||||
static RzILOpPure *f32_trunc2int(RzILOpPure *x) {
|
||||
return F2SINT(32, 0, FROUND(0, x));
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *p;
|
||||
const char *x;
|
||||
unsigned i;
|
||||
unsigned b;
|
||||
} FLG;
|
||||
|
||||
static const FLG flags[] = {
|
||||
{ "PSW", "RFU", 20, 12 },
|
||||
{ "PSW", "I3", 19, 1 },
|
||||
{ "PSW", "I2", 18, 1 },
|
||||
{ "PSW", "I1", 17, 1 },
|
||||
{ "PSW", "I0", 16, 1 },
|
||||
{ "PSW", "NP", 15, 1 },
|
||||
{ "PSW", "EP", 14, 1 },
|
||||
{ "PSW", "AE", 13, 1 },
|
||||
{ "PSW", "ID", 12, 1 },
|
||||
{ "PSW", "RFU", 10, 2 },
|
||||
{ "PSW", "FRO", 9, 1 },
|
||||
{ "PSW", "FIV", 8, 1 },
|
||||
{ "PSW", "FZD", 7, 1 },
|
||||
{ "PSW", "FOV", 6, 1 },
|
||||
{ "PSW", "FUD", 5, 1 },
|
||||
{ "PSW", "FPR", 4, 1 },
|
||||
{ "PSW", "CY", 3, 1 },
|
||||
{ "PSW", "OV", 2, 1 },
|
||||
{ "PSW", "S", 1, 1 },
|
||||
{ "PSW", "Z", 0, 1 },
|
||||
|
||||
{ "PIR", "RFU", 16, 16 },
|
||||
{ "PIR", "PT", 4, 12 },
|
||||
{ "PIR", "NECRV", 0, 4 },
|
||||
|
||||
{ "TKCW", "RFU", 9, 24 },
|
||||
{ "TKCW", "OTM", 8, 1 },
|
||||
{ "TKCW", "FIT", 7, 1 },
|
||||
{ "TKCW", "FZT", 6, 1 },
|
||||
{ "TKCW", "FVT", 5, 1 },
|
||||
{ "TKCW", "FUT", 4, 1 },
|
||||
{ "TKCW", "FPT", 3, 1 },
|
||||
{ "TKCW", "RDI", 2, 1 },
|
||||
{ "TKCW", "RD", 0, 2 },
|
||||
|
||||
{ "CHCW", "SA", 8, 25 },
|
||||
{ "CHCW", "CEN", 20, 12 },
|
||||
{ "CHCW", "CEC", 8, 12 },
|
||||
{ "CHCW", "RFU", 6, 2 },
|
||||
{ "CHCW", "ICR", 5, 1 },
|
||||
{ "CHCW", "ICD", 4, 1 },
|
||||
{ "CHCW", "RFU", 2, 2 },
|
||||
{ "CHCW", "ICE", 1, 1 },
|
||||
{ "CHCW", "ICC", 0, 1 },
|
||||
};
|
||||
|
||||
static const FLG *flag_find(const char *p, const char *x) {
|
||||
for (int i = 0; i < RZ_ARRAY_SIZE(flags); ++i) {
|
||||
const FLG *f = flags + i;
|
||||
if (RZ_STR_NE(p, f->p)) {
|
||||
continue;
|
||||
}
|
||||
if (RZ_STR_NE(x, f->x)) {
|
||||
continue;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static RzILOpPure *VARGb(const char *p, const char *x) {
|
||||
const FLG *f = flag_find(p, x);
|
||||
if (!f) {
|
||||
rz_warn_if_reached();
|
||||
return NULL;
|
||||
}
|
||||
RzILOpPure *y = LET("_v_parent", VARG(p),
|
||||
LOGAND(shr0(VARLP("_v_parent"), U32(f->i)), U32(f->b)));
|
||||
if (f->b == 1) {
|
||||
y = LET("_v_part", y,
|
||||
NON_ZERO(VARLP("_v_part")));
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
static RzILOpEffect *SETGbs(const char *p, unsigned n, ...) {
|
||||
va_list args;
|
||||
va_start(args, n);
|
||||
|
||||
RzILOpPure *expr = NULL;
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
const char *x = va_arg(args, const char *);
|
||||
RzILOpPure *y = va_arg(args, RzILOpPure *);
|
||||
|
||||
const FLG *f = flag_find(p, x);
|
||||
if (!f) {
|
||||
rz_warn_if_reached();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RzILOpPure *v = shl0(f->b == 1 ? BOOL_TO_BV(y, 32) : y, U32(f->i));
|
||||
expr = !expr ? v : LOGOR(expr, v);
|
||||
}
|
||||
return SETG(p, expr);
|
||||
}
|
||||
|
||||
#define SETGb(p, ...) SETGbs(p, 1, __VA_ARGS__)
|
||||
|
||||
static RzILOpPure *overflow(RzILOpPure *x) {
|
||||
return LET("_x", x,
|
||||
OR(
|
||||
SGT(VARLP("_x"), S32(+0x7fffffff)),
|
||||
SLT(VARLP("_x"), S32(-0x80000000))));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp flags_update(const V810AnalysisContext *ctx) {
|
||||
switch (COPCODE) {
|
||||
case V810_NOT:
|
||||
case V810_DIVU:
|
||||
case V810_AND:
|
||||
case V810_OR:
|
||||
case V810_ORI:
|
||||
case V810_XOR:
|
||||
case V810_XORI:
|
||||
return SETGbs("PSW", 3,
|
||||
"OV", IL_FALSE,
|
||||
"S", SLT(R2V, S32(0)),
|
||||
"Z", IS_ZERO(R2V));
|
||||
case V810_ANDI:
|
||||
return SETGbs("PSW", 3,
|
||||
"OV", IL_FALSE,
|
||||
"S", IL_FALSE,
|
||||
"Z", IS_ZERO(R2V));
|
||||
|
||||
case V810_DIV:
|
||||
case V810_MUL:
|
||||
case V810_MULU:
|
||||
return SETGbs("PSW", 3,
|
||||
"OV", overflow(R2V),
|
||||
"S", SLT(R2V, S32(0)),
|
||||
"Z", IS_ZERO(R2V));
|
||||
|
||||
case V810_CMP_IMM5:
|
||||
return SETGbs("PSW", 4,
|
||||
"CY", SLT(R2V, SEXT5),
|
||||
"OV", overflow(VARL("result")),
|
||||
"S", SLT(VARL("result"), S32(0)),
|
||||
"Z", IS_ZERO(VARL("result")));
|
||||
case V810_CMP:
|
||||
case V810_SUB:
|
||||
return SETGbs("PSW", 4,
|
||||
"CY", SLT(R2V, R1V),
|
||||
"OV", overflow(VARL("result")),
|
||||
"S", SLT(VARL("result"), S32(0)),
|
||||
"Z", IS_ZERO(VARL("result")));
|
||||
case V810_ADD:
|
||||
return SETGbs("PSW", 4,
|
||||
"CY", OR(SLT(VARL("result"), R2V), SLT(VARL("result"), R1V)),
|
||||
"OV", overflow(VARL("result")),
|
||||
"S", SLT(VARL("result"), S32(0)),
|
||||
"Z", IS_ZERO(VARL("result")));
|
||||
case V810_ADD_IMM5:
|
||||
return SETGbs("PSW", 4,
|
||||
"CY", OR(SLT(VARL("result"), R2V), SLT(VARL("result"), SEXT5)),
|
||||
"OV", overflow(VARL("result")),
|
||||
"S", SLT(VARL("result"), S32(0)),
|
||||
"Z", IS_ZERO(VARL("result")));
|
||||
case V810_ADDI:
|
||||
return SETGbs("PSW", 4,
|
||||
"CY", OR(SLT(VARL("result"), SEXT16), SLT(VARL("result"), R1V)),
|
||||
"OV", overflow(VARL("result")),
|
||||
"S", SLT(VARL("result"), S32(0)),
|
||||
"Z", IS_ZERO(VARL("result")));
|
||||
case V810_SAR:
|
||||
case V810_SHR:
|
||||
return SETGbs("PSW", 3,
|
||||
"CY", AND(NON_ZERO(ZEXT5), NON_ZERO(LOGAND(R2V, SUB(shl0(U32(1), ZEXT5), U32(1))))),
|
||||
"S", SLT(VARL("result"), S32(0)),
|
||||
"Z", IS_ZERO(VARL("result")));
|
||||
case V810_SAR_IMM5:
|
||||
case V810_SHR_IMM5:
|
||||
return SETGbs("PSW", 3,
|
||||
"CY", AND(NON_ZERO(R1V), NON_ZERO(LOGAND(R2V, SUB(shl0(U32(1), R1V), U32(1))))),
|
||||
"S", SLT(VARL("result"), S32(0)),
|
||||
"Z", IS_ZERO(VARL("result")));
|
||||
|
||||
case V810_SHL:
|
||||
return SETGbs("PSW", 3,
|
||||
"CY", AND(NON_ZERO(ZEXT5), NON_ZERO(shr0(R2V, SUB(U32(32), R1V)))),
|
||||
"S", SLT(VARL("result"), S32(0)),
|
||||
"Z", IS_ZERO(VARL("result")));
|
||||
case V810_SHL_IMM5:
|
||||
return SETGbs("PSW", 3,
|
||||
"CY", AND(NON_ZERO(ZEXT5), NON_ZERO(shr0(R2V, SUB(U32(32), ZEXT5)))),
|
||||
"S", SLT(VARL("result"), S32(0)),
|
||||
"Z", IS_ZERO(VARL("result")));
|
||||
case V810_CAXI:
|
||||
return SETGbs("PSW", 4,
|
||||
"CY", SLT(R2V, R1V),
|
||||
"OV", overflow(VARL("result")),
|
||||
"S", SLT(VARL("result"), S32(0)),
|
||||
"Z", IS_ZERO(VARL("result")));
|
||||
case V810_EXT: {
|
||||
switch (SUBOPC) {
|
||||
case V810_EXT_CMPF_S: return SETGbs("PSW", 4,
|
||||
"OV", IL_FALSE,
|
||||
"S", SLT(VARL("result"), S32(0)),
|
||||
"Z", IS_ZERO(VARL("result")),
|
||||
"FRO", LET("_x", R2F, OR(IS_FNAN(VARLP("_x")), IS_FINF(VARLP("_x")))) // TODO: denormal number
|
||||
// "FPR", // 1 if degradation in precision is detected; otherwise, not affected
|
||||
);
|
||||
case V810_EXT_CVT_WS: return SETGbs("PSW", 5,
|
||||
"CY", INV(IS_FPOS(R2F)),
|
||||
"OV", IL_FALSE,
|
||||
"S", FLT(R2F, F32(0)),
|
||||
"Z", IS_ZERO(R2F),
|
||||
"FRO", LET("_x", R2F, OR(IS_FNAN(VARLP("_x")), IS_FINF(VARLP("_x")))) // TODO: denormal number
|
||||
// "FPR", // TODO: 1 if degradation in precision is detected; otherwise, not affected
|
||||
);
|
||||
case V810_EXT_CVT_SW: return SETGbs("PSW", 3,
|
||||
"OV", IL_FALSE,
|
||||
"S", SLT(R2V, S32(0)),
|
||||
"Z", IS_ZERO(R2V)
|
||||
// "FRO", LET("_x", R2V, OR(IS_FNAN(VARLP("_x")), IS_FINF(VARLP("_x")))) // TODO: denormal number
|
||||
// ,"FIV",// TODO: invalid operation occurs
|
||||
// "FPR", // TODO: 1 if degradation in precision is detected; otherwise, not affected
|
||||
);
|
||||
case V810_EXT_ADDF_S:
|
||||
case V810_EXT_SUBF_S:
|
||||
case V810_EXT_MULF_S:
|
||||
case V810_EXT_DIVF_S: return SETGbs("PSW", 6,
|
||||
"CY", INV(IS_FPOS(VARL("result"))),
|
||||
"OV", IL_FALSE,
|
||||
"S", FLT(VARL("result"), F32(0)),
|
||||
"Z", IS_FZERO(VARL("result")),
|
||||
"FRO", OR(IS_FNAN(VARL("result")), IS_FINF(VARL("result"))) // TODO: denormal number
|
||||
// ,"FIV",// TODO: invalid operation occurs
|
||||
,
|
||||
"FZD", IS_FZERO(R1F)
|
||||
// "FOV", // TODO: 1 if result of operation is greater than maximum normalized number that can be expressed;
|
||||
// "FUD", // TODO: if result of operation is less than minimum (absolute value) normalized number that can be expressed;
|
||||
// "FPR", // TODO: 1 if degradation in precision is detected; otherwise, not affected
|
||||
);
|
||||
case V810_EXT_XB:
|
||||
case V810_EXT_XH:
|
||||
case V810_EXT_REV: return NOP();
|
||||
case V810_EXT_TRNC_SW: return SETGbs("PSW", 4,
|
||||
"OV", IL_FALSE,
|
||||
"S", FLT(FLOATV32(VARL("result")), F32(0)),
|
||||
"Z", IS_FZERO(FLOATV32(VARL("result"))),
|
||||
"FRO", LET("_x", FLOATV32(VARL("result")), OR(IS_FNAN(VARLP("_x")), IS_FINF(VARLP("_x")))) // TODO: denormal number
|
||||
// ,"FIV",// TODO: invalid operation occurs
|
||||
// "FPR", // TODO: 1 if degradation in precision is detected; otherwise, not affected
|
||||
);
|
||||
case V810_EXT_MPYHW:
|
||||
default:
|
||||
return NOP();
|
||||
}
|
||||
}
|
||||
default:
|
||||
return NOP();
|
||||
}
|
||||
}
|
||||
|
||||
typedef RzILOpPure *(*F_OP1)(RzILOpPure *);
|
||||
typedef RzILOpPure *(*F_OP2)(RzILOpPure *, RzILOpPure *);
|
||||
|
||||
static RzAnalysisLiftedILOp lift_mov(const V810AnalysisContext *ctx, RzILOpPure *x0) {
|
||||
return SETG(R2, x0);
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp lift_op1(const V810AnalysisContext *ctx, RzILOpPure *x0, F_OP1 f) {
|
||||
return SEQ2(
|
||||
SETG(R2, f(x0)),
|
||||
flags_update(ctx));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp lift_op2(const V810AnalysisContext *ctx, RzILOpPure *x0, RzILOpPure *x1, F_OP2 f) {
|
||||
return SEQ3(
|
||||
SETL("result", f(x0, x1)),
|
||||
flags_update(ctx),
|
||||
SETG(R2, VARL("result")));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp lift_fop1(const V810AnalysisContext *ctx, RzILOpPure *x0, F_OP1 f) {
|
||||
return SEQ2(
|
||||
SETG(R2, F2BV(f(x0))),
|
||||
flags_update(ctx));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp lift_fop2(const V810AnalysisContext *ctx, RzILOpPure *x0, RzILOpPure *x1, F_OP2 f) {
|
||||
return SEQ3(
|
||||
SETL("result", f(x0, x1)),
|
||||
flags_update(ctx),
|
||||
SETG(R2, F2BV(VARL("result"))));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp lift_div(const V810AnalysisContext *ctx, RzILOpPure *x0, RzILOpPure *x1) {
|
||||
return SEQ3(
|
||||
SETG(R2, DIV(x0, x1)),
|
||||
SETG(GR[30], MOD(DUP(x0), DUP(x1))),
|
||||
flags_update(ctx));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp lift_mul(const V810AnalysisContext *ctx, RzILOpPure *x0, RzILOpPure *x1) {
|
||||
return SEQ4(
|
||||
SETL("result", MUL(SIGNED(64, x0), SIGNED(64, x1))),
|
||||
SETG(R2, UNSIGNED(32, VARL("result"))),
|
||||
SETG(GR[30], UNSIGNED(32, shr0(VARL("result"), U32(32)))),
|
||||
flags_update(ctx));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp lift_mulu(const V810AnalysisContext *ctx, RzILOpPure *x0, RzILOpPure *x1) {
|
||||
return SEQ4(
|
||||
SETL("result", MUL(UNSIGNED(64, x0), UNSIGNED(64, x1))),
|
||||
SETG(R2, UNSIGNED(32, VARL("result"))),
|
||||
SETG(GR[30], UNSIGNED(32, shr0(VARL("result"), U32(32)))),
|
||||
flags_update(ctx));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp lift_cmp(const V810AnalysisContext *ctx, RzILOpPure *x0, RzILOpPure *x1, F_OP2 f) {
|
||||
return SEQ2(
|
||||
SETL("result", f(x0, x1)),
|
||||
flags_update(ctx));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp lift_ld(const V810AnalysisContext *ctx, RzILOpPure *addr, unsigned B) {
|
||||
RzILOpPure *y = LOADW(B, VARL("_adr"));
|
||||
if (B == 8 || B == 16) {
|
||||
y = LET("_v", UNSIGNED(32, y), SEXTRACT32(VARLP("_v"), U32(0), U32(B)));
|
||||
} else {
|
||||
rz_warn_if_fail(B == 32);
|
||||
}
|
||||
return SEQ2(
|
||||
SETL("_adr", addr),
|
||||
SETG(R2, y));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp lift_st(const V810AnalysisContext *ctx, RzILOpPure *addr, unsigned B) {
|
||||
RzILOpPure *y = R2V;
|
||||
if (B == 8 || B == 16) {
|
||||
y = UNSIGNED(B, y);
|
||||
} else {
|
||||
rz_warn_if_fail(B == 32);
|
||||
}
|
||||
return SEQ2(
|
||||
SETL("_adr", addr),
|
||||
STOREW(VARL("_adr"), y));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp lift_reti(const V810AnalysisContext *ctx) {
|
||||
return SEQ3(
|
||||
SETL("_pc", ITE(VARGb("PSW", "NP"), VARG("FEPC"), VARG("EIPC"))),
|
||||
SETL("PSW", ITE(VARGb("PSW", "NP"), VARG("FEPSW"), VARG("EIPSW"))),
|
||||
JMP(VARL("_pc")));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp lift_jal(const V810AnalysisContext *ctx) {
|
||||
return SEQ3(
|
||||
SETG(GR[31], ADD(U32(ctx->pc), U32(4))),
|
||||
SETL("_pc", ADD(U32(ctx->pc), SEXT26)),
|
||||
JMP(VARL("_pc")));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp lift_jr(const V810AnalysisContext *ctx) {
|
||||
return SEQ2(
|
||||
SETL("_pc", ADD(S32(ctx->pc), SEXT26)),
|
||||
JMP(VARL("_pc")));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp lift_caxi(const V810AnalysisContext *ctx) {
|
||||
return SEQ5(
|
||||
SETL("_adr", ADD(R1V, SEXT16)),
|
||||
SETL("_tmp", LOADW(32, VARL("_adr"))),
|
||||
SETL("result", SUB(R2V, VARL("_tmp"))),
|
||||
flags_update(ctx),
|
||||
BRANCH(IS_ZERO(VARL("result")),
|
||||
SEQ2(
|
||||
STOREW(VARL("_adr"), VARG(GR[30])),
|
||||
SETG(R2, VARL("_tmp"))),
|
||||
SEQ2(
|
||||
STOREW(VARL("_adr"), VARL("_tmp")),
|
||||
SETG(R2, VARL("_tmp")))));
|
||||
}
|
||||
|
||||
static RzAnalysisLiftedILOp lift_bcond(const V810AnalysisContext *ctx, RzILOpPure *cond) {
|
||||
return BRANCH(cond, SEQ2(SETL("_pc", ADD(S32(ctx->pc), SEXT9)), JMP(VARL("_pc"))), NOP());
|
||||
}
|
||||
|
||||
RzAnalysisLiftedILOp v810_il_op(const V810AnalysisContext *ctx) {
|
||||
switch (COPCODE) {
|
||||
case V810_MOV: return lift_mov(ctx, R1V);
|
||||
case V810_MOV_IMM5: return lift_mov(ctx, SEXT5);
|
||||
case V810_MOVHI: return lift_mov(ctx, ADD(R1V, shl0(ZEXT16, U32(16))));
|
||||
case V810_MOVEA: return lift_mov(ctx, ADD(R1V, SEXT16));
|
||||
case V810_LDSR: return SETG(SR[I5], R2V);
|
||||
case V810_STSR: return SETG(R2, VARG(SR[I5]));
|
||||
case V810_NOT: return lift_op1(ctx, R1V, rz_il_op_new_log_not);
|
||||
case V810_DIV:
|
||||
case V810_DIVU: return lift_div(ctx, R2V, R1V);
|
||||
case V810_OR: return lift_op2(ctx, R2V, R1V, rz_il_op_new_log_or);
|
||||
case V810_ORI: return lift_op2(ctx, R2V, ZEXT16, rz_il_op_new_log_or);
|
||||
case V810_MUL: return lift_mul(ctx, R2V, R1V);
|
||||
case V810_MULU: return lift_mulu(ctx, R2V, R1V);
|
||||
case V810_XOR: return lift_op2(ctx, R2V, R1V, rz_il_op_new_log_xor);
|
||||
case V810_XORI: return lift_op2(ctx, R2V, ZEXT16, rz_il_op_new_log_xor);
|
||||
case V810_AND: return lift_op2(ctx, R2V, R1V, rz_il_op_new_log_and);
|
||||
case V810_ANDI: return lift_op2(ctx, R2V, ZEXT16, rz_il_op_new_log_and);
|
||||
case V810_CMP: return lift_cmp(ctx, R2V, R1V, rz_il_op_new_sub);
|
||||
case V810_CMP_IMM5: return lift_cmp(ctx, R2V, SEXT5, rz_il_op_new_sub);
|
||||
case V810_SUB: return lift_op2(ctx, R2V, R1V, rz_il_op_new_sub);
|
||||
case V810_ADD: return lift_op2(ctx, R2V, R1V, rz_il_op_new_add);
|
||||
case V810_ADDI: return lift_op2(ctx, R1V, SEXT16, rz_il_op_new_add);
|
||||
case V810_ADD_IMM5: return lift_op2(ctx, R2V, SEXT5, rz_il_op_new_add);
|
||||
case V810_SHR: return lift_op2(ctx, R2V, R1V, shr0);
|
||||
case V810_SHR_IMM5: return lift_op2(ctx, R2V, ZEXT5, shr0);
|
||||
case V810_SAR: return lift_op2(ctx, R2V, R1V, rz_il_op_new_shiftr_arith);
|
||||
case V810_SAR_IMM5: return lift_op2(ctx, R2V, ZEXT5, rz_il_op_new_shiftr_arith);
|
||||
case V810_SHL: return lift_op2(ctx, R2V, R1V, shl0);
|
||||
case V810_SHL_IMM5: return lift_op2(ctx, R2V, ZEXT5, shl0);
|
||||
|
||||
case V810_INB:
|
||||
case V810_LDB: return lift_ld(ctx, ADD(R1V, SEXT16), 8);
|
||||
case V810_INH:
|
||||
case V810_LDH: return lift_ld(ctx, ADD(R1V, SEXT16), 16);
|
||||
case V810_INW:
|
||||
case V810_LDW: return lift_ld(ctx, ADD(R1V, SEXT16), 32);
|
||||
|
||||
case V810_OUTB:
|
||||
case V810_STB: return lift_st(ctx, ADD(R1V, SEXT16), 8);
|
||||
case V810_OUTH:
|
||||
case V810_STH: return lift_st(ctx, ADD(R1V, SEXT16), 16);
|
||||
case V810_OUTW:
|
||||
case V810_STW: return lift_st(ctx, ADD(R1V, SEXT16), 32);
|
||||
|
||||
case V810_HALT:
|
||||
case V810_TRAP: return NOP();
|
||||
case V810_RETI: return lift_reti(ctx);
|
||||
case V810_JMP: return JMP(LOGAND(R1V, U32(0xfffffffe)));
|
||||
case V810_JAL: return lift_jal(ctx);
|
||||
case V810_JR: return lift_jr(ctx);
|
||||
case V810_CLI:
|
||||
case V810_SEI: return NOP();
|
||||
case V810_CAXI: return lift_caxi(ctx);
|
||||
case V810_EXT: {
|
||||
switch (SUBOPC) {
|
||||
case V810_EXT_CMPF_S: return lift_cmp(ctx, R2F, R1F, fsub_);
|
||||
case V810_EXT_CVT_WS: return lift_fop1(ctx, R1V, bv2f32);
|
||||
case V810_EXT_CVT_SW: return lift_op1(ctx, R1F, f32_2int);
|
||||
case V810_EXT_ADDF_S: return lift_fop2(ctx, R2F, R1F, fadd_);
|
||||
case V810_EXT_SUBF_S: return lift_fop2(ctx, R2F, R1F, fsub_);
|
||||
case V810_EXT_MULF_S: return lift_fop2(ctx, R2F, R1F, fmul_);
|
||||
case V810_EXT_DIVF_S: return lift_fop2(ctx, R2F, R1F, fdiv_);
|
||||
case V810_EXT_XB:
|
||||
case V810_EXT_XH:
|
||||
case V810_EXT_REV: return NOP();
|
||||
case V810_EXT_TRNC_SW: return lift_fop1(ctx, R1V, f32_trunc2int);
|
||||
case V810_EXT_MPYHW: return NOP();
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (COPCODE >> 3 == 4) {
|
||||
RzILOpPure *cnd = NULL;
|
||||
switch (CCOND) {
|
||||
case C_BGT: cnd = INV(OR(XOR(VARGb("PSW", "S"), VARGb("PSW", "OV")), VARGb("PSW", "Z"))); break;
|
||||
case C_BGE: cnd = INV(XOR(VARGb("PSW", "S"), VARGb("PSW", "OV"))); break;
|
||||
case C_BLT: cnd = XOR(VARGb("PSW", "S"), VARGb("PSW", "OV")); break;
|
||||
case C_BLE: cnd = OR(XOR(VARGb("PSW", "S"), VARGb("PSW", "OV")), VARGb("PSW", "Z")); break;
|
||||
|
||||
case C_BH: cnd = INV(OR(VARGb("PSW", "CY"), VARGb("PSW", "Z"))); break;
|
||||
case C_BNL: cnd = INV(VARGb("PSW", "CY")); break;
|
||||
case C_BL: cnd = VARGb("PSW", "CY"); break;
|
||||
case C_BNH: cnd = OR(VARGb("PSW", "CY"), VARGb("PSW", "Z")); break;
|
||||
|
||||
case C_BE: cnd = VARGb("PSW", "Z"); break;
|
||||
case C_BNE: cnd = INV(VARGb("PSW", "Z")); break;
|
||||
|
||||
case C_BV: cnd = VARGb("PSW", "OV"); break;
|
||||
case C_BNV: cnd = INV(VARGb("PSW", "OV")); break;
|
||||
case C_BN: cnd = VARGb("PSW", "S"); break;
|
||||
case C_BP: cnd = INV(VARGb("PSW", "S")); break;
|
||||
// case C_BC: break;
|
||||
// case C_BNC: break;
|
||||
// case C_BZ: break;
|
||||
// case C_BNZ: break;
|
||||
case C_BR: cnd = IL_TRUE; break;
|
||||
case C_NOP: cnd = IL_FALSE; break;
|
||||
default: break;
|
||||
}
|
||||
return lift_bcond(ctx, cnd);
|
||||
}
|
||||
break;
|
||||
}
|
||||
rz_warn_if_reached();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#include <rz_il/rz_il_opbuilder_end.h>
|
||||
@@ -170,6 +170,7 @@ rz_analysis_sources = [
|
||||
'arch/x86/x86_il.c',
|
||||
'arch/8051/8051_il.c',
|
||||
'arch/8051/8051_parse.c',
|
||||
'arch/v810/v810_il.c',
|
||||
'../asm/arch/amd29k/amd29k.c',
|
||||
'../asm/arch/avr/disassembler.c',
|
||||
'../asm/arch/cil/cil_dis.c',
|
||||
|
||||
+357
-238
@@ -8,7 +8,7 @@
|
||||
#include <rz_analysis.h>
|
||||
#include <rz_util.h>
|
||||
|
||||
#include <v810_disas.h>
|
||||
#include "../arch/v810/v810.h"
|
||||
|
||||
enum {
|
||||
V810_FLAG_CY = 1,
|
||||
@@ -17,41 +17,305 @@ enum {
|
||||
V810_FLAG_Z = 8,
|
||||
};
|
||||
|
||||
static void update_flags(RzAnalysisOp *op, int flags) {
|
||||
static void update_flags(RzStrBuf *out, int flags) {
|
||||
if (flags & V810_FLAG_CY) {
|
||||
rz_strbuf_append(&op->esil, ",31,$c,cy,:=");
|
||||
rz_strbuf_append(out, ",31,$c,cy,:=");
|
||||
}
|
||||
if (flags & V810_FLAG_OV) {
|
||||
rz_strbuf_append(&op->esil, ",31,$o,ov,:=");
|
||||
rz_strbuf_append(out, ",31,$o,ov,:=");
|
||||
}
|
||||
if (flags & V810_FLAG_S) {
|
||||
rz_strbuf_append(&op->esil, ",31,$s,s,:=");
|
||||
rz_strbuf_append(out, ",31,$s,s,:=");
|
||||
}
|
||||
if (flags & V810_FLAG_Z) {
|
||||
rz_strbuf_append(&op->esil, ",$z,z,:=");
|
||||
rz_strbuf_append(out, ",$z,z,:=");
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_flags(RzAnalysisOp *op, int flags) {
|
||||
static void clear_flags(RzStrBuf *out, int flags) {
|
||||
if (flags & V810_FLAG_CY) {
|
||||
rz_strbuf_append(&op->esil, ",0,cy,:=");
|
||||
rz_strbuf_append(out, ",0,cy,:=");
|
||||
}
|
||||
if (flags & V810_FLAG_OV) {
|
||||
rz_strbuf_append(&op->esil, ",0,ov,:=");
|
||||
rz_strbuf_append(out, ",0,ov,:=");
|
||||
}
|
||||
if (flags & V810_FLAG_S) {
|
||||
rz_strbuf_append(&op->esil, ",0,s,:=");
|
||||
rz_strbuf_append(out, ",0,s,:=");
|
||||
}
|
||||
if (flags & V810_FLAG_Z) {
|
||||
rz_strbuf_append(&op->esil, ",0,z,:=");
|
||||
rz_strbuf_append(out, ",0,z,:=");
|
||||
}
|
||||
}
|
||||
|
||||
static void v810_esil(RzStrBuf *out, ut8 opcode, ut16 word1, ut16 word2) {
|
||||
ut8 reg1 = 0, reg2 = 0, imm5 = 0, cond = 0;
|
||||
switch (opcode) {
|
||||
case V810_MOV:
|
||||
rz_strbuf_appendf(out, "r%u,r%u,=",
|
||||
REG1(word1), REG2(word1));
|
||||
break;
|
||||
case V810_MOV_IMM5:
|
||||
rz_strbuf_appendf(out, "%d,r%u,=",
|
||||
(st8)SIGN_EXT_T5(IMM5(word1)), REG2(word1));
|
||||
break;
|
||||
case V810_MOVHI:
|
||||
rz_strbuf_appendf(out, "16,%hu,<<,r%u,+,r%u,=",
|
||||
word2, REG1(word1), REG2(word1));
|
||||
break;
|
||||
case V810_MOVEA:
|
||||
rz_strbuf_appendf(out, "%hd,r%u,+,r%u,=",
|
||||
word2, REG1(word1), REG2(word1));
|
||||
break;
|
||||
case V810_LDSR:
|
||||
case V810_STSR:
|
||||
break;
|
||||
case V810_NOT:
|
||||
rz_strbuf_appendf(out, "r%u,0xffffffff,^,r%u,=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(out, V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(out, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_DIV:
|
||||
case V810_DIVU:
|
||||
rz_strbuf_appendf(out, "r%u,r%u,/=,r%u,r%u,%%,r30,=",
|
||||
REG1(word1), REG2(word1),
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(out, V810_FLAG_OV | V810_FLAG_S | V810_FLAG_Z);
|
||||
break;
|
||||
case V810_JMP:
|
||||
rz_strbuf_appendf(out, "r%u,pc,=",
|
||||
REG1(word1));
|
||||
break;
|
||||
case V810_OR:
|
||||
rz_strbuf_appendf(out, "r%u,r%u,|=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(out, V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(out, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_ORI:
|
||||
rz_strbuf_appendf(out, "%hu,r%u,|,r%u,=",
|
||||
word2, REG1(word1), REG2(word1));
|
||||
update_flags(out, V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(out, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_MUL:
|
||||
case V810_MULU:
|
||||
rz_strbuf_appendf(out, "r%u,r%u,*=,32,r%u,r%u,*,>>,r30,=",
|
||||
REG1(word1), REG2(word1),
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(out, V810_FLAG_OV | V810_FLAG_S | V810_FLAG_Z);
|
||||
break;
|
||||
case V810_XOR:
|
||||
rz_strbuf_appendf(out, "r%u,r%u,^=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(out, V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(out, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_XORI:
|
||||
rz_strbuf_appendf(out, "%hu,r%u,^,r%u,=",
|
||||
word2, REG1(word1), REG2(word1));
|
||||
update_flags(out, V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(out, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_AND:
|
||||
rz_strbuf_appendf(out, "r%u,r%u,&=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(out, V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(out, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_ANDI:
|
||||
rz_strbuf_appendf(out, "%hu,r%u,&,r%u,=",
|
||||
word2, REG1(word1), REG2(word1));
|
||||
update_flags(out, V810_FLAG_Z);
|
||||
clear_flags(out, V810_FLAG_OV | V810_FLAG_S);
|
||||
break;
|
||||
case V810_CMP:
|
||||
rz_strbuf_appendf(out, "r%u,r%u,==",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(out, -1);
|
||||
break;
|
||||
case V810_CMP_IMM5:
|
||||
rz_strbuf_appendf(out, "%d,r%u,==",
|
||||
(st8)SIGN_EXT_T5(IMM5(word1)), REG2(word1));
|
||||
update_flags(out, -1);
|
||||
break;
|
||||
case V810_SUB:
|
||||
rz_strbuf_appendf(out, "r%u,r%u,-=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(out, -1);
|
||||
break;
|
||||
case V810_ADD:
|
||||
rz_strbuf_appendf(out, "r%u,r%u,+=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(out, -1);
|
||||
break;
|
||||
case V810_ADDI:
|
||||
rz_strbuf_appendf(out, "%hd,r%u,+,r%u,=",
|
||||
word2, REG1(word1), REG2(word1));
|
||||
update_flags(out, -1);
|
||||
break;
|
||||
case V810_ADD_IMM5:
|
||||
rz_strbuf_appendf(out, "%d,r%u,+=",
|
||||
(st8)SIGN_EXT_T5(IMM5(word1)), REG2(word1));
|
||||
update_flags(out, -1);
|
||||
break;
|
||||
case V810_SHR:
|
||||
rz_strbuf_appendf(out, "r%u,r%u,>>=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(out, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(out, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_SHR_IMM5:
|
||||
rz_strbuf_appendf(out, "%u,r%u,>>=",
|
||||
(ut8)IMM5(word1), REG2(word1));
|
||||
update_flags(out, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(out, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_SAR:
|
||||
reg1 = REG1(word1);
|
||||
reg2 = REG2(word1);
|
||||
rz_strbuf_appendf(out, "31,r%u,>>,?{,r%u,32,-,r%u,1,<<,--,<<,}{,0,},r%u,r%u,>>,|,r%u,=",
|
||||
reg2, reg1, reg1, reg1, reg2, reg2);
|
||||
update_flags(out, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(out, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_SAR_IMM5:
|
||||
imm5 = IMM5(word1);
|
||||
reg2 = REG2(word1);
|
||||
rz_strbuf_appendf(out, "31,r%u,>>,?{,%u,32,-,%u,1,<<,--,<<,}{,0,},%u,r%u,>>,|,r%u,=",
|
||||
reg2, (ut8)imm5, (ut8)imm5, (ut8)imm5, reg2, reg2);
|
||||
update_flags(out, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(out, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_SHL:
|
||||
rz_strbuf_appendf(out, "r%u,r%u,<<=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(out, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(out, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_SHL_IMM5:
|
||||
rz_strbuf_appendf(out, "%u,r%u,<<=",
|
||||
(ut8)IMM5(word1), REG2(word1));
|
||||
update_flags(out, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(out, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_LDB:
|
||||
rz_strbuf_appendf(out, "r%u,%hd,+,[1],r%u,=",
|
||||
REG1(word1), word2, REG2(word1));
|
||||
rz_strbuf_appendf(out, ",DUP,0x80,&,?{,0xffffff00,|,}");
|
||||
break;
|
||||
case V810_LDH:
|
||||
rz_strbuf_appendf(out, "r%u,%hd,+,0xfffffffe,&,[2],r%u,=",
|
||||
REG1(word1), word2, REG2(word1));
|
||||
rz_strbuf_appendf(out, ",DUP,0x8000,&,?{,0xffffff00,|,}");
|
||||
break;
|
||||
case V810_LDW:
|
||||
rz_strbuf_appendf(out, "r%u,%hd,+,0xfffffffc,&,[4],r%u,=",
|
||||
REG1(word1), word2, REG2(word1));
|
||||
rz_strbuf_appendf(out, ",DUP,0x80000000,&,?{,0xffffff00,|,}");
|
||||
break;
|
||||
case V810_STB:
|
||||
rz_strbuf_appendf(out, "r%u,r%u,%hd,+,=[1]",
|
||||
REG2(word1), REG1(word1), word2);
|
||||
break;
|
||||
case V810_STH:
|
||||
rz_strbuf_appendf(out, "r%u,r%u,%hd,+,0xfffffffe,&,=[2]",
|
||||
REG2(word1), REG1(word1), word2);
|
||||
break;
|
||||
case V810_STW:
|
||||
rz_strbuf_appendf(out, "r%u,r%u,%hd,+,=[4]",
|
||||
REG2(word1), REG1(word1), word2);
|
||||
break;
|
||||
case V810_INB:
|
||||
case V810_INH:
|
||||
case V810_INW:
|
||||
case V810_OUTB:
|
||||
case V810_OUTH:
|
||||
case V810_OUTW:
|
||||
break;
|
||||
case V810_TRAP:
|
||||
rz_strbuf_appendf(out, "%u,TRAP", IMM5(word1));
|
||||
break;
|
||||
case V810_RETI:
|
||||
// rz_strbuf_appendf (out, "np,?{,fepc,fepsw,}{,eipc,eipsw,},psw,=,pc,=");
|
||||
break;
|
||||
case V810_JAL:
|
||||
case V810_JR: {
|
||||
st32 jumpdisp = DISP26(word1, word2);
|
||||
if (opcode == V810_JAL) {
|
||||
rz_strbuf_appendf(out, "$$,4,+,r31,=,");
|
||||
}
|
||||
rz_strbuf_appendf(out, "$$,%d,+,pc,=", jumpdisp);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (OPCODE(word1) >> 3 == 4) {
|
||||
cond = COND(word1);
|
||||
if (cond == V810_COND_NOP) {
|
||||
break;
|
||||
}
|
||||
|
||||
st32 jumpdisp = DISP9(word1);
|
||||
switch (cond) {
|
||||
case V810_COND_V:
|
||||
rz_strbuf_appendf(out, "ov");
|
||||
break;
|
||||
case V810_COND_L:
|
||||
rz_strbuf_appendf(out, "cy");
|
||||
break;
|
||||
case V810_COND_E:
|
||||
rz_strbuf_appendf(out, "z");
|
||||
break;
|
||||
case V810_COND_NH:
|
||||
rz_strbuf_appendf(out, "cy,z,|");
|
||||
break;
|
||||
case V810_COND_N:
|
||||
rz_strbuf_appendf(out, "s");
|
||||
break;
|
||||
case V810_COND_NONE:
|
||||
rz_strbuf_appendf(out, "1");
|
||||
break;
|
||||
case V810_COND_LT:
|
||||
rz_strbuf_appendf(out, "s,ov,^");
|
||||
break;
|
||||
case V810_COND_LE:
|
||||
rz_strbuf_appendf(out, "s,ov,^,z,|");
|
||||
break;
|
||||
case V810_COND_NV:
|
||||
rz_strbuf_appendf(out, "ov,!");
|
||||
break;
|
||||
case V810_COND_NL:
|
||||
rz_strbuf_appendf(out, "cy,!");
|
||||
break;
|
||||
case V810_COND_NE:
|
||||
rz_strbuf_appendf(out, "z,!");
|
||||
break;
|
||||
case V810_COND_H:
|
||||
rz_strbuf_appendf(out, "cy,z,|,!");
|
||||
break;
|
||||
case V810_COND_P:
|
||||
rz_strbuf_appendf(out, "s,!");
|
||||
break;
|
||||
case V810_COND_GE:
|
||||
rz_strbuf_appendf(out, "s,ov,^,!");
|
||||
break;
|
||||
case V810_COND_GT:
|
||||
rz_strbuf_appendf(out, "s,ov,^,z,|,!");
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
rz_strbuf_appendf(out, ",?{,$$,%d,+,pc,=,}", jumpdisp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int v810_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask) {
|
||||
int ret;
|
||||
ut8 opcode, reg1, reg2, imm5, cond;
|
||||
ut16 word1, word2 = 0;
|
||||
st32 jumpdisp;
|
||||
int ret = 0;
|
||||
ut8 opcode = 0, cond = 0;
|
||||
ut16 word1 = 0, word2 = 0;
|
||||
st32 jumpdisp = 0;
|
||||
struct v810_cmd cmd;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
@@ -68,7 +332,6 @@ static int v810_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
|
||||
}
|
||||
|
||||
op->addr = addr;
|
||||
|
||||
opcode = OPCODE(word1);
|
||||
if (opcode >> 3 == 0x4) {
|
||||
opcode &= 0x20;
|
||||
@@ -76,219 +339,69 @@ static int v810_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
|
||||
|
||||
switch (opcode) {
|
||||
case V810_MOV:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,r%u,=",
|
||||
REG1(word1), REG2(word1));
|
||||
break;
|
||||
case V810_MOV_IMM5:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
|
||||
rz_strbuf_appendf(&op->esil, "%d,r%u,=",
|
||||
(st8)SIGN_EXT_T5(IMM5(word1)), REG2(word1));
|
||||
break;
|
||||
case V810_MOVHI:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
|
||||
rz_strbuf_appendf(&op->esil, "16,%hu,<<,r%u,+,r%u,=",
|
||||
word2, REG1(word1), REG2(word1));
|
||||
break;
|
||||
case V810_MOVEA:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
|
||||
rz_strbuf_appendf(&op->esil, "%hd,r%u,+,r%u,=",
|
||||
word2, REG1(word1), REG2(word1));
|
||||
break;
|
||||
case V810_LDSR:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
|
||||
break;
|
||||
case V810_STSR:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_MOV;
|
||||
break;
|
||||
case V810_NOT:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_NOT;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,0xffffffff,^,r%u,=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(op, V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(op, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_DIV:
|
||||
case V810_DIVU:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_DIV;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,r%u,/=,r%u,r%u,%%,r30,=",
|
||||
REG1(word1), REG2(word1),
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(op, V810_FLAG_OV | V810_FLAG_S | V810_FLAG_Z);
|
||||
break;
|
||||
case V810_JMP:
|
||||
if (REG1(word1) == 31) {
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_RET;
|
||||
} else {
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_UJMP;
|
||||
}
|
||||
rz_strbuf_appendf(&op->esil, "r%u,pc,=",
|
||||
REG1(word1));
|
||||
break;
|
||||
case V810_OR:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_OR;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,r%u,|=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(op, V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(op, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_ORI:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_OR;
|
||||
rz_strbuf_appendf(&op->esil, "%hu,r%u,|,r%u,=",
|
||||
word2, REG1(word1), REG2(word1));
|
||||
update_flags(op, V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(op, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_MUL:
|
||||
case V810_MULU:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_MUL;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,r%u,*=,32,r%u,r%u,*,>>,r30,=",
|
||||
REG1(word1), REG2(word1),
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(op, V810_FLAG_OV | V810_FLAG_S | V810_FLAG_Z);
|
||||
break;
|
||||
case V810_XOR:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_XOR;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,r%u,^=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(op, V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(op, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_XORI:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_XOR;
|
||||
rz_strbuf_appendf(&op->esil, "%hu,r%u,^,r%u,=",
|
||||
word2, REG1(word1), REG2(word1));
|
||||
update_flags(op, V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(op, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_AND:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_AND;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,r%u,&=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(op, V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(op, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_ANDI:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_AND;
|
||||
rz_strbuf_appendf(&op->esil, "%hu,r%u,&,r%u,=",
|
||||
word2, REG1(word1), REG2(word1));
|
||||
update_flags(op, V810_FLAG_Z);
|
||||
clear_flags(op, V810_FLAG_OV | V810_FLAG_S);
|
||||
break;
|
||||
case V810_CMP:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_CMP;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,r%u,==",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(op, -1);
|
||||
break;
|
||||
case V810_CMP_IMM5:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_CMP;
|
||||
rz_strbuf_appendf(&op->esil, "%d,r%u,==",
|
||||
(st8)SIGN_EXT_T5(IMM5(word1)), REG2(word1));
|
||||
update_flags(op, -1);
|
||||
break;
|
||||
case V810_SUB:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_SUB;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,r%u,-=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(op, -1);
|
||||
break;
|
||||
case V810_ADD:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_ADD;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,r%u,+=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(op, -1);
|
||||
break;
|
||||
case V810_ADDI:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_ADD;
|
||||
rz_strbuf_appendf(&op->esil, "%hd,r%u,+,r%u,=",
|
||||
word2, REG1(word1), REG2(word1));
|
||||
update_flags(op, -1);
|
||||
break;
|
||||
case V810_ADD_IMM5:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_ADD;
|
||||
rz_strbuf_appendf(&op->esil, "%d,r%u,+=",
|
||||
(st8)SIGN_EXT_T5(IMM5(word1)), REG2(word1));
|
||||
update_flags(op, -1);
|
||||
break;
|
||||
case V810_SHR:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_SHR;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,r%u,>>=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(op, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(op, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_SHR_IMM5:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_SHR;
|
||||
rz_strbuf_appendf(&op->esil, "%u,r%u,>>=",
|
||||
(ut8)IMM5(word1), REG2(word1));
|
||||
update_flags(op, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(op, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_SAR:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_SAR;
|
||||
reg1 = REG1(word1);
|
||||
reg2 = REG2(word1);
|
||||
rz_strbuf_appendf(&op->esil, "31,r%u,>>,?{,r%u,32,-,r%u,1,<<,--,<<,}{,0,},r%u,r%u,>>,|,r%u,=",
|
||||
reg2, reg1, reg1, reg1, reg2, reg2);
|
||||
update_flags(op, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(op, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_SAR_IMM5:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_SAR;
|
||||
imm5 = IMM5(word1);
|
||||
reg2 = REG2(word1);
|
||||
rz_strbuf_appendf(&op->esil, "31,r%u,>>,?{,%u,32,-,%u,1,<<,--,<<,}{,0,},%u,r%u,>>,|,r%u,=",
|
||||
reg2, (ut8)imm5, (ut8)imm5, (ut8)imm5, reg2, reg2);
|
||||
update_flags(op, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(op, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_SHL:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_SHL;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,r%u,<<=",
|
||||
REG1(word1), REG2(word1));
|
||||
update_flags(op, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(op, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_SHL_IMM5:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_SHL;
|
||||
rz_strbuf_appendf(&op->esil, "%u,r%u,<<=",
|
||||
(ut8)IMM5(word1), REG2(word1));
|
||||
update_flags(op, V810_FLAG_CY | V810_FLAG_S | V810_FLAG_Z);
|
||||
clear_flags(op, V810_FLAG_OV);
|
||||
break;
|
||||
case V810_LDB:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,%hd,+,[1],r%u,=",
|
||||
REG1(word1), word2, REG2(word1));
|
||||
rz_strbuf_appendf(&op->esil, ",DUP,0x80,&,?{,0xffffff00,|,}");
|
||||
break;
|
||||
case V810_LDH:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,%hd,+,0xfffffffe,&,[2],r%u,=",
|
||||
REG1(word1), word2, REG2(word1));
|
||||
rz_strbuf_appendf(&op->esil, ",DUP,0x8000,&,?{,0xffffff00,|,}");
|
||||
break;
|
||||
case V810_LDW:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_LOAD;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,%hd,+,0xfffffffc,&,[4],r%u,=",
|
||||
REG1(word1), word2, REG2(word1));
|
||||
rz_strbuf_appendf(&op->esil, ",DUP,0x80000000,&,?{,0xffffff00,|,}");
|
||||
break;
|
||||
case V810_STB:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_STORE;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,r%u,%hd,+,=[1]",
|
||||
REG2(word1), REG1(word1), word2);
|
||||
break;
|
||||
case V810_STH:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_STORE;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,r%u,%hd,+,0xfffffffe,&,=[2]",
|
||||
REG2(word1), REG1(word1), word2);
|
||||
break;
|
||||
case V810_STW:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_STORE;
|
||||
rz_strbuf_appendf(&op->esil, "r%u,r%u,%hd,+,=[4]",
|
||||
REG2(word1), REG1(word1), word2);
|
||||
break;
|
||||
case V810_INB:
|
||||
case V810_INH:
|
||||
@@ -300,11 +413,16 @@ static int v810_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
|
||||
break;
|
||||
case V810_TRAP:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_TRAP;
|
||||
rz_strbuf_appendf(&op->esil, "%u,TRAP", IMM5(word1));
|
||||
break;
|
||||
case V810_RETI:
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_RET;
|
||||
// rz_strbuf_appendf (&op->esil, "np,?{,fepc,fepsw,}{,eipc,eipsw,},psw,=,pc,=");
|
||||
break;
|
||||
case V810_JMP:
|
||||
if (REG1(word1) == 31) {
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_RET;
|
||||
} else {
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_UJMP;
|
||||
}
|
||||
break;
|
||||
case V810_JAL:
|
||||
case V810_JR:
|
||||
@@ -314,76 +432,44 @@ static int v810_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8
|
||||
|
||||
if (opcode == V810_JAL) {
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_CALL;
|
||||
rz_strbuf_appendf(&op->esil, "$$,4,+,r31,=,");
|
||||
} else {
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_JMP;
|
||||
}
|
||||
|
||||
rz_strbuf_appendf(&op->esil, "$$,%d,+,pc,=", jumpdisp);
|
||||
break;
|
||||
case V810_BCOND:
|
||||
cond = COND(word1);
|
||||
if (cond == V810_COND_NOP) {
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_NOP;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (OPCODE(word1) >> 3 == 4) {
|
||||
cond = COND(word1);
|
||||
if (cond == V810_COND_NOP) {
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_NOP;
|
||||
break;
|
||||
}
|
||||
|
||||
jumpdisp = DISP9(word1);
|
||||
op->jump = addr + jumpdisp;
|
||||
op->fail = addr + 2;
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_CJMP;
|
||||
|
||||
switch (cond) {
|
||||
case V810_COND_V:
|
||||
rz_strbuf_appendf(&op->esil, "ov");
|
||||
break;
|
||||
case V810_COND_L:
|
||||
rz_strbuf_appendf(&op->esil, "cy");
|
||||
break;
|
||||
case V810_COND_E:
|
||||
rz_strbuf_appendf(&op->esil, "z");
|
||||
break;
|
||||
case V810_COND_NH:
|
||||
rz_strbuf_appendf(&op->esil, "cy,z,|");
|
||||
break;
|
||||
case V810_COND_N:
|
||||
rz_strbuf_appendf(&op->esil, "s");
|
||||
break;
|
||||
case V810_COND_NONE:
|
||||
rz_strbuf_appendf(&op->esil, "1");
|
||||
break;
|
||||
case V810_COND_LT:
|
||||
rz_strbuf_appendf(&op->esil, "s,ov,^");
|
||||
break;
|
||||
case V810_COND_LE:
|
||||
rz_strbuf_appendf(&op->esil, "s,ov,^,z,|");
|
||||
break;
|
||||
case V810_COND_NV:
|
||||
rz_strbuf_appendf(&op->esil, "ov,!");
|
||||
break;
|
||||
case V810_COND_NL:
|
||||
rz_strbuf_appendf(&op->esil, "cy,!");
|
||||
break;
|
||||
case V810_COND_NE:
|
||||
rz_strbuf_appendf(&op->esil, "z,!");
|
||||
break;
|
||||
case V810_COND_H:
|
||||
rz_strbuf_appendf(&op->esil, "cy,z,|,!");
|
||||
break;
|
||||
case V810_COND_P:
|
||||
rz_strbuf_appendf(&op->esil, "s,!");
|
||||
break;
|
||||
case V810_COND_GE:
|
||||
rz_strbuf_appendf(&op->esil, "s,ov,^,!");
|
||||
break;
|
||||
case V810_COND_GT:
|
||||
rz_strbuf_appendf(&op->esil, "s,ov,^,z,|,!");
|
||||
break;
|
||||
jumpdisp = DISP9(word1);
|
||||
op->jump = addr + jumpdisp;
|
||||
op->fail = addr + 2;
|
||||
op->type = RZ_ANALYSIS_OP_TYPE_CJMP;
|
||||
}
|
||||
rz_strbuf_appendf(&op->esil, ",?{,$$,%d,+,pc,=,}", jumpdisp);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mask & RZ_ANALYSIS_OP_MASK_DISASM) {
|
||||
op->mnemonic = rz_str_newf("%s %s", cmd.instr, cmd.operands);
|
||||
}
|
||||
|
||||
if (mask & RZ_ANALYSIS_OP_MASK_ESIL) {
|
||||
v810_esil(&op->esil, opcode, word1, word2);
|
||||
}
|
||||
|
||||
if (mask & RZ_ANALYSIS_OP_MASK_IL) {
|
||||
V810AnalysisContext ctx = { 0 };
|
||||
ctx.a = analysis;
|
||||
ctx.w1 = word1;
|
||||
ctx.w2 = word2;
|
||||
ctx.pc = addr;
|
||||
|
||||
op->il_op = v810_il_op(&ctx);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -431,15 +517,47 @@ static char *get_reg_profile(RzAnalysis *analysis) {
|
||||
"gpr r31 .32 124 0\n"
|
||||
"gpr pc .32 128 0\n"
|
||||
|
||||
"gpr psw .32 132 0\n"
|
||||
"gpr np .1 132.16 0\n"
|
||||
"gpr ep .1 132.17 0\n"
|
||||
"gpr ae .1 132.18 0\n"
|
||||
"gpr id .1 132.19 0\n"
|
||||
"flg cy .1 132.28 0\n"
|
||||
"flg ov .1 132.29 0\n"
|
||||
"flg s .1 132.30 0\n"
|
||||
"flg z .1 132.31 0\n";
|
||||
"gpr EIPC .32 132 0\n"
|
||||
"gpr EIPSW .32 136 0\n"
|
||||
"gpr FEPC .32 140 0\n"
|
||||
"gpr FEPSW .32 144 0\n"
|
||||
"gpr ECR .32 148 0\n"
|
||||
"gpr PSW .32 152 0\n"
|
||||
"gpr PIR .32 156 0\n"
|
||||
"gpr TKCW .32 160 0\n"
|
||||
"gpr Reserved_8 .32 164 0\n"
|
||||
"gpr Reserved_9 .32 168 0\n"
|
||||
"gpr Reserved_10 .32 172 0\n"
|
||||
"gpr Reserved_11 .32 176 0\n"
|
||||
"gpr Reserved_12 .32 180 0\n"
|
||||
"gpr Reserved_13 .32 184 0\n"
|
||||
"gpr Reserved_14 .32 188 0\n"
|
||||
"gpr Reserved_15 .32 192 0\n"
|
||||
"gpr Reserved_16 .32 196 0\n"
|
||||
"gpr Reserved_17 .32 200 0\n"
|
||||
"gpr Reserved_18 .32 204 0\n"
|
||||
"gpr Reserved_19 .32 208 0\n"
|
||||
"gpr Reserved_20 .32 212 0\n"
|
||||
"gpr Reserved_21 .32 216 0\n"
|
||||
"gpr Reserved_22 .32 220 0\n"
|
||||
"gpr Reserved_23 .32 224 0\n"
|
||||
"gpr CHCW .32 228 0\n"
|
||||
"gpr ADTRE .32 232 0\n"
|
||||
"gpr Reserved_26 .32 236 0\n"
|
||||
"gpr Reserved_27 .32 240 0\n"
|
||||
"gpr Reserved_28 .32 244 0\n"
|
||||
"gpr Reserved_29 .32 248 0\n"
|
||||
"gpr Reserved_30 .32 252 0\n"
|
||||
"gpr Reserved_31 .32 256 0\n"
|
||||
|
||||
"gpr np .1 152.16 0\n"
|
||||
"gpr ep .1 152.17 0\n"
|
||||
"gpr ae .1 152.18 0\n"
|
||||
"gpr id .1 152.19 0\n"
|
||||
"flg cy .1 152.28 0\n"
|
||||
"flg ov .1 152.29 0\n"
|
||||
"flg s .1 152.30 0\n"
|
||||
"flg z .1 152.31 0\n";
|
||||
|
||||
return strdup(p);
|
||||
}
|
||||
@@ -452,6 +570,7 @@ RzAnalysisPlugin rz_analysis_plugin_v810 = {
|
||||
.bits = 32,
|
||||
.op = v810_op,
|
||||
.esil = true,
|
||||
.il_config = v810_il_config,
|
||||
.get_reg_profile = get_reg_profile,
|
||||
};
|
||||
|
||||
|
||||
@@ -276,6 +276,7 @@ static const struct arch_translation arch_translation_table[] = {
|
||||
{ EM_VIDEOCORE4, "vc4" },
|
||||
{ EM_MSP430, "msp430" },
|
||||
{ EM_SH, "sh" },
|
||||
{ EM_V810, "v810" },
|
||||
{ EM_V800, "v850" },
|
||||
{ EM_V850, "v850" },
|
||||
{ EM_IA_64, "ia64" },
|
||||
|
||||
@@ -374,6 +374,7 @@ typedef struct
|
||||
chances of collision with official or non-GNU unofficial values. */
|
||||
|
||||
#define EM_ALPHA 0x9026
|
||||
#define EM_V810 0x9081
|
||||
|
||||
/* Legal values for e_version (version). */
|
||||
|
||||
|
||||
+32
-1
@@ -38,6 +38,37 @@ r29 = 0x00000000
|
||||
r30 = 0x00000000
|
||||
r31 = 0x00000000
|
||||
pc = 0x00000000
|
||||
psw = 0x00000000
|
||||
EIPC = 0x00000000
|
||||
EIPSW = 0x00000000
|
||||
FEPC = 0x00000000
|
||||
FEPSW = 0x00000000
|
||||
ECR = 0x00000000
|
||||
PSW = 0x00000000
|
||||
PIR = 0x00000000
|
||||
TKCW = 0x00000000
|
||||
Reserved_8 = 0x00000000
|
||||
Reserved_9 = 0x00000000
|
||||
Reserved_10 = 0x00000000
|
||||
Reserved_11 = 0x00000000
|
||||
Reserved_12 = 0x00000000
|
||||
Reserved_13 = 0x00000000
|
||||
Reserved_14 = 0x00000000
|
||||
Reserved_15 = 0x00000000
|
||||
Reserved_16 = 0x00000000
|
||||
Reserved_17 = 0x00000000
|
||||
Reserved_18 = 0x00000000
|
||||
Reserved_19 = 0x00000000
|
||||
Reserved_20 = 0x00000000
|
||||
Reserved_21 = 0x00000000
|
||||
Reserved_22 = 0x00000000
|
||||
Reserved_23 = 0x00000000
|
||||
CHCW = 0x00000000
|
||||
ADTRE = 0x00000000
|
||||
Reserved_26 = 0x00000000
|
||||
Reserved_27 = 0x00000000
|
||||
Reserved_28 = 0x00000000
|
||||
Reserved_29 = 0x00000000
|
||||
Reserved_30 = 0x00000000
|
||||
Reserved_31 = 0x00000000
|
||||
EOF
|
||||
RUN
|
||||
|
||||
+57
-57
@@ -1,57 +1,57 @@
|
||||
d "mov r1, r2" 4100
|
||||
d "add r1, r2" 4104
|
||||
d "sub r1, r2" 4108
|
||||
d "cmp r1, r2" 410c
|
||||
d "shl r1, r2" 4110
|
||||
d "shr r1, r2" 4114
|
||||
d "jmp [r1]" 0118
|
||||
d "sar r1, r2" 411c
|
||||
d "mul r1, r2" 4120
|
||||
d "div r1, r2" 4124
|
||||
d "mulu r1, r2" 4128
|
||||
d "divu r1, r2" 412c
|
||||
d "or r1, r2" 4130
|
||||
d "and r1, r2" 4134
|
||||
d "not r1, r2" 413c
|
||||
d "mov -1, r2" 5f40
|
||||
d "add 1, r2" 4144
|
||||
d "cmp 0, r2" 404c
|
||||
d "shl 8, r2" 4850
|
||||
d "shr 24, r2" 5854
|
||||
d "sar 0, r2" 405c
|
||||
d "cli " 0058
|
||||
d "sei " 0078
|
||||
d "trap 15" 0f60
|
||||
d "reti " 0064
|
||||
d "halt " 0068
|
||||
d "ldsr FEPSW, r2" 4370
|
||||
d "stsr TKCW, r2" 4774
|
||||
d "stsr s8, r2" 4874
|
||||
d "bv -8" f881
|
||||
d "ble 8" 088e
|
||||
d "movea 0xffff, r1, r2" 41a0ffff
|
||||
d "addi -1, r1, r2" 41a4ffff
|
||||
d "jr -8" ffabf8ff
|
||||
d "jal 8" 00ac0800
|
||||
d "ori 0xff, r1, r2" 41b0ff00
|
||||
d "andi 0x0, r1, r2" 41b40000
|
||||
d "xori 0x0, r1, r2" 41b80000
|
||||
d "movhi 0x501, r1, r2" 41bc0105
|
||||
d "ld.b 0[r1], r2" 41c00000
|
||||
d "ld.h 32[r1], r2" 41c42000
|
||||
d "ld.w -32[r1], r2" 41cce0ff
|
||||
d "st.b r2, -32[r1]" 41d0e0ff
|
||||
d "st.h r2, 32[r1]" 41d42000
|
||||
d "st.w r2, 0[r1]" 41dc0000
|
||||
d "in.b 123[r1], r2" 41e07b00
|
||||
d "in.h 123[r1], r2" 41e47b00
|
||||
d "caxi 123[r1], r2" 41e87b00
|
||||
d "in.w 123[r1], r2" 41ec7b00
|
||||
d "out.b r2, 123[r1]" 41f07b00
|
||||
d "out.h r2, 123[r1]" 41f47b00
|
||||
d "out.w r2, 123[r1]" 41fc7b00
|
||||
d "mulf.s r11, r10" 4bf90018
|
||||
d "cvt.sw r10, r11" 6af9000c
|
||||
d "subf.s r15, r30" cffb0014
|
||||
d "rev r15, r10" 4ff90028
|
||||
d "xb r11" 60f90020
|
||||
d "mov r1, r2" 4100 0x0 (set r2 (var r1))
|
||||
d "add r1, r2" 4104 0x0 (seq (set result (+ (var r2) (var r1))) (set PSW (| (| (| (<< (ite (|| (&& (sle (var result) (var r2)) (! (== (var result) (var r2)))) (&& (sle (var result) (var r1)) (! (== (var result) (var r1))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (let _x (var result) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
|
||||
d "sub r1, r2" 4108 0x0 (seq (set result (- (var r2) (var r1))) (set PSW (| (| (| (<< (ite (&& (sle (var r2) (var r1)) (! (== (var r2) (var r1)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (let _x (var result) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
|
||||
d "cmp r1, r2" 410c 0x0 (seq (set result (- (var r2) (var r1))) (set PSW (| (| (| (<< (ite (&& (sle (var r2) (var r1)) (! (== (var r2) (var r1)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (let _x (var result) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
|
||||
d "shl r1, r2" 4110 0x0 (seq (set result (<< (var r2) (var r1) false)) (set PSW (| (| (<< (ite (&& (! (is_zero (bv 32 0x1))) (! (is_zero (>> (var r2) (- (bv 32 0x20) (var r1)) false)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
|
||||
d "shr r1, r2" 4114 0x0 (seq (set result (>> (var r2) (var r1) false)) (set PSW (| (| (<< (ite (&& (! (is_zero (bv 32 0x1))) (! (is_zero (& (var r2) (- (<< (bv 32 0x1) (bv 32 0x1) false) (bv 32 0x1)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
|
||||
d "jmp [r1]" 0118 0x0 (jmp (& (var r1) (bv 32 0xfffffffe)))
|
||||
d "sar r1, r2" 411c 0x0 (seq (set result (>> (var r2) (var r1) (msb (var r2)))) (set PSW (| (| (<< (ite (&& (! (is_zero (bv 32 0x1))) (! (is_zero (& (var r2) (- (<< (bv 32 0x1) (bv 32 0x1) false) (bv 32 0x1)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
|
||||
d "mul r1, r2" 4120 0x0 (seq (set result (* (cast 64 (msb (var r2)) (var r2)) (cast 64 (msb (var r1)) (var r1)))) (set r2 (cast 32 false (var result))) (set r30 (cast 32 false (>> (var result) (bv 32 0x20) false))) (set PSW (| (| (<< (ite (let _x (var r2) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
|
||||
d "div r1, r2" 4124 0x0 (seq (set r2 (div (var r2) (var r1))) (set r30 (mod (var r2) (var r1))) (set PSW (| (| (<< (ite (let _x (var r2) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
|
||||
d "mulu r1, r2" 4128 0x0 (seq (set result (* (cast 64 false (var r2)) (cast 64 false (var r1)))) (set r2 (cast 32 false (var result))) (set r30 (cast 32 false (>> (var result) (bv 32 0x20) false))) (set PSW (| (| (<< (ite (let _x (var r2) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
|
||||
d "divu r1, r2" 412c 0x0 (seq (set r2 (div (var r2) (var r1))) (set r30 (mod (var r2) (var r1))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
|
||||
d "or r1, r2" 4130 0x0 (seq (set result (| (var r2) (var r1))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
|
||||
d "and r1, r2" 4134 0x0 (seq (set result (& (var r2) (var r1))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
|
||||
d "not r1, r2" 413c 0x0 (seq (set r2 (~ (var r1))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
|
||||
d "mov -1, r2" 5f40 0x0 (set r2 (bv 32 0xffffffff))
|
||||
d "add 1, r2" 4144 0x0 (seq (set result (+ (var r2) (bv 32 0x1))) (set PSW (| (| (| (<< (ite (|| (&& (sle (var result) (var r2)) (! (== (var result) (var r2)))) (&& (sle (var result) (bv 32 0x1)) (! (== (var result) (bv 32 0x1))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (let _x (var result) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
|
||||
d "cmp 0, r2" 404c 0x0 (seq (set result (- (var r2) (bv 32 0x0))) (set PSW (| (| (| (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (let _x (var result) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
|
||||
d "shl 8, r2" 4850 0x0 (seq (set result (<< (var r2) (bv 32 0x8) false)) (set PSW (| (| (<< (ite (&& (! (is_zero (bv 32 0x8))) (! (is_zero (>> (var r2) (- (bv 32 0x20) (bv 32 0x8)) false)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
|
||||
d "shr 24, r2" 5854 0x0 (seq (set result (>> (var r2) (bv 32 0x18) false)) (set PSW (| (| (<< (ite (&& (! (is_zero (var r24))) (! (is_zero (& (var r2) (- (<< (bv 32 0x1) (var r24) false) (bv 32 0x1)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
|
||||
d "sar 0, r2" 405c 0x0 (seq (set result (>> (var r2) (bv 32 0x0) (msb (var r2)))) (set PSW (| (| (<< (ite (&& (! (is_zero (var r0))) (! (is_zero (& (var r2) (- (<< (bv 32 0x1) (var r0) false) (bv 32 0x1)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
|
||||
d "cli" 0058 0x0 nop
|
||||
d "sei" 0078 0x0 nop
|
||||
d "trap 15" 0f60 0x0 nop
|
||||
d "reti" 0064 0x0 (seq (set _pc (ite (let _v_part (let _v_parent (var PSW) (& (>> (var _v_parent) (bv 32 0xf) false) (bv 32 0x1))) (! (is_zero (var _v_part)))) (var FEPC) (var EIPC))) (set PSW (ite (let _v_part (let _v_parent (var PSW) (& (>> (var _v_parent) (bv 32 0xf) false) (bv 32 0x1))) (! (is_zero (var _v_part)))) (var FEPSW) (var EIPSW))) (jmp (var _pc)))
|
||||
d "halt" 0068 0x0 nop
|
||||
d "ldsr FEPSW, r2" 4370 0x0 (set FEPSW (var r2))
|
||||
d "stsr TKCW, r2" 4774 0x0 (set r2 (var TKCW))
|
||||
d "stsr s8, r2" 4874 0x0 (set r2 (var Reserved_8))
|
||||
d "bv -8" f881 0x0 (branch (let _v_part (let _v_parent (var PSW) (& (>> (var _v_parent) (bv 32 0x2) false) (bv 32 0x1))) (! (is_zero (var _v_part)))) (seq (set _pc (+ (bv 32 0x0) (bv 32 0xfffffff8))) (jmp (var _pc))) nop)
|
||||
d "ble 8" 088e 0x0 (branch (|| (^^ (let _v_part (let _v_parent (var PSW) (& (>> (var _v_parent) (bv 32 0x1) false) (bv 32 0x1))) (! (is_zero (var _v_part)))) (let _v_part (let _v_parent (var PSW) (& (>> (var _v_parent) (bv 32 0x2) false) (bv 32 0x1))) (! (is_zero (var _v_part))))) (let _v_part (let _v_parent (var PSW) (& (>> (var _v_parent) (bv 32 0x0) false) (bv 32 0x1))) (! (is_zero (var _v_part))))) (seq (set _pc (+ (bv 32 0x0) (bv 32 0x8))) (jmp (var _pc))) nop)
|
||||
d "movea 0xffff, r1, r2" 41a0ffff 0x0 (set r2 (+ (var r1) (bv 32 0xffffffff)))
|
||||
d "addi -1, r1, r2" 41a4ffff 0x0 (seq (set result (+ (var r1) (bv 32 0xffffffff))) (set PSW (| (| (| (<< (ite (|| (&& (sle (var result) (bv 32 0xffffffff)) (! (== (var result) (bv 32 0xffffffff)))) (&& (sle (var result) (var r1)) (! (== (var result) (var r1))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (let _x (var result) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
|
||||
d "jr -8" ffabf8ff 0x0 (seq (set _pc (+ (bv 32 0x0) (bv 32 0xfffffff8))) (jmp (var _pc)))
|
||||
d "jal 8" 00ac0800 0x0 (seq (set r31 (+ (bv 32 0x0) (bv 32 0x4))) (set _pc (+ (bv 32 0x0) (bv 32 0x8))) (jmp (var _pc)))
|
||||
d "ori 0xff, r1, r2" 41b0ff00 0x0 (seq (set result (| (var r2) (bv 32 0xff))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
|
||||
d "andi 0x0, r1, r2" 41b40000 0x0 (seq (set result (& (var r2) (bv 32 0x0))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
|
||||
d "xori 0x0, r1, r2" 41b80000 0x0 (seq (set result (^ (var r2) (bv 32 0x0))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r2) (bv 32 0x0)) (! (== (var r2) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r2)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (set r2 (var result)))
|
||||
d "movhi 0x501, r1, r2" 41bc0105 0x0 (set r2 (+ (var r1) (<< (bv 32 0x501) (bv 32 0x10) false)))
|
||||
d "ld.b 0[r1], r2" 41c00000 0x0 (seq (set _adr (+ (var r1) (bv 32 0x0))) (set r2 (let _v (cast 32 false (loadw 0 8 (var _adr))) (>> (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x8)) (bv 32 0x0)) false)) (- (bv 32 0x20) (bv 32 0x8)) (msb (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x8)) (bv 32 0x0)) false)))))))
|
||||
d "ld.h 32[r1], r2" 41c42000 0x0 (seq (set _adr (+ (var r1) (bv 32 0x20))) (set r2 (let _v (cast 32 false (loadw 0 16 (var _adr))) (>> (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x10)) (bv 32 0x0)) false)) (- (bv 32 0x20) (bv 32 0x10)) (msb (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x10)) (bv 32 0x0)) false)))))))
|
||||
d "ld.w -32[r1], r2" 41cce0ff 0x0 (seq (set _adr (+ (var r1) (bv 32 0xffffffe0))) (set r2 (loadw 0 32 (var _adr))))
|
||||
d "st.b r2, -32[r1]" 41d0e0ff 0x0 (seq (set _adr (+ (var r1) (bv 32 0xffffffe0))) (storew 0 (var _adr) (cast 8 false (var r2))))
|
||||
d "st.h r2, 32[r1]" 41d42000 0x0 (seq (set _adr (+ (var r1) (bv 32 0x20))) (storew 0 (var _adr) (cast 16 false (var r2))))
|
||||
d "st.w r2, 0[r1]" 41dc0000 0x0 (seq (set _adr (+ (var r1) (bv 32 0x0))) (storew 0 (var _adr) (var r2)))
|
||||
d "in.b 123[r1], r2" 41e07b00 0x0 (seq (set _adr (+ (var r1) (bv 32 0x7b))) (set r2 (let _v (cast 32 false (loadw 0 8 (var _adr))) (>> (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x8)) (bv 32 0x0)) false)) (- (bv 32 0x20) (bv 32 0x8)) (msb (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x8)) (bv 32 0x0)) false)))))))
|
||||
d "in.h 123[r1], r2" 41e47b00 0x0 (seq (set _adr (+ (var r1) (bv 32 0x7b))) (set r2 (let _v (cast 32 false (loadw 0 16 (var _adr))) (>> (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x10)) (bv 32 0x0)) false)) (- (bv 32 0x20) (bv 32 0x10)) (msb (cast 32 false (<< (var _v) (- (- (bv 32 0x20) (bv 32 0x10)) (bv 32 0x0)) false)))))))
|
||||
d "caxi 123[r1], r2" 41e87b00 0x0 (seq (set _adr (+ (var r1) (bv 32 0x7b))) (set _tmp (loadw 0 32 (var _adr))) (set result (- (var r2) (var _tmp))) (set PSW (| (| (| (<< (ite (&& (sle (var r2) (var r1)) (! (== (var r2) (var r1)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite (let _x (var result) (|| (! (sle (var _x) (bv 32 0x7fffffff))) (&& (sle (var _x) (bv 32 0x80000000)) (! (== (var _x) (bv 32 0x80000000)))))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (sle (var result) (bv 32 0x0)) (! (== (var result) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))) (branch (is_zero (var result)) (seq (storew 0 (var _adr) (var r30)) (set r2 (var _tmp))) (seq (storew 0 (var _adr) (var _tmp)) (set r2 (var _tmp)))))
|
||||
d "in.w 123[r1], r2" 41ec7b00 0x0 (seq (set _adr (+ (var r1) (bv 32 0x7b))) (set r2 (loadw 0 32 (var _adr))))
|
||||
d "out.b r2, 123[r1]" 41f07b00 0x0 (seq (set _adr (+ (var r1) (bv 32 0x7b))) (storew 0 (var _adr) (cast 8 false (var r2))))
|
||||
d "out.h r2, 123[r1]" 41f47b00 0x0 (seq (set _adr (+ (var r1) (bv 32 0x7b))) (storew 0 (var _adr) (cast 16 false (var r2))))
|
||||
d "out.w r2, 123[r1]" 41fc7b00 0x0 (seq (set _adr (+ (var r1) (bv 32 0x7b))) (storew 0 (var _adr) (var r2)))
|
||||
d "mulf.s r11, r10" 4bf90018 0x0 (seq (set result (*. rne (float 0 (var r10) ) (float 0 (var r11) ))) (set PSW (| (| (| (| (| (<< (ite (! (is_fpos (var result))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (! (|| (is_nan (var result)) (is_nan (float 0 (bv 32 0x0) )))) (<. (var result) (float 0 (bv 32 0x0) ))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_fzero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false)) (<< (ite (|| (is_nan (var result)) (is_inf (var result))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x9) false)) (<< (ite (is_fzero (float 0 (var r11) )) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x7) false))) (set r10 (fbits (var result))))
|
||||
d "cvt.sw r10, r11" 6af9000c 0x0 (seq (set r11 (fcast_sint 32 rne (float 0 (var r10) ))) (set PSW (| (| (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false) (<< (ite (&& (sle (var r11) (bv 32 0x0)) (! (== (var r11) (bv 32 0x0)))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_zero (var r11)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false))))
|
||||
d "subf.s r15, r30" cffb0014 0x0 (seq (set result (-. rne (float 0 (var r30) ) (float 0 (var r15) ))) (set PSW (| (| (| (| (| (<< (ite (! (is_fpos (var result))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x3) false) (<< (ite false (bv 32 0x1) (bv 32 0x0)) (bv 32 0x2) false)) (<< (ite (&& (! (|| (is_nan (var result)) (is_nan (float 0 (bv 32 0x0) )))) (<. (var result) (float 0 (bv 32 0x0) ))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x1) false)) (<< (ite (is_fzero (var result)) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x0) false)) (<< (ite (|| (is_nan (var result)) (is_inf (var result))) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x9) false)) (<< (ite (is_fzero (float 0 (var r15) )) (bv 32 0x1) (bv 32 0x0)) (bv 32 0x7) false))) (set r30 (fbits (var result))))
|
||||
d "rev r15, r10" 4ff90028 0x0 nop
|
||||
d "xb r11" 60f90020 0x0 nop
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
NAME=Testing the decryption in emulateme
|
||||
FILE=bins/v810/emulateme.v810
|
||||
TIMEOUT=30
|
||||
CMDS=<<EOF
|
||||
aaa
|
||||
e io.cache=1
|
||||
s entry0
|
||||
aezi
|
||||
aezsu 0x00008156
|
||||
ps @ obj._seckrit
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
Hello from RzIL!
|
||||
EOF
|
||||
RUN
|
||||
Reference in New Issue
Block a user