1 /* ARC target-dependent stuff. Extension structure access functions 2 Copyright (C) 1995-2024 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 free (arc_extension_map.coreRegisters[i].name); 249 250 /* Free condition codes. */ 251 for (i = 0; i < NUM_EXT_COND; i++) 252 free (arc_extension_map.condCodes[i]); 253 254 memset (&arc_extension_map, 0, sizeof (arc_extension_map)); 255 } 256 257 258 static const char * 259 ExtReadWrite_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 276 const extInstruction_t * 277 arcExtMap_insn (int opcode, unsigned long long insn) 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; 295 extInstruction_t *temp; 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 { 356 return temp; 357 } 358 temp = temp->next; 359 } 360 361 return NULL; 362 } 363 364 /* Get the name of an extension core register. */ 365 366 const char * 367 arcExtMap_coreRegName (int regnum) 368 { 369 if (regnum < FIRST_EXTENSION_CORE_REGISTER 370 || regnum > LAST_EXTENSION_CORE_REGISTER) 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 378 enum ExtReadWrite 379 arcExtMap_coreReadWrite (int regnum) 380 { 381 if (regnum < FIRST_EXTENSION_CORE_REGISTER 382 || regnum > LAST_EXTENSION_CORE_REGISTER) 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 390 const char * 391 arcExtMap_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 402 const char * 403 arcExtMap_auxRegName (unsigned address) 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. */ 418 419 void 420 build_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")) 434 { 435 bfd_size_type count = bfd_section_size (sect); 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 } 444 } 445 } 446 447 /* Debug function used to dump the ARC information fount in arcextmap 448 sections. */ 449 450 void 451 dump_ARC_extmap (void) 452 { 453 struct ExtAuxRegister *r; 454 int i; 455 456 r = arc_extension_map.auxRegisters; 457 458 while (r) 459 { 460 printf ("AUX : %s %u\n", r->name, r->address); 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) 470 { 471 printf ("INST: 0x%02x 0x%02x ", insn->major, insn->minor); 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 } 490 491 if (insn->flags & 0x10) 492 printf ("|MODIFIER"); 493 494 printf (" %s\n", insn->name); 495 } 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) 503 printf ("CORE: 0x%04x %s %s\n", reg.number, 504 ExtReadWrite_image (reg.rw), 505 reg.name); 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 } 512 513 /* For a given extension instruction generate the equivalent arc 514 opcode structure. */ 515 516 struct arc_opcode * 517 arcExtMap_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. */ 527 switch (einsn->flags & ARC_SYNTAX_MASK) 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; 535 case ARC_SYNTAX_1OP: 536 count = 3; 537 break; 538 case ARC_SYNTAX_NOP: 539 count = 1; 540 break; 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 } 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 } 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 } 811