From 04c527758dc28d77f259fb3f9bb05af680891acd Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Mon, 29 May 2023 01:04:56 +0300 Subject: [PATCH] ppc/svp64: validate SVP64 context --- gas/config/tc-ppc-svp64.c | 62 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/gas/config/tc-ppc-svp64.c b/gas/config/tc-ppc-svp64.c index 819d6457391..cbaaaf5fbd9 100644 --- a/gas/config/tc-ppc-svp64.c +++ b/gas/config/tc-ppc-svp64.c @@ -608,6 +608,67 @@ svp64_decode (char *str, struct svp64_ctx *svp64) ; } +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) { @@ -619,6 +680,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