Avoid using the ISO C99 `z' formatted output modifier
[deliverable/binutils-gdb.git] / gas / config / tc-rl78.c
CommitLineData
99c513f6 1/* tc-rl78.c -- Assembler for the Renesas RL78
4b95cf5c 2 Copyright (C) 2011-2014 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"
23#include "obstack.h"
24#include "safe-ctype.h"
25#include "dwarf2dbg.h"
26#include "libbfd.h"
27#include "elf/common.h"
28#include "elf/rl78.h"
29#include "rl78-defs.h"
30#include "filenames.h"
31#include "listing.h"
32#include "sb.h"
33#include "macro.h"
34
35const char comment_chars[] = ";";
36/* Note that input_file.c hand checks for '#' at the beginning of the
37 first line of the input file. This is because the compiler outputs
38 #NO_APP at the beginning of its output. */
39const char line_comment_chars[] = "#";
cbf1fdc9
DD
40/* Use something that isn't going to be needed by any expressions or
41 other syntax. */
42const char line_separator_chars[] = "@";
99c513f6
DD
43
44const char EXP_CHARS[] = "eE";
45const char FLT_CHARS[] = "dD";
46
4046d87a
NC
47/* ELF flags to set in the output file header. */
48static int elf_flags = 0;
49
99c513f6
DD
50/*------------------------------------------------------------------*/
51
52char * rl78_lex_start;
53char * rl78_lex_end;
54
55typedef struct rl78_bytesT
56{
57 char prefix[1];
58 int n_prefix;
59 char base[4];
60 int n_base;
61 char ops[8];
62 int n_ops;
63 struct
64 {
65 expressionS exp;
66 char offset;
67 char nbits;
68 char type; /* RL78REL_*. */
69 int reloc;
70 fixS * fixP;
71 } fixups[2];
72 int n_fixups;
73 struct
74 {
75 char type;
76 char field_pos;
77 char val_ofs;
78 } relax[2];
79 int n_relax;
80 int link_relax;
81 fixS *link_relax_fixP;
82 char times_grown;
83 char times_shrank;
84} rl78_bytesT;
85
86static rl78_bytesT rl78_bytes;
87
9cea966c
DD
88void
89rl78_linkrelax_addr16 (void)
90{
91 rl78_bytes.link_relax |= RL78_RELAXA_ADDR16;
92}
93
94void
95rl78_linkrelax_branch (void)
96{
97 rl78_bytes.link_relax |= RL78_RELAXA_BRA;
98}
99
99c513f6
DD
100static void
101rl78_fixup (expressionS exp, int offsetbits, int nbits, int type)
102{
103 rl78_bytes.fixups[rl78_bytes.n_fixups].exp = exp;
104 rl78_bytes.fixups[rl78_bytes.n_fixups].offset = offsetbits;
105 rl78_bytes.fixups[rl78_bytes.n_fixups].nbits = nbits;
106 rl78_bytes.fixups[rl78_bytes.n_fixups].type = type;
107 rl78_bytes.fixups[rl78_bytes.n_fixups].reloc = exp.X_md;
108 rl78_bytes.n_fixups ++;
109}
110
111#define rl78_field_fixup(exp, offset, nbits, type) \
112 rl78_fixup (exp, offset + 8 * rl78_bytes.n_prefix), nbits, type)
113
114#define rl78_op_fixup(exp, offset, nbits, type) \
115 rl78_fixup (exp, offset + 8 * (rl78_bytes.n_prefix + rl78_bytes.n_base), nbits, type)
116
117void
118rl78_prefix (int p)
119{
120 rl78_bytes.prefix[0] = p;
121 rl78_bytes.n_prefix = 1;
122}
123
124int
125rl78_has_prefix ()
126{
127 return rl78_bytes.n_prefix;
128}
129
130void
131rl78_base1 (int b1)
132{
133 rl78_bytes.base[0] = b1;
134 rl78_bytes.n_base = 1;
135}
136
137void
138rl78_base2 (int b1, int b2)
139{
140 rl78_bytes.base[0] = b1;
141 rl78_bytes.base[1] = b2;
142 rl78_bytes.n_base = 2;
143}
144
145void
146rl78_base3 (int b1, int b2, int b3)
147{
148 rl78_bytes.base[0] = b1;
149 rl78_bytes.base[1] = b2;
150 rl78_bytes.base[2] = b3;
151 rl78_bytes.n_base = 3;
152}
153
154void
155rl78_base4 (int b1, int b2, int b3, int b4)
156{
157 rl78_bytes.base[0] = b1;
158 rl78_bytes.base[1] = b2;
159 rl78_bytes.base[2] = b3;
160 rl78_bytes.base[3] = b4;
161 rl78_bytes.n_base = 4;
162}
163
164#define F_PRECISION 2
165
166void
167rl78_op (expressionS exp, int nbytes, int type)
168{
169 int v = 0;
170
171 if ((exp.X_op == O_constant || exp.X_op == O_big)
172 && type != RL78REL_PCREL)
173 {
174 if (exp.X_op == O_big && exp.X_add_number <= 0)
175 {
176 LITTLENUM_TYPE w[2];
177 char * ip = rl78_bytes.ops + rl78_bytes.n_ops;
178
179 gen_to_words (w, F_PRECISION, 8);
180 ip[3] = w[0] >> 8;
181 ip[2] = w[0];
182 ip[1] = w[1] >> 8;
183 ip[0] = w[1];
184 rl78_bytes.n_ops += 4;
185 }
186 else
187 {
188 v = exp.X_add_number;
189 while (nbytes)
190 {
191 rl78_bytes.ops[rl78_bytes.n_ops++] =v & 0xff;
192 v >>= 8;
193 nbytes --;
194 }
195 }
196 }
197 else
198 {
4107ae22
DD
199 if (nbytes > 2
200 && exp.X_md == BFD_RELOC_RL78_CODE)
201 exp.X_md = 0;
99c513f6
DD
202 rl78_op_fixup (exp, rl78_bytes.n_ops * 8, nbytes * 8, type);
203 memset (rl78_bytes.ops + rl78_bytes.n_ops, 0, nbytes);
204 rl78_bytes.n_ops += nbytes;
205 }
206}
207
208/* This gets complicated when the field spans bytes, because fields
209 are numbered from the MSB of the first byte as zero, and bits are
210 stored LSB towards the LSB of the byte. Thus, a simple four-bit
211 insertion of 12 at position 4 of 0x00 yields: 0x0b. A three-bit
212 insertion of b'MXL at position 7 is like this:
213
214 - - - - - - - - - - - - - - - -
215 M X L */
216
217void
218rl78_field (int val, int pos, int sz)
219{
220 int valm;
221 int bytep, bitp;
222
223 if (sz > 0)
224 {
225 if (val < 0 || val >= (1 << sz))
226 as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz);
227 }
228 else
229 {
230 sz = - sz;
231 if (val < -(1 << (sz - 1)) || val >= (1 << (sz - 1)))
232 as_bad (_("Value %d doesn't fit in signed %d-bit field"), val, sz);
233 }
234
235 /* This code points at 'M' in the above example. */
236 bytep = pos / 8;
237 bitp = pos % 8;
238
239 while (bitp + sz > 8)
240 {
241 int ssz = 8 - bitp;
242 int svalm;
243
244 svalm = val >> (sz - ssz);
245 svalm = svalm & ((1 << ssz) - 1);
246 svalm = svalm << (8 - bitp - ssz);
247 gas_assert (bytep < rl78_bytes.n_base);
248 rl78_bytes.base[bytep] |= svalm;
249
250 bitp = 0;
251 sz -= ssz;
252 bytep ++;
253 }
254 valm = val & ((1 << sz) - 1);
255 valm = valm << (8 - bitp - sz);
256 gas_assert (bytep < rl78_bytes.n_base);
257 rl78_bytes.base[bytep] |= valm;
258}
259
260/*------------------------------------------------------------------*/
261
9cea966c
DD
262enum options
263{
264 OPTION_RELAX = OPTION_MD_BASE,
4046d87a 265 OPTION_G10,
9cea966c
DD
266};
267
99c513f6
DD
268#define RL78_SHORTOPTS ""
269const char * md_shortopts = RL78_SHORTOPTS;
270
271/* Assembler options. */
272struct option md_longopts[] =
273{
9cea966c 274 {"relax", no_argument, NULL, OPTION_RELAX},
4046d87a 275 {"mg10", no_argument, NULL, OPTION_G10},
99c513f6
DD
276 {NULL, no_argument, NULL, 0}
277};
278size_t md_longopts_size = sizeof (md_longopts);
279
280int
9cea966c 281md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
99c513f6 282{
9cea966c
DD
283 switch (c)
284 {
285 case OPTION_RELAX:
286 linkrelax = 1;
287 return 1;
288
4046d87a
NC
289 case OPTION_G10:
290 elf_flags |= E_FLAG_RL78_G10;
291 return 1;
9cea966c 292 }
99c513f6
DD
293 return 0;
294}
295
296void
297md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
298{
299}
300
301
302static void
303s_bss (int ignore ATTRIBUTE_UNUSED)
304{
305 int temp;
306
307 temp = get_absolute_expression ();
308 subseg_set (bss_section, (subsegT) temp);
309 demand_empty_rest_of_line ();
310}
311
312/* The target specific pseudo-ops which we support. */
313const pseudo_typeS md_pseudo_table[] =
314{
315 /* Our "standard" pseudos. */
316 { "double", float_cons, 'd' },
317 { "bss", s_bss, 0 },
318 { "3byte", cons, 3 },
319 { "int", cons, 4 },
320 { "word", cons, 4 },
321
322 /* End of list marker. */
323 { NULL, NULL, 0 }
324};
325
326void
327md_begin (void)
328{
329}
330
331void
332rl78_md_end (void)
333{
334}
335
4046d87a
NC
336/* Set the ELF specific flags. */
337void
338rl78_elf_final_processing (void)
339{
340 elf_elfheader (stdoutput)->e_flags |= elf_flags;
341}
342
99c513f6
DD
343/* Write a value out to the object file, using the appropriate endianness. */
344void
345md_number_to_chars (char * buf, valueT val, int n)
346{
347 number_to_chars_littleendian (buf, val, n);
348}
349
c9d66558
DD
350static void
351require_end_of_expr (char *fname)
352{
353 while (* input_line_pointer == ' '
354 || * input_line_pointer == '\t')
355 input_line_pointer ++;
356
357 if (! * input_line_pointer
358 || strchr ("\n\r,", * input_line_pointer)
359 || strchr (comment_chars, * input_line_pointer)
360 || strchr (line_comment_chars, * input_line_pointer)
361 || strchr (line_separator_chars, * input_line_pointer))
362 return;
363
364 as_bad (_("%%%s() must be outermost term in expression"), fname);
365}
366
99c513f6
DD
367static struct
368{
369 char * fname;
370 int reloc;
371}
372reloc_functions[] =
373{
4107ae22 374 { "code", BFD_RELOC_RL78_CODE },
99c513f6
DD
375 { "lo16", BFD_RELOC_RL78_LO16 },
376 { "hi16", BFD_RELOC_RL78_HI16 },
377 { "hi8", BFD_RELOC_RL78_HI8 },
378 { 0, 0 }
379};
380
381void
382md_operand (expressionS * exp ATTRIBUTE_UNUSED)
383{
384 int reloc = 0;
385 int i;
386
387 for (i = 0; reloc_functions[i].fname; i++)
388 {
389 int flen = strlen (reloc_functions[i].fname);
390
391 if (input_line_pointer[0] == '%'
392 && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
393 && input_line_pointer[flen + 1] == '(')
394 {
395 reloc = reloc_functions[i].reloc;
396 input_line_pointer += flen + 2;
397 break;
398 }
399 }
400 if (reloc == 0)
401 return;
402
403 expression (exp);
404 if (* input_line_pointer == ')')
405 input_line_pointer ++;
406
407 exp->X_md = reloc;
c9d66558
DD
408
409 require_end_of_expr (reloc_functions[i].fname);
99c513f6
DD
410}
411
412void
413rl78_frag_init (fragS * fragP)
414{
9cea966c
DD
415 if (rl78_bytes.n_relax || rl78_bytes.link_relax)
416 {
417 fragP->tc_frag_data = malloc (sizeof (rl78_bytesT));
418 memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT));
419 }
420 else
421 fragP->tc_frag_data = 0;
422}
423
424/* When relaxing, we need to output a reloc for any .align directive
425 so that we can retain this alignment as we adjust opcode sizes. */
426void
427rl78_handle_align (fragS * frag)
428{
429 if (linkrelax
430 && (frag->fr_type == rs_align
431 || frag->fr_type == rs_align_code)
432 && frag->fr_address + frag->fr_fix > 0
433 && frag->fr_offset > 0
434 && now_seg != bss_section)
435 {
436 fix_new (frag, frag->fr_fix, 0,
437 &abs_symbol, RL78_RELAXA_ALIGN + frag->fr_offset,
438 0, BFD_RELOC_RL78_RELAX);
439 /* For the purposes of relaxation, this relocation is attached
440 to the byte *after* the alignment - i.e. the byte that must
441 remain aligned. */
442 fix_new (frag->fr_next, 0, 0,
443 &abs_symbol, RL78_RELAXA_ELIGN + frag->fr_offset,
444 0, BFD_RELOC_RL78_RELAX);
445 }
99c513f6
DD
446}
447
448char *
449md_atof (int type, char * litP, int * sizeP)
450{
451 return ieee_md_atof (type, litP, sizeP, target_big_endian);
452}
453
454symbolS *
455md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
456{
457 return NULL;
458}
459
460#define APPEND(B, N_B) \
461 if (rl78_bytes.N_B) \
462 { \
463 memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B); \
464 idx += rl78_bytes.N_B; \
465 }
466
467
468void
469md_assemble (char * str)
470{
471 char * bytes;
472 fragS * frag_then = frag_now;
473 int idx = 0;
474 int i;
475 int rel;
476 expressionS *exp;
477
478 /*printf("\033[32mASM: %s\033[0m\n", str);*/
479
480 dwarf2_emit_insn (0);
481
482 memset (& rl78_bytes, 0, sizeof (rl78_bytes));
483
484 rl78_lex_init (str, str + strlen (str));
485
486 rl78_parse ();
487
9cea966c
DD
488 /* This simplifies the relaxation code. */
489 if (rl78_bytes.link_relax)
490 {
491 int olen = rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops;
492 /* We do it this way because we want the frag to have the
493 rl78_bytes in it, which we initialize above. */
494 bytes = frag_more (olen);
495 frag_then = frag_now;
496 frag_variant (rs_machine_dependent,
497 olen /* max_chars */,
498 0 /* var */,
499 olen /* subtype */,
500 0 /* symbol */,
501 0 /* offset */,
502 0 /* opcode */);
503 frag_then->fr_opcode = bytes;
504 frag_then->fr_fix = olen + (bytes - frag_then->fr_literal);
505 frag_then->fr_subtype = olen;
506 frag_then->fr_var = 0;
507 }
508 else
509 {
510 bytes = frag_more (rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops);
511 frag_then = frag_now;
512 }
99c513f6
DD
513
514 APPEND (prefix, n_prefix);
515 APPEND (base, n_base);
516 APPEND (ops, n_ops);
517
9cea966c
DD
518 if (rl78_bytes.link_relax)
519 {
520 fixS * f;
521
522 f = fix_new (frag_then,
523 (char *) bytes - frag_then->fr_literal,
524 0,
525 abs_section_sym,
526 rl78_bytes.link_relax | rl78_bytes.n_fixups,
527 0,
528 BFD_RELOC_RL78_RELAX);
529 frag_then->tc_frag_data->link_relax_fixP = f;
530 }
531
99c513f6
DD
532 for (i = 0; i < rl78_bytes.n_fixups; i ++)
533 {
534 /* index: [nbytes][type] */
535 static int reloc_map[5][4] =
536 {
537 { 0, 0 },
538 { BFD_RELOC_8, BFD_RELOC_8_PCREL },
539 { BFD_RELOC_16, BFD_RELOC_16_PCREL },
540 { BFD_RELOC_24, BFD_RELOC_24_PCREL },
541 { BFD_RELOC_32, BFD_RELOC_32_PCREL },
542 };
543 fixS * f;
544
545 idx = rl78_bytes.fixups[i].offset / 8;
546 rel = reloc_map [rl78_bytes.fixups[i].nbits / 8][(int) rl78_bytes.fixups[i].type];
547
548 if (rl78_bytes.fixups[i].reloc)
549 rel = rl78_bytes.fixups[i].reloc;
550
551 if (frag_then->tc_frag_data)
552 exp = & frag_then->tc_frag_data->fixups[i].exp;
553 else
554 exp = & rl78_bytes.fixups[i].exp;
555
556 f = fix_new_exp (frag_then,
557 (char *) bytes + idx - frag_then->fr_literal,
558 rl78_bytes.fixups[i].nbits / 8,
559 exp,
560 rl78_bytes.fixups[i].type == RL78REL_PCREL ? 1 : 0,
561 rel);
562 if (frag_then->tc_frag_data)
563 frag_then->tc_frag_data->fixups[i].fixP = f;
564 }
565}
566
567void
568rl78_cons_fix_new (fragS * frag,
569 int where,
570 int size,
571 expressionS * exp)
572{
573 bfd_reloc_code_real_type type;
c9d66558 574 fixS *fixP;
99c513f6
DD
575
576 switch (size)
577 {
578 case 1:
579 type = BFD_RELOC_8;
580 break;
581 case 2:
582 type = BFD_RELOC_16;
583 break;
584 case 3:
585 type = BFD_RELOC_24;
586 break;
587 case 4:
588 type = BFD_RELOC_32;
589 break;
590 default:
591 as_bad (_("unsupported constant size %d\n"), size);
592 return;
593 }
594
392ca752
DD
595 switch (exp->X_md)
596 {
4107ae22
DD
597 case BFD_RELOC_RL78_CODE:
598 if (size == 2)
599 type = exp->X_md;
600 break;
392ca752
DD
601 case BFD_RELOC_RL78_LO16:
602 case BFD_RELOC_RL78_HI16:
603 if (size != 2)
604 as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
605 type = exp->X_md;
606 break;
607 case BFD_RELOC_RL78_HI8:
608 if (size != 1)
609 as_bad (_("%%hi8 only applies to .byte"));
610 type = exp->X_md;
611 break;
612 default:
613 break;
614 }
615
99c513f6
DD
616 if (exp->X_op == O_subtract && exp->X_op_symbol)
617 {
618 if (size != 4 && size != 2 && size != 1)
619 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
620 else
621 type = BFD_RELOC_RL78_DIFF;
622 }
623
c9d66558
DD
624 fixP = fix_new_exp (frag, where, (int) size, exp, 0, type);
625 switch (exp->X_md)
626 {
627 /* These are intended to have values larger than the container,
628 since the backend puts only the portion we need in it.
629 However, we don't have a backend-specific reloc for them as
630 they're handled with complex relocations. */
631 case BFD_RELOC_RL78_LO16:
632 case BFD_RELOC_RL78_HI16:
633 case BFD_RELOC_RL78_HI8:
634 fixP->fx_no_overflow = 1;
635 break;
636 default:
637 break;
638 }
99c513f6
DD
639}
640
641/* No relaxation just yet */
642int
643md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
644{
645 return 0;
646}
9cea966c 647
99c513f6
DD
648arelent **
649tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
650{
651 static arelent * reloc[8];
652 int rp;
99c513f6
DD
653
654 if (fixp->fx_r_type == BFD_RELOC_NONE)
655 {
656 reloc[0] = NULL;
657 return reloc;
658 }
659
660 if (fixp->fx_subsy
661 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
662 {
663 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
664 fixp->fx_subsy = NULL;
665 }
666
667 reloc[0] = (arelent *) xmalloc (sizeof (arelent));
668 reloc[0]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
669 * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
670 reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
671 reloc[0]->addend = fixp->fx_offset;
672
673 if (fixp->fx_r_type == BFD_RELOC_RL78_32_OP
674 && fixp->fx_subsy)
675 {
676 fixp->fx_r_type = BFD_RELOC_RL78_DIFF;
99c513f6
DD
677 }
678
679#define OPX(REL,SYM,ADD) \
680 reloc[rp] = (arelent *) xmalloc (sizeof (arelent)); \
681 reloc[rp]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); \
682 reloc[rp]->howto = bfd_reloc_type_lookup (stdoutput, REL); \
683 reloc[rp]->addend = ADD; \
684 * reloc[rp]->sym_ptr_ptr = SYM; \
685 reloc[rp]->address = fixp->fx_frag->fr_address + fixp->fx_where; \
686 reloc[++rp] = NULL
687#define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
688#define OPIMM(IMM) OPX(BFD_RELOC_RL78_SYM, abs_symbol.bsym, IMM)
689#define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
690#define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
691
692 rp = 1;
693
694 /* Certain BFD relocations cannot be translated directly into
695 a single (non-Red Hat) RL78 relocation, but instead need
696 multiple RL78 relocations - handle them here. */
697 switch (fixp->fx_r_type)
698 {
699 case BFD_RELOC_RL78_DIFF:
700 SYM0 ();
701 OPSYM (symbol_get_bfdsym (fixp->fx_subsy));
702 OP(OP_SUBTRACT);
703
704 switch (fixp->fx_size)
705 {
706 case 1:
707 OP(ABS8);
708 break;
709 case 2:
710 OP (ABS16);
711 break;
712 case 4:
713 OP (ABS32);
714 break;
715 }
716 break;
717
718 case BFD_RELOC_RL78_NEG32:
719 SYM0 ();
720 OP (OP_NEG);
721 OP (ABS32);
722 break;
723
4107ae22
DD
724 case BFD_RELOC_RL78_CODE:
725 SYM0 ();
726 OP (ABS16);
727 break;
728
99c513f6
DD
729 case BFD_RELOC_RL78_LO16:
730 SYM0 ();
731 OPIMM (0xffff);
732 OP (OP_AND);
733 OP (ABS16);
734 break;
735
736 case BFD_RELOC_RL78_HI16:
737 SYM0 ();
738 OPIMM (16);
739 OP (OP_SHRA);
740 OP (ABS16);
741 break;
742
743 case BFD_RELOC_RL78_HI8:
744 SYM0 ();
745 OPIMM (16);
746 OP (OP_SHRA);
747 OPIMM (0xff);
748 OP (OP_AND);
749 OP (ABS8);
750 break;
751
752 default:
753 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
754 reloc[1] = NULL;
755 break;
756 }
757
758 return reloc;
759}
760
761int
762rl78_validate_fix_sub (struct fix * f)
763{
764 /* We permit the subtraction of two symbols in a few cases. */
765 /* mov #sym1-sym2, R3 */
766 if (f->fx_r_type == BFD_RELOC_RL78_32_OP)
767 return 1;
768 /* .long sym1-sym2 */
769 if (f->fx_r_type == BFD_RELOC_RL78_DIFF
770 && ! f->fx_pcrel
771 && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
772 return 1;
773 return 0;
774}
775
776long
777md_pcrel_from_section (fixS * fixP, segT sec)
778{
779 long rv;
780
781 if (fixP->fx_addsy != NULL
782 && (! S_IS_DEFINED (fixP->fx_addsy)
783 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
784 /* The symbol is undefined (or is defined but not in this section).
785 Let the linker figure it out. */
786 return 0;
787
788 rv = fixP->fx_frag->fr_address + fixP->fx_where;
789 switch (fixP->fx_r_type)
790 {
791 case BFD_RELOC_8_PCREL:
792 rv += 1;
793 break;
794 case BFD_RELOC_16_PCREL:
795 rv += 2;
796 break;
797 default:
798 break;
799 }
800 return rv;
801}
802
803void
804md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
805 valueT * t ATTRIBUTE_UNUSED,
806 segT s ATTRIBUTE_UNUSED)
807{
808 char * op;
809 unsigned long val;
810
811 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
812 return;
813 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
814 return;
815
816 op = f->fx_frag->fr_literal + f->fx_where;
817 val = (unsigned long) * t;
818
819 switch (f->fx_r_type)
820 {
821 case BFD_RELOC_NONE:
822 break;
823
9cea966c
DD
824 case BFD_RELOC_RL78_RELAX:
825 f->fx_done = 1;
826 break;
827
99c513f6
DD
828 case BFD_RELOC_8:
829 case BFD_RELOC_8_PCREL:
830 op[0] = val;
831 break;
832
833 case BFD_RELOC_16:
834 case BFD_RELOC_16_PCREL:
4107ae22 835 case BFD_RELOC_RL78_CODE:
99c513f6
DD
836 op[0] = val;
837 op[1] = val >> 8;
838 break;
839
840 case BFD_RELOC_24:
841 op[0] = val;
842 op[1] = val >> 8;
843 op[2] = val >> 16;
844 break;
845
846 case BFD_RELOC_32:
847 case BFD_RELOC_RL78_DIFF:
848 op[0] = val;
849 op[1] = val >> 8;
850 op[2] = val >> 16;
851 op[3] = val >> 24;
852 break;
853
854 default:
855 as_bad (_("Unknown reloc in md_apply_fix: %s"),
856 bfd_get_reloc_code_name (f->fx_r_type));
857 break;
858 }
859
860 if (f->fx_addsy == NULL)
861 f->fx_done = 1;
862}
863
864valueT
865md_section_align (segT segment, valueT size)
866{
867 int align = bfd_get_section_alignment (stdoutput, segment);
868 return ((size + (1 << align) - 1) & (-1 << align));
869}
870
871void
872md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
873 segT segment ATTRIBUTE_UNUSED,
874 fragS * fragP ATTRIBUTE_UNUSED)
875{
876 /* No relaxation yet */
9cea966c 877 fragP->fr_var = 0;
99c513f6 878}
This page took 0.191671 seconds and 4 git commands to generate.