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