1 /* tc-mn10200.c -- Assembler code for the Matsushita 10200 2 Copyright (C) 1996-2014 Free Software Foundation, Inc. 3 4 This file is part of GAS, the GNU Assembler. 5 6 GAS 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 GAS is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GAS; see the file COPYING. If not, write to 18 the Free Software Foundation, 51 Franklin Street - Fifth Floor, 19 Boston, MA 02110-1301, USA. */ 20 21 #include "as.h" 22 #include "safe-ctype.h" 23 #include "subsegs.h" 24 #include "opcode/mn10200.h" 25 26 /* Structure to hold information about predefined registers. */ 28 struct reg_name 29 { 30 const char *name; 31 int value; 32 }; 33 34 /* Generic assembler global variables which must be defined by all 35 targets. */ 36 37 /* Characters which always start a comment. */ 38 const char comment_chars[] = "#"; 39 40 /* Characters which start a comment at the beginning of a line. */ 41 const char line_comment_chars[] = ";#"; 42 43 /* Characters which may be used to separate multiple commands on a 44 single line. */ 45 const char line_separator_chars[] = ";"; 46 47 /* Characters which are used to indicate an exponent in a floating 48 point number. */ 49 const char EXP_CHARS[] = "eE"; 50 51 /* Characters which mean that a number is a floating point constant, 52 as in 0d1.0. */ 53 const char FLT_CHARS[] = "dD"; 54 55 const relax_typeS md_relax_table[] = 57 { 58 /* bCC relaxing */ 59 {0x81, -0x7e, 2, 1}, 60 {0x8004, -0x7ffb, 5, 2}, 61 {0x800006, -0x7ffff9, 7, 0}, 62 /* bCCx relaxing */ 63 {0x81, -0x7e, 3, 4}, 64 {0x8004, -0x7ffb, 6, 5}, 65 {0x800006, -0x7ffff9, 8, 0}, 66 /* jsr relaxing */ 67 {0x8004, -0x7ffb, 3, 7}, 68 {0x800006, -0x7ffff9, 5, 0}, 69 /* jmp relaxing */ 70 {0x81, -0x7e, 2, 9}, 71 {0x8004, -0x7ffb, 3, 10}, 72 {0x800006, -0x7ffff9, 5, 0}, 73 74 }; 75 76 77 /* Fixups. */ 78 #define MAX_INSN_FIXUPS 5 79 80 struct mn10200_fixup 81 { 82 expressionS exp; 83 int opindex; 84 bfd_reloc_code_real_type reloc; 85 }; 86 87 struct mn10200_fixup fixups[MAX_INSN_FIXUPS]; 88 static int fc; 89 90 const char *md_shortopts = ""; 92 93 struct option md_longopts[] = 94 { 95 {NULL, no_argument, NULL, 0} 96 }; 97 98 size_t md_longopts_size = sizeof (md_longopts); 99 100 /* The target specific pseudo-ops which we support. */ 101 const pseudo_typeS md_pseudo_table[] = 102 { 103 { NULL, NULL, 0 } 104 }; 105 106 /* Opcode hash table. */ 107 static struct hash_control *mn10200_hash; 108 109 /* This table is sorted. Suitable for searching by a binary search. */ 110 static const struct reg_name data_registers[] = 111 { 112 { "d0", 0 }, 113 { "d1", 1 }, 114 { "d2", 2 }, 115 { "d3", 3 }, 116 }; 117 #define DATA_REG_NAME_CNT \ 118 (sizeof (data_registers) / sizeof (struct reg_name)) 119 120 static const struct reg_name address_registers[] = 121 { 122 { "a0", 0 }, 123 { "a1", 1 }, 124 { "a2", 2 }, 125 { "a3", 3 }, 126 }; 127 #define ADDRESS_REG_NAME_CNT \ 128 (sizeof (address_registers) / sizeof (struct reg_name)) 129 130 static const struct reg_name other_registers[] = 131 { 132 { "mdr", 0 }, 133 { "psw", 0 }, 134 }; 135 #define OTHER_REG_NAME_CNT \ 136 (sizeof (other_registers) / sizeof (struct reg_name)) 137 138 /* reg_name_search does a binary search of the given register table 139 to see if "name" is a valid regiter name. Returns the register 140 number from the array on success, or -1 on failure. */ 141 142 static int 143 reg_name_search (const struct reg_name *regs, 144 int regcount, 145 const char *name) 146 { 147 int middle, low, high; 148 int cmp; 149 150 low = 0; 151 high = regcount - 1; 152 153 do 154 { 155 middle = (low + high) / 2; 156 cmp = strcasecmp (name, regs[middle].name); 157 if (cmp < 0) 158 high = middle - 1; 159 else if (cmp > 0) 160 low = middle + 1; 161 else 162 return regs[middle].value; 163 } 164 while (low <= high); 165 return -1; 166 } 167 168 /* Summary of register_name(). 169 170 in: Input_line_pointer points to 1st char of operand. 171 172 out: An expressionS. 173 The operand may have been a register: in this case, X_op == O_register, 174 X_add_number is set to the register number, and truth is returned. 175 Input_line_pointer->(next non-blank) char after operand, or is in 176 its original state. */ 177 178 static bfd_boolean 179 data_register_name (expressionS *expressionP) 180 { 181 int reg_number; 182 char *name; 183 char *start; 184 char c; 185 186 /* Find the spelling of the operand. */ 187 start = name = input_line_pointer; 188 189 c = get_symbol_end (); 190 reg_number = reg_name_search (data_registers, DATA_REG_NAME_CNT, name); 191 192 /* Put back the delimiting char. */ 193 *input_line_pointer = c; 194 195 /* Look to see if it's in the register table. */ 196 if (reg_number >= 0) 197 { 198 expressionP->X_op = O_register; 199 expressionP->X_add_number = reg_number; 200 201 /* Make the rest nice. */ 202 expressionP->X_add_symbol = NULL; 203 expressionP->X_op_symbol = NULL; 204 205 return TRUE; 206 } 207 208 /* Reset the line as if we had not done anything. */ 209 input_line_pointer = start; 210 return FALSE; 211 } 212 213 /* Summary of register_name(). 214 215 in: Input_line_pointer points to 1st char of operand. 216 217 out: An expressionS. 218 The operand may have been a register: in this case, X_op == O_register, 219 X_add_number is set to the register number, and truth is returned. 220 Input_line_pointer->(next non-blank) char after operand, or is in 221 its original state. */ 222 223 static bfd_boolean 224 address_register_name (expressionS *expressionP) 225 { 226 int reg_number; 227 char *name; 228 char *start; 229 char c; 230 231 /* Find the spelling of the operand. */ 232 start = name = input_line_pointer; 233 234 c = get_symbol_end (); 235 reg_number = reg_name_search (address_registers, ADDRESS_REG_NAME_CNT, name); 236 237 /* Put back the delimiting char. */ 238 *input_line_pointer = c; 239 240 /* Look to see if it's in the register table. */ 241 if (reg_number >= 0) 242 { 243 expressionP->X_op = O_register; 244 expressionP->X_add_number = reg_number; 245 246 /* Make the rest nice. */ 247 expressionP->X_add_symbol = NULL; 248 expressionP->X_op_symbol = NULL; 249 250 return TRUE; 251 } 252 253 /* Reset the line as if we had not done anything. */ 254 input_line_pointer = start; 255 return FALSE; 256 } 257 258 /* Summary of register_name(). 259 260 in: Input_line_pointer points to 1st char of operand. 261 262 out: An expressionS. 263 The operand may have been a register: in this case, X_op == O_register, 264 X_add_number is set to the register number, and truth is returned. 265 Input_line_pointer->(next non-blank) char after operand, or is in 266 its original state. */ 267 268 static bfd_boolean 269 other_register_name (expressionS *expressionP) 270 { 271 int reg_number; 272 char *name; 273 char *start; 274 char c; 275 276 /* Find the spelling of the operand. */ 277 start = name = input_line_pointer; 278 279 c = get_symbol_end (); 280 reg_number = reg_name_search (other_registers, OTHER_REG_NAME_CNT, name); 281 282 /* Put back the delimiting char. */ 283 *input_line_pointer = c; 284 285 /* Look to see if it's in the register table. */ 286 if (reg_number >= 0) 287 { 288 expressionP->X_op = O_register; 289 expressionP->X_add_number = reg_number; 290 291 /* Make the rest nice. */ 292 expressionP->X_add_symbol = NULL; 293 expressionP->X_op_symbol = NULL; 294 295 return TRUE; 296 } 297 298 /* Reset the line as if we had not done anything. */ 299 input_line_pointer = start; 300 return FALSE; 301 } 302 303 void 304 md_show_usage (FILE *stream) 305 { 306 fprintf (stream, _("MN10200 options:\n\ 307 none yet\n")); 308 } 309 310 int 311 md_parse_option (int c ATTRIBUTE_UNUSED, 312 char *arg ATTRIBUTE_UNUSED) 313 { 314 return 0; 315 } 316 317 symbolS * 318 md_undefined_symbol (char *name ATTRIBUTE_UNUSED) 319 { 320 return 0; 321 } 322 323 char * 324 md_atof (int type, char *litp, int *sizep) 325 { 326 return ieee_md_atof (type, litp, sizep, FALSE); 327 } 328 329 void 330 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, 331 asection *sec, 332 fragS *fragP) 333 { 334 static unsigned long label_count = 0; 335 char buf[40]; 336 337 subseg_change (sec, 0); 338 if (fragP->fr_subtype == 0) 339 { 340 fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol, 341 fragP->fr_offset, 1, BFD_RELOC_8_PCREL); 342 fragP->fr_var = 0; 343 fragP->fr_fix += 2; 344 } 345 else if (fragP->fr_subtype == 1) 346 { 347 /* Reverse the condition of the first branch. */ 348 int offset = fragP->fr_fix; 349 int opcode = fragP->fr_literal[offset] & 0xff; 350 351 switch (opcode) 352 { 353 case 0xe8: 354 opcode = 0xe9; 355 break; 356 case 0xe9: 357 opcode = 0xe8; 358 break; 359 case 0xe0: 360 opcode = 0xe2; 361 break; 362 case 0xe2: 363 opcode = 0xe0; 364 break; 365 case 0xe3: 366 opcode = 0xe1; 367 break; 368 case 0xe1: 369 opcode = 0xe3; 370 break; 371 case 0xe4: 372 opcode = 0xe6; 373 break; 374 case 0xe6: 375 opcode = 0xe4; 376 break; 377 case 0xe7: 378 opcode = 0xe5; 379 break; 380 case 0xe5: 381 opcode = 0xe7; 382 break; 383 default: 384 abort (); 385 } 386 fragP->fr_literal[offset] = opcode; 387 388 /* Create a fixup for the reversed conditional branch. */ 389 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++); 390 fix_new (fragP, fragP->fr_fix + 1, 1, 391 symbol_new (buf, sec, 0, fragP->fr_next), 392 fragP->fr_offset, 1, BFD_RELOC_8_PCREL); 393 394 /* Now create the unconditional branch + fixup to the 395 final target. */ 396 fragP->fr_literal[offset + 2] = 0xfc; 397 fix_new (fragP, fragP->fr_fix + 3, 2, fragP->fr_symbol, 398 fragP->fr_offset, 1, BFD_RELOC_16_PCREL); 399 fragP->fr_var = 0; 400 fragP->fr_fix += 5; 401 } 402 else if (fragP->fr_subtype == 2) 403 { 404 /* Reverse the condition of the first branch. */ 405 int offset = fragP->fr_fix; 406 int opcode = fragP->fr_literal[offset] & 0xff; 407 408 switch (opcode) 409 { 410 case 0xe8: 411 opcode = 0xe9; 412 break; 413 case 0xe9: 414 opcode = 0xe8; 415 break; 416 case 0xe0: 417 opcode = 0xe2; 418 break; 419 case 0xe2: 420 opcode = 0xe0; 421 break; 422 case 0xe3: 423 opcode = 0xe1; 424 break; 425 case 0xe1: 426 opcode = 0xe3; 427 break; 428 case 0xe4: 429 opcode = 0xe6; 430 break; 431 case 0xe6: 432 opcode = 0xe4; 433 break; 434 case 0xe7: 435 opcode = 0xe5; 436 break; 437 case 0xe5: 438 opcode = 0xe7; 439 break; 440 default: 441 abort (); 442 } 443 fragP->fr_literal[offset] = opcode; 444 445 /* Create a fixup for the reversed conditional branch. */ 446 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++); 447 fix_new (fragP, fragP->fr_fix + 1, 1, 448 symbol_new (buf, sec, 0, fragP->fr_next), 449 fragP->fr_offset, 1, BFD_RELOC_8_PCREL); 450 451 /* Now create the unconditional branch + fixup to the 452 final target. */ 453 fragP->fr_literal[offset + 2] = 0xf4; 454 fragP->fr_literal[offset + 3] = 0xe0; 455 fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol, 456 fragP->fr_offset, 1, BFD_RELOC_24_PCREL); 457 fragP->fr_var = 0; 458 fragP->fr_fix += 7; 459 } 460 else if (fragP->fr_subtype == 3) 461 { 462 fix_new (fragP, fragP->fr_fix + 2, 1, fragP->fr_symbol, 463 fragP->fr_offset, 1, BFD_RELOC_8_PCREL); 464 fragP->fr_var = 0; 465 fragP->fr_fix += 3; 466 } 467 else if (fragP->fr_subtype == 4) 468 { 469 /* Reverse the condition of the first branch. */ 470 int offset = fragP->fr_fix; 471 int opcode = fragP->fr_literal[offset + 1] & 0xff; 472 473 switch (opcode) 474 { 475 case 0xfc: 476 opcode = 0xfd; 477 break; 478 case 0xfd: 479 opcode = 0xfc; 480 break; 481 case 0xfe: 482 opcode = 0xff; 483 break; 484 case 0xff: 485 opcode = 0xfe; 486 break; 487 case 0xe8: 488 opcode = 0xe9; 489 break; 490 case 0xe9: 491 opcode = 0xe8; 492 break; 493 case 0xe0: 494 opcode = 0xe2; 495 break; 496 case 0xe2: 497 opcode = 0xe0; 498 break; 499 case 0xe3: 500 opcode = 0xe1; 501 break; 502 case 0xe1: 503 opcode = 0xe3; 504 break; 505 case 0xe4: 506 opcode = 0xe6; 507 break; 508 case 0xe6: 509 opcode = 0xe4; 510 break; 511 case 0xe7: 512 opcode = 0xe5; 513 break; 514 case 0xe5: 515 opcode = 0xe7; 516 break; 517 case 0xec: 518 opcode = 0xed; 519 break; 520 case 0xed: 521 opcode = 0xec; 522 break; 523 case 0xee: 524 opcode = 0xef; 525 break; 526 case 0xef: 527 opcode = 0xee; 528 break; 529 default: 530 abort (); 531 } 532 fragP->fr_literal[offset + 1] = opcode; 533 534 /* Create a fixup for the reversed conditional branch. */ 535 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++); 536 fix_new (fragP, fragP->fr_fix + 2, 1, 537 symbol_new (buf, sec, 0, fragP->fr_next), 538 fragP->fr_offset, 1, BFD_RELOC_8_PCREL); 539 540 /* Now create the unconditional branch + fixup to the 541 final target. */ 542 fragP->fr_literal[offset + 3] = 0xfc; 543 fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol, 544 fragP->fr_offset, 1, BFD_RELOC_16_PCREL); 545 fragP->fr_var = 0; 546 fragP->fr_fix += 6; 547 } 548 else if (fragP->fr_subtype == 5) 549 { 550 /* Reverse the condition of the first branch. */ 551 int offset = fragP->fr_fix; 552 int opcode = fragP->fr_literal[offset + 1] & 0xff; 553 554 switch (opcode) 555 { 556 case 0xfc: 557 opcode = 0xfd; 558 break; 559 case 0xfd: 560 opcode = 0xfc; 561 break; 562 case 0xfe: 563 opcode = 0xff; 564 break; 565 case 0xff: 566 opcode = 0xfe; 567 break; 568 case 0xe8: 569 opcode = 0xe9; 570 break; 571 case 0xe9: 572 opcode = 0xe8; 573 break; 574 case 0xe0: 575 opcode = 0xe2; 576 break; 577 case 0xe2: 578 opcode = 0xe0; 579 break; 580 case 0xe3: 581 opcode = 0xe1; 582 break; 583 case 0xe1: 584 opcode = 0xe3; 585 break; 586 case 0xe4: 587 opcode = 0xe6; 588 break; 589 case 0xe6: 590 opcode = 0xe4; 591 break; 592 case 0xe7: 593 opcode = 0xe5; 594 break; 595 case 0xe5: 596 opcode = 0xe7; 597 break; 598 case 0xec: 599 opcode = 0xed; 600 break; 601 case 0xed: 602 opcode = 0xec; 603 break; 604 case 0xee: 605 opcode = 0xef; 606 break; 607 case 0xef: 608 opcode = 0xee; 609 break; 610 default: 611 abort (); 612 } 613 fragP->fr_literal[offset + 1] = opcode; 614 615 /* Create a fixup for the reversed conditional branch. */ 616 sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++); 617 fix_new (fragP, fragP->fr_fix + 2, 1, 618 symbol_new (buf, sec, 0, fragP->fr_next), 619 fragP->fr_offset, 1, BFD_RELOC_8_PCREL); 620 621 /* Now create the unconditional branch + fixup to the 622 final target. */ 623 fragP->fr_literal[offset + 3] = 0xf4; 624 fragP->fr_literal[offset + 4] = 0xe0; 625 fix_new (fragP, fragP->fr_fix + 5, 4, fragP->fr_symbol, 626 fragP->fr_offset, 1, BFD_RELOC_24_PCREL); 627 fragP->fr_var = 0; 628 fragP->fr_fix += 8; 629 } 630 else if (fragP->fr_subtype == 6) 631 { 632 fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol, 633 fragP->fr_offset, 1, BFD_RELOC_16_PCREL); 634 fragP->fr_var = 0; 635 fragP->fr_fix += 3; 636 } 637 else if (fragP->fr_subtype == 7) 638 { 639 int offset = fragP->fr_fix; 640 fragP->fr_literal[offset] = 0xf4; 641 fragP->fr_literal[offset + 1] = 0xe1; 642 643 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol, 644 fragP->fr_offset, 1, BFD_RELOC_24_PCREL); 645 fragP->fr_var = 0; 646 fragP->fr_fix += 5; 647 } 648 else if (fragP->fr_subtype == 8) 649 { 650 fragP->fr_literal[fragP->fr_fix] = 0xea; 651 fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol, 652 fragP->fr_offset, 1, BFD_RELOC_8_PCREL); 653 fragP->fr_var = 0; 654 fragP->fr_fix += 2; 655 } 656 else if (fragP->fr_subtype == 9) 657 { 658 int offset = fragP->fr_fix; 659 fragP->fr_literal[offset] = 0xfc; 660 661 fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol, 662 fragP->fr_offset, 1, BFD_RELOC_16_PCREL); 663 fragP->fr_var = 0; 664 fragP->fr_fix += 3; 665 } 666 else if (fragP->fr_subtype == 10) 667 { 668 int offset = fragP->fr_fix; 669 fragP->fr_literal[offset] = 0xf4; 670 fragP->fr_literal[offset + 1] = 0xe0; 671 672 fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol, 673 fragP->fr_offset, 1, BFD_RELOC_24_PCREL); 674 fragP->fr_var = 0; 675 fragP->fr_fix += 5; 676 } 677 else 678 abort (); 679 } 680 681 valueT 682 md_section_align (asection *seg, valueT addr) 683 { 684 int align = bfd_get_section_alignment (stdoutput, seg); 685 return ((addr + (1 << align) - 1) & (-1 << align)); 686 } 687 688 void 689 md_begin (void) 690 { 691 char *prev_name = ""; 692 const struct mn10200_opcode *op; 693 694 mn10200_hash = hash_new (); 695 696 /* Insert unique names into hash table. The MN10200 instruction set 697 has many identical opcode names that have different opcodes based 698 on the operands. This hash table then provides a quick index to 699 the first opcode with a particular name in the opcode table. */ 700 701 op = mn10200_opcodes; 702 while (op->name) 703 { 704 if (strcmp (prev_name, op->name)) 705 { 706 prev_name = (char *) op->name; 707 hash_insert (mn10200_hash, op->name, (char *) op); 708 } 709 op++; 710 } 711 712 /* This is both a simplification (we don't have to write md_apply_fix) 713 and support for future optimizations (branch shortening and similar 714 stuff in the linker. */ 715 linkrelax = 1; 716 } 717 718 static unsigned long 719 check_operand (unsigned long insn ATTRIBUTE_UNUSED, 720 const struct mn10200_operand *operand, 721 offsetT val) 722 { 723 /* No need to check 24bit or 32bit operands for a bit. */ 724 if (operand->bits < 24 725 && (operand->flags & MN10200_OPERAND_NOCHECK) == 0) 726 { 727 long min, max; 728 offsetT test; 729 730 if ((operand->flags & MN10200_OPERAND_SIGNED) != 0) 731 { 732 max = (1 << (operand->bits - 1)) - 1; 733 min = - (1 << (operand->bits - 1)); 734 } 735 else 736 { 737 max = (1 << operand->bits) - 1; 738 min = 0; 739 } 740 741 test = val; 742 743 if (test < (offsetT) min || test > (offsetT) max) 744 return 0; 745 else 746 return 1; 747 } 748 return 1; 749 } 750 /* If while processing a fixup, a reloc really needs to be created 751 Then it is done here. */ 752 753 arelent * 754 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp) 755 { 756 arelent *reloc; 757 reloc = xmalloc (sizeof (arelent)); 758 759 if (fixp->fx_subsy != NULL) 760 { 761 if (S_GET_SEGMENT (fixp->fx_addsy) == S_GET_SEGMENT (fixp->fx_subsy) 762 && S_IS_DEFINED (fixp->fx_subsy)) 763 { 764 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy); 765 fixp->fx_subsy = NULL; 766 } 767 else 768 /* FIXME: We should try more ways to resolve difference expressions 769 here. At least this is better than silently ignoring the 770 subtrahend. */ 771 as_bad_where (fixp->fx_file, fixp->fx_line, 772 _("can't resolve `%s' {%s section} - `%s' {%s section}"), 773 fixp->fx_addsy ? S_GET_NAME (fixp->fx_addsy) : "0", 774 segment_name (fixp->fx_addsy 775 ? S_GET_SEGMENT (fixp->fx_addsy) 776 : absolute_section), 777 S_GET_NAME (fixp->fx_subsy), 778 segment_name (S_GET_SEGMENT (fixp->fx_addsy))); 779 } 780 781 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 782 if (reloc->howto == NULL) 783 { 784 as_bad_where (fixp->fx_file, fixp->fx_line, 785 _("reloc %d not supported by object file format"), 786 (int) fixp->fx_r_type); 787 return NULL; 788 } 789 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 790 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *)); 791 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 792 reloc->addend = fixp->fx_offset; 793 return reloc; 794 } 795 796 int 797 md_estimate_size_before_relax (fragS *fragp, asection *seg) 798 { 799 if (fragp->fr_subtype == 6 800 && (!S_IS_DEFINED (fragp->fr_symbol) 801 || seg != S_GET_SEGMENT (fragp->fr_symbol))) 802 fragp->fr_subtype = 7; 803 else if (fragp->fr_subtype == 8 804 && (!S_IS_DEFINED (fragp->fr_symbol) 805 || seg != S_GET_SEGMENT (fragp->fr_symbol))) 806 fragp->fr_subtype = 10; 807 808 if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0])) 809 abort (); 810 811 return md_relax_table[fragp->fr_subtype].rlx_length; 812 } 813 814 long 815 md_pcrel_from (fixS *fixp) 816 { 817 return fixp->fx_frag->fr_address; 818 } 819 820 void 821 md_apply_fix (fixS * fixP, valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED) 822 { 823 /* We shouldn't ever get here because linkrelax is nonzero. */ 824 abort (); 825 fixP->fx_done = 1; 826 } 827 828 /* Insert an operand value into an instruction. */ 829 830 static void 831 mn10200_insert_operand (unsigned long *insnp, 832 unsigned long *extensionp, 833 const struct mn10200_operand *operand, 834 offsetT val, 835 char *file, 836 unsigned int line, 837 unsigned int shift) 838 { 839 /* No need to check 24 or 32bit operands for a bit. */ 840 if (operand->bits < 24 841 && (operand->flags & MN10200_OPERAND_NOCHECK) == 0) 842 { 843 long min, max; 844 offsetT test; 845 846 if ((operand->flags & MN10200_OPERAND_SIGNED) != 0) 847 { 848 max = (1 << (operand->bits - 1)) - 1; 849 min = - (1 << (operand->bits - 1)); 850 } 851 else 852 { 853 max = (1 << operand->bits) - 1; 854 min = 0; 855 } 856 857 test = val; 858 859 if (test < (offsetT) min || test > (offsetT) max) 860 as_warn_value_out_of_range (_("operand"), test, (offsetT) min, (offsetT) max, file, line); 861 } 862 863 if ((operand->flags & MN10200_OPERAND_EXTENDED) == 0) 864 { 865 *insnp |= (((long) val & ((1 << operand->bits) - 1)) 866 << (operand->shift + shift)); 867 868 if ((operand->flags & MN10200_OPERAND_REPEATED) != 0) 869 *insnp |= (((long) val & ((1 << operand->bits) - 1)) 870 << (operand->shift + shift + 2)); 871 } 872 else 873 { 874 *extensionp |= (val >> 16) & 0xff; 875 *insnp |= val & 0xffff; 876 } 877 } 878 879 void 880 md_assemble (char *str) 881 { 882 char *s; 883 struct mn10200_opcode *opcode; 884 struct mn10200_opcode *next_opcode; 885 const unsigned char *opindex_ptr; 886 int next_opindex, relaxable; 887 unsigned long insn, extension, size = 0; 888 char *f; 889 int i; 890 int match; 891 892 /* Get the opcode. */ 893 for (s = str; *s != '\0' && !ISSPACE (*s); s++) 894 ; 895 if (*s != '\0') 896 *s++ = '\0'; 897 898 /* Find the first opcode with the proper name. */ 899 opcode = (struct mn10200_opcode *) hash_find (mn10200_hash, str); 900 if (opcode == NULL) 901 { 902 as_bad (_("Unrecognized opcode: `%s'"), str); 903 return; 904 } 905 906 str = s; 907 while (ISSPACE (*str)) 908 ++str; 909 910 input_line_pointer = str; 911 912 for (;;) 913 { 914 const char *errmsg = NULL; 915 int op_idx; 916 char *hold; 917 int extra_shift = 0; 918 919 relaxable = 0; 920 fc = 0; 921 match = 0; 922 next_opindex = 0; 923 insn = opcode->opcode; 924 extension = 0; 925 for (op_idx = 1, opindex_ptr = opcode->operands; 926 *opindex_ptr != 0; 927 opindex_ptr++, op_idx++) 928 { 929 const struct mn10200_operand *operand; 930 expressionS ex; 931 932 if (next_opindex == 0) 933 { 934 operand = &mn10200_operands[*opindex_ptr]; 935 } 936 else 937 { 938 operand = &mn10200_operands[next_opindex]; 939 next_opindex = 0; 940 } 941 942 errmsg = NULL; 943 944 while (*str == ' ' || *str == ',') 945 ++str; 946 947 if (operand->flags & MN10200_OPERAND_RELAX) 948 relaxable = 1; 949 950 /* Gather the operand. */ 951 hold = input_line_pointer; 952 input_line_pointer = str; 953 954 if (operand->flags & MN10200_OPERAND_PAREN) 955 { 956 if (*input_line_pointer != ')' && *input_line_pointer != '(') 957 { 958 input_line_pointer = hold; 959 str = hold; 960 goto error; 961 } 962 input_line_pointer++; 963 goto keep_going; 964 } 965 /* See if we can match the operands. */ 966 else if (operand->flags & MN10200_OPERAND_DREG) 967 { 968 if (!data_register_name (&ex)) 969 { 970 input_line_pointer = hold; 971 str = hold; 972 goto error; 973 } 974 } 975 else if (operand->flags & MN10200_OPERAND_AREG) 976 { 977 if (!address_register_name (&ex)) 978 { 979 input_line_pointer = hold; 980 str = hold; 981 goto error; 982 } 983 } 984 else if (operand->flags & MN10200_OPERAND_PSW) 985 { 986 char *start = input_line_pointer; 987 char c = get_symbol_end (); 988 989 if (strcmp (start, "psw") != 0) 990 { 991 *input_line_pointer = c; 992 input_line_pointer = hold; 993 str = hold; 994 goto error; 995 } 996 *input_line_pointer = c; 997 goto keep_going; 998 } 999 else if (operand->flags & MN10200_OPERAND_MDR) 1000 { 1001 char *start = input_line_pointer; 1002 char c = get_symbol_end (); 1003 1004 if (strcmp (start, "mdr") != 0) 1005 { 1006 *input_line_pointer = c; 1007 input_line_pointer = hold; 1008 str = hold; 1009 goto error; 1010 } 1011 *input_line_pointer = c; 1012 goto keep_going; 1013 } 1014 else if (data_register_name (&ex)) 1015 { 1016 input_line_pointer = hold; 1017 str = hold; 1018 goto error; 1019 } 1020 else if (address_register_name (&ex)) 1021 { 1022 input_line_pointer = hold; 1023 str = hold; 1024 goto error; 1025 } 1026 else if (other_register_name (&ex)) 1027 { 1028 input_line_pointer = hold; 1029 str = hold; 1030 goto error; 1031 } 1032 else if (*str == ')' || *str == '(') 1033 { 1034 input_line_pointer = hold; 1035 str = hold; 1036 goto error; 1037 } 1038 else 1039 { 1040 expression (&ex); 1041 } 1042 1043 switch (ex.X_op) 1044 { 1045 case O_illegal: 1046 errmsg = _("illegal operand"); 1047 goto error; 1048 case O_absent: 1049 errmsg = _("missing operand"); 1050 goto error; 1051 case O_register: 1052 if ((operand->flags 1053 & (MN10200_OPERAND_DREG | MN10200_OPERAND_AREG)) == 0) 1054 { 1055 input_line_pointer = hold; 1056 str = hold; 1057 goto error; 1058 } 1059 1060 if (opcode->format == FMT_2 || opcode->format == FMT_5) 1061 extra_shift = 8; 1062 else if (opcode->format == FMT_3 || opcode->format == FMT_6 1063 || opcode->format == FMT_7) 1064 extra_shift = 16; 1065 else 1066 extra_shift = 0; 1067 1068 mn10200_insert_operand (&insn, &extension, operand, 1069 ex.X_add_number, NULL, 1070 0, extra_shift); 1071 1072 break; 1073 1074 case O_constant: 1075 /* If this operand can be promoted, and it doesn't 1076 fit into the allocated bitfield for this insn, 1077 then promote it (ie this opcode does not match). */ 1078 if (operand->flags 1079 & (MN10200_OPERAND_PROMOTE | MN10200_OPERAND_RELAX) 1080 && !check_operand (insn, operand, ex.X_add_number)) 1081 { 1082 input_line_pointer = hold; 1083 str = hold; 1084 goto error; 1085 } 1086 1087 mn10200_insert_operand (&insn, &extension, operand, 1088 ex.X_add_number, NULL, 1089 0, 0); 1090 break; 1091 1092 default: 1093 /* If this operand can be promoted, then this opcode didn't 1094 match since we can't know if it needed promotion! */ 1095 if (operand->flags & MN10200_OPERAND_PROMOTE) 1096 { 1097 input_line_pointer = hold; 1098 str = hold; 1099 goto error; 1100 } 1101 1102 /* We need to generate a fixup for this expression. */ 1103 if (fc >= MAX_INSN_FIXUPS) 1104 as_fatal (_("too many fixups")); 1105 fixups[fc].exp = ex; 1106 fixups[fc].opindex = *opindex_ptr; 1107 fixups[fc].reloc = BFD_RELOC_UNUSED; 1108 ++fc; 1109 break; 1110 } 1111 1112 keep_going: 1113 str = input_line_pointer; 1114 input_line_pointer = hold; 1115 1116 while (*str == ' ' || *str == ',') 1117 ++str; 1118 1119 } 1120 1121 /* Make sure we used all the operands! */ 1122 if (*str != ',') 1123 match = 1; 1124 1125 error: 1126 if (match == 0) 1127 { 1128 next_opcode = opcode + 1; 1129 if (!strcmp (next_opcode->name, opcode->name)) 1130 { 1131 opcode = next_opcode; 1132 continue; 1133 } 1134 1135 as_bad ("%s", errmsg); 1136 return; 1137 } 1138 break; 1139 } 1140 1141 while (ISSPACE (*str)) 1142 ++str; 1143 1144 if (*str != '\0') 1145 as_bad (_("junk at end of line: `%s'"), str); 1146 1147 input_line_pointer = str; 1148 1149 if (opcode->format == FMT_1) 1150 size = 1; 1151 else if (opcode->format == FMT_2 || opcode->format == FMT_4) 1152 size = 2; 1153 else if (opcode->format == FMT_3 || opcode->format == FMT_5) 1154 size = 3; 1155 else if (opcode->format == FMT_6) 1156 size = 4; 1157 else if (opcode->format == FMT_7) 1158 size = 5; 1159 else 1160 abort (); 1161 1162 /* Write out the instruction. */ 1163 dwarf2_emit_insn (0); 1164 if (relaxable && fc > 0) 1165 { 1166 /* On a 64-bit host the size of an 'int' is not the same 1167 as the size of a pointer, so we need a union to convert 1168 the opindex field of the fr_cgen structure into a char * 1169 so that it can be stored in the frag. We do not have 1170 to worry about loosing accuracy as we are not going to 1171 be even close to the 32bit limit of the int. */ 1172 union 1173 { 1174 int opindex; 1175 char * ptr; 1176 } 1177 opindex_converter; 1178 int type; 1179 1180 /* bCC */ 1181 if (size == 2 && opcode->opcode != 0xfc0000) 1182 { 1183 /* Handle bra specially. Basically treat it like jmp so 1184 that we automatically handle 8, 16 and 32 bit offsets 1185 correctly as well as jumps to an undefined address. 1186 1187 It is also important to not treat it like other bCC 1188 instructions since the long forms of bra is different 1189 from other bCC instructions. */ 1190 if (opcode->opcode == 0xea00) 1191 type = 8; 1192 else 1193 type = 0; 1194 } 1195 /* jsr */ 1196 else if (size == 3 && opcode->opcode == 0xfd0000) 1197 type = 6; 1198 /* jmp */ 1199 else if (size == 3 && opcode->opcode == 0xfc0000) 1200 type = 8; 1201 /* bCCx */ 1202 else 1203 type = 3; 1204 1205 opindex_converter.opindex = fixups[0].opindex; 1206 f = frag_var (rs_machine_dependent, 8, 8 - size, type, 1207 fixups[0].exp.X_add_symbol, 1208 fixups[0].exp.X_add_number, 1209 opindex_converter.ptr); 1210 number_to_chars_bigendian (f, insn, size); 1211 if (8 - size > 4) 1212 { 1213 number_to_chars_bigendian (f + size, 0, 4); 1214 number_to_chars_bigendian (f + size + 4, 0, 8 - size - 4); 1215 } 1216 else 1217 number_to_chars_bigendian (f + size, 0, 8 - size); 1218 } 1219 else 1220 { 1221 f = frag_more (size); 1222 1223 /* Oh, what a mess. The instruction is in big endian format, but 1224 16 and 24bit immediates are little endian! */ 1225 if (opcode->format == FMT_3) 1226 { 1227 number_to_chars_bigendian (f, (insn >> 16) & 0xff, 1); 1228 number_to_chars_littleendian (f + 1, insn & 0xffff, 2); 1229 } 1230 else if (opcode->format == FMT_6) 1231 { 1232 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2); 1233 number_to_chars_littleendian (f + 2, insn & 0xffff, 2); 1234 } 1235 else if (opcode->format == FMT_7) 1236 { 1237 number_to_chars_bigendian (f, (insn >> 16) & 0xffff, 2); 1238 number_to_chars_littleendian (f + 2, insn & 0xffff, 2); 1239 number_to_chars_littleendian (f + 4, extension & 0xff, 1); 1240 } 1241 else 1242 number_to_chars_bigendian (f, insn, size > 4 ? 4 : size); 1243 1244 /* Create any fixups. */ 1245 for (i = 0; i < fc; i++) 1246 { 1247 const struct mn10200_operand *operand; 1248 int reloc_size; 1249 1250 operand = &mn10200_operands[fixups[i].opindex]; 1251 if (fixups[i].reloc != BFD_RELOC_UNUSED) 1252 { 1253 reloc_howto_type *reloc_howto; 1254 int offset; 1255 fixS *fixP; 1256 1257 reloc_howto = bfd_reloc_type_lookup (stdoutput, 1258 fixups[i].reloc); 1259 1260 if (!reloc_howto) 1261 abort (); 1262 1263 reloc_size = bfd_get_reloc_size (reloc_howto); 1264 1265 if (reloc_size < 1 || reloc_size > 4) 1266 abort (); 1267 1268 offset = 4 - reloc_size; 1269 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset, 1270 reloc_size, 1271 &fixups[i].exp, 1272 reloc_howto->pc_relative, 1273 fixups[i].reloc); 1274 1275 /* PC-relative offsets are from the first byte of the 1276 next instruction, not from the start of the current 1277 instruction. */ 1278 if (reloc_howto->pc_relative) 1279 fixP->fx_offset += reloc_size; 1280 } 1281 else 1282 { 1283 int reloc, pcrel, offset; 1284 fixS *fixP; 1285 1286 reloc = BFD_RELOC_NONE; 1287 /* How big is the reloc? Remember SPLIT relocs are 1288 implicitly 32bits. */ 1289 reloc_size = operand->bits; 1290 1291 offset = size - reloc_size / 8; 1292 1293 /* Is the reloc pc-relative? */ 1294 pcrel = (operand->flags & MN10200_OPERAND_PCREL) != 0; 1295 1296 /* Choose a proper BFD relocation type. */ 1297 if (pcrel) 1298 { 1299 if (reloc_size == 8) 1300 reloc = BFD_RELOC_8_PCREL; 1301 else if (reloc_size == 24) 1302 reloc = BFD_RELOC_24_PCREL; 1303 else 1304 abort (); 1305 } 1306 else 1307 { 1308 if (reloc_size == 32) 1309 reloc = BFD_RELOC_32; 1310 else if (reloc_size == 16) 1311 reloc = BFD_RELOC_16; 1312 else if (reloc_size == 8) 1313 reloc = BFD_RELOC_8; 1314 else if (reloc_size == 24) 1315 reloc = BFD_RELOC_24; 1316 else 1317 abort (); 1318 } 1319 1320 /* Convert the size of the reloc into what fix_new_exp 1321 wants. */ 1322 reloc_size = reloc_size / 8; 1323 if (reloc_size == 8) 1324 reloc_size = 0; 1325 else if (reloc_size == 16) 1326 reloc_size = 1; 1327 else if (reloc_size == 32 || reloc_size == 24) 1328 reloc_size = 2; 1329 1330 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset, 1331 reloc_size, &fixups[i].exp, pcrel, 1332 ((bfd_reloc_code_real_type) reloc)); 1333 1334 /* PC-relative offsets are from the first byte of the 1335 next instruction, not from the start of the current 1336 instruction. */ 1337 if (pcrel) 1338 fixP->fx_offset += size; 1339 } 1340 } 1341 } 1342 } 1343 1344