1 /* tc-rx.c -- Assembler for the Renesas RX 2 Copyright 2008, 2009, 2010, 2011 3 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 the Free 19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 20 02110-1301, USA. */ 21 22 #include "as.h" 23 #include "struc-symbol.h" 24 #include "obstack.h" 25 #include "safe-ctype.h" 26 #include "dwarf2dbg.h" 27 #include "libbfd.h" 28 #include "elf/common.h" 29 #include "elf/rx.h" 30 #include "rx-defs.h" 31 #include "filenames.h" 32 #include "listing.h" 33 #include "sb.h" 34 #include "macro.h" 35 36 #define RX_OPCODE_BIG_ENDIAN 0 37 38 const char comment_chars[] = ";"; 39 /* Note that input_file.c hand checks for '#' at the beginning of the 40 first line of the input file. This is because the compiler outputs 41 #NO_APP at the beginning of its output. */ 42 const char line_comment_chars[] = "#"; 43 const char line_separator_chars[] = "!"; 44 45 const char EXP_CHARS[] = "eE"; 46 const char FLT_CHARS[] = "dD"; 47 48 /* ELF flags to set in the output file header. */ 49 static int elf_flags = 0; 50 51 bfd_boolean rx_use_conventional_section_names = FALSE; 52 static bfd_boolean rx_use_small_data_limit = FALSE; 53 54 static bfd_boolean rx_pid_mode = FALSE; 55 static int rx_num_int_regs = 0; 56 int rx_pid_register; 57 int rx_gp_register; 58 59 static void rx_fetchalign (int ignore ATTRIBUTE_UNUSED); 60 61 enum options 62 { 63 OPTION_BIG = OPTION_MD_BASE, 64 OPTION_LITTLE, 65 OPTION_32BIT_DOUBLES, 66 OPTION_64BIT_DOUBLES, 67 OPTION_CONVENTIONAL_SECTION_NAMES, 68 OPTION_RENESAS_SECTION_NAMES, 69 OPTION_SMALL_DATA_LIMIT, 70 OPTION_RELAX, 71 OPTION_PID, 72 OPTION_INT_REGS, 73 }; 74 75 #define RX_SHORTOPTS "" 76 const char * md_shortopts = RX_SHORTOPTS; 77 78 /* Assembler options. */ 79 struct option md_longopts[] = 80 { 81 {"mbig-endian-data", no_argument, NULL, OPTION_BIG}, 82 {"mlittle-endian-data", no_argument, NULL, OPTION_LITTLE}, 83 /* The next two switches are here because the 84 generic parts of the linker testsuite uses them. */ 85 {"EB", no_argument, NULL, OPTION_BIG}, 86 {"EL", no_argument, NULL, OPTION_LITTLE}, 87 {"m32bit-doubles", no_argument, NULL, OPTION_32BIT_DOUBLES}, 88 {"m64bit-doubles", no_argument, NULL, OPTION_64BIT_DOUBLES}, 89 /* This option is here mainly for the binutils testsuites, 90 as many of their tests assume conventional section naming. */ 91 {"muse-conventional-section-names", no_argument, NULL, OPTION_CONVENTIONAL_SECTION_NAMES}, 92 {"muse-renesas-section-names", no_argument, NULL, OPTION_RENESAS_SECTION_NAMES}, 93 {"msmall-data-limit", no_argument, NULL, OPTION_SMALL_DATA_LIMIT}, 94 {"relax", no_argument, NULL, OPTION_RELAX}, 95 {"mpid", no_argument, NULL, OPTION_PID}, 96 {"mint-register", required_argument, NULL, OPTION_INT_REGS}, 97 {NULL, no_argument, NULL, 0} 98 }; 99 size_t md_longopts_size = sizeof (md_longopts); 100 101 int 102 md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED) 103 { 104 switch (c) 105 { 106 case OPTION_BIG: 107 target_big_endian = 1; 108 return 1; 109 110 case OPTION_LITTLE: 111 target_big_endian = 0; 112 return 1; 113 114 case OPTION_32BIT_DOUBLES: 115 elf_flags &= ~ E_FLAG_RX_64BIT_DOUBLES; 116 return 1; 117 118 case OPTION_64BIT_DOUBLES: 119 elf_flags |= E_FLAG_RX_64BIT_DOUBLES; 120 return 1; 121 122 case OPTION_CONVENTIONAL_SECTION_NAMES: 123 rx_use_conventional_section_names = TRUE; 124 return 1; 125 126 case OPTION_RENESAS_SECTION_NAMES: 127 rx_use_conventional_section_names = FALSE; 128 return 1; 129 130 case OPTION_SMALL_DATA_LIMIT: 131 rx_use_small_data_limit = TRUE; 132 return 1; 133 134 case OPTION_RELAX: 135 linkrelax = 1; 136 return 1; 137 138 case OPTION_PID: 139 rx_pid_mode = TRUE; 140 elf_flags |= E_FLAG_RX_PID; 141 return 1; 142 143 case OPTION_INT_REGS: 144 rx_num_int_regs = atoi (optarg); 145 return 1; 146 } 147 return 0; 148 } 149 150 void 151 md_show_usage (FILE * stream) 152 { 153 fprintf (stream, _(" RX specific command line options:\n")); 154 fprintf (stream, _(" --mbig-endian-data\n")); 155 fprintf (stream, _(" --mlittle-endian-data [default]\n")); 156 fprintf (stream, _(" --m32bit-doubles [default]\n")); 157 fprintf (stream, _(" --m64bit-doubles\n")); 158 fprintf (stream, _(" --muse-conventional-section-names\n")); 159 fprintf (stream, _(" --muse-renesas-section-names [default]\n")); 160 fprintf (stream, _(" --msmall-data-limit\n")); 161 fprintf (stream, _(" --mrelax\n")); 162 fprintf (stream, _(" --mpid\n")); 163 fprintf (stream, _(" --mint-register=<value>\n")); 164 } 165 166 static void 167 s_bss (int ignore ATTRIBUTE_UNUSED) 168 { 169 int temp; 170 171 temp = get_absolute_expression (); 172 subseg_set (bss_section, (subsegT) temp); 173 demand_empty_rest_of_line (); 174 } 175 176 static void 177 rx_float_cons (int ignore ATTRIBUTE_UNUSED) 178 { 179 if (elf_flags & E_FLAG_RX_64BIT_DOUBLES) 180 return float_cons ('d'); 181 return float_cons ('f'); 182 } 183 184 static char * 185 rx_strcasestr (const char *string, const char *sub) 186 { 187 int subl; 188 int strl; 189 190 if (!sub || !sub[0]) 191 return (char *)string; 192 193 subl = strlen (sub); 194 strl = strlen (string); 195 196 while (strl >= subl) 197 { 198 /* strncasecmp is in libiberty. */ 199 if (strncasecmp (string, sub, subl) == 0) 200 return (char *)string; 201 202 string ++; 203 strl --; 204 } 205 return NULL; 206 } 207 208 static void 209 rx_include (int ignore) 210 { 211 FILE * try; 212 char * path; 213 char * filename; 214 char * current_filename; 215 char * eof; 216 char * p; 217 char * d; 218 char * f; 219 char end_char; 220 size_t len; 221 222 /* The RX version of the .INCLUDE pseudo-op does not 223 have to have the filename inside double quotes. */ 224 SKIP_WHITESPACE (); 225 if (*input_line_pointer == '"') 226 { 227 /* Treat as the normal GAS .include pseudo-op. */ 228 s_include (ignore); 229 return; 230 } 231 232 /* Get the filename. Spaces are allowed, NUL characters are not. */ 233 filename = input_line_pointer; 234 eof = find_end_of_line (filename, FALSE); 235 input_line_pointer = eof; 236 237 while (eof >= filename && (* eof == ' ' || * eof == '\n')) 238 -- eof; 239 end_char = *(++ eof); 240 * eof = 0; 241 if (eof == filename) 242 { 243 as_bad (_("no filename following .INCLUDE pseudo-op")); 244 * eof = end_char; 245 return; 246 } 247 248 as_where (& current_filename, NULL); 249 f = (char *) xmalloc (strlen (current_filename) + strlen (filename) + 1); 250 251 /* Check the filename. If [@]..FILE[@] is found then replace 252 this with the current assembler source filename, stripped 253 of any directory prefixes or extensions. */ 254 if ((p = rx_strcasestr (filename, "..file")) != NULL) 255 { 256 char * c; 257 258 len = 6; /* strlen ("..file"); */ 259 260 if (p > filename && p[-1] == '@') 261 -- p, ++len; 262 263 if (p[len] == '@') 264 len ++; 265 266 for (d = c = current_filename; *c; c++) 267 if (IS_DIR_SEPARATOR (* c)) 268 d = c + 1; 269 for (c = d; *c; c++) 270 if (*c == '.') 271 break; 272 273 sprintf (f, "%.*s%.*s%.*s", (int) (p - filename), filename, 274 (int) (c - d), d, 275 (int) (strlen (filename) - ((p + len) - filename)), 276 p + len); 277 } 278 else 279 strcpy (f, filename); 280 281 /* RX .INCLUDE semantics say that 'filename' is located by: 282 283 1. If filename is absolute, just try that. Otherwise... 284 285 2. If the current source file includes a directory component 286 then prepend that to the filename and try. Otherwise... 287 288 3. Try any directories specified by the -I command line 289 option(s). 290 291 4 .Try a directory specifed by the INC100 environment variable. */ 292 293 if (IS_ABSOLUTE_PATH (f)) 294 try = fopen (path = f, FOPEN_RT); 295 else 296 { 297 char * env = getenv ("INC100"); 298 299 try = NULL; 300 301 len = strlen (current_filename); 302 if ((size_t) include_dir_maxlen > len) 303 len = include_dir_maxlen; 304 if (env && strlen (env) > len) 305 len = strlen (env); 306 307 path = (char *) xmalloc (strlen (f) + len + 5); 308 309 if (current_filename != NULL) 310 { 311 for (d = NULL, p = current_filename; *p; p++) 312 if (IS_DIR_SEPARATOR (* p)) 313 d = p; 314 315 if (d != NULL) 316 { 317 sprintf (path, "%.*s/%s", (int) (d - current_filename), current_filename, 318 f); 319 try = fopen (path, FOPEN_RT); 320 } 321 } 322 323 if (try == NULL) 324 { 325 int i; 326 327 for (i = 0; i < include_dir_count; i++) 328 { 329 sprintf (path, "%s/%s", include_dirs[i], f); 330 if ((try = fopen (path, FOPEN_RT)) != NULL) 331 break; 332 } 333 } 334 335 if (try == NULL && env != NULL) 336 { 337 sprintf (path, "%s/%s", env, f); 338 try = fopen (path, FOPEN_RT); 339 } 340 341 free (f); 342 } 343 344 if (try == NULL) 345 { 346 as_bad (_("unable to locate include file: %s"), filename); 347 free (path); 348 } 349 else 350 { 351 fclose (try); 352 register_dependency (path); 353 input_scrub_insert_file (path); 354 } 355 356 * eof = end_char; 357 } 358 359 static void 360 parse_rx_section (char * name) 361 { 362 asection * sec; 363 int type; 364 int attr = SHF_ALLOC | SHF_EXECINSTR; 365 int align = 2; 366 char end_char; 367 368 do 369 { 370 char * p; 371 372 SKIP_WHITESPACE (); 373 for (p = input_line_pointer; *p && strchr ("\n\t, =", *p) == NULL; p++) 374 ; 375 end_char = *p; 376 *p = 0; 377 378 if (strcasecmp (input_line_pointer, "ALIGN") == 0) 379 { 380 *p = end_char; 381 382 if (end_char == ' ') 383 while (ISSPACE (*p)) 384 p++; 385 386 if (*p == '=') 387 { 388 ++ p; 389 while (ISSPACE (*p)) 390 p++; 391 switch (*p) 392 { 393 case '2': align = 2; break; 394 case '4': align = 4; break; 395 case '8': align = 8; break; 396 default: 397 as_bad (_("unrecognised alignment value in .SECTION directive: %s"), p); 398 ignore_rest_of_line (); 399 return; 400 } 401 ++ p; 402 } 403 404 end_char = *p; 405 } 406 else if (strcasecmp (input_line_pointer, "CODE") == 0) 407 attr = SHF_ALLOC | SHF_EXECINSTR; 408 else if (strcasecmp (input_line_pointer, "DATA") == 0) 409 attr = SHF_ALLOC | SHF_WRITE; 410 else if (strcasecmp (input_line_pointer, "ROMDATA") == 0) 411 attr = SHF_ALLOC; 412 else 413 { 414 as_bad (_("unknown parameter following .SECTION directive: %s"), 415 input_line_pointer); 416 417 *p = end_char; 418 input_line_pointer = p + 1; 419 ignore_rest_of_line (); 420 return; 421 } 422 423 *p = end_char; 424 input_line_pointer = p + 1; 425 } 426 while (end_char != '\n' && end_char != 0); 427 428 if ((sec = bfd_get_section_by_name (stdoutput, name)) == NULL) 429 { 430 if (strcmp (name, "B") && strcmp (name, "B_1") && strcmp (name, "B_2")) 431 type = SHT_NULL; 432 else 433 type = SHT_NOBITS; 434 435 obj_elf_change_section (name, type, attr, 0, NULL, FALSE, FALSE); 436 } 437 else /* Try not to redefine a section, especially B_1. */ 438 { 439 int flags = sec->flags; 440 441 type = elf_section_type (sec); 442 443 attr = ((flags & SEC_READONLY) ? 0 : SHF_WRITE) 444 | ((flags & SEC_ALLOC) ? SHF_ALLOC : 0) 445 | ((flags & SEC_CODE) ? SHF_EXECINSTR : 0) 446 | ((flags & SEC_MERGE) ? SHF_MERGE : 0) 447 | ((flags & SEC_STRINGS) ? SHF_STRINGS : 0) 448 | ((flags & SEC_THREAD_LOCAL) ? SHF_TLS : 0); 449 450 obj_elf_change_section (name, type, attr, 0, NULL, FALSE, FALSE); 451 } 452 453 bfd_set_section_alignment (stdoutput, now_seg, align); 454 } 455 456 static void 457 rx_section (int ignore) 458 { 459 char * p; 460 461 /* The as100 assembler supports a different syntax for the .section 462 pseudo-op. So check for it and handle it here if necessary. */ 463 SKIP_WHITESPACE (); 464 465 /* Peek past the section name to see if arguments follow. */ 466 for (p = input_line_pointer; *p; p++) 467 if (*p == ',' || *p == '\n') 468 break; 469 470 if (*p == ',') 471 { 472 int len = p - input_line_pointer; 473 474 while (ISSPACE (*++p)) 475 ; 476 477 if (*p != '"' && *p != '#') 478 { 479 char * name = (char *) xmalloc (len + 1); 480 481 strncpy (name, input_line_pointer, len); 482 name[len] = 0; 483 484 input_line_pointer = p; 485 parse_rx_section (name); 486 return; 487 } 488 } 489 490 obj_elf_section (ignore); 491 } 492 493 static void 494 rx_list (int ignore ATTRIBUTE_UNUSED) 495 { 496 SKIP_WHITESPACE (); 497 498 if (strncasecmp (input_line_pointer, "OFF", 3)) 499 listing_list (0); 500 else if (strncasecmp (input_line_pointer, "ON", 2)) 501 listing_list (1); 502 else 503 as_warn (_("expecting either ON or OFF after .list")); 504 } 505 506 /* Like the .rept pseudo op, but supports the 507 use of ..MACREP inside the repeated region. */ 508 509 static void 510 rx_rept (int ignore ATTRIBUTE_UNUSED) 511 { 512 int count = get_absolute_expression (); 513 514 do_repeat_with_expander (count, "MREPEAT", "ENDR", "..MACREP"); 515 } 516 517 /* Like cons() accept that strings are allowed. */ 518 519 static void 520 rx_cons (int size) 521 { 522 SKIP_WHITESPACE (); 523 524 if (* input_line_pointer == '"') 525 stringer (8+0); 526 else 527 cons (size); 528 } 529 530 static void 531 rx_nop (int ignore ATTRIBUTE_UNUSED) 532 { 533 ignore_rest_of_line (); 534 } 535 536 static void 537 rx_unimp (int idx) 538 { 539 as_warn (_("The \".%s\" pseudo-op is not implemented\n"), 540 md_pseudo_table[idx].poc_name); 541 ignore_rest_of_line (); 542 } 543 544 /* The target specific pseudo-ops which we support. */ 545 const pseudo_typeS md_pseudo_table[] = 546 { 547 /* These are unimplemented. They're listed first so that we can use 548 the poc_value as the index into this array, to get the name of 549 the pseudo. So, keep these (1) first, and (2) in order, with (3) 550 the poc_value's in sequence. */ 551 { "btglb", rx_unimp, 0 }, 552 { "call", rx_unimp, 1 }, 553 { "einsf", rx_unimp, 2 }, 554 { "fb", rx_unimp, 3 }, 555 { "fbsym", rx_unimp, 4 }, 556 { "id", rx_unimp, 5 }, 557 { "initsct", rx_unimp, 6 }, 558 { "insf", rx_unimp, 7 }, 559 { "instr", rx_unimp, 8 }, 560 { "lbba", rx_unimp, 9 }, 561 { "len", rx_unimp, 10 }, 562 { "optj", rx_unimp, 11 }, 563 { "rvector", rx_unimp, 12 }, 564 { "sb", rx_unimp, 13 }, 565 { "sbbit", rx_unimp, 14 }, 566 { "sbsym", rx_unimp, 15 }, 567 { "sbsym16", rx_unimp, 16 }, 568 569 /* These are the do-nothing pseudos. */ 570 { "stk", rx_nop, 0 }, 571 /* The manual documents ".stk" but the compiler emits ".stack". */ 572 { "stack", rx_nop, 0 }, 573 574 /* These are Renesas as100 assembler pseudo-ops that we do support. */ 575 { "addr", rx_cons, 3 }, 576 { "align", s_align_bytes, 2 }, 577 { "byte", rx_cons, 1 }, 578 { "fixed", float_cons, 'f' }, 579 { "form", listing_psize, 0 }, 580 { "glb", s_globl, 0 }, 581 { "include", rx_include, 0 }, 582 { "list", rx_list, 0 }, 583 { "lword", rx_cons, 4 }, 584 { "mrepeat", rx_rept, 0 }, 585 { "section", rx_section, 0 }, 586 587 /* FIXME: The following pseudo-ops place their values (and associated 588 label if present) in the data section, regardless of whatever 589 section we are currently in. At the moment this code does not 590 implement that part of the semantics. */ 591 { "blka", s_space, 3 }, 592 { "blkb", s_space, 1 }, 593 { "blkd", s_space, 8 }, 594 { "blkf", s_space, 4 }, 595 { "blkl", s_space, 4 }, 596 { "blkw", s_space, 2 }, 597 598 /* Our "standard" pseudos. */ 599 { "double", rx_float_cons, 0 }, 600 { "bss", s_bss, 0 }, 601 { "3byte", cons, 3 }, 602 { "int", cons, 4 }, 603 { "word", cons, 4 }, 604 605 { "fetchalign", rx_fetchalign, 0 }, 606 607 /* End of list marker. */ 608 { NULL, NULL, 0 } 609 }; 610 611 static asymbol * gp_symbol; 612 static asymbol * rx_pid_symbol; 613 614 static symbolS * rx_pidreg_symbol; 615 static symbolS * rx_gpreg_symbol; 616 617 void 618 md_begin (void) 619 { 620 /* Make the __gp and __pid_base symbols now rather 621 than after the symbol table is frozen. We only do this 622 when supporting small data limits because otherwise we 623 pollute the symbol table. */ 624 625 /* The meta-registers %pidreg and %gpreg depend on what other 626 options are specified. The __rx_*_defined symbols exist so we 627 can .ifdef asm code based on what options were passed to gas, 628 without needing a preprocessor */ 629 630 if (rx_pid_mode) 631 { 632 rx_pid_register = 13 - rx_num_int_regs; 633 rx_pid_symbol = symbol_get_bfdsym (symbol_find_or_make ("__pid_base")); 634 rx_pidreg_symbol = symbol_find_or_make ("__rx_pidreg_defined"); 635 S_SET_VALUE (rx_pidreg_symbol, rx_pid_register); 636 S_SET_SEGMENT (rx_pidreg_symbol, absolute_section); 637 } 638 639 if (rx_use_small_data_limit) 640 { 641 if (rx_pid_mode) 642 rx_gp_register = rx_pid_register - 1; 643 else 644 rx_gp_register = 13 - rx_num_int_regs; 645 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp")); 646 rx_gpreg_symbol = symbol_find_or_make ("__rx_gpreg_defined"); 647 S_SET_VALUE (rx_gpreg_symbol, rx_gp_register); 648 S_SET_SEGMENT (rx_gpreg_symbol, absolute_section); 649 } 650 } 651 652 char * rx_lex_start; 653 char * rx_lex_end; 654 655 /* These negative numbers are found in rx_bytesT.n_base for non-opcode 656 md_frags */ 657 #define RX_NBASE_FETCHALIGN -1 658 659 typedef struct rx_bytesT 660 { 661 char base[4]; 662 /* If this is negative, it's a special-purpose frag as per the defines above. */ 663 int n_base; 664 char ops[8]; 665 int n_ops; 666 struct 667 { 668 expressionS exp; 669 char offset; 670 char nbits; 671 char type; /* RXREL_*. */ 672 int reloc; 673 fixS * fixP; 674 } fixups[2]; 675 int n_fixups; 676 struct 677 { 678 char type; 679 char field_pos; 680 char val_ofs; 681 } relax[2]; 682 int n_relax; 683 int link_relax; 684 fixS *link_relax_fixP; 685 char times_grown; 686 char times_shrank; 687 } rx_bytesT; 688 689 static rx_bytesT rx_bytes; 690 /* We set n_ops to be "size of next opcode" if the next opcode doesn't relax. */ 691 static rx_bytesT *fetchalign_bytes = NULL; 692 693 static void 694 rx_fetchalign (int ignore ATTRIBUTE_UNUSED) 695 { 696 char * bytes; 697 fragS * frag_then; 698 699 memset (& rx_bytes, 0, sizeof (rx_bytes)); 700 rx_bytes.n_base = RX_NBASE_FETCHALIGN; 701 702 bytes = frag_more (8); 703 frag_then = frag_now; 704 frag_variant (rs_machine_dependent, 705 0 /* max_chars */, 706 0 /* var */, 707 0 /* subtype */, 708 0 /* symbol */, 709 0 /* offset */, 710 0 /* opcode */); 711 frag_then->fr_opcode = bytes; 712 frag_then->fr_subtype = 0; 713 fetchalign_bytes = frag_then->tc_frag_data; 714 } 715 716 void 717 rx_relax (int type, int pos) 718 { 719 rx_bytes.relax[rx_bytes.n_relax].type = type; 720 rx_bytes.relax[rx_bytes.n_relax].field_pos = pos; 721 rx_bytes.relax[rx_bytes.n_relax].val_ofs = rx_bytes.n_base + rx_bytes.n_ops; 722 rx_bytes.n_relax ++; 723 } 724 725 void 726 rx_linkrelax_dsp (int pos) 727 { 728 switch (pos) 729 { 730 case 4: 731 rx_bytes.link_relax |= RX_RELAXA_DSP4; 732 break; 733 case 6: 734 rx_bytes.link_relax |= RX_RELAXA_DSP6; 735 break; 736 case 14: 737 rx_bytes.link_relax |= RX_RELAXA_DSP14; 738 break; 739 } 740 } 741 742 void 743 rx_linkrelax_imm (int pos) 744 { 745 switch (pos) 746 { 747 case 6: 748 rx_bytes.link_relax |= RX_RELAXA_IMM6; 749 break; 750 case 12: 751 rx_bytes.link_relax |= RX_RELAXA_IMM12; 752 break; 753 } 754 } 755 756 void 757 rx_linkrelax_branch (void) 758 { 759 rx_bytes.link_relax |= RX_RELAXA_BRA; 760 } 761 762 static void 763 rx_fixup (expressionS exp, int offsetbits, int nbits, int type) 764 { 765 rx_bytes.fixups[rx_bytes.n_fixups].exp = exp; 766 rx_bytes.fixups[rx_bytes.n_fixups].offset = offsetbits; 767 rx_bytes.fixups[rx_bytes.n_fixups].nbits = nbits; 768 rx_bytes.fixups[rx_bytes.n_fixups].type = type; 769 rx_bytes.fixups[rx_bytes.n_fixups].reloc = exp.X_md; 770 rx_bytes.n_fixups ++; 771 } 772 773 #define rx_field_fixup(exp, offset, nbits, type) \ 774 rx_fixup (exp, offset, nbits, type) 775 776 #define rx_op_fixup(exp, offset, nbits, type) \ 777 rx_fixup (exp, offset + 8 * rx_bytes.n_base, nbits, type) 778 779 void 780 rx_base1 (int b1) 781 { 782 rx_bytes.base[0] = b1; 783 rx_bytes.n_base = 1; 784 } 785 786 void 787 rx_base2 (int b1, int b2) 788 { 789 rx_bytes.base[0] = b1; 790 rx_bytes.base[1] = b2; 791 rx_bytes.n_base = 2; 792 } 793 794 void 795 rx_base3 (int b1, int b2, int b3) 796 { 797 rx_bytes.base[0] = b1; 798 rx_bytes.base[1] = b2; 799 rx_bytes.base[2] = b3; 800 rx_bytes.n_base = 3; 801 } 802 803 void 804 rx_base4 (int b1, int b2, int b3, int b4) 805 { 806 rx_bytes.base[0] = b1; 807 rx_bytes.base[1] = b2; 808 rx_bytes.base[2] = b3; 809 rx_bytes.base[3] = b4; 810 rx_bytes.n_base = 4; 811 } 812 813 /* This gets complicated when the field spans bytes, because fields 814 are numbered from the MSB of the first byte as zero, and bits are 815 stored LSB towards the LSB of the byte. Thus, a simple four-bit 816 insertion of 12 at position 4 of 0x00 yields: 0x0b. A three-bit 817 insertion of b'MXL at position 7 is like this: 818 819 - - - - - - - - - - - - - - - - 820 M X L */ 821 822 void 823 rx_field (int val, int pos, int sz) 824 { 825 int valm; 826 int bytep, bitp; 827 828 if (sz > 0) 829 { 830 if (val < 0 || val >= (1 << sz)) 831 as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz); 832 } 833 else 834 { 835 sz = - sz; 836 if (val < -(1 << (sz - 1)) || val >= (1 << (sz - 1))) 837 as_bad (_("Value %d doesn't fit in signed %d-bit field"), val, sz); 838 } 839 840 /* This code points at 'M' in the above example. */ 841 bytep = pos / 8; 842 bitp = pos % 8; 843 844 while (bitp + sz > 8) 845 { 846 int ssz = 8 - bitp; 847 int svalm; 848 849 svalm = val >> (sz - ssz); 850 svalm = svalm & ((1 << ssz) - 1); 851 svalm = svalm << (8 - bitp - ssz); 852 gas_assert (bytep < rx_bytes.n_base); 853 rx_bytes.base[bytep] |= svalm; 854 855 bitp = 0; 856 sz -= ssz; 857 bytep ++; 858 } 859 valm = val & ((1 << sz) - 1); 860 valm = valm << (8 - bitp - sz); 861 gas_assert (bytep < rx_bytes.n_base); 862 rx_bytes.base[bytep] |= valm; 863 } 864 865 /* Special case of the above, for 3-bit displacements of 2..9. */ 866 867 void 868 rx_disp3 (expressionS exp, int pos) 869 { 870 rx_field_fixup (exp, pos, 3, RXREL_PCREL); 871 } 872 873 /* Special case of the above, for split 5-bit displacements. Assumes 874 the displacement has been checked with rx_disp5op. */ 875 /* ---- -432 1--- 0--- */ 876 877 void 878 rx_field5s (expressionS exp) 879 { 880 int val; 881 882 val = exp.X_add_number; 883 rx_bytes.base[0] |= val >> 2; 884 rx_bytes.base[1] |= (val << 6) & 0x80; 885 rx_bytes.base[1] |= (val << 3) & 0x08; 886 } 887 888 /* ---- ---- 4--- 3210 */ 889 890 void 891 rx_field5s2 (expressionS exp) 892 { 893 int val; 894 895 val = exp.X_add_number; 896 rx_bytes.base[1] |= (val << 3) & 0x80; 897 rx_bytes.base[1] |= (val ) & 0x0f; 898 } 899 900 #define OP(x) rx_bytes.ops[rx_bytes.n_ops++] = (x) 901 902 #define F_PRECISION 2 903 904 void 905 rx_op (expressionS exp, int nbytes, int type) 906 { 907 int v = 0; 908 909 if ((exp.X_op == O_constant || exp.X_op == O_big) 910 && type != RXREL_PCREL) 911 { 912 if (exp.X_op == O_big && exp.X_add_number <= 0) 913 { 914 LITTLENUM_TYPE w[2]; 915 char * ip = rx_bytes.ops + rx_bytes.n_ops; 916 917 gen_to_words (w, F_PRECISION, 8); 918 #if RX_OPCODE_BIG_ENDIAN 919 ip[0] = w[0] >> 8; 920 ip[1] = w[0]; 921 ip[2] = w[1] >> 8; 922 ip[3] = w[1]; 923 #else 924 ip[3] = w[0] >> 8; 925 ip[2] = w[0]; 926 ip[1] = w[1] >> 8; 927 ip[0] = w[1]; 928 #endif 929 rx_bytes.n_ops += 4; 930 } 931 else 932 { 933 v = exp.X_add_number; 934 while (nbytes) 935 { 936 #if RX_OPCODE_BIG_ENDIAN 937 OP ((v >> (8 * (nbytes - 1))) & 0xff); 938 #else 939 OP (v & 0xff); 940 v >>= 8; 941 #endif 942 nbytes --; 943 } 944 } 945 } 946 else 947 { 948 rx_op_fixup (exp, rx_bytes.n_ops * 8, nbytes * 8, type); 949 memset (rx_bytes.ops + rx_bytes.n_ops, 0, nbytes); 950 rx_bytes.n_ops += nbytes; 951 } 952 } 953 954 int 955 rx_wrap (void) 956 { 957 return 0; 958 } 959 960 #define APPEND(B, N_B) \ 961 if (rx_bytes.N_B) \ 962 { \ 963 memcpy (bytes + idx, rx_bytes.B, rx_bytes.N_B); \ 964 idx += rx_bytes.N_B; \ 965 } 966 967 void 968 rx_frag_init (fragS * fragP) 969 { 970 if (rx_bytes.n_relax || rx_bytes.link_relax || rx_bytes.n_base < 0) 971 { 972 fragP->tc_frag_data = malloc (sizeof (rx_bytesT)); 973 memcpy (fragP->tc_frag_data, & rx_bytes, sizeof (rx_bytesT)); 974 } 975 else 976 fragP->tc_frag_data = 0; 977 } 978 979 /* Handle the as100's version of the .equ pseudo-op. It has the syntax: 980 <symbol_name> .equ <expression> */ 981 982 static void 983 rx_equ (char * name, char * expression) 984 { 985 char saved_name_end_char; 986 char * name_end; 987 char * saved_ilp; 988 989 while (ISSPACE (* name)) 990 name ++; 991 992 for (name_end = name + 1; *name_end; name_end ++) 993 if (! ISALNUM (* name_end)) 994 break; 995 996 saved_name_end_char = * name_end; 997 * name_end = 0; 998 999 saved_ilp = input_line_pointer; 1000 input_line_pointer = expression; 1001 1002 equals (name, 1); 1003 1004 input_line_pointer = saved_ilp; 1005 * name_end = saved_name_end_char; 1006 } 1007 1008 /* Look for Renesas as100 pseudo-ops that occur after a symbol name 1009 rather than at the start of a line. (eg .EQU or .DEFINE). If one 1010 is found, process it and return TRUE otherwise return FALSE. */ 1011 1012 static bfd_boolean 1013 scan_for_infix_rx_pseudo_ops (char * str) 1014 { 1015 char * p; 1016 char * pseudo_op; 1017 char * dot = strchr (str, '.'); 1018 1019 if (dot == NULL || dot == str) 1020 return FALSE; 1021 1022 /* A real pseudo-op must be preceeded by whitespace. */ 1023 if (dot[-1] != ' ' && dot[-1] != '\t') 1024 return FALSE; 1025 1026 pseudo_op = dot + 1; 1027 1028 if (!ISALNUM (* pseudo_op)) 1029 return FALSE; 1030 1031 for (p = pseudo_op + 1; ISALNUM (* p); p++) 1032 ; 1033 1034 if (strncasecmp ("EQU", pseudo_op, p - pseudo_op) == 0) 1035 rx_equ (str, p); 1036 else if (strncasecmp ("DEFINE", pseudo_op, p - pseudo_op) == 0) 1037 as_warn (_("The .DEFINE pseudo-op is not implemented")); 1038 else if (strncasecmp ("MACRO", pseudo_op, p - pseudo_op) == 0) 1039 as_warn (_("The .MACRO pseudo-op is not implemented")); 1040 else if (strncasecmp ("BTEQU", pseudo_op, p - pseudo_op) == 0) 1041 as_warn (_("The .BTEQU pseudo-op is not implemented.")); 1042 else 1043 return FALSE; 1044 1045 return TRUE; 1046 } 1047 1048 void 1049 md_assemble (char * str) 1050 { 1051 char * bytes; 1052 int idx = 0; 1053 int i, rel; 1054 fragS * frag_then = frag_now; 1055 expressionS *exp; 1056 1057 memset (& rx_bytes, 0, sizeof (rx_bytes)); 1058 1059 rx_lex_init (str, str + strlen (str)); 1060 if (scan_for_infix_rx_pseudo_ops (str)) 1061 return; 1062 rx_parse (); 1063 1064 /* This simplifies the relaxation code. */ 1065 if (rx_bytes.n_relax || rx_bytes.link_relax) 1066 { 1067 /* We do it this way because we want the frag to have the 1068 rx_bytes in it, which we initialize above. */ 1069 bytes = frag_more (12); 1070 frag_then = frag_now; 1071 frag_variant (rs_machine_dependent, 1072 0 /* max_chars */, 1073 0 /* var */, 1074 0 /* subtype */, 1075 0 /* symbol */, 1076 0 /* offset */, 1077 0 /* opcode */); 1078 frag_then->fr_opcode = bytes; 1079 frag_then->fr_fix += rx_bytes.n_base + rx_bytes.n_ops; 1080 frag_then->fr_subtype = rx_bytes.n_base + rx_bytes.n_ops; 1081 } 1082 else 1083 { 1084 bytes = frag_more (rx_bytes.n_base + rx_bytes.n_ops); 1085 frag_then = frag_now; 1086 if (fetchalign_bytes) 1087 fetchalign_bytes->n_ops = rx_bytes.n_base + rx_bytes.n_ops; 1088 } 1089 1090 fetchalign_bytes = NULL; 1091 1092 APPEND (base, n_base); 1093 APPEND (ops, n_ops); 1094 1095 if (rx_bytes.link_relax && rx_bytes.n_fixups) 1096 { 1097 fixS * f; 1098 1099 f = fix_new (frag_then, 1100 (char *) bytes - frag_then->fr_literal, 1101 0, 1102 abs_section_sym, 1103 rx_bytes.link_relax | rx_bytes.n_fixups, 1104 0, 1105 BFD_RELOC_RX_RELAX); 1106 frag_then->tc_frag_data->link_relax_fixP = f; 1107 } 1108 1109 for (i = 0; i < rx_bytes.n_fixups; i ++) 1110 { 1111 /* index: [nbytes][type] */ 1112 static int reloc_map[5][4] = 1113 { 1114 { 0, 0, 0, BFD_RELOC_RX_DIR3U_PCREL }, 1115 { BFD_RELOC_8, BFD_RELOC_RX_8U, BFD_RELOC_RX_NEG8, BFD_RELOC_8_PCREL }, 1116 { BFD_RELOC_RX_16_OP, BFD_RELOC_RX_16U, BFD_RELOC_RX_NEG16, BFD_RELOC_16_PCREL }, 1117 { BFD_RELOC_RX_24_OP, BFD_RELOC_RX_24U, BFD_RELOC_RX_NEG24, BFD_RELOC_24_PCREL }, 1118 { BFD_RELOC_RX_32_OP, BFD_RELOC_32, BFD_RELOC_RX_NEG32, BFD_RELOC_32_PCREL }, 1119 }; 1120 fixS * f; 1121 1122 idx = rx_bytes.fixups[i].offset / 8; 1123 rel = reloc_map [rx_bytes.fixups[i].nbits / 8][(int) rx_bytes.fixups[i].type]; 1124 1125 if (rx_bytes.fixups[i].reloc) 1126 rel = rx_bytes.fixups[i].reloc; 1127 1128 if (frag_then->tc_frag_data) 1129 exp = & frag_then->tc_frag_data->fixups[i].exp; 1130 else 1131 exp = & rx_bytes.fixups[i].exp; 1132 1133 f = fix_new_exp (frag_then, 1134 (char *) bytes + idx - frag_then->fr_literal, 1135 rx_bytes.fixups[i].nbits / 8, 1136 exp, 1137 rx_bytes.fixups[i].type == RXREL_PCREL ? 1 : 0, 1138 rel); 1139 if (frag_then->tc_frag_data) 1140 frag_then->tc_frag_data->fixups[i].fixP = f; 1141 } 1142 1143 dwarf2_emit_insn (idx); 1144 } 1145 1146 void 1147 rx_md_end (void) 1148 { 1149 } 1150 1151 /* Write a value out to the object file, using the appropriate endianness. */ 1152 1153 void 1154 md_number_to_chars (char * buf, valueT val, int n) 1155 { 1156 if (target_big_endian) 1157 number_to_chars_bigendian (buf, val, n); 1158 else 1159 number_to_chars_littleendian (buf, val, n); 1160 } 1161 1162 static struct 1163 { 1164 char * fname; 1165 int reloc; 1166 } 1167 reloc_functions[] = 1168 { 1169 { "gp", BFD_RELOC_GPREL16 }, 1170 { 0, 0 } 1171 }; 1172 1173 void 1174 md_operand (expressionS * exp ATTRIBUTE_UNUSED) 1175 { 1176 int reloc = 0; 1177 int i; 1178 1179 for (i = 0; reloc_functions[i].fname; i++) 1180 { 1181 int flen = strlen (reloc_functions[i].fname); 1182 1183 if (input_line_pointer[0] == '%' 1184 && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0 1185 && input_line_pointer[flen + 1] == '(') 1186 { 1187 reloc = reloc_functions[i].reloc; 1188 input_line_pointer += flen + 2; 1189 break; 1190 } 1191 } 1192 if (reloc == 0) 1193 return; 1194 1195 expression (exp); 1196 if (* input_line_pointer == ')') 1197 input_line_pointer ++; 1198 1199 exp->X_md = reloc; 1200 } 1201 1202 valueT 1203 md_section_align (segT segment, valueT size) 1204 { 1205 int align = bfd_get_section_alignment (stdoutput, segment); 1206 return ((size + (1 << align) - 1) & (-1 << align)); 1207 } 1208 1209 /* NOP - 1 cycle */ 1210 static unsigned char nop_1[] = { 0x03}; 1211 /* MOV.L R0,R0 - 1 cycle */ 1212 static unsigned char nop_2[] = { 0xef, 0x00}; 1213 /* MAX R0,R0 - 1 cycle */ 1214 static unsigned char nop_3[] = { 0xfc, 0x13, 0x00 }; 1215 /* MUL #1,R0 - 1 cycle */ 1216 static unsigned char nop_4[] = { 0x76, 0x10, 0x01, 0x00 }; 1217 /* MUL #1,R0 - 1 cycle */ 1218 static unsigned char nop_5[] = { 0x77, 0x10, 0x01, 0x00, 0x00 }; 1219 /* MUL #1,R0 - 1 cycle */ 1220 static unsigned char nop_6[] = { 0x74, 0x10, 0x01, 0x00, 0x00, 0x00 }; 1221 /* BRA.S .+7 - 1 cycle */ 1222 static unsigned char nop_7[] = { 0x0F, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }; 1223 1224 static unsigned char *nops[] = { NULL, nop_1, nop_2, nop_3, nop_4, nop_5, nop_6, nop_7 }; 1225 #define BIGGEST_NOP 7 1226 1227 /* When relaxing, we need to output a reloc for any .align directive 1228 so that we can retain this alignment as we adjust opcode sizes. */ 1229 void 1230 rx_handle_align (fragS * frag) 1231 { 1232 /* If handling an alignment frag, use an optimal NOP pattern. 1233 Only do this if a fill value has not already been provided. 1234 FIXME: This test fails if the provided fill value is zero. */ 1235 if ((frag->fr_type == rs_align 1236 || frag->fr_type == rs_align_code) 1237 && subseg_text_p (now_seg)) 1238 { 1239 int count = (frag->fr_next->fr_address 1240 - frag->fr_address 1241 - frag->fr_fix); 1242 unsigned char *base = (unsigned char *)frag->fr_literal + frag->fr_fix; 1243 1244 if (* base == 0) 1245 { 1246 if (count > BIGGEST_NOP) 1247 { 1248 base[0] = 0x2e; 1249 base[1] = count; 1250 frag->fr_var = 2; 1251 } 1252 else if (count > 0) 1253 { 1254 memcpy (base, nops[count], count); 1255 frag->fr_var = count; 1256 } 1257 } 1258 } 1259 1260 if (linkrelax 1261 && (frag->fr_type == rs_align 1262 || frag->fr_type == rs_align_code) 1263 && frag->fr_address + frag->fr_fix > 0 1264 && frag->fr_offset > 0 1265 && now_seg != bss_section) 1266 { 1267 fix_new (frag, frag->fr_fix, 0, 1268 &abs_symbol, RX_RELAXA_ALIGN + frag->fr_offset, 1269 0, BFD_RELOC_RX_RELAX); 1270 /* For the purposes of relaxation, this relocation is attached 1271 to the byte *after* the alignment - i.e. the byte that must 1272 remain aligned. */ 1273 fix_new (frag->fr_next, 0, 0, 1274 &abs_symbol, RX_RELAXA_ELIGN + frag->fr_offset, 1275 0, BFD_RELOC_RX_RELAX); 1276 } 1277 } 1278 1279 char * 1280 md_atof (int type, char * litP, int * sizeP) 1281 { 1282 return ieee_md_atof (type, litP, sizeP, target_big_endian); 1283 } 1284 1285 symbolS * 1286 md_undefined_symbol (char * name ATTRIBUTE_UNUSED) 1287 { 1288 return NULL; 1289 } 1290 1291 /*----------------------------------------------------------------------*/ 1292 /* To recap: we estimate everything based on md_estimate_size, then 1293 adjust based on rx_relax_frag. When it all settles, we call 1294 md_convert frag to update the bytes. The relaxation types and 1295 relocations are in fragP->tc_frag_data, which is a copy of that 1296 rx_bytes. 1297 1298 Our scheme is as follows: fr_fix has the size of the smallest 1299 opcode (like BRA.S). We store the number of total bytes we need in 1300 fr_subtype. When we're done relaxing, we use fr_subtype and the 1301 existing opcode bytes to figure out what actual opcode we need to 1302 put in there. If the fixup isn't resolvable now, we use the 1303 maximal size. */ 1304 1305 #define TRACE_RELAX 0 1306 #define tprintf if (TRACE_RELAX) printf 1307 1308 typedef enum 1309 { 1310 OT_other, 1311 OT_bra, 1312 OT_beq, 1313 OT_bne, 1314 OT_bsr, 1315 OT_bcc 1316 } op_type_T; 1317 1318 /* We're looking for these types of relaxations: 1319 1320 BRA.S 00001dsp 1321 BRA.B 00101110 dspppppp 1322 BRA.W 00111000 dspppppp pppppppp 1323 BRA.A 00000100 dspppppp pppppppp pppppppp 1324 1325 BEQ.S 00010dsp 1326 BEQ.B 00100000 dspppppp 1327 BEQ.W 00111010 dspppppp pppppppp 1328 1329 BNE.S 00011dsp 1330 BNE.B 00100001 dspppppp 1331 BNE.W 00111011 dspppppp pppppppp 1332 1333 BSR.W 00111001 dspppppp pppppppp 1334 BSR.A 00000101 dspppppp pppppppp pppppppp 1335 1336 Bcc.B 0010cond dspppppp 1337 1338 Additionally, we can synthesize longer conditional branches using 1339 pairs of opcodes, one with an inverted conditional (flip LSB): 1340 1341 Bcc.W 0010ncnd 00000110 00111000 dspppppp pppppppp 1342 Bcc.A 0010ncnd 00000111 00000100 dspppppp pppppppp pppppppp 1343 BEQ.A 00011100 00000100 dspppppp pppppppp pppppppp 1344 BNE.A 00010100 00000100 dspppppp pppppppp pppppppp */ 1345 1346 /* Given the opcode bytes at OP, figure out which opcode it is and 1347 return the type of opcode. We use this to re-encode the opcode as 1348 a different size later. */ 1349 1350 static op_type_T 1351 rx_opcode_type (char * op) 1352 { 1353 unsigned char b = (unsigned char) op[0]; 1354 1355 switch (b & 0xf8) 1356 { 1357 case 0x08: return OT_bra; 1358 case 0x10: return OT_beq; 1359 case 0x18: return OT_bne; 1360 } 1361 1362 switch (b) 1363 { 1364 case 0x2e: return OT_bra; 1365 case 0x38: return OT_bra; 1366 case 0x04: return OT_bra; 1367 1368 case 0x20: return OT_beq; 1369 case 0x3a: return OT_beq; 1370 1371 case 0x21: return OT_bne; 1372 case 0x3b: return OT_bne; 1373 1374 case 0x39: return OT_bsr; 1375 case 0x05: return OT_bsr; 1376 } 1377 1378 if ((b & 0xf0) == 0x20) 1379 return OT_bcc; 1380 1381 return OT_other; 1382 } 1383 1384 /* Returns zero if *addrP has the target address. Else returns nonzero 1385 if we cannot compute the target address yet. */ 1386 1387 static int 1388 rx_frag_fix_value (fragS * fragP, 1389 segT segment, 1390 int which, 1391 addressT * addrP, 1392 int need_diff, 1393 addressT * sym_addr) 1394 { 1395 addressT addr = 0; 1396 rx_bytesT * b = fragP->tc_frag_data; 1397 expressionS * exp = & b->fixups[which].exp; 1398 1399 if (need_diff && exp->X_op != O_subtract) 1400 return 1; 1401 1402 if (exp->X_add_symbol) 1403 { 1404 if (S_FORCE_RELOC (exp->X_add_symbol, 1)) 1405 return 1; 1406 if (S_GET_SEGMENT (exp->X_add_symbol) != segment) 1407 return 1; 1408 addr += S_GET_VALUE (exp->X_add_symbol); 1409 } 1410 1411 if (exp->X_op_symbol) 1412 { 1413 if (exp->X_op != O_subtract) 1414 return 1; 1415 if (S_FORCE_RELOC (exp->X_op_symbol, 1)) 1416 return 1; 1417 if (S_GET_SEGMENT (exp->X_op_symbol) != segment) 1418 return 1; 1419 addr -= S_GET_VALUE (exp->X_op_symbol); 1420 } 1421 if (sym_addr) 1422 * sym_addr = addr; 1423 addr += exp->X_add_number; 1424 * addrP = addr; 1425 return 0; 1426 } 1427 1428 /* Estimate how big the opcode is after this relax pass. The return 1429 value is the difference between fr_fix and the actual size. We 1430 compute the total size in rx_relax_frag and store it in fr_subtype, 1431 sowe only need to subtract fx_fix and return it. */ 1432 1433 int 1434 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED) 1435 { 1436 int opfixsize; 1437 int delta; 1438 1439 tprintf ("\033[32m est frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n", 1440 (unsigned long) (fragP->fr_address 1441 + (fragP->fr_opcode - fragP->fr_literal)), 1442 (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset, 1443 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype); 1444 1445 /* This is the size of the opcode that's accounted for in fr_fix. */ 1446 opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal); 1447 /* This is the size of the opcode that isn't. */ 1448 delta = (fragP->fr_subtype - opfixsize); 1449 1450 tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta); 1451 return delta; 1452 } 1453 1454 /* Given a frag FRAGP, return the "next" frag that contains an 1455 opcode. Assumes the next opcode is relaxable, and thus rs_machine_dependent. */ 1456 1457 static fragS * 1458 rx_next_opcode (fragS *fragP) 1459 { 1460 do { 1461 fragP = fragP->fr_next; 1462 } while (fragP && fragP->fr_type != rs_machine_dependent); 1463 return fragP; 1464 } 1465 1466 /* Given the new addresses for this relax pass, figure out how big 1467 each opcode must be. We store the total number of bytes needed in 1468 fr_subtype. The return value is the difference between the size 1469 after the last pass and the size after this pass, so we use the old 1470 fr_subtype to calculate the difference. */ 1471 1472 int 1473 rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch) 1474 { 1475 addressT addr0, sym_addr; 1476 addressT mypc; 1477 int disp; 1478 int oldsize = fragP->fr_subtype; 1479 int newsize = oldsize; 1480 op_type_T optype; 1481 /* Index of relaxation we care about. */ 1482 int ri; 1483 1484 tprintf ("\033[36mrelax frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d str %ld\033[0m\n", 1485 (unsigned long) (fragP->fr_address 1486 + (fragP->fr_opcode - fragP->fr_literal)), 1487 (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset, 1488 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype, stretch); 1489 1490 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal); 1491 1492 if (fragP->tc_frag_data->n_base == RX_NBASE_FETCHALIGN) 1493 { 1494 unsigned int next_size; 1495 if (fragP->fr_next == NULL) 1496 return 0; 1497 1498 next_size = fragP->tc_frag_data->n_ops; 1499 if (next_size == 0) 1500 { 1501 fragS *n = rx_next_opcode (fragP); 1502 next_size = n->fr_subtype; 1503 } 1504 1505 fragP->fr_subtype = (8-(mypc & 7)) & 7; 1506 tprintf("subtype %u\n", fragP->fr_subtype); 1507 if (fragP->fr_subtype >= next_size) 1508 fragP->fr_subtype = 0; 1509 tprintf ("\033[34m -> mypc %lu next_size %u new %d old %d delta %d (fetchalign)\033[0m\n", 1510 mypc & 7, 1511 next_size, fragP->fr_subtype, oldsize, fragP->fr_subtype-oldsize); 1512 1513 newsize = fragP->fr_subtype; 1514 1515 return newsize - oldsize; 1516 } 1517 1518 optype = rx_opcode_type (fragP->fr_opcode); 1519 1520 /* In the one case where we have both a disp and imm relaxation, we want 1521 the imm relaxation here. */ 1522 ri = 0; 1523 if (fragP->tc_frag_data->n_relax > 1 1524 && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP) 1525 ri = 1; 1526 1527 /* Try to get the target address. */ 1528 if (rx_frag_fix_value (fragP, segment, ri, & addr0, 1529 fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH, 1530 & sym_addr)) 1531 { 1532 /* If we don't, we must use the maximum size for the linker. 1533 Note that we don't use synthetically expanded conditionals 1534 for this. */ 1535 switch (fragP->tc_frag_data->relax[ri].type) 1536 { 1537 case RX_RELAX_BRANCH: 1538 switch (optype) 1539 { 1540 case OT_bra: 1541 case OT_bsr: 1542 newsize = 4; 1543 break; 1544 case OT_beq: 1545 case OT_bne: 1546 newsize = 3; 1547 break; 1548 case OT_bcc: 1549 newsize = 2; 1550 break; 1551 case OT_other: 1552 newsize = oldsize; 1553 break; 1554 } 1555 break; 1556 1557 case RX_RELAX_IMM: 1558 newsize = fragP->tc_frag_data->relax[ri].val_ofs + 4; 1559 break; 1560 } 1561 fragP->fr_subtype = newsize; 1562 tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize); 1563 return newsize - oldsize; 1564 } 1565 1566 if (sym_addr > mypc) 1567 addr0 += stretch; 1568 1569 switch (fragP->tc_frag_data->relax[ri].type) 1570 { 1571 case RX_RELAX_BRANCH: 1572 tprintf ("branch, addr %08lx pc %08lx disp %ld\n", 1573 (unsigned long) addr0, (unsigned long) mypc, 1574 (long) (addr0 - mypc)); 1575 disp = (int) addr0 - (int) mypc; 1576 1577 switch (optype) 1578 { 1579 case OT_bcc: 1580 if (disp >= -128 && (disp - (oldsize-2)) <= 127) 1581 /* bcc.b */ 1582 newsize = 2; 1583 else if (disp >= -32768 && (disp - (oldsize-5)) <= 32767) 1584 /* bncc.b/bra.w */ 1585 newsize = 5; 1586 else 1587 /* bncc.b/bra.a */ 1588 newsize = 6; 1589 break; 1590 1591 case OT_beq: 1592 case OT_bne: 1593 if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax) 1594 /* beq.s */ 1595 newsize = 1; 1596 else if (disp >= -128 && (disp - (oldsize-2)) <= 127) 1597 /* beq.b */ 1598 newsize = 2; 1599 else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767) 1600 /* beq.w */ 1601 newsize = 3; 1602 else 1603 /* bne.s/bra.a */ 1604 newsize = 5; 1605 break; 1606 1607 case OT_bra: 1608 case OT_bsr: 1609 if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax) 1610 /* bra.s */ 1611 newsize = 1; 1612 else if (disp >= -128 && (disp - (oldsize-2)) <= 127) 1613 /* bra.b */ 1614 newsize = 2; 1615 else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767) 1616 /* bra.w */ 1617 newsize = 3; 1618 else 1619 /* bra.a */ 1620 newsize = 4; 1621 break; 1622 1623 case OT_other: 1624 break; 1625 } 1626 tprintf (" - newsize %d\n", newsize); 1627 break; 1628 1629 case RX_RELAX_IMM: 1630 tprintf ("other, addr %08lx pc %08lx LI %d OF %d\n", 1631 (unsigned long) addr0, (unsigned long) mypc, 1632 fragP->tc_frag_data->relax[ri].field_pos, 1633 fragP->tc_frag_data->relax[ri].val_ofs); 1634 1635 newsize = fragP->tc_frag_data->relax[ri].val_ofs; 1636 1637 if ((long) addr0 >= -128 && (long) addr0 <= 127) 1638 newsize += 1; 1639 else if ((long) addr0 >= -32768 && (long) addr0 <= 32767) 1640 newsize += 2; 1641 else if ((long) addr0 >= -8388608 && (long) addr0 <= 8388607) 1642 newsize += 3; 1643 else 1644 newsize += 4; 1645 break; 1646 1647 default: 1648 break; 1649 } 1650 1651 if (fragP->tc_frag_data->relax[ri].type == RX_RELAX_BRANCH) 1652 switch (optype) 1653 { 1654 case OT_bra: 1655 case OT_bcc: 1656 case OT_beq: 1657 case OT_bne: 1658 break; 1659 case OT_bsr: 1660 if (newsize < 3) 1661 newsize = 3; 1662 break; 1663 case OT_other: 1664 break; 1665 } 1666 1667 /* This prevents infinite loops in align-heavy sources. */ 1668 if (newsize < oldsize) 1669 { 1670 if (fragP->tc_frag_data->times_shrank > 10 1671 && fragP->tc_frag_data->times_grown > 10) 1672 newsize = oldsize; 1673 if (fragP->tc_frag_data->times_shrank < 20) 1674 fragP->tc_frag_data->times_shrank ++; 1675 } 1676 else if (newsize > oldsize) 1677 { 1678 if (fragP->tc_frag_data->times_grown < 20) 1679 fragP->tc_frag_data->times_grown ++; 1680 } 1681 1682 fragP->fr_subtype = newsize; 1683 tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize); 1684 return newsize - oldsize; 1685 } 1686 1687 /* This lets us test for the opcode type and the desired size in a 1688 switch statement. */ 1689 #define OPCODE(type,size) ((type) * 16 + (size)) 1690 1691 /* Given the opcode stored in fr_opcode and the number of bytes we 1692 think we need, encode a new opcode. We stored a pointer to the 1693 fixup for this opcode in the tc_frag_data structure. If we can do 1694 the fixup here, we change the relocation type to "none" (we test 1695 for that in tc_gen_reloc) else we change it to the right type for 1696 the new (biggest) opcode. */ 1697 1698 void 1699 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, 1700 segT segment ATTRIBUTE_UNUSED, 1701 fragS * fragP ATTRIBUTE_UNUSED) 1702 { 1703 rx_bytesT * rxb = fragP->tc_frag_data; 1704 addressT addr0, mypc; 1705 int disp; 1706 int reloc_type, reloc_adjust; 1707 char * op = fragP->fr_opcode; 1708 int keep_reloc = 0; 1709 int ri; 1710 int fi = (rxb->n_fixups > 1) ? 1 : 0; 1711 fixS * fix = rxb->fixups[fi].fixP; 1712 1713 tprintf ("\033[31mconvrt frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n", 1714 (unsigned long) (fragP->fr_address 1715 + (fragP->fr_opcode - fragP->fr_literal)), 1716 (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset, 1717 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, 1718 fragP->fr_subtype); 1719 1720 #if TRACE_RELAX 1721 { 1722 int i; 1723 1724 printf ("lit 0x%p opc 0x%p", fragP->fr_literal, fragP->fr_opcode); 1725 for (i = 0; i < 10; i++) 1726 printf (" %02x", (unsigned char) (fragP->fr_opcode[i])); 1727 printf ("\n"); 1728 } 1729 #endif 1730 1731 if (fragP->tc_frag_data->n_base == RX_NBASE_FETCHALIGN) 1732 { 1733 int count = fragP->fr_subtype; 1734 if (count == 0) 1735 ; 1736 else if (count > BIGGEST_NOP) 1737 { 1738 op[0] = 0x2e; 1739 op[1] = count; 1740 } 1741 else if (count > 0) 1742 { 1743 memcpy (op, nops[count], count); 1744 } 1745 } 1746 1747 /* In the one case where we have both a disp and imm relaxation, we want 1748 the imm relaxation here. */ 1749 ri = 0; 1750 if (fragP->tc_frag_data->n_relax > 1 1751 && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP) 1752 ri = 1; 1753 1754 /* We used a new frag for this opcode, so the opcode address should 1755 be the frag address. */ 1756 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal); 1757 1758 /* Try to get the target address. If we fail here, we just use the 1759 largest format. */ 1760 if (rx_frag_fix_value (fragP, segment, 0, & addr0, 1761 fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH, 0)) 1762 { 1763 /* We don't know the target address. */ 1764 keep_reloc = 1; 1765 addr0 = 0; 1766 disp = 0; 1767 } 1768 else 1769 { 1770 /* We know the target address, and it's in addr0. */ 1771 disp = (int) addr0 - (int) mypc; 1772 } 1773 1774 if (linkrelax) 1775 keep_reloc = 1; 1776 1777 reloc_type = BFD_RELOC_NONE; 1778 reloc_adjust = 0; 1779 1780 tprintf ("convert, op is %d, disp %d (%lx-%lx)\n", 1781 rx_opcode_type (fragP->fr_opcode), disp, 1782 (unsigned long) addr0, (unsigned long) mypc); 1783 switch (fragP->tc_frag_data->relax[ri].type) 1784 { 1785 case RX_RELAX_BRANCH: 1786 switch (OPCODE (rx_opcode_type (fragP->fr_opcode), fragP->fr_subtype)) 1787 { 1788 case OPCODE (OT_bra, 1): /* BRA.S - no change. */ 1789 op[0] = 0x08 + (disp & 7); 1790 break; 1791 case OPCODE (OT_bra, 2): /* BRA.B - 8 bit. */ 1792 op[0] = 0x2e; 1793 op[1] = disp; 1794 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE; 1795 reloc_adjust = 1; 1796 break; 1797 case OPCODE (OT_bra, 3): /* BRA.W - 16 bit. */ 1798 op[0] = 0x38; 1799 #if RX_OPCODE_BIG_ENDIAN 1800 op[1] = (disp >> 8) & 0xff; 1801 op[2] = disp; 1802 #else 1803 op[2] = (disp >> 8) & 0xff; 1804 op[1] = disp; 1805 #endif 1806 reloc_adjust = 1; 1807 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE; 1808 break; 1809 case OPCODE (OT_bra, 4): /* BRA.A - 24 bit. */ 1810 op[0] = 0x04; 1811 #if RX_OPCODE_BIG_ENDIAN 1812 op[1] = (disp >> 16) & 0xff; 1813 op[2] = (disp >> 8) & 0xff; 1814 op[3] = disp; 1815 #else 1816 op[3] = (disp >> 16) & 0xff; 1817 op[2] = (disp >> 8) & 0xff; 1818 op[1] = disp; 1819 #endif 1820 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE; 1821 reloc_adjust = 1; 1822 break; 1823 1824 case OPCODE (OT_beq, 1): /* BEQ.S - no change. */ 1825 op[0] = 0x10 + (disp & 7); 1826 break; 1827 case OPCODE (OT_beq, 2): /* BEQ.B - 8 bit. */ 1828 op[0] = 0x20; 1829 op[1] = disp; 1830 reloc_adjust = 1; 1831 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE; 1832 break; 1833 case OPCODE (OT_beq, 3): /* BEQ.W - 16 bit. */ 1834 op[0] = 0x3a; 1835 #if RX_OPCODE_BIG_ENDIAN 1836 op[1] = (disp >> 8) & 0xff; 1837 op[2] = disp; 1838 #else 1839 op[2] = (disp >> 8) & 0xff; 1840 op[1] = disp; 1841 #endif 1842 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE; 1843 reloc_adjust = 1; 1844 break; 1845 case OPCODE (OT_beq, 5): /* BEQ.A - synthetic. */ 1846 op[0] = 0x1d; /* bne.s .+5. */ 1847 op[1] = 0x04; /* bra.a dsp:24. */ 1848 disp -= 1; 1849 #if RX_OPCODE_BIG_ENDIAN 1850 op[2] = (disp >> 16) & 0xff; 1851 op[3] = (disp >> 8) & 0xff; 1852 op[4] = disp; 1853 #else 1854 op[4] = (disp >> 16) & 0xff; 1855 op[3] = (disp >> 8) & 0xff; 1856 op[2] = disp; 1857 #endif 1858 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE; 1859 reloc_adjust = 2; 1860 break; 1861 1862 case OPCODE (OT_bne, 1): /* BNE.S - no change. */ 1863 op[0] = 0x18 + (disp & 7); 1864 break; 1865 case OPCODE (OT_bne, 2): /* BNE.B - 8 bit. */ 1866 op[0] = 0x21; 1867 op[1] = disp; 1868 reloc_adjust = 1; 1869 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE; 1870 break; 1871 case OPCODE (OT_bne, 3): /* BNE.W - 16 bit. */ 1872 op[0] = 0x3b; 1873 #if RX_OPCODE_BIG_ENDIAN 1874 op[1] = (disp >> 8) & 0xff; 1875 op[2] = disp; 1876 #else 1877 op[2] = (disp >> 8) & 0xff; 1878 op[1] = disp; 1879 #endif 1880 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE; 1881 reloc_adjust = 1; 1882 break; 1883 case OPCODE (OT_bne, 5): /* BNE.A - synthetic. */ 1884 op[0] = 0x15; /* beq.s .+5. */ 1885 op[1] = 0x04; /* bra.a dsp:24. */ 1886 disp -= 1; 1887 #if RX_OPCODE_BIG_ENDIAN 1888 op[2] = (disp >> 16) & 0xff; 1889 op[3] = (disp >> 8) & 0xff; 1890 op[4] = disp; 1891 #else 1892 op[4] = (disp >> 16) & 0xff; 1893 op[3] = (disp >> 8) & 0xff; 1894 op[2] = disp; 1895 #endif 1896 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE; 1897 reloc_adjust = 2; 1898 break; 1899 1900 case OPCODE (OT_bsr, 3): /* BSR.W - 16 bit. */ 1901 op[0] = 0x39; 1902 #if RX_OPCODE_BIG_ENDIAN 1903 op[1] = (disp >> 8) & 0xff; 1904 op[2] = disp; 1905 #else 1906 op[2] = (disp >> 8) & 0xff; 1907 op[1] = disp; 1908 #endif 1909 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE; 1910 reloc_adjust = 0; 1911 break; 1912 case OPCODE (OT_bsr, 4): /* BSR.A - 24 bit. */ 1913 op[0] = 0x05; 1914 #if RX_OPCODE_BIG_ENDIAN 1915 op[1] = (disp >> 16) & 0xff; 1916 op[2] = (disp >> 8) & 0xff; 1917 op[3] = disp; 1918 #else 1919 op[3] = (disp >> 16) & 0xff; 1920 op[2] = (disp >> 8) & 0xff; 1921 op[1] = disp; 1922 #endif 1923 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE; 1924 reloc_adjust = 0; 1925 break; 1926 1927 case OPCODE (OT_bcc, 2): /* Bcond.B - 8 bit. */ 1928 op[1] = disp; 1929 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE; 1930 break; 1931 case OPCODE (OT_bcc, 5): /* Bcond.W - synthetic. */ 1932 op[0] ^= 1; /* Invert condition. */ 1933 op[1] = 5; /* Displacement. */ 1934 op[2] = 0x38; 1935 disp -= 2; 1936 #if RX_OPCODE_BIG_ENDIAN 1937 op[3] = (disp >> 8) & 0xff; 1938 op[4] = disp; 1939 #else 1940 op[4] = (disp >> 8) & 0xff; 1941 op[3] = disp; 1942 #endif 1943 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE; 1944 reloc_adjust = 2; 1945 break; 1946 case OPCODE (OT_bcc, 6): /* Bcond.S - synthetic. */ 1947 op[0] ^= 1; /* Invert condition. */ 1948 op[1] = 6; /* Displacement. */ 1949 op[2] = 0x04; 1950 disp -= 2; 1951 #if RX_OPCODE_BIG_ENDIAN 1952 op[3] = (disp >> 16) & 0xff; 1953 op[4] = (disp >> 8) & 0xff; 1954 op[5] = disp; 1955 #else 1956 op[5] = (disp >> 16) & 0xff; 1957 op[4] = (disp >> 8) & 0xff; 1958 op[3] = disp; 1959 #endif 1960 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE; 1961 reloc_adjust = 2; 1962 break; 1963 1964 default: 1965 /* These are opcodes we'll relax in th linker, later. */ 1966 if (rxb->n_fixups) 1967 reloc_type = rxb->fixups[ri].fixP->fx_r_type; 1968 break; 1969 } 1970 break; 1971 1972 case RX_RELAX_IMM: 1973 { 1974 int nbytes = fragP->fr_subtype - fragP->tc_frag_data->relax[ri].val_ofs; 1975 int li; 1976 char * imm = op + fragP->tc_frag_data->relax[ri].val_ofs; 1977 1978 switch (nbytes) 1979 { 1980 case 1: 1981 li = 1; 1982 imm[0] = addr0; 1983 reloc_type = BFD_RELOC_8; 1984 break; 1985 case 2: 1986 li = 2; 1987 #if RX_OPCODE_BIG_ENDIAN 1988 imm[1] = addr0; 1989 imm[0] = addr0 >> 8; 1990 #else 1991 imm[0] = addr0; 1992 imm[1] = addr0 >> 8; 1993 #endif 1994 reloc_type = BFD_RELOC_RX_16_OP; 1995 break; 1996 case 3: 1997 li = 3; 1998 #if RX_OPCODE_BIG_ENDIAN 1999 imm[2] = addr0; 2000 imm[1] = addr0 >> 8; 2001 imm[0] = addr0 >> 16; 2002 #else 2003 imm[0] = addr0; 2004 imm[1] = addr0 >> 8; 2005 imm[2] = addr0 >> 16; 2006 #endif 2007 reloc_type = BFD_RELOC_RX_24_OP; 2008 break; 2009 case 4: 2010 li = 0; 2011 #if RX_OPCODE_BIG_ENDIAN 2012 imm[3] = addr0; 2013 imm[2] = addr0 >> 8; 2014 imm[1] = addr0 >> 16; 2015 imm[0] = addr0 >> 24; 2016 #else 2017 imm[0] = addr0; 2018 imm[1] = addr0 >> 8; 2019 imm[2] = addr0 >> 16; 2020 imm[3] = addr0 >> 24; 2021 #endif 2022 reloc_type = BFD_RELOC_RX_32_OP; 2023 break; 2024 default: 2025 as_bad (_("invalid immediate size")); 2026 li = -1; 2027 } 2028 2029 switch (fragP->tc_frag_data->relax[ri].field_pos) 2030 { 2031 case 6: 2032 op[0] &= 0xfc; 2033 op[0] |= li; 2034 break; 2035 case 12: 2036 op[1] &= 0xf3; 2037 op[1] |= li << 2; 2038 break; 2039 case 20: 2040 op[2] &= 0xf3; 2041 op[2] |= li << 2; 2042 break; 2043 default: 2044 as_bad (_("invalid immediate field position")); 2045 } 2046 } 2047 break; 2048 2049 default: 2050 if (rxb->n_fixups) 2051 { 2052 reloc_type = fix->fx_r_type; 2053 reloc_adjust = 0; 2054 } 2055 break; 2056 } 2057 2058 if (rxb->n_fixups) 2059 { 2060 2061 fix->fx_r_type = reloc_type; 2062 fix->fx_where += reloc_adjust; 2063 switch (reloc_type) 2064 { 2065 case BFD_RELOC_NONE: 2066 fix->fx_size = 0; 2067 break; 2068 case BFD_RELOC_8: 2069 fix->fx_size = 1; 2070 break; 2071 case BFD_RELOC_16_PCREL: 2072 case BFD_RELOC_RX_16_OP: 2073 fix->fx_size = 2; 2074 break; 2075 case BFD_RELOC_24_PCREL: 2076 case BFD_RELOC_RX_24_OP: 2077 fix->fx_size = 3; 2078 break; 2079 case BFD_RELOC_RX_32_OP: 2080 fix->fx_size = 4; 2081 break; 2082 } 2083 } 2084 2085 fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal); 2086 tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix, 2087 fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal); 2088 fragP->fr_var = 0; 2089 2090 if (fragP->fr_next != NULL 2091 && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address) 2092 != fragP->fr_fix)) 2093 as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP, 2094 (long) fragP->fr_fix, 2095 (long) fragP->fr_address, (long) fragP->fr_next->fr_address); 2096 } 2097 2098 #undef OPCODE 2099 2100 int 2101 rx_validate_fix_sub (struct fix * f) 2102 { 2103 /* We permit the subtraction of two symbols in a few cases. */ 2104 /* mov #sym1-sym2, R3 */ 2105 if (f->fx_r_type == BFD_RELOC_RX_32_OP) 2106 return 1; 2107 /* .long sym1-sym2 */ 2108 if (f->fx_r_type == BFD_RELOC_RX_DIFF 2109 && ! f->fx_pcrel 2110 && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1)) 2111 return 1; 2112 return 0; 2113 } 2114 2115 long 2116 md_pcrel_from_section (fixS * fixP, segT sec) 2117 { 2118 long rv; 2119 2120 if (fixP->fx_addsy != NULL 2121 && (! S_IS_DEFINED (fixP->fx_addsy) 2122 || S_GET_SEGMENT (fixP->fx_addsy) != sec)) 2123 /* The symbol is undefined (or is defined but not in this section). 2124 Let the linker figure it out. */ 2125 return 0; 2126 2127 rv = fixP->fx_frag->fr_address + fixP->fx_where; 2128 switch (fixP->fx_r_type) 2129 { 2130 case BFD_RELOC_RX_DIR3U_PCREL: 2131 return rv; 2132 default: 2133 return rv - 1; 2134 } 2135 } 2136 2137 void 2138 rx_cons_fix_new (fragS * frag, 2139 int where, 2140 int size, 2141 expressionS * exp) 2142 { 2143 bfd_reloc_code_real_type type; 2144 2145 switch (size) 2146 { 2147 case 1: 2148 type = BFD_RELOC_8; 2149 break; 2150 case 2: 2151 type = BFD_RELOC_16; 2152 break; 2153 case 3: 2154 type = BFD_RELOC_24; 2155 break; 2156 case 4: 2157 type = BFD_RELOC_32; 2158 break; 2159 default: 2160 as_bad (_("unsupported constant size %d\n"), size); 2161 return; 2162 } 2163 2164 if (exp->X_op == O_subtract && exp->X_op_symbol) 2165 { 2166 if (size != 4 && size != 2 && size != 1) 2167 as_bad (_("difference of two symbols only supported with .long, .short, or .byte")); 2168 else 2169 type = BFD_RELOC_RX_DIFF; 2170 } 2171 2172 fix_new_exp (frag, where, (int) size, exp, 0, type); 2173 } 2174 2175 void 2176 md_apply_fix (struct fix * f ATTRIBUTE_UNUSED, 2177 valueT * t ATTRIBUTE_UNUSED, 2178 segT s ATTRIBUTE_UNUSED) 2179 { 2180 /* Instruction bytes are always little endian. */ 2181 char * op; 2182 unsigned long val; 2183 2184 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1)) 2185 return; 2186 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1)) 2187 return; 2188 2189 #define OP2(x) op[target_big_endian ? 1-x : x] 2190 #define OP3(x) op[target_big_endian ? 2-x : x] 2191 #define OP4(x) op[target_big_endian ? 3-x : x] 2192 2193 op = f->fx_frag->fr_literal + f->fx_where; 2194 val = (unsigned long) * t; 2195 2196 /* Opcode words are always the same endian. Data words are either 2197 big or little endian. */ 2198 2199 switch (f->fx_r_type) 2200 { 2201 case BFD_RELOC_NONE: 2202 break; 2203 2204 case BFD_RELOC_RX_RELAX: 2205 f->fx_done = 1; 2206 break; 2207 2208 case BFD_RELOC_RX_DIR3U_PCREL: 2209 if (val < 3 || val > 10) 2210 as_bad_where (f->fx_file, f->fx_line, 2211 _("jump not 3..10 bytes away (is %d)"), (int) val); 2212 op[0] &= 0xf8; 2213 op[0] |= val & 0x07; 2214 break; 2215 2216 case BFD_RELOC_8: 2217 case BFD_RELOC_8_PCREL: 2218 case BFD_RELOC_RX_8U: 2219 op[0] = val; 2220 break; 2221 2222 case BFD_RELOC_16: 2223 OP2(1) = val & 0xff; 2224 OP2(0) = (val >> 8) & 0xff; 2225 break; 2226 2227 case BFD_RELOC_16_PCREL: 2228 case BFD_RELOC_RX_16_OP: 2229 case BFD_RELOC_RX_16U: 2230 #if RX_OPCODE_BIG_ENDIAN 2231 op[1] = val & 0xff; 2232 op[0] = (val >> 8) & 0xff; 2233 #else 2234 op[0] = val & 0xff; 2235 op[1] = (val >> 8) & 0xff; 2236 #endif 2237 break; 2238 2239 case BFD_RELOC_24: 2240 OP3(0) = val & 0xff; 2241 OP3(1) = (val >> 8) & 0xff; 2242 OP3(2) = (val >> 16) & 0xff; 2243 break; 2244 2245 case BFD_RELOC_24_PCREL: 2246 case BFD_RELOC_RX_24_OP: 2247 case BFD_RELOC_RX_24U: 2248 #if RX_OPCODE_BIG_ENDIAN 2249 op[2] = val & 0xff; 2250 op[1] = (val >> 8) & 0xff; 2251 op[0] = (val >> 16) & 0xff; 2252 #else 2253 op[0] = val & 0xff; 2254 op[1] = (val >> 8) & 0xff; 2255 op[2] = (val >> 16) & 0xff; 2256 #endif 2257 break; 2258 2259 case BFD_RELOC_RX_DIFF: 2260 switch (f->fx_size) 2261 { 2262 case 1: 2263 op[0] = val & 0xff; 2264 break; 2265 case 2: 2266 OP2(0) = val & 0xff; 2267 OP2(1) = (val >> 8) & 0xff; 2268 break; 2269 case 4: 2270 OP4(0) = val & 0xff; 2271 OP4(1) = (val >> 8) & 0xff; 2272 OP4(2) = (val >> 16) & 0xff; 2273 OP4(3) = (val >> 24) & 0xff; 2274 break; 2275 } 2276 break; 2277 2278 case BFD_RELOC_32: 2279 OP4(0) = val & 0xff; 2280 OP4(1) = (val >> 8) & 0xff; 2281 OP4(2) = (val >> 16) & 0xff; 2282 OP4(3) = (val >> 24) & 0xff; 2283 break; 2284 2285 case BFD_RELOC_RX_32_OP: 2286 #if RX_OPCODE_BIG_ENDIAN 2287 op[3] = val & 0xff; 2288 op[2] = (val >> 8) & 0xff; 2289 op[1] = (val >> 16) & 0xff; 2290 op[0] = (val >> 24) & 0xff; 2291 #else 2292 op[0] = val & 0xff; 2293 op[1] = (val >> 8) & 0xff; 2294 op[2] = (val >> 16) & 0xff; 2295 op[3] = (val >> 24) & 0xff; 2296 #endif 2297 break; 2298 2299 case BFD_RELOC_RX_NEG8: 2300 op[0] = - val; 2301 break; 2302 2303 case BFD_RELOC_RX_NEG16: 2304 val = -val; 2305 #if RX_OPCODE_BIG_ENDIAN 2306 op[1] = val & 0xff; 2307 op[0] = (val >> 8) & 0xff; 2308 #else 2309 op[0] = val & 0xff; 2310 op[1] = (val >> 8) & 0xff; 2311 #endif 2312 break; 2313 2314 case BFD_RELOC_RX_NEG24: 2315 val = -val; 2316 #if RX_OPCODE_BIG_ENDIAN 2317 op[2] = val & 0xff; 2318 op[1] = (val >> 8) & 0xff; 2319 op[0] = (val >> 16) & 0xff; 2320 #else 2321 op[0] = val & 0xff; 2322 op[1] = (val >> 8) & 0xff; 2323 op[2] = (val >> 16) & 0xff; 2324 #endif 2325 break; 2326 2327 case BFD_RELOC_RX_NEG32: 2328 val = -val; 2329 #if RX_OPCODE_BIG_ENDIAN 2330 op[3] = val & 0xff; 2331 op[2] = (val >> 8) & 0xff; 2332 op[1] = (val >> 16) & 0xff; 2333 op[0] = (val >> 24) & 0xff; 2334 #else 2335 op[0] = val & 0xff; 2336 op[1] = (val >> 8) & 0xff; 2337 op[2] = (val >> 16) & 0xff; 2338 op[3] = (val >> 24) & 0xff; 2339 #endif 2340 break; 2341 2342 case BFD_RELOC_RX_GPRELL: 2343 val >>= 1; 2344 case BFD_RELOC_RX_GPRELW: 2345 val >>= 1; 2346 case BFD_RELOC_RX_GPRELB: 2347 #if RX_OPCODE_BIG_ENDIAN 2348 op[1] = val & 0xff; 2349 op[0] = (val >> 8) & 0xff; 2350 #else 2351 op[0] = val & 0xff; 2352 op[1] = (val >> 8) & 0xff; 2353 #endif 2354 break; 2355 2356 default: 2357 as_bad (_("Unknown reloc in md_apply_fix: %s"), 2358 bfd_get_reloc_code_name (f->fx_r_type)); 2359 break; 2360 } 2361 2362 if (f->fx_addsy == NULL) 2363 f->fx_done = 1; 2364 } 2365 2366 arelent ** 2367 tc_gen_reloc (asection * sec ATTRIBUTE_UNUSED, fixS * fixp) 2368 { 2369 static arelent * reloc[5]; 2370 bfd_boolean is_opcode = FALSE; 2371 2372 if (fixp->fx_r_type == BFD_RELOC_NONE) 2373 { 2374 reloc[0] = NULL; 2375 return reloc; 2376 } 2377 2378 if (fixp->fx_subsy 2379 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section) 2380 { 2381 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy); 2382 fixp->fx_subsy = NULL; 2383 } 2384 2385 reloc[0] = (arelent *) xmalloc (sizeof (arelent)); 2386 reloc[0]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); 2387 * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 2388 reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where; 2389 reloc[0]->addend = fixp->fx_offset; 2390 2391 if (fixp->fx_r_type == BFD_RELOC_RX_32_OP 2392 && fixp->fx_subsy) 2393 { 2394 fixp->fx_r_type = BFD_RELOC_RX_DIFF; 2395 is_opcode = TRUE; 2396 } 2397 else if (sec) 2398 is_opcode = sec->flags & SEC_CODE; 2399 2400 /* Certain BFD relocations cannot be translated directly into 2401 a single (non-Red Hat) RX relocation, but instead need 2402 multiple RX relocations - handle them here. */ 2403 switch (fixp->fx_r_type) 2404 { 2405 case BFD_RELOC_RX_DIFF: 2406 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM); 2407 2408 reloc[1] = (arelent *) xmalloc (sizeof (arelent)); 2409 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); 2410 * reloc[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy); 2411 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where; 2412 reloc[1]->addend = 0; 2413 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM); 2414 2415 reloc[2] = (arelent *) xmalloc (sizeof (arelent)); 2416 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT); 2417 reloc[2]->addend = 0; 2418 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr; 2419 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where; 2420 2421 reloc[3] = (arelent *) xmalloc (sizeof (arelent)); 2422 switch (fixp->fx_size) 2423 { 2424 case 1: 2425 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS8); 2426 break; 2427 case 2: 2428 if (!is_opcode && target_big_endian) 2429 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16_REV); 2430 else if (is_opcode) 2431 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL); 2432 else 2433 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16); 2434 break; 2435 case 4: 2436 if (!is_opcode && target_big_endian) 2437 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32_REV); 2438 else 2439 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32); 2440 break; 2441 } 2442 reloc[3]->addend = 0; 2443 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr; 2444 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where; 2445 2446 reloc[4] = NULL; 2447 break; 2448 2449 case BFD_RELOC_RX_GPRELL: 2450 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM); 2451 2452 reloc[1] = (arelent *) xmalloc (sizeof (arelent)); 2453 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); 2454 if (gp_symbol == NULL) 2455 { 2456 if (symbol_table_frozen) 2457 { 2458 symbolS * gp; 2459 2460 gp = symbol_find ("__gp"); 2461 if (gp == NULL) 2462 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified")); 2463 else 2464 gp_symbol = symbol_get_bfdsym (gp); 2465 } 2466 else 2467 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp")); 2468 } 2469 * reloc[1]->sym_ptr_ptr = gp_symbol; 2470 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where; 2471 reloc[1]->addend = 0; 2472 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM); 2473 2474 reloc[2] = (arelent *) xmalloc (sizeof (arelent)); 2475 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT); 2476 reloc[2]->addend = 0; 2477 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr; 2478 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where; 2479 2480 reloc[3] = (arelent *) xmalloc (sizeof (arelent)); 2481 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL); 2482 reloc[3]->addend = 0; 2483 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr; 2484 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where; 2485 2486 reloc[4] = NULL; 2487 break; 2488 2489 case BFD_RELOC_RX_GPRELW: 2490 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM); 2491 2492 reloc[1] = (arelent *) xmalloc (sizeof (arelent)); 2493 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); 2494 if (gp_symbol == NULL) 2495 { 2496 if (symbol_table_frozen) 2497 { 2498 symbolS * gp; 2499 2500 gp = symbol_find ("__gp"); 2501 if (gp == NULL) 2502 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified")); 2503 else 2504 gp_symbol = symbol_get_bfdsym (gp); 2505 } 2506 else 2507 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp")); 2508 } 2509 * reloc[1]->sym_ptr_ptr = gp_symbol; 2510 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where; 2511 reloc[1]->addend = 0; 2512 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM); 2513 2514 reloc[2] = (arelent *) xmalloc (sizeof (arelent)); 2515 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT); 2516 reloc[2]->addend = 0; 2517 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr; 2518 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where; 2519 2520 reloc[3] = (arelent *) xmalloc (sizeof (arelent)); 2521 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UW); 2522 reloc[3]->addend = 0; 2523 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr; 2524 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where; 2525 2526 reloc[4] = NULL; 2527 break; 2528 2529 case BFD_RELOC_RX_GPRELB: 2530 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM); 2531 2532 reloc[1] = (arelent *) xmalloc (sizeof (arelent)); 2533 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); 2534 if (gp_symbol == NULL) 2535 { 2536 if (symbol_table_frozen) 2537 { 2538 symbolS * gp; 2539 2540 gp = symbol_find ("__gp"); 2541 if (gp == NULL) 2542 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified")); 2543 else 2544 gp_symbol = symbol_get_bfdsym (gp); 2545 } 2546 else 2547 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp")); 2548 } 2549 * reloc[1]->sym_ptr_ptr = gp_symbol; 2550 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where; 2551 reloc[1]->addend = 0; 2552 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM); 2553 2554 reloc[2] = (arelent *) xmalloc (sizeof (arelent)); 2555 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT); 2556 reloc[2]->addend = 0; 2557 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr; 2558 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where; 2559 2560 reloc[3] = (arelent *) xmalloc (sizeof (arelent)); 2561 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16U); 2562 reloc[3]->addend = 0; 2563 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr; 2564 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where; 2565 2566 reloc[4] = NULL; 2567 break; 2568 2569 case BFD_RELOC_RX_NEG32: 2570 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM); 2571 2572 reloc[1] = (arelent *) xmalloc (sizeof (arelent)); 2573 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_NEG); 2574 reloc[1]->addend = 0; 2575 reloc[1]->sym_ptr_ptr = reloc[0]->sym_ptr_ptr; 2576 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where; 2577 2578 reloc[2] = (arelent *) xmalloc (sizeof (arelent)); 2579 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32); 2580 reloc[2]->addend = 0; 2581 reloc[2]->sym_ptr_ptr = reloc[0]->sym_ptr_ptr; 2582 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where; 2583 2584 reloc[3] = NULL; 2585 break; 2586 2587 default: 2588 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 2589 reloc[1] = NULL; 2590 break; 2591 } 2592 2593 return reloc; 2594 } 2595 2596 /* Set the ELF specific flags. */ 2597 2598 void 2599 rx_elf_final_processing (void) 2600 { 2601 elf_elfheader (stdoutput)->e_flags |= elf_flags; 2602 } 2603 2604 /* Scan the current input line for occurances of Renesas 2605 local labels and replace them with the GAS version. */ 2606 2607 void 2608 rx_start_line (void) 2609 { 2610 int in_double_quote = 0; 2611 int in_single_quote = 0; 2612 int done = 0; 2613 char * p = input_line_pointer; 2614 2615 /* Scan the line looking for question marks. Skip past quote enclosed regions. */ 2616 do 2617 { 2618 switch (*p) 2619 { 2620 case '\n': 2621 case 0: 2622 done = 1; 2623 break; 2624 2625 case '"': 2626 in_double_quote = ! in_double_quote; 2627 break; 2628 2629 case '\'': 2630 in_single_quote = ! in_single_quote; 2631 break; 2632 2633 case '?': 2634 if (in_double_quote || in_single_quote) 2635 break; 2636 2637 if (p[1] == ':') 2638 *p = '1'; 2639 else if (p[1] == '+') 2640 { 2641 p[0] = '1'; 2642 p[1] = 'f'; 2643 } 2644 else if (p[1] == '-') 2645 { 2646 p[0] = '1'; 2647 p[1] = 'b'; 2648 } 2649 break; 2650 2651 default: 2652 break; 2653 } 2654 2655 p ++; 2656 } 2657 while (! done); 2658 } 2659