From 8cbfd685a11cb6735c27a6bdf05cb6feff6b7114 Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Sun, 19 Jun 2022 19:59:00 +0300 Subject: [PATCH] ppc/svp64: validate SVP64 context --- gas/config/tc-ppc-svp64.c | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/gas/config/tc-ppc-svp64.c b/gas/config/tc-ppc-svp64.c index 21f6014d004..b867b186df4 100644 --- a/gas/config/tc-ppc-svp64.c +++ b/gas/config/tc-ppc-svp64.c @@ -756,6 +756,75 @@ svp64_decode (char *str, struct svp64_ctx *svp64) svp64_raise (_("unrecognized opcode: `%s'"), str); } +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->svm) + { + svp64_raise_if (svp64->sv_mode != 0, + "sub-vector mode in mapreduce only"); + svp64_raise_if (svp64->subvl == 0, + "sub-vector mode not possible on SUBVL!=0"); + } + + if (svp64->src_zero) + { + svp64_raise_if (!svp64->has_smask && !svp64->mask_m_specified, + "src zeroing requires a source predicate"); + } + if (svp64->dst_zero) + { + svp64_raise_if (!svp64->has_pmask && !svp64->mask_m_specified, + "dest zeroing requires a dest predicate"); + } +} + static void svp64_assemble (char *str) { @@ -767,6 +836,7 @@ 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")); -- 2.30.2