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