From 84629a61ee0f459a78e245e5aa41bec73f30c4d1 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Sun, 14 Mar 2021 15:34:16 -0300 Subject: [PATCH] introduce svp64 prefixing This (very incomplete) patch introduces svp64 prefixing support in the GNU assembler. The idea is to mark opcodes (in .../ppc-opc.c) that can be prefixed with XT2 or XT3, and svp64 opcodes that aren't prefixed (setvl) with OPC. ??? I'm not sure XT2 and XT3 are enough, though. We might need to know the RM-* encoding to be able to parse the prefixed opcode. That's where I got stuck a few weeks ago. --- gas/config/tc-ppc.c | 54 +++++++++++++++++++++++++++++++++++++++++--- include/opcode/ppc.h | 16 +++++++++++++ 2 files changed, 67 insertions(+), 3 deletions(-) diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 95000fd28a9..cd0ba56ddff 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -3106,12 +3106,29 @@ parse_tls_arg (char **str, const expressionS *exp, struct ppc_fixup *tls_fix) } #endif +/* Parse svp64 extra operands given to the MACRO opcode starting at S, + then its operands, and assemble the svp64 macro. */ + +static void +parse_svp64_macro (char *s, struct powerpc_macro *macro) +{ + as_bad (_("`sv.'-prefixed macros are not supported")); +} + +/* Parse extra operands at S, and initialize SVP64_PREFIX with them. */ +static void +parse_svp64_operands (char **s, uint32_t *svp64_prefix, ppc_cpu_t flags) +{ + *svp64_prefix = (uint32_t)1 << 26; + /* Do nothing for now. */ +} + /* This routine is called for each instruction to be assembled. */ void md_assemble (char *str) { - char *s; + char *s, *spfx = str; const struct powerpc_opcode *opcode; uint64_t insn; const unsigned char *opindex_ptr; @@ -3123,10 +3140,20 @@ md_assemble (char *str) int addr_mask; int i; unsigned int insn_length; + bfd_boolean svp64 = FALSE; + char opc_trailer; + uint32_t svp64_prefix; + + if (strncmp (str, "sv.", 3) == 0) + { + svp64 = TRUE; + str += 3; + } /* Get the opcode. */ - for (s = str; *s != '\0' && ! ISSPACE (*s); s++) + for (s = str; *s != '\0' && ! ISSPACE (*s) && (!svp64 || *s != '/'); s++) ; + opc_trailer = *s; if (*s != '\0') *s++ = '\0'; @@ -3139,7 +3166,14 @@ md_assemble (char *str) macro = (const struct powerpc_macro *) str_hash_find (ppc_macro_hash, str); if (macro == (const struct powerpc_macro *) NULL) - as_bad (_("unrecognized opcode: `%s'"), str); + as_bad (_("unrecognized opcode: `%s'"), spfx); + else if (svp64 && !(macro->flags & PPC_OPCODE_SVP64PFX)) + as_bad (_("opcode is not `sv.'-prefixable: `%s'"), str); + else if (svp64) + { + *--s = opc_trailer; + ppc_svp64_macro (s, macro); + } else ppc_macro (s, macro); @@ -3158,6 +3192,20 @@ md_assemble (char *str) return; } + if (svp64) + { + if (!(opcode->flags & PPC_OPCODE_SVP64PFX)) + { + as_bad (_("opcode is not `sv.'-prefixable: `%s'"), str); + ppc_clear_labels (); + return; + } + + *--s = opc_trailer; + parse_svp64_operands (&s, &svp64_prefix, + opcode->flags & PPC_OPCODE_SVP64MSK); + } + str = s; while (ISSPACE (*str)) ++str; diff --git a/include/opcode/ppc.h b/include/opcode/ppc.h index a5ee560aa17..8c356b1ff4c 100644 --- a/include/opcode/ppc.h +++ b/include/opcode/ppc.h @@ -231,6 +231,22 @@ extern const unsigned int spe2_num_opcodes; /* Opcode is only supported by power10 architecture. */ #define PPC_OPCODE_POWER10 0x400000000000ull +/* Opcode is a standalone, unprefixed SVP64 opcode (e.g. setvl). */ +#define PPC_OPCODE_SVP64OPC 0x800000000000ull + +/* Opcode is SVP64-prefixed, with EXTRA2 encoding. */ +#define PPC_OPCODE_SVP64XT2 0x1000000000000ull + +/* Opcode is SVP64-prefixed, with EXTRA3 encoding. */ +#define PPC_OPCODE_SVP64XT3 0x1800000000000ull + +/* Opcode is SVP64-prefixed, with either EXTRA encoding. */ +#define PPC_OPCODE_SVP64PFX 0x1000000000000ull + +/* Opcode is SVP64-related, prefixed or standalone. */ +#define PPC_OPCODE_SVP64MSK 0x1800000000000ull + + /* A macro to extract the major opcode from an instruction. */ #define PPC_OP(i) (((i) >> 26) & 0x3f) -- 2.30.2