tc-rl78.c revision 1.9 1 /* tc-rl78.c -- Assembler for the Renesas RL78
2 Copyright (C) 2011-2024 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 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 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 (* input_line_pointer == ' '
429 || * input_line_pointer == '\t')
430 input_line_pointer ++;
431
432 if (! * input_line_pointer
433 || strchr ("\n\r,", * input_line_pointer)
434 || strchr (comment_chars, * input_line_pointer)
435 || strchr (line_comment_chars, * input_line_pointer)
436 || strchr (line_separator_chars, * input_line_pointer))
437 return;
438
439 as_bad (_("%%%s() must be outermost term in expression"), fname);
440 }
441
442 static struct
443 {
444 const char * fname;
445 int reloc;
446 }
447 reloc_functions[] =
448 {
449 { "code", BFD_RELOC_RL78_CODE },
450 { "lo16", BFD_RELOC_RL78_LO16 },
451 { "hi16", BFD_RELOC_RL78_HI16 },
452 { "hi8", BFD_RELOC_RL78_HI8 },
453 { 0, 0 }
454 };
455
456 void
457 md_operand (expressionS * exp ATTRIBUTE_UNUSED)
458 {
459 int reloc = 0;
460 int i;
461
462 for (i = 0; reloc_functions[i].fname; i++)
463 {
464 int flen = strlen (reloc_functions[i].fname);
465
466 if (input_line_pointer[0] == '%'
467 && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
468 && input_line_pointer[flen + 1] == '(')
469 {
470 reloc = reloc_functions[i].reloc;
471 input_line_pointer += flen + 2;
472 break;
473 }
474 }
475 if (reloc == 0)
476 return;
477
478 expression (exp);
479 if (* input_line_pointer == ')')
480 input_line_pointer ++;
481
482 exp->X_md = reloc;
483
484 require_end_of_expr (reloc_functions[i].fname);
485 }
486
487 void
488 rl78_frag_init (fragS * fragP)
489 {
490 if (rl78_bytes.n_relax || rl78_bytes.link_relax)
491 {
492 fragP->tc_frag_data = XNEW (rl78_bytesT);
493 memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT));
494 }
495 else
496 fragP->tc_frag_data = 0;
497 }
498
499 /* When relaxing, we need to output a reloc for any .align directive
500 so that we can retain this alignment as we adjust opcode sizes. */
501 void
502 rl78_handle_align (fragS * frag)
503 {
504 if (linkrelax
505 && (frag->fr_type == rs_align
506 || frag->fr_type == rs_align_code)
507 && frag->fr_address + frag->fr_fix > 0
508 && frag->fr_offset > 0
509 && now_seg != bss_section)
510 {
511 fix_new (frag, frag->fr_fix, 0,
512 &abs_symbol, RL78_RELAXA_ALIGN + frag->fr_offset,
513 0, BFD_RELOC_RL78_RELAX);
514 /* For the purposes of relaxation, this relocation is attached
515 to the byte *after* the alignment - i.e. the byte that must
516 remain aligned. */
517 fix_new (frag->fr_next, 0, 0,
518 &abs_symbol, RL78_RELAXA_ELIGN + frag->fr_offset,
519 0, BFD_RELOC_RL78_RELAX);
520 }
521 }
522
523 const char *
524 md_atof (int type, char * litP, int * sizeP)
525 {
526 return ieee_md_atof (type, litP, sizeP, target_big_endian);
527 }
528
529 symbolS *
530 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
531 {
532 return NULL;
533 }
534
535 #define APPEND(B, N_B) \
536 if (rl78_bytes.N_B) \
537 { \
538 memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B); \
539 idx += rl78_bytes.N_B; \
540 }
541
542
543 void
544 md_assemble (char * str)
545 {
546 char * bytes;
547 fragS * frag_then = frag_now;
548 int idx = 0;
549 int i;
550 int rel;
551 expressionS *exp;
552
553 /*printf("\033[32mASM: %s\033[0m\n", str);*/
554
555 dwarf2_emit_insn (0);
556
557 memset (& rl78_bytes, 0, sizeof (rl78_bytes));
558
559 rl78_lex_init (str, str + strlen (str));
560
561 rl78_parse ();
562
563 /* This simplifies the relaxation code. */
564 if (rl78_bytes.n_relax || rl78_bytes.link_relax)
565 {
566 int olen = rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops;
567 /* We do it this way because we want the frag to have the
568 rl78_bytes in it, which we initialize above. The extra bytes
569 are for relaxing. */
570 bytes = frag_more (olen + 3);
571 frag_then = frag_now;
572 frag_variant (rs_machine_dependent,
573 olen /* max_chars */,
574 0 /* var */,
575 olen /* subtype */,
576 0 /* symbol */,
577 0 /* offset */,
578 0 /* opcode */);
579 frag_then->fr_opcode = bytes;
580 frag_then->fr_fix = olen + (bytes - frag_then->fr_literal);
581 frag_then->fr_subtype = olen;
582 frag_then->fr_var = 0;
583 }
584 else
585 {
586 bytes = frag_more (rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops);
587 frag_then = frag_now;
588 }
589
590 APPEND (prefix, n_prefix);
591 APPEND (base, n_base);
592 APPEND (ops, n_ops);
593
594 if (rl78_bytes.link_relax)
595 {
596 fixS * f;
597
598 f = fix_new (frag_then,
599 (char *) bytes - frag_then->fr_literal,
600 0,
601 abs_section_sym,
602 rl78_bytes.link_relax | rl78_bytes.n_fixups,
603 0,
604 BFD_RELOC_RL78_RELAX);
605 frag_then->tc_frag_data->link_relax_fixP = f;
606 }
607
608 for (i = 0; i < rl78_bytes.n_fixups; i ++)
609 {
610 /* index: [nbytes][type] */
611 static int reloc_map[5][4] =
612 {
613 { 0, 0 },
614 { BFD_RELOC_8, BFD_RELOC_8_PCREL },
615 { BFD_RELOC_16, BFD_RELOC_16_PCREL },
616 { BFD_RELOC_24, BFD_RELOC_24_PCREL },
617 { BFD_RELOC_32, BFD_RELOC_32_PCREL },
618 };
619 fixS * f;
620
621 idx = rl78_bytes.fixups[i].offset / 8;
622 rel = reloc_map [rl78_bytes.fixups[i].nbits / 8][(int) rl78_bytes.fixups[i].type];
623
624 if (rl78_bytes.fixups[i].reloc)
625 rel = rl78_bytes.fixups[i].reloc;
626
627 if (frag_then->tc_frag_data)
628 exp = & frag_then->tc_frag_data->fixups[i].exp;
629 else
630 exp = & rl78_bytes.fixups[i].exp;
631
632 f = fix_new_exp (frag_then,
633 (char *) bytes + idx - frag_then->fr_literal,
634 rl78_bytes.fixups[i].nbits / 8,
635 exp,
636 rl78_bytes.fixups[i].type == RL78REL_PCREL ? 1 : 0,
637 rel);
638 if (frag_then->tc_frag_data)
639 frag_then->tc_frag_data->fixups[i].fixP = f;
640 }
641 }
642
643 void
644 rl78_cons_fix_new (fragS * frag,
645 int where,
646 int size,
647 expressionS * exp)
648 {
649 bfd_reloc_code_real_type type;
650 fixS *fixP;
651
652 switch (size)
653 {
654 case 1:
655 type = BFD_RELOC_8;
656 break;
657 case 2:
658 type = BFD_RELOC_16;
659 break;
660 case 3:
661 type = BFD_RELOC_24;
662 break;
663 case 4:
664 type = BFD_RELOC_32;
665 break;
666 default:
667 as_bad (_("unsupported constant size %d\n"), size);
668 return;
669 }
670
671 switch (exp->X_md)
672 {
673 case BFD_RELOC_RL78_CODE:
674 if (size == 2)
675 type = exp->X_md;
676 break;
677 case BFD_RELOC_RL78_LO16:
678 case BFD_RELOC_RL78_HI16:
679 if (size != 2)
680 {
681 /* Fixups to assembler generated expressions do not use %hi or %lo. */
682 if (frag->fr_file)
683 as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
684 }
685 else
686 type = exp->X_md;
687 break;
688 case BFD_RELOC_RL78_HI8:
689 if (size != 1)
690 {
691 /* Fixups to assembler generated expressions do not use %hi or %lo. */
692 if (frag->fr_file)
693 as_bad (_("%%hi8 only applies to .byte"));
694 }
695 else
696 type = exp->X_md;
697 break;
698 default:
699 break;
700 }
701
702 if (exp->X_op == O_subtract && exp->X_op_symbol)
703 {
704 if (size != 4 && size != 2 && size != 1)
705 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
706 else
707 type = BFD_RELOC_RL78_DIFF;
708 }
709
710 fixP = fix_new_exp (frag, where, (int) size, exp, 0, type);
711 switch (exp->X_md)
712 {
713 /* These are intended to have values larger than the container,
714 since the backend puts only the portion we need in it.
715 However, we don't have a backend-specific reloc for them as
716 they're handled with complex relocations. */
717 case BFD_RELOC_RL78_LO16:
718 case BFD_RELOC_RL78_HI16:
719 case BFD_RELOC_RL78_HI8:
720 fixP->fx_no_overflow = 1;
721 break;
722 default:
723 break;
724 }
725 }
726
727
728 /*----------------------------------------------------------------------*/
730 /* To recap: we estimate everything based on md_estimate_size, then
731 adjust based on rl78_relax_frag. When it all settles, we call
732 md_convert frag to update the bytes. The relaxation types and
733 relocations are in fragP->tc_frag_data, which is a copy of that
734 rl78_bytes.
735
736 Our scheme is as follows: fr_fix has the size of the smallest
737 opcode (like BRA.S). We store the number of total bytes we need in
738 fr_subtype. When we're done relaxing, we use fr_subtype and the
739 existing opcode bytes to figure out what actual opcode we need to
740 put in there. If the fixup isn't resolvable now, we use the
741 maximal size. */
742
743 #define TRACE_RELAX 0
744 #define tprintf if (TRACE_RELAX) printf
745
746
747 typedef enum
748 {
749 OT_other,
750 OT_bt,
751 OT_bt_sfr,
752 OT_bt_es,
753 OT_bc,
754 OT_bh,
755 OT_sk,
756 OT_call,
757 OT_br,
758 } op_type_T;
759
760 /* We're looking for these types of relaxations:
761
762 BT 00110001 sbit0cc1 addr---- (cc is 10 (BF) or 01 (BT))
763 B~T 00110001 sbit0cc1 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
764
765 BT sfr 00110001 sbit0cc0 sfr----- addr----
766 BT ES: 00010001 00101110 sbit0cc1 addr----
767
768 BC 110111cc addr----
769 B~C 110111cc 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
770
771 BH 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
772 B~H 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
773 */
774
775 /* Given the opcode bytes at OP, figure out which opcode it is and
776 return the type of opcode. We use this to re-encode the opcode as
777 a different size later. */
778
779 static op_type_T
780 rl78_opcode_type (char * ops)
781 {
782 unsigned char *op = (unsigned char *)ops;
783
784 if (op[0] == 0x31
785 && ((op[1] & 0x0f) == 0x05
786 || (op[1] & 0x0f) == 0x03))
787 return OT_bt;
788
789 if (op[0] == 0x31
790 && ((op[1] & 0x0f) == 0x04
791 || (op[1] & 0x0f) == 0x02))
792 return OT_bt_sfr;
793
794 if (op[0] == 0x11
795 && op[1] == 0x31
796 && ((op[2] & 0x0f) == 0x05
797 || (op[2] & 0x0f) == 0x03))
798 return OT_bt_es;
799
800 if ((op[0] & 0xfc) == 0xdc)
801 return OT_bc;
802
803 if (op[0] == 0x61
804 && (op[1] & 0xef) == 0xc3)
805 return OT_bh;
806
807 if (op[0] == 0x61
808 && (op[1] & 0xcf) == 0xc8)
809 return OT_sk;
810
811 if (op[0] == 0x61
812 && (op[1] & 0xef) == 0xe3)
813 return OT_sk;
814
815 if (op[0] == 0xfc)
816 return OT_call;
817
818 if ((op[0] & 0xec) == 0xec)
819 return OT_br;
820
821 return OT_other;
822 }
823
824 /* Returns zero if *addrP has the target address. Else returns nonzero
825 if we cannot compute the target address yet. */
826
827 static int
828 rl78_frag_fix_value (fragS * fragP,
829 segT segment,
830 int which,
831 addressT * addrP,
832 int need_diff,
833 addressT * sym_addr)
834 {
835 addressT addr = 0;
836 rl78_bytesT * b = fragP->tc_frag_data;
837 expressionS * exp = & b->fixups[which].exp;
838
839 if (need_diff && exp->X_op != O_subtract)
840 return 1;
841
842 if (exp->X_add_symbol)
843 {
844 if (S_FORCE_RELOC (exp->X_add_symbol, 1))
845 return 1;
846 if (S_GET_SEGMENT (exp->X_add_symbol) != segment)
847 return 1;
848 addr += S_GET_VALUE (exp->X_add_symbol);
849 }
850
851 if (exp->X_op_symbol)
852 {
853 if (exp->X_op != O_subtract)
854 return 1;
855 if (S_FORCE_RELOC (exp->X_op_symbol, 1))
856 return 1;
857 if (S_GET_SEGMENT (exp->X_op_symbol) != segment)
858 return 1;
859 addr -= S_GET_VALUE (exp->X_op_symbol);
860 }
861 if (sym_addr)
862 * sym_addr = addr;
863 addr += exp->X_add_number;
864 * addrP = addr;
865 return 0;
866 }
867
868 /* Estimate how big the opcode is after this relax pass. The return
869 value is the difference between fr_fix and the actual size. We
870 compute the total size in rl78_relax_frag and store it in fr_subtype,
871 so we only need to subtract fx_fix and return it. */
872
873 int
874 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
875 {
876 int opfixsize;
877 int delta;
878
879 /* This is the size of the opcode that's accounted for in fr_fix. */
880 opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal);
881 /* This is the size of the opcode that isn't. */
882 delta = (fragP->fr_subtype - opfixsize);
883
884 tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta);
885 return delta;
886 }
887
888 /* Given the new addresses for this relax pass, figure out how big
889 each opcode must be. We store the total number of bytes needed in
890 fr_subtype. The return value is the difference between the size
891 after the last pass and the size after this pass, so we use the old
892 fr_subtype to calculate the difference. */
893
894 int
895 rl78_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
896 {
897 addressT addr0, sym_addr;
898 addressT mypc;
899 int disp;
900 int oldsize = fragP->fr_subtype;
901 int newsize = oldsize;
902 op_type_T optype;
903 int ri;
904
905 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
906
907 /* If we ever get more than one reloc per opcode, this is the one
908 we're relaxing. */
909 ri = 0;
910
911 optype = rl78_opcode_type (fragP->fr_opcode);
912 /* Try to get the target address. */
913 if (rl78_frag_fix_value (fragP, segment, ri, & addr0,
914 fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH,
915 & sym_addr))
916 {
917 /* If we don't expect the linker to do relaxing, don't emit
918 expanded opcodes that only the linker will relax. */
919 if (!linkrelax)
920 return newsize - oldsize;
921
922 /* If we don't, we must use the maximum size for the linker. */
923 switch (fragP->tc_frag_data->relax[ri].type)
924 {
925 case RL78_RELAX_BRANCH:
926 switch (optype)
927 {
928 case OT_bt:
929 newsize = 6;
930 break;
931 case OT_bt_sfr:
932 case OT_bt_es:
933 newsize = 7;
934 break;
935 case OT_bc:
936 newsize = 5;
937 break;
938 case OT_bh:
939 newsize = 6;
940 break;
941 case OT_sk:
942 newsize = 2;
943 break;
944 default:
945 newsize = oldsize;
946 break;
947 }
948 break;
949
950 }
951 fragP->fr_subtype = newsize;
952 tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize);
953 return newsize - oldsize;
954 }
955
956 if (sym_addr > mypc)
957 addr0 += stretch;
958
959 switch (fragP->tc_frag_data->relax[ri].type)
960 {
961 case RL78_RELAX_BRANCH:
962 disp = (int) addr0 - (int) mypc;
963
964 switch (optype)
965 {
966 case OT_bt:
967 if (disp >= -128 && (disp - (oldsize-2)) <= 127)
968 newsize = 3;
969 else
970 newsize = 6;
971 break;
972 case OT_bt_sfr:
973 case OT_bt_es:
974 if (disp >= -128 && (disp - (oldsize-3)) <= 127)
975 newsize = 4;
976 else
977 newsize = 7;
978 break;
979 case OT_bc:
980 if (disp >= -128 && (disp - (oldsize-1)) <= 127)
981 newsize = 2;
982 else
983 newsize = 5;
984 break;
985 case OT_bh:
986 if (disp >= -128 && (disp - (oldsize-2)) <= 127)
987 newsize = 3;
988 else
989 newsize = 6;
990 break;
991 case OT_sk:
992 newsize = 2;
993 break;
994 default:
995 newsize = oldsize;
996 break;
997 }
998 break;
999 }
1000
1001 /* This prevents infinite loops in align-heavy sources. */
1002 if (newsize < oldsize)
1003 {
1004 if (fragP->tc_frag_data->times_shrank > 10
1005 && fragP->tc_frag_data->times_grown > 10)
1006 newsize = oldsize;
1007 if (fragP->tc_frag_data->times_shrank < 20)
1008 fragP->tc_frag_data->times_shrank ++;
1009 }
1010 else if (newsize > oldsize)
1011 {
1012 if (fragP->tc_frag_data->times_grown < 20)
1013 fragP->tc_frag_data->times_grown ++;
1014 }
1015
1016 fragP->fr_subtype = newsize;
1017 tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
1018 return newsize - oldsize;
1019 }
1020
1021 /* This lets us test for the opcode type and the desired size in a
1022 switch statement. */
1023 #define OPCODE(type,size) ((type) * 16 + (size))
1024
1025 /* Given the opcode stored in fr_opcode and the number of bytes we
1026 think we need, encode a new opcode. We stored a pointer to the
1027 fixup for this opcode in the tc_frag_data structure. If we can do
1028 the fixup here, we change the relocation type to "none" (we test
1029 for that in tc_gen_reloc) else we change it to the right type for
1030 the new (biggest) opcode. */
1031
1032 void
1033 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1034 segT segment ATTRIBUTE_UNUSED,
1035 fragS * fragP ATTRIBUTE_UNUSED)
1036 {
1037 rl78_bytesT * rl78b = fragP->tc_frag_data;
1038 addressT addr0, mypc;
1039 int disp;
1040 int reloc_type, reloc_adjust;
1041 char * op = fragP->fr_opcode;
1042 int keep_reloc = 0;
1043 int ri;
1044 int fi = (rl78b->n_fixups > 1) ? 1 : 0;
1045 fixS * fix = rl78b->fixups[fi].fixP;
1046
1047 /* If we ever get more than one reloc per opcode, this is the one
1048 we're relaxing. */
1049 ri = 0;
1050
1051 /* We used a new frag for this opcode, so the opcode address should
1052 be the frag address. */
1053 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1054 tprintf ("\033[32mmypc: 0x%x\033[0m\n", (int)mypc);
1055
1056 /* Try to get the target address. If we fail here, we just use the
1057 largest format. */
1058 if (rl78_frag_fix_value (fragP, segment, 0, & addr0,
1059 fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH, 0))
1060 {
1061 /* We don't know the target address. */
1062 keep_reloc = 1;
1063 addr0 = 0;
1064 disp = 0;
1065 tprintf ("unknown addr ? - %x = ?\n", (int)mypc);
1066 }
1067 else
1068 {
1069 /* We know the target address, and it's in addr0. */
1070 disp = (int) addr0 - (int) mypc;
1071 tprintf ("known addr %x - %x = %d\n", (int)addr0, (int)mypc, disp);
1072 }
1073
1074 if (linkrelax)
1075 keep_reloc = 1;
1076
1077 reloc_type = BFD_RELOC_NONE;
1078 reloc_adjust = 0;
1079
1080 switch (fragP->tc_frag_data->relax[ri].type)
1081 {
1082 case RL78_RELAX_BRANCH:
1083 switch (OPCODE (rl78_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
1084 {
1085
1086 case OPCODE (OT_bt, 3): /* BT A,$ - no change. */
1087 disp -= 3;
1088 op[2] = disp;
1089 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1090 break;
1091
1092 case OPCODE (OT_bt, 6): /* BT A,$ - long version. */
1093 disp -= 3;
1094 op[1] ^= 0x06; /* toggle conditional. */
1095 op[2] = 3; /* displacement over long branch. */
1096 disp -= 3;
1097 op[3] = 0xEE; /* BR $!addr20 */
1098 op[4] = disp & 0xff;
1099 op[5] = disp >> 8;
1100 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1101 reloc_adjust = 2;
1102 break;
1103
1104 case OPCODE (OT_bt_sfr, 4): /* BT PSW,$ - no change. */
1105 disp -= 4;
1106 op[3] = disp;
1107 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1108 break;
1109
1110 case OPCODE (OT_bt_sfr, 7): /* BT PSW,$ - long version. */
1111 disp -= 4;
1112 op[1] ^= 0x06; /* toggle conditional. */
1113 op[3] = 3; /* displacement over long branch. */
1114 disp -= 3;
1115 op[4] = 0xEE; /* BR $!addr20 */
1116 op[5] = disp & 0xff;
1117 op[6] = disp >> 8;
1118 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1119 reloc_adjust = 2;
1120 break;
1121
1122 case OPCODE (OT_bt_es, 4): /* BT ES:[HL],$ - no change. */
1123 disp -= 4;
1124 op[3] = disp;
1125 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1126 break;
1127
1128 case OPCODE (OT_bt_es, 7): /* BT PSW,$ - long version. */
1129 disp -= 4;
1130 op[2] ^= 0x06; /* toggle conditional. */
1131 op[3] = 3; /* displacement over long branch. */
1132 disp -= 3;
1133 op[4] = 0xEE; /* BR $!addr20 */
1134 op[5] = disp & 0xff;
1135 op[6] = disp >> 8;
1136 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1137 reloc_adjust = 2;
1138 break;
1139
1140 case OPCODE (OT_bc, 2): /* BC $ - no change. */
1141 disp -= 2;
1142 op[1] = disp;
1143 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1144 break;
1145
1146 case OPCODE (OT_bc, 5): /* BC $ - long version. */
1147 disp -= 2;
1148 op[0] ^= 0x02; /* toggle conditional. */
1149 op[1] = 3;
1150 disp -= 3;
1151 op[2] = 0xEE; /* BR $!addr20 */
1152 op[3] = disp & 0xff;
1153 op[4] = disp >> 8;
1154 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1155 reloc_adjust = 2;
1156 break;
1157
1158 case OPCODE (OT_bh, 3): /* BH $ - no change. */
1159 disp -= 3;
1160 op[2] = disp;
1161 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1162 break;
1163
1164 case OPCODE (OT_bh, 6): /* BC $ - long version. */
1165 disp -= 3;
1166 op[1] ^= 0x10; /* toggle conditional. */
1167 op[2] = 3;
1168 disp -= 3;
1169 op[3] = 0xEE; /* BR $!addr20 */
1170 op[4] = disp & 0xff;
1171 op[5] = disp >> 8;
1172 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1173 reloc_adjust = 2;
1174 break;
1175
1176 case OPCODE (OT_sk, 2): /* SK<cond> - no change */
1177 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1178 break;
1179
1180 default:
1181 reloc_type = fix ? fix->fx_r_type : BFD_RELOC_NONE;
1182 break;
1183 }
1184 break;
1185
1186 default:
1187 if (rl78b->n_fixups)
1188 {
1189 reloc_type = fix->fx_r_type;
1190 reloc_adjust = 0;
1191 }
1192 break;
1193 }
1194
1195 if (rl78b->n_fixups)
1196 {
1197
1198 fix->fx_r_type = reloc_type;
1199 fix->fx_where += reloc_adjust;
1200 switch (reloc_type)
1201 {
1202 case BFD_RELOC_NONE:
1203 fix->fx_size = 0;
1204 break;
1205 case BFD_RELOC_8:
1206 fix->fx_size = 1;
1207 break;
1208 case BFD_RELOC_16_PCREL:
1209 fix->fx_size = 2;
1210 break;
1211 }
1212 }
1213
1214 fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
1215 tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix,
1216 fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
1217 fragP->fr_var = 0;
1218
1219 tprintf ("compare 0x%lx vs 0x%lx - 0x%lx = 0x%lx (%p)\n",
1220 (long)fragP->fr_fix,
1221 (long)fragP->fr_next->fr_address, (long)fragP->fr_address,
1222 (long)(fragP->fr_next->fr_address - fragP->fr_address),
1223 fragP->fr_next);
1224
1225 if (fragP->fr_next != NULL
1226 && fragP->fr_next->fr_address - fragP->fr_address != fragP->fr_fix)
1227 as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
1228 (long) fragP->fr_fix,
1229 (long) fragP->fr_address, (long) fragP->fr_next->fr_address);
1230 }
1231
1232 /* End of relaxation code.
1233 ----------------------------------------------------------------------*/
1234
1235
1237 arelent **
1238 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
1239 {
1240 static arelent * reloc[8];
1241 int rp;
1242
1243 if (fixp->fx_r_type == BFD_RELOC_NONE)
1244 {
1245 reloc[0] = NULL;
1246 return reloc;
1247 }
1248
1249 if (fixp->fx_r_type == BFD_RELOC_RL78_RELAX && !linkrelax)
1250 {
1251 reloc[0] = NULL;
1252 return reloc;
1253 }
1254
1255 if (fixp->fx_subsy
1256 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1257 {
1258 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
1259 fixp->fx_subsy = NULL;
1260 }
1261
1262 reloc[0] = XNEW (arelent);
1263 reloc[0]->sym_ptr_ptr = XNEW (asymbol *);
1264 * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1265 reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
1266 reloc[0]->addend = fixp->fx_offset;
1267
1268 if (fixp->fx_r_type == BFD_RELOC_RL78_32_OP
1269 && fixp->fx_subsy)
1270 {
1271 fixp->fx_r_type = BFD_RELOC_RL78_DIFF;
1272 }
1273
1274 #define OPX(REL,SYM,ADD) \
1275 reloc[rp] = XNEW (arelent); \
1276 reloc[rp]->sym_ptr_ptr = XNEW (asymbol *); \
1277 reloc[rp]->howto = bfd_reloc_type_lookup (stdoutput, REL); \
1278 reloc[rp]->addend = ADD; \
1279 * reloc[rp]->sym_ptr_ptr = SYM; \
1280 reloc[rp]->address = fixp->fx_frag->fr_address + fixp->fx_where; \
1281 reloc[++rp] = NULL
1282 #define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
1283
1284 /* FIXME: We cannot do the normal thing for an immediate value reloc,
1285 ie creating a RL78_SYM reloc in the *ABS* section with an offset
1286 equal to the immediate value we want to store. This fails because
1287 the reloc processing in bfd_perform_relocation and bfd_install_relocation
1288 will short circuit such relocs and never pass them on to the special
1289 reloc processing code. So instead we create a RL78_SYM reloc against
1290 the __rl78_abs__ symbol and arrange for the linker scripts to place
1291 this symbol at address 0. */
1292 #define OPIMM(IMM) OPX (BFD_RELOC_RL78_SYM, symbol_get_bfdsym (rl78_abs_sym), IMM)
1293
1294 #define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
1295 #define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
1296
1297 rp = 1;
1298
1299 /* Certain BFD relocations cannot be translated directly into
1300 a single (non-Red Hat) RL78 relocation, but instead need
1301 multiple RL78 relocations - handle them here. */
1302 switch (fixp->fx_r_type)
1303 {
1304 case BFD_RELOC_RL78_DIFF:
1305 SYM0 ();
1306 OPSYM (symbol_get_bfdsym (fixp->fx_subsy));
1307 OP(OP_SUBTRACT);
1308
1309 switch (fixp->fx_size)
1310 {
1311 case 1:
1312 OP(ABS8);
1313 break;
1314 case 2:
1315 OP (ABS16);
1316 break;
1317 case 4:
1318 OP (ABS32);
1319 break;
1320 }
1321 break;
1322
1323 case BFD_RELOC_RL78_NEG32:
1324 SYM0 ();
1325 OP (OP_NEG);
1326 OP (ABS32);
1327 break;
1328
1329 case BFD_RELOC_RL78_CODE:
1330 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_16U);
1331 reloc[1] = NULL;
1332 break;
1333
1334 case BFD_RELOC_RL78_LO16:
1335 SYM0 ();
1336 OPIMM (0xffff);
1337 OP (OP_AND);
1338 OP (ABS16);
1339 break;
1340
1341 case BFD_RELOC_RL78_HI16:
1342 SYM0 ();
1343 OPIMM (16);
1344 OP (OP_SHRA);
1345 OP (ABS16);
1346 break;
1347
1348 case BFD_RELOC_RL78_HI8:
1349 SYM0 ();
1350 OPIMM (16);
1351 OP (OP_SHRA);
1352 OPIMM (0xff);
1353 OP (OP_AND);
1354 OP (ABS8);
1355 break;
1356
1357 default:
1358 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1359 reloc[1] = NULL;
1360 break;
1361 }
1362
1363 return reloc;
1364 }
1365
1366 int
1367 rl78_validate_fix_sub (struct fix * f)
1368 {
1369 /* We permit the subtraction of two symbols in a few cases. */
1370 /* mov #sym1-sym2, R3 */
1371 if (f->fx_r_type == BFD_RELOC_RL78_32_OP)
1372 return 1;
1373 /* .long sym1-sym2 */
1374 if (f->fx_r_type == BFD_RELOC_RL78_DIFF
1375 && ! f->fx_pcrel
1376 && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
1377 return 1;
1378 return 0;
1379 }
1380
1381 long
1382 md_pcrel_from_section (fixS * fixP, segT sec)
1383 {
1384 long rv;
1385
1386 if (fixP->fx_addsy != NULL
1387 && (! S_IS_DEFINED (fixP->fx_addsy)
1388 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
1389 /* The symbol is undefined (or is defined but not in this section).
1390 Let the linker figure it out. */
1391 return 0;
1392
1393 rv = fixP->fx_frag->fr_address + fixP->fx_where;
1394 switch (fixP->fx_r_type)
1395 {
1396 case BFD_RELOC_8_PCREL:
1397 rv += 1;
1398 break;
1399 case BFD_RELOC_16_PCREL:
1400 rv += 2;
1401 break;
1402 default:
1403 break;
1404 }
1405 return rv;
1406 }
1407
1408 void
1409 md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
1410 valueT * t ATTRIBUTE_UNUSED,
1411 segT s ATTRIBUTE_UNUSED)
1412 {
1413 char * op;
1414 unsigned long val;
1415
1416 /* We always defer overflow checks for these to the linker, as it
1417 needs to do PLT stuff. */
1418 if (f->fx_r_type == BFD_RELOC_RL78_CODE)
1419 f->fx_no_overflow = 1;
1420
1421 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
1422 return;
1423 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
1424 return;
1425
1426 op = f->fx_frag->fr_literal + f->fx_where;
1427 val = (unsigned long) * t;
1428
1429 if (f->fx_addsy == NULL)
1430 f->fx_done = 1;
1431
1432 switch (f->fx_r_type)
1433 {
1434 case BFD_RELOC_NONE:
1435 break;
1436
1437 case BFD_RELOC_RL78_RELAX:
1438 f->fx_done = 0;
1439 break;
1440
1441 case BFD_RELOC_8_PCREL:
1442 if ((long)val < -128 || (long)val > 127)
1443 as_bad_where (f->fx_file, f->fx_line,
1444 _("value of %ld too large for 8-bit branch"),
1445 val);
1446 /* Fall through. */
1447 case BFD_RELOC_8:
1448 case BFD_RELOC_RL78_SADDR: /* We need to store the 8 LSB, but this works. */
1449 op[0] = val;
1450 break;
1451
1452 case BFD_RELOC_16_PCREL:
1453 if ((long)val < -32768 || (long)val > 32767)
1454 as_bad_where (f->fx_file, f->fx_line,
1455 _("value of %ld too large for 16-bit branch"),
1456 val);
1457 /* Fall through. */
1458 case BFD_RELOC_16:
1459 case BFD_RELOC_RL78_CODE:
1460 op[0] = val;
1461 op[1] = val >> 8;
1462 break;
1463
1464 case BFD_RELOC_24:
1465 op[0] = val;
1466 op[1] = val >> 8;
1467 op[2] = val >> 16;
1468 break;
1469
1470 case BFD_RELOC_32:
1471 op[0] = val;
1472 op[1] = val >> 8;
1473 op[2] = val >> 16;
1474 op[3] = val >> 24;
1475 break;
1476
1477 case BFD_RELOC_RL78_DIFF:
1478 op[0] = val;
1479 if (f->fx_size > 1)
1480 op[1] = val >> 8;
1481 if (f->fx_size > 2)
1482 op[2] = val >> 16;
1483 if (f->fx_size > 3)
1484 op[3] = val >> 24;
1485 break;
1486
1487 case BFD_RELOC_RL78_HI8:
1488 val = val >> 16;
1489 op[0] = val;
1490 break;
1491
1492 case BFD_RELOC_RL78_HI16:
1493 val = val >> 16;
1494 op[0] = val;
1495 op[1] = val >> 8;
1496 break;
1497
1498 case BFD_RELOC_RL78_LO16:
1499 op[0] = val;
1500 op[1] = val >> 8;
1501 break;
1502
1503 default:
1504 as_bad (_("Unknown reloc in md_apply_fix: %s"),
1505 bfd_get_reloc_code_name (f->fx_r_type));
1506 break;
1507 }
1508
1509 }
1510
1511 valueT
1512 md_section_align (segT segment, valueT size)
1513 {
1514 int align = bfd_section_alignment (segment);
1515 return ((size + (1 << align) - 1) & -(1 << align));
1516 }
1517