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