1 /* tc-rl78.c -- Assembler for the Renesas RL78
2 Copyright (C) 2011-2023 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 "safe-ctype.h"
23 #include "dwarf2dbg.h"
24 #include "elf/common.h"
26 #include "rl78-defs.h"
27 #include "filenames.h"
32 const char comment_chars
[] = ";";
33 /* Note that input_file.c hand checks for '#' at the beginning of the
34 first line of the input file. This is because the compiler outputs
35 #NO_APP at the beginning of its output. */
36 const char line_comment_chars
[] = "#";
37 /* Use something that isn't going to be needed by any expressions or
39 const char line_separator_chars
[] = "@";
41 const char EXP_CHARS
[] = "eE";
42 const char FLT_CHARS
[] = "dD";
44 /* ELF flags to set in the output file header. */
45 static int elf_flags
= 0;
47 /*------------------------------------------------------------------*/
49 char * rl78_lex_start
;
52 typedef struct rl78_bytesT
65 char type
; /* RL78REL_*. */
78 fixS
*link_relax_fixP
;
83 static rl78_bytesT rl78_bytes
;
86 rl78_relax (int type
, int pos
)
88 rl78_bytes
.relax
[rl78_bytes
.n_relax
].type
= type
;
89 rl78_bytes
.relax
[rl78_bytes
.n_relax
].field_pos
= pos
;
90 rl78_bytes
.relax
[rl78_bytes
.n_relax
].val_ofs
= rl78_bytes
.n_base
+ rl78_bytes
.n_ops
;
91 rl78_bytes
.n_relax
++;
95 rl78_linkrelax_addr16 (void)
97 rl78_bytes
.link_relax
|= RL78_RELAXA_ADDR16
;
101 rl78_linkrelax_branch (void)
103 rl78_relax (RL78_RELAX_BRANCH
, 0);
104 rl78_bytes
.link_relax
|= RL78_RELAXA_BRA
;
108 rl78_fixup (expressionS exp
, int offsetbits
, int nbits
, int type
)
110 rl78_bytes
.fixups
[rl78_bytes
.n_fixups
].exp
= exp
;
111 rl78_bytes
.fixups
[rl78_bytes
.n_fixups
].offset
= offsetbits
;
112 rl78_bytes
.fixups
[rl78_bytes
.n_fixups
].nbits
= nbits
;
113 rl78_bytes
.fixups
[rl78_bytes
.n_fixups
].type
= type
;
114 rl78_bytes
.fixups
[rl78_bytes
.n_fixups
].reloc
= exp
.X_md
;
115 rl78_bytes
.n_fixups
++;
118 #define rl78_field_fixup(exp, offset, nbits, type) \
119 rl78_fixup (exp, offset + 8 * rl78_bytes.n_prefix), nbits, type)
121 #define rl78_op_fixup(exp, offset, nbits, type) \
122 rl78_fixup (exp, offset + 8 * (rl78_bytes.n_prefix + rl78_bytes.n_base), nbits, type)
127 rl78_bytes
.prefix
[0] = p
;
128 rl78_bytes
.n_prefix
= 1;
132 rl78_has_prefix (void)
134 return rl78_bytes
.n_prefix
;
140 rl78_bytes
.base
[0] = b1
;
141 rl78_bytes
.n_base
= 1;
145 rl78_base2 (int b1
, int b2
)
147 rl78_bytes
.base
[0] = b1
;
148 rl78_bytes
.base
[1] = b2
;
149 rl78_bytes
.n_base
= 2;
153 rl78_base3 (int b1
, int b2
, int b3
)
155 rl78_bytes
.base
[0] = b1
;
156 rl78_bytes
.base
[1] = b2
;
157 rl78_bytes
.base
[2] = b3
;
158 rl78_bytes
.n_base
= 3;
162 rl78_base4 (int b1
, int b2
, int b3
, int b4
)
164 rl78_bytes
.base
[0] = b1
;
165 rl78_bytes
.base
[1] = b2
;
166 rl78_bytes
.base
[2] = b3
;
167 rl78_bytes
.base
[3] = b4
;
168 rl78_bytes
.n_base
= 4;
171 #define F_PRECISION 2
174 rl78_op (expressionS exp
, int nbytes
, int type
)
178 if ((exp
.X_op
== O_constant
|| exp
.X_op
== O_big
)
179 && type
!= RL78REL_PCREL
)
181 if (exp
.X_op
== O_big
&& exp
.X_add_number
<= 0)
184 char * ip
= rl78_bytes
.ops
+ rl78_bytes
.n_ops
;
186 gen_to_words (w
, F_PRECISION
, 8);
191 rl78_bytes
.n_ops
+= 4;
195 v
= exp
.X_add_number
;
198 rl78_bytes
.ops
[rl78_bytes
.n_ops
++] =v
& 0xff;
207 && exp
.X_md
== BFD_RELOC_RL78_CODE
)
211 && (exp
.X_md
== BFD_RELOC_RL78_LO16
212 || exp
.X_md
== BFD_RELOC_RL78_HI16
))
213 as_bad (_("16-bit relocation used in 8-bit operand"));
216 && exp
.X_md
== BFD_RELOC_RL78_HI8
)
217 as_bad (_("8-bit relocation used in 16-bit operand"));
219 rl78_op_fixup (exp
, rl78_bytes
.n_ops
* 8, nbytes
* 8, type
);
220 memset (rl78_bytes
.ops
+ rl78_bytes
.n_ops
, 0, nbytes
);
221 rl78_bytes
.n_ops
+= nbytes
;
225 /* This gets complicated when the field spans bytes, because fields
226 are numbered from the MSB of the first byte as zero, and bits are
227 stored LSB towards the LSB of the byte. Thus, a simple four-bit
228 insertion of 12 at position 4 of 0x00 yields: 0x0b. A three-bit
229 insertion of b'MXL at position 7 is like this:
231 - - - - - - - - - - - - - - - -
235 rl78_field (int val
, int pos
, int sz
)
242 if (val
< 0 || val
>= (1 << sz
))
243 as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val
, sz
);
248 if (val
< -(1 << (sz
- 1)) || val
>= (1 << (sz
- 1)))
249 as_bad (_("Value %d doesn't fit in signed %d-bit field"), val
, sz
);
252 /* This code points at 'M' in the above example. */
256 while (bitp
+ sz
> 8)
261 svalm
= val
>> (sz
- ssz
);
262 svalm
= svalm
& ((1 << ssz
) - 1);
263 svalm
= svalm
<< (8 - bitp
- ssz
);
264 gas_assert (bytep
< rl78_bytes
.n_base
);
265 rl78_bytes
.base
[bytep
] |= svalm
;
271 valm
= val
& ((1 << sz
) - 1);
272 valm
= valm
<< (8 - bitp
- sz
);
273 gas_assert (bytep
< rl78_bytes
.n_base
);
274 rl78_bytes
.base
[bytep
] |= valm
;
277 /*------------------------------------------------------------------*/
281 OPTION_RELAX
= OPTION_MD_BASE
,
286 OPTION_32BIT_DOUBLES
,
287 OPTION_64BIT_DOUBLES
,
290 #define RL78_SHORTOPTS ""
291 const char * md_shortopts
= RL78_SHORTOPTS
;
293 /* Assembler options. */
294 struct option md_longopts
[] =
296 {"relax", no_argument
, NULL
, OPTION_RELAX
},
297 {"norelax", no_argument
, NULL
, OPTION_NORELAX
},
298 {"mg10", no_argument
, NULL
, OPTION_G10
},
299 {"mg13", no_argument
, NULL
, OPTION_G13
},
300 {"mg14", no_argument
, NULL
, OPTION_G14
},
301 {"mrl78", no_argument
, NULL
, OPTION_G14
},
302 {"m32bit-doubles", no_argument
, NULL
, OPTION_32BIT_DOUBLES
},
303 {"m64bit-doubles", no_argument
, NULL
, OPTION_64BIT_DOUBLES
},
304 {NULL
, no_argument
, NULL
, 0}
306 size_t md_longopts_size
= sizeof (md_longopts
);
309 md_parse_option (int c
, const char * arg ATTRIBUTE_UNUSED
)
321 elf_flags
&= ~ E_FLAG_RL78_CPU_MASK
;
322 elf_flags
|= E_FLAG_RL78_G10
;
326 elf_flags
&= ~ E_FLAG_RL78_CPU_MASK
;
327 elf_flags
|= E_FLAG_RL78_G13
;
331 elf_flags
&= ~ E_FLAG_RL78_CPU_MASK
;
332 elf_flags
|= E_FLAG_RL78_G14
;
335 case OPTION_32BIT_DOUBLES
:
336 elf_flags
&= ~ E_FLAG_RL78_64BIT_DOUBLES
;
339 case OPTION_64BIT_DOUBLES
:
340 elf_flags
|= E_FLAG_RL78_64BIT_DOUBLES
;
349 return (elf_flags
& E_FLAG_RL78_CPU_MASK
) == E_FLAG_RL78_G10
;
355 return (elf_flags
& E_FLAG_RL78_CPU_MASK
) == E_FLAG_RL78_G13
;
361 return (elf_flags
& E_FLAG_RL78_CPU_MASK
) == E_FLAG_RL78_G14
;
365 md_show_usage (FILE * stream
)
367 fprintf (stream
, _(" RL78 specific command line options:\n"));
368 fprintf (stream
, _(" --mrelax Enable link time relaxation\n"));
369 fprintf (stream
, _(" --mg10 Enable support for G10 variant\n"));
370 fprintf (stream
, _(" --mg13 Selects the G13 core.\n"));
371 fprintf (stream
, _(" --mg14 Selects the G14 core [default]\n"));
372 fprintf (stream
, _(" --mrl78 Alias for --mg14\n"));
373 fprintf (stream
, _(" --m32bit-doubles [default]\n"));
374 fprintf (stream
, _(" --m64bit-doubles Source code uses 64-bit doubles\n"));
378 s_bss (int ignore ATTRIBUTE_UNUSED
)
382 temp
= get_absolute_expression ();
383 subseg_set (bss_section
, (subsegT
) temp
);
384 demand_empty_rest_of_line ();
388 rl78_float_cons (int ignore ATTRIBUTE_UNUSED
)
390 if (elf_flags
& E_FLAG_RL78_64BIT_DOUBLES
)
391 return float_cons ('d');
392 return float_cons ('f');
395 /* The target specific pseudo-ops which we support. */
396 const pseudo_typeS md_pseudo_table
[] =
398 /* Our "standard" pseudos. */
399 { "double", rl78_float_cons
, 'd' },
401 { "3byte", cons
, 3 },
405 /* End of list marker. */
409 static symbolS
* rl78_abs_sym
= NULL
;
414 rl78_abs_sym
= symbol_make ("__rl78_abs__");
422 /* Set the ELF specific flags. */
424 rl78_elf_final_processing (void)
426 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;
429 /* Write a value out to the object file, using the appropriate endianness. */
431 md_number_to_chars (char * buf
, valueT val
, int n
)
433 number_to_chars_littleendian (buf
, val
, n
);
437 require_end_of_expr (const char *fname
)
439 while (* input_line_pointer
== ' '
440 || * input_line_pointer
== '\t')
441 input_line_pointer
++;
443 if (! * input_line_pointer
444 || strchr ("\n\r,", * input_line_pointer
)
445 || strchr (comment_chars
, * input_line_pointer
)
446 || strchr (line_comment_chars
, * input_line_pointer
)
447 || strchr (line_separator_chars
, * input_line_pointer
))
450 as_bad (_("%%%s() must be outermost term in expression"), fname
);
460 { "code", BFD_RELOC_RL78_CODE
},
461 { "lo16", BFD_RELOC_RL78_LO16
},
462 { "hi16", BFD_RELOC_RL78_HI16
},
463 { "hi8", BFD_RELOC_RL78_HI8
},
468 md_operand (expressionS
* exp ATTRIBUTE_UNUSED
)
473 for (i
= 0; reloc_functions
[i
].fname
; i
++)
475 int flen
= strlen (reloc_functions
[i
].fname
);
477 if (input_line_pointer
[0] == '%'
478 && strncasecmp (input_line_pointer
+ 1, reloc_functions
[i
].fname
, flen
) == 0
479 && input_line_pointer
[flen
+ 1] == '(')
481 reloc
= reloc_functions
[i
].reloc
;
482 input_line_pointer
+= flen
+ 2;
490 if (* input_line_pointer
== ')')
491 input_line_pointer
++;
495 require_end_of_expr (reloc_functions
[i
].fname
);
499 rl78_frag_init (fragS
* fragP
)
501 if (rl78_bytes
.n_relax
|| rl78_bytes
.link_relax
)
503 fragP
->tc_frag_data
= XNEW (rl78_bytesT
);
504 memcpy (fragP
->tc_frag_data
, & rl78_bytes
, sizeof (rl78_bytesT
));
507 fragP
->tc_frag_data
= 0;
510 /* When relaxing, we need to output a reloc for any .align directive
511 so that we can retain this alignment as we adjust opcode sizes. */
513 rl78_handle_align (fragS
* frag
)
516 && (frag
->fr_type
== rs_align
517 || frag
->fr_type
== rs_align_code
)
518 && frag
->fr_address
+ frag
->fr_fix
> 0
519 && frag
->fr_offset
> 0
520 && now_seg
!= bss_section
)
522 fix_new (frag
, frag
->fr_fix
, 0,
523 &abs_symbol
, RL78_RELAXA_ALIGN
+ frag
->fr_offset
,
524 0, BFD_RELOC_RL78_RELAX
);
525 /* For the purposes of relaxation, this relocation is attached
526 to the byte *after* the alignment - i.e. the byte that must
528 fix_new (frag
->fr_next
, 0, 0,
529 &abs_symbol
, RL78_RELAXA_ELIGN
+ frag
->fr_offset
,
530 0, BFD_RELOC_RL78_RELAX
);
535 md_atof (int type
, char * litP
, int * sizeP
)
537 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
541 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
546 #define APPEND(B, N_B) \
547 if (rl78_bytes.N_B) \
549 memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B); \
550 idx += rl78_bytes.N_B; \
555 md_assemble (char * str
)
558 fragS
* frag_then
= frag_now
;
564 /*printf("\033[32mASM: %s\033[0m\n", str);*/
566 dwarf2_emit_insn (0);
568 memset (& rl78_bytes
, 0, sizeof (rl78_bytes
));
570 rl78_lex_init (str
, str
+ strlen (str
));
574 /* This simplifies the relaxation code. */
575 if (rl78_bytes
.n_relax
|| rl78_bytes
.link_relax
)
577 int olen
= rl78_bytes
.n_prefix
+ rl78_bytes
.n_base
+ rl78_bytes
.n_ops
;
578 /* We do it this way because we want the frag to have the
579 rl78_bytes in it, which we initialize above. The extra bytes
581 bytes
= frag_more (olen
+ 3);
582 frag_then
= frag_now
;
583 frag_variant (rs_machine_dependent
,
584 olen
/* max_chars */,
590 frag_then
->fr_opcode
= bytes
;
591 frag_then
->fr_fix
= olen
+ (bytes
- frag_then
->fr_literal
);
592 frag_then
->fr_subtype
= olen
;
593 frag_then
->fr_var
= 0;
597 bytes
= frag_more (rl78_bytes
.n_prefix
+ rl78_bytes
.n_base
+ rl78_bytes
.n_ops
);
598 frag_then
= frag_now
;
601 APPEND (prefix
, n_prefix
);
602 APPEND (base
, n_base
);
605 if (rl78_bytes
.link_relax
)
609 f
= fix_new (frag_then
,
610 (char *) bytes
- frag_then
->fr_literal
,
613 rl78_bytes
.link_relax
| rl78_bytes
.n_fixups
,
615 BFD_RELOC_RL78_RELAX
);
616 frag_then
->tc_frag_data
->link_relax_fixP
= f
;
619 for (i
= 0; i
< rl78_bytes
.n_fixups
; i
++)
621 /* index: [nbytes][type] */
622 static int reloc_map
[5][4] =
625 { BFD_RELOC_8
, BFD_RELOC_8_PCREL
},
626 { BFD_RELOC_16
, BFD_RELOC_16_PCREL
},
627 { BFD_RELOC_24
, BFD_RELOC_24_PCREL
},
628 { BFD_RELOC_32
, BFD_RELOC_32_PCREL
},
632 idx
= rl78_bytes
.fixups
[i
].offset
/ 8;
633 rel
= reloc_map
[rl78_bytes
.fixups
[i
].nbits
/ 8][(int) rl78_bytes
.fixups
[i
].type
];
635 if (rl78_bytes
.fixups
[i
].reloc
)
636 rel
= rl78_bytes
.fixups
[i
].reloc
;
638 if (frag_then
->tc_frag_data
)
639 exp
= & frag_then
->tc_frag_data
->fixups
[i
].exp
;
641 exp
= & rl78_bytes
.fixups
[i
].exp
;
643 f
= fix_new_exp (frag_then
,
644 (char *) bytes
+ idx
- frag_then
->fr_literal
,
645 rl78_bytes
.fixups
[i
].nbits
/ 8,
647 rl78_bytes
.fixups
[i
].type
== RL78REL_PCREL
? 1 : 0,
649 if (frag_then
->tc_frag_data
)
650 frag_then
->tc_frag_data
->fixups
[i
].fixP
= f
;
655 rl78_cons_fix_new (fragS
* frag
,
660 bfd_reloc_code_real_type type
;
678 as_bad (_("unsupported constant size %d\n"), size
);
684 case BFD_RELOC_RL78_CODE
:
688 case BFD_RELOC_RL78_LO16
:
689 case BFD_RELOC_RL78_HI16
:
692 /* Fixups to assembler generated expressions do not use %hi or %lo. */
694 as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
699 case BFD_RELOC_RL78_HI8
:
702 /* Fixups to assembler generated expressions do not use %hi or %lo. */
704 as_bad (_("%%hi8 only applies to .byte"));
713 if (exp
->X_op
== O_subtract
&& exp
->X_op_symbol
)
715 if (size
!= 4 && size
!= 2 && size
!= 1)
716 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
718 type
= BFD_RELOC_RL78_DIFF
;
721 fixP
= fix_new_exp (frag
, where
, (int) size
, exp
, 0, type
);
724 /* These are intended to have values larger than the container,
725 since the backend puts only the portion we need in it.
726 However, we don't have a backend-specific reloc for them as
727 they're handled with complex relocations. */
728 case BFD_RELOC_RL78_LO16
:
729 case BFD_RELOC_RL78_HI16
:
730 case BFD_RELOC_RL78_HI8
:
731 fixP
->fx_no_overflow
= 1;
739 /*----------------------------------------------------------------------*/
740 /* To recap: we estimate everything based on md_estimate_size, then
741 adjust based on rl78_relax_frag. When it all settles, we call
742 md_convert frag to update the bytes. The relaxation types and
743 relocations are in fragP->tc_frag_data, which is a copy of that
746 Our scheme is as follows: fr_fix has the size of the smallest
747 opcode (like BRA.S). We store the number of total bytes we need in
748 fr_subtype. When we're done relaxing, we use fr_subtype and the
749 existing opcode bytes to figure out what actual opcode we need to
750 put in there. If the fixup isn't resolvable now, we use the
753 #define TRACE_RELAX 0
754 #define tprintf if (TRACE_RELAX) printf
770 /* We're looking for these types of relaxations:
772 BT 00110001 sbit0cc1 addr---- (cc is 10 (BF) or 01 (BT))
773 B~T 00110001 sbit0cc1 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
775 BT sfr 00110001 sbit0cc0 sfr----- addr----
776 BT ES: 00010001 00101110 sbit0cc1 addr----
779 B~C 110111cc 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
781 BH 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
782 B~H 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
785 /* Given the opcode bytes at OP, figure out which opcode it is and
786 return the type of opcode. We use this to re-encode the opcode as
787 a different size later. */
790 rl78_opcode_type (char * ops
)
792 unsigned char *op
= (unsigned char *)ops
;
795 && ((op
[1] & 0x0f) == 0x05
796 || (op
[1] & 0x0f) == 0x03))
800 && ((op
[1] & 0x0f) == 0x04
801 || (op
[1] & 0x0f) == 0x02))
806 && ((op
[2] & 0x0f) == 0x05
807 || (op
[2] & 0x0f) == 0x03))
810 if ((op
[0] & 0xfc) == 0xdc)
814 && (op
[1] & 0xef) == 0xc3)
818 && (op
[1] & 0xcf) == 0xc8)
822 && (op
[1] & 0xef) == 0xe3)
828 if ((op
[0] & 0xec) == 0xec)
834 /* Returns zero if *addrP has the target address. Else returns nonzero
835 if we cannot compute the target address yet. */
838 rl78_frag_fix_value (fragS
* fragP
,
846 rl78_bytesT
* b
= fragP
->tc_frag_data
;
847 expressionS
* exp
= & b
->fixups
[which
].exp
;
849 if (need_diff
&& exp
->X_op
!= O_subtract
)
852 if (exp
->X_add_symbol
)
854 if (S_FORCE_RELOC (exp
->X_add_symbol
, 1))
856 if (S_GET_SEGMENT (exp
->X_add_symbol
) != segment
)
858 addr
+= S_GET_VALUE (exp
->X_add_symbol
);
861 if (exp
->X_op_symbol
)
863 if (exp
->X_op
!= O_subtract
)
865 if (S_FORCE_RELOC (exp
->X_op_symbol
, 1))
867 if (S_GET_SEGMENT (exp
->X_op_symbol
) != segment
)
869 addr
-= S_GET_VALUE (exp
->X_op_symbol
);
873 addr
+= exp
->X_add_number
;
878 /* Estimate how big the opcode is after this relax pass. The return
879 value is the difference between fr_fix and the actual size. We
880 compute the total size in rl78_relax_frag and store it in fr_subtype,
881 so we only need to subtract fx_fix and return it. */
884 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
, segT segment ATTRIBUTE_UNUSED
)
889 /* This is the size of the opcode that's accounted for in fr_fix. */
890 opfixsize
= fragP
->fr_fix
- (fragP
->fr_opcode
- fragP
->fr_literal
);
891 /* This is the size of the opcode that isn't. */
892 delta
= (fragP
->fr_subtype
- opfixsize
);
894 tprintf (" -> opfixsize %d delta %d\n", opfixsize
, delta
);
898 /* Given the new addresses for this relax pass, figure out how big
899 each opcode must be. We store the total number of bytes needed in
900 fr_subtype. The return value is the difference between the size
901 after the last pass and the size after this pass, so we use the old
902 fr_subtype to calculate the difference. */
905 rl78_relax_frag (segT segment ATTRIBUTE_UNUSED
, fragS
* fragP
, long stretch
)
907 addressT addr0
, sym_addr
;
910 int oldsize
= fragP
->fr_subtype
;
911 int newsize
= oldsize
;
915 mypc
= fragP
->fr_address
+ (fragP
->fr_opcode
- fragP
->fr_literal
);
917 /* If we ever get more than one reloc per opcode, this is the one
921 optype
= rl78_opcode_type (fragP
->fr_opcode
);
922 /* Try to get the target address. */
923 if (rl78_frag_fix_value (fragP
, segment
, ri
, & addr0
,
924 fragP
->tc_frag_data
->relax
[ri
].type
!= RL78_RELAX_BRANCH
,
927 /* If we don't expect the linker to do relaxing, don't emit
928 expanded opcodes that only the linker will relax. */
930 return newsize
- oldsize
;
932 /* If we don't, we must use the maximum size for the linker. */
933 switch (fragP
->tc_frag_data
->relax
[ri
].type
)
935 case RL78_RELAX_BRANCH
:
961 fragP
->fr_subtype
= newsize
;
962 tprintf (" -> new %d old %d delta %d (external)\n", newsize
, oldsize
, newsize
-oldsize
);
963 return newsize
- oldsize
;
969 switch (fragP
->tc_frag_data
->relax
[ri
].type
)
971 case RL78_RELAX_BRANCH
:
972 disp
= (int) addr0
- (int) mypc
;
977 if (disp
>= -128 && (disp
- (oldsize
-2)) <= 127)
984 if (disp
>= -128 && (disp
- (oldsize
-3)) <= 127)
990 if (disp
>= -128 && (disp
- (oldsize
-1)) <= 127)
996 if (disp
>= -128 && (disp
- (oldsize
-2)) <= 127)
1011 /* This prevents infinite loops in align-heavy sources. */
1012 if (newsize
< oldsize
)
1014 if (fragP
->tc_frag_data
->times_shrank
> 10
1015 && fragP
->tc_frag_data
->times_grown
> 10)
1017 if (fragP
->tc_frag_data
->times_shrank
< 20)
1018 fragP
->tc_frag_data
->times_shrank
++;
1020 else if (newsize
> oldsize
)
1022 if (fragP
->tc_frag_data
->times_grown
< 20)
1023 fragP
->tc_frag_data
->times_grown
++;
1026 fragP
->fr_subtype
= newsize
;
1027 tprintf (" -> new %d old %d delta %d\n", newsize
, oldsize
, newsize
-oldsize
);
1028 return newsize
- oldsize
;
1031 /* This lets us test for the opcode type and the desired size in a
1032 switch statement. */
1033 #define OPCODE(type,size) ((type) * 16 + (size))
1035 /* Given the opcode stored in fr_opcode and the number of bytes we
1036 think we need, encode a new opcode. We stored a pointer to the
1037 fixup for this opcode in the tc_frag_data structure. If we can do
1038 the fixup here, we change the relocation type to "none" (we test
1039 for that in tc_gen_reloc) else we change it to the right type for
1040 the new (biggest) opcode. */
1043 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
1044 segT segment ATTRIBUTE_UNUSED
,
1045 fragS
* fragP ATTRIBUTE_UNUSED
)
1047 rl78_bytesT
* rl78b
= fragP
->tc_frag_data
;
1048 addressT addr0
, mypc
;
1050 int reloc_type
, reloc_adjust
;
1051 char * op
= fragP
->fr_opcode
;
1054 int fi
= (rl78b
->n_fixups
> 1) ? 1 : 0;
1055 fixS
* fix
= rl78b
->fixups
[fi
].fixP
;
1057 /* If we ever get more than one reloc per opcode, this is the one
1061 /* We used a new frag for this opcode, so the opcode address should
1062 be the frag address. */
1063 mypc
= fragP
->fr_address
+ (fragP
->fr_opcode
- fragP
->fr_literal
);
1064 tprintf ("\033[32mmypc: 0x%x\033[0m\n", (int)mypc
);
1066 /* Try to get the target address. If we fail here, we just use the
1068 if (rl78_frag_fix_value (fragP
, segment
, 0, & addr0
,
1069 fragP
->tc_frag_data
->relax
[ri
].type
!= RL78_RELAX_BRANCH
, 0))
1071 /* We don't know the target address. */
1075 tprintf ("unknown addr ? - %x = ?\n", (int)mypc
);
1079 /* We know the target address, and it's in addr0. */
1080 disp
= (int) addr0
- (int) mypc
;
1081 tprintf ("known addr %x - %x = %d\n", (int)addr0
, (int)mypc
, disp
);
1087 reloc_type
= BFD_RELOC_NONE
;
1090 switch (fragP
->tc_frag_data
->relax
[ri
].type
)
1092 case RL78_RELAX_BRANCH
:
1093 switch (OPCODE (rl78_opcode_type (fragP
->fr_opcode
), fragP
->fr_subtype
))
1096 case OPCODE (OT_bt
, 3): /* BT A,$ - no change. */
1099 reloc_type
= keep_reloc
? BFD_RELOC_8_PCREL
: BFD_RELOC_NONE
;
1102 case OPCODE (OT_bt
, 6): /* BT A,$ - long version. */
1104 op
[1] ^= 0x06; /* toggle conditional. */
1105 op
[2] = 3; /* displacement over long branch. */
1107 op
[3] = 0xEE; /* BR $!addr20 */
1108 op
[4] = disp
& 0xff;
1110 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1114 case OPCODE (OT_bt_sfr
, 4): /* BT PSW,$ - no change. */
1117 reloc_type
= keep_reloc
? BFD_RELOC_8_PCREL
: BFD_RELOC_NONE
;
1120 case OPCODE (OT_bt_sfr
, 7): /* BT PSW,$ - long version. */
1122 op
[1] ^= 0x06; /* toggle conditional. */
1123 op
[3] = 3; /* displacement over long branch. */
1125 op
[4] = 0xEE; /* BR $!addr20 */
1126 op
[5] = disp
& 0xff;
1128 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1132 case OPCODE (OT_bt_es
, 4): /* BT ES:[HL],$ - no change. */
1135 reloc_type
= keep_reloc
? BFD_RELOC_8_PCREL
: BFD_RELOC_NONE
;
1138 case OPCODE (OT_bt_es
, 7): /* BT PSW,$ - long version. */
1140 op
[2] ^= 0x06; /* toggle conditional. */
1141 op
[3] = 3; /* displacement over long branch. */
1143 op
[4] = 0xEE; /* BR $!addr20 */
1144 op
[5] = disp
& 0xff;
1146 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1150 case OPCODE (OT_bc
, 2): /* BC $ - no change. */
1153 reloc_type
= keep_reloc
? BFD_RELOC_8_PCREL
: BFD_RELOC_NONE
;
1156 case OPCODE (OT_bc
, 5): /* BC $ - long version. */
1158 op
[0] ^= 0x02; /* toggle conditional. */
1161 op
[2] = 0xEE; /* BR $!addr20 */
1162 op
[3] = disp
& 0xff;
1164 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1168 case OPCODE (OT_bh
, 3): /* BH $ - no change. */
1171 reloc_type
= keep_reloc
? BFD_RELOC_8_PCREL
: BFD_RELOC_NONE
;
1174 case OPCODE (OT_bh
, 6): /* BC $ - long version. */
1176 op
[1] ^= 0x10; /* toggle conditional. */
1179 op
[3] = 0xEE; /* BR $!addr20 */
1180 op
[4] = disp
& 0xff;
1182 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1186 case OPCODE (OT_sk
, 2): /* SK<cond> - no change */
1187 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1191 reloc_type
= fix
? fix
->fx_r_type
: BFD_RELOC_NONE
;
1197 if (rl78b
->n_fixups
)
1199 reloc_type
= fix
->fx_r_type
;
1205 if (rl78b
->n_fixups
)
1208 fix
->fx_r_type
= reloc_type
;
1209 fix
->fx_where
+= reloc_adjust
;
1212 case BFD_RELOC_NONE
:
1218 case BFD_RELOC_16_PCREL
:
1224 fragP
->fr_fix
= fragP
->fr_subtype
+ (fragP
->fr_opcode
- fragP
->fr_literal
);
1225 tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP
->fr_fix
,
1226 fragP
->fr_subtype
, fragP
->fr_opcode
, fragP
->fr_literal
);
1229 tprintf ("compare 0x%lx vs 0x%lx - 0x%lx = 0x%lx (%p)\n",
1230 (long)fragP
->fr_fix
,
1231 (long)fragP
->fr_next
->fr_address
, (long)fragP
->fr_address
,
1232 (long)(fragP
->fr_next
->fr_address
- fragP
->fr_address
),
1235 if (fragP
->fr_next
!= NULL
1236 && fragP
->fr_next
->fr_address
- fragP
->fr_address
!= fragP
->fr_fix
)
1237 as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP
,
1238 (long) fragP
->fr_fix
,
1239 (long) fragP
->fr_address
, (long) fragP
->fr_next
->fr_address
);
1242 /* End of relaxation code.
1243 ----------------------------------------------------------------------*/
1247 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
1249 static arelent
* reloc
[8];
1252 if (fixp
->fx_r_type
== BFD_RELOC_NONE
)
1258 if (fixp
->fx_r_type
== BFD_RELOC_RL78_RELAX
&& !linkrelax
)
1265 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
1267 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
1268 fixp
->fx_subsy
= NULL
;
1271 reloc
[0] = XNEW (arelent
);
1272 reloc
[0]->sym_ptr_ptr
= XNEW (asymbol
*);
1273 * reloc
[0]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1274 reloc
[0]->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1275 reloc
[0]->addend
= fixp
->fx_offset
;
1277 if (fixp
->fx_r_type
== BFD_RELOC_RL78_32_OP
1280 fixp
->fx_r_type
= BFD_RELOC_RL78_DIFF
;
1283 #define OPX(REL,SYM,ADD) \
1284 reloc[rp] = XNEW (arelent); \
1285 reloc[rp]->sym_ptr_ptr = XNEW (asymbol *); \
1286 reloc[rp]->howto = bfd_reloc_type_lookup (stdoutput, REL); \
1287 reloc[rp]->addend = ADD; \
1288 * reloc[rp]->sym_ptr_ptr = SYM; \
1289 reloc[rp]->address = fixp->fx_frag->fr_address + fixp->fx_where; \
1291 #define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
1293 /* FIXME: We cannot do the normal thing for an immediate value reloc,
1294 ie creating a RL78_SYM reloc in the *ABS* section with an offset
1295 equal to the immediate value we want to store. This fails because
1296 the reloc processing in bfd_perform_relocation and bfd_install_relocation
1297 will short circuit such relocs and never pass them on to the special
1298 reloc processing code. So instead we create a RL78_SYM reloc against
1299 the __rl78_abs__ symbol and arrange for the linker scripts to place
1300 this symbol at address 0. */
1301 #define OPIMM(IMM) OPX (BFD_RELOC_RL78_SYM, symbol_get_bfdsym (rl78_abs_sym), IMM)
1303 #define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
1304 #define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
1308 /* Certain BFD relocations cannot be translated directly into
1309 a single (non-Red Hat) RL78 relocation, but instead need
1310 multiple RL78 relocations - handle them here. */
1311 switch (fixp
->fx_r_type
)
1313 case BFD_RELOC_RL78_DIFF
:
1315 OPSYM (symbol_get_bfdsym (fixp
->fx_subsy
));
1318 switch (fixp
->fx_size
)
1332 case BFD_RELOC_RL78_NEG32
:
1338 case BFD_RELOC_RL78_CODE
:
1339 reloc
[0]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_RL78_16U
);
1343 case BFD_RELOC_RL78_LO16
:
1350 case BFD_RELOC_RL78_HI16
:
1357 case BFD_RELOC_RL78_HI8
:
1367 reloc
[0]->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1376 rl78_validate_fix_sub (struct fix
* f
)
1378 /* We permit the subtraction of two symbols in a few cases. */
1379 /* mov #sym1-sym2, R3 */
1380 if (f
->fx_r_type
== BFD_RELOC_RL78_32_OP
)
1382 /* .long sym1-sym2 */
1383 if (f
->fx_r_type
== BFD_RELOC_RL78_DIFF
1385 && (f
->fx_size
== 4 || f
->fx_size
== 2 || f
->fx_size
== 1))
1391 md_pcrel_from_section (fixS
* fixP
, segT sec
)
1395 if (fixP
->fx_addsy
!= NULL
1396 && (! S_IS_DEFINED (fixP
->fx_addsy
)
1397 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
1398 /* The symbol is undefined (or is defined but not in this section).
1399 Let the linker figure it out. */
1402 rv
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1403 switch (fixP
->fx_r_type
)
1405 case BFD_RELOC_8_PCREL
:
1408 case BFD_RELOC_16_PCREL
:
1418 md_apply_fix (struct fix
* f ATTRIBUTE_UNUSED
,
1419 valueT
* t ATTRIBUTE_UNUSED
,
1420 segT s ATTRIBUTE_UNUSED
)
1425 /* We always defer overflow checks for these to the linker, as it
1426 needs to do PLT stuff. */
1427 if (f
->fx_r_type
== BFD_RELOC_RL78_CODE
)
1428 f
->fx_no_overflow
= 1;
1430 if (f
->fx_addsy
&& S_FORCE_RELOC (f
->fx_addsy
, 1))
1432 if (f
->fx_subsy
&& S_FORCE_RELOC (f
->fx_subsy
, 1))
1435 op
= f
->fx_frag
->fr_literal
+ f
->fx_where
;
1436 val
= (unsigned long) * t
;
1438 if (f
->fx_addsy
== NULL
)
1441 switch (f
->fx_r_type
)
1443 case BFD_RELOC_NONE
:
1446 case BFD_RELOC_RL78_RELAX
:
1450 case BFD_RELOC_8_PCREL
:
1451 if ((long)val
< -128 || (long)val
> 127)
1452 as_bad_where (f
->fx_file
, f
->fx_line
,
1453 _("value of %ld too large for 8-bit branch"),
1457 case BFD_RELOC_RL78_SADDR
: /* We need to store the 8 LSB, but this works. */
1461 case BFD_RELOC_16_PCREL
:
1462 if ((long)val
< -32768 || (long)val
> 32767)
1463 as_bad_where (f
->fx_file
, f
->fx_line
,
1464 _("value of %ld too large for 16-bit branch"),
1468 case BFD_RELOC_RL78_CODE
:
1486 case BFD_RELOC_RL78_DIFF
:
1496 case BFD_RELOC_RL78_HI8
:
1501 case BFD_RELOC_RL78_HI16
:
1507 case BFD_RELOC_RL78_LO16
:
1513 as_bad (_("Unknown reloc in md_apply_fix: %s"),
1514 bfd_get_reloc_code_name (f
->fx_r_type
));
1521 md_section_align (segT segment
, valueT size
)
1523 int align
= bfd_section_alignment (segment
);
1524 return ((size
+ (1 << align
) - 1) & -(1 << align
));