;
}
+static void
+svp64_validate (struct svp64_ctx *svp64)
+{
+ if (svp64->desc->ptype == SVP64_PTYPE_P2)
+ {
+ /*
+ * Since m=xx takes precedence (overrides) sm=xx and dm=xx,
+ * treat them as mutually exclusive.
+ */
+ if (svp64->mask_m_specified)
+ {
+ svp64_raise_if (svp64->has_smask,
+ "cannot have both source-mask and predicate mask");
+ svp64_raise_if (svp64->has_pmask,
+ "cannot have both dest-mask and predicate mask");
+ }
+
+ /*
+ * Since the default is INT predication (ALWAYS), if you
+ * specify one CR mask, you must specify both, to avoid
+ * mixing INT and CR reg types.
+ */
+ if (svp64->has_pmask && (svp64->pmmode == 1))
+ {
+ svp64_raise_if (!svp64->has_smask,
+ "need explicit source-mask in CR twin predication");
+ }
+ if (svp64->has_smask && (svp64->smmode == 1))
+ {
+ svp64_raise_if (!svp64->has_pmask,
+ "need explicit dest-mask in CR twin predication");
+ }
+
+ /* Sanity-check that 2Pred mask is same mode. */
+ if (svp64->has_pmask && svp64->has_smask)
+ {
+ svp64_raise_if (svp64->smmode != svp64->pmmode,
+ "predicate masks mismatch: pmmode=0x%08x, smmode=0x%08x",
+ (unsigned int)svp64->pmmode, (unsigned int)svp64->smmode);
+ }
+ else if (svp64->desc->ptype == SVP64_PTYPE_P1)
+ {
+ svp64_raise_if (svp64->has_smask,
+ "source-mask can only be specified on Twin-predicate ops");
+ svp64_raise_if (svp64->has_pmask,
+ "dest-mask can only be specified on Twin-predicate ops");
+ }
+ }
+
+ if (svp64->dz)
+ {
+ svp64_raise_if (!svp64->has_pmask && !svp64->mask_m_specified,
+ "dest zeroing requires a dest predicate");
+ }
+ if (svp64->sz)
+ {
+ svp64_raise_if (!svp64->has_smask && !svp64->mask_m_specified,
+ "src zeroing requires a source predicate");
+ }
+}
+
static void
svp64_assemble (char *str)
{
memset (&svp64, 0, sizeof (svp64));
svp64_decode (str, &svp64);
+ svp64_validate (&svp64);
as_warn (_("opcode ignored (desc=%p)"), svp64.desc);
memcpy (str, "nop", sizeof ("nop"));