[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