arch/tms320: list C6000 (c6x) instruction mnemonics

This commit is contained in:
Anton Kochkov
2026-09-08 10:50:05 +08:00
committed by NOT XVilka
parent e2673beaf0
commit 743d25b12a
2 changed files with 66 additions and 0 deletions
+23
View File
@@ -2528,3 +2528,26 @@ RZ_IPI bool c6x_decode(const C6xArchDesc *desc, const ut8 *buf, int len, ut64 pc
}
return true;
}
/** Every mnemonic the decoder can print, sorted and de-duplicated, for the
* `rz-asm -e` listing. Elements are borrowed static strings; free the vector
* only. */
RZ_IPI RZ_OWN RzPVector /*<const char *>*/ *c6x_mnemonics(void) {
RzPVector *v = rz_pvector_new(NULL);
if (!v) {
return NULL;
}
// C6xInsnId enumerates every opcode the decoder can emit, whether it comes
// from a functional-unit table or is built inline, so walking the name table
// needs no second list to drift out of step. The strings are borrowed from
// static storage, so the pvector owns no elements.
for (C6xInsnId id = C6X_INS_INVALID + 1; id < C6X_INS_LAST; id++) {
const char *name = c6x_ins_name(id);
// .fphead names a fetch-packet header word, not an opcode, so it has an
// id to decode with but does not belong in the instruction listing
if (name && id != C6X_INS_FPHEAD) {
rz_pvector_push(v, (void *)name);
}
}
return v;
}
+43
View File
@@ -92,6 +92,48 @@ static bool tms320_fini(void *user) {
return true;
}
static char *tms320_mnemonics(const RzAsm *a, int id, bool json) {
// Only the native C6000 engine can enumerate its instruction set; the
// C5000/C54x decode-IR front-ends expose no such listing.
if (!c6x_desc_from_cpu(a->cpu)) {
return NULL;
}
RzPVector *mnems = c6x_mnemonics();
if (!mnems) {
return NULL;
}
char *ret = NULL;
if (id >= 0) {
// The id space is C6xInsnId, the same value RzAnalysisOp::id reports, so
// a mnemonic looked up by id matches the instruction that produced it.
const char *m = c6x_ins_name((C6xInsnId)id);
ret = m ? (json ? rz_str_newf("[\"%s\"]\n", m) : rz_str_dup(m)) : NULL;
} else {
RzStrBuf sb;
rz_strbuf_init(&sb);
if (json) {
rz_strbuf_append(&sb, "[");
}
void **it;
bool first = true;
rz_pvector_foreach (mnems, it) {
const char *m = *it;
if (json) {
rz_strbuf_appendf(&sb, "%s\"%s\"", first ? "" : ",", m);
} else {
rz_strbuf_appendf(&sb, "%s\n", m);
}
first = false;
}
if (json) {
rz_strbuf_append(&sb, "]\n");
}
ret = rz_strbuf_drain_nofree(&sb);
}
rz_pvector_free(mnems);
return ret;
}
static char **tms320_cpu_descriptions() {
static char *cpu_desc[] = {
"c54x", "Texas Instruments TMS320C54x DSP family",
@@ -120,5 +162,6 @@ RzAsmPlugin rz_asm_plugin_tms320 = {
.init = tms320_init,
.fini = tms320_fini,
.disassemble = &tms320_disassemble,
.mnemonics = tms320_mnemonics,
.get_cpu_desc = tms320_cpu_descriptions,
};