* elf32-rl78.c (rl78_elf_merge_private_bfd_data): Complain if G10
[external/binutils.git] / gas / config / tc-rl78.c
1 /* tc-rl78.c -- Assembler for the Renesas RL78
2    Copyright 2011-2013 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 "obstack.h"
24 #include "safe-ctype.h"
25 #include "dwarf2dbg.h"
26 #include "libbfd.h"
27 #include "elf/common.h"
28 #include "elf/rl78.h"
29 #include "rl78-defs.h"
30 #include "filenames.h"
31 #include "listing.h"
32 #include "sb.h"
33 #include "macro.h"
34
35 const char comment_chars[]        = ";";
36 /* Note that input_file.c hand checks for '#' at the beginning of the
37    first line of the input file.  This is because the compiler outputs
38    #NO_APP at the beginning of its output.  */
39 const char line_comment_chars[]   = "#";
40 /* Use something that isn't going to be needed by any expressions or
41    other syntax.  */
42 const char line_separator_chars[] = "@";
43
44 const char EXP_CHARS[]            = "eE";
45 const char FLT_CHARS[]            = "dD";
46
47 /* ELF flags to set in the output file header.  */
48 static int elf_flags = 0;
49
50 /*------------------------------------------------------------------*/
51
52 char * rl78_lex_start;
53 char * rl78_lex_end;
54
55 typedef struct rl78_bytesT
56 {
57   char prefix[1];
58   int n_prefix;
59   char base[4];
60   int n_base;
61   char ops[8];
62   int n_ops;
63   struct
64   {
65     expressionS  exp;
66     char         offset;
67     char         nbits;
68     char         type; /* RL78REL_*.  */
69     int          reloc;
70     fixS *       fixP;
71   } fixups[2];
72   int n_fixups;
73   struct
74   {
75     char type;
76     char field_pos;
77     char val_ofs;
78   } relax[2];
79   int n_relax;
80   int link_relax;
81   fixS *link_relax_fixP;
82   char times_grown;
83   char times_shrank;
84 } rl78_bytesT;
85
86 static rl78_bytesT rl78_bytes;
87
88 void
89 rl78_linkrelax_addr16 (void)
90 {
91   rl78_bytes.link_relax |= RL78_RELAXA_ADDR16;
92 }
93
94 void
95 rl78_linkrelax_branch (void)
96 {
97   rl78_bytes.link_relax |= RL78_RELAXA_BRA;
98 }
99
100 static void
101 rl78_fixup (expressionS exp, int offsetbits, int nbits, int type)
102 {
103   rl78_bytes.fixups[rl78_bytes.n_fixups].exp = exp;
104   rl78_bytes.fixups[rl78_bytes.n_fixups].offset = offsetbits;
105   rl78_bytes.fixups[rl78_bytes.n_fixups].nbits = nbits;
106   rl78_bytes.fixups[rl78_bytes.n_fixups].type = type;
107   rl78_bytes.fixups[rl78_bytes.n_fixups].reloc = exp.X_md;
108   rl78_bytes.n_fixups ++;
109 }
110
111 #define rl78_field_fixup(exp, offset, nbits, type)      \
112   rl78_fixup (exp, offset + 8 * rl78_bytes.n_prefix), nbits, type)
113
114 #define rl78_op_fixup(exp, offset, nbits, type)         \
115   rl78_fixup (exp, offset + 8 * (rl78_bytes.n_prefix + rl78_bytes.n_base), nbits, type)
116
117 void
118 rl78_prefix (int p)
119 {
120   rl78_bytes.prefix[0] = p;
121   rl78_bytes.n_prefix = 1;
122 }
123
124 int
125 rl78_has_prefix ()
126 {
127   return rl78_bytes.n_prefix;
128 }
129
130 void
131 rl78_base1 (int b1)
132 {
133   rl78_bytes.base[0] = b1;
134   rl78_bytes.n_base = 1;
135 }
136
137 void
138 rl78_base2 (int b1, int b2)
139 {
140   rl78_bytes.base[0] = b1;
141   rl78_bytes.base[1] = b2;
142   rl78_bytes.n_base = 2;
143 }
144
145 void
146 rl78_base3 (int b1, int b2, int b3)
147 {
148   rl78_bytes.base[0] = b1;
149   rl78_bytes.base[1] = b2;
150   rl78_bytes.base[2] = b3;
151   rl78_bytes.n_base = 3;
152 }
153
154 void
155 rl78_base4 (int b1, int b2, int b3, int b4)
156 {
157   rl78_bytes.base[0] = b1;
158   rl78_bytes.base[1] = b2;
159   rl78_bytes.base[2] = b3;
160   rl78_bytes.base[3] = b4;
161   rl78_bytes.n_base = 4;
162 }
163
164 #define F_PRECISION 2
165
166 void
167 rl78_op (expressionS exp, int nbytes, int type)
168 {
169   int v = 0;
170
171   if ((exp.X_op == O_constant || exp.X_op == O_big)
172       && type != RL78REL_PCREL)
173     {
174       if (exp.X_op == O_big && exp.X_add_number <= 0)
175         {
176           LITTLENUM_TYPE w[2];
177           char * ip = rl78_bytes.ops + rl78_bytes.n_ops;
178
179           gen_to_words (w, F_PRECISION, 8);
180           ip[3] = w[0] >> 8;
181           ip[2] = w[0];
182           ip[1] = w[1] >> 8;
183           ip[0] = w[1];
184           rl78_bytes.n_ops += 4;
185         }
186       else
187         {
188           v = exp.X_add_number;
189           while (nbytes)
190             {
191               rl78_bytes.ops[rl78_bytes.n_ops++] =v & 0xff;
192               v >>= 8;
193               nbytes --;
194             }
195         }
196     }
197   else
198     {
199       if (nbytes > 2
200           && exp.X_md == BFD_RELOC_RL78_CODE)
201         exp.X_md = 0;
202       rl78_op_fixup (exp, rl78_bytes.n_ops * 8, nbytes * 8, type);
203       memset (rl78_bytes.ops + rl78_bytes.n_ops, 0, nbytes);
204       rl78_bytes.n_ops += nbytes;
205     }
206 }
207
208 /* This gets complicated when the field spans bytes, because fields
209    are numbered from the MSB of the first byte as zero, and bits are
210    stored LSB towards the LSB of the byte.  Thus, a simple four-bit
211    insertion of 12 at position 4 of 0x00 yields: 0x0b.  A three-bit
212    insertion of b'MXL at position 7 is like this:
213
214      - - - -  - - - -   - - - -  - - - -
215                     M   X L               */
216
217 void
218 rl78_field (int val, int pos, int sz)
219 {
220   int valm;
221   int bytep, bitp;
222
223   if (sz > 0)
224     {
225       if (val < 0 || val >= (1 << sz))
226         as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz);
227     }
228   else
229     {
230       sz = - sz;
231       if (val < -(1 << (sz - 1)) || val >= (1 << (sz - 1)))
232         as_bad (_("Value %d doesn't fit in signed %d-bit field"), val, sz);
233     }
234
235   /* This code points at 'M' in the above example.  */
236   bytep = pos / 8;
237   bitp = pos % 8;
238
239   while (bitp + sz > 8)
240     {
241       int ssz = 8 - bitp;
242       int svalm;
243
244       svalm = val >> (sz - ssz);
245       svalm = svalm & ((1 << ssz) - 1);
246       svalm = svalm << (8 - bitp - ssz);
247       gas_assert (bytep < rl78_bytes.n_base);
248       rl78_bytes.base[bytep] |= svalm;
249
250       bitp = 0;
251       sz -= ssz;
252       bytep ++;
253     }
254   valm = val & ((1 << sz) - 1);
255   valm = valm << (8 - bitp - sz);
256   gas_assert (bytep < rl78_bytes.n_base);
257   rl78_bytes.base[bytep] |= valm;
258 }
259
260 /*------------------------------------------------------------------*/
261
262 enum options
263 {
264   OPTION_RELAX = OPTION_MD_BASE,
265   OPTION_G10,
266 };
267
268 #define RL78_SHORTOPTS ""
269 const char * md_shortopts = RL78_SHORTOPTS;
270
271 /* Assembler options.  */
272 struct option md_longopts[] =
273 {
274   {"relax", no_argument, NULL, OPTION_RELAX},
275   {"mg10", no_argument, NULL, OPTION_G10},
276   {NULL, no_argument, NULL, 0}
277 };
278 size_t md_longopts_size = sizeof (md_longopts);
279
280 int
281 md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
282 {
283   switch (c)
284     {
285     case OPTION_RELAX:
286       linkrelax = 1;
287       return 1;
288
289     case OPTION_G10:
290       elf_flags |= E_FLAG_RL78_G10;
291       return 1;
292     }
293   return 0;
294 }
295
296 void
297 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
298 {
299 }
300
301
302 static void
303 s_bss (int ignore ATTRIBUTE_UNUSED)
304 {
305   int temp;
306
307   temp = get_absolute_expression ();
308   subseg_set (bss_section, (subsegT) temp);
309   demand_empty_rest_of_line ();
310 }
311
312 /* The target specific pseudo-ops which we support.  */
313 const pseudo_typeS md_pseudo_table[] =
314 {
315   /* Our "standard" pseudos. */
316   { "double",   float_cons,    'd' },
317   { "bss",      s_bss,          0 },
318   { "3byte",    cons,           3 },
319   { "int",      cons,           4 },
320   { "word",     cons,           4 },
321
322   /* End of list marker.  */
323   { NULL,       NULL,           0 }
324 };
325
326 void
327 md_begin (void)
328 {
329 }
330
331 void
332 rl78_md_end (void)
333 {
334 }
335
336 /* Set the ELF specific flags.  */
337 void
338 rl78_elf_final_processing (void)
339 {
340   elf_elfheader (stdoutput)->e_flags |= elf_flags;
341 }
342
343 /* Write a value out to the object file, using the appropriate endianness.  */
344 void
345 md_number_to_chars (char * buf, valueT val, int n)
346 {
347   number_to_chars_littleendian (buf, val, n);
348 }
349
350 static struct
351 {
352   char * fname;
353   int    reloc;
354 }
355 reloc_functions[] =
356 {
357   { "code", BFD_RELOC_RL78_CODE },
358   { "lo16", BFD_RELOC_RL78_LO16 },
359   { "hi16", BFD_RELOC_RL78_HI16 },
360   { "hi8",  BFD_RELOC_RL78_HI8 },
361   { 0, 0 }
362 };
363
364 void
365 md_operand (expressionS * exp ATTRIBUTE_UNUSED)
366 {
367   int reloc = 0;
368   int i;
369
370   for (i = 0; reloc_functions[i].fname; i++)
371     {
372       int flen = strlen (reloc_functions[i].fname);
373
374       if (input_line_pointer[0] == '%'
375           && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
376           && input_line_pointer[flen + 1] == '(')
377         {
378           reloc = reloc_functions[i].reloc;
379           input_line_pointer += flen + 2;
380           break;
381         }
382     }
383   if (reloc == 0)
384     return;
385
386   expression (exp);
387   if (* input_line_pointer == ')')
388     input_line_pointer ++;
389
390   exp->X_md = reloc;
391 }
392
393 void
394 rl78_frag_init (fragS * fragP)
395 {
396   if (rl78_bytes.n_relax || rl78_bytes.link_relax)
397     {
398       fragP->tc_frag_data = malloc (sizeof (rl78_bytesT));
399       memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT));
400     }
401   else
402     fragP->tc_frag_data = 0;
403 }
404
405 /* When relaxing, we need to output a reloc for any .align directive
406    so that we can retain this alignment as we adjust opcode sizes.  */
407 void
408 rl78_handle_align (fragS * frag)
409 {
410   if (linkrelax
411       && (frag->fr_type == rs_align
412           || frag->fr_type == rs_align_code)
413       && frag->fr_address + frag->fr_fix > 0
414       && frag->fr_offset > 0
415       && now_seg != bss_section)
416     {
417       fix_new (frag, frag->fr_fix, 0,
418                &abs_symbol, RL78_RELAXA_ALIGN + frag->fr_offset,
419                0, BFD_RELOC_RL78_RELAX);
420       /* For the purposes of relaxation, this relocation is attached
421          to the byte *after* the alignment - i.e. the byte that must
422          remain aligned.  */
423       fix_new (frag->fr_next, 0, 0,
424                &abs_symbol, RL78_RELAXA_ELIGN + frag->fr_offset,
425                0, BFD_RELOC_RL78_RELAX);
426     }
427 }
428
429 char *
430 md_atof (int type, char * litP, int * sizeP)
431 {
432   return ieee_md_atof (type, litP, sizeP, target_big_endian);
433 }
434
435 symbolS *
436 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
437 {
438   return NULL;
439 }
440
441 #define APPEND(B, N_B)                                 \
442   if (rl78_bytes.N_B)                                  \
443     {                                                  \
444       memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B);  \
445       idx += rl78_bytes.N_B;                           \
446     }
447
448
449 void
450 md_assemble (char * str)
451 {
452   char * bytes;
453   fragS * frag_then = frag_now;
454   int idx = 0;
455   int i;
456   int rel;
457   expressionS  *exp;
458
459   /*printf("\033[32mASM: %s\033[0m\n", str);*/
460
461   dwarf2_emit_insn (0);
462
463   memset (& rl78_bytes, 0, sizeof (rl78_bytes));
464
465   rl78_lex_init (str, str + strlen (str));
466
467   rl78_parse ();
468
469   /* This simplifies the relaxation code.  */
470   if (rl78_bytes.link_relax)
471     {
472       int olen = rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops;
473       /* We do it this way because we want the frag to have the
474          rl78_bytes in it, which we initialize above.  */
475       bytes = frag_more (olen);
476       frag_then = frag_now;
477       frag_variant (rs_machine_dependent,
478                     olen /* max_chars */,
479                     0 /* var */,
480                     olen /* subtype */,
481                     0 /* symbol */,
482                     0 /* offset */,
483                     0 /* opcode */);
484       frag_then->fr_opcode = bytes;
485       frag_then->fr_fix = olen + (bytes - frag_then->fr_literal);
486       frag_then->fr_subtype = olen;
487       frag_then->fr_var = 0;
488     }
489   else
490     {
491       bytes = frag_more (rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops);
492       frag_then = frag_now;
493     }
494
495   APPEND (prefix, n_prefix);
496   APPEND (base, n_base);
497   APPEND (ops, n_ops);
498
499   if (rl78_bytes.link_relax)
500     {
501       fixS * f;
502
503       f = fix_new (frag_then,
504                    (char *) bytes - frag_then->fr_literal,
505                    0,
506                    abs_section_sym,
507                    rl78_bytes.link_relax | rl78_bytes.n_fixups,
508                    0,
509                    BFD_RELOC_RL78_RELAX);
510       frag_then->tc_frag_data->link_relax_fixP = f;
511     }
512
513   for (i = 0; i < rl78_bytes.n_fixups; i ++)
514     {
515       /* index: [nbytes][type] */
516       static int reloc_map[5][4] =
517         {
518           { 0,            0 },
519           { BFD_RELOC_8,  BFD_RELOC_8_PCREL },
520           { BFD_RELOC_16, BFD_RELOC_16_PCREL },
521           { BFD_RELOC_24, BFD_RELOC_24_PCREL },
522           { BFD_RELOC_32, BFD_RELOC_32_PCREL },
523         };
524       fixS * f;
525
526       idx = rl78_bytes.fixups[i].offset / 8;
527       rel = reloc_map [rl78_bytes.fixups[i].nbits / 8][(int) rl78_bytes.fixups[i].type];
528
529       if (rl78_bytes.fixups[i].reloc)
530         rel = rl78_bytes.fixups[i].reloc;
531
532       if (frag_then->tc_frag_data)
533         exp = & frag_then->tc_frag_data->fixups[i].exp;
534       else
535         exp = & rl78_bytes.fixups[i].exp;
536
537       f = fix_new_exp (frag_then,
538                        (char *) bytes + idx - frag_then->fr_literal,
539                        rl78_bytes.fixups[i].nbits / 8,
540                        exp,
541                        rl78_bytes.fixups[i].type == RL78REL_PCREL ? 1 : 0,
542                        rel);
543       if (frag_then->tc_frag_data)
544         frag_then->tc_frag_data->fixups[i].fixP = f;
545     }
546 }
547
548 void
549 rl78_cons_fix_new (fragS *      frag,
550                  int            where,
551                  int            size,
552                  expressionS *  exp)
553 {
554   bfd_reloc_code_real_type type;
555
556   switch (size)
557     {
558     case 1:
559       type = BFD_RELOC_8;
560       break;
561     case 2:
562       type = BFD_RELOC_16;
563       break;
564     case 3:
565       type = BFD_RELOC_24;
566       break;
567     case 4:
568       type = BFD_RELOC_32;
569       break;
570     default:
571       as_bad (_("unsupported constant size %d\n"), size);
572       return;
573     }
574
575   switch (exp->X_md)
576     {
577     case BFD_RELOC_RL78_CODE:
578       if (size == 2)
579         type = exp->X_md;
580       break;
581     case BFD_RELOC_RL78_LO16:
582     case BFD_RELOC_RL78_HI16:
583       if (size != 2)
584         as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
585       type = exp->X_md;
586       break;
587     case BFD_RELOC_RL78_HI8:
588       if (size != 1)
589         as_bad (_("%%hi8 only applies to .byte"));
590       type = exp->X_md;
591       break;
592     default:
593       break;
594     }
595
596   if (exp->X_op == O_subtract && exp->X_op_symbol)
597     {
598       if (size != 4 && size != 2 && size != 1)
599         as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
600       else
601         type = BFD_RELOC_RL78_DIFF;
602     }
603
604   fix_new_exp (frag, where, (int) size, exp, 0, type);
605 }
606
607 /* No relaxation just yet */
608 int
609 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
610 {
611   return 0;
612 }
613
614 arelent **
615 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
616 {
617   static arelent * reloc[8];
618   int rp;
619
620   if (fixp->fx_r_type == BFD_RELOC_NONE)
621     {
622       reloc[0] = NULL;
623       return reloc;
624     }
625
626   if (fixp->fx_subsy
627       && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
628     {
629       fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
630       fixp->fx_subsy = NULL;
631     }
632
633   reloc[0]                = (arelent *) xmalloc (sizeof (arelent));
634   reloc[0]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
635   * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
636   reloc[0]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
637   reloc[0]->addend        = fixp->fx_offset;
638
639   if (fixp->fx_r_type == BFD_RELOC_RL78_32_OP
640       && fixp->fx_subsy)
641     {
642       fixp->fx_r_type = BFD_RELOC_RL78_DIFF;
643     }
644
645 #define OPX(REL,SYM,ADD)                                                        \
646   reloc[rp]                = (arelent *) xmalloc (sizeof (arelent));            \
647   reloc[rp]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));         \
648   reloc[rp]->howto         = bfd_reloc_type_lookup (stdoutput, REL);            \
649   reloc[rp]->addend        = ADD;                                               \
650   * reloc[rp]->sym_ptr_ptr = SYM;                                               \
651   reloc[rp]->address       = fixp->fx_frag->fr_address + fixp->fx_where;        \
652   reloc[++rp] = NULL
653 #define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
654 #define OPIMM(IMM) OPX(BFD_RELOC_RL78_SYM, abs_symbol.bsym, IMM)
655 #define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
656 #define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
657
658   rp = 1;
659
660   /* Certain BFD relocations cannot be translated directly into
661      a single (non-Red Hat) RL78 relocation, but instead need
662      multiple RL78 relocations - handle them here.  */
663   switch (fixp->fx_r_type)
664     {
665     case BFD_RELOC_RL78_DIFF:
666       SYM0 ();
667       OPSYM (symbol_get_bfdsym (fixp->fx_subsy));
668       OP(OP_SUBTRACT);
669
670       switch (fixp->fx_size)
671         {
672         case 1:
673           OP(ABS8);
674           break;
675         case 2:
676           OP (ABS16);
677           break;
678         case 4:
679           OP (ABS32);
680           break;
681         }
682       break;
683
684     case BFD_RELOC_RL78_NEG32:
685       SYM0 ();
686       OP (OP_NEG);
687       OP (ABS32);
688       break;
689
690     case BFD_RELOC_RL78_CODE:
691       SYM0 ();
692       OP (ABS16);
693       break;
694
695     case BFD_RELOC_RL78_LO16:
696       SYM0 ();
697       OPIMM (0xffff);
698       OP (OP_AND);
699       OP (ABS16);
700       break;
701
702     case BFD_RELOC_RL78_HI16:
703       SYM0 ();
704       OPIMM (16);
705       OP (OP_SHRA);
706       OP (ABS16);
707       break;
708
709     case BFD_RELOC_RL78_HI8:
710       SYM0 ();
711       OPIMM (16);
712       OP (OP_SHRA);
713       OPIMM (0xff);
714       OP (OP_AND);
715       OP (ABS8);
716       break;
717
718     default:
719       reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
720       reloc[1] = NULL;
721       break;
722     }
723
724   return reloc;
725 }
726
727 int
728 rl78_validate_fix_sub (struct fix * f)
729 {
730   /* We permit the subtraction of two symbols in a few cases.  */
731   /* mov #sym1-sym2, R3 */
732   if (f->fx_r_type == BFD_RELOC_RL78_32_OP)
733     return 1;
734   /* .long sym1-sym2 */
735   if (f->fx_r_type == BFD_RELOC_RL78_DIFF
736       && ! f->fx_pcrel
737       && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
738     return 1;
739   return 0;
740 }
741
742 long
743 md_pcrel_from_section (fixS * fixP, segT sec)
744 {
745   long rv;
746
747   if (fixP->fx_addsy != NULL
748       && (! S_IS_DEFINED (fixP->fx_addsy)
749           || S_GET_SEGMENT (fixP->fx_addsy) != sec))
750     /* The symbol is undefined (or is defined but not in this section).
751        Let the linker figure it out.  */
752     return 0;
753
754   rv = fixP->fx_frag->fr_address + fixP->fx_where;
755   switch (fixP->fx_r_type)
756     {
757     case BFD_RELOC_8_PCREL:
758       rv += 1;
759       break;
760     case BFD_RELOC_16_PCREL:
761       rv += 2;
762       break;
763     default:
764       break;
765     }
766   return rv;
767 }
768
769 void
770 md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
771               valueT *     t ATTRIBUTE_UNUSED,
772               segT         s ATTRIBUTE_UNUSED)
773 {
774   char * op;
775   unsigned long val;
776
777   if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
778     return;
779   if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
780     return;
781
782   op = f->fx_frag->fr_literal + f->fx_where;
783   val = (unsigned long) * t;
784
785   switch (f->fx_r_type)
786     {
787     case BFD_RELOC_NONE:
788       break;
789
790     case BFD_RELOC_RL78_RELAX:
791       f->fx_done = 1;
792       break;
793
794     case BFD_RELOC_8:
795     case BFD_RELOC_8_PCREL:
796       op[0] = val;
797       break;
798
799     case BFD_RELOC_16:
800     case BFD_RELOC_16_PCREL:
801     case BFD_RELOC_RL78_CODE:
802       op[0] = val;
803       op[1] = val >> 8;
804       break;
805
806     case BFD_RELOC_24:
807       op[0] = val;
808       op[1] = val >> 8;
809       op[2] = val >> 16;
810       break;
811
812     case BFD_RELOC_32:
813     case BFD_RELOC_RL78_DIFF:
814       op[0] = val;
815       op[1] = val >> 8;
816       op[2] = val >> 16;
817       op[3] = val >> 24;
818       break;
819
820     default:
821       as_bad (_("Unknown reloc in md_apply_fix: %s"),
822               bfd_get_reloc_code_name (f->fx_r_type));
823       break;
824     }
825
826   if (f->fx_addsy == NULL)
827     f->fx_done = 1;
828 }
829
830 valueT
831 md_section_align (segT segment, valueT size)
832 {
833   int align = bfd_get_section_alignment (stdoutput, segment);
834   return ((size + (1 << align) - 1) & (-1 << align));
835 }
836
837 void
838 md_convert_frag (bfd *   abfd ATTRIBUTE_UNUSED,
839                  segT    segment ATTRIBUTE_UNUSED,
840                  fragS * fragP ATTRIBUTE_UNUSED)
841 {
842   /* No relaxation yet */
843   fragP->fr_var = 0;
844 }