xref: /netbsd-src/external/gpl3/binutils/dist/opcodes/arc-ext.c (revision cb63e24e8d6aae7ddac1859a9015f48b1d8bd90e)
12a6b7db3Sskrll /* ARC target-dependent stuff.  Extension structure access functions
2*cb63e24eSchristos    Copyright (C) 1995-2024 Free Software Foundation, Inc.
32a6b7db3Sskrll 
42a6b7db3Sskrll    This file is part of libopcodes.
52a6b7db3Sskrll 
62a6b7db3Sskrll    This library is free software; you can redistribute it and/or modify
72a6b7db3Sskrll    it under the terms of the GNU General Public License as published by
82a6b7db3Sskrll    the Free Software Foundation; either version 3, or (at your option)
92a6b7db3Sskrll    any later version.
102a6b7db3Sskrll 
112a6b7db3Sskrll    It is distributed in the hope that it will be useful, but WITHOUT
122a6b7db3Sskrll    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
132a6b7db3Sskrll    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
142a6b7db3Sskrll    License for more details.
152a6b7db3Sskrll 
162a6b7db3Sskrll    You should have received a copy of the GNU General Public License
172a6b7db3Sskrll    along with this program; if not, write to the Free Software
182a6b7db3Sskrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
192a6b7db3Sskrll    MA 02110-1301, USA.  */
202a6b7db3Sskrll 
212a6b7db3Sskrll #include "sysdep.h"
222a6b7db3Sskrll #include <stdlib.h>
232a6b7db3Sskrll #include <stdio.h>
249573673dSchristos 
252a6b7db3Sskrll #include "bfd.h"
262a6b7db3Sskrll #include "arc-ext.h"
279573673dSchristos #include "elf/arc.h"
282a6b7db3Sskrll #include "libiberty.h"
292a6b7db3Sskrll 
309573673dSchristos /* This module provides support for extensions to the ARC processor
319573673dSchristos    architecture.  */
329573673dSchristos 
339573673dSchristos 
349573673dSchristos /* Local constants.  */
359573673dSchristos 
369573673dSchristos #define FIRST_EXTENSION_CORE_REGISTER   32
379573673dSchristos #define LAST_EXTENSION_CORE_REGISTER    59
389573673dSchristos #define FIRST_EXTENSION_CONDITION_CODE  0x10
399573673dSchristos #define LAST_EXTENSION_CONDITION_CODE   0x1f
409573673dSchristos 
419573673dSchristos #define NUM_EXT_CORE      \
429573673dSchristos   (LAST_EXTENSION_CORE_REGISTER  - FIRST_EXTENSION_CORE_REGISTER  + 1)
439573673dSchristos #define NUM_EXT_COND      \
449573673dSchristos   (LAST_EXTENSION_CONDITION_CODE - FIRST_EXTENSION_CONDITION_CODE + 1)
459573673dSchristos #define INST_HASH_BITS    6
469573673dSchristos #define INST_HASH_SIZE    (1 << INST_HASH_BITS)
479573673dSchristos #define INST_HASH_MASK    (INST_HASH_SIZE - 1)
489573673dSchristos 
499573673dSchristos 
509573673dSchristos /* Local types.  */
519573673dSchristos 
529573673dSchristos /* These types define the information stored in the table.  */
539573673dSchristos 
549573673dSchristos struct ExtAuxRegister
559573673dSchristos {
566f4ced0bSchristos   unsigned		  address;
579573673dSchristos   char *		  name;
589573673dSchristos   struct ExtAuxRegister * next;
599573673dSchristos };
609573673dSchristos 
619573673dSchristos struct ExtCoreRegister
629573673dSchristos {
639573673dSchristos   short		    number;
649573673dSchristos   enum ExtReadWrite rw;
659573673dSchristos   char *	    name;
669573673dSchristos };
679573673dSchristos 
689573673dSchristos struct arcExtMap
699573673dSchristos {
709573673dSchristos   struct ExtAuxRegister* auxRegisters;
719573673dSchristos   struct ExtInstruction* instructions[INST_HASH_SIZE];
729573673dSchristos   struct ExtCoreRegister coreRegisters[NUM_EXT_CORE];
739573673dSchristos   char *		 condCodes[NUM_EXT_COND];
749573673dSchristos };
759573673dSchristos 
769573673dSchristos 
779573673dSchristos /* Local data.  */
789573673dSchristos 
799573673dSchristos /* Extension table.  */
802a6b7db3Sskrll static struct arcExtMap arc_extension_map;
812a6b7db3Sskrll 
822a6b7db3Sskrll 
839573673dSchristos /* Local macros.  */
842a6b7db3Sskrll 
859573673dSchristos /* A hash function used to map instructions into the table.  */
869573673dSchristos #define INST_HASH(MAJOR, MINOR)    ((((MAJOR) << 3) ^ (MINOR)) & INST_HASH_MASK)
872a6b7db3Sskrll 
882a6b7db3Sskrll 
899573673dSchristos /* Local functions.  */
902a6b7db3Sskrll 
912a6b7db3Sskrll static void
create_map(unsigned char * block,unsigned long length)929573673dSchristos create_map (unsigned char *block,
939573673dSchristos 	    unsigned long length)
942a6b7db3Sskrll {
959573673dSchristos   unsigned char *p = block;
962a6b7db3Sskrll 
972a6b7db3Sskrll   while (p && p < (block + length))
982a6b7db3Sskrll     {
992a6b7db3Sskrll       /* p[0] == length of record
1002a6b7db3Sskrll 	 p[1] == type of record
1012a6b7db3Sskrll 	 For instructions:
1022a6b7db3Sskrll 	   p[2]  = opcode
1032a6b7db3Sskrll 	   p[3]  = minor opcode (if opcode == 3)
1042a6b7db3Sskrll 	   p[4]  = flags
1052a6b7db3Sskrll 	   p[5]+ = name
1062a6b7db3Sskrll 	 For core regs and condition codes:
1072a6b7db3Sskrll 	   p[2]  = value
1082a6b7db3Sskrll 	   p[3]+ = name
1099573673dSchristos 	 For auxiliary regs:
1102a6b7db3Sskrll 	   p[2..5] = value
1112a6b7db3Sskrll 	   p[6]+   = name
1129573673dSchristos 	     (value is p[2]<<24|p[3]<<16|p[4]<<8|p[5]).  */
1132a6b7db3Sskrll 
1149573673dSchristos       /* The sequence of records is temrinated by an "empty"
1159573673dSchristos 	 record.  */
1162a6b7db3Sskrll       if (p[0] == 0)
1179573673dSchristos 	break;
1182a6b7db3Sskrll 
1192a6b7db3Sskrll       switch (p[1])
1202a6b7db3Sskrll 	{
1212a6b7db3Sskrll 	case EXT_INSTRUCTION:
1222a6b7db3Sskrll 	  {
1239573673dSchristos 	    struct ExtInstruction  *insn = XNEW (struct ExtInstruction);
1249573673dSchristos 	    int			    major = p[2];
1259573673dSchristos 	    int			    minor = p[3];
1269573673dSchristos 	    struct ExtInstruction **bucket =
1279573673dSchristos 		   &arc_extension_map.instructions[INST_HASH (major, minor)];
1282a6b7db3Sskrll 
1299573673dSchristos 	    insn->name  = xstrdup ((char *) (p + 5));
1309573673dSchristos 	    insn->major = major;
1319573673dSchristos 	    insn->minor = minor;
1329573673dSchristos 	    insn->flags = p[4];
1339573673dSchristos 	    insn->next  = *bucket;
1348cbf5cb7Schristos 	    insn->suffix = 0;
1358cbf5cb7Schristos 	    insn->syntax = 0;
1368cbf5cb7Schristos 	    insn->modsyn = 0;
1379573673dSchristos 	    *bucket = insn;
1382a6b7db3Sskrll 	    break;
1399573673dSchristos 	  }
1402a6b7db3Sskrll 
1412a6b7db3Sskrll 	case EXT_CORE_REGISTER:
1422a6b7db3Sskrll 	  {
1439573673dSchristos 	    unsigned char number = p[2];
1449573673dSchristos 	    char*	  name	 = (char *) (p + 3);
1452a6b7db3Sskrll 
1469573673dSchristos 	    arc_extension_map.
1479573673dSchristos 	      coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].number
1489573673dSchristos 	      = number;
1499573673dSchristos 	    arc_extension_map.
1509573673dSchristos 	      coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].rw
1519573673dSchristos 	      = REG_READWRITE;
1529573673dSchristos 	    arc_extension_map.
1539573673dSchristos 	      coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].name
1549573673dSchristos 	      = xstrdup (name);
1552a6b7db3Sskrll 	    break;
1569573673dSchristos 	  }
1579573673dSchristos 
1589573673dSchristos 	case EXT_LONG_CORE_REGISTER:
1599573673dSchristos 	  {
1609573673dSchristos 	    unsigned char     number = p[2];
1619573673dSchristos 	    char*	      name   = (char *) (p + 7);
1629573673dSchristos 	    enum ExtReadWrite rw     = p[6];
1639573673dSchristos 
1649573673dSchristos 	    arc_extension_map.
1659573673dSchristos 	      coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].number
1669573673dSchristos 	      = number;
1679573673dSchristos 	    arc_extension_map.
1689573673dSchristos 	      coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].rw
1699573673dSchristos 	      = rw;
1709573673dSchristos 	    arc_extension_map.
1719573673dSchristos 	      coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].name
1729573673dSchristos 	      = xstrdup (name);
173fc4f4269Schristos 	    break;
1749573673dSchristos 	  }
1752a6b7db3Sskrll 
1762a6b7db3Sskrll 	case EXT_COND_CODE:
1772a6b7db3Sskrll 	  {
1789573673dSchristos 	    char *cc_name = xstrdup ((char *) (p + 3));
1799573673dSchristos 
1809573673dSchristos 	    arc_extension_map.
1819573673dSchristos 	      condCodes[p[2] - FIRST_EXTENSION_CONDITION_CODE]
1829573673dSchristos 	      = cc_name;
1832a6b7db3Sskrll 	    break;
1849573673dSchristos 	  }
1852a6b7db3Sskrll 
1862a6b7db3Sskrll 	case EXT_AUX_REGISTER:
1872a6b7db3Sskrll 	  {
1889573673dSchristos 	    /* Trickier -- need to store linked list of these.  */
1899573673dSchristos 	    struct ExtAuxRegister *newAuxRegister
1909573673dSchristos 	      = XNEW (struct ExtAuxRegister);
1919573673dSchristos 	    char *aux_name = xstrdup ((char *) (p + 6));
1922a6b7db3Sskrll 
1932a6b7db3Sskrll 	    newAuxRegister->name = aux_name;
1946f4ced0bSchristos 	    newAuxRegister->address = (((unsigned) p[2] << 24) | (p[3] << 16)
1956f4ced0bSchristos 				       | (p[4] << 8) | p[5]);
1962a6b7db3Sskrll 	    newAuxRegister->next = arc_extension_map.auxRegisters;
1972a6b7db3Sskrll 	    arc_extension_map.auxRegisters = newAuxRegister;
1982a6b7db3Sskrll 	    break;
1999573673dSchristos 	  }
2002a6b7db3Sskrll 
2012a6b7db3Sskrll 	default:
2022a6b7db3Sskrll 	  break;
2032a6b7db3Sskrll 	}
2049573673dSchristos 
2059573673dSchristos       p += p[0]; /* Move on to next record.  */
2062a6b7db3Sskrll     }
2072a6b7db3Sskrll }
2089573673dSchristos 
2099573673dSchristos 
2109573673dSchristos /* Free memory that has been allocated for the extensions.  */
2119573673dSchristos 
2129573673dSchristos static void
destroy_map(void)2139573673dSchristos destroy_map (void)
2149573673dSchristos {
2159573673dSchristos   struct ExtAuxRegister *r;
2169573673dSchristos   unsigned int		 i;
2179573673dSchristos 
2189573673dSchristos   /* Free auxiliary registers.  */
2199573673dSchristos   r = arc_extension_map.auxRegisters;
2209573673dSchristos   while (r)
2219573673dSchristos     {
2229573673dSchristos       /* N.B. after r has been freed, r->next is invalid!  */
2239573673dSchristos       struct ExtAuxRegister* next = r->next;
2249573673dSchristos 
2259573673dSchristos       free (r->name);
2269573673dSchristos       free (r);
2279573673dSchristos       r = next;
2289573673dSchristos     }
2299573673dSchristos 
2309573673dSchristos   /* Free instructions.  */
2319573673dSchristos   for (i = 0; i < INST_HASH_SIZE; i++)
2329573673dSchristos     {
2339573673dSchristos       struct ExtInstruction *insn = arc_extension_map.instructions[i];
2349573673dSchristos 
2359573673dSchristos       while (insn)
2369573673dSchristos 	{
2379573673dSchristos 	  /* N.B. after insn has been freed, insn->next is invalid!  */
2389573673dSchristos 	  struct ExtInstruction *next = insn->next;
2399573673dSchristos 
2409573673dSchristos 	  free (insn->name);
2419573673dSchristos 	  free (insn);
2429573673dSchristos 	  insn = next;
2439573673dSchristos 	}
2449573673dSchristos     }
2459573673dSchristos 
2469573673dSchristos   /* Free core registers.  */
2479573673dSchristos   for (i = 0; i < NUM_EXT_CORE; i++)
2489573673dSchristos     free (arc_extension_map.coreRegisters[i].name);
2499573673dSchristos 
2509573673dSchristos   /* Free condition codes.  */
2519573673dSchristos   for (i = 0; i < NUM_EXT_COND; i++)
2529573673dSchristos     free (arc_extension_map.condCodes[i]);
2539573673dSchristos 
2549573673dSchristos   memset (&arc_extension_map, 0, sizeof (arc_extension_map));
2559573673dSchristos }
2569573673dSchristos 
2579573673dSchristos 
2589573673dSchristos static const char *
ExtReadWrite_image(enum ExtReadWrite val)2599573673dSchristos ExtReadWrite_image (enum ExtReadWrite val)
2609573673dSchristos {
2619573673dSchristos     switch (val)
2629573673dSchristos     {
2639573673dSchristos 	case REG_INVALID  : return "INVALID";
2649573673dSchristos 	case REG_READ	  : return "RO";
2659573673dSchristos 	case REG_WRITE	  : return "WO";
2669573673dSchristos 	case REG_READWRITE: return "R/W";
2679573673dSchristos 	default		  : return "???";
2689573673dSchristos     }
2699573673dSchristos }
2709573673dSchristos 
2719573673dSchristos 
2729573673dSchristos /* Externally visible functions.  */
2739573673dSchristos 
2749573673dSchristos /* Get the name of an extension instruction.  */
2759573673dSchristos 
2768cbf5cb7Schristos const extInstruction_t *
arcExtMap_insn(int opcode,unsigned long long insn)277fc4f4269Schristos arcExtMap_insn (int opcode, unsigned long long insn)
2789573673dSchristos {
2799573673dSchristos   /* Here the following tasks need to be done.  First of all, the
2809573673dSchristos      opcode stored in the Extension Map is the real opcode.  However,
2819573673dSchristos      the subopcode stored in the instruction to be disassembled is
2829573673dSchristos      mangled.  We pass (in minor opcode), the instruction word.  Here
2839573673dSchristos      we will un-mangle it and get the real subopcode which we can look
2849573673dSchristos      for in the Extension Map.  This function is used both for the
2859573673dSchristos      ARCTangent and the ARCompact, so we would also need some sort of
2869573673dSchristos      a way to distinguish between the two architectures.  This is
2879573673dSchristos      because the ARCTangent does not do any of this mangling so we
2889573673dSchristos      have no issues there.  */
2899573673dSchristos 
2909573673dSchristos   /* If P[22:23] is 0 or 2 then un-mangle using iiiiiI.  If it is 1
2919573673dSchristos      then use iiiiIi.  Now, if P is 3 then check M[5:5] and if it is 0
2929573673dSchristos      then un-mangle using iiiiiI else iiiiii.  */
2939573673dSchristos 
2949573673dSchristos   unsigned char minor;
2958cbf5cb7Schristos   extInstruction_t *temp;
2969573673dSchristos 
2979573673dSchristos   /* 16-bit instructions.  */
2989573673dSchristos   if (0x08 <= opcode && opcode <= 0x0b)
2999573673dSchristos     {
3009573673dSchristos       unsigned char b, c, i;
3019573673dSchristos 
3029573673dSchristos       b = (insn & 0x0700) >> 8;
3039573673dSchristos       c = (insn & 0x00e0) >> 5;
3049573673dSchristos       i = (insn & 0x001f);
3059573673dSchristos 
3069573673dSchristos       if (i)
3079573673dSchristos 	minor = i;
3089573673dSchristos       else
3099573673dSchristos 	minor = (c == 0x07) ? b : c;
3109573673dSchristos     }
3119573673dSchristos   /* 32-bit instructions.  */
3129573673dSchristos   else
3139573673dSchristos     {
3149573673dSchristos       unsigned char I, A, B;
3159573673dSchristos 
3169573673dSchristos       I = (insn & 0x003f0000) >> 16;
3179573673dSchristos       A = (insn & 0x0000003f);
3189573673dSchristos       B = ((insn & 0x07000000) >> 24) | ((insn & 0x00007000) >> 9);
3199573673dSchristos 
3209573673dSchristos       if (I != 0x2f)
3219573673dSchristos 	{
3229573673dSchristos #ifndef UNMANGLED
3239573673dSchristos 	  switch (P)
3249573673dSchristos 	    {
3259573673dSchristos 	    case 3:
3269573673dSchristos 	      if (M)
3279573673dSchristos 		{
3289573673dSchristos 		  minor = I;
3299573673dSchristos 		  break;
3309573673dSchristos 		}
3319573673dSchristos 	    case 0:
3329573673dSchristos 	    case 2:
3339573673dSchristos 	      minor = (I >> 1) | ((I & 0x1) << 5);
3349573673dSchristos 	      break;
3359573673dSchristos 	    case 1:
3369573673dSchristos 	      minor = (I >> 1) | (I & 0x1) | ((I & 0x2) << 4);
3379573673dSchristos 	    }
3389573673dSchristos #else
3399573673dSchristos 	  minor = I;
3409573673dSchristos #endif
3419573673dSchristos 	}
3429573673dSchristos       else
3439573673dSchristos 	{
3449573673dSchristos 	  if (A != 0x3f)
3459573673dSchristos 	    minor = A;
3469573673dSchristos 	  else
3479573673dSchristos 	    minor = B;
3489573673dSchristos 	}
3499573673dSchristos     }
3509573673dSchristos 
3519573673dSchristos   temp = arc_extension_map.instructions[INST_HASH (opcode, minor)];
3529573673dSchristos   while (temp)
3539573673dSchristos     {
3549573673dSchristos       if ((temp->major == opcode) && (temp->minor == minor))
3559573673dSchristos 	{
3568cbf5cb7Schristos 	  return temp;
3579573673dSchristos 	}
3589573673dSchristos       temp = temp->next;
3599573673dSchristos     }
3609573673dSchristos 
3619573673dSchristos   return NULL;
3629573673dSchristos }
3639573673dSchristos 
3649573673dSchristos /* Get the name of an extension core register.  */
3659573673dSchristos 
3669573673dSchristos const char *
arcExtMap_coreRegName(int regnum)3679573673dSchristos arcExtMap_coreRegName (int regnum)
3689573673dSchristos {
3699573673dSchristos   if (regnum < FIRST_EXTENSION_CORE_REGISTER
3708cbf5cb7Schristos       || regnum > LAST_EXTENSION_CORE_REGISTER)
3719573673dSchristos     return NULL;
3729573673dSchristos   return arc_extension_map.
3739573673dSchristos     coreRegisters[regnum - FIRST_EXTENSION_CORE_REGISTER].name;
3749573673dSchristos }
3759573673dSchristos 
3769573673dSchristos /* Get the access mode of an extension core register.  */
3779573673dSchristos 
3789573673dSchristos enum ExtReadWrite
arcExtMap_coreReadWrite(int regnum)3799573673dSchristos arcExtMap_coreReadWrite (int regnum)
3809573673dSchristos {
3819573673dSchristos   if (regnum < FIRST_EXTENSION_CORE_REGISTER
3828cbf5cb7Schristos       || regnum > LAST_EXTENSION_CORE_REGISTER)
3839573673dSchristos     return REG_INVALID;
3849573673dSchristos   return arc_extension_map.
3859573673dSchristos     coreRegisters[regnum - FIRST_EXTENSION_CORE_REGISTER].rw;
3869573673dSchristos }
3879573673dSchristos 
3889573673dSchristos /* Get the name of an extension condition code.  */
3899573673dSchristos 
3909573673dSchristos const char *
arcExtMap_condCodeName(int code)3919573673dSchristos arcExtMap_condCodeName (int code)
3929573673dSchristos {
3939573673dSchristos   if (code < FIRST_EXTENSION_CONDITION_CODE
3949573673dSchristos       || code > LAST_EXTENSION_CONDITION_CODE)
3959573673dSchristos     return NULL;
3969573673dSchristos   return arc_extension_map.
3979573673dSchristos     condCodes[code - FIRST_EXTENSION_CONDITION_CODE];
3989573673dSchristos }
3999573673dSchristos 
4009573673dSchristos /* Get the name of an extension auxiliary register.  */
4019573673dSchristos 
4029573673dSchristos const char *
arcExtMap_auxRegName(unsigned address)4036f4ced0bSchristos arcExtMap_auxRegName (unsigned address)
4049573673dSchristos {
4059573673dSchristos   /* Walk the list of auxiliary register names and find the name.  */
4069573673dSchristos   struct ExtAuxRegister *r;
4079573673dSchristos 
4089573673dSchristos   for (r = arc_extension_map.auxRegisters; r; r = r->next)
4099573673dSchristos     {
4109573673dSchristos       if (r->address == address)
4119573673dSchristos 	return (const char *)r->name;
4129573673dSchristos     }
4139573673dSchristos   return NULL;
4149573673dSchristos }
4159573673dSchristos 
4169573673dSchristos /* Load extensions described in .arcextmap and
4179573673dSchristos    .gnu.linkonce.arcextmap.* ELF section.  */
4189573673dSchristos 
4199573673dSchristos void
build_ARC_extmap(bfd * text_bfd)4209573673dSchristos build_ARC_extmap (bfd *text_bfd)
4219573673dSchristos {
4229573673dSchristos   asection *sect;
4239573673dSchristos 
4249573673dSchristos   /* The map is built each time gdb loads an executable file - so free
4259573673dSchristos      any existing map, as the map defined by the new file may differ
4269573673dSchristos      from the old.  */
4279573673dSchristos   destroy_map ();
4289573673dSchristos 
4299573673dSchristos   for (sect = text_bfd->sections; sect != NULL; sect = sect->next)
4309573673dSchristos     if (!strncmp (sect->name,
4319573673dSchristos 		  ".gnu.linkonce.arcextmap.",
4329573673dSchristos 	  sizeof (".gnu.linkonce.arcextmap.") - 1)
4339573673dSchristos 	|| !strcmp (sect->name,".arcextmap"))
4349573673dSchristos       {
4356f4ced0bSchristos 	bfd_size_type  count  = bfd_section_size (sect);
4369573673dSchristos 	unsigned char* buffer = xmalloc (count);
4379573673dSchristos 
4389573673dSchristos 	if (buffer)
4399573673dSchristos 	  {
4409573673dSchristos 	    if (bfd_get_section_contents (text_bfd, sect, buffer, 0, count))
4419573673dSchristos 	      create_map (buffer, count);
4429573673dSchristos 	    free (buffer);
4439573673dSchristos 	  }
4449573673dSchristos       }
4459573673dSchristos }
4469573673dSchristos 
4478cbf5cb7Schristos /* Debug function used to dump the ARC information fount in arcextmap
4488cbf5cb7Schristos    sections.  */
4499573673dSchristos 
4509573673dSchristos void
dump_ARC_extmap(void)4519573673dSchristos dump_ARC_extmap (void)
4529573673dSchristos {
4539573673dSchristos     struct ExtAuxRegister *r;
4549573673dSchristos     int			   i;
4559573673dSchristos 
4569573673dSchristos     r = arc_extension_map.auxRegisters;
4579573673dSchristos 
4589573673dSchristos     while (r)
4599573673dSchristos     {
4606f4ced0bSchristos 	printf ("AUX : %s %u\n", r->name, r->address);
4619573673dSchristos 	r = r->next;
4629573673dSchristos     }
4639573673dSchristos 
4649573673dSchristos     for (i = 0; i < INST_HASH_SIZE; i++)
4659573673dSchristos     {
4669573673dSchristos 	struct ExtInstruction *insn;
4679573673dSchristos 
4689573673dSchristos 	for (insn = arc_extension_map.instructions[i];
4699573673dSchristos 	     insn != NULL; insn = insn->next)
4708cbf5cb7Schristos 	  {
4718cbf5cb7Schristos 	    printf ("INST: 0x%02x 0x%02x ", insn->major, insn->minor);
4728cbf5cb7Schristos 	    switch (insn->flags & ARC_SYNTAX_MASK)
4738cbf5cb7Schristos 	      {
4748cbf5cb7Schristos 	      case ARC_SYNTAX_2OP:
4758cbf5cb7Schristos 		printf ("SYNTAX_2OP");
4768cbf5cb7Schristos 		break;
4778cbf5cb7Schristos 	      case ARC_SYNTAX_3OP:
4788cbf5cb7Schristos 		printf ("SYNTAX_3OP");
4798cbf5cb7Schristos 		break;
4808cbf5cb7Schristos 	      case ARC_SYNTAX_1OP:
4818cbf5cb7Schristos 		printf ("SYNTAX_1OP");
4828cbf5cb7Schristos 		break;
4838cbf5cb7Schristos 	      case ARC_SYNTAX_NOP:
4848cbf5cb7Schristos 		printf ("SYNTAX_NOP");
4858cbf5cb7Schristos 		break;
4868cbf5cb7Schristos 	      default:
4878cbf5cb7Schristos 		printf ("SYNTAX_UNK");
4888cbf5cb7Schristos 		break;
4898cbf5cb7Schristos 	      }
4908cbf5cb7Schristos 
4918cbf5cb7Schristos 	    if (insn->flags & 0x10)
4928cbf5cb7Schristos 	      printf ("|MODIFIER");
4938cbf5cb7Schristos 
4948cbf5cb7Schristos 	    printf (" %s\n", insn->name);
4958cbf5cb7Schristos 	  }
4969573673dSchristos     }
4979573673dSchristos 
4989573673dSchristos     for (i = 0; i < NUM_EXT_CORE; i++)
4999573673dSchristos     {
5009573673dSchristos 	struct ExtCoreRegister reg = arc_extension_map.coreRegisters[i];
5019573673dSchristos 
5029573673dSchristos 	if (reg.name)
5038cbf5cb7Schristos 	  printf ("CORE: 0x%04x %s %s\n", reg.number,
5048cbf5cb7Schristos 		  ExtReadWrite_image (reg.rw),
5058cbf5cb7Schristos 		  reg.name);
5069573673dSchristos     }
5079573673dSchristos 
5089573673dSchristos     for (i = 0; i < NUM_EXT_COND; i++)
5099573673dSchristos 	if (arc_extension_map.condCodes[i])
5109573673dSchristos 	    printf ("COND: %s\n", arc_extension_map.condCodes[i]);
5119573673dSchristos }
5128cbf5cb7Schristos 
5138cbf5cb7Schristos /* For a given extension instruction generate the equivalent arc
5148cbf5cb7Schristos    opcode structure.  */
5158cbf5cb7Schristos 
5168cbf5cb7Schristos struct arc_opcode *
arcExtMap_genOpcode(const extInstruction_t * einsn,unsigned arc_target,const char ** errmsg)5178cbf5cb7Schristos arcExtMap_genOpcode (const extInstruction_t *einsn,
5188cbf5cb7Schristos 		     unsigned arc_target,
5198cbf5cb7Schristos 		     const char **errmsg)
5208cbf5cb7Schristos {
5218cbf5cb7Schristos   struct arc_opcode *q, *arc_ext_opcodes = NULL;
5228cbf5cb7Schristos   const unsigned char *lflags_f;
5238cbf5cb7Schristos   const unsigned char *lflags_ccf;
5248cbf5cb7Schristos   int count;
5258cbf5cb7Schristos 
5268cbf5cb7Schristos   /* Check for the class to see how many instructions we generate.  */
5278cbf5cb7Schristos   switch (einsn->flags & ARC_SYNTAX_MASK)
5288cbf5cb7Schristos     {
5298cbf5cb7Schristos     case ARC_SYNTAX_3OP:
5308cbf5cb7Schristos       count = (einsn->modsyn & ARC_OP1_MUST_BE_IMM) ? 10 : 20;
5318cbf5cb7Schristos       break;
5328cbf5cb7Schristos     case ARC_SYNTAX_2OP:
5338cbf5cb7Schristos       count = (einsn->flags & 0x10) ? 7 : 6;
5348cbf5cb7Schristos       break;
5358cbf5cb7Schristos     case ARC_SYNTAX_1OP:
5368cbf5cb7Schristos       count = 3;
5378cbf5cb7Schristos       break;
5388cbf5cb7Schristos     case ARC_SYNTAX_NOP:
5398cbf5cb7Schristos       count = 1;
5408cbf5cb7Schristos       break;
5418cbf5cb7Schristos     default:
5428cbf5cb7Schristos       count = 0;
5438cbf5cb7Schristos       break;
5448cbf5cb7Schristos     }
5458cbf5cb7Schristos 
5468cbf5cb7Schristos   /* Allocate memory.  */
5478cbf5cb7Schristos   arc_ext_opcodes = (struct arc_opcode *)
5488cbf5cb7Schristos     xmalloc ((count + 1) * sizeof (*arc_ext_opcodes));
5498cbf5cb7Schristos 
5508cbf5cb7Schristos   if (arc_ext_opcodes == NULL)
5518cbf5cb7Schristos     {
5528cbf5cb7Schristos       *errmsg = "Virtual memory exhausted";
5538cbf5cb7Schristos       return NULL;
5548cbf5cb7Schristos     }
5558cbf5cb7Schristos 
5568cbf5cb7Schristos   /* Generate the patterns.  */
5578cbf5cb7Schristos   q = arc_ext_opcodes;
5588cbf5cb7Schristos 
5598cbf5cb7Schristos   if (einsn->suffix)
5608cbf5cb7Schristos     {
5618cbf5cb7Schristos       lflags_f   = flags_none;
5628cbf5cb7Schristos       lflags_ccf = flags_none;
5638cbf5cb7Schristos     }
5648cbf5cb7Schristos   else
5658cbf5cb7Schristos     {
5668cbf5cb7Schristos       lflags_f   = flags_f;
5678cbf5cb7Schristos       lflags_ccf = flags_ccf;
5688cbf5cb7Schristos     }
5698cbf5cb7Schristos 
5708cbf5cb7Schristos   if (einsn->suffix & ARC_SUFFIX_COND)
5718cbf5cb7Schristos     lflags_ccf = flags_cc;
5728cbf5cb7Schristos   if (einsn->suffix & ARC_SUFFIX_FLAG)
5738cbf5cb7Schristos     {
5748cbf5cb7Schristos       lflags_f   = flags_f;
5758cbf5cb7Schristos       lflags_ccf = flags_f;
5768cbf5cb7Schristos     }
5778cbf5cb7Schristos   if (einsn->suffix & (ARC_SUFFIX_FLAG | ARC_SUFFIX_COND))
5788cbf5cb7Schristos     lflags_ccf = flags_ccf;
5798cbf5cb7Schristos 
5808cbf5cb7Schristos   if (einsn->flags & ARC_SYNTAX_2OP
5818cbf5cb7Schristos       && !(einsn->flags & 0x10))
5828cbf5cb7Schristos     {
5838cbf5cb7Schristos       /* Regular 2OP instruction.  */
5848cbf5cb7Schristos       if (einsn->suffix & ARC_SUFFIX_COND)
5858cbf5cb7Schristos 	*errmsg = "Suffix SUFFIX_COND ignored";
5868cbf5cb7Schristos 
5878cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
5888cbf5cb7Schristos 		  INSN2OP_BC (einsn->major, einsn->minor), MINSN2OP_BC,
5898cbf5cb7Schristos 		  arc_target, arg_32bit_rbrc, lflags_f);
5908cbf5cb7Schristos 
5918cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
5928cbf5cb7Schristos 		  INSN2OP_0C (einsn->major, einsn->minor), MINSN2OP_0C,
5938cbf5cb7Schristos 		  arc_target, arg_32bit_zarc, lflags_f);
5948cbf5cb7Schristos 
5958cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
5968cbf5cb7Schristos 		  INSN2OP_BU (einsn->major, einsn->minor), MINSN2OP_BU,
5978cbf5cb7Schristos 		  arc_target, arg_32bit_rbu6, lflags_f);
5988cbf5cb7Schristos 
5998cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6008cbf5cb7Schristos 		  INSN2OP_0U (einsn->major, einsn->minor), MINSN2OP_0U,
6018cbf5cb7Schristos 		  arc_target, arg_32bit_zau6, lflags_f);
6028cbf5cb7Schristos 
6038cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6048cbf5cb7Schristos 		  INSN2OP_BL (einsn->major, einsn->minor), MINSN2OP_BL,
6058cbf5cb7Schristos 		  arc_target, arg_32bit_rblimm, lflags_f);
6068cbf5cb7Schristos 
6078cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6088cbf5cb7Schristos 		  INSN2OP_0L (einsn->major, einsn->minor), MINSN2OP_0L,
6098cbf5cb7Schristos 		  arc_target, arg_32bit_zalimm, lflags_f);
6108cbf5cb7Schristos     }
6118cbf5cb7Schristos   else if (einsn->flags & (0x10 | ARC_SYNTAX_2OP))
6128cbf5cb7Schristos     {
6138cbf5cb7Schristos       /* This is actually a 3OP pattern.  The first operand is
6148cbf5cb7Schristos 	 immplied and is set to zero.  */
6158cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6168cbf5cb7Schristos 		  INSN3OP_0BC (einsn->major, einsn->minor),  MINSN3OP_0BC,
6178cbf5cb7Schristos 		  arc_target, arg_32bit_rbrc, lflags_f);
6188cbf5cb7Schristos 
6198cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6208cbf5cb7Schristos 		  INSN3OP_0BU (einsn->major, einsn->minor),  MINSN3OP_0BU,
6218cbf5cb7Schristos 		  arc_target, arg_32bit_rbu6, lflags_f);
6228cbf5cb7Schristos 
6238cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6248cbf5cb7Schristos 		  INSN3OP_0BL (einsn->major, einsn->minor),  MINSN3OP_0BL,
6258cbf5cb7Schristos 		  arc_target, arg_32bit_rblimm, lflags_f);
6268cbf5cb7Schristos 
6278cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6288cbf5cb7Schristos 		  INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
6298cbf5cb7Schristos 		  arc_target, arg_32bit_limmrc, lflags_ccf);
6308cbf5cb7Schristos 
6318cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6328cbf5cb7Schristos 		  INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
6338cbf5cb7Schristos 		  arc_target, arg_32bit_limmu6, lflags_ccf);
6348cbf5cb7Schristos 
6358cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6368cbf5cb7Schristos 		  INSN3OP_0LS (einsn->major, einsn->minor),  MINSN3OP_0LS,
6378cbf5cb7Schristos 		  arc_target, arg_32bit_limms12, lflags_f);
6388cbf5cb7Schristos 
6398cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6408cbf5cb7Schristos 		  INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
6418cbf5cb7Schristos 		  arc_target, arg_32bit_limmlimm, lflags_ccf);
6428cbf5cb7Schristos     }
6438cbf5cb7Schristos   else if (einsn->flags & ARC_SYNTAX_3OP
6448cbf5cb7Schristos 	   && !(einsn->modsyn & ARC_OP1_MUST_BE_IMM))
6458cbf5cb7Schristos     {
6468cbf5cb7Schristos       /* Regular 3OP instruction.  */
6478cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6488cbf5cb7Schristos 		  INSN3OP_ABC (einsn->major, einsn->minor),  MINSN3OP_ABC,
6498cbf5cb7Schristos 		  arc_target, arg_32bit_rarbrc, lflags_f);
6508cbf5cb7Schristos 
6518cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6528cbf5cb7Schristos 		  INSN3OP_0BC (einsn->major, einsn->minor),  MINSN3OP_0BC,
6538cbf5cb7Schristos 		  arc_target, arg_32bit_zarbrc, lflags_f);
6548cbf5cb7Schristos 
6558cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6568cbf5cb7Schristos 		  INSN3OP_CBBC (einsn->major, einsn->minor), MINSN3OP_CBBC,
6578cbf5cb7Schristos 		  arc_target, arg_32bit_rbrbrc, lflags_ccf);
6588cbf5cb7Schristos 
6598cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6608cbf5cb7Schristos 		  INSN3OP_ABU (einsn->major, einsn->minor),  MINSN3OP_ABU,
6618cbf5cb7Schristos 		  arc_target, arg_32bit_rarbu6, lflags_f);
6628cbf5cb7Schristos 
6638cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6648cbf5cb7Schristos 		  INSN3OP_0BU (einsn->major, einsn->minor),  MINSN3OP_0BU,
6658cbf5cb7Schristos 		  arc_target, arg_32bit_zarbu6, lflags_f);
6668cbf5cb7Schristos 
6678cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6688cbf5cb7Schristos 		  INSN3OP_CBBU (einsn->major, einsn->minor), MINSN3OP_CBBU,
6698cbf5cb7Schristos 		  arc_target, arg_32bit_rbrbu6, lflags_ccf);
6708cbf5cb7Schristos 
6718cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6728cbf5cb7Schristos 		  INSN3OP_BBS (einsn->major, einsn->minor),  MINSN3OP_BBS,
6738cbf5cb7Schristos 		  arc_target, arg_32bit_rbrbs12, lflags_f);
6748cbf5cb7Schristos 
6758cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6768cbf5cb7Schristos 		  INSN3OP_ALC (einsn->major, einsn->minor),  MINSN3OP_ALC,
6778cbf5cb7Schristos 		  arc_target, arg_32bit_ralimmrc, lflags_f);
6788cbf5cb7Schristos 
6798cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6808cbf5cb7Schristos 		  INSN3OP_ABL (einsn->major, einsn->minor),  MINSN3OP_ABL,
6818cbf5cb7Schristos 		  arc_target, arg_32bit_rarblimm, lflags_f);
6828cbf5cb7Schristos 
6838cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6848cbf5cb7Schristos 		  INSN3OP_0LC (einsn->major, einsn->minor),  MINSN3OP_0LC,
6858cbf5cb7Schristos 		  arc_target, arg_32bit_zalimmrc, lflags_f);
6868cbf5cb7Schristos 
6878cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6888cbf5cb7Schristos 		  INSN3OP_0BL (einsn->major, einsn->minor),  MINSN3OP_0BL,
6898cbf5cb7Schristos 		  arc_target, arg_32bit_zarblimm, lflags_f);
6908cbf5cb7Schristos 
6918cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6928cbf5cb7Schristos 		  INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
6938cbf5cb7Schristos 		  arc_target, arg_32bit_zalimmrc, lflags_ccf);
6948cbf5cb7Schristos 
6958cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
6968cbf5cb7Schristos 		  INSN3OP_CBBL (einsn->major, einsn->minor), MINSN3OP_CBBL,
6978cbf5cb7Schristos 		  arc_target, arg_32bit_rbrblimm, lflags_ccf);
6988cbf5cb7Schristos 
6998cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7008cbf5cb7Schristos 		  INSN3OP_ALU (einsn->major, einsn->minor),  MINSN3OP_ALU,
7018cbf5cb7Schristos 		  arc_target, arg_32bit_ralimmu6, lflags_f);
7028cbf5cb7Schristos 
7038cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7048cbf5cb7Schristos 		  INSN3OP_0LU (einsn->major, einsn->minor),  MINSN3OP_0LU,
7058cbf5cb7Schristos 		  arc_target, arg_32bit_zalimmu6, lflags_f);
7068cbf5cb7Schristos 
7078cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7088cbf5cb7Schristos 		  INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
7098cbf5cb7Schristos 		  arc_target, arg_32bit_zalimmu6, lflags_ccf);
7108cbf5cb7Schristos 
7118cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7128cbf5cb7Schristos 		  INSN3OP_0LS (einsn->major, einsn->minor),  MINSN3OP_0LS,
7138cbf5cb7Schristos 		  arc_target, arg_32bit_zalimms12, lflags_f);
7148cbf5cb7Schristos 
7158cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7168cbf5cb7Schristos 		  INSN3OP_ALL (einsn->major, einsn->minor),  MINSN3OP_ALL,
7178cbf5cb7Schristos 		  arc_target, arg_32bit_ralimmlimm, lflags_f);
7188cbf5cb7Schristos 
7198cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7208cbf5cb7Schristos 		  INSN3OP_0LL (einsn->major, einsn->minor),  MINSN3OP_0LL,
7218cbf5cb7Schristos 		  arc_target, arg_32bit_zalimmlimm, lflags_f);
7228cbf5cb7Schristos 
7238cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7248cbf5cb7Schristos 		  INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
7258cbf5cb7Schristos 		  arc_target, arg_32bit_zalimmlimm, lflags_ccf);
7268cbf5cb7Schristos     }
7278cbf5cb7Schristos   else if (einsn->flags & ARC_SYNTAX_3OP)
7288cbf5cb7Schristos     {
7298cbf5cb7Schristos       /* 3OP instruction which accepts only zero as first
7308cbf5cb7Schristos 	 argument.  */
7318cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7328cbf5cb7Schristos 		  INSN3OP_0BC (einsn->major, einsn->minor),  MINSN3OP_0BC,
7338cbf5cb7Schristos 		  arc_target, arg_32bit_zarbrc, lflags_f);
7348cbf5cb7Schristos 
7358cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7368cbf5cb7Schristos 		  INSN3OP_0BU (einsn->major, einsn->minor),  MINSN3OP_0BU,
7378cbf5cb7Schristos 		  arc_target, arg_32bit_zarbu6, lflags_f);
7388cbf5cb7Schristos 
7398cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7408cbf5cb7Schristos 		  INSN3OP_0LC (einsn->major, einsn->minor),  MINSN3OP_0LC,
7418cbf5cb7Schristos 		  arc_target, arg_32bit_zalimmrc, lflags_f);
7428cbf5cb7Schristos 
7438cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7448cbf5cb7Schristos 		  INSN3OP_0BL (einsn->major, einsn->minor),  MINSN3OP_0BL,
7458cbf5cb7Schristos 		  arc_target, arg_32bit_zarblimm, lflags_f);
7468cbf5cb7Schristos 
7478cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7488cbf5cb7Schristos 		  INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
7498cbf5cb7Schristos 		  arc_target, arg_32bit_zalimmrc, lflags_ccf);
7508cbf5cb7Schristos 
7518cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7528cbf5cb7Schristos 		  INSN3OP_0LU (einsn->major, einsn->minor),  MINSN3OP_0LU,
7538cbf5cb7Schristos 		  arc_target, arg_32bit_zalimmu6, lflags_f);
7548cbf5cb7Schristos 
7558cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7568cbf5cb7Schristos 		  INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
7578cbf5cb7Schristos 		  arc_target, arg_32bit_zalimmu6, lflags_ccf);
7588cbf5cb7Schristos 
7598cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7608cbf5cb7Schristos 		  INSN3OP_0LS (einsn->major, einsn->minor),  MINSN3OP_0LS,
7618cbf5cb7Schristos 		  arc_target, arg_32bit_zalimms12, lflags_f);
7628cbf5cb7Schristos 
7638cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7648cbf5cb7Schristos 		  INSN3OP_0LL (einsn->major, einsn->minor),  MINSN3OP_0LL,
7658cbf5cb7Schristos 		  arc_target, arg_32bit_zalimmlimm, lflags_f);
7668cbf5cb7Schristos 
7678cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7688cbf5cb7Schristos 		  INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
7698cbf5cb7Schristos 		  arc_target, arg_32bit_zalimmlimm, lflags_ccf);
7708cbf5cb7Schristos     }
7718cbf5cb7Schristos   else if (einsn->flags & ARC_SYNTAX_1OP)
7728cbf5cb7Schristos     {
7738cbf5cb7Schristos       if (einsn->suffix & ARC_SUFFIX_COND)
7748cbf5cb7Schristos 	*errmsg = "Suffix SUFFIX_COND ignored";
7758cbf5cb7Schristos 
7768cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7778cbf5cb7Schristos 		  INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor),
7788cbf5cb7Schristos 		  MINSN2OP_0C, arc_target, arg_32bit_rc, lflags_f);
7798cbf5cb7Schristos 
7808cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7818cbf5cb7Schristos 		  INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor)
7828cbf5cb7Schristos 		  | (0x01 << 22), MINSN2OP_0U, arc_target, arg_32bit_u6,
7838cbf5cb7Schristos 		  lflags_f);
7848cbf5cb7Schristos 
7858cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7868cbf5cb7Schristos 		  INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor)
7878cbf5cb7Schristos 		  | FIELDC (62), MINSN2OP_0L, arc_target, arg_32bit_limm,
7888cbf5cb7Schristos 		  lflags_f);
7898cbf5cb7Schristos 
7908cbf5cb7Schristos     }
7918cbf5cb7Schristos   else if (einsn->flags & ARC_SYNTAX_NOP)
7928cbf5cb7Schristos     {
7938cbf5cb7Schristos       if (einsn->suffix & ARC_SUFFIX_COND)
7948cbf5cb7Schristos 	*errmsg = "Suffix SUFFIX_COND ignored";
7958cbf5cb7Schristos 
7968cbf5cb7Schristos       INSERT_XOP (q, einsn->name,
7978cbf5cb7Schristos 		  INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor)
7988cbf5cb7Schristos 		  | (0x01 << 22), MINSN2OP_0L, arc_target, arg_none, lflags_f);
7998cbf5cb7Schristos     }
8008cbf5cb7Schristos   else
8018cbf5cb7Schristos     {
8028cbf5cb7Schristos       *errmsg = "Unknown syntax";
8038cbf5cb7Schristos       return NULL;
8048cbf5cb7Schristos     }
8058cbf5cb7Schristos 
8068cbf5cb7Schristos   /* End marker.  */
8078cbf5cb7Schristos   memset (q, 0, sizeof (*arc_ext_opcodes));
8088cbf5cb7Schristos 
8098cbf5cb7Schristos   return arc_ext_opcodes;
8108cbf5cb7Schristos }
811