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