Skip to content

Commit

Permalink
V850: fix decode_formatXIII
Browse files Browse the repository at this point in the history
  • Loading branch information
imbillow committed Jan 25, 2024
1 parent a524020 commit 0000064
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 11 deletions.
118 changes: 108 additions & 10 deletions librz/asm/arch/v850/v850_disas.c
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,64 @@ static bool decode_formatXII(V850_Inst *inst) {
return true;
}

static bool decode_formatXIII(V850_Inst *inst) {
static const ut8 list12_map[] = {
/*[0] = */ 30,
/*[21] = */ 31,
/*[22] = */ 29,
/*[23] = */ 28,
/*[24] = */ 23,
/*[25] = */ 22,
/*[26] = */ 21,
/*[27] = */ 20,
/*[28] = */ 27,
/*[29] = */ 26,
/*[30] = */ 25,
/*[31] = */ 24,
};

static int ut8_cmp(const void *a, const void *b) {
return ((ut8 *)a)[0] - ((ut8 *)b)[0];
}

static char *fmt_list(ut32 lst) {
ut8 set[12] = { 0 };
for (ut32 i = 0; i < 12; i++) {
set[i] = (lst & (1 << i)) ? list12_map[i] : UT8_MAX;
}
qsort(set, 12, sizeof(ut8), ut8_cmp);
RzStrBuf sb = { 0 };
rz_strbuf_initf(&sb, "{");
ut8 begin = set[0];
ut8 end = set[0];
bool sep = false;
for (ut32 i = 1; i < 12; i++) {
ut8 x = set[i];
if (x == UT8_MAX) {
break;
}
if (x - end == 1) {
end = x;
continue;
}
if (sep) {
rz_strbuf_append(&sb, ", ");
}
if (begin != end) {
rz_strbuf_appendf(&sb, "%s - %s", GR_get(begin), GR_get(end));
} else {
rz_strbuf_appendf(&sb, "%s", GR_get(begin));
}
sep = true;

rz_strbuf_appendf(&sb, ", %s", GR_get(x));
sep = true;
begin = end = x;
}
rz_strbuf_append(&sb, "}");
return rz_strbuf_drain_nofree(&sb);
}

static bool decode_formatXIII(V850_Inst *inst, RzBuffer *b) {
inst->opcode = get_opcode(inst, 6, 10);
inst->sub_opcode = get_reg2(inst);
inst->imm = inst->w1 & 0x3f >> 1;
Expand All @@ -764,27 +821,68 @@ static bool decode_formatXIII(V850_Inst *inst) {
return false;
}

char *list_str = NULL;
switch (inst->opcode) {
case 0b11001:
case 0b11001: {
inst->id = V850_DISPOSE;
// if (inst->reg2 == 0) {
//
// } else {
// }
ut8 RRRRR = inst->w2 & 0x1f;
PRINT_INSTR;
list_str = fmt_list(inst->list);
if (RRRRR > 0) {
OPERANDS("%d, %s, %s", inst->imm, list_str, GR_get(RRRRR));
} else {
OPERANDS("%d, %s", inst->imm, list_str);
}
break;
}

case 0b11110:
if (inst->reg2 == 1 || (inst->reg2 & 0x7) == 0x3) {
if (inst->reg2 == 1) {
inst->id = V850_PREPARE;
list_str = fmt_list(inst->list);
OPERANDS("%s, %x", list_str, inst->imm);
} else if ((inst->reg2 & 0x7) == 0x3) {
inst->id = V850_PREPARE;
ut8 ff = inst->reg2 >> 3;
switch (ff) {
case 0b00: OPERANDS("%s, %x, sp", list_str, inst->imm); break;
case 0b01: {
ut16 imm = 0;
if (!rz_buf_read_le16(b, &imm)) {
return false;
}
OPERANDS("%s, %x, %d", list_str, inst->imm, sext32(imm, 16));
break;
}
case 0b10: {
ut16 imm = 0;
if (!rz_buf_read_le16(b, &imm)) {
return false;
}
OPERANDS("%s, %x, %d", list_str, inst->imm, (ut32)(imm) << 16);
break;
}
case 0b11: {
ut32 imm = 0;
if (!rz_buf_read_le32(b, &imm)) {
return false;
}
OPERANDS("%s, %x, %d", list_str, inst->imm, imm);
break;
}
default: break;
}

} else {
return false;
}
PRINT_INSTR;
break;
default:
return false;
}

PRINT_INSTR;
OPERANDS("[%d], %08x", inst->imm, inst->list);
free(list_str);
return true;
}

Expand Down Expand Up @@ -851,7 +949,7 @@ int v850_decode_command(const ut8 *bytes, int len, V850_Inst *inst) {
decode_formatX(inst) ||
decode_formatXI(inst) ||
decode_formatXII(inst) ||
decode_formatXIII(inst)) {
decode_formatXIII(inst, b)) {
goto ok;
}

Expand Down
2 changes: 1 addition & 1 deletion librz/asm/arch/v850/v850_disas.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ static inline ut16 get_disp22(const V850_Inst *i) {
}

static inline ut16 get_list(const V850_Inst *i) {
return ((i->w2 & ~0x1f) >> 5) | ((i->w1 & 1) << 11);
return ((i->w2 >> 5) << 1) | (i->w1 & 1);
}

static inline int32_t sext32(uint32_t X, unsigned B) {
Expand Down

0 comments on commit 0000064

Please sign in to comment.