1 /* tc-rl78.c -- Assembler for the Renesas RL78
3 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23 #include "struc-symbol.h"
25 #include "safe-ctype.h"
26 #include "dwarf2dbg.h"
28 #include "elf/common.h"
30 #include "rl78-defs.h"
31 #include "filenames.h"
36 const char comment_chars[] = ";";
37 /* Note that input_file.c hand checks for '#' at the beginning of the
38 first line of the input file. This is because the compiler outputs
39 #NO_APP at the beginning of its output. */
40 const char line_comment_chars[] = "#";
41 /* Use something that isn't going to be needed by any expressions or
43 const char line_separator_chars[] = "@";
45 const char EXP_CHARS[] = "eE";
46 const char FLT_CHARS[] = "dD";
48 /*------------------------------------------------------------------*/
50 char * rl78_lex_start;
53 typedef struct rl78_bytesT
66 char type; /* RL78REL_*. */
79 fixS *link_relax_fixP;
84 static rl78_bytesT rl78_bytes;
87 rl78_linkrelax_addr16 (void)
89 rl78_bytes.link_relax |= RL78_RELAXA_ADDR16;
93 rl78_linkrelax_branch (void)
95 rl78_bytes.link_relax |= RL78_RELAXA_BRA;
99 rl78_fixup (expressionS exp, int offsetbits, int nbits, int type)
101 rl78_bytes.fixups[rl78_bytes.n_fixups].exp = exp;
102 rl78_bytes.fixups[rl78_bytes.n_fixups].offset = offsetbits;
103 rl78_bytes.fixups[rl78_bytes.n_fixups].nbits = nbits;
104 rl78_bytes.fixups[rl78_bytes.n_fixups].type = type;
105 rl78_bytes.fixups[rl78_bytes.n_fixups].reloc = exp.X_md;
106 rl78_bytes.n_fixups ++;
109 #define rl78_field_fixup(exp, offset, nbits, type) \
110 rl78_fixup (exp, offset + 8 * rl78_bytes.n_prefix), nbits, type)
112 #define rl78_op_fixup(exp, offset, nbits, type) \
113 rl78_fixup (exp, offset + 8 * (rl78_bytes.n_prefix + rl78_bytes.n_base), nbits, type)
118 rl78_bytes.prefix[0] = p;
119 rl78_bytes.n_prefix = 1;
125 return rl78_bytes.n_prefix;
131 rl78_bytes.base[0] = b1;
132 rl78_bytes.n_base = 1;
136 rl78_base2 (int b1, int b2)
138 rl78_bytes.base[0] = b1;
139 rl78_bytes.base[1] = b2;
140 rl78_bytes.n_base = 2;
144 rl78_base3 (int b1, int b2, int b3)
146 rl78_bytes.base[0] = b1;
147 rl78_bytes.base[1] = b2;
148 rl78_bytes.base[2] = b3;
149 rl78_bytes.n_base = 3;
153 rl78_base4 (int b1, int b2, int b3, int b4)
155 rl78_bytes.base[0] = b1;
156 rl78_bytes.base[1] = b2;
157 rl78_bytes.base[2] = b3;
158 rl78_bytes.base[3] = b4;
159 rl78_bytes.n_base = 4;
162 #define F_PRECISION 2
165 rl78_op (expressionS exp, int nbytes, int type)
169 if ((exp.X_op == O_constant || exp.X_op == O_big)
170 && type != RL78REL_PCREL)
172 if (exp.X_op == O_big && exp.X_add_number <= 0)
175 char * ip = rl78_bytes.ops + rl78_bytes.n_ops;
177 gen_to_words (w, F_PRECISION, 8);
182 rl78_bytes.n_ops += 4;
186 v = exp.X_add_number;
189 rl78_bytes.ops[rl78_bytes.n_ops++] =v & 0xff;
198 && exp.X_md == BFD_RELOC_RL78_CODE)
200 rl78_op_fixup (exp, rl78_bytes.n_ops * 8, nbytes * 8, type);
201 memset (rl78_bytes.ops + rl78_bytes.n_ops, 0, nbytes);
202 rl78_bytes.n_ops += nbytes;
206 /* This gets complicated when the field spans bytes, because fields
207 are numbered from the MSB of the first byte as zero, and bits are
208 stored LSB towards the LSB of the byte. Thus, a simple four-bit
209 insertion of 12 at position 4 of 0x00 yields: 0x0b. A three-bit
210 insertion of b'MXL at position 7 is like this:
212 - - - - - - - - - - - - - - - -
216 rl78_field (int val, int pos, int sz)
223 if (val < 0 || val >= (1 << sz))
224 as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz);
229 if (val < -(1 << (sz - 1)) || val >= (1 << (sz - 1)))
230 as_bad (_("Value %d doesn't fit in signed %d-bit field"), val, sz);
233 /* This code points at 'M' in the above example. */
237 while (bitp + sz > 8)
242 svalm = val >> (sz - ssz);
243 svalm = svalm & ((1 << ssz) - 1);
244 svalm = svalm << (8 - bitp - ssz);
245 gas_assert (bytep < rl78_bytes.n_base);
246 rl78_bytes.base[bytep] |= svalm;
252 valm = val & ((1 << sz) - 1);
253 valm = valm << (8 - bitp - sz);
254 gas_assert (bytep < rl78_bytes.n_base);
255 rl78_bytes.base[bytep] |= valm;
258 /*------------------------------------------------------------------*/
262 OPTION_RELAX = OPTION_MD_BASE,
265 #define RL78_SHORTOPTS ""
266 const char * md_shortopts = RL78_SHORTOPTS;
268 /* Assembler options. */
269 struct option md_longopts[] =
271 {"relax", no_argument, NULL, OPTION_RELAX},
272 {NULL, no_argument, NULL, 0}
274 size_t md_longopts_size = sizeof (md_longopts);
277 md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
290 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
296 s_bss (int ignore ATTRIBUTE_UNUSED)
300 temp = get_absolute_expression ();
301 subseg_set (bss_section, (subsegT) temp);
302 demand_empty_rest_of_line ();
305 /* The target specific pseudo-ops which we support. */
306 const pseudo_typeS md_pseudo_table[] =
308 /* Our "standard" pseudos. */
309 { "double", float_cons, 'd' },
311 { "3byte", cons, 3 },
315 /* End of list marker. */
329 /* Write a value out to the object file, using the appropriate endianness. */
331 md_number_to_chars (char * buf, valueT val, int n)
333 number_to_chars_littleendian (buf, val, n);
343 { "code", BFD_RELOC_RL78_CODE },
344 { "lo16", BFD_RELOC_RL78_LO16 },
345 { "hi16", BFD_RELOC_RL78_HI16 },
346 { "hi8", BFD_RELOC_RL78_HI8 },
351 md_operand (expressionS * exp ATTRIBUTE_UNUSED)
356 for (i = 0; reloc_functions[i].fname; i++)
358 int flen = strlen (reloc_functions[i].fname);
360 if (input_line_pointer[0] == '%'
361 && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
362 && input_line_pointer[flen + 1] == '(')
364 reloc = reloc_functions[i].reloc;
365 input_line_pointer += flen + 2;
373 if (* input_line_pointer == ')')
374 input_line_pointer ++;
380 rl78_frag_init (fragS * fragP)
382 if (rl78_bytes.n_relax || rl78_bytes.link_relax)
384 fragP->tc_frag_data = malloc (sizeof (rl78_bytesT));
385 memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT));
388 fragP->tc_frag_data = 0;
391 /* When relaxing, we need to output a reloc for any .align directive
392 so that we can retain this alignment as we adjust opcode sizes. */
394 rl78_handle_align (fragS * frag)
397 && (frag->fr_type == rs_align
398 || frag->fr_type == rs_align_code)
399 && frag->fr_address + frag->fr_fix > 0
400 && frag->fr_offset > 0
401 && now_seg != bss_section)
403 fix_new (frag, frag->fr_fix, 0,
404 &abs_symbol, RL78_RELAXA_ALIGN + frag->fr_offset,
405 0, BFD_RELOC_RL78_RELAX);
406 /* For the purposes of relaxation, this relocation is attached
407 to the byte *after* the alignment - i.e. the byte that must
409 fix_new (frag->fr_next, 0, 0,
410 &abs_symbol, RL78_RELAXA_ELIGN + frag->fr_offset,
411 0, BFD_RELOC_RL78_RELAX);
416 md_atof (int type, char * litP, int * sizeP)
418 return ieee_md_atof (type, litP, sizeP, target_big_endian);
422 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
427 #define APPEND(B, N_B) \
428 if (rl78_bytes.N_B) \
430 memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B); \
431 idx += rl78_bytes.N_B; \
436 md_assemble (char * str)
439 fragS * frag_then = frag_now;
445 /*printf("\033[32mASM: %s\033[0m\n", str);*/
447 dwarf2_emit_insn (0);
449 memset (& rl78_bytes, 0, sizeof (rl78_bytes));
451 rl78_lex_init (str, str + strlen (str));
455 /* This simplifies the relaxation code. */
456 if (rl78_bytes.link_relax)
458 int olen = rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops;
459 /* We do it this way because we want the frag to have the
460 rl78_bytes in it, which we initialize above. */
461 bytes = frag_more (olen);
462 frag_then = frag_now;
463 frag_variant (rs_machine_dependent,
464 olen /* max_chars */,
470 frag_then->fr_opcode = bytes;
471 frag_then->fr_fix = olen + (bytes - frag_then->fr_literal);
472 frag_then->fr_subtype = olen;
473 frag_then->fr_var = 0;
477 bytes = frag_more (rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops);
478 frag_then = frag_now;
481 APPEND (prefix, n_prefix);
482 APPEND (base, n_base);
485 if (rl78_bytes.link_relax)
489 f = fix_new (frag_then,
490 (char *) bytes - frag_then->fr_literal,
493 rl78_bytes.link_relax | rl78_bytes.n_fixups,
495 BFD_RELOC_RL78_RELAX);
496 frag_then->tc_frag_data->link_relax_fixP = f;
499 for (i = 0; i < rl78_bytes.n_fixups; i ++)
501 /* index: [nbytes][type] */
502 static int reloc_map[5][4] =
505 { BFD_RELOC_8, BFD_RELOC_8_PCREL },
506 { BFD_RELOC_16, BFD_RELOC_16_PCREL },
507 { BFD_RELOC_24, BFD_RELOC_24_PCREL },
508 { BFD_RELOC_32, BFD_RELOC_32_PCREL },
512 idx = rl78_bytes.fixups[i].offset / 8;
513 rel = reloc_map [rl78_bytes.fixups[i].nbits / 8][(int) rl78_bytes.fixups[i].type];
515 if (rl78_bytes.fixups[i].reloc)
516 rel = rl78_bytes.fixups[i].reloc;
518 if (frag_then->tc_frag_data)
519 exp = & frag_then->tc_frag_data->fixups[i].exp;
521 exp = & rl78_bytes.fixups[i].exp;
523 f = fix_new_exp (frag_then,
524 (char *) bytes + idx - frag_then->fr_literal,
525 rl78_bytes.fixups[i].nbits / 8,
527 rl78_bytes.fixups[i].type == RL78REL_PCREL ? 1 : 0,
529 if (frag_then->tc_frag_data)
530 frag_then->tc_frag_data->fixups[i].fixP = f;
535 rl78_cons_fix_new (fragS * frag,
540 bfd_reloc_code_real_type type;
557 as_bad (_("unsupported constant size %d\n"), size);
563 case BFD_RELOC_RL78_CODE:
567 case BFD_RELOC_RL78_LO16:
568 case BFD_RELOC_RL78_HI16:
570 as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
573 case BFD_RELOC_RL78_HI8:
575 as_bad (_("%%hi8 only applies to .byte"));
582 if (exp->X_op == O_subtract && exp->X_op_symbol)
584 if (size != 4 && size != 2 && size != 1)
585 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
587 type = BFD_RELOC_RL78_DIFF;
590 fix_new_exp (frag, where, (int) size, exp, 0, type);
593 /* No relaxation just yet */
595 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
601 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
603 static arelent * reloc[8];
606 if (fixp->fx_r_type == BFD_RELOC_NONE)
613 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
615 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
616 fixp->fx_subsy = NULL;
619 reloc[0] = (arelent *) xmalloc (sizeof (arelent));
620 reloc[0]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
621 * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
622 reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
623 reloc[0]->addend = fixp->fx_offset;
625 if (fixp->fx_r_type == BFD_RELOC_RL78_32_OP
628 fixp->fx_r_type = BFD_RELOC_RL78_DIFF;
631 #define OPX(REL,SYM,ADD) \
632 reloc[rp] = (arelent *) xmalloc (sizeof (arelent)); \
633 reloc[rp]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); \
634 reloc[rp]->howto = bfd_reloc_type_lookup (stdoutput, REL); \
635 reloc[rp]->addend = ADD; \
636 * reloc[rp]->sym_ptr_ptr = SYM; \
637 reloc[rp]->address = fixp->fx_frag->fr_address + fixp->fx_where; \
639 #define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
640 #define OPIMM(IMM) OPX(BFD_RELOC_RL78_SYM, abs_symbol.bsym, IMM)
641 #define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
642 #define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
646 /* Certain BFD relocations cannot be translated directly into
647 a single (non-Red Hat) RL78 relocation, but instead need
648 multiple RL78 relocations - handle them here. */
649 switch (fixp->fx_r_type)
651 case BFD_RELOC_RL78_DIFF:
653 OPSYM (symbol_get_bfdsym (fixp->fx_subsy));
656 switch (fixp->fx_size)
670 case BFD_RELOC_RL78_NEG32:
676 case BFD_RELOC_RL78_CODE:
681 case BFD_RELOC_RL78_LO16:
688 case BFD_RELOC_RL78_HI16:
695 case BFD_RELOC_RL78_HI8:
705 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
714 rl78_validate_fix_sub (struct fix * f)
716 /* We permit the subtraction of two symbols in a few cases. */
717 /* mov #sym1-sym2, R3 */
718 if (f->fx_r_type == BFD_RELOC_RL78_32_OP)
720 /* .long sym1-sym2 */
721 if (f->fx_r_type == BFD_RELOC_RL78_DIFF
723 && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
729 md_pcrel_from_section (fixS * fixP, segT sec)
733 if (fixP->fx_addsy != NULL
734 && (! S_IS_DEFINED (fixP->fx_addsy)
735 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
736 /* The symbol is undefined (or is defined but not in this section).
737 Let the linker figure it out. */
740 rv = fixP->fx_frag->fr_address + fixP->fx_where;
741 switch (fixP->fx_r_type)
743 case BFD_RELOC_8_PCREL:
746 case BFD_RELOC_16_PCREL:
756 md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
757 valueT * t ATTRIBUTE_UNUSED,
758 segT s ATTRIBUTE_UNUSED)
763 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
765 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
768 op = f->fx_frag->fr_literal + f->fx_where;
769 val = (unsigned long) * t;
771 switch (f->fx_r_type)
776 case BFD_RELOC_RL78_RELAX:
781 case BFD_RELOC_8_PCREL:
786 case BFD_RELOC_16_PCREL:
787 case BFD_RELOC_RL78_CODE:
799 case BFD_RELOC_RL78_DIFF:
807 as_bad (_("Unknown reloc in md_apply_fix: %s"),
808 bfd_get_reloc_code_name (f->fx_r_type));
812 if (f->fx_addsy == NULL)
817 md_section_align (segT segment, valueT size)
819 int align = bfd_get_section_alignment (stdoutput, segment);
820 return ((size + (1 << align) - 1) & (-1 << align));
824 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
825 segT segment ATTRIBUTE_UNUSED,
826 fragS * fragP ATTRIBUTE_UNUSED)
828 /* No relaxation yet */