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