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