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