This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RE: [PATCHv2 2/4] gas/arc: Additional work to support multiple arc_opcode chains
- From: Claudiu Zissulescu <Claudiu dot Zissulescu at synopsys dot com>
- To: Andrew Burgess <andrew dot burgess at embecosm dot com>, "binutils at sourceware dot org" <binutils at sourceware dot org>
- Cc: "Cupertino dot Miranda at synopsys dot com" <Cupertino dot Miranda at synopsys dot com>, "noamca at mellanox dot com" <noamca at mellanox dot com>
- Date: Thu, 7 Apr 2016 13:14:35 +0000
- Subject: RE: [PATCHv2 2/4] gas/arc: Additional work to support multiple arc_opcode chains
- Authentication-results: sourceware.org; auth=none
- References: <1459637470-30538-1-git-send-email-andrew dot burgess at embecosm dot com> <1460033811-17805-3-git-send-email-andrew dot burgess at embecosm dot com>
This also seems all right to me.
Cheers,
Claudiu
> -----Original Message-----
> From: Andrew Burgess [mailto:andrew.burgess@embecosm.com]
> Sent: Thursday, April 07, 2016 2:57 PM
> To: binutils@sourceware.org
> Cc: Claudiu.Zissulescu@synopsys.com; Cupertino.Miranda@synopsys.com;
> noamca@mellanox.com; Andrew Burgess
> Subject: [PATCHv2 2/4] gas/arc: Additional work to support multiple
> arc_opcode chains
>
> Building on earlier commits, this commit moves along support for having
> multiple arc_opcode entries in the arc_opcodes table that have the same
> mnemonic (name) field, but are not stored in a contiguous block in the
> table.
>
> In this commit we support looking up the arc_opcode_hash_entry from the
> hash table, and passing this along to the find_opcode_match function,
> which then finds the specific arc_opcode that we're assembling. We
> still don't actually support the multiple chains of arc_opcode entries
> in this commit, but the limitation is now isolated to the
> find_opcode_match function.
>
> There is no user visible change after this commit.
>
> gas/ChangeLog:
>
> * config/tc-arc.c (arc_find_opcode): Now returns
> arc_opcode_hash_entry pointer.
> (find_opcode_match): Update argument type, extract arc_opcode
> from
> incoming arc_opcode_hash_entry.
> (find_special_case_pseudo): Update return type.
> (find_special_case_flag): Update return type.
> (find_special_case): Update return type.
> (assemble_tokens): Lookup arc_opcode_hash_entry based on
> instruction mnemonic, then use find_opcode_match to identify
> specific arc_opcode.
> ---
> gas/ChangeLog | 13 ++++++++++
> gas/config/tc-arc.c | 68 ++++++++++++++++++++++++++-----------------------
> ----
> 2 files changed, 46 insertions(+), 35 deletions(-)
>
> diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c
> index 1dcf125..5b76a07 100644
> --- a/gas/config/tc-arc.c
> +++ b/gas/config/tc-arc.c
> @@ -564,27 +564,17 @@ static bfd_boolean assembling_insn = FALSE;
>
> /* Functions implementation. */
>
> -/* Return a pointer to the first entry in ARC_OPCODE_HASH that matches
> - NAME, or NULL if there are no matching entries. */
> +/* Return a pointer to ARC_OPCODE_HASH_ENTRY that identifies all
> + ARC_OPCODE entries in ARC_OPCODE_HASH that match NAME, or NULL if
> there
> + are no matching entries in ARC_OPCODE_HASH. */
>
> -static const struct arc_opcode *
> +static const struct arc_opcode_hash_entry *
> arc_find_opcode (const char *name)
> {
> const struct arc_opcode_hash_entry *entry;
> - const struct arc_opcode *opcode;
>
> entry = hash_find (arc_opcode_hash, name);
> - if (entry != NULL)
> - {
> - if (entry->count > 1)
> - as_fatal (_("unable to lookup `%s', too many opcode chains"),
> - name);
> - opcode = *entry->opcode;
> - }
> - else
> - opcode = NULL;
> -
> - return opcode;
> + return entry;
> }
>
> /* Like md_number_to_chars but used for limms. The 4-byte limm value,
> @@ -1409,13 +1399,14 @@ check_cpu_feature (insn_subclass_t sc)
> syntax match. */
>
> static const struct arc_opcode *
> -find_opcode_match (const struct arc_opcode *first_opcode,
> +find_opcode_match (const struct arc_opcode_hash_entry *entry,
> expressionS *tok,
> int *pntok,
> struct arc_flags *first_pflag,
> int nflgs,
> int *pcpumatch)
> {
> + const struct arc_opcode *first_opcode = entry->opcode[0];
> const struct arc_opcode *opcode = first_opcode;
> int ntok = *pntok;
> int got_cpu_match = 0;
> @@ -1423,6 +1414,10 @@ find_opcode_match (const struct arc_opcode
> *first_opcode,
> int bkntok;
> expressionS emptyE;
>
> + gas_assert (entry->count > 0);
> + if (entry->count > 1)
> + as_fatal (_("unable to lookup `%s', too many opcode chains"),
> + first_opcode->name);
> memset (&emptyE, 0, sizeof (emptyE));
> memcpy (bktok, tok, MAX_INSN_ARGS * sizeof (*tok));
> bkntok = ntok;
> @@ -1873,7 +1868,7 @@ find_pseudo_insn (const char *opname,
>
> /* Assumes the expressionS *tok is of sufficient size. */
>
> -static const struct arc_opcode *
> +static const struct arc_opcode_hash_entry *
> find_special_case_pseudo (const char *opname,
> int *ntok,
> expressionS *tok,
> @@ -1968,7 +1963,7 @@ find_special_case_pseudo (const char *opname,
> return arc_find_opcode (pseudo_insn->mnemonic_r);
> }
>
> -static const struct arc_opcode *
> +static const struct arc_opcode_hash_entry *
> find_special_case_flag (const char *opname,
> int *nflgs,
> struct arc_flags *pflags)
> @@ -1978,7 +1973,7 @@ find_special_case_flag (const char *opname,
> unsigned flag_idx, flag_arr_idx;
> size_t flaglen, oplen;
> const struct arc_flag_special *arc_flag_special_opcode;
> - const struct arc_opcode *opcode;
> + const struct arc_opcode_hash_entry *entry;
>
> /* Search for special case instruction. */
> for (i = 0; i < arc_num_flag_special; i++)
> @@ -2001,14 +1996,14 @@ find_special_case_flag (const char *opname,
> flaglen = strlen (flagnm);
> if (strcmp (opname + oplen, flagnm) == 0)
> {
> - opcode = arc_find_opcode (arc_flag_special_opcode->name);
> + entry = arc_find_opcode (arc_flag_special_opcode->name);
>
> if (*nflgs + 1 > MAX_INSN_FLGS)
> break;
> memcpy (pflags[*nflgs].name, flagnm, flaglen);
> pflags[*nflgs].name[flaglen] = '\0';
> (*nflgs)++;
> - return opcode;
> + return entry;
> }
> }
> }
> @@ -2017,21 +2012,21 @@ find_special_case_flag (const char *opname,
>
> /* Used to find special case opcode. */
>
> -static const struct arc_opcode *
> +static const struct arc_opcode_hash_entry *
> find_special_case (const char *opname,
> int *nflgs,
> struct arc_flags *pflags,
> expressionS *tok,
> int *ntok)
> {
> - const struct arc_opcode *opcode;
> + const struct arc_opcode_hash_entry *entry;
>
> - opcode = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
> + entry = find_special_case_pseudo (opname, ntok, tok, nflgs, pflags);
>
> - if (opcode == NULL)
> - opcode = find_special_case_flag (opname, nflgs, pflags);
> + if (entry == NULL)
> + entry = find_special_case_flag (opname, nflgs, pflags);
>
> - return opcode;
> + return entry;
> }
>
> /* Given an opcode name, pre-tockenized set of argumenst and the
> @@ -2045,27 +2040,30 @@ assemble_tokens (const char *opname,
> int nflgs)
> {
> bfd_boolean found_something = FALSE;
> - const struct arc_opcode *opcode;
> + const struct arc_opcode_hash_entry *entry;
> int cpumatch = 1;
>
> /* Search opcodes. */
> - opcode = arc_find_opcode (opname);
> + entry = arc_find_opcode (opname);
>
> /* Couldn't find opcode conventional way, try special cases. */
> - if (!opcode)
> - opcode = find_special_case (opname, &nflgs, pflags, tok, &ntok);
> + if (entry == NULL)
> + entry = find_special_case (opname, &nflgs, pflags, tok, &ntok);
>
> - if (opcode)
> + if (entry != NULL)
> {
> + const struct arc_opcode *opcode;
> +
> pr_debug ("%s:%d: assemble_tokens: %s trying opcode 0x%08X\n",
> frag_now->fr_file, frag_now->fr_line, opcode->name,
> opcode->opcode);
> -
> found_something = TRUE;
> - opcode = find_opcode_match (opcode, tok, &ntok, pflags, nflgs,
> &cpumatch);
> - if (opcode)
> + opcode = find_opcode_match (entry, tok, &ntok, pflags,
> + nflgs, &cpumatch);
> + if (opcode != NULL)
> {
> struct arc_insn insn;
> +
> assemble_insn (opcode, tok, ntok, pflags, nflgs, &insn);
> emit_insn (&insn);
> return;
> --
> 2.5.1