1 /* tc-rl78.c -- Assembler for the Renesas RL78
2 Copyright (C) 2011-2015 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"
23 #include "safe-ctype.h"
24 #include "dwarf2dbg.h"
26 #include "elf/common.h"
28 #include "rl78-defs.h"
29 #include "filenames.h"
34 const 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. */
38 const char line_comment_chars[] = "#";
39 /* Use something that isn't going to be needed by any expressions or
41 const char line_separator_chars[] = "@";
43 const char EXP_CHARS[] = "eE";
44 const char FLT_CHARS[] = "dD";
46 /* ELF flags to set in the output file header. */
47 static int elf_flags = 0;
49 /*------------------------------------------------------------------*/
51 char * rl78_lex_start;
54 typedef struct rl78_bytesT
67 char type; /* RL78REL_*. */
80 fixS *link_relax_fixP;
85 static rl78_bytesT rl78_bytes;
88 rl78_relax (int type, int pos)
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 ++;
97 rl78_linkrelax_addr16 (void)
99 rl78_bytes.link_relax |= RL78_RELAXA_ADDR16;
103 rl78_linkrelax_branch (void)
105 rl78_bytes.link_relax |= RL78_RELAXA_BRA;
109 rl78_fixup (expressionS exp, int offsetbits, int nbits, int type)
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 ++;
119 #define rl78_field_fixup(exp, offset, nbits, type) \
120 rl78_fixup (exp, offset + 8 * rl78_bytes.n_prefix), nbits, type)
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)
128 rl78_bytes.prefix[0] = p;
129 rl78_bytes.n_prefix = 1;
135 return rl78_bytes.n_prefix;
141 rl78_bytes.base[0] = b1;
142 rl78_bytes.n_base = 1;
146 rl78_base2 (int b1, int b2)
148 rl78_bytes.base[0] = b1;
149 rl78_bytes.base[1] = b2;
150 rl78_bytes.n_base = 2;
154 rl78_base3 (int b1, int b2, int b3)
156 rl78_bytes.base[0] = b1;
157 rl78_bytes.base[1] = b2;
158 rl78_bytes.base[2] = b3;
159 rl78_bytes.n_base = 3;
163 rl78_base4 (int b1, int b2, int b3, int b4)
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;
172 #define F_PRECISION 2
175 rl78_op (expressionS exp, int nbytes, int type)
179 if ((exp.X_op == O_constant || exp.X_op == O_big)
180 && type != RL78REL_PCREL)
182 if (exp.X_op == O_big && exp.X_add_number <= 0)
185 char * ip = rl78_bytes.ops + rl78_bytes.n_ops;
187 gen_to_words (w, F_PRECISION, 8);
192 rl78_bytes.n_ops += 4;
196 v = exp.X_add_number;
199 rl78_bytes.ops[rl78_bytes.n_ops++] =v & 0xff;
208 && exp.X_md == BFD_RELOC_RL78_CODE)
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"));
217 && exp.X_md == BFD_RELOC_RL78_HI8)
218 as_bad (_("8-bit relocation used in 16-bit operand"));
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;
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:
232 - - - - - - - - - - - - - - - -
236 rl78_field (int val, int pos, int sz)
243 if (val < 0 || val >= (1 << sz))
244 as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, 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);
253 /* This code points at 'M' in the above example. */
257 while (bitp + sz > 8)
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;
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;
278 /*------------------------------------------------------------------*/
282 OPTION_RELAX = OPTION_MD_BASE,
284 OPTION_32BIT_DOUBLES,
285 OPTION_64BIT_DOUBLES,
288 #define RL78_SHORTOPTS ""
289 const char * md_shortopts = RL78_SHORTOPTS;
291 /* Assembler options. */
292 struct option md_longopts[] =
294 {"relax", no_argument, NULL, OPTION_RELAX},
295 {"mg10", no_argument, NULL, OPTION_G10},
296 {"m32bit-doubles", no_argument, NULL, OPTION_32BIT_DOUBLES},
297 {"m64bit-doubles", no_argument, NULL, OPTION_64BIT_DOUBLES},
298 {NULL, no_argument, NULL, 0}
300 size_t md_longopts_size = sizeof (md_longopts);
303 md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
312 elf_flags |= E_FLAG_RL78_G10;
315 case OPTION_32BIT_DOUBLES:
316 elf_flags &= ~ E_FLAG_RL78_64BIT_DOUBLES;
319 case OPTION_64BIT_DOUBLES:
320 elf_flags |= E_FLAG_RL78_64BIT_DOUBLES;
327 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
329 fprintf (stream, _(" RL78 specific command line options:\n"));
330 fprintf (stream, _(" --mg10 Enable support for G10 variant\n"));
331 fprintf (stream, _(" --m32bit-doubles [default]\n"));
332 fprintf (stream, _(" --m64bit-doubles\n"));
336 s_bss (int ignore ATTRIBUTE_UNUSED)
340 temp = get_absolute_expression ();
341 subseg_set (bss_section, (subsegT) temp);
342 demand_empty_rest_of_line ();
346 rl78_float_cons (int ignore ATTRIBUTE_UNUSED)
348 if (elf_flags & E_FLAG_RL78_64BIT_DOUBLES)
349 return float_cons ('d');
350 return float_cons ('f');
353 /* The target specific pseudo-ops which we support. */
354 const pseudo_typeS md_pseudo_table[] =
356 /* Our "standard" pseudos. */
357 { "double", rl78_float_cons, 'd' },
359 { "3byte", cons, 3 },
363 /* End of list marker. */
377 /* Set the ELF specific flags. */
379 rl78_elf_final_processing (void)
381 elf_elfheader (stdoutput)->e_flags |= elf_flags;
384 /* Write a value out to the object file, using the appropriate endianness. */
386 md_number_to_chars (char * buf, valueT val, int n)
388 number_to_chars_littleendian (buf, val, n);
392 require_end_of_expr (char *fname)
394 while (* input_line_pointer == ' '
395 || * input_line_pointer == '\t')
396 input_line_pointer ++;
398 if (! * input_line_pointer
399 || strchr ("\n\r,", * input_line_pointer)
400 || strchr (comment_chars, * input_line_pointer)
401 || strchr (line_comment_chars, * input_line_pointer)
402 || strchr (line_separator_chars, * input_line_pointer))
405 as_bad (_("%%%s() must be outermost term in expression"), fname);
415 { "code", BFD_RELOC_RL78_CODE },
416 { "lo16", BFD_RELOC_RL78_LO16 },
417 { "hi16", BFD_RELOC_RL78_HI16 },
418 { "hi8", BFD_RELOC_RL78_HI8 },
423 md_operand (expressionS * exp ATTRIBUTE_UNUSED)
428 for (i = 0; reloc_functions[i].fname; i++)
430 int flen = strlen (reloc_functions[i].fname);
432 if (input_line_pointer[0] == '%'
433 && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
434 && input_line_pointer[flen + 1] == '(')
436 reloc = reloc_functions[i].reloc;
437 input_line_pointer += flen + 2;
445 if (* input_line_pointer == ')')
446 input_line_pointer ++;
450 require_end_of_expr (reloc_functions[i].fname);
454 rl78_frag_init (fragS * fragP)
456 if (rl78_bytes.n_relax || rl78_bytes.link_relax)
458 fragP->tc_frag_data = malloc (sizeof (rl78_bytesT));
459 memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT));
462 fragP->tc_frag_data = 0;
465 /* When relaxing, we need to output a reloc for any .align directive
466 so that we can retain this alignment as we adjust opcode sizes. */
468 rl78_handle_align (fragS * frag)
471 && (frag->fr_type == rs_align
472 || frag->fr_type == rs_align_code)
473 && frag->fr_address + frag->fr_fix > 0
474 && frag->fr_offset > 0
475 && now_seg != bss_section)
477 fix_new (frag, frag->fr_fix, 0,
478 &abs_symbol, RL78_RELAXA_ALIGN + frag->fr_offset,
479 0, BFD_RELOC_RL78_RELAX);
480 /* For the purposes of relaxation, this relocation is attached
481 to the byte *after* the alignment - i.e. the byte that must
483 fix_new (frag->fr_next, 0, 0,
484 &abs_symbol, RL78_RELAXA_ELIGN + frag->fr_offset,
485 0, BFD_RELOC_RL78_RELAX);
490 md_atof (int type, char * litP, int * sizeP)
492 return ieee_md_atof (type, litP, sizeP, target_big_endian);
496 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
501 #define APPEND(B, N_B) \
502 if (rl78_bytes.N_B) \
504 memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B); \
505 idx += rl78_bytes.N_B; \
510 md_assemble (char * str)
513 fragS * frag_then = frag_now;
519 /*printf("\033[32mASM: %s\033[0m\n", str);*/
521 dwarf2_emit_insn (0);
523 memset (& rl78_bytes, 0, sizeof (rl78_bytes));
525 rl78_lex_init (str, str + strlen (str));
529 /* This simplifies the relaxation code. */
530 if (rl78_bytes.n_relax || rl78_bytes.link_relax)
532 int olen = rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops;
533 /* We do it this way because we want the frag to have the
534 rl78_bytes in it, which we initialize above. The extra bytes
536 bytes = frag_more (olen + 3);
537 frag_then = frag_now;
538 frag_variant (rs_machine_dependent,
539 olen /* max_chars */,
545 frag_then->fr_opcode = bytes;
546 frag_then->fr_fix = olen + (bytes - frag_then->fr_literal);
547 frag_then->fr_subtype = olen;
548 frag_then->fr_var = 0;
552 bytes = frag_more (rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops);
553 frag_then = frag_now;
556 APPEND (prefix, n_prefix);
557 APPEND (base, n_base);
560 if (rl78_bytes.link_relax)
564 f = fix_new (frag_then,
565 (char *) bytes - frag_then->fr_literal,
568 rl78_bytes.link_relax | rl78_bytes.n_fixups,
570 BFD_RELOC_RL78_RELAX);
571 frag_then->tc_frag_data->link_relax_fixP = f;
574 for (i = 0; i < rl78_bytes.n_fixups; i ++)
576 /* index: [nbytes][type] */
577 static int reloc_map[5][4] =
580 { BFD_RELOC_8, BFD_RELOC_8_PCREL },
581 { BFD_RELOC_16, BFD_RELOC_16_PCREL },
582 { BFD_RELOC_24, BFD_RELOC_24_PCREL },
583 { BFD_RELOC_32, BFD_RELOC_32_PCREL },
587 idx = rl78_bytes.fixups[i].offset / 8;
588 rel = reloc_map [rl78_bytes.fixups[i].nbits / 8][(int) rl78_bytes.fixups[i].type];
590 if (rl78_bytes.fixups[i].reloc)
591 rel = rl78_bytes.fixups[i].reloc;
593 if (frag_then->tc_frag_data)
594 exp = & frag_then->tc_frag_data->fixups[i].exp;
596 exp = & rl78_bytes.fixups[i].exp;
598 f = fix_new_exp (frag_then,
599 (char *) bytes + idx - frag_then->fr_literal,
600 rl78_bytes.fixups[i].nbits / 8,
602 rl78_bytes.fixups[i].type == RL78REL_PCREL ? 1 : 0,
604 if (frag_then->tc_frag_data)
605 frag_then->tc_frag_data->fixups[i].fixP = f;
610 rl78_cons_fix_new (fragS * frag,
615 bfd_reloc_code_real_type type;
633 as_bad (_("unsupported constant size %d\n"), size);
639 case BFD_RELOC_RL78_CODE:
643 case BFD_RELOC_RL78_LO16:
644 case BFD_RELOC_RL78_HI16:
646 as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
649 case BFD_RELOC_RL78_HI8:
651 as_bad (_("%%hi8 only applies to .byte"));
658 if (exp->X_op == O_subtract && exp->X_op_symbol)
660 if (size != 4 && size != 2 && size != 1)
661 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
663 type = BFD_RELOC_RL78_DIFF;
666 fixP = fix_new_exp (frag, where, (int) size, exp, 0, type);
669 /* These are intended to have values larger than the container,
670 since the backend puts only the portion we need in it.
671 However, we don't have a backend-specific reloc for them as
672 they're handled with complex relocations. */
673 case BFD_RELOC_RL78_LO16:
674 case BFD_RELOC_RL78_HI16:
675 case BFD_RELOC_RL78_HI8:
676 fixP->fx_no_overflow = 1;
684 /*----------------------------------------------------------------------*/
685 /* To recap: we estimate everything based on md_estimate_size, then
686 adjust based on rl78_relax_frag. When it all settles, we call
687 md_convert frag to update the bytes. The relaxation types and
688 relocations are in fragP->tc_frag_data, which is a copy of that
691 Our scheme is as follows: fr_fix has the size of the smallest
692 opcode (like BRA.S). We store the number of total bytes we need in
693 fr_subtype. When we're done relaxing, we use fr_subtype and the
694 existing opcode bytes to figure out what actual opcode we need to
695 put in there. If the fixup isn't resolvable now, we use the
698 #define TRACE_RELAX 0
699 #define tprintf if (TRACE_RELAX) printf
712 /* We're looking for these types of relaxations:
714 BT 00110001 sbit0cc1 addr---- (cc is 10 (BF) or 01 (BT))
715 B~T 00110001 sbit0cc1 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
717 BT sfr 00110001 sbit0cc0 sfr----- addr----
718 BT ES: 00010001 00101110 sbit0cc1 addr----
721 B~C 110111cc 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
723 BH 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
724 B~H 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
727 /* Given the opcode bytes at OP, figure out which opcode it is and
728 return the type of opcode. We use this to re-encode the opcode as
729 a different size later. */
732 rl78_opcode_type (char * op)
735 && ((op[1] & 0x0f) == 0x05
736 || (op[1] & 0x0f) == 0x03))
740 && ((op[1] & 0x0f) == 0x04
741 || (op[1] & 0x0f) == 0x02))
746 && ((op[2] & 0x0f) == 0x05
747 || (op[2] & 0x0f) == 0x03))
750 if ((op[0] & 0xfc) == 0xdc)
754 && (op[1] & 0xef) == 0xc3)
760 /* Returns zero if *addrP has the target address. Else returns nonzero
761 if we cannot compute the target address yet. */
764 rl78_frag_fix_value (fragS * fragP,
772 rl78_bytesT * b = fragP->tc_frag_data;
773 expressionS * exp = & b->fixups[which].exp;
775 if (need_diff && exp->X_op != O_subtract)
778 if (exp->X_add_symbol)
780 if (S_FORCE_RELOC (exp->X_add_symbol, 1))
782 if (S_GET_SEGMENT (exp->X_add_symbol) != segment)
784 addr += S_GET_VALUE (exp->X_add_symbol);
787 if (exp->X_op_symbol)
789 if (exp->X_op != O_subtract)
791 if (S_FORCE_RELOC (exp->X_op_symbol, 1))
793 if (S_GET_SEGMENT (exp->X_op_symbol) != segment)
795 addr -= S_GET_VALUE (exp->X_op_symbol);
799 addr += exp->X_add_number;
804 /* Estimate how big the opcode is after this relax pass. The return
805 value is the difference between fr_fix and the actual size. We
806 compute the total size in rl78_relax_frag and store it in fr_subtype,
807 sowe only need to subtract fx_fix and return it. */
810 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
815 /* This is the size of the opcode that's accounted for in fr_fix. */
816 opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal);
817 /* This is the size of the opcode that isn't. */
818 delta = (fragP->fr_subtype - opfixsize);
820 tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta);
824 /* Given the new addresses for this relax pass, figure out how big
825 each opcode must be. We store the total number of bytes needed in
826 fr_subtype. The return value is the difference between the size
827 after the last pass and the size after this pass, so we use the old
828 fr_subtype to calculate the difference. */
831 rl78_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
833 addressT addr0, sym_addr;
836 int oldsize = fragP->fr_subtype;
837 int newsize = oldsize;
841 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
843 /* If we ever get more than one reloc per opcode, this is the one
847 optype = rl78_opcode_type (fragP->fr_opcode);
848 /* Try to get the target address. */
849 if (rl78_frag_fix_value (fragP, segment, ri, & addr0,
850 fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH,
853 /* If we don't, we must use the maximum size for the linker. */
854 switch (fragP->tc_frag_data->relax[ri].type)
856 case RL78_RELAX_BRANCH:
879 fragP->fr_subtype = newsize;
880 tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize);
881 return newsize - oldsize;
887 switch (fragP->tc_frag_data->relax[ri].type)
889 case RL78_RELAX_BRANCH:
890 disp = (int) addr0 - (int) mypc;
895 if (disp >= -128 && (disp - (oldsize-2)) <= 127)
902 if (disp >= -128 && (disp - (oldsize-3)) <= 127)
908 if (disp >= -128 && (disp - (oldsize-1)) <= 127)
914 if (disp >= -128 && (disp - (oldsize-2)) <= 127)
926 /* This prevents infinite loops in align-heavy sources. */
927 if (newsize < oldsize)
929 if (fragP->tc_frag_data->times_shrank > 10
930 && fragP->tc_frag_data->times_grown > 10)
932 if (fragP->tc_frag_data->times_shrank < 20)
933 fragP->tc_frag_data->times_shrank ++;
935 else if (newsize > oldsize)
937 if (fragP->tc_frag_data->times_grown < 20)
938 fragP->tc_frag_data->times_grown ++;
941 fragP->fr_subtype = newsize;
942 tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
943 return newsize - oldsize;
946 /* This lets us test for the opcode type and the desired size in a
948 #define OPCODE(type,size) ((type) * 16 + (size))
950 /* Given the opcode stored in fr_opcode and the number of bytes we
951 think we need, encode a new opcode. We stored a pointer to the
952 fixup for this opcode in the tc_frag_data structure. If we can do
953 the fixup here, we change the relocation type to "none" (we test
954 for that in tc_gen_reloc) else we change it to the right type for
955 the new (biggest) opcode. */
958 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
959 segT segment ATTRIBUTE_UNUSED,
960 fragS * fragP ATTRIBUTE_UNUSED)
962 rl78_bytesT * rl78b = fragP->tc_frag_data;
963 addressT addr0, mypc;
965 int reloc_type, reloc_adjust;
966 char * op = fragP->fr_opcode;
969 int fi = (rl78b->n_fixups > 1) ? 1 : 0;
970 fixS * fix = rl78b->fixups[fi].fixP;
972 /* If we ever get more than one reloc per opcode, this is the one
976 /* We used a new frag for this opcode, so the opcode address should
977 be the frag address. */
978 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
979 tprintf("\033[32mmypc: 0x%x\033[0m\n", (int)mypc);
981 /* Try to get the target address. If we fail here, we just use the
983 if (rl78_frag_fix_value (fragP, segment, 0, & addr0,
984 fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH, 0))
986 /* We don't know the target address. */
990 tprintf ("unknown addr ? - %x = ?\n", (int)mypc);
994 /* We know the target address, and it's in addr0. */
995 disp = (int) addr0 - (int) mypc;
996 tprintf ("known addr %x - %x = %d\n", (int)addr0, (int)mypc, disp);
1002 reloc_type = BFD_RELOC_NONE;
1005 switch (fragP->tc_frag_data->relax[ri].type)
1007 case RL78_RELAX_BRANCH:
1008 switch (OPCODE (rl78_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
1011 case OPCODE (OT_bt, 3): /* BT A,$ - no change. */
1016 case OPCODE (OT_bt, 6): /* BT A,$ - long version. */
1018 op[1] ^= 0x06; /* toggle conditional. */
1019 op[2] = 3; /* displacement over long branch. */
1021 op[3] = 0xEE; /* BR $!addr20 */
1022 op[4] = disp & 0xff;
1024 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1028 case OPCODE (OT_bt_sfr, 4): /* BT PSW,$ - no change. */
1033 case OPCODE (OT_bt_sfr, 7): /* BT PSW,$ - long version. */
1035 op[1] ^= 0x06; /* toggle conditional. */
1036 op[3] = 3; /* displacement over long branch. */
1038 op[4] = 0xEE; /* BR $!addr20 */
1039 op[5] = disp & 0xff;
1041 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1045 case OPCODE (OT_bt_es, 4): /* BT ES:[HL],$ - no change. */
1050 case OPCODE (OT_bt_es, 7): /* BT PSW,$ - long version. */
1052 op[2] ^= 0x06; /* toggle conditional. */
1053 op[3] = 3; /* displacement over long branch. */
1055 op[4] = 0xEE; /* BR $!addr20 */
1056 op[5] = disp & 0xff;
1058 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1062 case OPCODE (OT_bc, 2): /* BC $ - no change. */
1067 case OPCODE (OT_bc, 5): /* BC $ - long version. */
1069 op[0] ^= 0x02; /* toggle conditional. */
1072 op[2] = 0xEE; /* BR $!addr20 */
1073 op[3] = disp & 0xff;
1075 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1079 case OPCODE (OT_bh, 3): /* BH $ - no change. */
1084 case OPCODE (OT_bh, 6): /* BC $ - long version. */
1086 op[1] ^= 0x10; /* toggle conditional. */
1089 op[3] = 0xEE; /* BR $!addr20 */
1090 op[4] = disp & 0xff;
1092 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1097 fprintf(stderr, "Missed case %d %d at 0x%lx\n",
1098 rl78_opcode_type (fragP->fr_opcode), fragP->fr_subtype, mypc);
1105 if (rl78b->n_fixups)
1107 reloc_type = fix->fx_r_type;
1113 if (rl78b->n_fixups)
1116 fix->fx_r_type = reloc_type;
1117 fix->fx_where += reloc_adjust;
1120 case BFD_RELOC_NONE:
1126 case BFD_RELOC_16_PCREL:
1132 fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
1133 tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix,
1134 fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
1137 tprintf ("compare 0x%lx vs 0x%lx - 0x%lx = 0x%lx (%p)\n",
1138 (long)fragP->fr_fix,
1139 (long)fragP->fr_next->fr_address, (long)fragP->fr_address,
1140 (long)(fragP->fr_next->fr_address - fragP->fr_address),
1143 if (fragP->fr_next != NULL
1144 && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
1146 as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
1147 (long) fragP->fr_fix,
1148 (long) fragP->fr_address, (long) fragP->fr_next->fr_address);
1151 /* End of relaxation code.
1152 ----------------------------------------------------------------------*/
1156 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
1158 static arelent * reloc[8];
1161 if (fixp->fx_r_type == BFD_RELOC_NONE)
1168 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1170 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
1171 fixp->fx_subsy = NULL;
1174 reloc[0] = (arelent *) xmalloc (sizeof (arelent));
1175 reloc[0]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1176 * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1177 reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
1178 reloc[0]->addend = fixp->fx_offset;
1180 if (fixp->fx_r_type == BFD_RELOC_RL78_32_OP
1183 fixp->fx_r_type = BFD_RELOC_RL78_DIFF;
1186 #define OPX(REL,SYM,ADD) \
1187 reloc[rp] = (arelent *) xmalloc (sizeof (arelent)); \
1188 reloc[rp]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); \
1189 reloc[rp]->howto = bfd_reloc_type_lookup (stdoutput, REL); \
1190 reloc[rp]->addend = ADD; \
1191 * reloc[rp]->sym_ptr_ptr = SYM; \
1192 reloc[rp]->address = fixp->fx_frag->fr_address + fixp->fx_where; \
1194 #define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
1195 #define OPIMM(IMM) OPX(BFD_RELOC_RL78_SYM, abs_symbol.bsym, IMM)
1196 #define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
1197 #define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
1201 /* Certain BFD relocations cannot be translated directly into
1202 a single (non-Red Hat) RL78 relocation, but instead need
1203 multiple RL78 relocations - handle them here. */
1204 switch (fixp->fx_r_type)
1206 case BFD_RELOC_RL78_DIFF:
1208 OPSYM (symbol_get_bfdsym (fixp->fx_subsy));
1211 switch (fixp->fx_size)
1225 case BFD_RELOC_RL78_NEG32:
1231 case BFD_RELOC_RL78_CODE:
1232 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_16U);
1236 case BFD_RELOC_RL78_LO16:
1243 case BFD_RELOC_RL78_HI16:
1250 case BFD_RELOC_RL78_HI8:
1260 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1269 rl78_validate_fix_sub (struct fix * f)
1271 /* We permit the subtraction of two symbols in a few cases. */
1272 /* mov #sym1-sym2, R3 */
1273 if (f->fx_r_type == BFD_RELOC_RL78_32_OP)
1275 /* .long sym1-sym2 */
1276 if (f->fx_r_type == BFD_RELOC_RL78_DIFF
1278 && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
1284 md_pcrel_from_section (fixS * fixP, segT sec)
1288 if (fixP->fx_addsy != NULL
1289 && (! S_IS_DEFINED (fixP->fx_addsy)
1290 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
1291 /* The symbol is undefined (or is defined but not in this section).
1292 Let the linker figure it out. */
1295 rv = fixP->fx_frag->fr_address + fixP->fx_where;
1296 switch (fixP->fx_r_type)
1298 case BFD_RELOC_8_PCREL:
1301 case BFD_RELOC_16_PCREL:
1311 md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
1312 valueT * t ATTRIBUTE_UNUSED,
1313 segT s ATTRIBUTE_UNUSED)
1318 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
1320 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
1323 op = f->fx_frag->fr_literal + f->fx_where;
1324 val = (unsigned long) * t;
1326 switch (f->fx_r_type)
1328 case BFD_RELOC_NONE:
1331 case BFD_RELOC_RL78_RELAX:
1335 case BFD_RELOC_8_PCREL:
1336 if ((long)val < -128 || (long)val > 127)
1337 as_bad_where (f->fx_file, f->fx_line,
1338 _("value of %ld too large for 8-bit branch"),
1345 case BFD_RELOC_16_PCREL:
1346 if ((long)val < -32768 || (long)val > 32767)
1347 as_bad_where (f->fx_file, f->fx_line,
1348 _("value of %ld too large for 16-bit branch"),
1352 case BFD_RELOC_RL78_CODE:
1370 case BFD_RELOC_RL78_DIFF:
1380 case BFD_RELOC_RL78_HI8:
1385 case BFD_RELOC_RL78_HI16:
1391 case BFD_RELOC_RL78_LO16:
1397 as_bad (_("Unknown reloc in md_apply_fix: %s"),
1398 bfd_get_reloc_code_name (f->fx_r_type));
1402 if (f->fx_addsy == NULL)
1407 md_section_align (segT segment, valueT size)
1409 int align = bfd_get_section_alignment (stdoutput, segment);
1410 return ((size + (1 << align) - 1) & (-1 << align));