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