1 1.1 christos /* tc-rl78.c -- Assembler for the Renesas RL78 2 1.10 christos Copyright (C) 2011-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/rl78.h" 26 1.1 christos #include "rl78-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 const char comment_chars[] = ";"; 33 1.1 christos /* Note that input_file.c hand checks for '#' at the beginning of the 34 1.1 christos first line of the input file. This is because the compiler outputs 35 1.1 christos #NO_APP at the beginning of its output. */ 36 1.1 christos const char line_comment_chars[] = "#"; 37 1.3 christos /* Use something that isn't going to be needed by any expressions or 38 1.3 christos other syntax. */ 39 1.3 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.3 christos /* ELF flags to set in the output file header. */ 45 1.3 christos static int elf_flags = 0; 46 1.3 christos 47 1.1 christos /*------------------------------------------------------------------*/ 48 1.1 christos 49 1.1 christos char * rl78_lex_start; 50 1.1 christos char * rl78_lex_end; 51 1.1 christos 52 1.1 christos typedef struct rl78_bytesT 53 1.1 christos { 54 1.1 christos char prefix[1]; 55 1.1 christos int n_prefix; 56 1.1 christos char base[4]; 57 1.1 christos int n_base; 58 1.1 christos char ops[8]; 59 1.1 christos int n_ops; 60 1.1 christos struct 61 1.1 christos { 62 1.1 christos expressionS exp; 63 1.1 christos char offset; 64 1.1 christos char nbits; 65 1.1 christos char type; /* RL78REL_*. */ 66 1.1 christos int reloc; 67 1.1 christos fixS * fixP; 68 1.1 christos } fixups[2]; 69 1.1 christos int n_fixups; 70 1.1 christos struct 71 1.1 christos { 72 1.1 christos char type; 73 1.1 christos char field_pos; 74 1.1 christos char val_ofs; 75 1.1 christos } relax[2]; 76 1.1 christos int n_relax; 77 1.1 christos int link_relax; 78 1.1 christos fixS *link_relax_fixP; 79 1.1 christos char times_grown; 80 1.1 christos char times_shrank; 81 1.1 christos } rl78_bytesT; 82 1.1 christos 83 1.1 christos static rl78_bytesT rl78_bytes; 84 1.1 christos 85 1.1 christos void 86 1.3 christos rl78_relax (int type, int pos) 87 1.3 christos { 88 1.3 christos rl78_bytes.relax[rl78_bytes.n_relax].type = type; 89 1.3 christos rl78_bytes.relax[rl78_bytes.n_relax].field_pos = pos; 90 1.3 christos rl78_bytes.relax[rl78_bytes.n_relax].val_ofs = rl78_bytes.n_base + rl78_bytes.n_ops; 91 1.3 christos rl78_bytes.n_relax ++; 92 1.3 christos } 93 1.3 christos 94 1.3 christos void 95 1.1 christos rl78_linkrelax_addr16 (void) 96 1.1 christos { 97 1.1 christos rl78_bytes.link_relax |= RL78_RELAXA_ADDR16; 98 1.1 christos } 99 1.1 christos 100 1.1 christos void 101 1.1 christos rl78_linkrelax_branch (void) 102 1.1 christos { 103 1.5 christos rl78_relax (RL78_RELAX_BRANCH, 0); 104 1.1 christos rl78_bytes.link_relax |= RL78_RELAXA_BRA; 105 1.1 christos } 106 1.1 christos 107 1.1 christos static void 108 1.1 christos rl78_fixup (expressionS exp, int offsetbits, int nbits, int type) 109 1.1 christos { 110 1.1 christos rl78_bytes.fixups[rl78_bytes.n_fixups].exp = exp; 111 1.1 christos rl78_bytes.fixups[rl78_bytes.n_fixups].offset = offsetbits; 112 1.1 christos rl78_bytes.fixups[rl78_bytes.n_fixups].nbits = nbits; 113 1.1 christos rl78_bytes.fixups[rl78_bytes.n_fixups].type = type; 114 1.1 christos rl78_bytes.fixups[rl78_bytes.n_fixups].reloc = exp.X_md; 115 1.1 christos rl78_bytes.n_fixups ++; 116 1.1 christos } 117 1.1 christos 118 1.1 christos #define rl78_field_fixup(exp, offset, nbits, type) \ 119 1.1 christos rl78_fixup (exp, offset + 8 * rl78_bytes.n_prefix), nbits, type) 120 1.1 christos 121 1.1 christos #define rl78_op_fixup(exp, offset, nbits, type) \ 122 1.1 christos rl78_fixup (exp, offset + 8 * (rl78_bytes.n_prefix + rl78_bytes.n_base), nbits, type) 123 1.1 christos 124 1.1 christos void 125 1.1 christos rl78_prefix (int p) 126 1.1 christos { 127 1.1 christos rl78_bytes.prefix[0] = p; 128 1.1 christos rl78_bytes.n_prefix = 1; 129 1.1 christos } 130 1.1 christos 131 1.1 christos int 132 1.5 christos rl78_has_prefix (void) 133 1.1 christos { 134 1.1 christos return rl78_bytes.n_prefix; 135 1.1 christos } 136 1.1 christos 137 1.1 christos void 138 1.1 christos rl78_base1 (int b1) 139 1.1 christos { 140 1.1 christos rl78_bytes.base[0] = b1; 141 1.1 christos rl78_bytes.n_base = 1; 142 1.1 christos } 143 1.1 christos 144 1.1 christos void 145 1.1 christos rl78_base2 (int b1, int b2) 146 1.1 christos { 147 1.1 christos rl78_bytes.base[0] = b1; 148 1.1 christos rl78_bytes.base[1] = b2; 149 1.1 christos rl78_bytes.n_base = 2; 150 1.1 christos } 151 1.1 christos 152 1.1 christos void 153 1.1 christos rl78_base3 (int b1, int b2, int b3) 154 1.1 christos { 155 1.1 christos rl78_bytes.base[0] = b1; 156 1.1 christos rl78_bytes.base[1] = b2; 157 1.1 christos rl78_bytes.base[2] = b3; 158 1.1 christos rl78_bytes.n_base = 3; 159 1.1 christos } 160 1.1 christos 161 1.1 christos void 162 1.1 christos rl78_base4 (int b1, int b2, int b3, int b4) 163 1.1 christos { 164 1.1 christos rl78_bytes.base[0] = b1; 165 1.1 christos rl78_bytes.base[1] = b2; 166 1.1 christos rl78_bytes.base[2] = b3; 167 1.1 christos rl78_bytes.base[3] = b4; 168 1.1 christos rl78_bytes.n_base = 4; 169 1.1 christos } 170 1.1 christos 171 1.1 christos #define F_PRECISION 2 172 1.1 christos 173 1.1 christos void 174 1.1 christos rl78_op (expressionS exp, int nbytes, int type) 175 1.1 christos { 176 1.1 christos int v = 0; 177 1.1 christos 178 1.1 christos if ((exp.X_op == O_constant || exp.X_op == O_big) 179 1.1 christos && type != RL78REL_PCREL) 180 1.1 christos { 181 1.1 christos if (exp.X_op == O_big && exp.X_add_number <= 0) 182 1.1 christos { 183 1.1 christos LITTLENUM_TYPE w[2]; 184 1.1 christos char * ip = rl78_bytes.ops + rl78_bytes.n_ops; 185 1.1 christos 186 1.1 christos gen_to_words (w, F_PRECISION, 8); 187 1.1 christos ip[3] = w[0] >> 8; 188 1.1 christos ip[2] = w[0]; 189 1.1 christos ip[1] = w[1] >> 8; 190 1.1 christos ip[0] = w[1]; 191 1.1 christos rl78_bytes.n_ops += 4; 192 1.1 christos } 193 1.1 christos else 194 1.1 christos { 195 1.1 christos v = exp.X_add_number; 196 1.1 christos while (nbytes) 197 1.1 christos { 198 1.1 christos rl78_bytes.ops[rl78_bytes.n_ops++] =v & 0xff; 199 1.1 christos v >>= 8; 200 1.1 christos nbytes --; 201 1.1 christos } 202 1.1 christos } 203 1.1 christos } 204 1.1 christos else 205 1.1 christos { 206 1.3 christos if (nbytes > 2 207 1.3 christos && exp.X_md == BFD_RELOC_RL78_CODE) 208 1.3 christos exp.X_md = 0; 209 1.3 christos 210 1.3 christos if (nbytes == 1 211 1.3 christos && (exp.X_md == BFD_RELOC_RL78_LO16 212 1.3 christos || exp.X_md == BFD_RELOC_RL78_HI16)) 213 1.3 christos as_bad (_("16-bit relocation used in 8-bit operand")); 214 1.3 christos 215 1.3 christos if (nbytes == 2 216 1.3 christos && exp.X_md == BFD_RELOC_RL78_HI8) 217 1.3 christos as_bad (_("8-bit relocation used in 16-bit operand")); 218 1.3 christos 219 1.1 christos rl78_op_fixup (exp, rl78_bytes.n_ops * 8, nbytes * 8, type); 220 1.1 christos memset (rl78_bytes.ops + rl78_bytes.n_ops, 0, nbytes); 221 1.1 christos rl78_bytes.n_ops += nbytes; 222 1.1 christos } 223 1.1 christos } 224 1.1 christos 225 1.1 christos /* This gets complicated when the field spans bytes, because fields 226 1.1 christos are numbered from the MSB of the first byte as zero, and bits are 227 1.1 christos stored LSB towards the LSB of the byte. Thus, a simple four-bit 228 1.1 christos insertion of 12 at position 4 of 0x00 yields: 0x0b. A three-bit 229 1.1 christos insertion of b'MXL at position 7 is like this: 230 1.1 christos 231 1.1 christos - - - - - - - - - - - - - - - - 232 1.1 christos M X L */ 233 1.1 christos 234 1.1 christos void 235 1.1 christos rl78_field (int val, int pos, int sz) 236 1.1 christos { 237 1.1 christos int valm; 238 1.1 christos int bytep, bitp; 239 1.1 christos 240 1.1 christos if (sz > 0) 241 1.1 christos { 242 1.1 christos if (val < 0 || val >= (1 << sz)) 243 1.1 christos as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz); 244 1.1 christos } 245 1.1 christos else 246 1.1 christos { 247 1.1 christos sz = - sz; 248 1.1 christos if (val < -(1 << (sz - 1)) || val >= (1 << (sz - 1))) 249 1.1 christos as_bad (_("Value %d doesn't fit in signed %d-bit field"), val, sz); 250 1.1 christos } 251 1.1 christos 252 1.1 christos /* This code points at 'M' in the above example. */ 253 1.1 christos bytep = pos / 8; 254 1.1 christos bitp = pos % 8; 255 1.1 christos 256 1.1 christos while (bitp + sz > 8) 257 1.1 christos { 258 1.1 christos int ssz = 8 - bitp; 259 1.1 christos int svalm; 260 1.1 christos 261 1.1 christos svalm = val >> (sz - ssz); 262 1.1 christos svalm = svalm & ((1 << ssz) - 1); 263 1.1 christos svalm = svalm << (8 - bitp - ssz); 264 1.1 christos gas_assert (bytep < rl78_bytes.n_base); 265 1.1 christos rl78_bytes.base[bytep] |= svalm; 266 1.1 christos 267 1.1 christos bitp = 0; 268 1.1 christos sz -= ssz; 269 1.1 christos bytep ++; 270 1.1 christos } 271 1.1 christos valm = val & ((1 << sz) - 1); 272 1.1 christos valm = valm << (8 - bitp - sz); 273 1.1 christos gas_assert (bytep < rl78_bytes.n_base); 274 1.1 christos rl78_bytes.base[bytep] |= valm; 275 1.1 christos } 276 1.1 christos 277 1.1 christos /*------------------------------------------------------------------*/ 278 1.1 christos 279 1.1 christos enum options 280 1.1 christos { 281 1.1 christos OPTION_RELAX = OPTION_MD_BASE, 282 1.5 christos OPTION_NORELAX, 283 1.3 christos OPTION_G10, 284 1.3 christos OPTION_G13, 285 1.3 christos OPTION_G14, 286 1.3 christos OPTION_32BIT_DOUBLES, 287 1.3 christos OPTION_64BIT_DOUBLES, 288 1.1 christos }; 289 1.1 christos 290 1.1 christos #define RL78_SHORTOPTS "" 291 1.10 christos const char md_shortopts[] = RL78_SHORTOPTS; 292 1.1 christos 293 1.1 christos /* Assembler options. */ 294 1.10 christos const struct option md_longopts[] = 295 1.1 christos { 296 1.1 christos {"relax", no_argument, NULL, OPTION_RELAX}, 297 1.5 christos {"norelax", no_argument, NULL, OPTION_NORELAX}, 298 1.3 christos {"mg10", no_argument, NULL, OPTION_G10}, 299 1.3 christos {"mg13", no_argument, NULL, OPTION_G13}, 300 1.3 christos {"mg14", no_argument, NULL, OPTION_G14}, 301 1.3 christos {"mrl78", no_argument, NULL, OPTION_G14}, 302 1.3 christos {"m32bit-doubles", no_argument, NULL, OPTION_32BIT_DOUBLES}, 303 1.3 christos {"m64bit-doubles", no_argument, NULL, OPTION_64BIT_DOUBLES}, 304 1.1 christos {NULL, no_argument, NULL, 0} 305 1.1 christos }; 306 1.10 christos const size_t md_longopts_size = sizeof (md_longopts); 307 1.1 christos 308 1.1 christos int 309 1.5 christos md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED) 310 1.1 christos { 311 1.1 christos switch (c) 312 1.1 christos { 313 1.1 christos case OPTION_RELAX: 314 1.1 christos linkrelax = 1; 315 1.1 christos return 1; 316 1.5 christos case OPTION_NORELAX: 317 1.5 christos linkrelax = 0; 318 1.5 christos return 1; 319 1.1 christos 320 1.3 christos case OPTION_G10: 321 1.3 christos elf_flags &= ~ E_FLAG_RL78_CPU_MASK; 322 1.3 christos elf_flags |= E_FLAG_RL78_G10; 323 1.3 christos return 1; 324 1.3 christos 325 1.3 christos case OPTION_G13: 326 1.3 christos elf_flags &= ~ E_FLAG_RL78_CPU_MASK; 327 1.3 christos elf_flags |= E_FLAG_RL78_G13; 328 1.3 christos return 1; 329 1.3 christos 330 1.3 christos case OPTION_G14: 331 1.3 christos elf_flags &= ~ E_FLAG_RL78_CPU_MASK; 332 1.3 christos elf_flags |= E_FLAG_RL78_G14; 333 1.3 christos return 1; 334 1.3 christos 335 1.3 christos case OPTION_32BIT_DOUBLES: 336 1.3 christos elf_flags &= ~ E_FLAG_RL78_64BIT_DOUBLES; 337 1.3 christos return 1; 338 1.3 christos 339 1.3 christos case OPTION_64BIT_DOUBLES: 340 1.3 christos elf_flags |= E_FLAG_RL78_64BIT_DOUBLES; 341 1.3 christos return 1; 342 1.1 christos } 343 1.1 christos return 0; 344 1.1 christos } 345 1.1 christos 346 1.3 christos int 347 1.3 christos rl78_isa_g10 (void) 348 1.3 christos { 349 1.3 christos return (elf_flags & E_FLAG_RL78_CPU_MASK) == E_FLAG_RL78_G10; 350 1.3 christos } 351 1.3 christos 352 1.3 christos int 353 1.3 christos rl78_isa_g13 (void) 354 1.3 christos { 355 1.3 christos return (elf_flags & E_FLAG_RL78_CPU_MASK) == E_FLAG_RL78_G13; 356 1.3 christos } 357 1.3 christos 358 1.3 christos int 359 1.3 christos rl78_isa_g14 (void) 360 1.3 christos { 361 1.3 christos return (elf_flags & E_FLAG_RL78_CPU_MASK) == E_FLAG_RL78_G14; 362 1.3 christos } 363 1.3 christos 364 1.1 christos void 365 1.3 christos md_show_usage (FILE * stream) 366 1.1 christos { 367 1.3 christos fprintf (stream, _(" RL78 specific command line options:\n")); 368 1.3 christos fprintf (stream, _(" --mrelax Enable link time relaxation\n")); 369 1.3 christos fprintf (stream, _(" --mg10 Enable support for G10 variant\n")); 370 1.3 christos fprintf (stream, _(" --mg13 Selects the G13 core.\n")); 371 1.3 christos fprintf (stream, _(" --mg14 Selects the G14 core [default]\n")); 372 1.3 christos fprintf (stream, _(" --mrl78 Alias for --mg14\n")); 373 1.3 christos fprintf (stream, _(" --m32bit-doubles [default]\n")); 374 1.3 christos fprintf (stream, _(" --m64bit-doubles Source code uses 64-bit doubles\n")); 375 1.1 christos } 376 1.1 christos 377 1.1 christos static void 378 1.3 christos rl78_float_cons (int ignore ATTRIBUTE_UNUSED) 379 1.3 christos { 380 1.3 christos if (elf_flags & E_FLAG_RL78_64BIT_DOUBLES) 381 1.3 christos return float_cons ('d'); 382 1.3 christos return float_cons ('f'); 383 1.3 christos } 384 1.3 christos 385 1.1 christos /* The target specific pseudo-ops which we support. */ 386 1.1 christos const pseudo_typeS md_pseudo_table[] = 387 1.1 christos { 388 1.3 christos /* Our "standard" pseudos. */ 389 1.3 christos { "double", rl78_float_cons, 'd' }, 390 1.3 christos { "3byte", cons, 3 }, 391 1.3 christos { "int", cons, 4 }, 392 1.3 christos { "word", cons, 4 }, 393 1.1 christos 394 1.1 christos /* End of list marker. */ 395 1.1 christos { NULL, NULL, 0 } 396 1.1 christos }; 397 1.1 christos 398 1.3 christos static symbolS * rl78_abs_sym = NULL; 399 1.3 christos 400 1.1 christos void 401 1.1 christos md_begin (void) 402 1.1 christos { 403 1.3 christos rl78_abs_sym = symbol_make ("__rl78_abs__"); 404 1.1 christos } 405 1.1 christos 406 1.1 christos void 407 1.1 christos rl78_md_end (void) 408 1.1 christos { 409 1.1 christos } 410 1.1 christos 411 1.3 christos /* Set the ELF specific flags. */ 412 1.3 christos void 413 1.3 christos rl78_elf_final_processing (void) 414 1.3 christos { 415 1.3 christos elf_elfheader (stdoutput)->e_flags |= elf_flags; 416 1.3 christos } 417 1.3 christos 418 1.1 christos /* Write a value out to the object file, using the appropriate endianness. */ 419 1.1 christos void 420 1.1 christos md_number_to_chars (char * buf, valueT val, int n) 421 1.1 christos { 422 1.1 christos number_to_chars_littleendian (buf, val, n); 423 1.1 christos } 424 1.1 christos 425 1.3 christos static void 426 1.5 christos require_end_of_expr (const char *fname) 427 1.3 christos { 428 1.10 christos while (is_whitespace (* input_line_pointer)) 429 1.3 christos input_line_pointer ++; 430 1.3 christos 431 1.10 christos if (is_end_of_stmt (* input_line_pointer) 432 1.10 christos || * input_line_pointer == ',' 433 1.3 christos || strchr (comment_chars, * input_line_pointer) 434 1.10 christos || strchr (line_comment_chars, * input_line_pointer)) 435 1.3 christos return; 436 1.3 christos 437 1.3 christos as_bad (_("%%%s() must be outermost term in expression"), fname); 438 1.3 christos } 439 1.3 christos 440 1.1 christos static struct 441 1.1 christos { 442 1.5 christos const char * fname; 443 1.1 christos int reloc; 444 1.1 christos } 445 1.1 christos reloc_functions[] = 446 1.1 christos { 447 1.3 christos { "code", BFD_RELOC_RL78_CODE }, 448 1.1 christos { "lo16", BFD_RELOC_RL78_LO16 }, 449 1.1 christos { "hi16", BFD_RELOC_RL78_HI16 }, 450 1.1 christos { "hi8", BFD_RELOC_RL78_HI8 }, 451 1.1 christos { 0, 0 } 452 1.1 christos }; 453 1.1 christos 454 1.1 christos void 455 1.1 christos md_operand (expressionS * exp ATTRIBUTE_UNUSED) 456 1.1 christos { 457 1.1 christos int reloc = 0; 458 1.1 christos int i; 459 1.1 christos 460 1.1 christos for (i = 0; reloc_functions[i].fname; i++) 461 1.1 christos { 462 1.1 christos int flen = strlen (reloc_functions[i].fname); 463 1.1 christos 464 1.1 christos if (input_line_pointer[0] == '%' 465 1.1 christos && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0 466 1.1 christos && input_line_pointer[flen + 1] == '(') 467 1.1 christos { 468 1.1 christos reloc = reloc_functions[i].reloc; 469 1.1 christos input_line_pointer += flen + 2; 470 1.1 christos break; 471 1.1 christos } 472 1.1 christos } 473 1.1 christos if (reloc == 0) 474 1.1 christos return; 475 1.1 christos 476 1.1 christos expression (exp); 477 1.1 christos if (* input_line_pointer == ')') 478 1.1 christos input_line_pointer ++; 479 1.1 christos 480 1.1 christos exp->X_md = reloc; 481 1.3 christos 482 1.3 christos require_end_of_expr (reloc_functions[i].fname); 483 1.1 christos } 484 1.1 christos 485 1.1 christos void 486 1.1 christos rl78_frag_init (fragS * fragP) 487 1.1 christos { 488 1.1 christos if (rl78_bytes.n_relax || rl78_bytes.link_relax) 489 1.1 christos { 490 1.5 christos fragP->tc_frag_data = XNEW (rl78_bytesT); 491 1.1 christos memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT)); 492 1.1 christos } 493 1.1 christos else 494 1.1 christos fragP->tc_frag_data = 0; 495 1.1 christos } 496 1.1 christos 497 1.1 christos /* When relaxing, we need to output a reloc for any .align directive 498 1.1 christos so that we can retain this alignment as we adjust opcode sizes. */ 499 1.1 christos void 500 1.1 christos rl78_handle_align (fragS * frag) 501 1.1 christos { 502 1.1 christos if (linkrelax 503 1.1 christos && (frag->fr_type == rs_align 504 1.1 christos || frag->fr_type == rs_align_code) 505 1.1 christos && frag->fr_address + frag->fr_fix > 0 506 1.1 christos && frag->fr_offset > 0 507 1.1 christos && now_seg != bss_section) 508 1.1 christos { 509 1.1 christos fix_new (frag, frag->fr_fix, 0, 510 1.1 christos &abs_symbol, RL78_RELAXA_ALIGN + frag->fr_offset, 511 1.1 christos 0, BFD_RELOC_RL78_RELAX); 512 1.1 christos /* For the purposes of relaxation, this relocation is attached 513 1.1 christos to the byte *after* the alignment - i.e. the byte that must 514 1.1 christos remain aligned. */ 515 1.1 christos fix_new (frag->fr_next, 0, 0, 516 1.1 christos &abs_symbol, RL78_RELAXA_ELIGN + frag->fr_offset, 517 1.1 christos 0, BFD_RELOC_RL78_RELAX); 518 1.1 christos } 519 1.1 christos } 520 1.1 christos 521 1.5 christos const char * 522 1.1 christos md_atof (int type, char * litP, int * sizeP) 523 1.1 christos { 524 1.1 christos return ieee_md_atof (type, litP, sizeP, target_big_endian); 525 1.1 christos } 526 1.1 christos 527 1.1 christos symbolS * 528 1.1 christos md_undefined_symbol (char * name ATTRIBUTE_UNUSED) 529 1.1 christos { 530 1.1 christos return NULL; 531 1.1 christos } 532 1.1 christos 533 1.1 christos #define APPEND(B, N_B) \ 534 1.1 christos if (rl78_bytes.N_B) \ 535 1.1 christos { \ 536 1.1 christos memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B); \ 537 1.1 christos idx += rl78_bytes.N_B; \ 538 1.1 christos } 539 1.1 christos 540 1.1 christos 541 1.1 christos void 542 1.1 christos md_assemble (char * str) 543 1.1 christos { 544 1.1 christos char * bytes; 545 1.1 christos fragS * frag_then = frag_now; 546 1.1 christos int idx = 0; 547 1.1 christos int i; 548 1.1 christos int rel; 549 1.1 christos expressionS *exp; 550 1.1 christos 551 1.1 christos /*printf("\033[32mASM: %s\033[0m\n", str);*/ 552 1.1 christos 553 1.1 christos dwarf2_emit_insn (0); 554 1.1 christos 555 1.1 christos memset (& rl78_bytes, 0, sizeof (rl78_bytes)); 556 1.1 christos 557 1.1 christos rl78_lex_init (str, str + strlen (str)); 558 1.1 christos 559 1.1 christos rl78_parse (); 560 1.1 christos 561 1.1 christos /* This simplifies the relaxation code. */ 562 1.3 christos if (rl78_bytes.n_relax || rl78_bytes.link_relax) 563 1.1 christos { 564 1.1 christos int olen = rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops; 565 1.1 christos /* We do it this way because we want the frag to have the 566 1.3 christos rl78_bytes in it, which we initialize above. The extra bytes 567 1.3 christos are for relaxing. */ 568 1.3 christos bytes = frag_more (olen + 3); 569 1.1 christos frag_then = frag_now; 570 1.1 christos frag_variant (rs_machine_dependent, 571 1.1 christos olen /* max_chars */, 572 1.1 christos 0 /* var */, 573 1.1 christos olen /* subtype */, 574 1.1 christos 0 /* symbol */, 575 1.1 christos 0 /* offset */, 576 1.1 christos 0 /* opcode */); 577 1.1 christos frag_then->fr_opcode = bytes; 578 1.1 christos frag_then->fr_fix = olen + (bytes - frag_then->fr_literal); 579 1.1 christos frag_then->fr_subtype = olen; 580 1.1 christos frag_then->fr_var = 0; 581 1.1 christos } 582 1.1 christos else 583 1.1 christos { 584 1.1 christos bytes = frag_more (rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops); 585 1.1 christos frag_then = frag_now; 586 1.1 christos } 587 1.1 christos 588 1.1 christos APPEND (prefix, n_prefix); 589 1.1 christos APPEND (base, n_base); 590 1.1 christos APPEND (ops, n_ops); 591 1.1 christos 592 1.1 christos if (rl78_bytes.link_relax) 593 1.1 christos { 594 1.1 christos fixS * f; 595 1.1 christos 596 1.1 christos f = fix_new (frag_then, 597 1.1 christos (char *) bytes - frag_then->fr_literal, 598 1.1 christos 0, 599 1.1 christos abs_section_sym, 600 1.1 christos rl78_bytes.link_relax | rl78_bytes.n_fixups, 601 1.1 christos 0, 602 1.1 christos BFD_RELOC_RL78_RELAX); 603 1.1 christos frag_then->tc_frag_data->link_relax_fixP = f; 604 1.1 christos } 605 1.1 christos 606 1.1 christos for (i = 0; i < rl78_bytes.n_fixups; i ++) 607 1.1 christos { 608 1.1 christos /* index: [nbytes][type] */ 609 1.1 christos static int reloc_map[5][4] = 610 1.1 christos { 611 1.1 christos { 0, 0 }, 612 1.1 christos { BFD_RELOC_8, BFD_RELOC_8_PCREL }, 613 1.1 christos { BFD_RELOC_16, BFD_RELOC_16_PCREL }, 614 1.1 christos { BFD_RELOC_24, BFD_RELOC_24_PCREL }, 615 1.1 christos { BFD_RELOC_32, BFD_RELOC_32_PCREL }, 616 1.1 christos }; 617 1.1 christos fixS * f; 618 1.1 christos 619 1.1 christos idx = rl78_bytes.fixups[i].offset / 8; 620 1.1 christos rel = reloc_map [rl78_bytes.fixups[i].nbits / 8][(int) rl78_bytes.fixups[i].type]; 621 1.1 christos 622 1.1 christos if (rl78_bytes.fixups[i].reloc) 623 1.1 christos rel = rl78_bytes.fixups[i].reloc; 624 1.1 christos 625 1.1 christos if (frag_then->tc_frag_data) 626 1.1 christos exp = & frag_then->tc_frag_data->fixups[i].exp; 627 1.1 christos else 628 1.1 christos exp = & rl78_bytes.fixups[i].exp; 629 1.1 christos 630 1.1 christos f = fix_new_exp (frag_then, 631 1.1 christos (char *) bytes + idx - frag_then->fr_literal, 632 1.1 christos rl78_bytes.fixups[i].nbits / 8, 633 1.1 christos exp, 634 1.1 christos rl78_bytes.fixups[i].type == RL78REL_PCREL ? 1 : 0, 635 1.1 christos rel); 636 1.1 christos if (frag_then->tc_frag_data) 637 1.1 christos frag_then->tc_frag_data->fixups[i].fixP = f; 638 1.1 christos } 639 1.1 christos } 640 1.1 christos 641 1.1 christos void 642 1.1 christos rl78_cons_fix_new (fragS * frag, 643 1.1 christos int where, 644 1.1 christos int size, 645 1.1 christos expressionS * exp) 646 1.1 christos { 647 1.1 christos bfd_reloc_code_real_type type; 648 1.3 christos fixS *fixP; 649 1.1 christos 650 1.1 christos switch (size) 651 1.1 christos { 652 1.1 christos case 1: 653 1.1 christos type = BFD_RELOC_8; 654 1.1 christos break; 655 1.1 christos case 2: 656 1.1 christos type = BFD_RELOC_16; 657 1.1 christos break; 658 1.1 christos case 3: 659 1.1 christos type = BFD_RELOC_24; 660 1.1 christos break; 661 1.1 christos case 4: 662 1.1 christos type = BFD_RELOC_32; 663 1.1 christos break; 664 1.1 christos default: 665 1.1 christos as_bad (_("unsupported constant size %d\n"), size); 666 1.1 christos return; 667 1.1 christos } 668 1.1 christos 669 1.3 christos switch (exp->X_md) 670 1.3 christos { 671 1.3 christos case BFD_RELOC_RL78_CODE: 672 1.3 christos if (size == 2) 673 1.3 christos type = exp->X_md; 674 1.3 christos break; 675 1.3 christos case BFD_RELOC_RL78_LO16: 676 1.3 christos case BFD_RELOC_RL78_HI16: 677 1.3 christos if (size != 2) 678 1.3 christos { 679 1.3 christos /* Fixups to assembler generated expressions do not use %hi or %lo. */ 680 1.3 christos if (frag->fr_file) 681 1.3 christos as_bad (_("%%hi16/%%lo16 only applies to .short or .hword")); 682 1.3 christos } 683 1.3 christos else 684 1.3 christos type = exp->X_md; 685 1.3 christos break; 686 1.3 christos case BFD_RELOC_RL78_HI8: 687 1.3 christos if (size != 1) 688 1.3 christos { 689 1.3 christos /* Fixups to assembler generated expressions do not use %hi or %lo. */ 690 1.3 christos if (frag->fr_file) 691 1.3 christos as_bad (_("%%hi8 only applies to .byte")); 692 1.3 christos } 693 1.3 christos else 694 1.3 christos type = exp->X_md; 695 1.3 christos break; 696 1.3 christos default: 697 1.3 christos break; 698 1.3 christos } 699 1.3 christos 700 1.1 christos if (exp->X_op == O_subtract && exp->X_op_symbol) 701 1.1 christos { 702 1.1 christos if (size != 4 && size != 2 && size != 1) 703 1.1 christos as_bad (_("difference of two symbols only supported with .long, .short, or .byte")); 704 1.1 christos else 705 1.1 christos type = BFD_RELOC_RL78_DIFF; 706 1.1 christos } 707 1.1 christos 708 1.10 christos fixP = fix_new_exp (frag, where, size, exp, 0, type); 709 1.3 christos switch (exp->X_md) 710 1.3 christos { 711 1.3 christos /* These are intended to have values larger than the container, 712 1.3 christos since the backend puts only the portion we need in it. 713 1.3 christos However, we don't have a backend-specific reloc for them as 714 1.3 christos they're handled with complex relocations. */ 715 1.3 christos case BFD_RELOC_RL78_LO16: 716 1.3 christos case BFD_RELOC_RL78_HI16: 717 1.3 christos case BFD_RELOC_RL78_HI8: 718 1.3 christos fixP->fx_no_overflow = 1; 719 1.3 christos break; 720 1.3 christos default: 721 1.3 christos break; 722 1.3 christos } 723 1.3 christos } 724 1.3 christos 725 1.3 christos 726 1.3 christos /*----------------------------------------------------------------------*/ 728 1.3 christos /* To recap: we estimate everything based on md_estimate_size, then 729 1.3 christos adjust based on rl78_relax_frag. When it all settles, we call 730 1.3 christos md_convert frag to update the bytes. The relaxation types and 731 1.3 christos relocations are in fragP->tc_frag_data, which is a copy of that 732 1.3 christos rl78_bytes. 733 1.3 christos 734 1.3 christos Our scheme is as follows: fr_fix has the size of the smallest 735 1.3 christos opcode (like BRA.S). We store the number of total bytes we need in 736 1.3 christos fr_subtype. When we're done relaxing, we use fr_subtype and the 737 1.3 christos existing opcode bytes to figure out what actual opcode we need to 738 1.3 christos put in there. If the fixup isn't resolvable now, we use the 739 1.3 christos maximal size. */ 740 1.3 christos 741 1.3 christos #define TRACE_RELAX 0 742 1.3 christos #define tprintf if (TRACE_RELAX) printf 743 1.3 christos 744 1.3 christos 745 1.3 christos typedef enum 746 1.3 christos { 747 1.3 christos OT_other, 748 1.3 christos OT_bt, 749 1.3 christos OT_bt_sfr, 750 1.3 christos OT_bt_es, 751 1.5 christos OT_bc, 752 1.5 christos OT_bh, 753 1.5 christos OT_sk, 754 1.5 christos OT_call, 755 1.3 christos OT_br, 756 1.3 christos } op_type_T; 757 1.3 christos 758 1.3 christos /* We're looking for these types of relaxations: 759 1.3 christos 760 1.3 christos BT 00110001 sbit0cc1 addr---- (cc is 10 (BF) or 01 (BT)) 761 1.3 christos B~T 00110001 sbit0cc1 00000011 11101110 pcrel16- -------- (BR $!pcrel20) 762 1.3 christos 763 1.3 christos BT sfr 00110001 sbit0cc0 sfr----- addr---- 764 1.3 christos BT ES: 00010001 00101110 sbit0cc1 addr---- 765 1.3 christos 766 1.3 christos BC 110111cc addr---- 767 1.3 christos B~C 110111cc 00000011 11101110 pcrel16- -------- (BR $!pcrel20) 768 1.3 christos 769 1.3 christos BH 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20) 770 1.3 christos B~H 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20) 771 1.3 christos */ 772 1.3 christos 773 1.3 christos /* Given the opcode bytes at OP, figure out which opcode it is and 774 1.3 christos return the type of opcode. We use this to re-encode the opcode as 775 1.3 christos a different size later. */ 776 1.3 christos 777 1.5 christos static op_type_T 778 1.3 christos rl78_opcode_type (char * ops) 779 1.5 christos { 780 1.5 christos unsigned char *op = (unsigned char *)ops; 781 1.3 christos 782 1.3 christos if (op[0] == 0x31 783 1.3 christos && ((op[1] & 0x0f) == 0x05 784 1.3 christos || (op[1] & 0x0f) == 0x03)) 785 1.3 christos return OT_bt; 786 1.3 christos 787 1.3 christos if (op[0] == 0x31 788 1.3 christos && ((op[1] & 0x0f) == 0x04 789 1.3 christos || (op[1] & 0x0f) == 0x02)) 790 1.3 christos return OT_bt_sfr; 791 1.3 christos 792 1.3 christos if (op[0] == 0x11 793 1.3 christos && op[1] == 0x31 794 1.3 christos && ((op[2] & 0x0f) == 0x05 795 1.3 christos || (op[2] & 0x0f) == 0x03)) 796 1.3 christos return OT_bt_es; 797 1.3 christos 798 1.3 christos if ((op[0] & 0xfc) == 0xdc) 799 1.3 christos return OT_bc; 800 1.3 christos 801 1.3 christos if (op[0] == 0x61 802 1.3 christos && (op[1] & 0xef) == 0xc3) 803 1.3 christos return OT_bh; 804 1.5 christos 805 1.5 christos if (op[0] == 0x61 806 1.5 christos && (op[1] & 0xcf) == 0xc8) 807 1.5 christos return OT_sk; 808 1.5 christos 809 1.5 christos if (op[0] == 0x61 810 1.5 christos && (op[1] & 0xef) == 0xe3) 811 1.5 christos return OT_sk; 812 1.5 christos 813 1.5 christos if (op[0] == 0xfc) 814 1.5 christos return OT_call; 815 1.5 christos 816 1.5 christos if ((op[0] & 0xec) == 0xec) 817 1.5 christos return OT_br; 818 1.3 christos 819 1.3 christos return OT_other; 820 1.3 christos } 821 1.3 christos 822 1.3 christos /* Returns zero if *addrP has the target address. Else returns nonzero 823 1.3 christos if we cannot compute the target address yet. */ 824 1.3 christos 825 1.3 christos static int 826 1.3 christos rl78_frag_fix_value (fragS * fragP, 827 1.3 christos segT segment, 828 1.3 christos int which, 829 1.3 christos addressT * addrP, 830 1.3 christos int need_diff, 831 1.3 christos addressT * sym_addr) 832 1.3 christos { 833 1.3 christos addressT addr = 0; 834 1.3 christos rl78_bytesT * b = fragP->tc_frag_data; 835 1.3 christos expressionS * exp = & b->fixups[which].exp; 836 1.3 christos 837 1.3 christos if (need_diff && exp->X_op != O_subtract) 838 1.3 christos return 1; 839 1.3 christos 840 1.3 christos if (exp->X_add_symbol) 841 1.3 christos { 842 1.3 christos if (S_FORCE_RELOC (exp->X_add_symbol, 1)) 843 1.3 christos return 1; 844 1.3 christos if (S_GET_SEGMENT (exp->X_add_symbol) != segment) 845 1.3 christos return 1; 846 1.3 christos addr += S_GET_VALUE (exp->X_add_symbol); 847 1.3 christos } 848 1.3 christos 849 1.3 christos if (exp->X_op_symbol) 850 1.3 christos { 851 1.3 christos if (exp->X_op != O_subtract) 852 1.3 christos return 1; 853 1.3 christos if (S_FORCE_RELOC (exp->X_op_symbol, 1)) 854 1.3 christos return 1; 855 1.3 christos if (S_GET_SEGMENT (exp->X_op_symbol) != segment) 856 1.3 christos return 1; 857 1.3 christos addr -= S_GET_VALUE (exp->X_op_symbol); 858 1.3 christos } 859 1.3 christos if (sym_addr) 860 1.3 christos * sym_addr = addr; 861 1.3 christos addr += exp->X_add_number; 862 1.3 christos * addrP = addr; 863 1.1 christos return 0; 864 1.1 christos } 865 1.3 christos 866 1.3 christos /* Estimate how big the opcode is after this relax pass. The return 867 1.3 christos value is the difference between fr_fix and the actual size. We 868 1.3 christos compute the total size in rl78_relax_frag and store it in fr_subtype, 869 1.3 christos so we only need to subtract fx_fix and return it. */ 870 1.1 christos 871 1.1 christos int 872 1.1 christos md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED) 873 1.3 christos { 874 1.3 christos int opfixsize; 875 1.3 christos int delta; 876 1.3 christos 877 1.3 christos /* This is the size of the opcode that's accounted for in fr_fix. */ 878 1.3 christos opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal); 879 1.3 christos /* This is the size of the opcode that isn't. */ 880 1.3 christos delta = (fragP->fr_subtype - opfixsize); 881 1.3 christos 882 1.3 christos tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta); 883 1.3 christos return delta; 884 1.3 christos } 885 1.3 christos 886 1.3 christos /* Given the new addresses for this relax pass, figure out how big 887 1.3 christos each opcode must be. We store the total number of bytes needed in 888 1.3 christos fr_subtype. The return value is the difference between the size 889 1.3 christos after the last pass and the size after this pass, so we use the old 890 1.3 christos fr_subtype to calculate the difference. */ 891 1.3 christos 892 1.3 christos int 893 1.3 christos rl78_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch) 894 1.3 christos { 895 1.3 christos addressT addr0, sym_addr; 896 1.3 christos addressT mypc; 897 1.3 christos int disp; 898 1.3 christos int oldsize = fragP->fr_subtype; 899 1.3 christos int newsize = oldsize; 900 1.3 christos op_type_T optype; 901 1.3 christos int ri; 902 1.3 christos 903 1.3 christos mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal); 904 1.3 christos 905 1.3 christos /* If we ever get more than one reloc per opcode, this is the one 906 1.3 christos we're relaxing. */ 907 1.3 christos ri = 0; 908 1.3 christos 909 1.3 christos optype = rl78_opcode_type (fragP->fr_opcode); 910 1.3 christos /* Try to get the target address. */ 911 1.3 christos if (rl78_frag_fix_value (fragP, segment, ri, & addr0, 912 1.3 christos fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH, 913 1.3 christos & sym_addr)) 914 1.5 christos { 915 1.5 christos /* If we don't expect the linker to do relaxing, don't emit 916 1.5 christos expanded opcodes that only the linker will relax. */ 917 1.5 christos if (!linkrelax) 918 1.5 christos return newsize - oldsize; 919 1.3 christos 920 1.3 christos /* If we don't, we must use the maximum size for the linker. */ 921 1.3 christos switch (fragP->tc_frag_data->relax[ri].type) 922 1.3 christos { 923 1.3 christos case RL78_RELAX_BRANCH: 924 1.3 christos switch (optype) 925 1.3 christos { 926 1.3 christos case OT_bt: 927 1.3 christos newsize = 6; 928 1.3 christos break; 929 1.3 christos case OT_bt_sfr: 930 1.3 christos case OT_bt_es: 931 1.3 christos newsize = 7; 932 1.3 christos break; 933 1.3 christos case OT_bc: 934 1.3 christos newsize = 5; 935 1.3 christos break; 936 1.3 christos case OT_bh: 937 1.3 christos newsize = 6; 938 1.5 christos break; 939 1.5 christos case OT_sk: 940 1.5 christos newsize = 2; 941 1.5 christos break; 942 1.3 christos default: 943 1.3 christos newsize = oldsize; 944 1.3 christos break; 945 1.3 christos } 946 1.3 christos break; 947 1.3 christos 948 1.3 christos } 949 1.3 christos fragP->fr_subtype = newsize; 950 1.3 christos tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize); 951 1.3 christos return newsize - oldsize; 952 1.3 christos } 953 1.3 christos 954 1.3 christos if (sym_addr > mypc) 955 1.3 christos addr0 += stretch; 956 1.3 christos 957 1.3 christos switch (fragP->tc_frag_data->relax[ri].type) 958 1.3 christos { 959 1.3 christos case RL78_RELAX_BRANCH: 960 1.3 christos disp = (int) addr0 - (int) mypc; 961 1.3 christos 962 1.3 christos switch (optype) 963 1.3 christos { 964 1.3 christos case OT_bt: 965 1.3 christos if (disp >= -128 && (disp - (oldsize-2)) <= 127) 966 1.3 christos newsize = 3; 967 1.3 christos else 968 1.3 christos newsize = 6; 969 1.3 christos break; 970 1.3 christos case OT_bt_sfr: 971 1.3 christos case OT_bt_es: 972 1.3 christos if (disp >= -128 && (disp - (oldsize-3)) <= 127) 973 1.3 christos newsize = 4; 974 1.3 christos else 975 1.3 christos newsize = 7; 976 1.3 christos break; 977 1.3 christos case OT_bc: 978 1.3 christos if (disp >= -128 && (disp - (oldsize-1)) <= 127) 979 1.3 christos newsize = 2; 980 1.3 christos else 981 1.3 christos newsize = 5; 982 1.3 christos break; 983 1.3 christos case OT_bh: 984 1.3 christos if (disp >= -128 && (disp - (oldsize-2)) <= 127) 985 1.3 christos newsize = 3; 986 1.3 christos else 987 1.3 christos newsize = 6; 988 1.5 christos break; 989 1.5 christos case OT_sk: 990 1.5 christos newsize = 2; 991 1.5 christos break; 992 1.3 christos default: 993 1.3 christos newsize = oldsize; 994 1.3 christos break; 995 1.3 christos } 996 1.3 christos break; 997 1.3 christos } 998 1.3 christos 999 1.3 christos /* This prevents infinite loops in align-heavy sources. */ 1000 1.3 christos if (newsize < oldsize) 1001 1.3 christos { 1002 1.3 christos if (fragP->tc_frag_data->times_shrank > 10 1003 1.3 christos && fragP->tc_frag_data->times_grown > 10) 1004 1.3 christos newsize = oldsize; 1005 1.3 christos if (fragP->tc_frag_data->times_shrank < 20) 1006 1.3 christos fragP->tc_frag_data->times_shrank ++; 1007 1.3 christos } 1008 1.3 christos else if (newsize > oldsize) 1009 1.3 christos { 1010 1.3 christos if (fragP->tc_frag_data->times_grown < 20) 1011 1.3 christos fragP->tc_frag_data->times_grown ++; 1012 1.3 christos } 1013 1.3 christos 1014 1.3 christos fragP->fr_subtype = newsize; 1015 1.3 christos tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize); 1016 1.1 christos return newsize - oldsize; 1017 1.1 christos } 1018 1.3 christos 1019 1.3 christos /* This lets us test for the opcode type and the desired size in a 1020 1.3 christos switch statement. */ 1021 1.3 christos #define OPCODE(type,size) ((type) * 16 + (size)) 1022 1.3 christos 1023 1.3 christos /* Given the opcode stored in fr_opcode and the number of bytes we 1024 1.3 christos think we need, encode a new opcode. We stored a pointer to the 1025 1.3 christos fixup for this opcode in the tc_frag_data structure. If we can do 1026 1.3 christos the fixup here, we change the relocation type to "none" (we test 1027 1.3 christos for that in tc_gen_reloc) else we change it to the right type for 1028 1.3 christos the new (biggest) opcode. */ 1029 1.3 christos 1030 1.3 christos void 1031 1.3 christos md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, 1032 1.3 christos segT segment ATTRIBUTE_UNUSED, 1033 1.3 christos fragS * fragP ATTRIBUTE_UNUSED) 1034 1.3 christos { 1035 1.3 christos rl78_bytesT * rl78b = fragP->tc_frag_data; 1036 1.3 christos addressT addr0, mypc; 1037 1.3 christos int disp; 1038 1.3 christos int reloc_type, reloc_adjust; 1039 1.3 christos char * op = fragP->fr_opcode; 1040 1.3 christos int keep_reloc = 0; 1041 1.3 christos int ri; 1042 1.3 christos int fi = (rl78b->n_fixups > 1) ? 1 : 0; 1043 1.3 christos fixS * fix = rl78b->fixups[fi].fixP; 1044 1.3 christos 1045 1.3 christos /* If we ever get more than one reloc per opcode, this is the one 1046 1.3 christos we're relaxing. */ 1047 1.3 christos ri = 0; 1048 1.3 christos 1049 1.3 christos /* We used a new frag for this opcode, so the opcode address should 1050 1.3 christos be the frag address. */ 1051 1.3 christos mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal); 1052 1.3 christos tprintf ("\033[32mmypc: 0x%x\033[0m\n", (int)mypc); 1053 1.3 christos 1054 1.3 christos /* Try to get the target address. If we fail here, we just use the 1055 1.3 christos largest format. */ 1056 1.3 christos if (rl78_frag_fix_value (fragP, segment, 0, & addr0, 1057 1.3 christos fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH, 0)) 1058 1.3 christos { 1059 1.3 christos /* We don't know the target address. */ 1060 1.3 christos keep_reloc = 1; 1061 1.3 christos addr0 = 0; 1062 1.3 christos disp = 0; 1063 1.3 christos tprintf ("unknown addr ? - %x = ?\n", (int)mypc); 1064 1.3 christos } 1065 1.3 christos else 1066 1.3 christos { 1067 1.3 christos /* We know the target address, and it's in addr0. */ 1068 1.3 christos disp = (int) addr0 - (int) mypc; 1069 1.3 christos tprintf ("known addr %x - %x = %d\n", (int)addr0, (int)mypc, disp); 1070 1.3 christos } 1071 1.3 christos 1072 1.3 christos if (linkrelax) 1073 1.3 christos keep_reloc = 1; 1074 1.3 christos 1075 1.3 christos reloc_type = BFD_RELOC_NONE; 1076 1.3 christos reloc_adjust = 0; 1077 1.3 christos 1078 1.3 christos switch (fragP->tc_frag_data->relax[ri].type) 1079 1.3 christos { 1080 1.3 christos case RL78_RELAX_BRANCH: 1081 1.3 christos switch (OPCODE (rl78_opcode_type (fragP->fr_opcode), fragP->fr_subtype)) 1082 1.3 christos { 1083 1.3 christos 1084 1.3 christos case OPCODE (OT_bt, 3): /* BT A,$ - no change. */ 1085 1.3 christos disp -= 3; 1086 1.5 christos op[2] = disp; 1087 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE; 1088 1.3 christos break; 1089 1.3 christos 1090 1.3 christos case OPCODE (OT_bt, 6): /* BT A,$ - long version. */ 1091 1.3 christos disp -= 3; 1092 1.3 christos op[1] ^= 0x06; /* toggle conditional. */ 1093 1.3 christos op[2] = 3; /* displacement over long branch. */ 1094 1.3 christos disp -= 3; 1095 1.3 christos op[3] = 0xEE; /* BR $!addr20 */ 1096 1.3 christos op[4] = disp & 0xff; 1097 1.3 christos op[5] = disp >> 8; 1098 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE; 1099 1.3 christos reloc_adjust = 2; 1100 1.3 christos break; 1101 1.3 christos 1102 1.3 christos case OPCODE (OT_bt_sfr, 4): /* BT PSW,$ - no change. */ 1103 1.3 christos disp -= 4; 1104 1.5 christos op[3] = disp; 1105 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE; 1106 1.3 christos break; 1107 1.3 christos 1108 1.3 christos case OPCODE (OT_bt_sfr, 7): /* BT PSW,$ - long version. */ 1109 1.3 christos disp -= 4; 1110 1.3 christos op[1] ^= 0x06; /* toggle conditional. */ 1111 1.3 christos op[3] = 3; /* displacement over long branch. */ 1112 1.3 christos disp -= 3; 1113 1.3 christos op[4] = 0xEE; /* BR $!addr20 */ 1114 1.3 christos op[5] = disp & 0xff; 1115 1.3 christos op[6] = disp >> 8; 1116 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE; 1117 1.3 christos reloc_adjust = 2; 1118 1.3 christos break; 1119 1.3 christos 1120 1.3 christos case OPCODE (OT_bt_es, 4): /* BT ES:[HL],$ - no change. */ 1121 1.3 christos disp -= 4; 1122 1.5 christos op[3] = disp; 1123 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE; 1124 1.3 christos break; 1125 1.3 christos 1126 1.3 christos case OPCODE (OT_bt_es, 7): /* BT PSW,$ - long version. */ 1127 1.3 christos disp -= 4; 1128 1.3 christos op[2] ^= 0x06; /* toggle conditional. */ 1129 1.3 christos op[3] = 3; /* displacement over long branch. */ 1130 1.3 christos disp -= 3; 1131 1.3 christos op[4] = 0xEE; /* BR $!addr20 */ 1132 1.3 christos op[5] = disp & 0xff; 1133 1.3 christos op[6] = disp >> 8; 1134 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE; 1135 1.3 christos reloc_adjust = 2; 1136 1.3 christos break; 1137 1.3 christos 1138 1.3 christos case OPCODE (OT_bc, 2): /* BC $ - no change. */ 1139 1.3 christos disp -= 2; 1140 1.5 christos op[1] = disp; 1141 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE; 1142 1.3 christos break; 1143 1.3 christos 1144 1.3 christos case OPCODE (OT_bc, 5): /* BC $ - long version. */ 1145 1.3 christos disp -= 2; 1146 1.3 christos op[0] ^= 0x02; /* toggle conditional. */ 1147 1.3 christos op[1] = 3; 1148 1.3 christos disp -= 3; 1149 1.3 christos op[2] = 0xEE; /* BR $!addr20 */ 1150 1.3 christos op[3] = disp & 0xff; 1151 1.3 christos op[4] = disp >> 8; 1152 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE; 1153 1.3 christos reloc_adjust = 2; 1154 1.3 christos break; 1155 1.3 christos 1156 1.3 christos case OPCODE (OT_bh, 3): /* BH $ - no change. */ 1157 1.3 christos disp -= 3; 1158 1.5 christos op[2] = disp; 1159 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE; 1160 1.3 christos break; 1161 1.3 christos 1162 1.3 christos case OPCODE (OT_bh, 6): /* BC $ - long version. */ 1163 1.3 christos disp -= 3; 1164 1.3 christos op[1] ^= 0x10; /* toggle conditional. */ 1165 1.3 christos op[2] = 3; 1166 1.3 christos disp -= 3; 1167 1.3 christos op[3] = 0xEE; /* BR $!addr20 */ 1168 1.3 christos op[4] = disp & 0xff; 1169 1.3 christos op[5] = disp >> 8; 1170 1.3 christos reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE; 1171 1.3 christos reloc_adjust = 2; 1172 1.3 christos break; 1173 1.5 christos 1174 1.5 christos case OPCODE (OT_sk, 2): /* SK<cond> - no change */ 1175 1.5 christos reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE; 1176 1.5 christos break; 1177 1.3 christos 1178 1.5 christos default: 1179 1.5 christos reloc_type = fix ? fix->fx_r_type : BFD_RELOC_NONE; 1180 1.3 christos break; 1181 1.3 christos } 1182 1.3 christos break; 1183 1.3 christos 1184 1.3 christos default: 1185 1.3 christos if (rl78b->n_fixups) 1186 1.3 christos { 1187 1.3 christos reloc_type = fix->fx_r_type; 1188 1.3 christos reloc_adjust = 0; 1189 1.3 christos } 1190 1.3 christos break; 1191 1.3 christos } 1192 1.3 christos 1193 1.3 christos if (rl78b->n_fixups) 1194 1.3 christos { 1195 1.3 christos 1196 1.3 christos fix->fx_r_type = reloc_type; 1197 1.3 christos fix->fx_where += reloc_adjust; 1198 1.3 christos switch (reloc_type) 1199 1.3 christos { 1200 1.3 christos case BFD_RELOC_NONE: 1201 1.3 christos fix->fx_size = 0; 1202 1.3 christos break; 1203 1.3 christos case BFD_RELOC_8: 1204 1.3 christos fix->fx_size = 1; 1205 1.3 christos break; 1206 1.3 christos case BFD_RELOC_16_PCREL: 1207 1.3 christos fix->fx_size = 2; 1208 1.3 christos break; 1209 1.3 christos } 1210 1.3 christos } 1211 1.3 christos 1212 1.3 christos fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal); 1213 1.3 christos tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix, 1214 1.3 christos fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal); 1215 1.3 christos fragP->fr_var = 0; 1216 1.3 christos 1217 1.3 christos tprintf ("compare 0x%lx vs 0x%lx - 0x%lx = 0x%lx (%p)\n", 1218 1.3 christos (long)fragP->fr_fix, 1219 1.3 christos (long)fragP->fr_next->fr_address, (long)fragP->fr_address, 1220 1.3 christos (long)(fragP->fr_next->fr_address - fragP->fr_address), 1221 1.3 christos fragP->fr_next); 1222 1.3 christos 1223 1.7 christos if (fragP->fr_next != NULL 1224 1.3 christos && fragP->fr_next->fr_address - fragP->fr_address != fragP->fr_fix) 1225 1.3 christos as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP, 1226 1.3 christos (long) fragP->fr_fix, 1227 1.3 christos (long) fragP->fr_address, (long) fragP->fr_next->fr_address); 1228 1.3 christos } 1229 1.3 christos 1230 1.3 christos /* End of relaxation code. 1231 1.3 christos ----------------------------------------------------------------------*/ 1232 1.3 christos 1233 1.1 christos 1235 1.1 christos arelent ** 1236 1.1 christos tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp) 1237 1.1 christos { 1238 1.1 christos static arelent * reloc[8]; 1239 1.1 christos int rp; 1240 1.1 christos 1241 1.1 christos if (fixp->fx_r_type == BFD_RELOC_NONE) 1242 1.1 christos { 1243 1.1 christos reloc[0] = NULL; 1244 1.1 christos return reloc; 1245 1.5 christos } 1246 1.5 christos 1247 1.5 christos if (fixp->fx_r_type == BFD_RELOC_RL78_RELAX && !linkrelax) 1248 1.5 christos { 1249 1.5 christos reloc[0] = NULL; 1250 1.5 christos return reloc; 1251 1.1 christos } 1252 1.1 christos 1253 1.1 christos if (fixp->fx_subsy 1254 1.1 christos && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section) 1255 1.1 christos { 1256 1.1 christos fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy); 1257 1.1 christos fixp->fx_subsy = NULL; 1258 1.10 christos } 1259 1.10 christos 1260 1.10 christos reloc[0] = notes_alloc (sizeof (arelent)); 1261 1.10 christos reloc[0]->sym_ptr_ptr = notes_alloc (sizeof (asymbol *)); 1262 1.10 christos *reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 1263 1.1 christos reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where; 1264 1.1 christos reloc[0]->addend = fixp->fx_offset; 1265 1.1 christos 1266 1.1 christos if (fixp->fx_r_type == BFD_RELOC_RL78_32_OP 1267 1.1 christos && fixp->fx_subsy) 1268 1.1 christos { 1269 1.1 christos fixp->fx_r_type = BFD_RELOC_RL78_DIFF; 1270 1.10 christos } 1271 1.10 christos 1272 1.10 christos #define OPX(REL,SYM,ADD) \ 1273 1.10 christos reloc[rp] = notes_alloc (sizeof (arelent)); \ 1274 1.10 christos reloc[rp]->sym_ptr_ptr = notes_alloc (sizeof (asymbol *)); \ 1275 1.10 christos reloc[rp]->howto = bfd_reloc_type_lookup (stdoutput, REL); \ 1276 1.10 christos reloc[rp]->addend = ADD; \ 1277 1.1 christos *reloc[rp]->sym_ptr_ptr = SYM; \ 1278 1.1 christos reloc[rp]->address = fixp->fx_frag->fr_address + fixp->fx_where; \ 1279 1.3 christos reloc[++rp] = NULL 1280 1.3 christos #define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0) 1281 1.3 christos 1282 1.3 christos /* FIXME: We cannot do the normal thing for an immediate value reloc, 1283 1.3 christos ie creating a RL78_SYM reloc in the *ABS* section with an offset 1284 1.3 christos equal to the immediate value we want to store. This fails because 1285 1.3 christos the reloc processing in bfd_perform_relocation and bfd_install_relocation 1286 1.3 christos will short circuit such relocs and never pass them on to the special 1287 1.3 christos reloc processing code. So instead we create a RL78_SYM reloc against 1288 1.3 christos the __rl78_abs__ symbol and arrange for the linker scripts to place 1289 1.3 christos this symbol at address 0. */ 1290 1.1 christos #define OPIMM(IMM) OPX (BFD_RELOC_RL78_SYM, symbol_get_bfdsym (rl78_abs_sym), IMM) 1291 1.1 christos 1292 1.1 christos #define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0) 1293 1.1 christos #define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM) 1294 1.1 christos 1295 1.1 christos rp = 1; 1296 1.1 christos 1297 1.1 christos /* Certain BFD relocations cannot be translated directly into 1298 1.1 christos a single (non-Red Hat) RL78 relocation, but instead need 1299 1.1 christos multiple RL78 relocations - handle them here. */ 1300 1.1 christos switch (fixp->fx_r_type) 1301 1.1 christos { 1302 1.1 christos case BFD_RELOC_RL78_DIFF: 1303 1.1 christos SYM0 (); 1304 1.1 christos OPSYM (symbol_get_bfdsym (fixp->fx_subsy)); 1305 1.1 christos OP(OP_SUBTRACT); 1306 1.1 christos 1307 1.1 christos switch (fixp->fx_size) 1308 1.1 christos { 1309 1.1 christos case 1: 1310 1.1 christos OP(ABS8); 1311 1.1 christos break; 1312 1.1 christos case 2: 1313 1.1 christos OP (ABS16); 1314 1.1 christos break; 1315 1.1 christos case 4: 1316 1.1 christos OP (ABS32); 1317 1.1 christos break; 1318 1.1 christos } 1319 1.1 christos break; 1320 1.1 christos 1321 1.1 christos case BFD_RELOC_RL78_NEG32: 1322 1.1 christos SYM0 (); 1323 1.1 christos OP (OP_NEG); 1324 1.1 christos OP (ABS32); 1325 1.3 christos break; 1326 1.3 christos 1327 1.3 christos case BFD_RELOC_RL78_CODE: 1328 1.3 christos reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_16U); 1329 1.3 christos reloc[1] = NULL; 1330 1.1 christos break; 1331 1.1 christos 1332 1.1 christos case BFD_RELOC_RL78_LO16: 1333 1.1 christos SYM0 (); 1334 1.1 christos OPIMM (0xffff); 1335 1.1 christos OP (OP_AND); 1336 1.1 christos OP (ABS16); 1337 1.1 christos break; 1338 1.1 christos 1339 1.1 christos case BFD_RELOC_RL78_HI16: 1340 1.1 christos SYM0 (); 1341 1.1 christos OPIMM (16); 1342 1.1 christos OP (OP_SHRA); 1343 1.1 christos OP (ABS16); 1344 1.1 christos break; 1345 1.1 christos 1346 1.1 christos case BFD_RELOC_RL78_HI8: 1347 1.1 christos SYM0 (); 1348 1.1 christos OPIMM (16); 1349 1.1 christos OP (OP_SHRA); 1350 1.1 christos OPIMM (0xff); 1351 1.1 christos OP (OP_AND); 1352 1.1 christos OP (ABS8); 1353 1.1 christos break; 1354 1.1 christos 1355 1.1 christos default: 1356 1.1 christos reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 1357 1.1 christos reloc[1] = NULL; 1358 1.1 christos break; 1359 1.1 christos } 1360 1.1 christos 1361 1.1 christos return reloc; 1362 1.1 christos } 1363 1.1 christos 1364 1.1 christos int 1365 1.1 christos rl78_validate_fix_sub (struct fix * f) 1366 1.1 christos { 1367 1.1 christos /* We permit the subtraction of two symbols in a few cases. */ 1368 1.1 christos /* mov #sym1-sym2, R3 */ 1369 1.1 christos if (f->fx_r_type == BFD_RELOC_RL78_32_OP) 1370 1.1 christos return 1; 1371 1.1 christos /* .long sym1-sym2 */ 1372 1.1 christos if (f->fx_r_type == BFD_RELOC_RL78_DIFF 1373 1.1 christos && ! f->fx_pcrel 1374 1.1 christos && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1)) 1375 1.1 christos return 1; 1376 1.1 christos return 0; 1377 1.1 christos } 1378 1.1 christos 1379 1.1 christos long 1380 1.1 christos md_pcrel_from_section (fixS * fixP, segT sec) 1381 1.1 christos { 1382 1.1 christos long rv; 1383 1.1 christos 1384 1.1 christos if (fixP->fx_addsy != NULL 1385 1.1 christos && (! S_IS_DEFINED (fixP->fx_addsy) 1386 1.1 christos || S_GET_SEGMENT (fixP->fx_addsy) != sec)) 1387 1.1 christos /* The symbol is undefined (or is defined but not in this section). 1388 1.1 christos Let the linker figure it out. */ 1389 1.1 christos return 0; 1390 1.1 christos 1391 1.1 christos rv = fixP->fx_frag->fr_address + fixP->fx_where; 1392 1.1 christos switch (fixP->fx_r_type) 1393 1.1 christos { 1394 1.1 christos case BFD_RELOC_8_PCREL: 1395 1.1 christos rv += 1; 1396 1.1 christos break; 1397 1.1 christos case BFD_RELOC_16_PCREL: 1398 1.1 christos rv += 2; 1399 1.1 christos break; 1400 1.1 christos default: 1401 1.1 christos break; 1402 1.1 christos } 1403 1.1 christos return rv; 1404 1.1 christos } 1405 1.1 christos 1406 1.1 christos void 1407 1.1 christos md_apply_fix (struct fix * f ATTRIBUTE_UNUSED, 1408 1.1 christos valueT * t ATTRIBUTE_UNUSED, 1409 1.1 christos segT s ATTRIBUTE_UNUSED) 1410 1.1 christos { 1411 1.1 christos char * op; 1412 1.5 christos unsigned long val; 1413 1.5 christos 1414 1.5 christos /* We always defer overflow checks for these to the linker, as it 1415 1.5 christos needs to do PLT stuff. */ 1416 1.5 christos if (f->fx_r_type == BFD_RELOC_RL78_CODE) 1417 1.1 christos f->fx_no_overflow = 1; 1418 1.1 christos 1419 1.1 christos if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1)) 1420 1.1 christos return; 1421 1.1 christos if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1)) 1422 1.1 christos return; 1423 1.10 christos 1424 1.1 christos op = f->fx_frag->fr_literal + f->fx_where; 1425 1.5 christos val = *t; 1426 1.5 christos 1427 1.5 christos if (f->fx_addsy == NULL) 1428 1.1 christos f->fx_done = 1; 1429 1.1 christos 1430 1.1 christos switch (f->fx_r_type) 1431 1.1 christos { 1432 1.1 christos case BFD_RELOC_NONE: 1433 1.1 christos break; 1434 1.5 christos 1435 1.1 christos case BFD_RELOC_RL78_RELAX: 1436 1.1 christos f->fx_done = 0; 1437 1.3 christos break; 1438 1.3 christos 1439 1.3 christos case BFD_RELOC_8_PCREL: 1440 1.3 christos if ((long)val < -128 || (long)val > 127) 1441 1.3 christos as_bad_where (f->fx_file, f->fx_line, 1442 1.3 christos _("value of %ld too large for 8-bit branch"), 1443 1.1 christos val); 1444 1.3 christos /* Fall through. */ 1445 1.1 christos case BFD_RELOC_8: 1446 1.1 christos case BFD_RELOC_RL78_SADDR: /* We need to store the 8 LSB, but this works. */ 1447 1.1 christos op[0] = val; 1448 1.3 christos break; 1449 1.3 christos 1450 1.3 christos case BFD_RELOC_16_PCREL: 1451 1.3 christos if ((long)val < -32768 || (long)val > 32767) 1452 1.3 christos as_bad_where (f->fx_file, f->fx_line, 1453 1.3 christos _("value of %ld too large for 16-bit branch"), 1454 1.1 christos val); 1455 1.3 christos /* Fall through. */ 1456 1.1 christos case BFD_RELOC_16: 1457 1.1 christos case BFD_RELOC_RL78_CODE: 1458 1.1 christos op[0] = val; 1459 1.1 christos op[1] = val >> 8; 1460 1.1 christos break; 1461 1.1 christos 1462 1.1 christos case BFD_RELOC_24: 1463 1.1 christos op[0] = val; 1464 1.1 christos op[1] = val >> 8; 1465 1.1 christos op[2] = val >> 16; 1466 1.1 christos break; 1467 1.1 christos 1468 1.1 christos case BFD_RELOC_32: 1469 1.1 christos op[0] = val; 1470 1.1 christos op[1] = val >> 8; 1471 1.1 christos op[2] = val >> 16; 1472 1.1 christos op[3] = val >> 24; 1473 1.3 christos break; 1474 1.3 christos 1475 1.3 christos case BFD_RELOC_RL78_DIFF: 1476 1.3 christos op[0] = val; 1477 1.3 christos if (f->fx_size > 1) 1478 1.3 christos op[1] = val >> 8; 1479 1.3 christos if (f->fx_size > 2) 1480 1.3 christos op[2] = val >> 16; 1481 1.3 christos if (f->fx_size > 3) 1482 1.3 christos op[3] = val >> 24; 1483 1.3 christos break; 1484 1.3 christos 1485 1.3 christos case BFD_RELOC_RL78_HI8: 1486 1.3 christos val = val >> 16; 1487 1.3 christos op[0] = val; 1488 1.3 christos break; 1489 1.3 christos 1490 1.3 christos case BFD_RELOC_RL78_HI16: 1491 1.3 christos val = val >> 16; 1492 1.3 christos op[0] = val; 1493 1.3 christos op[1] = val >> 8; 1494 1.3 christos break; 1495 1.3 christos 1496 1.3 christos case BFD_RELOC_RL78_LO16: 1497 1.3 christos op[0] = val; 1498 1.3 christos op[1] = val >> 8; 1499 1.1 christos break; 1500 1.1 christos 1501 1.1 christos default: 1502 1.1 christos as_bad (_("Unknown reloc in md_apply_fix: %s"), 1503 1.1 christos bfd_get_reloc_code_name (f->fx_r_type)); 1504 1.1 christos break; 1505 1.1 christos } 1506 1.1 christos 1507 1.1 christos } 1508 1.1 christos 1509 1.1 christos valueT 1510 1.7 christos md_section_align (segT segment, valueT size) 1511 1.10 christos { 1512 1.1 christos int align = bfd_section_alignment (segment); 1513 return (size + ((valueT) 1 << align) - 1) & -((valueT) 1 << align); 1514 } 1515