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