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