1 /* DO NOT EDIT! -*- buffer-read-only: t -*- vi:set ro: */ 2 /* Instruction building/extraction support for iq2000. -*- C -*- 3 4 THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator. 5 - the resultant file is machine generated, cgen-ibld.in isn't 6 7 Copyright (C) 1996-2025 Free Software Foundation, Inc. 8 9 This file is part of libopcodes. 10 11 This library is free software; you can redistribute it and/or modify 12 it under the terms of the GNU General Public License as published by 13 the Free Software Foundation; either version 3, or (at your option) 14 any later version. 15 16 It is distributed in the hope that it will be useful, but WITHOUT 17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 18 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 19 License for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program; if not, write to the Free Software Foundation, Inc., 23 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 24 25 /* ??? Eventually more and more of this stuff can go to cpu-independent files. 26 Keep that in mind. */ 27 28 #include "sysdep.h" 29 #include <stdio.h> 30 #include "ansidecl.h" 31 #include "dis-asm.h" 32 #include "bfd.h" 33 #include "symcat.h" 34 #include "iq2000-desc.h" 35 #include "iq2000-opc.h" 36 #include "cgen/basic-modes.h" 37 #include "opintl.h" 38 #include "safe-ctype.h" 39 40 #undef min 41 #define min(a,b) ((a) < (b) ? (a) : (b)) 42 #undef max 43 #define max(a,b) ((a) > (b) ? (a) : (b)) 44 45 /* Used by the ifield rtx function. */ 46 #define FLD(f) (fields->f) 47 48 static const char * insert_normal 49 (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int, 50 unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR); 51 static const char * insert_insn_normal 52 (CGEN_CPU_DESC, const CGEN_INSN *, 53 CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma); 54 static int extract_normal 55 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, 56 unsigned int, unsigned int, unsigned int, unsigned int, 57 unsigned int, unsigned int, bfd_vma, long *); 58 static int extract_insn_normal 59 (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *, 60 CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma); 61 #if CGEN_INT_INSN_P 62 static void put_insn_int_value 63 (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT); 64 #endif 65 #if ! CGEN_INT_INSN_P 66 static CGEN_INLINE void insert_1 67 (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *); 68 static CGEN_INLINE int fill_cache 69 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma); 70 static CGEN_INLINE long extract_1 71 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma); 72 #endif 73 74 /* Operand insertion. */ 76 77 #if ! CGEN_INT_INSN_P 78 79 /* Subroutine of insert_normal. */ 80 81 static CGEN_INLINE void 82 insert_1 (CGEN_CPU_DESC cd, 83 unsigned long value, 84 int start, 85 int length, 86 int word_length, 87 unsigned char *bufp) 88 { 89 unsigned long x, mask; 90 int shift; 91 92 x = cgen_get_insn_value (cd, bufp, word_length, cd->endian); 93 94 /* Written this way to avoid undefined behaviour. */ 95 mask = (1UL << (length - 1) << 1) - 1; 96 if (CGEN_INSN_LSB0_P) 97 shift = (start + 1) - length; 98 else 99 shift = (word_length - (start + length)); 100 x = (x & ~(mask << shift)) | ((value & mask) << shift); 101 102 cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x, cd->endian); 103 } 104 105 #endif /* ! CGEN_INT_INSN_P */ 106 107 /* Default insertion routine. 108 109 ATTRS is a mask of the boolean attributes. 110 WORD_OFFSET is the offset in bits from the start of the insn of the value. 111 WORD_LENGTH is the length of the word in bits in which the value resides. 112 START is the starting bit number in the word, architecture origin. 113 LENGTH is the length of VALUE in bits. 114 TOTAL_LENGTH is the total length of the insn in bits. 115 116 The result is an error message or NULL if success. */ 117 118 /* ??? This duplicates functionality with bfd's howto table and 119 bfd_install_relocation. */ 120 /* ??? This doesn't handle bfd_vma's. Create another function when 121 necessary. */ 122 123 static const char * 124 insert_normal (CGEN_CPU_DESC cd, 125 long value, 126 unsigned int attrs, 127 unsigned int word_offset, 128 unsigned int start, 129 unsigned int length, 130 unsigned int word_length, 131 unsigned int total_length, 132 CGEN_INSN_BYTES_PTR buffer) 133 { 134 static char errbuf[100]; 135 unsigned long mask; 136 137 /* If LENGTH is zero, this operand doesn't contribute to the value. */ 138 if (length == 0) 139 return NULL; 140 141 /* Written this way to avoid undefined behaviour. */ 142 mask = (1UL << (length - 1) << 1) - 1; 143 144 if (word_length > 8 * sizeof (CGEN_INSN_INT)) 145 abort (); 146 147 /* For architectures with insns smaller than the base-insn-bitsize, 148 word_length may be too big. */ 149 if (cd->min_insn_bitsize < cd->base_insn_bitsize) 150 { 151 if (word_offset == 0 152 && word_length > total_length) 153 word_length = total_length; 154 } 155 156 /* Ensure VALUE will fit. */ 157 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT)) 158 { 159 long minval = - (1UL << (length - 1)); 160 unsigned long maxval = mask; 161 162 if ((value > 0 && (unsigned long) value > maxval) 163 || value < minval) 164 { 165 /* xgettext:c-format */ 166 sprintf (errbuf, 167 _("operand out of range (%ld not between %ld and %lu)"), 168 value, minval, maxval); 169 return errbuf; 170 } 171 } 172 else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)) 173 { 174 unsigned long maxval = mask; 175 unsigned long val = (unsigned long) value; 176 177 /* For hosts with a word size > 32 check to see if value has been sign 178 extended beyond 32 bits. If so then ignore these higher sign bits 179 as the user is attempting to store a 32-bit signed value into an 180 unsigned 32-bit field which is allowed. */ 181 if (sizeof (unsigned long) > 4 && ((value >> 32) == -1)) 182 val &= 0xFFFFFFFF; 183 184 if (val > maxval) 185 { 186 /* xgettext:c-format */ 187 sprintf (errbuf, 188 _("operand out of range (0x%lx not between 0 and 0x%lx)"), 189 val, maxval); 190 return errbuf; 191 } 192 } 193 else 194 { 195 if (! cgen_signed_overflow_ok_p (cd)) 196 { 197 long minval = - (1UL << (length - 1)); 198 long maxval = (1UL << (length - 1)) - 1; 199 200 if (value < minval || value > maxval) 201 { 202 sprintf 203 /* xgettext:c-format */ 204 (errbuf, _("operand out of range (%ld not between %ld and %ld)"), 205 value, minval, maxval); 206 return errbuf; 207 } 208 } 209 } 210 211 #if CGEN_INT_INSN_P 212 213 { 214 int shift_within_word, shift_to_word, shift; 215 216 /* How to shift the value to BIT0 of the word. */ 217 shift_to_word = total_length - (word_offset + word_length); 218 219 /* How to shift the value to the field within the word. */ 220 if (CGEN_INSN_LSB0_P) 221 shift_within_word = start + 1 - length; 222 else 223 shift_within_word = word_length - start - length; 224 225 /* The total SHIFT, then mask in the value. */ 226 shift = shift_to_word + shift_within_word; 227 *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift); 228 } 229 230 #else /* ! CGEN_INT_INSN_P */ 231 232 { 233 unsigned char *bufp = (unsigned char *) buffer + word_offset / 8; 234 235 insert_1 (cd, value, start, length, word_length, bufp); 236 } 237 238 #endif /* ! CGEN_INT_INSN_P */ 239 240 return NULL; 241 } 242 243 /* Default insn builder (insert handler). 244 The instruction is recorded in CGEN_INT_INSN_P byte order (meaning 245 that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is 246 recorded in host byte order, otherwise BUFFER is an array of bytes 247 and the value is recorded in target byte order). 248 The result is an error message or NULL if success. */ 249 250 static const char * 251 insert_insn_normal (CGEN_CPU_DESC cd, 252 const CGEN_INSN * insn, 253 CGEN_FIELDS * fields, 254 CGEN_INSN_BYTES_PTR buffer, 255 bfd_vma pc) 256 { 257 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); 258 unsigned long value; 259 const CGEN_SYNTAX_CHAR_TYPE * syn; 260 261 CGEN_INIT_INSERT (cd); 262 value = CGEN_INSN_BASE_VALUE (insn); 263 264 /* If we're recording insns as numbers (rather than a string of bytes), 265 target byte order handling is deferred until later. */ 266 267 #if CGEN_INT_INSN_P 268 269 put_insn_int_value (cd, buffer, cd->base_insn_bitsize, 270 CGEN_FIELDS_BITSIZE (fields), value); 271 272 #else 273 274 cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize, 275 (unsigned) CGEN_FIELDS_BITSIZE (fields)), 276 value, cd->insn_endian); 277 278 #endif /* ! CGEN_INT_INSN_P */ 279 280 /* ??? It would be better to scan the format's fields. 281 Still need to be able to insert a value based on the operand though; 282 e.g. storing a branch displacement that got resolved later. 283 Needs more thought first. */ 284 285 for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn) 286 { 287 const char *errmsg; 288 289 if (CGEN_SYNTAX_CHAR_P (* syn)) 290 continue; 291 292 errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn), 293 fields, buffer, pc); 294 if (errmsg) 295 return errmsg; 296 } 297 298 return NULL; 299 } 300 301 #if CGEN_INT_INSN_P 302 /* Cover function to store an insn value into an integral insn. Must go here 303 because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */ 304 305 static void 306 put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 307 CGEN_INSN_BYTES_PTR buf, 308 int length, 309 int insn_length, 310 CGEN_INSN_INT value) 311 { 312 /* For architectures with insns smaller than the base-insn-bitsize, 313 length may be too big. */ 314 if (length > insn_length) 315 *buf = value; 316 else 317 { 318 int shift = insn_length - length; 319 /* Written this way to avoid undefined behaviour. */ 320 CGEN_INSN_INT mask = length == 0 ? 0 : (1UL << (length - 1) << 1) - 1; 321 322 *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift); 323 } 324 } 325 #endif 326 327 /* Operand extraction. */ 329 330 #if ! CGEN_INT_INSN_P 331 332 /* Subroutine of extract_normal. 333 Ensure sufficient bytes are cached in EX_INFO. 334 OFFSET is the offset in bytes from the start of the insn of the value. 335 BYTES is the length of the needed value. 336 Returns 1 for success, 0 for failure. */ 337 338 static CGEN_INLINE int 339 fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 340 CGEN_EXTRACT_INFO *ex_info, 341 int offset, 342 int bytes, 343 bfd_vma pc) 344 { 345 /* It's doubtful that the middle part has already been fetched so 346 we don't optimize that case. kiss. */ 347 unsigned int mask; 348 disassemble_info *info = (disassemble_info *) ex_info->dis_info; 349 350 /* First do a quick check. */ 351 mask = (1 << bytes) - 1; 352 if (((ex_info->valid >> offset) & mask) == mask) 353 return 1; 354 355 /* Search for the first byte we need to read. */ 356 for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1) 357 if (! (mask & ex_info->valid)) 358 break; 359 360 if (bytes) 361 { 362 int status; 363 364 pc += offset; 365 status = (*info->read_memory_func) 366 (pc, ex_info->insn_bytes + offset, bytes, info); 367 368 if (status != 0) 369 { 370 (*info->memory_error_func) (status, pc, info); 371 return 0; 372 } 373 374 ex_info->valid |= ((1 << bytes) - 1) << offset; 375 } 376 377 return 1; 378 } 379 380 /* Subroutine of extract_normal. */ 381 382 static CGEN_INLINE long 383 extract_1 (CGEN_CPU_DESC cd, 384 CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED, 385 int start, 386 int length, 387 int word_length, 388 unsigned char *bufp, 389 bfd_vma pc ATTRIBUTE_UNUSED) 390 { 391 unsigned long x; 392 int shift; 393 394 x = cgen_get_insn_value (cd, bufp, word_length, cd->endian); 395 396 if (CGEN_INSN_LSB0_P) 397 shift = (start + 1) - length; 398 else 399 shift = (word_length - (start + length)); 400 return x >> shift; 401 } 402 403 #endif /* ! CGEN_INT_INSN_P */ 404 405 /* Default extraction routine. 406 407 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order, 408 or sometimes less for cases like the m32r where the base insn size is 32 409 but some insns are 16 bits. 410 ATTRS is a mask of the boolean attributes. We only need `SIGNED', 411 but for generality we take a bitmask of all of them. 412 WORD_OFFSET is the offset in bits from the start of the insn of the value. 413 WORD_LENGTH is the length of the word in bits in which the value resides. 414 START is the starting bit number in the word, architecture origin. 415 LENGTH is the length of VALUE in bits. 416 TOTAL_LENGTH is the total length of the insn in bits. 417 418 Returns 1 for success, 0 for failure. */ 419 420 /* ??? The return code isn't properly used. wip. */ 421 422 /* ??? This doesn't handle bfd_vma's. Create another function when 423 necessary. */ 424 425 static int 426 extract_normal (CGEN_CPU_DESC cd, 427 #if ! CGEN_INT_INSN_P 428 CGEN_EXTRACT_INFO *ex_info, 429 #else 430 CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED, 431 #endif 432 CGEN_INSN_INT insn_value, 433 unsigned int attrs, 434 unsigned int word_offset, 435 unsigned int start, 436 unsigned int length, 437 unsigned int word_length, 438 unsigned int total_length, 439 #if ! CGEN_INT_INSN_P 440 bfd_vma pc, 441 #else 442 bfd_vma pc ATTRIBUTE_UNUSED, 443 #endif 444 long *valuep) 445 { 446 long value, mask; 447 448 /* If LENGTH is zero, this operand doesn't contribute to the value 449 so give it a standard value of zero. */ 450 if (length == 0) 451 { 452 *valuep = 0; 453 return 1; 454 } 455 456 if (word_length > 8 * sizeof (CGEN_INSN_INT)) 457 abort (); 458 459 /* For architectures with insns smaller than the insn-base-bitsize, 460 word_length may be too big. */ 461 if (cd->min_insn_bitsize < cd->base_insn_bitsize) 462 { 463 if (word_offset + word_length > total_length) 464 word_length = total_length - word_offset; 465 } 466 467 /* Does the value reside in INSN_VALUE, and at the right alignment? */ 468 469 if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length)) 470 { 471 if (CGEN_INSN_LSB0_P) 472 value = insn_value >> ((word_offset + start + 1) - length); 473 else 474 value = insn_value >> (total_length - ( word_offset + start + length)); 475 } 476 477 #if ! CGEN_INT_INSN_P 478 479 else 480 { 481 unsigned char *bufp = ex_info->insn_bytes + word_offset / 8; 482 483 if (word_length > 8 * sizeof (CGEN_INSN_INT)) 484 abort (); 485 486 if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0) 487 { 488 *valuep = 0; 489 return 0; 490 } 491 492 value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc); 493 } 494 495 #endif /* ! CGEN_INT_INSN_P */ 496 497 /* Written this way to avoid undefined behaviour. */ 498 mask = (1UL << (length - 1) << 1) - 1; 499 500 value &= mask; 501 /* sign extend? */ 502 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED) 503 && (value & (1UL << (length - 1)))) 504 value |= ~mask; 505 506 *valuep = value; 507 508 return 1; 509 } 510 511 /* Default insn extractor. 512 513 INSN_VALUE is the first base_insn_bitsize bits, translated to host order. 514 The extracted fields are stored in FIELDS. 515 EX_INFO is used to handle reading variable length insns. 516 Return the length of the insn in bits, or 0 if no match, 517 or -1 if an error occurs fetching data (memory_error_func will have 518 been called). */ 519 520 static int 521 extract_insn_normal (CGEN_CPU_DESC cd, 522 const CGEN_INSN *insn, 523 CGEN_EXTRACT_INFO *ex_info, 524 CGEN_INSN_INT insn_value, 525 CGEN_FIELDS *fields, 526 bfd_vma pc) 527 { 528 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); 529 const CGEN_SYNTAX_CHAR_TYPE *syn; 530 531 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); 532 533 CGEN_INIT_EXTRACT (cd); 534 535 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn) 536 { 537 int length; 538 539 if (CGEN_SYNTAX_CHAR_P (*syn)) 540 continue; 541 542 length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn), 543 ex_info, insn_value, fields, pc); 544 if (length <= 0) 545 return length; 546 } 547 548 /* We recognized and successfully extracted this insn. */ 549 return CGEN_INSN_BITSIZE (insn); 550 } 551 552 /* Machine generated code added here. */ 554 555 const char * iq2000_cgen_insert_operand 556 (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma); 557 558 /* Main entry point for operand insertion. 559 560 This function is basically just a big switch statement. Earlier versions 561 used tables to look up the function to use, but 562 - if the table contains both assembler and disassembler functions then 563 the disassembler contains much of the assembler and vice-versa, 564 - there's a lot of inlining possibilities as things grow, 565 - using a switch statement avoids the function call overhead. 566 567 This function could be moved into `parse_insn_normal', but keeping it 568 separate makes clear the interface between `parse_insn_normal' and each of 569 the handlers. It's also needed by GAS to insert operands that couldn't be 570 resolved during parsing. */ 571 572 const char * 573 iq2000_cgen_insert_operand (CGEN_CPU_DESC cd, 574 int opindex, 575 CGEN_FIELDS * fields, 576 CGEN_INSN_BYTES_PTR buffer, 577 bfd_vma pc ATTRIBUTE_UNUSED) 578 { 579 const char * errmsg = NULL; 580 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields); 581 582 switch (opindex) 583 { 584 case IQ2000_OPERAND__INDEX : 585 errmsg = insert_normal (cd, fields->f_index, 0, 0, 8, 9, 32, total_length, buffer); 586 break; 587 case IQ2000_OPERAND_BASE : 588 errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer); 589 break; 590 case IQ2000_OPERAND_BASEOFF : 591 errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer); 592 break; 593 case IQ2000_OPERAND_BITNUM : 594 errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer); 595 break; 596 case IQ2000_OPERAND_BYTECOUNT : 597 errmsg = insert_normal (cd, fields->f_bytecount, 0, 0, 7, 8, 32, total_length, buffer); 598 break; 599 case IQ2000_OPERAND_CAM_Y : 600 errmsg = insert_normal (cd, fields->f_cam_y, 0, 0, 2, 3, 32, total_length, buffer); 601 break; 602 case IQ2000_OPERAND_CAM_Z : 603 errmsg = insert_normal (cd, fields->f_cam_z, 0, 0, 5, 3, 32, total_length, buffer); 604 break; 605 case IQ2000_OPERAND_CM_3FUNC : 606 errmsg = insert_normal (cd, fields->f_cm_3func, 0, 0, 5, 3, 32, total_length, buffer); 607 break; 608 case IQ2000_OPERAND_CM_3Z : 609 errmsg = insert_normal (cd, fields->f_cm_3z, 0, 0, 1, 2, 32, total_length, buffer); 610 break; 611 case IQ2000_OPERAND_CM_4FUNC : 612 errmsg = insert_normal (cd, fields->f_cm_4func, 0, 0, 5, 4, 32, total_length, buffer); 613 break; 614 case IQ2000_OPERAND_CM_4Z : 615 errmsg = insert_normal (cd, fields->f_cm_4z, 0, 0, 2, 3, 32, total_length, buffer); 616 break; 617 case IQ2000_OPERAND_COUNT : 618 errmsg = insert_normal (cd, fields->f_count, 0, 0, 15, 7, 32, total_length, buffer); 619 break; 620 case IQ2000_OPERAND_EXECODE : 621 errmsg = insert_normal (cd, fields->f_excode, 0, 0, 25, 20, 32, total_length, buffer); 622 break; 623 case IQ2000_OPERAND_HI16 : 624 errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer); 625 break; 626 case IQ2000_OPERAND_IMM : 627 errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer); 628 break; 629 case IQ2000_OPERAND_JMPTARG : 630 { 631 long value = fields->f_jtarg; 632 value = ((USI) (((value) & (262143))) >> (2)); 633 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 16, 32, total_length, buffer); 634 } 635 break; 636 case IQ2000_OPERAND_JMPTARGQ10 : 637 { 638 long value = fields->f_jtargq10; 639 value = ((USI) (((value) & (8388607))) >> (2)); 640 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 20, 21, 32, total_length, buffer); 641 } 642 break; 643 case IQ2000_OPERAND_LO16 : 644 errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer); 645 break; 646 case IQ2000_OPERAND_MASK : 647 errmsg = insert_normal (cd, fields->f_mask, 0, 0, 9, 4, 32, total_length, buffer); 648 break; 649 case IQ2000_OPERAND_MASKL : 650 errmsg = insert_normal (cd, fields->f_maskl, 0, 0, 4, 5, 32, total_length, buffer); 651 break; 652 case IQ2000_OPERAND_MASKQ10 : 653 errmsg = insert_normal (cd, fields->f_maskq10, 0, 0, 10, 5, 32, total_length, buffer); 654 break; 655 case IQ2000_OPERAND_MASKR : 656 errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer); 657 break; 658 case IQ2000_OPERAND_MLO16 : 659 errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer); 660 break; 661 case IQ2000_OPERAND_OFFSET : 662 { 663 long value = fields->f_offset; 664 value = ((SI) (((value) - (pc))) >> (2)); 665 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 16, 32, total_length, buffer); 666 } 667 break; 668 case IQ2000_OPERAND_RD : 669 errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 5, 32, total_length, buffer); 670 break; 671 case IQ2000_OPERAND_RD_RS : 672 { 673 { 674 FLD (f_rd) = FLD (f_rd_rs); 675 FLD (f_rs) = FLD (f_rd_rs); 676 } 677 errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 5, 32, total_length, buffer); 678 if (errmsg) 679 break; 680 errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer); 681 if (errmsg) 682 break; 683 } 684 break; 685 case IQ2000_OPERAND_RD_RT : 686 { 687 { 688 FLD (f_rd) = FLD (f_rd_rt); 689 FLD (f_rt) = FLD (f_rd_rt); 690 } 691 errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 5, 32, total_length, buffer); 692 if (errmsg) 693 break; 694 errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer); 695 if (errmsg) 696 break; 697 } 698 break; 699 case IQ2000_OPERAND_RS : 700 errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer); 701 break; 702 case IQ2000_OPERAND_RT : 703 errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer); 704 break; 705 case IQ2000_OPERAND_RT_RS : 706 { 707 { 708 FLD (f_rt) = FLD (f_rt_rs); 709 FLD (f_rs) = FLD (f_rt_rs); 710 } 711 errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer); 712 if (errmsg) 713 break; 714 errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer); 715 if (errmsg) 716 break; 717 } 718 break; 719 case IQ2000_OPERAND_SHAMT : 720 errmsg = insert_normal (cd, fields->f_shamt, 0, 0, 10, 5, 32, total_length, buffer); 721 break; 722 723 default : 724 /* xgettext:c-format */ 725 opcodes_error_handler 726 (_("internal error: unrecognized field %d while building insn"), 727 opindex); 728 abort (); 729 } 730 731 return errmsg; 732 } 733 734 int iq2000_cgen_extract_operand 735 (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma); 736 737 /* Main entry point for operand extraction. 738 The result is <= 0 for error, >0 for success. 739 ??? Actual values aren't well defined right now. 740 741 This function is basically just a big switch statement. Earlier versions 742 used tables to look up the function to use, but 743 - if the table contains both assembler and disassembler functions then 744 the disassembler contains much of the assembler and vice-versa, 745 - there's a lot of inlining possibilities as things grow, 746 - using a switch statement avoids the function call overhead. 747 748 This function could be moved into `print_insn_normal', but keeping it 749 separate makes clear the interface between `print_insn_normal' and each of 750 the handlers. */ 751 752 int 753 iq2000_cgen_extract_operand (CGEN_CPU_DESC cd, 754 int opindex, 755 CGEN_EXTRACT_INFO *ex_info, 756 CGEN_INSN_INT insn_value, 757 CGEN_FIELDS * fields, 758 bfd_vma pc) 759 { 760 /* Assume success (for those operands that are nops). */ 761 int length = 1; 762 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields); 763 764 switch (opindex) 765 { 766 case IQ2000_OPERAND__INDEX : 767 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 9, 32, total_length, pc, & fields->f_index); 768 break; 769 case IQ2000_OPERAND_BASE : 770 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs); 771 break; 772 case IQ2000_OPERAND_BASEOFF : 773 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm); 774 break; 775 case IQ2000_OPERAND_BITNUM : 776 length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt); 777 break; 778 case IQ2000_OPERAND_BYTECOUNT : 779 length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 8, 32, total_length, pc, & fields->f_bytecount); 780 break; 781 case IQ2000_OPERAND_CAM_Y : 782 length = extract_normal (cd, ex_info, insn_value, 0, 0, 2, 3, 32, total_length, pc, & fields->f_cam_y); 783 break; 784 case IQ2000_OPERAND_CAM_Z : 785 length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_cam_z); 786 break; 787 case IQ2000_OPERAND_CM_3FUNC : 788 length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_cm_3func); 789 break; 790 case IQ2000_OPERAND_CM_3Z : 791 length = extract_normal (cd, ex_info, insn_value, 0, 0, 1, 2, 32, total_length, pc, & fields->f_cm_3z); 792 break; 793 case IQ2000_OPERAND_CM_4FUNC : 794 length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 4, 32, total_length, pc, & fields->f_cm_4func); 795 break; 796 case IQ2000_OPERAND_CM_4Z : 797 length = extract_normal (cd, ex_info, insn_value, 0, 0, 2, 3, 32, total_length, pc, & fields->f_cm_4z); 798 break; 799 case IQ2000_OPERAND_COUNT : 800 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 7, 32, total_length, pc, & fields->f_count); 801 break; 802 case IQ2000_OPERAND_EXECODE : 803 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 20, 32, total_length, pc, & fields->f_excode); 804 break; 805 case IQ2000_OPERAND_HI16 : 806 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm); 807 break; 808 case IQ2000_OPERAND_IMM : 809 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm); 810 break; 811 case IQ2000_OPERAND_JMPTARG : 812 { 813 long value; 814 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 16, 32, total_length, pc, & value); 815 value = ((((pc) & (0xf0000000))) | (((value) << (2)))); 816 fields->f_jtarg = value; 817 } 818 break; 819 case IQ2000_OPERAND_JMPTARGQ10 : 820 { 821 long value; 822 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 20, 21, 32, total_length, pc, & value); 823 value = ((((pc) & (0xf0000000))) | (((value) << (2)))); 824 fields->f_jtargq10 = value; 825 } 826 break; 827 case IQ2000_OPERAND_LO16 : 828 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm); 829 break; 830 case IQ2000_OPERAND_MASK : 831 length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 4, 32, total_length, pc, & fields->f_mask); 832 break; 833 case IQ2000_OPERAND_MASKL : 834 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 5, 32, total_length, pc, & fields->f_maskl); 835 break; 836 case IQ2000_OPERAND_MASKQ10 : 837 length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 5, 32, total_length, pc, & fields->f_maskq10); 838 break; 839 case IQ2000_OPERAND_MASKR : 840 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs); 841 break; 842 case IQ2000_OPERAND_MLO16 : 843 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm); 844 break; 845 case IQ2000_OPERAND_OFFSET : 846 { 847 long value; 848 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 16, 32, total_length, pc, & value); 849 value = ((((value) * (4))) + (((pc) + (4)))); 850 fields->f_offset = value; 851 } 852 break; 853 case IQ2000_OPERAND_RD : 854 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_rd); 855 break; 856 case IQ2000_OPERAND_RD_RS : 857 { 858 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_rd); 859 if (length <= 0) break; 860 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs); 861 if (length <= 0) break; 862 { 863 FLD (f_rd_rs) = FLD (f_rs); 864 } 865 } 866 break; 867 case IQ2000_OPERAND_RD_RT : 868 { 869 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_rd); 870 if (length <= 0) break; 871 length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt); 872 if (length <= 0) break; 873 { 874 FLD (f_rd_rt) = FLD (f_rt); 875 } 876 } 877 break; 878 case IQ2000_OPERAND_RS : 879 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs); 880 break; 881 case IQ2000_OPERAND_RT : 882 length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt); 883 break; 884 case IQ2000_OPERAND_RT_RS : 885 { 886 length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt); 887 if (length <= 0) break; 888 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs); 889 if (length <= 0) break; 890 { 891 FLD (f_rd_rs) = FLD (f_rs); 892 } 893 } 894 break; 895 case IQ2000_OPERAND_SHAMT : 896 length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 5, 32, total_length, pc, & fields->f_shamt); 897 break; 898 899 default : 900 /* xgettext:c-format */ 901 opcodes_error_handler 902 (_("internal error: unrecognized field %d while decoding insn"), 903 opindex); 904 abort (); 905 } 906 907 return length; 908 } 909 910 cgen_insert_fn * const iq2000_cgen_insert_handlers[] = 911 { 912 insert_insn_normal, 913 }; 914 915 cgen_extract_fn * const iq2000_cgen_extract_handlers[] = 916 { 917 extract_insn_normal, 918 }; 919 920 int iq2000_cgen_get_int_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *); 921 bfd_vma iq2000_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *); 922 923 /* Getting values from cgen_fields is handled by a collection of functions. 924 They are distinguished by the type of the VALUE argument they return. 925 TODO: floating point, inlining support, remove cases where result type 926 not appropriate. */ 927 928 int 929 iq2000_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 930 int opindex, 931 const CGEN_FIELDS * fields) 932 { 933 int value; 934 935 switch (opindex) 936 { 937 case IQ2000_OPERAND__INDEX : 938 value = fields->f_index; 939 break; 940 case IQ2000_OPERAND_BASE : 941 value = fields->f_rs; 942 break; 943 case IQ2000_OPERAND_BASEOFF : 944 value = fields->f_imm; 945 break; 946 case IQ2000_OPERAND_BITNUM : 947 value = fields->f_rt; 948 break; 949 case IQ2000_OPERAND_BYTECOUNT : 950 value = fields->f_bytecount; 951 break; 952 case IQ2000_OPERAND_CAM_Y : 953 value = fields->f_cam_y; 954 break; 955 case IQ2000_OPERAND_CAM_Z : 956 value = fields->f_cam_z; 957 break; 958 case IQ2000_OPERAND_CM_3FUNC : 959 value = fields->f_cm_3func; 960 break; 961 case IQ2000_OPERAND_CM_3Z : 962 value = fields->f_cm_3z; 963 break; 964 case IQ2000_OPERAND_CM_4FUNC : 965 value = fields->f_cm_4func; 966 break; 967 case IQ2000_OPERAND_CM_4Z : 968 value = fields->f_cm_4z; 969 break; 970 case IQ2000_OPERAND_COUNT : 971 value = fields->f_count; 972 break; 973 case IQ2000_OPERAND_EXECODE : 974 value = fields->f_excode; 975 break; 976 case IQ2000_OPERAND_HI16 : 977 value = fields->f_imm; 978 break; 979 case IQ2000_OPERAND_IMM : 980 value = fields->f_imm; 981 break; 982 case IQ2000_OPERAND_JMPTARG : 983 value = fields->f_jtarg; 984 break; 985 case IQ2000_OPERAND_JMPTARGQ10 : 986 value = fields->f_jtargq10; 987 break; 988 case IQ2000_OPERAND_LO16 : 989 value = fields->f_imm; 990 break; 991 case IQ2000_OPERAND_MASK : 992 value = fields->f_mask; 993 break; 994 case IQ2000_OPERAND_MASKL : 995 value = fields->f_maskl; 996 break; 997 case IQ2000_OPERAND_MASKQ10 : 998 value = fields->f_maskq10; 999 break; 1000 case IQ2000_OPERAND_MASKR : 1001 value = fields->f_rs; 1002 break; 1003 case IQ2000_OPERAND_MLO16 : 1004 value = fields->f_imm; 1005 break; 1006 case IQ2000_OPERAND_OFFSET : 1007 value = fields->f_offset; 1008 break; 1009 case IQ2000_OPERAND_RD : 1010 value = fields->f_rd; 1011 break; 1012 case IQ2000_OPERAND_RD_RS : 1013 value = fields->f_rd_rs; 1014 break; 1015 case IQ2000_OPERAND_RD_RT : 1016 value = fields->f_rd_rt; 1017 break; 1018 case IQ2000_OPERAND_RS : 1019 value = fields->f_rs; 1020 break; 1021 case IQ2000_OPERAND_RT : 1022 value = fields->f_rt; 1023 break; 1024 case IQ2000_OPERAND_RT_RS : 1025 value = fields->f_rt_rs; 1026 break; 1027 case IQ2000_OPERAND_SHAMT : 1028 value = fields->f_shamt; 1029 break; 1030 1031 default : 1032 /* xgettext:c-format */ 1033 opcodes_error_handler 1034 (_("internal error: unrecognized field %d while getting int operand"), 1035 opindex); 1036 abort (); 1037 } 1038 1039 return value; 1040 } 1041 1042 bfd_vma 1043 iq2000_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 1044 int opindex, 1045 const CGEN_FIELDS * fields) 1046 { 1047 bfd_vma value; 1048 1049 switch (opindex) 1050 { 1051 case IQ2000_OPERAND__INDEX : 1052 value = fields->f_index; 1053 break; 1054 case IQ2000_OPERAND_BASE : 1055 value = fields->f_rs; 1056 break; 1057 case IQ2000_OPERAND_BASEOFF : 1058 value = fields->f_imm; 1059 break; 1060 case IQ2000_OPERAND_BITNUM : 1061 value = fields->f_rt; 1062 break; 1063 case IQ2000_OPERAND_BYTECOUNT : 1064 value = fields->f_bytecount; 1065 break; 1066 case IQ2000_OPERAND_CAM_Y : 1067 value = fields->f_cam_y; 1068 break; 1069 case IQ2000_OPERAND_CAM_Z : 1070 value = fields->f_cam_z; 1071 break; 1072 case IQ2000_OPERAND_CM_3FUNC : 1073 value = fields->f_cm_3func; 1074 break; 1075 case IQ2000_OPERAND_CM_3Z : 1076 value = fields->f_cm_3z; 1077 break; 1078 case IQ2000_OPERAND_CM_4FUNC : 1079 value = fields->f_cm_4func; 1080 break; 1081 case IQ2000_OPERAND_CM_4Z : 1082 value = fields->f_cm_4z; 1083 break; 1084 case IQ2000_OPERAND_COUNT : 1085 value = fields->f_count; 1086 break; 1087 case IQ2000_OPERAND_EXECODE : 1088 value = fields->f_excode; 1089 break; 1090 case IQ2000_OPERAND_HI16 : 1091 value = fields->f_imm; 1092 break; 1093 case IQ2000_OPERAND_IMM : 1094 value = fields->f_imm; 1095 break; 1096 case IQ2000_OPERAND_JMPTARG : 1097 value = fields->f_jtarg; 1098 break; 1099 case IQ2000_OPERAND_JMPTARGQ10 : 1100 value = fields->f_jtargq10; 1101 break; 1102 case IQ2000_OPERAND_LO16 : 1103 value = fields->f_imm; 1104 break; 1105 case IQ2000_OPERAND_MASK : 1106 value = fields->f_mask; 1107 break; 1108 case IQ2000_OPERAND_MASKL : 1109 value = fields->f_maskl; 1110 break; 1111 case IQ2000_OPERAND_MASKQ10 : 1112 value = fields->f_maskq10; 1113 break; 1114 case IQ2000_OPERAND_MASKR : 1115 value = fields->f_rs; 1116 break; 1117 case IQ2000_OPERAND_MLO16 : 1118 value = fields->f_imm; 1119 break; 1120 case IQ2000_OPERAND_OFFSET : 1121 value = fields->f_offset; 1122 break; 1123 case IQ2000_OPERAND_RD : 1124 value = fields->f_rd; 1125 break; 1126 case IQ2000_OPERAND_RD_RS : 1127 value = fields->f_rd_rs; 1128 break; 1129 case IQ2000_OPERAND_RD_RT : 1130 value = fields->f_rd_rt; 1131 break; 1132 case IQ2000_OPERAND_RS : 1133 value = fields->f_rs; 1134 break; 1135 case IQ2000_OPERAND_RT : 1136 value = fields->f_rt; 1137 break; 1138 case IQ2000_OPERAND_RT_RS : 1139 value = fields->f_rt_rs; 1140 break; 1141 case IQ2000_OPERAND_SHAMT : 1142 value = fields->f_shamt; 1143 break; 1144 1145 default : 1146 /* xgettext:c-format */ 1147 opcodes_error_handler 1148 (_("internal error: unrecognized field %d while getting vma operand"), 1149 opindex); 1150 abort (); 1151 } 1152 1153 return value; 1154 } 1155 1156 void iq2000_cgen_set_int_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, int); 1157 void iq2000_cgen_set_vma_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma); 1158 1159 /* Stuffing values in cgen_fields is handled by a collection of functions. 1160 They are distinguished by the type of the VALUE argument they accept. 1161 TODO: floating point, inlining support, remove cases where argument type 1162 not appropriate. */ 1163 1164 void 1165 iq2000_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 1166 int opindex, 1167 CGEN_FIELDS * fields, 1168 int value) 1169 { 1170 switch (opindex) 1171 { 1172 case IQ2000_OPERAND__INDEX : 1173 fields->f_index = value; 1174 break; 1175 case IQ2000_OPERAND_BASE : 1176 fields->f_rs = value; 1177 break; 1178 case IQ2000_OPERAND_BASEOFF : 1179 fields->f_imm = value; 1180 break; 1181 case IQ2000_OPERAND_BITNUM : 1182 fields->f_rt = value; 1183 break; 1184 case IQ2000_OPERAND_BYTECOUNT : 1185 fields->f_bytecount = value; 1186 break; 1187 case IQ2000_OPERAND_CAM_Y : 1188 fields->f_cam_y = value; 1189 break; 1190 case IQ2000_OPERAND_CAM_Z : 1191 fields->f_cam_z = value; 1192 break; 1193 case IQ2000_OPERAND_CM_3FUNC : 1194 fields->f_cm_3func = value; 1195 break; 1196 case IQ2000_OPERAND_CM_3Z : 1197 fields->f_cm_3z = value; 1198 break; 1199 case IQ2000_OPERAND_CM_4FUNC : 1200 fields->f_cm_4func = value; 1201 break; 1202 case IQ2000_OPERAND_CM_4Z : 1203 fields->f_cm_4z = value; 1204 break; 1205 case IQ2000_OPERAND_COUNT : 1206 fields->f_count = value; 1207 break; 1208 case IQ2000_OPERAND_EXECODE : 1209 fields->f_excode = value; 1210 break; 1211 case IQ2000_OPERAND_HI16 : 1212 fields->f_imm = value; 1213 break; 1214 case IQ2000_OPERAND_IMM : 1215 fields->f_imm = value; 1216 break; 1217 case IQ2000_OPERAND_JMPTARG : 1218 fields->f_jtarg = value; 1219 break; 1220 case IQ2000_OPERAND_JMPTARGQ10 : 1221 fields->f_jtargq10 = value; 1222 break; 1223 case IQ2000_OPERAND_LO16 : 1224 fields->f_imm = value; 1225 break; 1226 case IQ2000_OPERAND_MASK : 1227 fields->f_mask = value; 1228 break; 1229 case IQ2000_OPERAND_MASKL : 1230 fields->f_maskl = value; 1231 break; 1232 case IQ2000_OPERAND_MASKQ10 : 1233 fields->f_maskq10 = value; 1234 break; 1235 case IQ2000_OPERAND_MASKR : 1236 fields->f_rs = value; 1237 break; 1238 case IQ2000_OPERAND_MLO16 : 1239 fields->f_imm = value; 1240 break; 1241 case IQ2000_OPERAND_OFFSET : 1242 fields->f_offset = value; 1243 break; 1244 case IQ2000_OPERAND_RD : 1245 fields->f_rd = value; 1246 break; 1247 case IQ2000_OPERAND_RD_RS : 1248 fields->f_rd_rs = value; 1249 break; 1250 case IQ2000_OPERAND_RD_RT : 1251 fields->f_rd_rt = value; 1252 break; 1253 case IQ2000_OPERAND_RS : 1254 fields->f_rs = value; 1255 break; 1256 case IQ2000_OPERAND_RT : 1257 fields->f_rt = value; 1258 break; 1259 case IQ2000_OPERAND_RT_RS : 1260 fields->f_rt_rs = value; 1261 break; 1262 case IQ2000_OPERAND_SHAMT : 1263 fields->f_shamt = value; 1264 break; 1265 1266 default : 1267 /* xgettext:c-format */ 1268 opcodes_error_handler 1269 (_("internal error: unrecognized field %d while setting int operand"), 1270 opindex); 1271 abort (); 1272 } 1273 } 1274 1275 void 1276 iq2000_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 1277 int opindex, 1278 CGEN_FIELDS * fields, 1279 bfd_vma value) 1280 { 1281 switch (opindex) 1282 { 1283 case IQ2000_OPERAND__INDEX : 1284 fields->f_index = value; 1285 break; 1286 case IQ2000_OPERAND_BASE : 1287 fields->f_rs = value; 1288 break; 1289 case IQ2000_OPERAND_BASEOFF : 1290 fields->f_imm = value; 1291 break; 1292 case IQ2000_OPERAND_BITNUM : 1293 fields->f_rt = value; 1294 break; 1295 case IQ2000_OPERAND_BYTECOUNT : 1296 fields->f_bytecount = value; 1297 break; 1298 case IQ2000_OPERAND_CAM_Y : 1299 fields->f_cam_y = value; 1300 break; 1301 case IQ2000_OPERAND_CAM_Z : 1302 fields->f_cam_z = value; 1303 break; 1304 case IQ2000_OPERAND_CM_3FUNC : 1305 fields->f_cm_3func = value; 1306 break; 1307 case IQ2000_OPERAND_CM_3Z : 1308 fields->f_cm_3z = value; 1309 break; 1310 case IQ2000_OPERAND_CM_4FUNC : 1311 fields->f_cm_4func = value; 1312 break; 1313 case IQ2000_OPERAND_CM_4Z : 1314 fields->f_cm_4z = value; 1315 break; 1316 case IQ2000_OPERAND_COUNT : 1317 fields->f_count = value; 1318 break; 1319 case IQ2000_OPERAND_EXECODE : 1320 fields->f_excode = value; 1321 break; 1322 case IQ2000_OPERAND_HI16 : 1323 fields->f_imm = value; 1324 break; 1325 case IQ2000_OPERAND_IMM : 1326 fields->f_imm = value; 1327 break; 1328 case IQ2000_OPERAND_JMPTARG : 1329 fields->f_jtarg = value; 1330 break; 1331 case IQ2000_OPERAND_JMPTARGQ10 : 1332 fields->f_jtargq10 = value; 1333 break; 1334 case IQ2000_OPERAND_LO16 : 1335 fields->f_imm = value; 1336 break; 1337 case IQ2000_OPERAND_MASK : 1338 fields->f_mask = value; 1339 break; 1340 case IQ2000_OPERAND_MASKL : 1341 fields->f_maskl = value; 1342 break; 1343 case IQ2000_OPERAND_MASKQ10 : 1344 fields->f_maskq10 = value; 1345 break; 1346 case IQ2000_OPERAND_MASKR : 1347 fields->f_rs = value; 1348 break; 1349 case IQ2000_OPERAND_MLO16 : 1350 fields->f_imm = value; 1351 break; 1352 case IQ2000_OPERAND_OFFSET : 1353 fields->f_offset = value; 1354 break; 1355 case IQ2000_OPERAND_RD : 1356 fields->f_rd = value; 1357 break; 1358 case IQ2000_OPERAND_RD_RS : 1359 fields->f_rd_rs = value; 1360 break; 1361 case IQ2000_OPERAND_RD_RT : 1362 fields->f_rd_rt = value; 1363 break; 1364 case IQ2000_OPERAND_RS : 1365 fields->f_rs = value; 1366 break; 1367 case IQ2000_OPERAND_RT : 1368 fields->f_rt = value; 1369 break; 1370 case IQ2000_OPERAND_RT_RS : 1371 fields->f_rt_rs = value; 1372 break; 1373 case IQ2000_OPERAND_SHAMT : 1374 fields->f_shamt = value; 1375 break; 1376 1377 default : 1378 /* xgettext:c-format */ 1379 opcodes_error_handler 1380 (_("internal error: unrecognized field %d while setting vma operand"), 1381 opindex); 1382 abort (); 1383 } 1384 } 1385 1386 /* Function to call before using the instruction builder tables. */ 1387 1388 void 1389 iq2000_cgen_init_ibld_table (CGEN_CPU_DESC cd) 1390 { 1391 cd->insert_handlers = & iq2000_cgen_insert_handlers[0]; 1392 cd->extract_handlers = & iq2000_cgen_extract_handlers[0]; 1393 1394 cd->insert_operand = iq2000_cgen_insert_operand; 1395 cd->extract_operand = iq2000_cgen_extract_operand; 1396 1397 cd->get_int_operand = iq2000_cgen_get_int_operand; 1398 cd->set_int_operand = iq2000_cgen_set_int_operand; 1399 cd->get_vma_operand = iq2000_cgen_get_vma_operand; 1400 cd->set_vma_operand = iq2000_cgen_set_vma_operand; 1401 } 1402