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