Arm64: correct 64-bit element fmmla encoding
[deliverable/binutils-gdb.git] / opcodes / arc-ext.c
1 /* ARC target-dependent stuff. Extension structure access functions
2 Copyright (C) 1995-2020 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 unsigned 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 break;
174 }
175
176 case EXT_COND_CODE:
177 {
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;
184 }
185
186 case EXT_AUX_REGISTER:
187 {
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));
192
193 newAuxRegister->name = aux_name;
194 newAuxRegister->address = (((unsigned) p[2] << 24) | (p[3] << 16)
195 | (p[4] << 8) | p[5]);
196 newAuxRegister->next = arc_extension_map.auxRegisters;
197 arc_extension_map.auxRegisters = newAuxRegister;
198 break;
199 }
200
201 default:
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
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 }
252
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
282 const extInstruction_t *
283 arcExtMap_insn (int opcode, unsigned long long insn)
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;
301 extInstruction_t *temp;
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 }
356
357 temp = arc_extension_map.instructions[INST_HASH (opcode, minor)];
358 while (temp)
359 {
360 if ((temp->major == opcode) && (temp->minor == minor))
361 {
362 return temp;
363 }
364 temp = temp->next;
365 }
366
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
376 || regnum > LAST_EXTENSION_CORE_REGISTER)
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
388 || regnum > LAST_EXTENSION_CORE_REGISTER)
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 *
409 arcExtMap_auxRegName (unsigned address)
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;
420 }
421
422 /* Load extensions described in .arcextmap and
423 .gnu.linkonce.arcextmap.* ELF section. */
424
425 void
426 build_ARC_extmap (bfd *text_bfd)
427 {
428 asection *sect;
429
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"))
440 {
441 bfd_size_type count = bfd_section_size (sect);
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 }
450 }
451 }
452
453 /* Debug function used to dump the ARC information fount in arcextmap
454 sections. */
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 {
466 printf ("AUX : %s %u\n", r->name, r->address);
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)
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 }
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)
509 printf ("CORE: 0x%04x %s %s\n", reg.number,
510 ExtReadWrite_image (reg.rw),
511 reg.name);
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 }
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 }
This page took 0.04666 seconds and 4 git commands to generate.