Move struc-symbol.h to symbols.c
[deliverable/binutils-gdb.git] / gas / config / tc-rl78.c
CommitLineData
99c513f6 1/* tc-rl78.c -- Assembler for the Renesas RL78
219d1afa 2 Copyright (C) 2011-2018 Free Software Foundation, Inc.
99c513f6
DD
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"
99c513f6
DD
22#include "safe-ctype.h"
23#include "dwarf2dbg.h"
99c513f6
DD
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
32const 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. */
36const char line_comment_chars[] = "#";
cbf1fdc9
DD
37/* Use something that isn't going to be needed by any expressions or
38 other syntax. */
39const char line_separator_chars[] = "@";
99c513f6
DD
40
41const char EXP_CHARS[] = "eE";
42const char FLT_CHARS[] = "dD";
43
4046d87a
NC
44/* ELF flags to set in the output file header. */
45static int elf_flags = 0;
46
99c513f6
DD
47/*------------------------------------------------------------------*/
48
49char * rl78_lex_start;
50char * rl78_lex_end;
51
52typedef 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
83static rl78_bytesT rl78_bytes;
84
0c315784
DD
85void
86rl78_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
9cea966c
DD
94void
95rl78_linkrelax_addr16 (void)
96{
97 rl78_bytes.link_relax |= RL78_RELAXA_ADDR16;
98}
99
100void
101rl78_linkrelax_branch (void)
102{
e896287c 103 rl78_relax (RL78_RELAX_BRANCH, 0);
9cea966c
DD
104 rl78_bytes.link_relax |= RL78_RELAXA_BRA;
105}
106
99c513f6
DD
107static void
108rl78_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
124void
125rl78_prefix (int p)
126{
127 rl78_bytes.prefix[0] = p;
128 rl78_bytes.n_prefix = 1;
129}
130
131int
e6c7cdec 132rl78_has_prefix (void)
99c513f6
DD
133{
134 return rl78_bytes.n_prefix;
135}
136
137void
138rl78_base1 (int b1)
139{
140 rl78_bytes.base[0] = b1;
141 rl78_bytes.n_base = 1;
142}
143
144void
145rl78_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
152void
153rl78_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
161void
162rl78_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
173void
174rl78_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 {
4107ae22
DD
206 if (nbytes > 2
207 && exp.X_md == BFD_RELOC_RL78_CODE)
208 exp.X_md = 0;
b3fe4307
NC
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
99c513f6
DD
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
234void
235rl78_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
9cea966c
DD
279enum options
280{
281 OPTION_RELAX = OPTION_MD_BASE,
e896287c 282 OPTION_NORELAX,
4046d87a 283 OPTION_G10,
1740ba0c
NC
284 OPTION_G13,
285 OPTION_G14,
856ea05c
KP
286 OPTION_32BIT_DOUBLES,
287 OPTION_64BIT_DOUBLES,
9cea966c
DD
288};
289
99c513f6
DD
290#define RL78_SHORTOPTS ""
291const char * md_shortopts = RL78_SHORTOPTS;
292
293/* Assembler options. */
294struct option md_longopts[] =
295{
9cea966c 296 {"relax", no_argument, NULL, OPTION_RELAX},
e896287c 297 {"norelax", no_argument, NULL, OPTION_NORELAX},
4046d87a 298 {"mg10", no_argument, NULL, OPTION_G10},
1740ba0c
NC
299 {"mg13", no_argument, NULL, OPTION_G13},
300 {"mg14", no_argument, NULL, OPTION_G14},
301 {"mrl78", no_argument, NULL, OPTION_G14},
856ea05c
KP
302 {"m32bit-doubles", no_argument, NULL, OPTION_32BIT_DOUBLES},
303 {"m64bit-doubles", no_argument, NULL, OPTION_64BIT_DOUBLES},
99c513f6
DD
304 {NULL, no_argument, NULL, 0}
305};
306size_t md_longopts_size = sizeof (md_longopts);
307
308int
17b9d67d 309md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
99c513f6 310{
9cea966c
DD
311 switch (c)
312 {
313 case OPTION_RELAX:
314 linkrelax = 1;
315 return 1;
e896287c
DD
316 case OPTION_NORELAX:
317 linkrelax = 0;
318 return 1;
9cea966c 319
4046d87a 320 case OPTION_G10:
1740ba0c 321 elf_flags &= ~ E_FLAG_RL78_CPU_MASK;
4046d87a
NC
322 elf_flags |= E_FLAG_RL78_G10;
323 return 1;
856ea05c 324
1740ba0c
NC
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
856ea05c
KP
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;
9cea966c 342 }
99c513f6
DD
343 return 0;
344}
345
0952813b
DD
346int
347rl78_isa_g10 (void)
348{
349 return (elf_flags & E_FLAG_RL78_CPU_MASK) == E_FLAG_RL78_G10;
350}
351
352int
353rl78_isa_g13 (void)
354{
355 return (elf_flags & E_FLAG_RL78_CPU_MASK) == E_FLAG_RL78_G13;
356}
357
358int
359rl78_isa_g14 (void)
360{
361 return (elf_flags & E_FLAG_RL78_CPU_MASK) == E_FLAG_RL78_G14;
362}
363
99c513f6 364void
6ff71e76 365md_show_usage (FILE * stream)
99c513f6 366{
856ea05c 367 fprintf (stream, _(" RL78 specific command line options:\n"));
6ff71e76 368 fprintf (stream, _(" --mrelax Enable link time relaxation\n"));
856ea05c 369 fprintf (stream, _(" --mg10 Enable support for G10 variant\n"));
1740ba0c
NC
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"));
856ea05c 373 fprintf (stream, _(" --m32bit-doubles [default]\n"));
6ff71e76 374 fprintf (stream, _(" --m64bit-doubles Source code uses 64-bit doubles\n"));
99c513f6
DD
375}
376
99c513f6
DD
377static void
378s_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
856ea05c
KP
387static void
388rl78_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
99c513f6
DD
395/* The target specific pseudo-ops which we support. */
396const pseudo_typeS md_pseudo_table[] =
397{
856ea05c
KP
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 },
99c513f6
DD
404
405 /* End of list marker. */
406 { NULL, NULL, 0 }
407};
408
aff1a65e
NC
409static symbolS * rl78_abs_sym = NULL;
410
99c513f6
DD
411void
412md_begin (void)
413{
aff1a65e 414 rl78_abs_sym = symbol_make ("__rl78_abs__");
99c513f6
DD
415}
416
417void
418rl78_md_end (void)
419{
420}
421
4046d87a
NC
422/* Set the ELF specific flags. */
423void
424rl78_elf_final_processing (void)
425{
426 elf_elfheader (stdoutput)->e_flags |= elf_flags;
427}
428
99c513f6
DD
429/* Write a value out to the object file, using the appropriate endianness. */
430void
431md_number_to_chars (char * buf, valueT val, int n)
432{
433 number_to_chars_littleendian (buf, val, n);
434}
435
c9d66558 436static void
e0471c16 437require_end_of_expr (const char *fname)
c9d66558
DD
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
99c513f6
DD
453static struct
454{
e0471c16 455 const char * fname;
99c513f6
DD
456 int reloc;
457}
458reloc_functions[] =
459{
4107ae22 460 { "code", BFD_RELOC_RL78_CODE },
99c513f6
DD
461 { "lo16", BFD_RELOC_RL78_LO16 },
462 { "hi16", BFD_RELOC_RL78_HI16 },
463 { "hi8", BFD_RELOC_RL78_HI8 },
464 { 0, 0 }
465};
466
467void
468md_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;
c9d66558
DD
494
495 require_end_of_expr (reloc_functions[i].fname);
99c513f6
DD
496}
497
498void
499rl78_frag_init (fragS * fragP)
500{
9cea966c
DD
501 if (rl78_bytes.n_relax || rl78_bytes.link_relax)
502 {
325801bd 503 fragP->tc_frag_data = XNEW (rl78_bytesT);
9cea966c
DD
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. */
512void
513rl78_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 }
99c513f6
DD
532}
533
6d4af3c2 534const char *
99c513f6
DD
535md_atof (int type, char * litP, int * sizeP)
536{
537 return ieee_md_atof (type, litP, sizeP, target_big_endian);
538}
539
540symbolS *
541md_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
554void
555md_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
9cea966c 574 /* This simplifies the relaxation code. */
0c315784 575 if (rl78_bytes.n_relax || rl78_bytes.link_relax)
9cea966c
DD
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
0c315784
DD
579 rl78_bytes in it, which we initialize above. The extra bytes
580 are for relaxing. */
581 bytes = frag_more (olen + 3);
9cea966c
DD
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 }
99c513f6
DD
600
601 APPEND (prefix, n_prefix);
602 APPEND (base, n_base);
603 APPEND (ops, n_ops);
604
9cea966c
DD
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
99c513f6
DD
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
654void
655rl78_cons_fix_new (fragS * frag,
656 int where,
657 int size,
658 expressionS * exp)
659{
660 bfd_reloc_code_real_type type;
c9d66558 661 fixS *fixP;
99c513f6
DD
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
392ca752
DD
682 switch (exp->X_md)
683 {
4107ae22
DD
684 case BFD_RELOC_RL78_CODE:
685 if (size == 2)
686 type = exp->X_md;
687 break;
392ca752
DD
688 case BFD_RELOC_RL78_LO16:
689 case BFD_RELOC_RL78_HI16:
690 if (size != 2)
6ff71e76
NC
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;
392ca752
DD
698 break;
699 case BFD_RELOC_RL78_HI8:
700 if (size != 1)
6ff71e76
NC
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;
392ca752
DD
708 break;
709 default:
710 break;
711 }
712
99c513f6
DD
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
c9d66558
DD
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 }
99c513f6
DD
736}
737
0c315784
DD
738\f
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
757typedef enum
758{
759 OT_other,
760 OT_bt,
761 OT_bt_sfr,
762 OT_bt_es,
763 OT_bc,
e896287c
DD
764 OT_bh,
765 OT_sk,
766 OT_call,
767 OT_br,
0c315784
DD
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
789static op_type_T
e896287c 790rl78_opcode_type (char * ops)
0c315784 791{
e896287c
DD
792 unsigned char *op = (unsigned char *)ops;
793
0c315784
DD
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
e896287c
DD
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
0c315784
DD
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
837static int
838rl78_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,
6ff71e76 881 so we only need to subtract fx_fix and return it. */
0c315784 882
99c513f6
DD
883int
884md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
885{
0c315784
DD
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
904int
905rl78_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 {
e896287c
DD
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
0c315784
DD
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;
e896287c
DD
951 case OT_sk:
952 newsize = 2;
953 break;
954 default:
0c315784
DD
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;
e896287c
DD
1001 case OT_sk:
1002 newsize = 2;
1003 break;
1004 default:
0c315784
DD
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;
6ff71e76
NC
1029}
1030
0c315784
DD
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
1042void
1043md_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);
54f66250 1064 tprintf ("\033[32mmypc: 0x%x\033[0m\n", (int)mypc);
0c315784
DD
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,
54f66250 1069 fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH, 0))
0c315784
DD
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;
e896287c 1099 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
0c315784
DD
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;
e896287c 1117 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
0c315784
DD
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;
e896287c 1135 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
0c315784
DD
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;
e896287c 1153 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
0c315784
DD
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;
e896287c 1171 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
0c315784
DD
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
e896287c
DD
1186 case OPCODE (OT_sk, 2): /* SK<cond> - no change */
1187 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1188 break;
3739860c 1189
e896287c
DD
1190 default:
1191 reloc_type = fix ? fix->fx_r_type : BFD_RELOC_NONE;
1192 break;
0c315784
DD
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 && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
1237 != fragP->fr_fix))
1238 as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
1239 (long) fragP->fr_fix,
1240 (long) fragP->fr_address, (long) fragP->fr_next->fr_address);
99c513f6 1241}
9cea966c 1242
0c315784
DD
1243/* End of relaxation code.
1244 ----------------------------------------------------------------------*/
1245\f
1246
99c513f6
DD
1247arelent **
1248tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
1249{
1250 static arelent * reloc[8];
1251 int rp;
99c513f6
DD
1252
1253 if (fixp->fx_r_type == BFD_RELOC_NONE)
1254 {
1255 reloc[0] = NULL;
1256 return reloc;
1257 }
1258
e896287c
DD
1259 if (fixp->fx_r_type == BFD_RELOC_RL78_RELAX && !linkrelax)
1260 {
1261 reloc[0] = NULL;
1262 return reloc;
1263 }
1264
99c513f6
DD
1265 if (fixp->fx_subsy
1266 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1267 {
1268 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
1269 fixp->fx_subsy = NULL;
1270 }
1271
add39d23
TS
1272 reloc[0] = XNEW (arelent);
1273 reloc[0]->sym_ptr_ptr = XNEW (asymbol *);
99c513f6
DD
1274 * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1275 reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
1276 reloc[0]->addend = fixp->fx_offset;
1277
1278 if (fixp->fx_r_type == BFD_RELOC_RL78_32_OP
1279 && fixp->fx_subsy)
1280 {
1281 fixp->fx_r_type = BFD_RELOC_RL78_DIFF;
99c513f6
DD
1282 }
1283
1284#define OPX(REL,SYM,ADD) \
add39d23
TS
1285 reloc[rp] = XNEW (arelent); \
1286 reloc[rp]->sym_ptr_ptr = XNEW (asymbol *); \
99c513f6
DD
1287 reloc[rp]->howto = bfd_reloc_type_lookup (stdoutput, REL); \
1288 reloc[rp]->addend = ADD; \
1289 * reloc[rp]->sym_ptr_ptr = SYM; \
1290 reloc[rp]->address = fixp->fx_frag->fr_address + fixp->fx_where; \
1291 reloc[++rp] = NULL
1292#define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
aff1a65e
NC
1293
1294 /* FIXME: We cannot do the normal thing for an immediate value reloc,
1295 ie creating a RL78_SYM reloc in the *ABS* section with an offset
1296 equal to the immediate value we want to store. This fails because
1297 the reloc processing in bfd_perform_relocation and bfd_install_relocation
1298 will short circuit such relocs and never pass them on to the special
1299 reloc processing code. So instead we create a RL78_SYM reloc against
1300 the __rl78_abs__ symbol and arrange for the linker scripts to place
1301 this symbol at address 0. */
1302#define OPIMM(IMM) OPX (BFD_RELOC_RL78_SYM, symbol_get_bfdsym (rl78_abs_sym), IMM)
3739860c 1303
99c513f6
DD
1304#define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
1305#define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
1306
1307 rp = 1;
1308
1309 /* Certain BFD relocations cannot be translated directly into
1310 a single (non-Red Hat) RL78 relocation, but instead need
1311 multiple RL78 relocations - handle them here. */
1312 switch (fixp->fx_r_type)
1313 {
1314 case BFD_RELOC_RL78_DIFF:
1315 SYM0 ();
1316 OPSYM (symbol_get_bfdsym (fixp->fx_subsy));
1317 OP(OP_SUBTRACT);
1318
1319 switch (fixp->fx_size)
1320 {
1321 case 1:
1322 OP(ABS8);
1323 break;
1324 case 2:
1325 OP (ABS16);
1326 break;
1327 case 4:
1328 OP (ABS32);
1329 break;
1330 }
1331 break;
1332
1333 case BFD_RELOC_RL78_NEG32:
1334 SYM0 ();
1335 OP (OP_NEG);
1336 OP (ABS32);
1337 break;
1338
4107ae22 1339 case BFD_RELOC_RL78_CODE:
b3fe4307
NC
1340 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_16U);
1341 reloc[1] = NULL;
4107ae22
DD
1342 break;
1343
99c513f6
DD
1344 case BFD_RELOC_RL78_LO16:
1345 SYM0 ();
1346 OPIMM (0xffff);
1347 OP (OP_AND);
1348 OP (ABS16);
1349 break;
1350
1351 case BFD_RELOC_RL78_HI16:
1352 SYM0 ();
1353 OPIMM (16);
1354 OP (OP_SHRA);
1355 OP (ABS16);
1356 break;
1357
1358 case BFD_RELOC_RL78_HI8:
1359 SYM0 ();
1360 OPIMM (16);
1361 OP (OP_SHRA);
1362 OPIMM (0xff);
1363 OP (OP_AND);
1364 OP (ABS8);
1365 break;
1366
1367 default:
1368 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1369 reloc[1] = NULL;
1370 break;
1371 }
1372
1373 return reloc;
1374}
1375
1376int
1377rl78_validate_fix_sub (struct fix * f)
1378{
1379 /* We permit the subtraction of two symbols in a few cases. */
1380 /* mov #sym1-sym2, R3 */
1381 if (f->fx_r_type == BFD_RELOC_RL78_32_OP)
1382 return 1;
1383 /* .long sym1-sym2 */
1384 if (f->fx_r_type == BFD_RELOC_RL78_DIFF
1385 && ! f->fx_pcrel
1386 && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
1387 return 1;
1388 return 0;
1389}
1390
1391long
1392md_pcrel_from_section (fixS * fixP, segT sec)
1393{
1394 long rv;
1395
1396 if (fixP->fx_addsy != NULL
1397 && (! S_IS_DEFINED (fixP->fx_addsy)
1398 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
1399 /* The symbol is undefined (or is defined but not in this section).
1400 Let the linker figure it out. */
1401 return 0;
1402
1403 rv = fixP->fx_frag->fr_address + fixP->fx_where;
1404 switch (fixP->fx_r_type)
1405 {
1406 case BFD_RELOC_8_PCREL:
1407 rv += 1;
1408 break;
1409 case BFD_RELOC_16_PCREL:
1410 rv += 2;
1411 break;
1412 default:
1413 break;
1414 }
1415 return rv;
1416}
1417
1418void
1419md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
1420 valueT * t ATTRIBUTE_UNUSED,
1421 segT s ATTRIBUTE_UNUSED)
1422{
1423 char * op;
1424 unsigned long val;
1425
e896287c
DD
1426 /* We always defer overflow checks for these to the linker, as it
1427 needs to do PLT stuff. */
1428 if (f->fx_r_type == BFD_RELOC_RL78_CODE)
1429 f->fx_no_overflow = 1;
1430
99c513f6
DD
1431 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
1432 return;
1433 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
1434 return;
1435
1436 op = f->fx_frag->fr_literal + f->fx_where;
1437 val = (unsigned long) * t;
1438
e896287c
DD
1439 if (f->fx_addsy == NULL)
1440 f->fx_done = 1;
1441
99c513f6
DD
1442 switch (f->fx_r_type)
1443 {
1444 case BFD_RELOC_NONE:
1445 break;
1446
9cea966c 1447 case BFD_RELOC_RL78_RELAX:
e896287c 1448 f->fx_done = 0;
9cea966c
DD
1449 break;
1450
99c513f6 1451 case BFD_RELOC_8_PCREL:
0a899fd5
DD
1452 if ((long)val < -128 || (long)val > 127)
1453 as_bad_where (f->fx_file, f->fx_line,
1454 _("value of %ld too large for 8-bit branch"),
1455 val);
1456 /* Fall through. */
1457 case BFD_RELOC_8:
54f66250 1458 case BFD_RELOC_RL78_SADDR: /* We need to store the 8 LSB, but this works. */
99c513f6
DD
1459 op[0] = val;
1460 break;
1461
99c513f6 1462 case BFD_RELOC_16_PCREL:
0a899fd5
DD
1463 if ((long)val < -32768 || (long)val > 32767)
1464 as_bad_where (f->fx_file, f->fx_line,
1465 _("value of %ld too large for 16-bit branch"),
1466 val);
1467 /* Fall through. */
1468 case BFD_RELOC_16:
4107ae22 1469 case BFD_RELOC_RL78_CODE:
99c513f6
DD
1470 op[0] = val;
1471 op[1] = val >> 8;
1472 break;
1473
1474 case BFD_RELOC_24:
1475 op[0] = val;
1476 op[1] = val >> 8;
1477 op[2] = val >> 16;
1478 break;
1479
1480 case BFD_RELOC_32:
99c513f6
DD
1481 op[0] = val;
1482 op[1] = val >> 8;
1483 op[2] = val >> 16;
1484 op[3] = val >> 24;
1485 break;
1486
3ce3a066
NC
1487 case BFD_RELOC_RL78_DIFF:
1488 op[0] = val;
1489 if (f->fx_size > 1)
1490 op[1] = val >> 8;
1491 if (f->fx_size > 2)
1492 op[2] = val >> 16;
1493 if (f->fx_size > 3)
1494 op[3] = val >> 24;
1495 break;
1496
b3fe4307
NC
1497 case BFD_RELOC_RL78_HI8:
1498 val = val >> 16;
1499 op[0] = val;
1500 break;
1501
1502 case BFD_RELOC_RL78_HI16:
1503 val = val >> 16;
1504 op[0] = val;
1505 op[1] = val >> 8;
1506 break;
1507
1508 case BFD_RELOC_RL78_LO16:
1509 op[0] = val;
1510 op[1] = val >> 8;
1511 break;
1512
99c513f6
DD
1513 default:
1514 as_bad (_("Unknown reloc in md_apply_fix: %s"),
1515 bfd_get_reloc_code_name (f->fx_r_type));
1516 break;
1517 }
1518
99c513f6
DD
1519}
1520
1521valueT
1522md_section_align (segT segment, valueT size)
1523{
1524 int align = bfd_get_section_alignment (stdoutput, segment);
8d3842cd 1525 return ((size + (1 << align) - 1) & -(1 << align));
99c513f6 1526}
This page took 0.387547 seconds and 4 git commands to generate.