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