45734a083299e229b399d37f697cc88e01b94a39
[deliverable/binutils-gdb.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_CONDITION_CODE)
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_CONDITION_CODE)
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 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 }
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)
496 printf ("CORE: %s %d %s\n", reg.name, reg.number,
497 ExtReadWrite_image (reg.rw));
498 }
499
500 for (i = 0; i < NUM_EXT_COND; i++)
501 if (arc_extension_map.condCodes[i])
502 printf ("COND: %s\n", arc_extension_map.condCodes[i]);
503 }
504
505 /* For a given extension instruction generate the equivalent arc
506 opcode structure. */
507
508 struct arc_opcode *
509 arcExtMap_genOpcode (const extInstruction_t *einsn,
510 unsigned arc_target,
511 const char **errmsg)
512 {
513 struct arc_opcode *q, *arc_ext_opcodes = NULL;
514 const unsigned char *lflags_f;
515 const unsigned char *lflags_ccf;
516 int count;
517
518 /* Check for the class to see how many instructions we generate. */
519 switch (einsn->flags & (ARC_SYNTAX_3OP | ARC_SYNTAX_2OP))
520 {
521 case ARC_SYNTAX_3OP:
522 count = (einsn->modsyn & ARC_OP1_MUST_BE_IMM) ? 10 : 20;
523 break;
524 case ARC_SYNTAX_2OP:
525 count = (einsn->flags & 0x10) ? 7 : 6;
526 break;
527 default:
528 count = 0;
529 break;
530 }
531
532 /* Allocate memory. */
533 arc_ext_opcodes = (struct arc_opcode *)
534 xmalloc ((count + 1) * sizeof (*arc_ext_opcodes));
535
536 if (arc_ext_opcodes == NULL)
537 {
538 *errmsg = "Virtual memory exhausted";
539 return NULL;
540 }
541
542 /* Generate the patterns. */
543 q = arc_ext_opcodes;
544
545 if (einsn->suffix)
546 {
547 lflags_f = flags_none;
548 lflags_ccf = flags_none;
549 }
550 else
551 {
552 lflags_f = flags_f;
553 lflags_ccf = flags_ccf;
554 }
555
556 if (einsn->suffix & ARC_SUFFIX_COND)
557 lflags_ccf = flags_cc;
558 if (einsn->suffix & ARC_SUFFIX_FLAG)
559 {
560 lflags_f = flags_f;
561 lflags_ccf = flags_f;
562 }
563 if (einsn->suffix & (ARC_SUFFIX_FLAG | ARC_SUFFIX_COND))
564 lflags_ccf = flags_ccf;
565
566 if (einsn->flags & ARC_SYNTAX_2OP
567 && !(einsn->flags & 0x10))
568 {
569 /* Regular 2OP instruction. */
570 if (einsn->suffix & ARC_SUFFIX_COND)
571 *errmsg = "Suffix SUFFIX_COND ignored";
572
573 INSERT_XOP (q, einsn->name,
574 INSN2OP_BC (einsn->major, einsn->minor), MINSN2OP_BC,
575 arc_target, arg_32bit_rbrc, lflags_f);
576
577 INSERT_XOP (q, einsn->name,
578 INSN2OP_0C (einsn->major, einsn->minor), MINSN2OP_0C,
579 arc_target, arg_32bit_zarc, lflags_f);
580
581 INSERT_XOP (q, einsn->name,
582 INSN2OP_BU (einsn->major, einsn->minor), MINSN2OP_BU,
583 arc_target, arg_32bit_rbu6, lflags_f);
584
585 INSERT_XOP (q, einsn->name,
586 INSN2OP_0U (einsn->major, einsn->minor), MINSN2OP_0U,
587 arc_target, arg_32bit_zau6, lflags_f);
588
589 INSERT_XOP (q, einsn->name,
590 INSN2OP_BL (einsn->major, einsn->minor), MINSN2OP_BL,
591 arc_target, arg_32bit_rblimm, lflags_f);
592
593 INSERT_XOP (q, einsn->name,
594 INSN2OP_0L (einsn->major, einsn->minor), MINSN2OP_0L,
595 arc_target, arg_32bit_zalimm, lflags_f);
596 }
597 else if (einsn->flags & (0x10 | ARC_SYNTAX_2OP))
598 {
599 /* This is actually a 3OP pattern. The first operand is
600 immplied and is set to zero. */
601 INSERT_XOP (q, einsn->name,
602 INSN3OP_0BC (einsn->major, einsn->minor), MINSN3OP_0BC,
603 arc_target, arg_32bit_rbrc, lflags_f);
604
605 INSERT_XOP (q, einsn->name,
606 INSN3OP_0BU (einsn->major, einsn->minor), MINSN3OP_0BU,
607 arc_target, arg_32bit_rbu6, lflags_f);
608
609 INSERT_XOP (q, einsn->name,
610 INSN3OP_0BL (einsn->major, einsn->minor), MINSN3OP_0BL,
611 arc_target, arg_32bit_rblimm, lflags_f);
612
613 INSERT_XOP (q, einsn->name,
614 INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
615 arc_target, arg_32bit_limmrc, lflags_ccf);
616
617 INSERT_XOP (q, einsn->name,
618 INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
619 arc_target, arg_32bit_limmu6, lflags_ccf);
620
621 INSERT_XOP (q, einsn->name,
622 INSN3OP_0LS (einsn->major, einsn->minor), MINSN3OP_0LS,
623 arc_target, arg_32bit_limms12, lflags_f);
624
625 INSERT_XOP (q, einsn->name,
626 INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
627 arc_target, arg_32bit_limmlimm, lflags_ccf);
628 }
629 else if (einsn->flags & ARC_SYNTAX_3OP
630 && !(einsn->modsyn & ARC_OP1_MUST_BE_IMM))
631 {
632 /* Regular 3OP instruction. */
633 INSERT_XOP (q, einsn->name,
634 INSN3OP_ABC (einsn->major, einsn->minor), MINSN3OP_ABC,
635 arc_target, arg_32bit_rarbrc, lflags_f);
636
637 INSERT_XOP (q, einsn->name,
638 INSN3OP_0BC (einsn->major, einsn->minor), MINSN3OP_0BC,
639 arc_target, arg_32bit_zarbrc, lflags_f);
640
641 INSERT_XOP (q, einsn->name,
642 INSN3OP_CBBC (einsn->major, einsn->minor), MINSN3OP_CBBC,
643 arc_target, arg_32bit_rbrbrc, lflags_ccf);
644
645 INSERT_XOP (q, einsn->name,
646 INSN3OP_ABU (einsn->major, einsn->minor), MINSN3OP_ABU,
647 arc_target, arg_32bit_rarbu6, lflags_f);
648
649 INSERT_XOP (q, einsn->name,
650 INSN3OP_0BU (einsn->major, einsn->minor), MINSN3OP_0BU,
651 arc_target, arg_32bit_zarbu6, lflags_f);
652
653 INSERT_XOP (q, einsn->name,
654 INSN3OP_CBBU (einsn->major, einsn->minor), MINSN3OP_CBBU,
655 arc_target, arg_32bit_rbrbu6, lflags_ccf);
656
657 INSERT_XOP (q, einsn->name,
658 INSN3OP_BBS (einsn->major, einsn->minor), MINSN3OP_BBS,
659 arc_target, arg_32bit_rbrbs12, lflags_f);
660
661 INSERT_XOP (q, einsn->name,
662 INSN3OP_ALC (einsn->major, einsn->minor), MINSN3OP_ALC,
663 arc_target, arg_32bit_ralimmrc, lflags_f);
664
665 INSERT_XOP (q, einsn->name,
666 INSN3OP_ABL (einsn->major, einsn->minor), MINSN3OP_ABL,
667 arc_target, arg_32bit_rarblimm, lflags_f);
668
669 INSERT_XOP (q, einsn->name,
670 INSN3OP_0LC (einsn->major, einsn->minor), MINSN3OP_0LC,
671 arc_target, arg_32bit_zalimmrc, lflags_f);
672
673 INSERT_XOP (q, einsn->name,
674 INSN3OP_0BL (einsn->major, einsn->minor), MINSN3OP_0BL,
675 arc_target, arg_32bit_zarblimm, lflags_f);
676
677 INSERT_XOP (q, einsn->name,
678 INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
679 arc_target, arg_32bit_zalimmrc, lflags_ccf);
680
681 INSERT_XOP (q, einsn->name,
682 INSN3OP_CBBL (einsn->major, einsn->minor), MINSN3OP_CBBL,
683 arc_target, arg_32bit_rbrblimm, lflags_ccf);
684
685 INSERT_XOP (q, einsn->name,
686 INSN3OP_ALU (einsn->major, einsn->minor), MINSN3OP_ALU,
687 arc_target, arg_32bit_ralimmu6, lflags_f);
688
689 INSERT_XOP (q, einsn->name,
690 INSN3OP_0LU (einsn->major, einsn->minor), MINSN3OP_0LU,
691 arc_target, arg_32bit_zalimmu6, lflags_f);
692
693 INSERT_XOP (q, einsn->name,
694 INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
695 arc_target, arg_32bit_zalimmu6, lflags_ccf);
696
697 INSERT_XOP (q, einsn->name,
698 INSN3OP_0LS (einsn->major, einsn->minor), MINSN3OP_0LS,
699 arc_target, arg_32bit_zalimms12, lflags_f);
700
701 INSERT_XOP (q, einsn->name,
702 INSN3OP_ALL (einsn->major, einsn->minor), MINSN3OP_ALL,
703 arc_target, arg_32bit_ralimmlimm, lflags_f);
704
705 INSERT_XOP (q, einsn->name,
706 INSN3OP_0LL (einsn->major, einsn->minor), MINSN3OP_0LL,
707 arc_target, arg_32bit_zalimmlimm, lflags_f);
708
709 INSERT_XOP (q, einsn->name,
710 INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
711 arc_target, arg_32bit_zalimmlimm, lflags_ccf);
712 }
713 else if (einsn->flags & ARC_SYNTAX_3OP)
714 {
715 /* 3OP instruction which accepts only zero as first
716 argument. */
717 INSERT_XOP (q, einsn->name,
718 INSN3OP_0BC (einsn->major, einsn->minor), MINSN3OP_0BC,
719 arc_target, arg_32bit_zarbrc, lflags_f);
720
721 INSERT_XOP (q, einsn->name,
722 INSN3OP_0BU (einsn->major, einsn->minor), MINSN3OP_0BU,
723 arc_target, arg_32bit_zarbu6, lflags_f);
724
725 INSERT_XOP (q, einsn->name,
726 INSN3OP_0LC (einsn->major, einsn->minor), MINSN3OP_0LC,
727 arc_target, arg_32bit_zalimmrc, lflags_f);
728
729 INSERT_XOP (q, einsn->name,
730 INSN3OP_0BL (einsn->major, einsn->minor), MINSN3OP_0BL,
731 arc_target, arg_32bit_zarblimm, lflags_f);
732
733 INSERT_XOP (q, einsn->name,
734 INSN3OP_C0LC (einsn->major, einsn->minor), MINSN3OP_C0LC,
735 arc_target, arg_32bit_zalimmrc, lflags_ccf);
736
737 INSERT_XOP (q, einsn->name,
738 INSN3OP_0LU (einsn->major, einsn->minor), MINSN3OP_0LU,
739 arc_target, arg_32bit_zalimmu6, lflags_f);
740
741 INSERT_XOP (q, einsn->name,
742 INSN3OP_C0LU (einsn->major, einsn->minor), MINSN3OP_C0LU,
743 arc_target, arg_32bit_zalimmu6, lflags_ccf);
744
745 INSERT_XOP (q, einsn->name,
746 INSN3OP_0LS (einsn->major, einsn->minor), MINSN3OP_0LS,
747 arc_target, arg_32bit_zalimms12, lflags_f);
748
749 INSERT_XOP (q, einsn->name,
750 INSN3OP_0LL (einsn->major, einsn->minor), MINSN3OP_0LL,
751 arc_target, arg_32bit_zalimmlimm, lflags_f);
752
753 INSERT_XOP (q, einsn->name,
754 INSN3OP_C0LL (einsn->major, einsn->minor), MINSN3OP_C0LL,
755 arc_target, arg_32bit_zalimmlimm, lflags_ccf);
756 }
757 else
758 {
759 *errmsg = "Unknown syntax";
760 return NULL;
761 }
762
763 /* End marker. */
764 memset (q, 0, sizeof (*arc_ext_opcodes));
765
766 return arc_ext_opcodes;
767 }
This page took 0.047977 seconds and 3 git commands to generate.