1 /* tc-rl78.c -- Assembler for the Renesas RL78
2 Copyright 2011-2013 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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)
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.
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
22 #include "struc-symbol.h"
24 #include "safe-ctype.h"
25 #include "dwarf2dbg.h"
27 #include "elf/common.h"
29 #include "rl78-defs.h"
30 #include "filenames.h"
35 const 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. */
39 const char line_comment_chars[] = "#";
40 /* Use something that isn't going to be needed by any expressions or
42 const char line_separator_chars[] = "@";
44 const char EXP_CHARS[] = "eE";
45 const char FLT_CHARS[] = "dD";
47 /* ELF flags to set in the output file header. */
48 static int elf_flags = 0;
50 /*------------------------------------------------------------------*/
52 char * rl78_lex_start;
55 typedef struct rl78_bytesT
68 char type; /* RL78REL_*. */
81 fixS *link_relax_fixP;
86 static rl78_bytesT rl78_bytes;
89 rl78_linkrelax_addr16 (void)
91 rl78_bytes.link_relax |= RL78_RELAXA_ADDR16;
95 rl78_linkrelax_branch (void)
97 rl78_bytes.link_relax |= RL78_RELAXA_BRA;
101 rl78_fixup (expressionS exp, int offsetbits, int nbits, int type)
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 ++;
111 #define rl78_field_fixup(exp, offset, nbits, type) \
112 rl78_fixup (exp, offset + 8 * rl78_bytes.n_prefix), nbits, type)
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)
120 rl78_bytes.prefix[0] = p;
121 rl78_bytes.n_prefix = 1;
127 return rl78_bytes.n_prefix;
133 rl78_bytes.base[0] = b1;
134 rl78_bytes.n_base = 1;
138 rl78_base2 (int b1, int b2)
140 rl78_bytes.base[0] = b1;
141 rl78_bytes.base[1] = b2;
142 rl78_bytes.n_base = 2;
146 rl78_base3 (int b1, int b2, int b3)
148 rl78_bytes.base[0] = b1;
149 rl78_bytes.base[1] = b2;
150 rl78_bytes.base[2] = b3;
151 rl78_bytes.n_base = 3;
155 rl78_base4 (int b1, int b2, int b3, int b4)
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;
164 #define F_PRECISION 2
167 rl78_op (expressionS exp, int nbytes, int type)
171 if ((exp.X_op == O_constant || exp.X_op == O_big)
172 && type != RL78REL_PCREL)
174 if (exp.X_op == O_big && exp.X_add_number <= 0)
177 char * ip = rl78_bytes.ops + rl78_bytes.n_ops;
179 gen_to_words (w, F_PRECISION, 8);
184 rl78_bytes.n_ops += 4;
188 v = exp.X_add_number;
191 rl78_bytes.ops[rl78_bytes.n_ops++] =v & 0xff;
200 && exp.X_md == BFD_RELOC_RL78_CODE)
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;
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:
214 - - - - - - - - - - - - - - - -
218 rl78_field (int val, int pos, int sz)
225 if (val < 0 || val >= (1 << sz))
226 as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, 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);
235 /* This code points at 'M' in the above example. */
239 while (bitp + sz > 8)
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;
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;
260 /*------------------------------------------------------------------*/
264 OPTION_RELAX = OPTION_MD_BASE,
268 #define RL78_SHORTOPTS ""
269 const char * md_shortopts = RL78_SHORTOPTS;
271 /* Assembler options. */
272 struct option md_longopts[] =
274 {"relax", no_argument, NULL, OPTION_RELAX},
275 {"mg10", no_argument, NULL, OPTION_G10},
276 {NULL, no_argument, NULL, 0}
278 size_t md_longopts_size = sizeof (md_longopts);
281 md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
290 elf_flags |= E_FLAG_RL78_G10;
297 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
303 s_bss (int ignore ATTRIBUTE_UNUSED)
307 temp = get_absolute_expression ();
308 subseg_set (bss_section, (subsegT) temp);
309 demand_empty_rest_of_line ();
312 /* The target specific pseudo-ops which we support. */
313 const pseudo_typeS md_pseudo_table[] =
315 /* Our "standard" pseudos. */
316 { "double", float_cons, 'd' },
318 { "3byte", cons, 3 },
322 /* End of list marker. */
336 /* Set the ELF specific flags. */
338 rl78_elf_final_processing (void)
340 elf_elfheader (stdoutput)->e_flags |= elf_flags;
343 /* Write a value out to the object file, using the appropriate endianness. */
345 md_number_to_chars (char * buf, valueT val, int n)
347 number_to_chars_littleendian (buf, val, n);
351 require_end_of_expr (char *fname)
353 while (* input_line_pointer == ' '
354 || * input_line_pointer == '\t')
355 input_line_pointer ++;
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))
364 as_bad (_("%%%s() must be outermost term in expression"), fname);
374 { "code", BFD_RELOC_RL78_CODE },
375 { "lo16", BFD_RELOC_RL78_LO16 },
376 { "hi16", BFD_RELOC_RL78_HI16 },
377 { "hi8", BFD_RELOC_RL78_HI8 },
382 md_operand (expressionS * exp ATTRIBUTE_UNUSED)
387 for (i = 0; reloc_functions[i].fname; i++)
389 int flen = strlen (reloc_functions[i].fname);
391 if (input_line_pointer[0] == '%'
392 && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
393 && input_line_pointer[flen + 1] == '(')
395 reloc = reloc_functions[i].reloc;
396 input_line_pointer += flen + 2;
404 if (* input_line_pointer == ')')
405 input_line_pointer ++;
409 require_end_of_expr (reloc_functions[i].fname);
413 rl78_frag_init (fragS * fragP)
415 if (rl78_bytes.n_relax || rl78_bytes.link_relax)
417 fragP->tc_frag_data = malloc (sizeof (rl78_bytesT));
418 memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT));
421 fragP->tc_frag_data = 0;
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. */
427 rl78_handle_align (fragS * frag)
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)
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
442 fix_new (frag->fr_next, 0, 0,
443 &abs_symbol, RL78_RELAXA_ELIGN + frag->fr_offset,
444 0, BFD_RELOC_RL78_RELAX);
449 md_atof (int type, char * litP, int * sizeP)
451 return ieee_md_atof (type, litP, sizeP, target_big_endian);
455 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
460 #define APPEND(B, N_B) \
461 if (rl78_bytes.N_B) \
463 memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B); \
464 idx += rl78_bytes.N_B; \
469 md_assemble (char * str)
472 fragS * frag_then = frag_now;
478 /*printf("\033[32mASM: %s\033[0m\n", str);*/
480 dwarf2_emit_insn (0);
482 memset (& rl78_bytes, 0, sizeof (rl78_bytes));
484 rl78_lex_init (str, str + strlen (str));
488 /* This simplifies the relaxation code. */
489 if (rl78_bytes.link_relax)
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 */,
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;
510 bytes = frag_more (rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops);
511 frag_then = frag_now;
514 APPEND (prefix, n_prefix);
515 APPEND (base, n_base);
518 if (rl78_bytes.link_relax)
522 f = fix_new (frag_then,
523 (char *) bytes - frag_then->fr_literal,
526 rl78_bytes.link_relax | rl78_bytes.n_fixups,
528 BFD_RELOC_RL78_RELAX);
529 frag_then->tc_frag_data->link_relax_fixP = f;
532 for (i = 0; i < rl78_bytes.n_fixups; i ++)
534 /* index: [nbytes][type] */
535 static int reloc_map[5][4] =
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 },
545 idx = rl78_bytes.fixups[i].offset / 8;
546 rel = reloc_map [rl78_bytes.fixups[i].nbits / 8][(int) rl78_bytes.fixups[i].type];
548 if (rl78_bytes.fixups[i].reloc)
549 rel = rl78_bytes.fixups[i].reloc;
551 if (frag_then->tc_frag_data)
552 exp = & frag_then->tc_frag_data->fixups[i].exp;
554 exp = & rl78_bytes.fixups[i].exp;
556 f = fix_new_exp (frag_then,
557 (char *) bytes + idx - frag_then->fr_literal,
558 rl78_bytes.fixups[i].nbits / 8,
560 rl78_bytes.fixups[i].type == RL78REL_PCREL ? 1 : 0,
562 if (frag_then->tc_frag_data)
563 frag_then->tc_frag_data->fixups[i].fixP = f;
568 rl78_cons_fix_new (fragS * frag,
573 bfd_reloc_code_real_type type;
591 as_bad (_("unsupported constant size %d\n"), size);
597 case BFD_RELOC_RL78_CODE:
601 case BFD_RELOC_RL78_LO16:
602 case BFD_RELOC_RL78_HI16:
604 as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
607 case BFD_RELOC_RL78_HI8:
609 as_bad (_("%%hi8 only applies to .byte"));
616 if (exp->X_op == O_subtract && exp->X_op_symbol)
618 if (size != 4 && size != 2 && size != 1)
619 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
621 type = BFD_RELOC_RL78_DIFF;
624 fixP = fix_new_exp (frag, where, (int) size, exp, 0, type);
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;
641 /* No relaxation just yet */
643 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
649 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
651 static arelent * reloc[8];
654 if (fixp->fx_r_type == BFD_RELOC_NONE)
661 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
663 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
664 fixp->fx_subsy = NULL;
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;
673 if (fixp->fx_r_type == BFD_RELOC_RL78_32_OP
676 fixp->fx_r_type = BFD_RELOC_RL78_DIFF;
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; \
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)
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)
699 case BFD_RELOC_RL78_DIFF:
701 OPSYM (symbol_get_bfdsym (fixp->fx_subsy));
704 switch (fixp->fx_size)
718 case BFD_RELOC_RL78_NEG32:
724 case BFD_RELOC_RL78_CODE:
729 case BFD_RELOC_RL78_LO16:
736 case BFD_RELOC_RL78_HI16:
743 case BFD_RELOC_RL78_HI8:
753 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
762 rl78_validate_fix_sub (struct fix * f)
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)
768 /* .long sym1-sym2 */
769 if (f->fx_r_type == BFD_RELOC_RL78_DIFF
771 && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
777 md_pcrel_from_section (fixS * fixP, segT sec)
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. */
788 rv = fixP->fx_frag->fr_address + fixP->fx_where;
789 switch (fixP->fx_r_type)
791 case BFD_RELOC_8_PCREL:
794 case BFD_RELOC_16_PCREL:
804 md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
805 valueT * t ATTRIBUTE_UNUSED,
806 segT s ATTRIBUTE_UNUSED)
811 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
813 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
816 op = f->fx_frag->fr_literal + f->fx_where;
817 val = (unsigned long) * t;
819 switch (f->fx_r_type)
824 case BFD_RELOC_RL78_RELAX:
829 case BFD_RELOC_8_PCREL:
834 case BFD_RELOC_16_PCREL:
835 case BFD_RELOC_RL78_CODE:
847 case BFD_RELOC_RL78_DIFF:
855 as_bad (_("Unknown reloc in md_apply_fix: %s"),
856 bfd_get_reloc_code_name (f->fx_r_type));
860 if (f->fx_addsy == NULL)
865 md_section_align (segT segment, valueT size)
867 int align = bfd_get_section_alignment (stdoutput, segment);
868 return ((size + (1 << align) - 1) & (-1 << align));
872 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
873 segT segment ATTRIBUTE_UNUSED,
874 fragS * fragP ATTRIBUTE_UNUSED)
876 /* No relaxation yet */