[Libre-soc-bugs] [Bug 898] binutils svp64 objdump support
bugzilla-daemon at libre-soc.org
bugzilla-daemon at libre-soc.org
Mon Aug 29 17:01:58 BST 2022
https://bugs.libre-soc.org/show_bug.cgi?id=898
--- Comment #30 from Dmitry Selyutin <ghostmansd at gmail.com> ---
After a long and boring per-day debug, I've finally made binutils deal with the
new fields.
Here's how it eventually looks:
static void
svp64_assemble (char *str)
{
struct svp64_ctx svp64;
if (setjmp (svp64_exception) != 0)
return;
memset (&svp64, 0, sizeof (svp64));
svp64_decode (str, &svp64);
svp64_validate_and_fix (&svp64);
svp64_insn_set_prefix_PO (&svp64.insn, 0x1);
svp64_insn_set_prefix_id (&svp64.insn, 0x3);
svp64_insn_set_prefix_rm_mode (&svp64.insn, svp64.mode);
if (svp64.desc->sv_ptype == SVP64_PTYPE_P2)
svp64_insn_set_prefix_rm_smask (&svp64.insn, svp64.smask);
svp64_insn_set_prefix_rm_mmode (&svp64.insn, svp64.mmode);
svp64_insn_set_prefix_rm_mask (&svp64.insn, svp64.pmask);
svp64_insn_set_prefix_rm_subvl (&svp64.insn, svp64.subvl);
svp64_insn_set_prefix_rm_ewsrc (&svp64.insn, svp64.srcwid);
svp64_insn_set_prefix_rm_elwidth (&svp64.insn, svp64.destwid);
ppc_assemble (str, &svp64);
}
Once we collected the SVP64 context (and also partially initialized it), we
"jump" to common code in ppc_assemble, which takes care of operands. Whenever
there's an operand, we "remap" it (I use "remap" wording even when the operand
stands unchanged). The remapping process also affects the `svp64.insn` field;
the logic there is obviously longer than the code above, since we also have to
take care of EXTRA2/EXTRA3 schemes.
For the reference, here's how the disassembly looks like:
static const struct powerpc_opcode *
svp64_lookup (uint64_t insn, ppc_cpu_t dialect,
struct svp64_ctx *svp64)
{
uint32_t suffix;
unsigned long op;
const struct powerpc_opcode *opcode;
const struct svp64_record *record;
const struct svp64_record *record_end;
svp64_insn_set (&svp64->insn, insn);
if ((svp64_insn_get_prefix_PO (&svp64->insn) != 0x1) ||
(svp64_insn_get_prefix_id (&svp64->insn) != 0x3))
return NULL;
suffix = (uint32_t)svp64_insn_get_suffix (&svp64->insn);
opcode = lookup_powerpc (suffix, dialect & ~PPC_OPCODE_ANY);
if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
opcode = lookup_powerpc (suffix, dialect);
if (opcode == NULL)
return NULL;
op = SVP64_OP (suffix);
record_end = (svp64_records + svp64_record_indices[op + 1]);
for (record = svp64_records + svp64_record_indices[op];
record < record_end;
++record)
{
/* binutils consider Rc bit to be a part of the mask.
SVP64, however, has per-instruction mask. */
if ((record->opcode.value & record->opcode.mask) ==
((opcode->opcode & opcode->mask) & record->opcode.mask))
break;
}
if (record == record_end)
return NULL;
svp64->desc = &record->desc;
return opcode;
}
The next step is to start filling other bits of SVP64 context, not only `desc`
and `insn`. Since recent we already have `function` field, so this should give
us a good start.
--
You are receiving this mail because:
You are on the CC list for the bug.
More information about the libre-soc-bugs
mailing list