Ensure that %func() expressions are outermost terms
[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 void
351 require_end_of_expr (char *fname)
352 {
353   while (* input_line_pointer == ' '
354          || * input_line_pointer == '\t')
355     input_line_pointer ++;
356
357   if (! * input_line_pointer
358       || strchr ("\n\r,", * input_line_pointer)
359       || strchr (comment_chars, * input_line_pointer)
360       || strchr (line_comment_chars, * input_line_pointer)
361       || strchr (line_separator_chars, * input_line_pointer))
362     return;
363
364   as_bad (_("%%%s() must be outermost term in expression"), fname);
365 }
366
367 static struct
368 {
369   char * fname;
370   int    reloc;
371 }
372 reloc_functions[] =
373 {
374   { "code", BFD_RELOC_RL78_CODE },
375   { "lo16", BFD_RELOC_RL78_LO16 },
376   { "hi16", BFD_RELOC_RL78_HI16 },
377   { "hi8",  BFD_RELOC_RL78_HI8 },
378   { 0, 0 }
379 };
380
381 void
382 md_operand (expressionS * exp ATTRIBUTE_UNUSED)
383 {
384   int reloc = 0;
385   int i;
386
387   for (i = 0; reloc_functions[i].fname; i++)
388     {
389       int flen = strlen (reloc_functions[i].fname);
390
391       if (input_line_pointer[0] == '%'
392           && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
393           && input_line_pointer[flen + 1] == '(')
394         {
395           reloc = reloc_functions[i].reloc;
396           input_line_pointer += flen + 2;
397           break;
398         }
399     }
400   if (reloc == 0)
401     return;
402
403   expression (exp);
404   if (* input_line_pointer == ')')
405     input_line_pointer ++;
406
407   exp->X_md = reloc;
408
409   require_end_of_expr (reloc_functions[i].fname);
410 }
411
412 void
413 rl78_frag_init (fragS * fragP)
414 {
415   if (rl78_bytes.n_relax || rl78_bytes.link_relax)
416     {
417       fragP->tc_frag_data = malloc (sizeof (rl78_bytesT));
418       memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT));
419     }
420   else
421     fragP->tc_frag_data = 0;
422 }
423
424 /* When relaxing, we need to output a reloc for any .align directive
425    so that we can retain this alignment as we adjust opcode sizes.  */
426 void
427 rl78_handle_align (fragS * frag)
428 {
429   if (linkrelax
430       && (frag->fr_type == rs_align
431           || frag->fr_type == rs_align_code)
432       && frag->fr_address + frag->fr_fix > 0
433       && frag->fr_offset > 0
434       && now_seg != bss_section)
435     {
436       fix_new (frag, frag->fr_fix, 0,
437                &abs_symbol, RL78_RELAXA_ALIGN + frag->fr_offset,
438                0, BFD_RELOC_RL78_RELAX);
439       /* For the purposes of relaxation, this relocation is attached
440          to the byte *after* the alignment - i.e. the byte that must
441          remain aligned.  */
442       fix_new (frag->fr_next, 0, 0,
443                &abs_symbol, RL78_RELAXA_ELIGN + frag->fr_offset,
444                0, BFD_RELOC_RL78_RELAX);
445     }
446 }
447
448 char *
449 md_atof (int type, char * litP, int * sizeP)
450 {
451   return ieee_md_atof (type, litP, sizeP, target_big_endian);
452 }
453
454 symbolS *
455 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
456 {
457   return NULL;
458 }
459
460 #define APPEND(B, N_B)                                 \
461   if (rl78_bytes.N_B)                                  \
462     {                                                  \
463       memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B);  \
464       idx += rl78_bytes.N_B;                           \
465     }
466
467
468 void
469 md_assemble (char * str)
470 {
471   char * bytes;
472   fragS * frag_then = frag_now;
473   int idx = 0;
474   int i;
475   int rel;
476   expressionS  *exp;
477
478   /*printf("\033[32mASM: %s\033[0m\n", str);*/
479
480   dwarf2_emit_insn (0);
481
482   memset (& rl78_bytes, 0, sizeof (rl78_bytes));
483
484   rl78_lex_init (str, str + strlen (str));
485
486   rl78_parse ();
487
488   /* This simplifies the relaxation code.  */
489   if (rl78_bytes.link_relax)
490     {
491       int olen = rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops;
492       /* We do it this way because we want the frag to have the
493          rl78_bytes in it, which we initialize above.  */
494       bytes = frag_more (olen);
495       frag_then = frag_now;
496       frag_variant (rs_machine_dependent,
497                     olen /* max_chars */,
498                     0 /* var */,
499                     olen /* subtype */,
500                     0 /* symbol */,
501                     0 /* offset */,
502                     0 /* opcode */);
503       frag_then->fr_opcode = bytes;
504       frag_then->fr_fix = olen + (bytes - frag_then->fr_literal);
505       frag_then->fr_subtype = olen;
506       frag_then->fr_var = 0;
507     }
508   else
509     {
510       bytes = frag_more (rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops);
511       frag_then = frag_now;
512     }
513
514   APPEND (prefix, n_prefix);
515   APPEND (base, n_base);
516   APPEND (ops, n_ops);
517
518   if (rl78_bytes.link_relax)
519     {
520       fixS * f;
521
522       f = fix_new (frag_then,
523                    (char *) bytes - frag_then->fr_literal,
524                    0,
525                    abs_section_sym,
526                    rl78_bytes.link_relax | rl78_bytes.n_fixups,
527                    0,
528                    BFD_RELOC_RL78_RELAX);
529       frag_then->tc_frag_data->link_relax_fixP = f;
530     }
531
532   for (i = 0; i < rl78_bytes.n_fixups; i ++)
533     {
534       /* index: [nbytes][type] */
535       static int reloc_map[5][4] =
536         {
537           { 0,            0 },
538           { BFD_RELOC_8,  BFD_RELOC_8_PCREL },
539           { BFD_RELOC_16, BFD_RELOC_16_PCREL },
540           { BFD_RELOC_24, BFD_RELOC_24_PCREL },
541           { BFD_RELOC_32, BFD_RELOC_32_PCREL },
542         };
543       fixS * f;
544
545       idx = rl78_bytes.fixups[i].offset / 8;
546       rel = reloc_map [rl78_bytes.fixups[i].nbits / 8][(int) rl78_bytes.fixups[i].type];
547
548       if (rl78_bytes.fixups[i].reloc)
549         rel = rl78_bytes.fixups[i].reloc;
550
551       if (frag_then->tc_frag_data)
552         exp = & frag_then->tc_frag_data->fixups[i].exp;
553       else
554         exp = & rl78_bytes.fixups[i].exp;
555
556       f = fix_new_exp (frag_then,
557                        (char *) bytes + idx - frag_then->fr_literal,
558                        rl78_bytes.fixups[i].nbits / 8,
559                        exp,
560                        rl78_bytes.fixups[i].type == RL78REL_PCREL ? 1 : 0,
561                        rel);
562       if (frag_then->tc_frag_data)
563         frag_then->tc_frag_data->fixups[i].fixP = f;
564     }
565 }
566
567 void
568 rl78_cons_fix_new (fragS *      frag,
569                  int            where,
570                  int            size,
571                  expressionS *  exp)
572 {
573   bfd_reloc_code_real_type type;
574   fixS *fixP;
575
576   switch (size)
577     {
578     case 1:
579       type = BFD_RELOC_8;
580       break;
581     case 2:
582       type = BFD_RELOC_16;
583       break;
584     case 3:
585       type = BFD_RELOC_24;
586       break;
587     case 4:
588       type = BFD_RELOC_32;
589       break;
590     default:
591       as_bad (_("unsupported constant size %d\n"), size);
592       return;
593     }
594
595   switch (exp->X_md)
596     {
597     case BFD_RELOC_RL78_CODE:
598       if (size == 2)
599         type = exp->X_md;
600       break;
601     case BFD_RELOC_RL78_LO16:
602     case BFD_RELOC_RL78_HI16:
603       if (size != 2)
604         as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
605       type = exp->X_md;
606       break;
607     case BFD_RELOC_RL78_HI8:
608       if (size != 1)
609         as_bad (_("%%hi8 only applies to .byte"));
610       type = exp->X_md;
611       break;
612     default:
613       break;
614     }
615
616   if (exp->X_op == O_subtract && exp->X_op_symbol)
617     {
618       if (size != 4 && size != 2 && size != 1)
619         as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
620       else
621         type = BFD_RELOC_RL78_DIFF;
622     }
623
624   fixP = fix_new_exp (frag, where, (int) size, exp, 0, type);
625   switch (exp->X_md)
626     {
627       /* These are intended to have values larger than the container,
628          since the backend puts only the portion we need in it.
629          However, we don't have a backend-specific reloc for them as
630          they're handled with complex relocations.  */
631     case BFD_RELOC_RL78_LO16:
632     case BFD_RELOC_RL78_HI16:
633     case BFD_RELOC_RL78_HI8:
634       fixP->fx_no_overflow = 1;
635       break;
636     default:
637       break;
638     }
639 }
640
641 /* No relaxation just yet */
642 int
643 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
644 {
645   return 0;
646 }
647
648 arelent **
649 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
650 {
651   static arelent * reloc[8];
652   int rp;
653
654   if (fixp->fx_r_type == BFD_RELOC_NONE)
655     {
656       reloc[0] = NULL;
657       return reloc;
658     }
659
660   if (fixp->fx_subsy
661       && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
662     {
663       fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
664       fixp->fx_subsy = NULL;
665     }
666
667   reloc[0]                = (arelent *) xmalloc (sizeof (arelent));
668   reloc[0]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));
669   * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
670   reloc[0]->address       = fixp->fx_frag->fr_address + fixp->fx_where;
671   reloc[0]->addend        = fixp->fx_offset;
672
673   if (fixp->fx_r_type == BFD_RELOC_RL78_32_OP
674       && fixp->fx_subsy)
675     {
676       fixp->fx_r_type = BFD_RELOC_RL78_DIFF;
677     }
678
679 #define OPX(REL,SYM,ADD)                                                        \
680   reloc[rp]                = (arelent *) xmalloc (sizeof (arelent));            \
681   reloc[rp]->sym_ptr_ptr   = (asymbol **) xmalloc (sizeof (asymbol *));         \
682   reloc[rp]->howto         = bfd_reloc_type_lookup (stdoutput, REL);            \
683   reloc[rp]->addend        = ADD;                                               \
684   * reloc[rp]->sym_ptr_ptr = SYM;                                               \
685   reloc[rp]->address       = fixp->fx_frag->fr_address + fixp->fx_where;        \
686   reloc[++rp] = NULL
687 #define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
688 #define OPIMM(IMM) OPX(BFD_RELOC_RL78_SYM, abs_symbol.bsym, IMM)
689 #define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
690 #define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
691
692   rp = 1;
693
694   /* Certain BFD relocations cannot be translated directly into
695      a single (non-Red Hat) RL78 relocation, but instead need
696      multiple RL78 relocations - handle them here.  */
697   switch (fixp->fx_r_type)
698     {
699     case BFD_RELOC_RL78_DIFF:
700       SYM0 ();
701       OPSYM (symbol_get_bfdsym (fixp->fx_subsy));
702       OP(OP_SUBTRACT);
703
704       switch (fixp->fx_size)
705         {
706         case 1:
707           OP(ABS8);
708           break;
709         case 2:
710           OP (ABS16);
711           break;
712         case 4:
713           OP (ABS32);
714           break;
715         }
716       break;
717
718     case BFD_RELOC_RL78_NEG32:
719       SYM0 ();
720       OP (OP_NEG);
721       OP (ABS32);
722       break;
723
724     case BFD_RELOC_RL78_CODE:
725       SYM0 ();
726       OP (ABS16);
727       break;
728
729     case BFD_RELOC_RL78_LO16:
730       SYM0 ();
731       OPIMM (0xffff);
732       OP (OP_AND);
733       OP (ABS16);
734       break;
735
736     case BFD_RELOC_RL78_HI16:
737       SYM0 ();
738       OPIMM (16);
739       OP (OP_SHRA);
740       OP (ABS16);
741       break;
742
743     case BFD_RELOC_RL78_HI8:
744       SYM0 ();
745       OPIMM (16);
746       OP (OP_SHRA);
747       OPIMM (0xff);
748       OP (OP_AND);
749       OP (ABS8);
750       break;
751
752     default:
753       reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
754       reloc[1] = NULL;
755       break;
756     }
757
758   return reloc;
759 }
760
761 int
762 rl78_validate_fix_sub (struct fix * f)
763 {
764   /* We permit the subtraction of two symbols in a few cases.  */
765   /* mov #sym1-sym2, R3 */
766   if (f->fx_r_type == BFD_RELOC_RL78_32_OP)
767     return 1;
768   /* .long sym1-sym2 */
769   if (f->fx_r_type == BFD_RELOC_RL78_DIFF
770       && ! f->fx_pcrel
771       && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
772     return 1;
773   return 0;
774 }
775
776 long
777 md_pcrel_from_section (fixS * fixP, segT sec)
778 {
779   long rv;
780
781   if (fixP->fx_addsy != NULL
782       && (! S_IS_DEFINED (fixP->fx_addsy)
783           || S_GET_SEGMENT (fixP->fx_addsy) != sec))
784     /* The symbol is undefined (or is defined but not in this section).
785        Let the linker figure it out.  */
786     return 0;
787
788   rv = fixP->fx_frag->fr_address + fixP->fx_where;
789   switch (fixP->fx_r_type)
790     {
791     case BFD_RELOC_8_PCREL:
792       rv += 1;
793       break;
794     case BFD_RELOC_16_PCREL:
795       rv += 2;
796       break;
797     default:
798       break;
799     }
800   return rv;
801 }
802
803 void
804 md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
805               valueT *     t ATTRIBUTE_UNUSED,
806               segT         s ATTRIBUTE_UNUSED)
807 {
808   char * op;
809   unsigned long val;
810
811   if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
812     return;
813   if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
814     return;
815
816   op = f->fx_frag->fr_literal + f->fx_where;
817   val = (unsigned long) * t;
818
819   switch (f->fx_r_type)
820     {
821     case BFD_RELOC_NONE:
822       break;
823
824     case BFD_RELOC_RL78_RELAX:
825       f->fx_done = 1;
826       break;
827
828     case BFD_RELOC_8:
829     case BFD_RELOC_8_PCREL:
830       op[0] = val;
831       break;
832
833     case BFD_RELOC_16:
834     case BFD_RELOC_16_PCREL:
835     case BFD_RELOC_RL78_CODE:
836       op[0] = val;
837       op[1] = val >> 8;
838       break;
839
840     case BFD_RELOC_24:
841       op[0] = val;
842       op[1] = val >> 8;
843       op[2] = val >> 16;
844       break;
845
846     case BFD_RELOC_32:
847     case BFD_RELOC_RL78_DIFF:
848       op[0] = val;
849       op[1] = val >> 8;
850       op[2] = val >> 16;
851       op[3] = val >> 24;
852       break;
853
854     default:
855       as_bad (_("Unknown reloc in md_apply_fix: %s"),
856               bfd_get_reloc_code_name (f->fx_r_type));
857       break;
858     }
859
860   if (f->fx_addsy == NULL)
861     f->fx_done = 1;
862 }
863
864 valueT
865 md_section_align (segT segment, valueT size)
866 {
867   int align = bfd_get_section_alignment (stdoutput, segment);
868   return ((size + (1 << align) - 1) & (-1 << align));
869 }
870
871 void
872 md_convert_frag (bfd *   abfd ATTRIBUTE_UNUSED,
873                  segT    segment ATTRIBUTE_UNUSED,
874                  fragS * fragP ATTRIBUTE_UNUSED)
875 {
876   /* No relaxation yet */
877   fragP->fr_var = 0;
878 }