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