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