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