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