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