Fix seg fault in linker when performing garbage collection on COFF based targets.
[external/binutils.git] / opcodes / arc-ext.c
1 /* ARC target-dependent stuff.  Extension structure access functions
2    Copyright (C) 1995-2016 Free Software Foundation, Inc.
3
4    This file is part of libopcodes.
5
6    This library is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10
11    It is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14    License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19    MA 02110-1301, USA.  */
20
21 #include "sysdep.h"
22 #include <stdlib.h>
23 #include <stdio.h>
24
25 #include "bfd.h"
26 #include "arc-ext.h"
27 #include "elf/arc.h"
28 #include "libiberty.h"
29
30 /* This module provides support for extensions to the ARC processor
31    architecture.  */
32
33
34 /* Local constants.  */
35
36 #define FIRST_EXTENSION_CORE_REGISTER   32
37 #define LAST_EXTENSION_CORE_REGISTER    59
38 #define FIRST_EXTENSION_CONDITION_CODE  0x10
39 #define LAST_EXTENSION_CONDITION_CODE   0x1f
40
41 #define NUM_EXT_CORE      \
42   (LAST_EXTENSION_CORE_REGISTER  - FIRST_EXTENSION_CORE_REGISTER  + 1)
43 #define NUM_EXT_COND      \
44   (LAST_EXTENSION_CONDITION_CODE - FIRST_EXTENSION_CONDITION_CODE + 1)
45 #define INST_HASH_BITS    6
46 #define INST_HASH_SIZE    (1 << INST_HASH_BITS)
47 #define INST_HASH_MASK    (INST_HASH_SIZE - 1)
48
49
50 /* Local types.  */
51
52 /* These types define the information stored in the table.  */
53
54 struct ExtAuxRegister
55 {
56   long                   address;
57   char*                  name;
58   struct ExtAuxRegister* next;
59 };
60
61 struct ExtCoreRegister
62 {
63   short             number;
64   enum ExtReadWrite rw;
65   char*             name;
66 };
67
68 struct arcExtMap
69 {
70   struct ExtAuxRegister* auxRegisters;
71   struct ExtInstruction* instructions[INST_HASH_SIZE];
72   struct ExtCoreRegister coreRegisters[NUM_EXT_CORE];
73   char*                  condCodes[NUM_EXT_COND];
74 };
75
76
77 /* Local data.  */
78
79 /* Extension table.  */
80 static struct arcExtMap arc_extension_map;
81
82
83 /* Local macros.  */
84
85 /* A hash function used to map instructions into the table.  */
86 #define INST_HASH(MAJOR, MINOR)    ((((MAJOR) << 3) ^ (MINOR)) & INST_HASH_MASK)
87
88
89 /* Local functions.  */
90
91 static void
92 create_map (unsigned char *block,
93             unsigned long length)
94 {
95   unsigned char *p = block;
96
97   while (p && p < (block + length))
98     {
99       /* p[0] == length of record
100          p[1] == type of record
101          For instructions:
102            p[2]  = opcode
103            p[3]  = minor opcode (if opcode == 3)
104            p[4]  = flags
105            p[5]+ = name
106          For core regs and condition codes:
107            p[2]  = value
108            p[3]+ = name
109          For auxiliary regs:
110            p[2..5] = value
111            p[6]+   = name
112              (value is p[2]<<24|p[3]<<16|p[4]<<8|p[5]).  */
113
114       /* The sequence of records is temrinated by an "empty"
115          record.  */
116       if (p[0] == 0)
117         break;
118
119       switch (p[1])
120         {
121         case EXT_INSTRUCTION:
122           {
123             struct ExtInstruction  *insn = XNEW (struct ExtInstruction);
124             int                     major = p[2];
125             int                     minor = p[3];
126             struct ExtInstruction **bucket =
127                    &arc_extension_map.instructions[INST_HASH (major, minor)];
128
129             insn->name  = xstrdup ((char *) (p + 5));
130             insn->major = major;
131             insn->minor = minor;
132             insn->flags = p[4];
133             insn->next  = *bucket;
134             insn->suffix = 0;
135             insn->syntax = 0;
136             insn->modsyn = 0;
137             *bucket = insn;
138             break;
139           }
140
141         case EXT_CORE_REGISTER:
142           {
143             unsigned char number = p[2];
144             char*         name   = (char *) (p + 3);
145
146             arc_extension_map.
147               coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].number
148               = number;
149             arc_extension_map.
150               coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].rw
151               = REG_READWRITE;
152             arc_extension_map.
153               coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].name
154               = xstrdup (name);
155             break;
156           }
157
158         case EXT_LONG_CORE_REGISTER:
159           {
160             unsigned char     number = p[2];
161             char*             name   = (char *) (p + 7);
162             enum ExtReadWrite rw     = p[6];
163
164             arc_extension_map.
165               coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].number
166               = number;
167             arc_extension_map.
168               coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].rw
169               = rw;
170             arc_extension_map.
171               coreRegisters[number - FIRST_EXTENSION_CORE_REGISTER].name
172               = xstrdup (name);
173           }
174
175         case EXT_COND_CODE:
176           {
177             char *cc_name = xstrdup ((char *) (p + 3));
178
179             arc_extension_map.
180               condCodes[p[2] - FIRST_EXTENSION_CONDITION_CODE]
181               = cc_name;
182             break;
183           }
184
185         case EXT_AUX_REGISTER:
186           {
187             /* Trickier -- need to store linked list of these.  */
188             struct ExtAuxRegister *newAuxRegister
189               = XNEW (struct ExtAuxRegister);
190             char *aux_name = xstrdup ((char *) (p + 6));
191
192             newAuxRegister->name = aux_name;
193             newAuxRegister->address = (p[2] << 24) | (p[3] << 16)
194               | (p[4] << 8) | p[5];
195             newAuxRegister->next = arc_extension_map.auxRegisters;
196             arc_extension_map.auxRegisters = newAuxRegister;
197             break;
198           }
199
200         default:
201           break;
202         }
203
204       p += p[0]; /* Move on to next record.  */
205     }
206 }
207
208
209 /* Free memory that has been allocated for the extensions.  */
210
211 static void
212 destroy_map (void)
213 {
214   struct ExtAuxRegister *r;
215   unsigned int           i;
216
217   /* Free auxiliary registers.  */
218   r = arc_extension_map.auxRegisters;
219   while (r)
220     {
221       /* N.B. after r has been freed, r->next is invalid!  */
222       struct ExtAuxRegister* next = r->next;
223
224       free (r->name);
225       free (r);
226       r = next;
227     }
228
229   /* Free instructions.  */
230   for (i = 0; i < INST_HASH_SIZE; i++)
231     {
232       struct ExtInstruction *insn = arc_extension_map.instructions[i];
233
234       while (insn)
235         {
236           /* N.B. after insn has been freed, insn->next is invalid!  */
237           struct ExtInstruction *next = insn->next;
238
239           free (insn->name);
240           free (insn);
241           insn = next;
242         }
243     }
244
245   /* Free core registers.  */
246   for (i = 0; i < NUM_EXT_CORE; i++)
247     {
248       if (arc_extension_map.coreRegisters[i].name)
249         free (arc_extension_map.coreRegisters[i].name);
250     }
251
252   /* Free condition codes.  */
253   for (i = 0; i < NUM_EXT_COND; i++)
254     {
255       if (arc_extension_map.condCodes[i])
256         free (arc_extension_map.condCodes[i]);
257     }
258
259   memset (&arc_extension_map, 0, sizeof (arc_extension_map));
260 }
261
262
263 static const char *
264 ExtReadWrite_image (enum ExtReadWrite val)
265 {
266     switch (val)
267     {
268         case REG_INVALID  : return "INVALID";
269         case REG_READ     : return "RO";
270         case REG_WRITE    : return "WO";
271         case REG_READWRITE: return "R/W";
272         default           : return "???";
273     }
274 }
275
276
277 /* Externally visible functions.  */
278
279 /* Get the name of an extension instruction.  */
280
281 const extInstruction_t *
282 arcExtMap_insn (int opcode, int insn)
283 {
284   /* Here the following tasks need to be done.  First of all, the
285      opcode stored in the Extension Map is the real opcode.  However,
286      the subopcode stored in the instruction to be disassembled is
287      mangled.  We pass (in minor opcode), the instruction word.  Here
288      we will un-mangle it and get the real subopcode which we can look
289      for in the Extension Map.  This function is used both for the
290      ARCTangent and the ARCompact, so we would also need some sort of
291      a way to distinguish between the two architectures.  This is
292      because the ARCTangent does not do any of this mangling so we
293      have no issues there.  */
294
295   /* If P[22:23] is 0 or 2 then un-mangle using iiiiiI.  If it is 1
296      then use iiiiIi.  Now, if P is 3 then check M[5:5] and if it is 0
297      then un-mangle using iiiiiI else iiiiii.  */
298
299   unsigned char minor;
300   extInstruction_t *temp;
301
302   /* 16-bit instructions.  */
303   if (0x08 <= opcode && opcode <= 0x0b)
304     {
305       unsigned char b, c, i;
306
307       b = (insn & 0x0700) >> 8;
308       c = (insn & 0x00e0) >> 5;
309       i = (insn & 0x001f);
310
311       if (i)
312         minor = i;
313       else
314         minor = (c == 0x07) ? b : c;
315     }
316   /* 32-bit instructions.  */
317   else
318     {
319       unsigned char I, A, B;
320
321       I = (insn & 0x003f0000) >> 16;
322       A = (insn & 0x0000003f);
323       B = ((insn & 0x07000000) >> 24) | ((insn & 0x00007000) >> 9);
324
325       if (I != 0x2f)
326         {
327 #ifndef UNMANGLED
328           switch (P)
329             {
330             case 3:
331               if (M)
332                 {
333                   minor = I;
334                   break;
335                 }
336             case 0:
337             case 2:
338               minor = (I >> 1) | ((I & 0x1) << 5);
339               break;
340             case 1:
341               minor = (I >> 1) | (I & 0x1) | ((I & 0x2) << 4);
342             }
343 #else
344           minor = I;
345 #endif
346         }
347       else
348         {
349           if (A != 0x3f)
350             minor = A;
351           else
352             minor = B;
353         }
354     }
355
356   temp = arc_extension_map.instructions[INST_HASH (opcode, minor)];
357   while (temp)
358     {
359       if ((temp->major == opcode) && (temp->minor == minor))
360         {
361           return temp;
362         }
363       temp = temp->next;
364     }
365
366   return NULL;
367 }
368
369 /* Get the name of an extension core register.  */
370
371 const char *
372 arcExtMap_coreRegName (int regnum)
373 {
374   if (regnum < FIRST_EXTENSION_CORE_REGISTER
375       || regnum > LAST_EXTENSION_CORE_REGISTER)
376     return NULL;
377   return arc_extension_map.
378     coreRegisters[regnum - FIRST_EXTENSION_CORE_REGISTER].name;
379 }
380
381 /* Get the access mode of an extension core register.  */
382
383 enum ExtReadWrite
384 arcExtMap_coreReadWrite (int regnum)
385 {
386   if (regnum < FIRST_EXTENSION_CORE_REGISTER
387       || regnum > LAST_EXTENSION_CORE_REGISTER)
388     return REG_INVALID;
389   return arc_extension_map.
390     coreRegisters[regnum - FIRST_EXTENSION_CORE_REGISTER].rw;
391 }
392
393 /* Get the name of an extension condition code.  */
394
395 const char *
396 arcExtMap_condCodeName (int code)
397 {
398   if (code < FIRST_EXTENSION_CONDITION_CODE
399       || code > LAST_EXTENSION_CONDITION_CODE)
400     return NULL;
401   return arc_extension_map.
402     condCodes[code - FIRST_EXTENSION_CONDITION_CODE];
403 }
404
405 /* Get the name of an extension auxiliary register.  */
406
407 const char *
408 arcExtMap_auxRegName (long address)
409 {
410   /* Walk the list of auxiliary register names and find the name.  */
411   struct ExtAuxRegister *r;
412
413   for (r = arc_extension_map.auxRegisters; r; r = r->next)
414     {
415       if (r->address == address)
416         return (const char *)r->name;
417     }
418   return NULL;
419 }
420
421 /* Load extensions described in .arcextmap and
422    .gnu.linkonce.arcextmap.* ELF section.  */
423
424 void
425 build_ARC_extmap (bfd *text_bfd)
426 {
427   asection *sect;
428
429   /* The map is built each time gdb loads an executable file - so free
430      any existing map, as the map defined by the new file may differ
431      from the old.  */
432   destroy_map ();
433
434   for (sect = text_bfd->sections; sect != NULL; sect = sect->next)
435     if (!strncmp (sect->name,
436                   ".gnu.linkonce.arcextmap.",
437           sizeof (".gnu.linkonce.arcextmap.") - 1)
438         || !strcmp (sect->name,".arcextmap"))
439       {
440         bfd_size_type  count  = bfd_get_section_size (sect);
441         unsigned char* buffer = xmalloc (count);
442
443         if (buffer)
444           {
445             if (bfd_get_section_contents (text_bfd, sect, buffer, 0, count))
446               create_map (buffer, count);
447             free (buffer);
448           }
449       }
450 }
451
452 /* Debug function used to dump the ARC information fount in arcextmap
453    sections.  */
454
455 void
456 dump_ARC_extmap (void)
457 {
458     struct ExtAuxRegister *r;
459     int                    i;
460
461     r = arc_extension_map.auxRegisters;
462
463     while (r)
464     {
465         printf ("AUX : %s %ld\n", r->name, r->address);
466         r = r->next;
467     }
468
469     for (i = 0; i < INST_HASH_SIZE; i++)
470     {
471         struct ExtInstruction *insn;
472
473         for (insn = arc_extension_map.instructions[i];
474              insn != NULL; insn = insn->next)
475           {
476             printf ("INST: 0x%02x 0x%02x ", insn->major, insn->minor);
477             switch (insn->flags & ARC_SYNTAX_MASK)
478               {
479               case ARC_SYNTAX_2OP:
480                 printf ("SYNTAX_2OP");
481                 break;
482               case ARC_SYNTAX_3OP:
483                 printf ("SYNTAX_3OP");
484                 break;
485               case ARC_SYNTAX_1OP:
486                 printf ("SYNTAX_1OP");
487                 break;
488               case ARC_SYNTAX_NOP:
489                 printf ("SYNTAX_NOP");
490                 break;
491               default:
492                 printf ("SYNTAX_UNK");
493                 break;
494               }
495
496             if (insn->flags & 0x10)
497               printf ("|MODIFIER");
498
499             printf (" %s\n", insn->name);
500           }
501     }
502
503     for (i = 0; i < NUM_EXT_CORE; i++)
504     {
505         struct ExtCoreRegister reg = arc_extension_map.coreRegisters[i];
506
507         if (reg.name)
508           printf ("CORE: 0x%04x %s %s\n", reg.number,
509                   ExtReadWrite_image (reg.rw),
510                   reg.name);
511     }
512
513     for (i = 0; i < NUM_EXT_COND; i++)
514         if (arc_extension_map.condCodes[i])
515             printf ("COND: %s\n", arc_extension_map.condCodes[i]);
516 }
517
518 /* For a given extension instruction generate the equivalent arc
519    opcode structure.  */
520
521 struct arc_opcode *
522 arcExtMap_genOpcode (const extInstruction_t *einsn,
523                      unsigned arc_target,
524                      const char **errmsg)
525 {
526   struct arc_opcode *q, *arc_ext_opcodes = NULL;
527   const unsigned char *lflags_f;
528   const unsigned char *lflags_ccf;
529   int count;
530
531   /* Check for the class to see how many instructions we generate.  */
532   switch (einsn->flags & ARC_SYNTAX_MASK)
533     {
534     case ARC_SYNTAX_3OP:
535       count = (einsn->modsyn & ARC_OP1_MUST_BE_IMM) ? 10 : 20;
536       break;
537     case ARC_SYNTAX_2OP:
538       count = (einsn->flags & 0x10) ? 7 : 6;
539       break;
540     case ARC_SYNTAX_1OP:
541       count = 3;
542       break;
543     case ARC_SYNTAX_NOP:
544       count = 1;
545       break;
546     default:
547       count = 0;
548       break;
549     }
550
551   /* Allocate memory.  */
552   arc_ext_opcodes = (struct arc_opcode *)
553     xmalloc ((count + 1) * sizeof (*arc_ext_opcodes));
554
555   if (arc_ext_opcodes == NULL)
556     {
557       *errmsg = "Virtual memory exhausted";
558       return NULL;
559     }
560
561   /* Generate the patterns.  */
562   q = arc_ext_opcodes;
563
564   if (einsn->suffix)
565     {
566       lflags_f   = flags_none;
567       lflags_ccf = flags_none;
568     }
569   else
570     {
571       lflags_f   = flags_f;
572       lflags_ccf = flags_ccf;
573     }
574
575   if (einsn->suffix & ARC_SUFFIX_COND)
576     lflags_ccf = flags_cc;
577   if (einsn->suffix & ARC_SUFFIX_FLAG)
578     {
579       lflags_f   = flags_f;
580       lflags_ccf = flags_f;
581     }
582   if (einsn->suffix & (ARC_SUFFIX_FLAG | ARC_SUFFIX_COND))
583     lflags_ccf = flags_ccf;
584
585   if (einsn->flags & ARC_SYNTAX_2OP
586       && !(einsn->flags & 0x10))
587     {
588       /* Regular 2OP instruction.  */
589       if (einsn->suffix & ARC_SUFFIX_COND)
590         *errmsg = "Suffix SUFFIX_COND ignored";
591
592       INSERT_XOP (q, einsn->name,
593                   INSN2OP_BC (einsn->major, einsn->minor), MINSN2OP_BC,
594                   arc_target, arg_32bit_rbrc, lflags_f);
595
596       INSERT_XOP (q, einsn->name,
597                   INSN2OP_0C (einsn->major, einsn->minor), MINSN2OP_0C,
598                   arc_target, arg_32bit_zarc, lflags_f);
599
600       INSERT_XOP (q, einsn->name,
601                   INSN2OP_BU (einsn->major, einsn->minor), MINSN2OP_BU,
602                   arc_target, arg_32bit_rbu6, lflags_f);
603
604       INSERT_XOP (q, einsn->name,
605                   INSN2OP_0U (einsn->major, einsn->minor), MINSN2OP_0U,
606                   arc_target, arg_32bit_zau6, lflags_f);
607
608       INSERT_XOP (q, einsn->name,
609                   INSN2OP_BL (einsn->major, einsn->minor), MINSN2OP_BL,
610                   arc_target, arg_32bit_rblimm, lflags_f);
611
612       INSERT_XOP (q, einsn->name,
613                   INSN2OP_0L (einsn->major, einsn->minor), MINSN2OP_0L,
614                   arc_target, arg_32bit_zalimm, lflags_f);
615     }
616   else if (einsn->flags & (0x10 | ARC_SYNTAX_2OP))
617     {
618       /* This is actually a 3OP pattern.  The first operand is
619          immplied and is set to zero.  */
620       INSERT_XOP (q, einsn->name,
621                   INSN3OP_0BC (einsn->major, einsn->minor),  MINSN3OP_0BC,
622                   arc_target, arg_32bit_rbrc, lflags_f);
623
624       INSERT_XOP (q, einsn->name,
625                   INSN3OP_0BU (einsn->major, einsn->minor),  MINSN3OP_0BU,
626                   arc_target, arg_32bit_rbu6, lflags_f);
627
628       INSERT_XOP (q, einsn->name,
629                   INSN3OP_0BL (einsn->major, einsn->minor),  MINSN3OP_0BL,
630                   arc_target, arg_32bit_rblimm, lflags_f);
631
632       INSERT_XOP (q, einsn->name,
633                   INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
634                   arc_target, arg_32bit_limmrc, lflags_ccf);
635
636       INSERT_XOP (q, einsn->name,
637                   INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
638                   arc_target, arg_32bit_limmu6, lflags_ccf);
639
640       INSERT_XOP (q, einsn->name,
641                   INSN3OP_0LS (einsn->major, einsn->minor),  MINSN3OP_0LS,
642                   arc_target, arg_32bit_limms12, lflags_f);
643
644       INSERT_XOP (q, einsn->name,
645                   INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
646                   arc_target, arg_32bit_limmlimm, lflags_ccf);
647     }
648   else if (einsn->flags & ARC_SYNTAX_3OP
649            && !(einsn->modsyn & ARC_OP1_MUST_BE_IMM))
650     {
651       /* Regular 3OP instruction.  */
652       INSERT_XOP (q, einsn->name,
653                   INSN3OP_ABC (einsn->major, einsn->minor),  MINSN3OP_ABC,
654                   arc_target, arg_32bit_rarbrc, lflags_f);
655
656       INSERT_XOP (q, einsn->name,
657                   INSN3OP_0BC (einsn->major, einsn->minor),  MINSN3OP_0BC,
658                   arc_target, arg_32bit_zarbrc, lflags_f);
659
660       INSERT_XOP (q, einsn->name,
661                   INSN3OP_CBBC (einsn->major, einsn->minor), MINSN3OP_CBBC,
662                   arc_target, arg_32bit_rbrbrc, lflags_ccf);
663
664       INSERT_XOP (q, einsn->name,
665                   INSN3OP_ABU (einsn->major, einsn->minor),  MINSN3OP_ABU,
666                   arc_target, arg_32bit_rarbu6, lflags_f);
667
668       INSERT_XOP (q, einsn->name,
669                   INSN3OP_0BU (einsn->major, einsn->minor),  MINSN3OP_0BU,
670                   arc_target, arg_32bit_zarbu6, lflags_f);
671
672       INSERT_XOP (q, einsn->name,
673                   INSN3OP_CBBU (einsn->major, einsn->minor), MINSN3OP_CBBU,
674                   arc_target, arg_32bit_rbrbu6, lflags_ccf);
675
676       INSERT_XOP (q, einsn->name,
677                   INSN3OP_BBS (einsn->major, einsn->minor),  MINSN3OP_BBS,
678                   arc_target, arg_32bit_rbrbs12, lflags_f);
679
680       INSERT_XOP (q, einsn->name,
681                   INSN3OP_ALC (einsn->major, einsn->minor),  MINSN3OP_ALC,
682                   arc_target, arg_32bit_ralimmrc, lflags_f);
683
684       INSERT_XOP (q, einsn->name,
685                   INSN3OP_ABL (einsn->major, einsn->minor),  MINSN3OP_ABL,
686                   arc_target, arg_32bit_rarblimm, lflags_f);
687
688       INSERT_XOP (q, einsn->name,
689                   INSN3OP_0LC (einsn->major, einsn->minor),  MINSN3OP_0LC,
690                   arc_target, arg_32bit_zalimmrc, lflags_f);
691
692       INSERT_XOP (q, einsn->name,
693                   INSN3OP_0BL (einsn->major, einsn->minor),  MINSN3OP_0BL,
694                   arc_target, arg_32bit_zarblimm, lflags_f);
695
696       INSERT_XOP (q, einsn->name,
697                   INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
698                   arc_target, arg_32bit_zalimmrc, lflags_ccf);
699
700       INSERT_XOP (q, einsn->name,
701                   INSN3OP_CBBL (einsn->major, einsn->minor), MINSN3OP_CBBL,
702                   arc_target, arg_32bit_rbrblimm, lflags_ccf);
703
704       INSERT_XOP (q, einsn->name,
705                   INSN3OP_ALU (einsn->major, einsn->minor),  MINSN3OP_ALU,
706                   arc_target, arg_32bit_ralimmu6, lflags_f);
707
708       INSERT_XOP (q, einsn->name,
709                   INSN3OP_0LU (einsn->major, einsn->minor),  MINSN3OP_0LU,
710                   arc_target, arg_32bit_zalimmu6, lflags_f);
711
712       INSERT_XOP (q, einsn->name,
713                   INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
714                   arc_target, arg_32bit_zalimmu6, lflags_ccf);
715
716       INSERT_XOP (q, einsn->name,
717                   INSN3OP_0LS (einsn->major, einsn->minor),  MINSN3OP_0LS,
718                   arc_target, arg_32bit_zalimms12, lflags_f);
719
720       INSERT_XOP (q, einsn->name,
721                   INSN3OP_ALL (einsn->major, einsn->minor),  MINSN3OP_ALL,
722                   arc_target, arg_32bit_ralimmlimm, lflags_f);
723
724       INSERT_XOP (q, einsn->name,
725                   INSN3OP_0LL (einsn->major, einsn->minor),  MINSN3OP_0LL,
726                   arc_target, arg_32bit_zalimmlimm, lflags_f);
727
728       INSERT_XOP (q, einsn->name,
729                   INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
730                   arc_target, arg_32bit_zalimmlimm, lflags_ccf);
731     }
732   else if (einsn->flags & ARC_SYNTAX_3OP)
733     {
734       /* 3OP instruction which accepts only zero as first
735          argument.  */
736       INSERT_XOP (q, einsn->name,
737                   INSN3OP_0BC (einsn->major, einsn->minor),  MINSN3OP_0BC,
738                   arc_target, arg_32bit_zarbrc, lflags_f);
739
740       INSERT_XOP (q, einsn->name,
741                   INSN3OP_0BU (einsn->major, einsn->minor),  MINSN3OP_0BU,
742                   arc_target, arg_32bit_zarbu6, lflags_f);
743
744       INSERT_XOP (q, einsn->name,
745                   INSN3OP_0LC (einsn->major, einsn->minor),  MINSN3OP_0LC,
746                   arc_target, arg_32bit_zalimmrc, lflags_f);
747
748       INSERT_XOP (q, einsn->name,
749                   INSN3OP_0BL (einsn->major, einsn->minor),  MINSN3OP_0BL,
750                   arc_target, arg_32bit_zarblimm, lflags_f);
751
752       INSERT_XOP (q, einsn->name,
753                   INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
754                   arc_target, arg_32bit_zalimmrc, lflags_ccf);
755
756       INSERT_XOP (q, einsn->name,
757                   INSN3OP_0LU (einsn->major, einsn->minor),  MINSN3OP_0LU,
758                   arc_target, arg_32bit_zalimmu6, lflags_f);
759
760       INSERT_XOP (q, einsn->name,
761                   INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
762                   arc_target, arg_32bit_zalimmu6, lflags_ccf);
763
764       INSERT_XOP (q, einsn->name,
765                   INSN3OP_0LS (einsn->major, einsn->minor),  MINSN3OP_0LS,
766                   arc_target, arg_32bit_zalimms12, lflags_f);
767
768       INSERT_XOP (q, einsn->name,
769                   INSN3OP_0LL (einsn->major, einsn->minor),  MINSN3OP_0LL,
770                   arc_target, arg_32bit_zalimmlimm, lflags_f);
771
772       INSERT_XOP (q, einsn->name,
773                   INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
774                   arc_target, arg_32bit_zalimmlimm, lflags_ccf);
775     }
776   else if (einsn->flags & ARC_SYNTAX_1OP)
777     {
778       if (einsn->suffix & ARC_SUFFIX_COND)
779         *errmsg = "Suffix SUFFIX_COND ignored";
780
781       INSERT_XOP (q, einsn->name,
782                   INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor),
783                   MINSN2OP_0C, arc_target, arg_32bit_rc, lflags_f);
784
785       INSERT_XOP (q, einsn->name,
786                   INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor)
787                   | (0x01 << 22), MINSN2OP_0U, arc_target, arg_32bit_u6,
788                   lflags_f);
789
790       INSERT_XOP (q, einsn->name,
791                   INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor)
792                   | FIELDC (62), MINSN2OP_0L, arc_target, arg_32bit_limm,
793                   lflags_f);
794
795     }
796   else if (einsn->flags & ARC_SYNTAX_NOP)
797     {
798       if (einsn->suffix & ARC_SUFFIX_COND)
799         *errmsg = "Suffix SUFFIX_COND ignored";
800
801       INSERT_XOP (q, einsn->name,
802                   INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor)
803                   | (0x01 << 22), MINSN2OP_0L, arc_target, arg_none, lflags_f);
804     }
805   else
806     {
807       *errmsg = "Unknown syntax";
808       return NULL;
809     }
810
811   /* End marker.  */
812   memset (q, 0, sizeof (*arc_ext_opcodes));
813
814   return arc_ext_opcodes;
815 }