Throw NOT_AVAILABLE_ERROR in read_stack and read_code
[deliverable/binutils-gdb.git] / opcodes / arc-ext.c
CommitLineData
886a2506 1/* ARC target-dependent stuff. Extension structure access functions
6f2750fe 2 Copyright (C) 1995-2016 Free Software Foundation, Inc.
0d2bcfaf 3
9b201bb5 4 This file is part of libopcodes.
0d2bcfaf 5
9b201bb5 6 This library is free software; you can redistribute it and/or modify
0d2bcfaf 7 it under the terms of the GNU General Public License as published by
9b201bb5
NC
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
0d2bcfaf 10
9b201bb5
NC
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.
0d2bcfaf
NC
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
9b201bb5
NC
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
0d2bcfaf 20
5bd67f35 21#include "sysdep.h"
0d2bcfaf
NC
22#include <stdlib.h>
23#include <stdio.h>
886a2506 24
0d2bcfaf
NC
25#include "bfd.h"
26#include "arc-ext.h"
886a2506 27#include "elf/arc.h"
0d2bcfaf
NC
28#include "libiberty.h"
29
886a2506
NC
30/* This module provides support for extensions to the ARC processor
31 architecture. */
0d2bcfaf 32
0d2bcfaf 33
886a2506 34/* Local constants. */
0d2bcfaf 35
886a2506
NC
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
0d2bcfaf 40
886a2506
NC
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)
0d2bcfaf 48
0d2bcfaf 49
886a2506 50/* Local types. */
0d2bcfaf 51
886a2506 52/* These types define the information stored in the table. */
0d2bcfaf 53
886a2506
NC
54struct ExtAuxRegister
55{
56 long address;
57 char* name;
58 struct ExtAuxRegister* next;
59};
0d2bcfaf 60
886a2506
NC
61struct ExtCoreRegister
62{
63 short number;
64 enum ExtReadWrite rw;
65 char* name;
66};
0d2bcfaf 67
886a2506 68struct arcExtMap
0d2bcfaf 69{
886a2506
NC
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};
5bd67f35 75
0d2bcfaf 76
886a2506 77/* Local data. */
0d2bcfaf 78
886a2506
NC
79/* Extension table. */
80static struct arcExtMap arc_extension_map;
5bd67f35 81
5bd67f35 82
886a2506 83/* Local macros. */
5bd67f35 84
886a2506
NC
85/* A hash function used to map instructions into the table. */
86#define INST_HASH(MAJOR, MINOR) ((((MAJOR) << 3) ^ (MINOR)) & INST_HASH_MASK)
5bd67f35 87
0d2bcfaf 88
886a2506 89/* Local functions. */
5bd67f35 90
886a2506
NC
91static void
92create_map (unsigned char *block,
93 unsigned long length)
94{
95 unsigned char *p = block;
0d2bcfaf 96
5bd67f35 97 while (p && p < (block + length))
0d2bcfaf
NC
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
886a2506 109 For auxiliary regs:
0d2bcfaf
NC
110 p[2..5] = value
111 p[6]+ = name
886a2506 112 (value is p[2]<<24|p[3]<<16|p[4]<<8|p[5]). */
0d2bcfaf 113
886a2506
NC
114 /* The sequence of records is temrinated by an "empty"
115 record. */
0d2bcfaf 116 if (p[0] == 0)
886a2506 117 break;
5bd67f35 118
0d2bcfaf
NC
119 switch (p[1])
120 {
121 case EXT_INSTRUCTION:
122 {
886a2506
NC
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;
b99747ae
CZ
134 insn->suffix = 0;
135 insn->syntax = 0;
136 insn->modsyn = 0;
886a2506
NC
137 *bucket = insn;
138 break;
0d2bcfaf 139 }
5bd67f35
AJ
140
141 case EXT_CORE_REGISTER:
0d2bcfaf 142 {
886a2506
NC
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 }
0d2bcfaf 157
886a2506
NC
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);
0d2bcfaf 173 }
5bd67f35
AJ
174
175 case EXT_COND_CODE:
0d2bcfaf 176 {
886a2506
NC
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;
5bd67f35 183 }
5bd67f35
AJ
184
185 case EXT_AUX_REGISTER:
0d2bcfaf 186 {
886a2506
NC
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));
0d2bcfaf 191
0d2bcfaf 192 newAuxRegister->name = aux_name;
886a2506
NC
193 newAuxRegister->address = (p[2] << 24) | (p[3] << 16)
194 | (p[4] << 8) | p[5];
0d2bcfaf
NC
195 newAuxRegister->next = arc_extension_map.auxRegisters;
196 arc_extension_map.auxRegisters = newAuxRegister;
886a2506 197 break;
0d2bcfaf 198 }
5bd67f35 199
0d2bcfaf 200 default:
886a2506
NC
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
211static void
212destroy_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 }
5bd67f35 251
886a2506
NC
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
263static const char *
264ExtReadWrite_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
b99747ae
CZ
281const extInstruction_t *
282arcExtMap_insn (int opcode, int insn)
886a2506
NC
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;
b99747ae 300 extInstruction_t *temp;
886a2506
NC
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 {
b99747ae 361 return temp;
0d2bcfaf 362 }
886a2506 363 temp = temp->next;
0d2bcfaf 364 }
5bd67f35 365
886a2506 366 return NULL;
0d2bcfaf
NC
367}
368
886a2506 369/* Get the name of an extension core register. */
0d2bcfaf 370
886a2506
NC
371const char *
372arcExtMap_coreRegName (int regnum)
373{
374 if (regnum < FIRST_EXTENSION_CORE_REGISTER
f36e33da 375 || regnum > LAST_EXTENSION_CORE_REGISTER)
886a2506
NC
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
383enum ExtReadWrite
384arcExtMap_coreReadWrite (int regnum)
0d2bcfaf 385{
886a2506 386 if (regnum < FIRST_EXTENSION_CORE_REGISTER
f36e33da 387 || regnum > LAST_EXTENSION_CORE_REGISTER)
886a2506
NC
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
395const char *
396arcExtMap_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
407const char *
408arcExtMap_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. */
0d2bcfaf 423
886a2506
NC
424void
425build_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"))
0d2bcfaf 439 {
886a2506
NC
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 }
0d2bcfaf
NC
449 }
450}
886a2506 451
b99747ae
CZ
452/* Debug function used to dump the ARC information fount in arcextmap
453 sections. */
886a2506
NC
454
455void
456dump_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)
b99747ae
CZ
475 {
476 printf ("INST: 0x%02x 0x%02x ", insn->major, insn->minor);
477 if (insn->flags & ARC_SYNTAX_2OP)
478 printf ("SYNTAX_2OP");
479 else if (insn->flags & ARC_SYNTAX_3OP)
480 printf ("SYNTAX_3OP");
481 else
482 printf ("SYNTAX_UNK");
483
484 if (insn->flags & 0x10)
485 printf ("|MODIFIER");
486
487 printf (" %s\n", insn->name);
488 }
886a2506
NC
489 }
490
491 for (i = 0; i < NUM_EXT_CORE; i++)
492 {
493 struct ExtCoreRegister reg = arc_extension_map.coreRegisters[i];
494
495 if (reg.name)
f36e33da
CZ
496 printf ("CORE: 0x%04x %s %s\n", reg.number,
497 ExtReadWrite_image (reg.rw),
498 reg.name);
886a2506
NC
499 }
500
501 for (i = 0; i < NUM_EXT_COND; i++)
502 if (arc_extension_map.condCodes[i])
503 printf ("COND: %s\n", arc_extension_map.condCodes[i]);
504}
b99747ae
CZ
505
506/* For a given extension instruction generate the equivalent arc
507 opcode structure. */
508
509struct arc_opcode *
510arcExtMap_genOpcode (const extInstruction_t *einsn,
511 unsigned arc_target,
512 const char **errmsg)
513{
514 struct arc_opcode *q, *arc_ext_opcodes = NULL;
515 const unsigned char *lflags_f;
516 const unsigned char *lflags_ccf;
517 int count;
518
519 /* Check for the class to see how many instructions we generate. */
520 switch (einsn->flags & (ARC_SYNTAX_3OP | ARC_SYNTAX_2OP))
521 {
522 case ARC_SYNTAX_3OP:
523 count = (einsn->modsyn & ARC_OP1_MUST_BE_IMM) ? 10 : 20;
524 break;
525 case ARC_SYNTAX_2OP:
526 count = (einsn->flags & 0x10) ? 7 : 6;
527 break;
528 default:
529 count = 0;
530 break;
531 }
532
533 /* Allocate memory. */
534 arc_ext_opcodes = (struct arc_opcode *)
535 xmalloc ((count + 1) * sizeof (*arc_ext_opcodes));
536
537 if (arc_ext_opcodes == NULL)
538 {
539 *errmsg = "Virtual memory exhausted";
540 return NULL;
541 }
542
543 /* Generate the patterns. */
544 q = arc_ext_opcodes;
545
546 if (einsn->suffix)
547 {
548 lflags_f = flags_none;
549 lflags_ccf = flags_none;
550 }
551 else
552 {
553 lflags_f = flags_f;
554 lflags_ccf = flags_ccf;
555 }
556
557 if (einsn->suffix & ARC_SUFFIX_COND)
558 lflags_ccf = flags_cc;
559 if (einsn->suffix & ARC_SUFFIX_FLAG)
560 {
561 lflags_f = flags_f;
562 lflags_ccf = flags_f;
563 }
564 if (einsn->suffix & (ARC_SUFFIX_FLAG | ARC_SUFFIX_COND))
565 lflags_ccf = flags_ccf;
566
567 if (einsn->flags & ARC_SYNTAX_2OP
568 && !(einsn->flags & 0x10))
569 {
570 /* Regular 2OP instruction. */
571 if (einsn->suffix & ARC_SUFFIX_COND)
572 *errmsg = "Suffix SUFFIX_COND ignored";
573
574 INSERT_XOP (q, einsn->name,
575 INSN2OP_BC (einsn->major, einsn->minor), MINSN2OP_BC,
576 arc_target, arg_32bit_rbrc, lflags_f);
577
578 INSERT_XOP (q, einsn->name,
579 INSN2OP_0C (einsn->major, einsn->minor), MINSN2OP_0C,
580 arc_target, arg_32bit_zarc, lflags_f);
581
582 INSERT_XOP (q, einsn->name,
583 INSN2OP_BU (einsn->major, einsn->minor), MINSN2OP_BU,
584 arc_target, arg_32bit_rbu6, lflags_f);
585
586 INSERT_XOP (q, einsn->name,
587 INSN2OP_0U (einsn->major, einsn->minor), MINSN2OP_0U,
588 arc_target, arg_32bit_zau6, lflags_f);
589
590 INSERT_XOP (q, einsn->name,
591 INSN2OP_BL (einsn->major, einsn->minor), MINSN2OP_BL,
592 arc_target, arg_32bit_rblimm, lflags_f);
593
594 INSERT_XOP (q, einsn->name,
595 INSN2OP_0L (einsn->major, einsn->minor), MINSN2OP_0L,
596 arc_target, arg_32bit_zalimm, lflags_f);
597 }
598 else if (einsn->flags & (0x10 | ARC_SYNTAX_2OP))
599 {
600 /* This is actually a 3OP pattern. The first operand is
601 immplied and is set to zero. */
602 INSERT_XOP (q, einsn->name,
603 INSN3OP_0BC (einsn->major, einsn->minor), MINSN3OP_0BC,
604 arc_target, arg_32bit_rbrc, lflags_f);
605
606 INSERT_XOP (q, einsn->name,
607 INSN3OP_0BU (einsn->major, einsn->minor), MINSN3OP_0BU,
608 arc_target, arg_32bit_rbu6, lflags_f);
609
610 INSERT_XOP (q, einsn->name,
611 INSN3OP_0BL (einsn->major, einsn->minor), MINSN3OP_0BL,
612 arc_target, arg_32bit_rblimm, lflags_f);
613
614 INSERT_XOP (q, einsn->name,
615 INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
616 arc_target, arg_32bit_limmrc, lflags_ccf);
617
618 INSERT_XOP (q, einsn->name,
619 INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
620 arc_target, arg_32bit_limmu6, lflags_ccf);
621
622 INSERT_XOP (q, einsn->name,
623 INSN3OP_0LS (einsn->major, einsn->minor), MINSN3OP_0LS,
624 arc_target, arg_32bit_limms12, lflags_f);
625
626 INSERT_XOP (q, einsn->name,
627 INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
628 arc_target, arg_32bit_limmlimm, lflags_ccf);
629 }
630 else if (einsn->flags & ARC_SYNTAX_3OP
631 && !(einsn->modsyn & ARC_OP1_MUST_BE_IMM))
632 {
633 /* Regular 3OP instruction. */
634 INSERT_XOP (q, einsn->name,
635 INSN3OP_ABC (einsn->major, einsn->minor), MINSN3OP_ABC,
636 arc_target, arg_32bit_rarbrc, lflags_f);
637
638 INSERT_XOP (q, einsn->name,
639 INSN3OP_0BC (einsn->major, einsn->minor), MINSN3OP_0BC,
640 arc_target, arg_32bit_zarbrc, lflags_f);
641
642 INSERT_XOP (q, einsn->name,
643 INSN3OP_CBBC (einsn->major, einsn->minor), MINSN3OP_CBBC,
644 arc_target, arg_32bit_rbrbrc, lflags_ccf);
645
646 INSERT_XOP (q, einsn->name,
647 INSN3OP_ABU (einsn->major, einsn->minor), MINSN3OP_ABU,
648 arc_target, arg_32bit_rarbu6, lflags_f);
649
650 INSERT_XOP (q, einsn->name,
651 INSN3OP_0BU (einsn->major, einsn->minor), MINSN3OP_0BU,
652 arc_target, arg_32bit_zarbu6, lflags_f);
653
654 INSERT_XOP (q, einsn->name,
655 INSN3OP_CBBU (einsn->major, einsn->minor), MINSN3OP_CBBU,
656 arc_target, arg_32bit_rbrbu6, lflags_ccf);
657
658 INSERT_XOP (q, einsn->name,
659 INSN3OP_BBS (einsn->major, einsn->minor), MINSN3OP_BBS,
660 arc_target, arg_32bit_rbrbs12, lflags_f);
661
662 INSERT_XOP (q, einsn->name,
663 INSN3OP_ALC (einsn->major, einsn->minor), MINSN3OP_ALC,
664 arc_target, arg_32bit_ralimmrc, lflags_f);
665
666 INSERT_XOP (q, einsn->name,
667 INSN3OP_ABL (einsn->major, einsn->minor), MINSN3OP_ABL,
668 arc_target, arg_32bit_rarblimm, lflags_f);
669
670 INSERT_XOP (q, einsn->name,
671 INSN3OP_0LC (einsn->major, einsn->minor), MINSN3OP_0LC,
672 arc_target, arg_32bit_zalimmrc, lflags_f);
673
674 INSERT_XOP (q, einsn->name,
675 INSN3OP_0BL (einsn->major, einsn->minor), MINSN3OP_0BL,
676 arc_target, arg_32bit_zarblimm, lflags_f);
677
678 INSERT_XOP (q, einsn->name,
679 INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
680 arc_target, arg_32bit_zalimmrc, lflags_ccf);
681
682 INSERT_XOP (q, einsn->name,
683 INSN3OP_CBBL (einsn->major, einsn->minor), MINSN3OP_CBBL,
684 arc_target, arg_32bit_rbrblimm, lflags_ccf);
685
686 INSERT_XOP (q, einsn->name,
687 INSN3OP_ALU (einsn->major, einsn->minor), MINSN3OP_ALU,
688 arc_target, arg_32bit_ralimmu6, lflags_f);
689
690 INSERT_XOP (q, einsn->name,
691 INSN3OP_0LU (einsn->major, einsn->minor), MINSN3OP_0LU,
692 arc_target, arg_32bit_zalimmu6, lflags_f);
693
694 INSERT_XOP (q, einsn->name,
695 INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
696 arc_target, arg_32bit_zalimmu6, lflags_ccf);
697
698 INSERT_XOP (q, einsn->name,
699 INSN3OP_0LS (einsn->major, einsn->minor), MINSN3OP_0LS,
700 arc_target, arg_32bit_zalimms12, lflags_f);
701
702 INSERT_XOP (q, einsn->name,
703 INSN3OP_ALL (einsn->major, einsn->minor), MINSN3OP_ALL,
704 arc_target, arg_32bit_ralimmlimm, lflags_f);
705
706 INSERT_XOP (q, einsn->name,
707 INSN3OP_0LL (einsn->major, einsn->minor), MINSN3OP_0LL,
708 arc_target, arg_32bit_zalimmlimm, lflags_f);
709
710 INSERT_XOP (q, einsn->name,
711 INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
712 arc_target, arg_32bit_zalimmlimm, lflags_ccf);
713 }
714 else if (einsn->flags & ARC_SYNTAX_3OP)
715 {
716 /* 3OP instruction which accepts only zero as first
717 argument. */
718 INSERT_XOP (q, einsn->name,
719 INSN3OP_0BC (einsn->major, einsn->minor), MINSN3OP_0BC,
720 arc_target, arg_32bit_zarbrc, lflags_f);
721
722 INSERT_XOP (q, einsn->name,
723 INSN3OP_0BU (einsn->major, einsn->minor), MINSN3OP_0BU,
724 arc_target, arg_32bit_zarbu6, lflags_f);
725
726 INSERT_XOP (q, einsn->name,
727 INSN3OP_0LC (einsn->major, einsn->minor), MINSN3OP_0LC,
728 arc_target, arg_32bit_zalimmrc, lflags_f);
729
730 INSERT_XOP (q, einsn->name,
731 INSN3OP_0BL (einsn->major, einsn->minor), MINSN3OP_0BL,
732 arc_target, arg_32bit_zarblimm, lflags_f);
733
734 INSERT_XOP (q, einsn->name,
735 INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
736 arc_target, arg_32bit_zalimmrc, lflags_ccf);
737
738 INSERT_XOP (q, einsn->name,
739 INSN3OP_0LU (einsn->major, einsn->minor), MINSN3OP_0LU,
740 arc_target, arg_32bit_zalimmu6, lflags_f);
741
742 INSERT_XOP (q, einsn->name,
743 INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
744 arc_target, arg_32bit_zalimmu6, lflags_ccf);
745
746 INSERT_XOP (q, einsn->name,
747 INSN3OP_0LS (einsn->major, einsn->minor), MINSN3OP_0LS,
748 arc_target, arg_32bit_zalimms12, lflags_f);
749
750 INSERT_XOP (q, einsn->name,
751 INSN3OP_0LL (einsn->major, einsn->minor), MINSN3OP_0LL,
752 arc_target, arg_32bit_zalimmlimm, lflags_f);
753
754 INSERT_XOP (q, einsn->name,
755 INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
756 arc_target, arg_32bit_zalimmlimm, lflags_ccf);
757 }
758 else
759 {
760 *errmsg = "Unknown syntax";
761 return NULL;
762 }
763
764 /* End marker. */
765 memset (q, 0, sizeof (*arc_ext_opcodes));
766
767 return arc_ext_opcodes;
768}
This page took 0.707106 seconds and 4 git commands to generate.