xref: /netbsd-src/external/gpl3/binutils.old/dist/opcodes/arc-ext.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
175fd0b74Schristos /* ARC target-dependent stuff.  Extension structure access functions
2*e992f068Schristos    Copyright (C) 1995-2022 Free Software Foundation, Inc.
375fd0b74Schristos 
475fd0b74Schristos    This file is part of libopcodes.
575fd0b74Schristos 
675fd0b74Schristos    This library is free software; you can redistribute it and/or modify
775fd0b74Schristos    it under the terms of the GNU General Public License as published by
875fd0b74Schristos    the Free Software Foundation; either version 3, or (at your option)
975fd0b74Schristos    any later version.
1075fd0b74Schristos 
1175fd0b74Schristos    It is distributed in the hope that it will be useful, but WITHOUT
1275fd0b74Schristos    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1375fd0b74Schristos    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
1475fd0b74Schristos    License for more details.
1575fd0b74Schristos 
1675fd0b74Schristos    You should have received a copy of the GNU General Public License
1775fd0b74Schristos    along with this program; if not, write to the Free Software
1875fd0b74Schristos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
1975fd0b74Schristos    MA 02110-1301, USA.  */
2075fd0b74Schristos 
2175fd0b74Schristos #include "sysdep.h"
2275fd0b74Schristos #include <stdlib.h>
2375fd0b74Schristos #include <stdio.h>
2475fd0b74Schristos 
2575fd0b74Schristos #include "bfd.h"
2675fd0b74Schristos #include "arc-ext.h"
2775fd0b74Schristos #include "elf/arc.h"
2875fd0b74Schristos #include "libiberty.h"
2975fd0b74Schristos 
3075fd0b74Schristos /* This module provides support for extensions to the ARC processor
3175fd0b74Schristos    architecture.  */
3275fd0b74Schristos 
3375fd0b74Schristos 
3475fd0b74Schristos /* Local constants.  */
3575fd0b74Schristos 
3675fd0b74Schristos #define FIRST_EXTENSION_CORE_REGISTER   32
3775fd0b74Schristos #define LAST_EXTENSION_CORE_REGISTER    59
3875fd0b74Schristos #define FIRST_EXTENSION_CONDITION_CODE  0x10
3975fd0b74Schristos #define LAST_EXTENSION_CONDITION_CODE   0x1f
4075fd0b74Schristos 
4175fd0b74Schristos #define NUM_EXT_CORE      \
4275fd0b74Schristos   (LAST_EXTENSION_CORE_REGISTER  - FIRST_EXTENSION_CORE_REGISTER  + 1)
4375fd0b74Schristos #define NUM_EXT_COND      \
4475fd0b74Schristos   (LAST_EXTENSION_CONDITION_CODE - FIRST_EXTENSION_CONDITION_CODE + 1)
4575fd0b74Schristos #define INST_HASH_BITS    6
4675fd0b74Schristos #define INST_HASH_SIZE    (1 << INST_HASH_BITS)
4775fd0b74Schristos #define INST_HASH_MASK    (INST_HASH_SIZE - 1)
4875fd0b74Schristos 
4975fd0b74Schristos 
5075fd0b74Schristos /* Local types.  */
5175fd0b74Schristos 
5275fd0b74Schristos /* These types define the information stored in the table.  */
5375fd0b74Schristos 
5475fd0b74Schristos struct ExtAuxRegister
5575fd0b74Schristos {
56012573ebSchristos   unsigned		  address;
5775fd0b74Schristos   char *		  name;
5875fd0b74Schristos   struct ExtAuxRegister * next;
5975fd0b74Schristos };
6075fd0b74Schristos 
6175fd0b74Schristos struct ExtCoreRegister
6275fd0b74Schristos {
6375fd0b74Schristos   short		    number;
6475fd0b74Schristos   enum ExtReadWrite rw;
6575fd0b74Schristos   char *	    name;
6675fd0b74Schristos };
6775fd0b74Schristos 
6875fd0b74Schristos struct arcExtMap
6975fd0b74Schristos {
7075fd0b74Schristos   struct ExtAuxRegister* auxRegisters;
7175fd0b74Schristos   struct ExtInstruction* instructions[INST_HASH_SIZE];
7275fd0b74Schristos   struct ExtCoreRegister coreRegisters[NUM_EXT_CORE];
7375fd0b74Schristos   char *		 condCodes[NUM_EXT_COND];
7475fd0b74Schristos };
7575fd0b74Schristos 
7675fd0b74Schristos 
7775fd0b74Schristos /* Local data.  */
7875fd0b74Schristos 
7975fd0b74Schristos /* Extension table.  */
8075fd0b74Schristos static struct arcExtMap arc_extension_map;
8175fd0b74Schristos 
8275fd0b74Schristos 
8375fd0b74Schristos /* Local macros.  */
8475fd0b74Schristos 
8575fd0b74Schristos /* A hash function used to map instructions into the table.  */
8675fd0b74Schristos #define INST_HASH(MAJOR, MINOR)    ((((MAJOR) << 3) ^ (MINOR)) & INST_HASH_MASK)
8775fd0b74Schristos 
8875fd0b74Schristos 
8975fd0b74Schristos /* Local functions.  */
9075fd0b74Schristos 
9175fd0b74Schristos static void
create_map(unsigned char * block,unsigned long length)9275fd0b74Schristos create_map (unsigned char *block,
9375fd0b74Schristos 	    unsigned long length)
9475fd0b74Schristos {
9575fd0b74Schristos   unsigned char *p = block;
9675fd0b74Schristos 
9775fd0b74Schristos   while (p && p < (block + length))
9875fd0b74Schristos     {
9975fd0b74Schristos       /* p[0] == length of record
10075fd0b74Schristos 	 p[1] == type of record
10175fd0b74Schristos 	 For instructions:
10275fd0b74Schristos 	   p[2]  = opcode
10375fd0b74Schristos 	   p[3]  = minor opcode (if opcode == 3)
10475fd0b74Schristos 	   p[4]  = flags
10575fd0b74Schristos 	   p[5]+ = name
10675fd0b74Schristos 	 For core regs and condition codes:
10775fd0b74Schristos 	   p[2]  = value
10875fd0b74Schristos 	   p[3]+ = name
10975fd0b74Schristos 	 For auxiliary regs:
11075fd0b74Schristos 	   p[2..5] = value
11175fd0b74Schristos 	   p[6]+   = name
11275fd0b74Schristos 	     (value is p[2]<<24|p[3]<<16|p[4]<<8|p[5]).  */
11375fd0b74Schristos 
11475fd0b74Schristos       /* The sequence of records is temrinated by an "empty"
11575fd0b74Schristos 	 record.  */
11675fd0b74Schristos       if (p[0] == 0)
11775fd0b74Schristos 	break;
11875fd0b74Schristos 
11975fd0b74Schristos       switch (p[1])
12075fd0b74Schristos 	{
12175fd0b74Schristos 	case EXT_INSTRUCTION:
12275fd0b74Schristos 	  {
12375fd0b74Schristos 	    struct ExtInstruction  *insn = XNEW (struct ExtInstruction);
12475fd0b74Schristos 	    int			    major = p[2];
12575fd0b74Schristos 	    int			    minor = p[3];
12675fd0b74Schristos 	    struct ExtInstruction **bucket =
12775fd0b74Schristos 		   &arc_extension_map.instructions[INST_HASH (major, minor)];
12875fd0b74Schristos 
12975fd0b74Schristos 	    insn->name  = xstrdup ((char *) (p + 5));
13075fd0b74Schristos 	    insn->major = major;
13175fd0b74Schristos 	    insn->minor = minor;
13275fd0b74Schristos 	    insn->flags = p[4];
13375fd0b74Schristos 	    insn->next  = *bucket;
13475fd0b74Schristos 	    insn->suffix = 0;
13575fd0b74Schristos 	    insn->syntax = 0;
13675fd0b74Schristos 	    insn->modsyn = 0;
13775fd0b74Schristos 	    *bucket = insn;
13875fd0b74Schristos 	    break;
13975fd0b74Schristos 	  }
14075fd0b74Schristos 
14175fd0b74Schristos 	case EXT_CORE_REGISTER:
14275fd0b74Schristos 	  {
14375fd0b74Schristos 	    unsigned char number = p[2];
14475fd0b74Schristos 	    char*	  name	 = (char *) (p + 3);
14575fd0b74Schristos 
14675fd0b74Schristos 	    arc_extension_map.
14775fd0b74Schristos 	      coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].number
14875fd0b74Schristos 	      = number;
14975fd0b74Schristos 	    arc_extension_map.
15075fd0b74Schristos 	      coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].rw
15175fd0b74Schristos 	      = REG_READWRITE;
15275fd0b74Schristos 	    arc_extension_map.
15375fd0b74Schristos 	      coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].name
15475fd0b74Schristos 	      = xstrdup (name);
15575fd0b74Schristos 	    break;
15675fd0b74Schristos 	  }
15775fd0b74Schristos 
15875fd0b74Schristos 	case EXT_LONG_CORE_REGISTER:
15975fd0b74Schristos 	  {
16075fd0b74Schristos 	    unsigned char     number = p[2];
16175fd0b74Schristos 	    char*	      name   = (char *) (p + 7);
16275fd0b74Schristos 	    enum ExtReadWrite rw     = p[6];
16375fd0b74Schristos 
16475fd0b74Schristos 	    arc_extension_map.
16575fd0b74Schristos 	      coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].number
16675fd0b74Schristos 	      = number;
16775fd0b74Schristos 	    arc_extension_map.
16875fd0b74Schristos 	      coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].rw
16975fd0b74Schristos 	      = rw;
17075fd0b74Schristos 	    arc_extension_map.
17175fd0b74Schristos 	      coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].name
17275fd0b74Schristos 	      = xstrdup (name);
173ede78133Schristos 	    break;
17475fd0b74Schristos 	  }
17575fd0b74Schristos 
17675fd0b74Schristos 	case EXT_COND_CODE:
17775fd0b74Schristos 	  {
17875fd0b74Schristos 	    char *cc_name = xstrdup ((char *) (p + 3));
17975fd0b74Schristos 
18075fd0b74Schristos 	    arc_extension_map.
18175fd0b74Schristos 	      condCodes[p[2] - FIRST_EXTENSION_CONDITION_CODE]
18275fd0b74Schristos 	      = cc_name;
18375fd0b74Schristos 	    break;
18475fd0b74Schristos 	  }
18575fd0b74Schristos 
18675fd0b74Schristos 	case EXT_AUX_REGISTER:
18775fd0b74Schristos 	  {
18875fd0b74Schristos 	    /* Trickier -- need to store linked list of these.  */
18975fd0b74Schristos 	    struct ExtAuxRegister *newAuxRegister
19075fd0b74Schristos 	      = XNEW (struct ExtAuxRegister);
19175fd0b74Schristos 	    char *aux_name = xstrdup ((char *) (p + 6));
19275fd0b74Schristos 
19375fd0b74Schristos 	    newAuxRegister->name = aux_name;
194012573ebSchristos 	    newAuxRegister->address = (((unsigned) p[2] << 24) | (p[3] << 16)
195012573ebSchristos 				       | (p[4] << 8) | p[5]);
19675fd0b74Schristos 	    newAuxRegister->next = arc_extension_map.auxRegisters;
19775fd0b74Schristos 	    arc_extension_map.auxRegisters = newAuxRegister;
19875fd0b74Schristos 	    break;
19975fd0b74Schristos 	  }
20075fd0b74Schristos 
20175fd0b74Schristos 	default:
20275fd0b74Schristos 	  break;
20375fd0b74Schristos 	}
20475fd0b74Schristos 
20575fd0b74Schristos       p += p[0]; /* Move on to next record.  */
20675fd0b74Schristos     }
20775fd0b74Schristos }
20875fd0b74Schristos 
20975fd0b74Schristos 
21075fd0b74Schristos /* Free memory that has been allocated for the extensions.  */
21175fd0b74Schristos 
21275fd0b74Schristos static void
destroy_map(void)21375fd0b74Schristos destroy_map (void)
21475fd0b74Schristos {
21575fd0b74Schristos   struct ExtAuxRegister *r;
21675fd0b74Schristos   unsigned int		 i;
21775fd0b74Schristos 
21875fd0b74Schristos   /* Free auxiliary registers.  */
21975fd0b74Schristos   r = arc_extension_map.auxRegisters;
22075fd0b74Schristos   while (r)
22175fd0b74Schristos     {
22275fd0b74Schristos       /* N.B. after r has been freed, r->next is invalid!  */
22375fd0b74Schristos       struct ExtAuxRegister* next = r->next;
22475fd0b74Schristos 
22575fd0b74Schristos       free (r->name);
22675fd0b74Schristos       free (r);
22775fd0b74Schristos       r = next;
22875fd0b74Schristos     }
22975fd0b74Schristos 
23075fd0b74Schristos   /* Free instructions.  */
23175fd0b74Schristos   for (i = 0; i < INST_HASH_SIZE; i++)
23275fd0b74Schristos     {
23375fd0b74Schristos       struct ExtInstruction *insn = arc_extension_map.instructions[i];
23475fd0b74Schristos 
23575fd0b74Schristos       while (insn)
23675fd0b74Schristos 	{
23775fd0b74Schristos 	  /* N.B. after insn has been freed, insn->next is invalid!  */
23875fd0b74Schristos 	  struct ExtInstruction *next = insn->next;
23975fd0b74Schristos 
24075fd0b74Schristos 	  free (insn->name);
24175fd0b74Schristos 	  free (insn);
24275fd0b74Schristos 	  insn = next;
24375fd0b74Schristos 	}
24475fd0b74Schristos     }
24575fd0b74Schristos 
24675fd0b74Schristos   /* Free core registers.  */
24775fd0b74Schristos   for (i = 0; i < NUM_EXT_CORE; i++)
24875fd0b74Schristos     free (arc_extension_map.coreRegisters[i].name);
24975fd0b74Schristos 
25075fd0b74Schristos   /* Free condition codes.  */
25175fd0b74Schristos   for (i = 0; i < NUM_EXT_COND; i++)
25275fd0b74Schristos     free (arc_extension_map.condCodes[i]);
25375fd0b74Schristos 
25475fd0b74Schristos   memset (&arc_extension_map, 0, sizeof (arc_extension_map));
25575fd0b74Schristos }
25675fd0b74Schristos 
25775fd0b74Schristos 
25875fd0b74Schristos static const char *
ExtReadWrite_image(enum ExtReadWrite val)25975fd0b74Schristos ExtReadWrite_image (enum ExtReadWrite val)
26075fd0b74Schristos {
26175fd0b74Schristos     switch (val)
26275fd0b74Schristos     {
26375fd0b74Schristos 	case REG_INVALID  : return "INVALID";
26475fd0b74Schristos 	case REG_READ	  : return "RO";
26575fd0b74Schristos 	case REG_WRITE	  : return "WO";
26675fd0b74Schristos 	case REG_READWRITE: return "R/W";
26775fd0b74Schristos 	default		  : return "???";
26875fd0b74Schristos     }
26975fd0b74Schristos }
27075fd0b74Schristos 
27175fd0b74Schristos 
27275fd0b74Schristos /* Externally visible functions.  */
27375fd0b74Schristos 
27475fd0b74Schristos /* Get the name of an extension instruction.  */
27575fd0b74Schristos 
27675fd0b74Schristos const extInstruction_t *
arcExtMap_insn(int opcode,unsigned long long insn)277ede78133Schristos arcExtMap_insn (int opcode, unsigned long long insn)
27875fd0b74Schristos {
27975fd0b74Schristos   /* Here the following tasks need to be done.  First of all, the
28075fd0b74Schristos      opcode stored in the Extension Map is the real opcode.  However,
28175fd0b74Schristos      the subopcode stored in the instruction to be disassembled is
28275fd0b74Schristos      mangled.  We pass (in minor opcode), the instruction word.  Here
28375fd0b74Schristos      we will un-mangle it and get the real subopcode which we can look
28475fd0b74Schristos      for in the Extension Map.  This function is used both for the
28575fd0b74Schristos      ARCTangent and the ARCompact, so we would also need some sort of
28675fd0b74Schristos      a way to distinguish between the two architectures.  This is
28775fd0b74Schristos      because the ARCTangent does not do any of this mangling so we
28875fd0b74Schristos      have no issues there.  */
28975fd0b74Schristos 
29075fd0b74Schristos   /* If P[22:23] is 0 or 2 then un-mangle using iiiiiI.  If it is 1
29175fd0b74Schristos      then use iiiiIi.  Now, if P is 3 then check M[5:5] and if it is 0
29275fd0b74Schristos      then un-mangle using iiiiiI else iiiiii.  */
29375fd0b74Schristos 
29475fd0b74Schristos   unsigned char minor;
29575fd0b74Schristos   extInstruction_t *temp;
29675fd0b74Schristos 
29775fd0b74Schristos   /* 16-bit instructions.  */
29875fd0b74Schristos   if (0x08 <= opcode && opcode <= 0x0b)
29975fd0b74Schristos     {
30075fd0b74Schristos       unsigned char b, c, i;
30175fd0b74Schristos 
30275fd0b74Schristos       b = (insn & 0x0700) >> 8;
30375fd0b74Schristos       c = (insn & 0x00e0) >> 5;
30475fd0b74Schristos       i = (insn & 0x001f);
30575fd0b74Schristos 
30675fd0b74Schristos       if (i)
30775fd0b74Schristos 	minor = i;
30875fd0b74Schristos       else
30975fd0b74Schristos 	minor = (c == 0x07) ? b : c;
31075fd0b74Schristos     }
31175fd0b74Schristos   /* 32-bit instructions.  */
31275fd0b74Schristos   else
31375fd0b74Schristos     {
31475fd0b74Schristos       unsigned char I, A, B;
31575fd0b74Schristos 
31675fd0b74Schristos       I = (insn & 0x003f0000) >> 16;
31775fd0b74Schristos       A = (insn & 0x0000003f);
31875fd0b74Schristos       B = ((insn & 0x07000000) >> 24) | ((insn & 0x00007000) >> 9);
31975fd0b74Schristos 
32075fd0b74Schristos       if (I != 0x2f)
32175fd0b74Schristos 	{
32275fd0b74Schristos #ifndef UNMANGLED
32375fd0b74Schristos 	  switch (P)
32475fd0b74Schristos 	    {
32575fd0b74Schristos 	    case 3:
32675fd0b74Schristos 	      if (M)
32775fd0b74Schristos 		{
32875fd0b74Schristos 		  minor = I;
32975fd0b74Schristos 		  break;
33075fd0b74Schristos 		}
33175fd0b74Schristos 	    case 0:
33275fd0b74Schristos 	    case 2:
33375fd0b74Schristos 	      minor = (I >> 1) | ((I & 0x1) << 5);
33475fd0b74Schristos 	      break;
33575fd0b74Schristos 	    case 1:
33675fd0b74Schristos 	      minor = (I >> 1) | (I & 0x1) | ((I & 0x2) << 4);
33775fd0b74Schristos 	    }
33875fd0b74Schristos #else
33975fd0b74Schristos 	  minor = I;
34075fd0b74Schristos #endif
34175fd0b74Schristos 	}
34275fd0b74Schristos       else
34375fd0b74Schristos 	{
34475fd0b74Schristos 	  if (A != 0x3f)
34575fd0b74Schristos 	    minor = A;
34675fd0b74Schristos 	  else
34775fd0b74Schristos 	    minor = B;
34875fd0b74Schristos 	}
34975fd0b74Schristos     }
35075fd0b74Schristos 
35175fd0b74Schristos   temp = arc_extension_map.instructions[INST_HASH (opcode, minor)];
35275fd0b74Schristos   while (temp)
35375fd0b74Schristos     {
35475fd0b74Schristos       if ((temp->major == opcode) && (temp->minor == minor))
35575fd0b74Schristos 	{
35675fd0b74Schristos 	  return temp;
35775fd0b74Schristos 	}
35875fd0b74Schristos       temp = temp->next;
35975fd0b74Schristos     }
36075fd0b74Schristos 
36175fd0b74Schristos   return NULL;
36275fd0b74Schristos }
36375fd0b74Schristos 
36475fd0b74Schristos /* Get the name of an extension core register.  */
36575fd0b74Schristos 
36675fd0b74Schristos const char *
arcExtMap_coreRegName(int regnum)36775fd0b74Schristos arcExtMap_coreRegName (int regnum)
36875fd0b74Schristos {
36975fd0b74Schristos   if (regnum < FIRST_EXTENSION_CORE_REGISTER
37075fd0b74Schristos       || regnum > LAST_EXTENSION_CORE_REGISTER)
37175fd0b74Schristos     return NULL;
37275fd0b74Schristos   return arc_extension_map.
37375fd0b74Schristos     coreRegisters[regnum - FIRST_EXTENSION_CORE_REGISTER].name;
37475fd0b74Schristos }
37575fd0b74Schristos 
37675fd0b74Schristos /* Get the access mode of an extension core register.  */
37775fd0b74Schristos 
37875fd0b74Schristos enum ExtReadWrite
arcExtMap_coreReadWrite(int regnum)37975fd0b74Schristos arcExtMap_coreReadWrite (int regnum)
38075fd0b74Schristos {
38175fd0b74Schristos   if (regnum < FIRST_EXTENSION_CORE_REGISTER
38275fd0b74Schristos       || regnum > LAST_EXTENSION_CORE_REGISTER)
38375fd0b74Schristos     return REG_INVALID;
38475fd0b74Schristos   return arc_extension_map.
38575fd0b74Schristos     coreRegisters[regnum - FIRST_EXTENSION_CORE_REGISTER].rw;
38675fd0b74Schristos }
38775fd0b74Schristos 
38875fd0b74Schristos /* Get the name of an extension condition code.  */
38975fd0b74Schristos 
39075fd0b74Schristos const char *
arcExtMap_condCodeName(int code)39175fd0b74Schristos arcExtMap_condCodeName (int code)
39275fd0b74Schristos {
39375fd0b74Schristos   if (code < FIRST_EXTENSION_CONDITION_CODE
39475fd0b74Schristos       || code > LAST_EXTENSION_CONDITION_CODE)
39575fd0b74Schristos     return NULL;
39675fd0b74Schristos   return arc_extension_map.
39775fd0b74Schristos     condCodes[code - FIRST_EXTENSION_CONDITION_CODE];
39875fd0b74Schristos }
39975fd0b74Schristos 
40075fd0b74Schristos /* Get the name of an extension auxiliary register.  */
40175fd0b74Schristos 
40275fd0b74Schristos const char *
arcExtMap_auxRegName(unsigned address)403012573ebSchristos arcExtMap_auxRegName (unsigned address)
40475fd0b74Schristos {
40575fd0b74Schristos   /* Walk the list of auxiliary register names and find the name.  */
40675fd0b74Schristos   struct ExtAuxRegister *r;
40775fd0b74Schristos 
40875fd0b74Schristos   for (r = arc_extension_map.auxRegisters; r; r = r->next)
40975fd0b74Schristos     {
41075fd0b74Schristos       if (r->address == address)
41175fd0b74Schristos 	return (const char *)r->name;
41275fd0b74Schristos     }
41375fd0b74Schristos   return NULL;
41475fd0b74Schristos }
41575fd0b74Schristos 
41675fd0b74Schristos /* Load extensions described in .arcextmap and
41775fd0b74Schristos    .gnu.linkonce.arcextmap.* ELF section.  */
41875fd0b74Schristos 
41975fd0b74Schristos void
build_ARC_extmap(bfd * text_bfd)42075fd0b74Schristos build_ARC_extmap (bfd *text_bfd)
42175fd0b74Schristos {
42275fd0b74Schristos   asection *sect;
42375fd0b74Schristos 
42475fd0b74Schristos   /* The map is built each time gdb loads an executable file - so free
42575fd0b74Schristos      any existing map, as the map defined by the new file may differ
42675fd0b74Schristos      from the old.  */
42775fd0b74Schristos   destroy_map ();
42875fd0b74Schristos 
42975fd0b74Schristos   for (sect = text_bfd->sections; sect != NULL; sect = sect->next)
43075fd0b74Schristos     if (!strncmp (sect->name,
43175fd0b74Schristos 		  ".gnu.linkonce.arcextmap.",
43275fd0b74Schristos 	  sizeof (".gnu.linkonce.arcextmap.") - 1)
43375fd0b74Schristos 	|| !strcmp (sect->name,".arcextmap"))
43475fd0b74Schristos       {
435012573ebSchristos 	bfd_size_type  count  = bfd_section_size (sect);
43675fd0b74Schristos 	unsigned char* buffer = xmalloc (count);
43775fd0b74Schristos 
43875fd0b74Schristos 	if (buffer)
43975fd0b74Schristos 	  {
44075fd0b74Schristos 	    if (bfd_get_section_contents (text_bfd, sect, buffer, 0, count))
44175fd0b74Schristos 	      create_map (buffer, count);
44275fd0b74Schristos 	    free (buffer);
44375fd0b74Schristos 	  }
44475fd0b74Schristos       }
44575fd0b74Schristos }
44675fd0b74Schristos 
44775fd0b74Schristos /* Debug function used to dump the ARC information fount in arcextmap
44875fd0b74Schristos    sections.  */
44975fd0b74Schristos 
45075fd0b74Schristos void
dump_ARC_extmap(void)45175fd0b74Schristos dump_ARC_extmap (void)
45275fd0b74Schristos {
45375fd0b74Schristos     struct ExtAuxRegister *r;
45475fd0b74Schristos     int			   i;
45575fd0b74Schristos 
45675fd0b74Schristos     r = arc_extension_map.auxRegisters;
45775fd0b74Schristos 
45875fd0b74Schristos     while (r)
45975fd0b74Schristos     {
460012573ebSchristos 	printf ("AUX : %s %u\n", r->name, r->address);
46175fd0b74Schristos 	r = r->next;
46275fd0b74Schristos     }
46375fd0b74Schristos 
46475fd0b74Schristos     for (i = 0; i < INST_HASH_SIZE; i++)
46575fd0b74Schristos     {
46675fd0b74Schristos 	struct ExtInstruction *insn;
46775fd0b74Schristos 
46875fd0b74Schristos 	for (insn = arc_extension_map.instructions[i];
46975fd0b74Schristos 	     insn != NULL; insn = insn->next)
47075fd0b74Schristos 	  {
47175fd0b74Schristos 	    printf ("INST: 0x%02x 0x%02x ", insn->major, insn->minor);
47275fd0b74Schristos 	    switch (insn->flags & ARC_SYNTAX_MASK)
47375fd0b74Schristos 	      {
47475fd0b74Schristos 	      case ARC_SYNTAX_2OP:
47575fd0b74Schristos 		printf ("SYNTAX_2OP");
47675fd0b74Schristos 		break;
47775fd0b74Schristos 	      case ARC_SYNTAX_3OP:
47875fd0b74Schristos 		printf ("SYNTAX_3OP");
47975fd0b74Schristos 		break;
48075fd0b74Schristos 	      case ARC_SYNTAX_1OP:
48175fd0b74Schristos 		printf ("SYNTAX_1OP");
48275fd0b74Schristos 		break;
48375fd0b74Schristos 	      case ARC_SYNTAX_NOP:
48475fd0b74Schristos 		printf ("SYNTAX_NOP");
48575fd0b74Schristos 		break;
48675fd0b74Schristos 	      default:
48775fd0b74Schristos 		printf ("SYNTAX_UNK");
48875fd0b74Schristos 		break;
48975fd0b74Schristos 	      }
49075fd0b74Schristos 
49175fd0b74Schristos 	    if (insn->flags & 0x10)
49275fd0b74Schristos 	      printf ("|MODIFIER");
49375fd0b74Schristos 
49475fd0b74Schristos 	    printf (" %s\n", insn->name);
49575fd0b74Schristos 	  }
49675fd0b74Schristos     }
49775fd0b74Schristos 
49875fd0b74Schristos     for (i = 0; i < NUM_EXT_CORE; i++)
49975fd0b74Schristos     {
50075fd0b74Schristos 	struct ExtCoreRegister reg = arc_extension_map.coreRegisters[i];
50175fd0b74Schristos 
50275fd0b74Schristos 	if (reg.name)
50375fd0b74Schristos 	  printf ("CORE: 0x%04x %s %s\n", reg.number,
50475fd0b74Schristos 		  ExtReadWrite_image (reg.rw),
50575fd0b74Schristos 		  reg.name);
50675fd0b74Schristos     }
50775fd0b74Schristos 
50875fd0b74Schristos     for (i = 0; i < NUM_EXT_COND; i++)
50975fd0b74Schristos 	if (arc_extension_map.condCodes[i])
51075fd0b74Schristos 	    printf ("COND: %s\n", arc_extension_map.condCodes[i]);
51175fd0b74Schristos }
51275fd0b74Schristos 
51375fd0b74Schristos /* For a given extension instruction generate the equivalent arc
51475fd0b74Schristos    opcode structure.  */
51575fd0b74Schristos 
51675fd0b74Schristos struct arc_opcode *
arcExtMap_genOpcode(const extInstruction_t * einsn,unsigned arc_target,const char ** errmsg)51775fd0b74Schristos arcExtMap_genOpcode (const extInstruction_t *einsn,
51875fd0b74Schristos 		     unsigned arc_target,
51975fd0b74Schristos 		     const char **errmsg)
52075fd0b74Schristos {
52175fd0b74Schristos   struct arc_opcode *q, *arc_ext_opcodes = NULL;
52275fd0b74Schristos   const unsigned char *lflags_f;
52375fd0b74Schristos   const unsigned char *lflags_ccf;
52475fd0b74Schristos   int count;
52575fd0b74Schristos 
52675fd0b74Schristos   /* Check for the class to see how many instructions we generate.  */
52775fd0b74Schristos   switch (einsn->flags & ARC_SYNTAX_MASK)
52875fd0b74Schristos     {
52975fd0b74Schristos     case ARC_SYNTAX_3OP:
53075fd0b74Schristos       count = (einsn->modsyn & ARC_OP1_MUST_BE_IMM) ? 10 : 20;
53175fd0b74Schristos       break;
53275fd0b74Schristos     case ARC_SYNTAX_2OP:
53375fd0b74Schristos       count = (einsn->flags & 0x10) ? 7 : 6;
53475fd0b74Schristos       break;
53575fd0b74Schristos     case ARC_SYNTAX_1OP:
53675fd0b74Schristos       count = 3;
53775fd0b74Schristos       break;
53875fd0b74Schristos     case ARC_SYNTAX_NOP:
53975fd0b74Schristos       count = 1;
54075fd0b74Schristos       break;
54175fd0b74Schristos     default:
54275fd0b74Schristos       count = 0;
54375fd0b74Schristos       break;
54475fd0b74Schristos     }
54575fd0b74Schristos 
54675fd0b74Schristos   /* Allocate memory.  */
54775fd0b74Schristos   arc_ext_opcodes = (struct arc_opcode *)
54875fd0b74Schristos     xmalloc ((count + 1) * sizeof (*arc_ext_opcodes));
54975fd0b74Schristos 
55075fd0b74Schristos   if (arc_ext_opcodes == NULL)
55175fd0b74Schristos     {
55275fd0b74Schristos       *errmsg = "Virtual memory exhausted";
55375fd0b74Schristos       return NULL;
55475fd0b74Schristos     }
55575fd0b74Schristos 
55675fd0b74Schristos   /* Generate the patterns.  */
55775fd0b74Schristos   q = arc_ext_opcodes;
55875fd0b74Schristos 
55975fd0b74Schristos   if (einsn->suffix)
56075fd0b74Schristos     {
56175fd0b74Schristos       lflags_f   = flags_none;
56275fd0b74Schristos       lflags_ccf = flags_none;
56375fd0b74Schristos     }
56475fd0b74Schristos   else
56575fd0b74Schristos     {
56675fd0b74Schristos       lflags_f   = flags_f;
56775fd0b74Schristos       lflags_ccf = flags_ccf;
56875fd0b74Schristos     }
56975fd0b74Schristos 
57075fd0b74Schristos   if (einsn->suffix & ARC_SUFFIX_COND)
57175fd0b74Schristos     lflags_ccf = flags_cc;
57275fd0b74Schristos   if (einsn->suffix & ARC_SUFFIX_FLAG)
57375fd0b74Schristos     {
57475fd0b74Schristos       lflags_f   = flags_f;
57575fd0b74Schristos       lflags_ccf = flags_f;
57675fd0b74Schristos     }
57775fd0b74Schristos   if (einsn->suffix & (ARC_SUFFIX_FLAG | ARC_SUFFIX_COND))
57875fd0b74Schristos     lflags_ccf = flags_ccf;
57975fd0b74Schristos 
58075fd0b74Schristos   if (einsn->flags & ARC_SYNTAX_2OP
58175fd0b74Schristos       && !(einsn->flags & 0x10))
58275fd0b74Schristos     {
58375fd0b74Schristos       /* Regular 2OP instruction.  */
58475fd0b74Schristos       if (einsn->suffix & ARC_SUFFIX_COND)
58575fd0b74Schristos 	*errmsg = "Suffix SUFFIX_COND ignored";
58675fd0b74Schristos 
58775fd0b74Schristos       INSERT_XOP (q, einsn->name,
58875fd0b74Schristos 		  INSN2OP_BC (einsn->major, einsn->minor), MINSN2OP_BC,
58975fd0b74Schristos 		  arc_target, arg_32bit_rbrc, lflags_f);
59075fd0b74Schristos 
59175fd0b74Schristos       INSERT_XOP (q, einsn->name,
59275fd0b74Schristos 		  INSN2OP_0C (einsn->major, einsn->minor), MINSN2OP_0C,
59375fd0b74Schristos 		  arc_target, arg_32bit_zarc, lflags_f);
59475fd0b74Schristos 
59575fd0b74Schristos       INSERT_XOP (q, einsn->name,
59675fd0b74Schristos 		  INSN2OP_BU (einsn->major, einsn->minor), MINSN2OP_BU,
59775fd0b74Schristos 		  arc_target, arg_32bit_rbu6, lflags_f);
59875fd0b74Schristos 
59975fd0b74Schristos       INSERT_XOP (q, einsn->name,
60075fd0b74Schristos 		  INSN2OP_0U (einsn->major, einsn->minor), MINSN2OP_0U,
60175fd0b74Schristos 		  arc_target, arg_32bit_zau6, lflags_f);
60275fd0b74Schristos 
60375fd0b74Schristos       INSERT_XOP (q, einsn->name,
60475fd0b74Schristos 		  INSN2OP_BL (einsn->major, einsn->minor), MINSN2OP_BL,
60575fd0b74Schristos 		  arc_target, arg_32bit_rblimm, lflags_f);
60675fd0b74Schristos 
60775fd0b74Schristos       INSERT_XOP (q, einsn->name,
60875fd0b74Schristos 		  INSN2OP_0L (einsn->major, einsn->minor), MINSN2OP_0L,
60975fd0b74Schristos 		  arc_target, arg_32bit_zalimm, lflags_f);
61075fd0b74Schristos     }
61175fd0b74Schristos   else if (einsn->flags & (0x10 | ARC_SYNTAX_2OP))
61275fd0b74Schristos     {
61375fd0b74Schristos       /* This is actually a 3OP pattern.  The first operand is
61475fd0b74Schristos 	 immplied and is set to zero.  */
61575fd0b74Schristos       INSERT_XOP (q, einsn->name,
61675fd0b74Schristos 		  INSN3OP_0BC (einsn->major, einsn->minor),  MINSN3OP_0BC,
61775fd0b74Schristos 		  arc_target, arg_32bit_rbrc, lflags_f);
61875fd0b74Schristos 
61975fd0b74Schristos       INSERT_XOP (q, einsn->name,
62075fd0b74Schristos 		  INSN3OP_0BU (einsn->major, einsn->minor),  MINSN3OP_0BU,
62175fd0b74Schristos 		  arc_target, arg_32bit_rbu6, lflags_f);
62275fd0b74Schristos 
62375fd0b74Schristos       INSERT_XOP (q, einsn->name,
62475fd0b74Schristos 		  INSN3OP_0BL (einsn->major, einsn->minor),  MINSN3OP_0BL,
62575fd0b74Schristos 		  arc_target, arg_32bit_rblimm, lflags_f);
62675fd0b74Schristos 
62775fd0b74Schristos       INSERT_XOP (q, einsn->name,
62875fd0b74Schristos 		  INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
62975fd0b74Schristos 		  arc_target, arg_32bit_limmrc, lflags_ccf);
63075fd0b74Schristos 
63175fd0b74Schristos       INSERT_XOP (q, einsn->name,
63275fd0b74Schristos 		  INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
63375fd0b74Schristos 		  arc_target, arg_32bit_limmu6, lflags_ccf);
63475fd0b74Schristos 
63575fd0b74Schristos       INSERT_XOP (q, einsn->name,
63675fd0b74Schristos 		  INSN3OP_0LS (einsn->major, einsn->minor),  MINSN3OP_0LS,
63775fd0b74Schristos 		  arc_target, arg_32bit_limms12, lflags_f);
63875fd0b74Schristos 
63975fd0b74Schristos       INSERT_XOP (q, einsn->name,
64075fd0b74Schristos 		  INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
64175fd0b74Schristos 		  arc_target, arg_32bit_limmlimm, lflags_ccf);
64275fd0b74Schristos     }
64375fd0b74Schristos   else if (einsn->flags & ARC_SYNTAX_3OP
64475fd0b74Schristos 	   && !(einsn->modsyn & ARC_OP1_MUST_BE_IMM))
64575fd0b74Schristos     {
64675fd0b74Schristos       /* Regular 3OP instruction.  */
64775fd0b74Schristos       INSERT_XOP (q, einsn->name,
64875fd0b74Schristos 		  INSN3OP_ABC (einsn->major, einsn->minor),  MINSN3OP_ABC,
64975fd0b74Schristos 		  arc_target, arg_32bit_rarbrc, lflags_f);
65075fd0b74Schristos 
65175fd0b74Schristos       INSERT_XOP (q, einsn->name,
65275fd0b74Schristos 		  INSN3OP_0BC (einsn->major, einsn->minor),  MINSN3OP_0BC,
65375fd0b74Schristos 		  arc_target, arg_32bit_zarbrc, lflags_f);
65475fd0b74Schristos 
65575fd0b74Schristos       INSERT_XOP (q, einsn->name,
65675fd0b74Schristos 		  INSN3OP_CBBC (einsn->major, einsn->minor), MINSN3OP_CBBC,
65775fd0b74Schristos 		  arc_target, arg_32bit_rbrbrc, lflags_ccf);
65875fd0b74Schristos 
65975fd0b74Schristos       INSERT_XOP (q, einsn->name,
66075fd0b74Schristos 		  INSN3OP_ABU (einsn->major, einsn->minor),  MINSN3OP_ABU,
66175fd0b74Schristos 		  arc_target, arg_32bit_rarbu6, lflags_f);
66275fd0b74Schristos 
66375fd0b74Schristos       INSERT_XOP (q, einsn->name,
66475fd0b74Schristos 		  INSN3OP_0BU (einsn->major, einsn->minor),  MINSN3OP_0BU,
66575fd0b74Schristos 		  arc_target, arg_32bit_zarbu6, lflags_f);
66675fd0b74Schristos 
66775fd0b74Schristos       INSERT_XOP (q, einsn->name,
66875fd0b74Schristos 		  INSN3OP_CBBU (einsn->major, einsn->minor), MINSN3OP_CBBU,
66975fd0b74Schristos 		  arc_target, arg_32bit_rbrbu6, lflags_ccf);
67075fd0b74Schristos 
67175fd0b74Schristos       INSERT_XOP (q, einsn->name,
67275fd0b74Schristos 		  INSN3OP_BBS (einsn->major, einsn->minor),  MINSN3OP_BBS,
67375fd0b74Schristos 		  arc_target, arg_32bit_rbrbs12, lflags_f);
67475fd0b74Schristos 
67575fd0b74Schristos       INSERT_XOP (q, einsn->name,
67675fd0b74Schristos 		  INSN3OP_ALC (einsn->major, einsn->minor),  MINSN3OP_ALC,
67775fd0b74Schristos 		  arc_target, arg_32bit_ralimmrc, lflags_f);
67875fd0b74Schristos 
67975fd0b74Schristos       INSERT_XOP (q, einsn->name,
68075fd0b74Schristos 		  INSN3OP_ABL (einsn->major, einsn->minor),  MINSN3OP_ABL,
68175fd0b74Schristos 		  arc_target, arg_32bit_rarblimm, lflags_f);
68275fd0b74Schristos 
68375fd0b74Schristos       INSERT_XOP (q, einsn->name,
68475fd0b74Schristos 		  INSN3OP_0LC (einsn->major, einsn->minor),  MINSN3OP_0LC,
68575fd0b74Schristos 		  arc_target, arg_32bit_zalimmrc, lflags_f);
68675fd0b74Schristos 
68775fd0b74Schristos       INSERT_XOP (q, einsn->name,
68875fd0b74Schristos 		  INSN3OP_0BL (einsn->major, einsn->minor),  MINSN3OP_0BL,
68975fd0b74Schristos 		  arc_target, arg_32bit_zarblimm, lflags_f);
69075fd0b74Schristos 
69175fd0b74Schristos       INSERT_XOP (q, einsn->name,
69275fd0b74Schristos 		  INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
69375fd0b74Schristos 		  arc_target, arg_32bit_zalimmrc, lflags_ccf);
69475fd0b74Schristos 
69575fd0b74Schristos       INSERT_XOP (q, einsn->name,
69675fd0b74Schristos 		  INSN3OP_CBBL (einsn->major, einsn->minor), MINSN3OP_CBBL,
69775fd0b74Schristos 		  arc_target, arg_32bit_rbrblimm, lflags_ccf);
69875fd0b74Schristos 
69975fd0b74Schristos       INSERT_XOP (q, einsn->name,
70075fd0b74Schristos 		  INSN3OP_ALU (einsn->major, einsn->minor),  MINSN3OP_ALU,
70175fd0b74Schristos 		  arc_target, arg_32bit_ralimmu6, lflags_f);
70275fd0b74Schristos 
70375fd0b74Schristos       INSERT_XOP (q, einsn->name,
70475fd0b74Schristos 		  INSN3OP_0LU (einsn->major, einsn->minor),  MINSN3OP_0LU,
70575fd0b74Schristos 		  arc_target, arg_32bit_zalimmu6, lflags_f);
70675fd0b74Schristos 
70775fd0b74Schristos       INSERT_XOP (q, einsn->name,
70875fd0b74Schristos 		  INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
70975fd0b74Schristos 		  arc_target, arg_32bit_zalimmu6, lflags_ccf);
71075fd0b74Schristos 
71175fd0b74Schristos       INSERT_XOP (q, einsn->name,
71275fd0b74Schristos 		  INSN3OP_0LS (einsn->major, einsn->minor),  MINSN3OP_0LS,
71375fd0b74Schristos 		  arc_target, arg_32bit_zalimms12, lflags_f);
71475fd0b74Schristos 
71575fd0b74Schristos       INSERT_XOP (q, einsn->name,
71675fd0b74Schristos 		  INSN3OP_ALL (einsn->major, einsn->minor),  MINSN3OP_ALL,
71775fd0b74Schristos 		  arc_target, arg_32bit_ralimmlimm, lflags_f);
71875fd0b74Schristos 
71975fd0b74Schristos       INSERT_XOP (q, einsn->name,
72075fd0b74Schristos 		  INSN3OP_0LL (einsn->major, einsn->minor),  MINSN3OP_0LL,
72175fd0b74Schristos 		  arc_target, arg_32bit_zalimmlimm, lflags_f);
72275fd0b74Schristos 
72375fd0b74Schristos       INSERT_XOP (q, einsn->name,
72475fd0b74Schristos 		  INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
72575fd0b74Schristos 		  arc_target, arg_32bit_zalimmlimm, lflags_ccf);
72675fd0b74Schristos     }
72775fd0b74Schristos   else if (einsn->flags & ARC_SYNTAX_3OP)
72875fd0b74Schristos     {
72975fd0b74Schristos       /* 3OP instruction which accepts only zero as first
73075fd0b74Schristos 	 argument.  */
73175fd0b74Schristos       INSERT_XOP (q, einsn->name,
73275fd0b74Schristos 		  INSN3OP_0BC (einsn->major, einsn->minor),  MINSN3OP_0BC,
73375fd0b74Schristos 		  arc_target, arg_32bit_zarbrc, lflags_f);
73475fd0b74Schristos 
73575fd0b74Schristos       INSERT_XOP (q, einsn->name,
73675fd0b74Schristos 		  INSN3OP_0BU (einsn->major, einsn->minor),  MINSN3OP_0BU,
73775fd0b74Schristos 		  arc_target, arg_32bit_zarbu6, lflags_f);
73875fd0b74Schristos 
73975fd0b74Schristos       INSERT_XOP (q, einsn->name,
74075fd0b74Schristos 		  INSN3OP_0LC (einsn->major, einsn->minor),  MINSN3OP_0LC,
74175fd0b74Schristos 		  arc_target, arg_32bit_zalimmrc, lflags_f);
74275fd0b74Schristos 
74375fd0b74Schristos       INSERT_XOP (q, einsn->name,
74475fd0b74Schristos 		  INSN3OP_0BL (einsn->major, einsn->minor),  MINSN3OP_0BL,
74575fd0b74Schristos 		  arc_target, arg_32bit_zarblimm, lflags_f);
74675fd0b74Schristos 
74775fd0b74Schristos       INSERT_XOP (q, einsn->name,
74875fd0b74Schristos 		  INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
74975fd0b74Schristos 		  arc_target, arg_32bit_zalimmrc, lflags_ccf);
75075fd0b74Schristos 
75175fd0b74Schristos       INSERT_XOP (q, einsn->name,
75275fd0b74Schristos 		  INSN3OP_0LU (einsn->major, einsn->minor),  MINSN3OP_0LU,
75375fd0b74Schristos 		  arc_target, arg_32bit_zalimmu6, lflags_f);
75475fd0b74Schristos 
75575fd0b74Schristos       INSERT_XOP (q, einsn->name,
75675fd0b74Schristos 		  INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
75775fd0b74Schristos 		  arc_target, arg_32bit_zalimmu6, lflags_ccf);
75875fd0b74Schristos 
75975fd0b74Schristos       INSERT_XOP (q, einsn->name,
76075fd0b74Schristos 		  INSN3OP_0LS (einsn->major, einsn->minor),  MINSN3OP_0LS,
76175fd0b74Schristos 		  arc_target, arg_32bit_zalimms12, lflags_f);
76275fd0b74Schristos 
76375fd0b74Schristos       INSERT_XOP (q, einsn->name,
76475fd0b74Schristos 		  INSN3OP_0LL (einsn->major, einsn->minor),  MINSN3OP_0LL,
76575fd0b74Schristos 		  arc_target, arg_32bit_zalimmlimm, lflags_f);
76675fd0b74Schristos 
76775fd0b74Schristos       INSERT_XOP (q, einsn->name,
76875fd0b74Schristos 		  INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
76975fd0b74Schristos 		  arc_target, arg_32bit_zalimmlimm, lflags_ccf);
77075fd0b74Schristos     }
77175fd0b74Schristos   else if (einsn->flags & ARC_SYNTAX_1OP)
77275fd0b74Schristos     {
77375fd0b74Schristos       if (einsn->suffix & ARC_SUFFIX_COND)
77475fd0b74Schristos 	*errmsg = "Suffix SUFFIX_COND ignored";
77575fd0b74Schristos 
77675fd0b74Schristos       INSERT_XOP (q, einsn->name,
77775fd0b74Schristos 		  INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor),
77875fd0b74Schristos 		  MINSN2OP_0C, arc_target, arg_32bit_rc, lflags_f);
77975fd0b74Schristos 
78075fd0b74Schristos       INSERT_XOP (q, einsn->name,
78175fd0b74Schristos 		  INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor)
78275fd0b74Schristos 		  | (0x01 << 22), MINSN2OP_0U, arc_target, arg_32bit_u6,
78375fd0b74Schristos 		  lflags_f);
78475fd0b74Schristos 
78575fd0b74Schristos       INSERT_XOP (q, einsn->name,
78675fd0b74Schristos 		  INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor)
78775fd0b74Schristos 		  | FIELDC (62), MINSN2OP_0L, arc_target, arg_32bit_limm,
78875fd0b74Schristos 		  lflags_f);
78975fd0b74Schristos 
79075fd0b74Schristos     }
79175fd0b74Schristos   else if (einsn->flags & ARC_SYNTAX_NOP)
79275fd0b74Schristos     {
79375fd0b74Schristos       if (einsn->suffix & ARC_SUFFIX_COND)
79475fd0b74Schristos 	*errmsg = "Suffix SUFFIX_COND ignored";
79575fd0b74Schristos 
79675fd0b74Schristos       INSERT_XOP (q, einsn->name,
79775fd0b74Schristos 		  INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor)
79875fd0b74Schristos 		  | (0x01 << 22), MINSN2OP_0L, arc_target, arg_none, lflags_f);
79975fd0b74Schristos     }
80075fd0b74Schristos   else
80175fd0b74Schristos     {
80275fd0b74Schristos       *errmsg = "Unknown syntax";
80375fd0b74Schristos       return NULL;
80475fd0b74Schristos     }
80575fd0b74Schristos 
80675fd0b74Schristos   /* End marker.  */
80775fd0b74Schristos   memset (q, 0, sizeof (*arc_ext_opcodes));
80875fd0b74Schristos 
80975fd0b74Schristos   return arc_ext_opcodes;
81075fd0b74Schristos }
811