gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / opcodes / arc-ext.c
CommitLineData
886a2506 1/* ARC target-dependent stuff. Extension structure access functions
b3adc24a 2 Copyright (C) 1995-2020 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{
2480b6fa 56 unsigned address;
db18dbab
GM
57 char * name;
58 struct ExtAuxRegister * next;
886a2506 59};
0d2bcfaf 60
886a2506
NC
61struct ExtCoreRegister
62{
63 short number;
64 enum ExtReadWrite rw;
db18dbab 65 char * name;
886a2506 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];
db18dbab 73 char * condCodes[NUM_EXT_COND];
886a2506 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);
2b804145 173 break;
0d2bcfaf 174 }
5bd67f35
AJ
175
176 case EXT_COND_CODE:
0d2bcfaf 177 {
886a2506
NC
178 char *cc_name = xstrdup ((char *) (p + 3));
179
180 arc_extension_map.
181 condCodes[p[2] - FIRST_EXTENSION_CONDITION_CODE]
182 = cc_name;
183 break;
5bd67f35 184 }
5bd67f35
AJ
185
186 case EXT_AUX_REGISTER:
0d2bcfaf 187 {
886a2506
NC
188 /* Trickier -- need to store linked list of these. */
189 struct ExtAuxRegister *newAuxRegister
190 = XNEW (struct ExtAuxRegister);
191 char *aux_name = xstrdup ((char *) (p + 6));
0d2bcfaf 192
0d2bcfaf 193 newAuxRegister->name = aux_name;
2480b6fa
AM
194 newAuxRegister->address = (((unsigned) p[2] << 24) | (p[3] << 16)
195 | (p[4] << 8) | p[5]);
0d2bcfaf
NC
196 newAuxRegister->next = arc_extension_map.auxRegisters;
197 arc_extension_map.auxRegisters = newAuxRegister;
886a2506 198 break;
0d2bcfaf 199 }
5bd67f35 200
0d2bcfaf 201 default:
886a2506
NC
202 break;
203 }
204
205 p += p[0]; /* Move on to next record. */
206 }
207}
208
209
210/* Free memory that has been allocated for the extensions. */
211
212static void
213destroy_map (void)
214{
215 struct ExtAuxRegister *r;
216 unsigned int i;
217
218 /* Free auxiliary registers. */
219 r = arc_extension_map.auxRegisters;
220 while (r)
221 {
222 /* N.B. after r has been freed, r->next is invalid! */
223 struct ExtAuxRegister* next = r->next;
224
225 free (r->name);
226 free (r);
227 r = next;
228 }
229
230 /* Free instructions. */
231 for (i = 0; i < INST_HASH_SIZE; i++)
232 {
233 struct ExtInstruction *insn = arc_extension_map.instructions[i];
234
235 while (insn)
236 {
237 /* N.B. after insn has been freed, insn->next is invalid! */
238 struct ExtInstruction *next = insn->next;
239
240 free (insn->name);
241 free (insn);
242 insn = next;
243 }
244 }
245
246 /* Free core registers. */
247 for (i = 0; i < NUM_EXT_CORE; i++)
d96bf37b 248 free (arc_extension_map.coreRegisters[i].name);
5bd67f35 249
886a2506
NC
250 /* Free condition codes. */
251 for (i = 0; i < NUM_EXT_COND; i++)
d96bf37b 252 free (arc_extension_map.condCodes[i]);
886a2506
NC
253
254 memset (&arc_extension_map, 0, sizeof (arc_extension_map));
255}
256
257
258static const char *
259ExtReadWrite_image (enum ExtReadWrite val)
260{
261 switch (val)
262 {
263 case REG_INVALID : return "INVALID";
264 case REG_READ : return "RO";
265 case REG_WRITE : return "WO";
266 case REG_READWRITE: return "R/W";
267 default : return "???";
268 }
269}
270
271
272/* Externally visible functions. */
273
274/* Get the name of an extension instruction. */
275
b99747ae 276const extInstruction_t *
bdfe53e3 277arcExtMap_insn (int opcode, unsigned long long insn)
886a2506
NC
278{
279 /* Here the following tasks need to be done. First of all, the
280 opcode stored in the Extension Map is the real opcode. However,
281 the subopcode stored in the instruction to be disassembled is
282 mangled. We pass (in minor opcode), the instruction word. Here
283 we will un-mangle it and get the real subopcode which we can look
284 for in the Extension Map. This function is used both for the
285 ARCTangent and the ARCompact, so we would also need some sort of
286 a way to distinguish between the two architectures. This is
287 because the ARCTangent does not do any of this mangling so we
288 have no issues there. */
289
290 /* If P[22:23] is 0 or 2 then un-mangle using iiiiiI. If it is 1
291 then use iiiiIi. Now, if P is 3 then check M[5:5] and if it is 0
292 then un-mangle using iiiiiI else iiiiii. */
293
294 unsigned char minor;
b99747ae 295 extInstruction_t *temp;
886a2506
NC
296
297 /* 16-bit instructions. */
298 if (0x08 <= opcode && opcode <= 0x0b)
299 {
300 unsigned char b, c, i;
301
302 b = (insn & 0x0700) >> 8;
303 c = (insn & 0x00e0) >> 5;
304 i = (insn & 0x001f);
305
306 if (i)
307 minor = i;
308 else
309 minor = (c == 0x07) ? b : c;
310 }
311 /* 32-bit instructions. */
312 else
313 {
314 unsigned char I, A, B;
315
316 I = (insn & 0x003f0000) >> 16;
317 A = (insn & 0x0000003f);
318 B = ((insn & 0x07000000) >> 24) | ((insn & 0x00007000) >> 9);
319
320 if (I != 0x2f)
321 {
322#ifndef UNMANGLED
323 switch (P)
324 {
325 case 3:
326 if (M)
327 {
328 minor = I;
329 break;
330 }
331 case 0:
332 case 2:
333 minor = (I >> 1) | ((I & 0x1) << 5);
334 break;
335 case 1:
336 minor = (I >> 1) | (I & 0x1) | ((I & 0x2) << 4);
337 }
338#else
339 minor = I;
340#endif
341 }
342 else
343 {
344 if (A != 0x3f)
345 minor = A;
346 else
347 minor = B;
348 }
349 }
350
351 temp = arc_extension_map.instructions[INST_HASH (opcode, minor)];
352 while (temp)
353 {
354 if ((temp->major == opcode) && (temp->minor == minor))
355 {
b99747ae 356 return temp;
0d2bcfaf 357 }
886a2506 358 temp = temp->next;
0d2bcfaf 359 }
5bd67f35 360
886a2506 361 return NULL;
0d2bcfaf
NC
362}
363
886a2506 364/* Get the name of an extension core register. */
0d2bcfaf 365
886a2506
NC
366const char *
367arcExtMap_coreRegName (int regnum)
368{
369 if (regnum < FIRST_EXTENSION_CORE_REGISTER
f36e33da 370 || regnum > LAST_EXTENSION_CORE_REGISTER)
886a2506
NC
371 return NULL;
372 return arc_extension_map.
373 coreRegisters[regnum - FIRST_EXTENSION_CORE_REGISTER].name;
374}
375
376/* Get the access mode of an extension core register. */
377
378enum ExtReadWrite
379arcExtMap_coreReadWrite (int regnum)
0d2bcfaf 380{
886a2506 381 if (regnum < FIRST_EXTENSION_CORE_REGISTER
f36e33da 382 || regnum > LAST_EXTENSION_CORE_REGISTER)
886a2506
NC
383 return REG_INVALID;
384 return arc_extension_map.
385 coreRegisters[regnum - FIRST_EXTENSION_CORE_REGISTER].rw;
386}
387
388/* Get the name of an extension condition code. */
389
390const char *
391arcExtMap_condCodeName (int code)
392{
393 if (code < FIRST_EXTENSION_CONDITION_CODE
394 || code > LAST_EXTENSION_CONDITION_CODE)
395 return NULL;
396 return arc_extension_map.
397 condCodes[code - FIRST_EXTENSION_CONDITION_CODE];
398}
399
400/* Get the name of an extension auxiliary register. */
401
402const char *
2480b6fa 403arcExtMap_auxRegName (unsigned address)
886a2506
NC
404{
405 /* Walk the list of auxiliary register names and find the name. */
406 struct ExtAuxRegister *r;
407
408 for (r = arc_extension_map.auxRegisters; r; r = r->next)
409 {
410 if (r->address == address)
411 return (const char *)r->name;
412 }
413 return NULL;
414}
415
416/* Load extensions described in .arcextmap and
417 .gnu.linkonce.arcextmap.* ELF section. */
0d2bcfaf 418
886a2506
NC
419void
420build_ARC_extmap (bfd *text_bfd)
421{
422 asection *sect;
423
424 /* The map is built each time gdb loads an executable file - so free
425 any existing map, as the map defined by the new file may differ
426 from the old. */
427 destroy_map ();
428
429 for (sect = text_bfd->sections; sect != NULL; sect = sect->next)
430 if (!strncmp (sect->name,
431 ".gnu.linkonce.arcextmap.",
432 sizeof (".gnu.linkonce.arcextmap.") - 1)
433 || !strcmp (sect->name,".arcextmap"))
0d2bcfaf 434 {
fd361982 435 bfd_size_type count = bfd_section_size (sect);
886a2506
NC
436 unsigned char* buffer = xmalloc (count);
437
438 if (buffer)
439 {
440 if (bfd_get_section_contents (text_bfd, sect, buffer, 0, count))
441 create_map (buffer, count);
442 free (buffer);
443 }
0d2bcfaf
NC
444 }
445}
886a2506 446
b99747ae
CZ
447/* Debug function used to dump the ARC information fount in arcextmap
448 sections. */
886a2506
NC
449
450void
451dump_ARC_extmap (void)
452{
453 struct ExtAuxRegister *r;
454 int i;
455
456 r = arc_extension_map.auxRegisters;
457
458 while (r)
459 {
2480b6fa 460 printf ("AUX : %s %u\n", r->name, r->address);
886a2506
NC
461 r = r->next;
462 }
463
464 for (i = 0; i < INST_HASH_SIZE; i++)
465 {
466 struct ExtInstruction *insn;
467
468 for (insn = arc_extension_map.instructions[i];
469 insn != NULL; insn = insn->next)
b99747ae
CZ
470 {
471 printf ("INST: 0x%02x 0x%02x ", insn->major, insn->minor);
945e0f82
CZ
472 switch (insn->flags & ARC_SYNTAX_MASK)
473 {
474 case ARC_SYNTAX_2OP:
475 printf ("SYNTAX_2OP");
476 break;
477 case ARC_SYNTAX_3OP:
478 printf ("SYNTAX_3OP");
479 break;
480 case ARC_SYNTAX_1OP:
481 printf ("SYNTAX_1OP");
482 break;
483 case ARC_SYNTAX_NOP:
484 printf ("SYNTAX_NOP");
485 break;
486 default:
487 printf ("SYNTAX_UNK");
488 break;
489 }
b99747ae
CZ
490
491 if (insn->flags & 0x10)
492 printf ("|MODIFIER");
493
494 printf (" %s\n", insn->name);
495 }
886a2506
NC
496 }
497
498 for (i = 0; i < NUM_EXT_CORE; i++)
499 {
500 struct ExtCoreRegister reg = arc_extension_map.coreRegisters[i];
501
502 if (reg.name)
f36e33da
CZ
503 printf ("CORE: 0x%04x %s %s\n", reg.number,
504 ExtReadWrite_image (reg.rw),
505 reg.name);
886a2506
NC
506 }
507
508 for (i = 0; i < NUM_EXT_COND; i++)
509 if (arc_extension_map.condCodes[i])
510 printf ("COND: %s\n", arc_extension_map.condCodes[i]);
511}
b99747ae
CZ
512
513/* For a given extension instruction generate the equivalent arc
514 opcode structure. */
515
516struct arc_opcode *
517arcExtMap_genOpcode (const extInstruction_t *einsn,
518 unsigned arc_target,
519 const char **errmsg)
520{
521 struct arc_opcode *q, *arc_ext_opcodes = NULL;
522 const unsigned char *lflags_f;
523 const unsigned char *lflags_ccf;
524 int count;
525
526 /* Check for the class to see how many instructions we generate. */
945e0f82 527 switch (einsn->flags & ARC_SYNTAX_MASK)
b99747ae
CZ
528 {
529 case ARC_SYNTAX_3OP:
530 count = (einsn->modsyn & ARC_OP1_MUST_BE_IMM) ? 10 : 20;
531 break;
532 case ARC_SYNTAX_2OP:
533 count = (einsn->flags & 0x10) ? 7 : 6;
534 break;
945e0f82
CZ
535 case ARC_SYNTAX_1OP:
536 count = 3;
537 break;
538 case ARC_SYNTAX_NOP:
539 count = 1;
540 break;
b99747ae
CZ
541 default:
542 count = 0;
543 break;
544 }
545
546 /* Allocate memory. */
547 arc_ext_opcodes = (struct arc_opcode *)
548 xmalloc ((count + 1) * sizeof (*arc_ext_opcodes));
549
550 if (arc_ext_opcodes == NULL)
551 {
552 *errmsg = "Virtual memory exhausted";
553 return NULL;
554 }
555
556 /* Generate the patterns. */
557 q = arc_ext_opcodes;
558
559 if (einsn->suffix)
560 {
561 lflags_f = flags_none;
562 lflags_ccf = flags_none;
563 }
564 else
565 {
566 lflags_f = flags_f;
567 lflags_ccf = flags_ccf;
568 }
569
570 if (einsn->suffix & ARC_SUFFIX_COND)
571 lflags_ccf = flags_cc;
572 if (einsn->suffix & ARC_SUFFIX_FLAG)
573 {
574 lflags_f = flags_f;
575 lflags_ccf = flags_f;
576 }
577 if (einsn->suffix & (ARC_SUFFIX_FLAG | ARC_SUFFIX_COND))
578 lflags_ccf = flags_ccf;
579
580 if (einsn->flags & ARC_SYNTAX_2OP
581 && !(einsn->flags & 0x10))
582 {
583 /* Regular 2OP instruction. */
584 if (einsn->suffix & ARC_SUFFIX_COND)
585 *errmsg = "Suffix SUFFIX_COND ignored";
586
587 INSERT_XOP (q, einsn->name,
588 INSN2OP_BC (einsn->major, einsn->minor), MINSN2OP_BC,
589 arc_target, arg_32bit_rbrc, lflags_f);
590
591 INSERT_XOP (q, einsn->name,
592 INSN2OP_0C (einsn->major, einsn->minor), MINSN2OP_0C,
593 arc_target, arg_32bit_zarc, lflags_f);
594
595 INSERT_XOP (q, einsn->name,
596 INSN2OP_BU (einsn->major, einsn->minor), MINSN2OP_BU,
597 arc_target, arg_32bit_rbu6, lflags_f);
598
599 INSERT_XOP (q, einsn->name,
600 INSN2OP_0U (einsn->major, einsn->minor), MINSN2OP_0U,
601 arc_target, arg_32bit_zau6, lflags_f);
602
603 INSERT_XOP (q, einsn->name,
604 INSN2OP_BL (einsn->major, einsn->minor), MINSN2OP_BL,
605 arc_target, arg_32bit_rblimm, lflags_f);
606
607 INSERT_XOP (q, einsn->name,
608 INSN2OP_0L (einsn->major, einsn->minor), MINSN2OP_0L,
609 arc_target, arg_32bit_zalimm, lflags_f);
610 }
611 else if (einsn->flags & (0x10 | ARC_SYNTAX_2OP))
612 {
613 /* This is actually a 3OP pattern. The first operand is
614 immplied and is set to zero. */
615 INSERT_XOP (q, einsn->name,
616 INSN3OP_0BC (einsn->major, einsn->minor), MINSN3OP_0BC,
617 arc_target, arg_32bit_rbrc, lflags_f);
618
619 INSERT_XOP (q, einsn->name,
620 INSN3OP_0BU (einsn->major, einsn->minor), MINSN3OP_0BU,
621 arc_target, arg_32bit_rbu6, lflags_f);
622
623 INSERT_XOP (q, einsn->name,
624 INSN3OP_0BL (einsn->major, einsn->minor), MINSN3OP_0BL,
625 arc_target, arg_32bit_rblimm, lflags_f);
626
627 INSERT_XOP (q, einsn->name,
628 INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
629 arc_target, arg_32bit_limmrc, lflags_ccf);
630
631 INSERT_XOP (q, einsn->name,
632 INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
633 arc_target, arg_32bit_limmu6, lflags_ccf);
634
635 INSERT_XOP (q, einsn->name,
636 INSN3OP_0LS (einsn->major, einsn->minor), MINSN3OP_0LS,
637 arc_target, arg_32bit_limms12, lflags_f);
638
639 INSERT_XOP (q, einsn->name,
640 INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
641 arc_target, arg_32bit_limmlimm, lflags_ccf);
642 }
643 else if (einsn->flags & ARC_SYNTAX_3OP
644 && !(einsn->modsyn & ARC_OP1_MUST_BE_IMM))
645 {
646 /* Regular 3OP instruction. */
647 INSERT_XOP (q, einsn->name,
648 INSN3OP_ABC (einsn->major, einsn->minor), MINSN3OP_ABC,
649 arc_target, arg_32bit_rarbrc, lflags_f);
650
651 INSERT_XOP (q, einsn->name,
652 INSN3OP_0BC (einsn->major, einsn->minor), MINSN3OP_0BC,
653 arc_target, arg_32bit_zarbrc, lflags_f);
654
655 INSERT_XOP (q, einsn->name,
656 INSN3OP_CBBC (einsn->major, einsn->minor), MINSN3OP_CBBC,
657 arc_target, arg_32bit_rbrbrc, lflags_ccf);
658
659 INSERT_XOP (q, einsn->name,
660 INSN3OP_ABU (einsn->major, einsn->minor), MINSN3OP_ABU,
661 arc_target, arg_32bit_rarbu6, lflags_f);
662
663 INSERT_XOP (q, einsn->name,
664 INSN3OP_0BU (einsn->major, einsn->minor), MINSN3OP_0BU,
665 arc_target, arg_32bit_zarbu6, lflags_f);
666
667 INSERT_XOP (q, einsn->name,
668 INSN3OP_CBBU (einsn->major, einsn->minor), MINSN3OP_CBBU,
669 arc_target, arg_32bit_rbrbu6, lflags_ccf);
670
671 INSERT_XOP (q, einsn->name,
672 INSN3OP_BBS (einsn->major, einsn->minor), MINSN3OP_BBS,
673 arc_target, arg_32bit_rbrbs12, lflags_f);
674
675 INSERT_XOP (q, einsn->name,
676 INSN3OP_ALC (einsn->major, einsn->minor), MINSN3OP_ALC,
677 arc_target, arg_32bit_ralimmrc, lflags_f);
678
679 INSERT_XOP (q, einsn->name,
680 INSN3OP_ABL (einsn->major, einsn->minor), MINSN3OP_ABL,
681 arc_target, arg_32bit_rarblimm, lflags_f);
682
683 INSERT_XOP (q, einsn->name,
684 INSN3OP_0LC (einsn->major, einsn->minor), MINSN3OP_0LC,
685 arc_target, arg_32bit_zalimmrc, lflags_f);
686
687 INSERT_XOP (q, einsn->name,
688 INSN3OP_0BL (einsn->major, einsn->minor), MINSN3OP_0BL,
689 arc_target, arg_32bit_zarblimm, lflags_f);
690
691 INSERT_XOP (q, einsn->name,
692 INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
693 arc_target, arg_32bit_zalimmrc, lflags_ccf);
694
695 INSERT_XOP (q, einsn->name,
696 INSN3OP_CBBL (einsn->major, einsn->minor), MINSN3OP_CBBL,
697 arc_target, arg_32bit_rbrblimm, lflags_ccf);
698
699 INSERT_XOP (q, einsn->name,
700 INSN3OP_ALU (einsn->major, einsn->minor), MINSN3OP_ALU,
701 arc_target, arg_32bit_ralimmu6, lflags_f);
702
703 INSERT_XOP (q, einsn->name,
704 INSN3OP_0LU (einsn->major, einsn->minor), MINSN3OP_0LU,
705 arc_target, arg_32bit_zalimmu6, lflags_f);
706
707 INSERT_XOP (q, einsn->name,
708 INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
709 arc_target, arg_32bit_zalimmu6, lflags_ccf);
710
711 INSERT_XOP (q, einsn->name,
712 INSN3OP_0LS (einsn->major, einsn->minor), MINSN3OP_0LS,
713 arc_target, arg_32bit_zalimms12, lflags_f);
714
715 INSERT_XOP (q, einsn->name,
716 INSN3OP_ALL (einsn->major, einsn->minor), MINSN3OP_ALL,
717 arc_target, arg_32bit_ralimmlimm, lflags_f);
718
719 INSERT_XOP (q, einsn->name,
720 INSN3OP_0LL (einsn->major, einsn->minor), MINSN3OP_0LL,
721 arc_target, arg_32bit_zalimmlimm, lflags_f);
722
723 INSERT_XOP (q, einsn->name,
724 INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
725 arc_target, arg_32bit_zalimmlimm, lflags_ccf);
726 }
727 else if (einsn->flags & ARC_SYNTAX_3OP)
728 {
729 /* 3OP instruction which accepts only zero as first
730 argument. */
731 INSERT_XOP (q, einsn->name,
732 INSN3OP_0BC (einsn->major, einsn->minor), MINSN3OP_0BC,
733 arc_target, arg_32bit_zarbrc, lflags_f);
734
735 INSERT_XOP (q, einsn->name,
736 INSN3OP_0BU (einsn->major, einsn->minor), MINSN3OP_0BU,
737 arc_target, arg_32bit_zarbu6, lflags_f);
738
739 INSERT_XOP (q, einsn->name,
740 INSN3OP_0LC (einsn->major, einsn->minor), MINSN3OP_0LC,
741 arc_target, arg_32bit_zalimmrc, lflags_f);
742
743 INSERT_XOP (q, einsn->name,
744 INSN3OP_0BL (einsn->major, einsn->minor), MINSN3OP_0BL,
745 arc_target, arg_32bit_zarblimm, lflags_f);
746
747 INSERT_XOP (q, einsn->name,
748 INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
749 arc_target, arg_32bit_zalimmrc, lflags_ccf);
750
751 INSERT_XOP (q, einsn->name,
752 INSN3OP_0LU (einsn->major, einsn->minor), MINSN3OP_0LU,
753 arc_target, arg_32bit_zalimmu6, lflags_f);
754
755 INSERT_XOP (q, einsn->name,
756 INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
757 arc_target, arg_32bit_zalimmu6, lflags_ccf);
758
759 INSERT_XOP (q, einsn->name,
760 INSN3OP_0LS (einsn->major, einsn->minor), MINSN3OP_0LS,
761 arc_target, arg_32bit_zalimms12, lflags_f);
762
763 INSERT_XOP (q, einsn->name,
764 INSN3OP_0LL (einsn->major, einsn->minor), MINSN3OP_0LL,
765 arc_target, arg_32bit_zalimmlimm, lflags_f);
766
767 INSERT_XOP (q, einsn->name,
768 INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
769 arc_target, arg_32bit_zalimmlimm, lflags_ccf);
770 }
945e0f82
CZ
771 else if (einsn->flags & ARC_SYNTAX_1OP)
772 {
773 if (einsn->suffix & ARC_SUFFIX_COND)
774 *errmsg = "Suffix SUFFIX_COND ignored";
775
776 INSERT_XOP (q, einsn->name,
777 INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor),
778 MINSN2OP_0C, arc_target, arg_32bit_rc, lflags_f);
779
780 INSERT_XOP (q, einsn->name,
781 INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor)
782 | (0x01 << 22), MINSN2OP_0U, arc_target, arg_32bit_u6,
783 lflags_f);
784
785 INSERT_XOP (q, einsn->name,
786 INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor)
787 | FIELDC (62), MINSN2OP_0L, arc_target, arg_32bit_limm,
788 lflags_f);
789
790 }
791 else if (einsn->flags & ARC_SYNTAX_NOP)
792 {
793 if (einsn->suffix & ARC_SUFFIX_COND)
794 *errmsg = "Suffix SUFFIX_COND ignored";
795
796 INSERT_XOP (q, einsn->name,
797 INSN2OP (einsn->major, 0x3F) | FIELDB (einsn->minor)
798 | (0x01 << 22), MINSN2OP_0L, arc_target, arg_none, lflags_f);
799 }
b99747ae
CZ
800 else
801 {
802 *errmsg = "Unknown syntax";
803 return NULL;
804 }
805
806 /* End marker. */
807 memset (q, 0, sizeof (*arc_ext_opcodes));
808
809 return arc_ext_opcodes;
810}
This page took 0.930115 seconds and 4 git commands to generate.