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