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