Skip to content

Commit

Permalink
v850 refactor v850_disas.c
Browse files Browse the repository at this point in the history
  • Loading branch information
imbillow committed Jan 16, 2024
1 parent fb80078 commit 7b03395
Show file tree
Hide file tree
Showing 6 changed files with 277 additions and 220 deletions.
70 changes: 30 additions & 40 deletions librz/analysis/arch/v850/v850_esil.inc
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ static void clear_flags(RzStrBuf *out, int flags) {
}
}

static void v850_esil(RzStrBuf *out, ut8 opcode, ut16 word1, ut16 word2) {
static void v850_esil(RzStrBuf *out, ut8 opcode, ut16 word1, ut16 word2, struct v850_cmd *x) {
const char *reg1 = NULL;
const char *reg2 = NULL;
ut32 bitmask = 0;
ut16 destaddr = 0;
st16 destaddrs = 0;
switch (opcode) {
switch (x->opcode) {
case V850_MOV_IMM5:
case V850_MOV:
// 2 formats
Expand Down Expand Up @@ -180,9 +180,6 @@ static void v850_esil(RzStrBuf *out, ut8 opcode, ut16 word1, ut16 word2) {
clear_flags(out, V850_FLAG_OV);
break;
case V850_BCOND:
case V850_BCOND2:
case V850_BCOND3:
case V850_BCOND4:
destaddr = ((((word1 >> 4) & 0x7) |
((word1 >> 11) << 3))
<< 1);
Expand Down Expand Up @@ -240,41 +237,34 @@ static void v850_esil(RzStrBuf *out, ut8 opcode, ut16 word1, ut16 word2) {
}
rz_strbuf_appendf(out, ",?{,$$,%d,+,pc,=,}", destaddrs);
break;
case V850_BIT_MANIP: {
ut8 bitop = word1 >> 14;
switch (bitop) {
case V850_BIT_CLR1:
bitmask = (1 << F8_BIT(word1));
rz_strbuf_appendf(out, "%hu,%s,+,[1],%u,&,%hu,%s,+,=[1]", word2, F8_RN1(word1), bitmask, word2, F8_RN1(word1));
// TODO: Read the value of the memory byte and set zero flag accordingly!
break;
case V850_BIT_NOT1:
bitmask = (1 << F8_BIT(word1));
rz_strbuf_appendf(out, "%hu,%s,+,[1],%u,^,%hu,%s,+,=[1]", word2, F8_RN1(word1), bitmask, word2, F8_RN1(word1));
// TODO: Read the value of the memory byte and set zero flag accordingly!
break;
}
} break;
case V850_EXT1:
switch (get_subopcode(word1 | (ut32)word2 << 16)) {
case V850_EXT_SHL:
rz_strbuf_appendf(out, "%s,%s,<<=", F9_RN1(word1), F9_RN2(word1));
update_flags(out, V850_FLAG_CY | V850_FLAG_S | V850_FLAG_Z);
clear_flags(out, V850_FLAG_OV);
break;
case V850_EXT_SHR:
rz_strbuf_appendf(out, "%s,%s,>>=", F9_RN1(word1), F9_RN2(word1));
update_flags(out, V850_FLAG_CY | V850_FLAG_S | V850_FLAG_Z);
clear_flags(out, V850_FLAG_OV);
break;
case V850_EXT_SAR:
reg1 = F9_RN1(word1);
reg2 = F9_RN2(word1);
rz_strbuf_appendf(out, "31,%s,>>,?{,%s,32,-,%s,1,<<,--,<<,}{,0,},%s,%s,>>,|,%s,=", reg2, reg1, reg1, reg1, reg2, reg2);
update_flags(out, V850_FLAG_CY | V850_FLAG_S | V850_FLAG_Z);
clear_flags(out, V850_FLAG_OV);
break;
}
case V850_CLR1:
bitmask = (1 << F8_BIT(word1));
rz_strbuf_appendf(out, "%hu,%s,+,[1],%u,&,%hu,%s,+,=[1]", word2, F8_RN1(word1), bitmask, word2, F8_RN1(word1));
// TODO: Read the value of the memory byte and set zero flag accordingly!
break;
case V850_NOT1:
bitmask = (1 << F8_BIT(word1));
rz_strbuf_appendf(out, "%hu,%s,+,[1],%u,^,%hu,%s,+,=[1]", word2, F8_RN1(word1), bitmask, word2, F8_RN1(word1));
// TODO: Read the value of the memory byte and set zero flag accordingly!
break;

case V850_SHL:
rz_strbuf_appendf(out, "%s,%s,<<=", F9_RN1(word1), F9_RN2(word1));
update_flags(out, V850_FLAG_CY | V850_FLAG_S | V850_FLAG_Z);
clear_flags(out, V850_FLAG_OV);
break;
case V850_SHR:
rz_strbuf_appendf(out, "%s,%s,>>=", F9_RN1(word1), F9_RN2(word1));
update_flags(out, V850_FLAG_CY | V850_FLAG_S | V850_FLAG_Z);
clear_flags(out, V850_FLAG_OV);
break;
case V850_SAR:
reg1 = F9_RN1(word1);
reg2 = F9_RN2(word1);
rz_strbuf_appendf(out, "31,%s,>>,?{,%s,32,-,%s,1,<<,--,<<,}{,0,},%s,%s,>>,|,%s,=", reg2, reg1, reg1, reg1, reg2, reg2);
update_flags(out, V850_FLAG_CY | V850_FLAG_S | V850_FLAG_Z);
clear_flags(out, V850_FLAG_OV);
break;
default: break;
}
}
170 changes: 84 additions & 86 deletions librz/analysis/arch/v850/v850_il.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,26 +88,67 @@ static const char *GR[] = {
"ep", // EP
"lp", // LP
/*PC*/
NULL
};

typedef struct {
const char *p;
const char *x;
unsigned i;
unsigned b;
} V850_FLG;

static const char *SR[] = {
"EIPC",
"EIPSW",
"FEPC",
"FEPSW",
"ECR",
"PSW",
NULL
"PSW", // 5
"RES6",
"RES7",
"RES8",
"RES9",
"RES10",
"RES11",
"RES12",
"RES6",
"RES13",
"RES14",
"RES15",
"RES16",
"RES17",
"RES18",
"RES19",
"RES20",
"RES21",
"RES22",
"RES23",
"RES24",
"RES25",
"RES26",
"RES27",
"RES28",
"RES29",
"RES30",
"RES31",
};

static const char *GR_get(ut8 i) {
if (i >= RZ_ARRAY_SIZE(GR)) {
rz_warn_if_reached();
return NULL;
}
return GR[i];
}

static const char *SR_get(ut8 i) {
if (i >= RZ_ARRAY_SIZE(SR)) {
rz_warn_if_reached();
return NULL;
}
return SR[i];
}

typedef struct {
const char *p;
const char *x;
unsigned i;
unsigned b;
} V850_FLG;

static const V850_FLG flags[] = {
{ "PSW", "RFU", 8, 24 },
{ "PSW", "NP", 7, 1 },
Expand Down Expand Up @@ -196,8 +237,8 @@ static inline int32_t sext32(uint32_t X, unsigned B) {

#define R1_ get_reg1(ctx->w1)
#define R2_ get_reg2(ctx->w1)
#define R1 (GR[R1_])
#define R2 (GR[R2_])
#define R1 (GR_get(R1_))
#define R2 (GR_get(R2_))
#define R1V VARG(R1)
#define R2V VARG(R2)
#define R1F FLOATV32(VARG(R1))
Expand Down Expand Up @@ -292,7 +333,7 @@ static RzILOpPure *condition_table(ut8 x) {
}

static RzAnalysisLiftedILOp flags_update(const V850AnalysisContext *ctx, RzILOpPure *a, RzILOpPure *b) {
switch (OPC) {
switch (ctx->x->opcode) {
case V850_ADD:
case V850_ADD_IMM5:
case V850_ADDI:
Expand All @@ -315,33 +356,20 @@ static RzAnalysisLiftedILOp flags_update(const V850AnalysisContext *ctx, RzILOpP
"OV", IS_ZERO(LH(R1V)),
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")));
case V850_SHR_IMM5:
case V850_SAR_IMM5: return SETGbs("PSW", 4,
"CY", AND(NON_ZERO(DUP(b)), NON_ZERO(LOGAND(DUP(a), SUB(SHIFTL0(U32(1), DUP(b)), U32(1))))),
case V850_SHL_IMM5:
case V850_SHL: return SETGbs("PSW", 4,
"CY", AND(NON_ZERO(DUP(b)), NON_ZERO(shr0(DUP(a), SUB(U32(32), DUP(b))))),
"OV", IL_FALSE,
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")));
case V850_SHL_IMM5: return SETGbs("PSW", 4,
"CY", AND(NON_ZERO(DUP(b)), NON_ZERO(shr0(DUP(a), SUB(U32(32), DUP(b))))),
case V850_SHR_IMM5:
case V850_SAR_IMM5:
case V850_SHR:
case V850_SAR: return SETGbs("PSW", 4,
"CY", AND(NON_ZERO(DUP(b)), NON_ZERO(LOGAND(DUP(a), SUB(SHIFTL0(U32(1), DUP(b)), U32(1))))),
"OV", IL_FALSE,
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")));
case V850_EXT1:
switch (EXT_SUB) {
case V850_EXT_SHL: return SETGbs("PSW", 4,
"CY", AND(NON_ZERO(DUP(b)), NON_ZERO(shr0(DUP(a), SUB(U32(32), DUP(b))))),
"OV", IL_FALSE,
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")));
case V850_EXT_SHR:
case V850_EXT_SAR: return SETGbs("PSW", 4,
"CY", AND(NON_ZERO(DUP(b)), NON_ZERO(LOGAND(DUP(a), SUB(SHIFTL0(U32(1), DUP(b)), U32(1))))),
"OV", IL_FALSE,
"S", SLT(VARL("result"), S32(0)),
"Z", IS_ZERO(VARL("result")));
default: break;
}
break;
case V850_SATADD:
case V850_SATADD_IMM5:
case V850_SATSUB:
Expand Down Expand Up @@ -476,7 +504,7 @@ static RzAnalysisLiftedILOp lift_tst1(const V850AnalysisContext *ctx) {
}

RzAnalysisLiftedILOp v850_il_op(const V850AnalysisContext *ctx) {
switch (OPC) {
switch (ctx->x->opcode) {
case V850_MOV_IMM5: return SETG(R2, SEXT5);
case V850_MOV: return SETG(R2, R1V);
case V850_MOVEA: return SETG(R2, ADD(R1V, SEXT16));
Expand All @@ -488,21 +516,11 @@ RzAnalysisLiftedILOp v850_il_op(const V850AnalysisContext *ctx) {
case V850_SSTH: return lift_st(ctx, ADD(VARG("ep"), U32(LD_ST_DISP_ << 1)), 16);
case V850_SSTW: return lift_st(ctx, ADD(VARG("ep"), U32((LD_ST_DISP_ & ~1) << 1)), 32);
case V850_STB: return lift_st(ctx, ADD(R1V, SEXT16), 8);
case V850_STHW: {
if (LD_ST32_SUB == 0) {
return lift_st(ctx, ADD(R1V, S32(I16 & ~1)), 16);
} else {
return lift_st(ctx, ADD(R1V, S32(I16 & ~1)), 32);
}
}
case V850_STH: return lift_st(ctx, ADD(R1V, S32(I16 & ~1)), 16);
case V850_STW: return lift_st(ctx, ADD(R1V, S32(I16 & ~1)), 32);
case V850_LDB: return lift_ld(ctx, ADD(R1V, SEXT16), 8);
case V850_LDHW: {
if (LD_ST32_SUB == 0) {
return lift_ld(ctx, ADD(R1V, S32(I16 & ~1)), 16);
} else {
return lift_ld(ctx, ADD(R1V, S32(I16 & ~1)), 32);
}
}
case V850_LDH: return lift_ld(ctx, ADD(R1V, S32(I16 & ~1)), 16);
case V850_LDW: return lift_ld(ctx, ADD(R1V, S32(I16 & ~1)), 32);
case V850_NOT: return lift_op1(ctx, R1V, rz_il_op_new_log_not);
case V850_DIVH: return lift_op2(ctx, R2V, LH(R1V), rz_il_op_new_div);
case V850_JMP: return JMP(R1V);
Expand Down Expand Up @@ -533,44 +551,24 @@ RzAnalysisLiftedILOp v850_il_op(const V850AnalysisContext *ctx) {
case V850_SHR_IMM5: return lift_op2(ctx, R2V, ZEXT5, shr0);
case V850_SAR_IMM5: return lift_op2(ctx, R2V, ZEXT5, rz_il_op_new_shiftr_arith);
case V850_SHL_IMM5: return lift_op2(ctx, R2V, ZEXT5, shl0);
case V850_BCOND:
case V850_BCOND2:
case V850_BCOND3:
case V850_BCOND4: return lift_bcond(ctx, condition_table(BCOND_COND));
case V850_BIT_MANIP: {
switch (BIT_SUB) {
case V850_BIT_CLR1: return lift_bit(ctx, ADD(R1V, SEXT16), 0);
case V850_BIT_SET1: return lift_bit(ctx, ADD(R1V, SEXT16), 1);
case V850_BIT_NOT1: return lift_bit(ctx, ADD(R1V, SEXT16), PSW_Z);
case V850_BIT_TST1: return lift_tst1(ctx);
default: break;
}
break;
}
case V850_EXT1:
switch (EXT_SUB) {
case V850_EXT_SHL: return lift_op2(ctx, R2V, R1V, shl0);
case V850_EXT_SHR: return lift_op2(ctx, R2V, R1V, shr0);
case V850_EXT_SAR: return lift_op2(ctx, R2V, R1V, rz_il_op_new_shiftr_arith);
case V850_EXT_HALT: return NOP();
case V850_EXT_RETI: return lift_reti(ctx);
case V850_EXT_SETF: return SETG(R2, ITE(condition_table(EXT_COND), U32((1)), U32(0)));
case V850_EXT_STSR: return SETG(R2, VARG(SR[regID]));
case V850_EXT_LDSR: return SETG(SR[regID], R2V);
case V850_EXT_TRAP: return lift_trap(ctx);
case V850_EXT_EXT2: {
switch (EXT_SUB2) {
case V850_EXT_DI: return SETGb("PSW", "ID", IL_TRUE);
case V850_EXT_EI: return SETGb("PSW", "ID", IL_FALSE);
}
}
default: break;
}
break;
case V850_BCOND: return lift_bcond(ctx, condition_table(BCOND_COND));
case V850_CLR1: return lift_bit(ctx, ADD(R1V, SEXT16), 0);
case V850_SET1: return lift_bit(ctx, ADD(R1V, SEXT16), 1);
case V850_NOT1: return lift_bit(ctx, ADD(R1V, SEXT16), PSW_Z);
case V850_TST1: return lift_tst1(ctx);
case V850_SHL: return lift_op2(ctx, R2V, R1V, shl0);
case V850_SHR: return lift_op2(ctx, R2V, R1V, shr0);
case V850_SAR: return lift_op2(ctx, R2V, R1V, rz_il_op_new_shiftr_arith);
case V850_HALT: return NOP();
case V850_RETI: return lift_reti(ctx);
case V850_SETF: return SETG(R2, ITE(condition_table(EXT_COND), U32((1)), U32(0)));
case V850_STSR: return SETG(R2, VARG(SR_get(regID)));
case V850_LDSR: return SETG(SR_get(ctx->w1 >> 11), VARG(GR_get(I5)));
case V850_TRAP: return lift_trap(ctx);
case V850_DI: return SETGb("PSW", "ID", IL_TRUE);
case V850_EI: return SETGb("PSW", "ID", IL_FALSE);
case V850_NOP: return NOP();
default:
if (ctx->w1 == 0x0000) {
return NOP();
}
break;
}

Expand Down
1 change: 1 addition & 0 deletions librz/analysis/arch/v850/v850_il.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ typedef struct {
ut16 w1;
ut16 w2;
ut32 pc;
struct v850_cmd *x;
} V850AnalysisContext;

RzAnalysisILConfig *v850_il_config(RzAnalysis *a);
Expand Down
Loading

0 comments on commit 7b03395

Please sign in to comment.