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