gas: ARM: Fix encoding of VCVTr.s32.f64 instructions
[deliverable/binutils-gdb.git] / gas / config / tc-rl78.c
CommitLineData
99c513f6 1/* tc-rl78.c -- Assembler for the Renesas RL78
4046d87a 2 Copyright 2011-2013 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
350static struct
351{
352 char * fname;
353 int reloc;
354}
355reloc_functions[] =
356{
4107ae22 357 { "code", BFD_RELOC_RL78_CODE },
99c513f6
DD
358 { "lo16", BFD_RELOC_RL78_LO16 },
359 { "hi16", BFD_RELOC_RL78_HI16 },
360 { "hi8", BFD_RELOC_RL78_HI8 },
361 { 0, 0 }
362};
363
364void
365md_operand (expressionS * exp ATTRIBUTE_UNUSED)
366{
367 int reloc = 0;
368 int i;
369
370 for (i = 0; reloc_functions[i].fname; i++)
371 {
372 int flen = strlen (reloc_functions[i].fname);
373
374 if (input_line_pointer[0] == '%'
375 && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
376 && input_line_pointer[flen + 1] == '(')
377 {
378 reloc = reloc_functions[i].reloc;
379 input_line_pointer += flen + 2;
380 break;
381 }
382 }
383 if (reloc == 0)
384 return;
385
386 expression (exp);
387 if (* input_line_pointer == ')')
388 input_line_pointer ++;
389
390 exp->X_md = reloc;
391}
392
393void
394rl78_frag_init (fragS * fragP)
395{
9cea966c
DD
396 if (rl78_bytes.n_relax || rl78_bytes.link_relax)
397 {
398 fragP->tc_frag_data = malloc (sizeof (rl78_bytesT));
399 memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT));
400 }
401 else
402 fragP->tc_frag_data = 0;
403}
404
405/* When relaxing, we need to output a reloc for any .align directive
406 so that we can retain this alignment as we adjust opcode sizes. */
407void
408rl78_handle_align (fragS * frag)
409{
410 if (linkrelax
411 && (frag->fr_type == rs_align
412 || frag->fr_type == rs_align_code)
413 && frag->fr_address + frag->fr_fix > 0
414 && frag->fr_offset > 0
415 && now_seg != bss_section)
416 {
417 fix_new (frag, frag->fr_fix, 0,
418 &abs_symbol, RL78_RELAXA_ALIGN + frag->fr_offset,
419 0, BFD_RELOC_RL78_RELAX);
420 /* For the purposes of relaxation, this relocation is attached
421 to the byte *after* the alignment - i.e. the byte that must
422 remain aligned. */
423 fix_new (frag->fr_next, 0, 0,
424 &abs_symbol, RL78_RELAXA_ELIGN + frag->fr_offset,
425 0, BFD_RELOC_RL78_RELAX);
426 }
99c513f6
DD
427}
428
429char *
430md_atof (int type, char * litP, int * sizeP)
431{
432 return ieee_md_atof (type, litP, sizeP, target_big_endian);
433}
434
435symbolS *
436md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
437{
438 return NULL;
439}
440
441#define APPEND(B, N_B) \
442 if (rl78_bytes.N_B) \
443 { \
444 memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B); \
445 idx += rl78_bytes.N_B; \
446 }
447
448
449void
450md_assemble (char * str)
451{
452 char * bytes;
453 fragS * frag_then = frag_now;
454 int idx = 0;
455 int i;
456 int rel;
457 expressionS *exp;
458
459 /*printf("\033[32mASM: %s\033[0m\n", str);*/
460
461 dwarf2_emit_insn (0);
462
463 memset (& rl78_bytes, 0, sizeof (rl78_bytes));
464
465 rl78_lex_init (str, str + strlen (str));
466
467 rl78_parse ();
468
9cea966c
DD
469 /* This simplifies the relaxation code. */
470 if (rl78_bytes.link_relax)
471 {
472 int olen = rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops;
473 /* We do it this way because we want the frag to have the
474 rl78_bytes in it, which we initialize above. */
475 bytes = frag_more (olen);
476 frag_then = frag_now;
477 frag_variant (rs_machine_dependent,
478 olen /* max_chars */,
479 0 /* var */,
480 olen /* subtype */,
481 0 /* symbol */,
482 0 /* offset */,
483 0 /* opcode */);
484 frag_then->fr_opcode = bytes;
485 frag_then->fr_fix = olen + (bytes - frag_then->fr_literal);
486 frag_then->fr_subtype = olen;
487 frag_then->fr_var = 0;
488 }
489 else
490 {
491 bytes = frag_more (rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops);
492 frag_then = frag_now;
493 }
99c513f6
DD
494
495 APPEND (prefix, n_prefix);
496 APPEND (base, n_base);
497 APPEND (ops, n_ops);
498
9cea966c
DD
499 if (rl78_bytes.link_relax)
500 {
501 fixS * f;
502
503 f = fix_new (frag_then,
504 (char *) bytes - frag_then->fr_literal,
505 0,
506 abs_section_sym,
507 rl78_bytes.link_relax | rl78_bytes.n_fixups,
508 0,
509 BFD_RELOC_RL78_RELAX);
510 frag_then->tc_frag_data->link_relax_fixP = f;
511 }
512
99c513f6
DD
513 for (i = 0; i < rl78_bytes.n_fixups; i ++)
514 {
515 /* index: [nbytes][type] */
516 static int reloc_map[5][4] =
517 {
518 { 0, 0 },
519 { BFD_RELOC_8, BFD_RELOC_8_PCREL },
520 { BFD_RELOC_16, BFD_RELOC_16_PCREL },
521 { BFD_RELOC_24, BFD_RELOC_24_PCREL },
522 { BFD_RELOC_32, BFD_RELOC_32_PCREL },
523 };
524 fixS * f;
525
526 idx = rl78_bytes.fixups[i].offset / 8;
527 rel = reloc_map [rl78_bytes.fixups[i].nbits / 8][(int) rl78_bytes.fixups[i].type];
528
529 if (rl78_bytes.fixups[i].reloc)
530 rel = rl78_bytes.fixups[i].reloc;
531
532 if (frag_then->tc_frag_data)
533 exp = & frag_then->tc_frag_data->fixups[i].exp;
534 else
535 exp = & rl78_bytes.fixups[i].exp;
536
537 f = fix_new_exp (frag_then,
538 (char *) bytes + idx - frag_then->fr_literal,
539 rl78_bytes.fixups[i].nbits / 8,
540 exp,
541 rl78_bytes.fixups[i].type == RL78REL_PCREL ? 1 : 0,
542 rel);
543 if (frag_then->tc_frag_data)
544 frag_then->tc_frag_data->fixups[i].fixP = f;
545 }
546}
547
548void
549rl78_cons_fix_new (fragS * frag,
550 int where,
551 int size,
552 expressionS * exp)
553{
554 bfd_reloc_code_real_type type;
555
556 switch (size)
557 {
558 case 1:
559 type = BFD_RELOC_8;
560 break;
561 case 2:
562 type = BFD_RELOC_16;
563 break;
564 case 3:
565 type = BFD_RELOC_24;
566 break;
567 case 4:
568 type = BFD_RELOC_32;
569 break;
570 default:
571 as_bad (_("unsupported constant size %d\n"), size);
572 return;
573 }
574
392ca752
DD
575 switch (exp->X_md)
576 {
4107ae22
DD
577 case BFD_RELOC_RL78_CODE:
578 if (size == 2)
579 type = exp->X_md;
580 break;
392ca752
DD
581 case BFD_RELOC_RL78_LO16:
582 case BFD_RELOC_RL78_HI16:
583 if (size != 2)
584 as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
585 type = exp->X_md;
586 break;
587 case BFD_RELOC_RL78_HI8:
588 if (size != 1)
589 as_bad (_("%%hi8 only applies to .byte"));
590 type = exp->X_md;
591 break;
592 default:
593 break;
594 }
595
99c513f6
DD
596 if (exp->X_op == O_subtract && exp->X_op_symbol)
597 {
598 if (size != 4 && size != 2 && size != 1)
599 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
600 else
601 type = BFD_RELOC_RL78_DIFF;
602 }
603
604 fix_new_exp (frag, where, (int) size, exp, 0, type);
605}
606
607/* No relaxation just yet */
608int
609md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
610{
611 return 0;
612}
9cea966c 613
99c513f6
DD
614arelent **
615tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
616{
617 static arelent * reloc[8];
618 int rp;
99c513f6
DD
619
620 if (fixp->fx_r_type == BFD_RELOC_NONE)
621 {
622 reloc[0] = NULL;
623 return reloc;
624 }
625
626 if (fixp->fx_subsy
627 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
628 {
629 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
630 fixp->fx_subsy = NULL;
631 }
632
633 reloc[0] = (arelent *) xmalloc (sizeof (arelent));
634 reloc[0]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
635 * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
636 reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
637 reloc[0]->addend = fixp->fx_offset;
638
639 if (fixp->fx_r_type == BFD_RELOC_RL78_32_OP
640 && fixp->fx_subsy)
641 {
642 fixp->fx_r_type = BFD_RELOC_RL78_DIFF;
99c513f6
DD
643 }
644
645#define OPX(REL,SYM,ADD) \
646 reloc[rp] = (arelent *) xmalloc (sizeof (arelent)); \
647 reloc[rp]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); \
648 reloc[rp]->howto = bfd_reloc_type_lookup (stdoutput, REL); \
649 reloc[rp]->addend = ADD; \
650 * reloc[rp]->sym_ptr_ptr = SYM; \
651 reloc[rp]->address = fixp->fx_frag->fr_address + fixp->fx_where; \
652 reloc[++rp] = NULL
653#define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
654#define OPIMM(IMM) OPX(BFD_RELOC_RL78_SYM, abs_symbol.bsym, IMM)
655#define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
656#define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
657
658 rp = 1;
659
660 /* Certain BFD relocations cannot be translated directly into
661 a single (non-Red Hat) RL78 relocation, but instead need
662 multiple RL78 relocations - handle them here. */
663 switch (fixp->fx_r_type)
664 {
665 case BFD_RELOC_RL78_DIFF:
666 SYM0 ();
667 OPSYM (symbol_get_bfdsym (fixp->fx_subsy));
668 OP(OP_SUBTRACT);
669
670 switch (fixp->fx_size)
671 {
672 case 1:
673 OP(ABS8);
674 break;
675 case 2:
676 OP (ABS16);
677 break;
678 case 4:
679 OP (ABS32);
680 break;
681 }
682 break;
683
684 case BFD_RELOC_RL78_NEG32:
685 SYM0 ();
686 OP (OP_NEG);
687 OP (ABS32);
688 break;
689
4107ae22
DD
690 case BFD_RELOC_RL78_CODE:
691 SYM0 ();
692 OP (ABS16);
693 break;
694
99c513f6
DD
695 case BFD_RELOC_RL78_LO16:
696 SYM0 ();
697 OPIMM (0xffff);
698 OP (OP_AND);
699 OP (ABS16);
700 break;
701
702 case BFD_RELOC_RL78_HI16:
703 SYM0 ();
704 OPIMM (16);
705 OP (OP_SHRA);
706 OP (ABS16);
707 break;
708
709 case BFD_RELOC_RL78_HI8:
710 SYM0 ();
711 OPIMM (16);
712 OP (OP_SHRA);
713 OPIMM (0xff);
714 OP (OP_AND);
715 OP (ABS8);
716 break;
717
718 default:
719 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
720 reloc[1] = NULL;
721 break;
722 }
723
724 return reloc;
725}
726
727int
728rl78_validate_fix_sub (struct fix * f)
729{
730 /* We permit the subtraction of two symbols in a few cases. */
731 /* mov #sym1-sym2, R3 */
732 if (f->fx_r_type == BFD_RELOC_RL78_32_OP)
733 return 1;
734 /* .long sym1-sym2 */
735 if (f->fx_r_type == BFD_RELOC_RL78_DIFF
736 && ! f->fx_pcrel
737 && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
738 return 1;
739 return 0;
740}
741
742long
743md_pcrel_from_section (fixS * fixP, segT sec)
744{
745 long rv;
746
747 if (fixP->fx_addsy != NULL
748 && (! S_IS_DEFINED (fixP->fx_addsy)
749 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
750 /* The symbol is undefined (or is defined but not in this section).
751 Let the linker figure it out. */
752 return 0;
753
754 rv = fixP->fx_frag->fr_address + fixP->fx_where;
755 switch (fixP->fx_r_type)
756 {
757 case BFD_RELOC_8_PCREL:
758 rv += 1;
759 break;
760 case BFD_RELOC_16_PCREL:
761 rv += 2;
762 break;
763 default:
764 break;
765 }
766 return rv;
767}
768
769void
770md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
771 valueT * t ATTRIBUTE_UNUSED,
772 segT s ATTRIBUTE_UNUSED)
773{
774 char * op;
775 unsigned long val;
776
777 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
778 return;
779 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
780 return;
781
782 op = f->fx_frag->fr_literal + f->fx_where;
783 val = (unsigned long) * t;
784
785 switch (f->fx_r_type)
786 {
787 case BFD_RELOC_NONE:
788 break;
789
9cea966c
DD
790 case BFD_RELOC_RL78_RELAX:
791 f->fx_done = 1;
792 break;
793
99c513f6
DD
794 case BFD_RELOC_8:
795 case BFD_RELOC_8_PCREL:
796 op[0] = val;
797 break;
798
799 case BFD_RELOC_16:
800 case BFD_RELOC_16_PCREL:
4107ae22 801 case BFD_RELOC_RL78_CODE:
99c513f6
DD
802 op[0] = val;
803 op[1] = val >> 8;
804 break;
805
806 case BFD_RELOC_24:
807 op[0] = val;
808 op[1] = val >> 8;
809 op[2] = val >> 16;
810 break;
811
812 case BFD_RELOC_32:
813 case BFD_RELOC_RL78_DIFF:
814 op[0] = val;
815 op[1] = val >> 8;
816 op[2] = val >> 16;
817 op[3] = val >> 24;
818 break;
819
820 default:
821 as_bad (_("Unknown reloc in md_apply_fix: %s"),
822 bfd_get_reloc_code_name (f->fx_r_type));
823 break;
824 }
825
826 if (f->fx_addsy == NULL)
827 f->fx_done = 1;
828}
829
830valueT
831md_section_align (segT segment, valueT size)
832{
833 int align = bfd_get_section_alignment (stdoutput, segment);
834 return ((size + (1 << align) - 1) & (-1 << align));
835}
836
837void
838md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
839 segT segment ATTRIBUTE_UNUSED,
840 fragS * fragP ATTRIBUTE_UNUSED)
841{
842 /* No relaxation yet */
9cea966c 843 fragP->fr_var = 0;
99c513f6 844}
This page took 0.132682 seconds and 4 git commands to generate.