[PATCHv2 2/4] gas/arc: Additional work to support multiple arc_opcode chains

Claudiu Zissulescu Claudiu.Zissulescu@synopsys.com
Thu Apr 7 13:14:00 GMT 2016


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



More information about the Binutils mailing list