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
,
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 {"mg10", no_argument
, NULL
, OPTION_G10
},
298 {"mg13", no_argument
, NULL
, OPTION_G13
},
299 {"mg14", no_argument
, NULL
, OPTION_G14
},
300 {"mrl78", no_argument
, NULL
, OPTION_G14
},
301 {"m32bit-doubles", no_argument
, NULL
, OPTION_32BIT_DOUBLES
},
302 {"m64bit-doubles", no_argument
, NULL
, OPTION_64BIT_DOUBLES
},
303 {NULL
, no_argument
, NULL
, 0}
305 size_t md_longopts_size
= sizeof (md_longopts
);
308 md_parse_option (int c
, char * arg ATTRIBUTE_UNUSED
)
317 elf_flags
&= ~ E_FLAG_RL78_CPU_MASK
;
318 elf_flags
|= E_FLAG_RL78_G10
;
322 elf_flags
&= ~ E_FLAG_RL78_CPU_MASK
;
323 elf_flags
|= E_FLAG_RL78_G13
;
327 elf_flags
&= ~ E_FLAG_RL78_CPU_MASK
;
328 elf_flags
|= E_FLAG_RL78_G14
;
331 case OPTION_32BIT_DOUBLES
:
332 elf_flags
&= ~ E_FLAG_RL78_64BIT_DOUBLES
;
335 case OPTION_64BIT_DOUBLES
:
336 elf_flags
|= E_FLAG_RL78_64BIT_DOUBLES
;
343 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
345 fprintf (stream
, _(" RL78 specific command line options:\n"));
346 fprintf (stream
, _(" --mg10 Enable support for G10 variant\n"));
347 fprintf (stream
, _(" --mg13 Selects the G13 core.\n"));
348 fprintf (stream
, _(" --mg14 Selects the G14 core [default]\n"));
349 fprintf (stream
, _(" --mrl78 Alias for --mg14\n"));
350 fprintf (stream
, _(" --m32bit-doubles [default]\n"));
351 fprintf (stream
, _(" --m64bit-doubles\n"));
355 s_bss (int ignore ATTRIBUTE_UNUSED
)
359 temp
= get_absolute_expression ();
360 subseg_set (bss_section
, (subsegT
) temp
);
361 demand_empty_rest_of_line ();
365 rl78_float_cons (int ignore ATTRIBUTE_UNUSED
)
367 if (elf_flags
& E_FLAG_RL78_64BIT_DOUBLES
)
368 return float_cons ('d');
369 return float_cons ('f');
372 /* The target specific pseudo-ops which we support. */
373 const pseudo_typeS md_pseudo_table
[] =
375 /* Our "standard" pseudos. */
376 { "double", rl78_float_cons
, 'd' },
378 { "3byte", cons
, 3 },
382 /* End of list marker. */
396 /* Set the ELF specific flags. */
398 rl78_elf_final_processing (void)
400 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;
403 /* Write a value out to the object file, using the appropriate endianness. */
405 md_number_to_chars (char * buf
, valueT val
, int n
)
407 number_to_chars_littleendian (buf
, val
, n
);
411 require_end_of_expr (char *fname
)
413 while (* input_line_pointer
== ' '
414 || * input_line_pointer
== '\t')
415 input_line_pointer
++;
417 if (! * input_line_pointer
418 || strchr ("\n\r,", * input_line_pointer
)
419 || strchr (comment_chars
, * input_line_pointer
)
420 || strchr (line_comment_chars
, * input_line_pointer
)
421 || strchr (line_separator_chars
, * input_line_pointer
))
424 as_bad (_("%%%s() must be outermost term in expression"), fname
);
434 { "code", BFD_RELOC_RL78_CODE
},
435 { "lo16", BFD_RELOC_RL78_LO16
},
436 { "hi16", BFD_RELOC_RL78_HI16
},
437 { "hi8", BFD_RELOC_RL78_HI8
},
442 md_operand (expressionS
* exp ATTRIBUTE_UNUSED
)
447 for (i
= 0; reloc_functions
[i
].fname
; i
++)
449 int flen
= strlen (reloc_functions
[i
].fname
);
451 if (input_line_pointer
[0] == '%'
452 && strncasecmp (input_line_pointer
+ 1, reloc_functions
[i
].fname
, flen
) == 0
453 && input_line_pointer
[flen
+ 1] == '(')
455 reloc
= reloc_functions
[i
].reloc
;
456 input_line_pointer
+= flen
+ 2;
464 if (* input_line_pointer
== ')')
465 input_line_pointer
++;
469 require_end_of_expr (reloc_functions
[i
].fname
);
473 rl78_frag_init (fragS
* fragP
)
475 if (rl78_bytes
.n_relax
|| rl78_bytes
.link_relax
)
477 fragP
->tc_frag_data
= malloc (sizeof (rl78_bytesT
));
478 memcpy (fragP
->tc_frag_data
, & rl78_bytes
, sizeof (rl78_bytesT
));
481 fragP
->tc_frag_data
= 0;
484 /* When relaxing, we need to output a reloc for any .align directive
485 so that we can retain this alignment as we adjust opcode sizes. */
487 rl78_handle_align (fragS
* frag
)
490 && (frag
->fr_type
== rs_align
491 || frag
->fr_type
== rs_align_code
)
492 && frag
->fr_address
+ frag
->fr_fix
> 0
493 && frag
->fr_offset
> 0
494 && now_seg
!= bss_section
)
496 fix_new (frag
, frag
->fr_fix
, 0,
497 &abs_symbol
, RL78_RELAXA_ALIGN
+ frag
->fr_offset
,
498 0, BFD_RELOC_RL78_RELAX
);
499 /* For the purposes of relaxation, this relocation is attached
500 to the byte *after* the alignment - i.e. the byte that must
502 fix_new (frag
->fr_next
, 0, 0,
503 &abs_symbol
, RL78_RELAXA_ELIGN
+ frag
->fr_offset
,
504 0, BFD_RELOC_RL78_RELAX
);
509 md_atof (int type
, char * litP
, int * sizeP
)
511 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
515 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
520 #define APPEND(B, N_B) \
521 if (rl78_bytes.N_B) \
523 memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B); \
524 idx += rl78_bytes.N_B; \
529 md_assemble (char * str
)
532 fragS
* frag_then
= frag_now
;
538 /*printf("\033[32mASM: %s\033[0m\n", str);*/
540 dwarf2_emit_insn (0);
542 memset (& rl78_bytes
, 0, sizeof (rl78_bytes
));
544 rl78_lex_init (str
, str
+ strlen (str
));
548 /* This simplifies the relaxation code. */
549 if (rl78_bytes
.n_relax
|| rl78_bytes
.link_relax
)
551 int olen
= rl78_bytes
.n_prefix
+ rl78_bytes
.n_base
+ rl78_bytes
.n_ops
;
552 /* We do it this way because we want the frag to have the
553 rl78_bytes in it, which we initialize above. The extra bytes
555 bytes
= frag_more (olen
+ 3);
556 frag_then
= frag_now
;
557 frag_variant (rs_machine_dependent
,
558 olen
/* max_chars */,
564 frag_then
->fr_opcode
= bytes
;
565 frag_then
->fr_fix
= olen
+ (bytes
- frag_then
->fr_literal
);
566 frag_then
->fr_subtype
= olen
;
567 frag_then
->fr_var
= 0;
571 bytes
= frag_more (rl78_bytes
.n_prefix
+ rl78_bytes
.n_base
+ rl78_bytes
.n_ops
);
572 frag_then
= frag_now
;
575 APPEND (prefix
, n_prefix
);
576 APPEND (base
, n_base
);
579 if (rl78_bytes
.link_relax
)
583 f
= fix_new (frag_then
,
584 (char *) bytes
- frag_then
->fr_literal
,
587 rl78_bytes
.link_relax
| rl78_bytes
.n_fixups
,
589 BFD_RELOC_RL78_RELAX
);
590 frag_then
->tc_frag_data
->link_relax_fixP
= f
;
593 for (i
= 0; i
< rl78_bytes
.n_fixups
; i
++)
595 /* index: [nbytes][type] */
596 static int reloc_map
[5][4] =
599 { BFD_RELOC_8
, BFD_RELOC_8_PCREL
},
600 { BFD_RELOC_16
, BFD_RELOC_16_PCREL
},
601 { BFD_RELOC_24
, BFD_RELOC_24_PCREL
},
602 { BFD_RELOC_32
, BFD_RELOC_32_PCREL
},
606 idx
= rl78_bytes
.fixups
[i
].offset
/ 8;
607 rel
= reloc_map
[rl78_bytes
.fixups
[i
].nbits
/ 8][(int) rl78_bytes
.fixups
[i
].type
];
609 if (rl78_bytes
.fixups
[i
].reloc
)
610 rel
= rl78_bytes
.fixups
[i
].reloc
;
612 if (frag_then
->tc_frag_data
)
613 exp
= & frag_then
->tc_frag_data
->fixups
[i
].exp
;
615 exp
= & rl78_bytes
.fixups
[i
].exp
;
617 f
= fix_new_exp (frag_then
,
618 (char *) bytes
+ idx
- frag_then
->fr_literal
,
619 rl78_bytes
.fixups
[i
].nbits
/ 8,
621 rl78_bytes
.fixups
[i
].type
== RL78REL_PCREL
? 1 : 0,
623 if (frag_then
->tc_frag_data
)
624 frag_then
->tc_frag_data
->fixups
[i
].fixP
= f
;
629 rl78_cons_fix_new (fragS
* frag
,
634 bfd_reloc_code_real_type type
;
652 as_bad (_("unsupported constant size %d\n"), size
);
658 case BFD_RELOC_RL78_CODE
:
662 case BFD_RELOC_RL78_LO16
:
663 case BFD_RELOC_RL78_HI16
:
665 as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
668 case BFD_RELOC_RL78_HI8
:
670 as_bad (_("%%hi8 only applies to .byte"));
677 if (exp
->X_op
== O_subtract
&& exp
->X_op_symbol
)
679 if (size
!= 4 && size
!= 2 && size
!= 1)
680 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
682 type
= BFD_RELOC_RL78_DIFF
;
685 fixP
= fix_new_exp (frag
, where
, (int) size
, exp
, 0, type
);
688 /* These are intended to have values larger than the container,
689 since the backend puts only the portion we need in it.
690 However, we don't have a backend-specific reloc for them as
691 they're handled with complex relocations. */
692 case BFD_RELOC_RL78_LO16
:
693 case BFD_RELOC_RL78_HI16
:
694 case BFD_RELOC_RL78_HI8
:
695 fixP
->fx_no_overflow
= 1;
703 /*----------------------------------------------------------------------*/
704 /* To recap: we estimate everything based on md_estimate_size, then
705 adjust based on rl78_relax_frag. When it all settles, we call
706 md_convert frag to update the bytes. The relaxation types and
707 relocations are in fragP->tc_frag_data, which is a copy of that
710 Our scheme is as follows: fr_fix has the size of the smallest
711 opcode (like BRA.S). We store the number of total bytes we need in
712 fr_subtype. When we're done relaxing, we use fr_subtype and the
713 existing opcode bytes to figure out what actual opcode we need to
714 put in there. If the fixup isn't resolvable now, we use the
717 #define TRACE_RELAX 0
718 #define tprintf if (TRACE_RELAX) printf
731 /* We're looking for these types of relaxations:
733 BT 00110001 sbit0cc1 addr---- (cc is 10 (BF) or 01 (BT))
734 B~T 00110001 sbit0cc1 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
736 BT sfr 00110001 sbit0cc0 sfr----- addr----
737 BT ES: 00010001 00101110 sbit0cc1 addr----
740 B~C 110111cc 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
742 BH 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
743 B~H 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
746 /* Given the opcode bytes at OP, figure out which opcode it is and
747 return the type of opcode. We use this to re-encode the opcode as
748 a different size later. */
751 rl78_opcode_type (char * op
)
754 && ((op
[1] & 0x0f) == 0x05
755 || (op
[1] & 0x0f) == 0x03))
759 && ((op
[1] & 0x0f) == 0x04
760 || (op
[1] & 0x0f) == 0x02))
765 && ((op
[2] & 0x0f) == 0x05
766 || (op
[2] & 0x0f) == 0x03))
769 if ((op
[0] & 0xfc) == 0xdc)
773 && (op
[1] & 0xef) == 0xc3)
779 /* Returns zero if *addrP has the target address. Else returns nonzero
780 if we cannot compute the target address yet. */
783 rl78_frag_fix_value (fragS
* fragP
,
791 rl78_bytesT
* b
= fragP
->tc_frag_data
;
792 expressionS
* exp
= & b
->fixups
[which
].exp
;
794 if (need_diff
&& exp
->X_op
!= O_subtract
)
797 if (exp
->X_add_symbol
)
799 if (S_FORCE_RELOC (exp
->X_add_symbol
, 1))
801 if (S_GET_SEGMENT (exp
->X_add_symbol
) != segment
)
803 addr
+= S_GET_VALUE (exp
->X_add_symbol
);
806 if (exp
->X_op_symbol
)
808 if (exp
->X_op
!= O_subtract
)
810 if (S_FORCE_RELOC (exp
->X_op_symbol
, 1))
812 if (S_GET_SEGMENT (exp
->X_op_symbol
) != segment
)
814 addr
-= S_GET_VALUE (exp
->X_op_symbol
);
818 addr
+= exp
->X_add_number
;
823 /* Estimate how big the opcode is after this relax pass. The return
824 value is the difference between fr_fix and the actual size. We
825 compute the total size in rl78_relax_frag and store it in fr_subtype,
826 sowe only need to subtract fx_fix and return it. */
829 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
, segT segment ATTRIBUTE_UNUSED
)
834 /* This is the size of the opcode that's accounted for in fr_fix. */
835 opfixsize
= fragP
->fr_fix
- (fragP
->fr_opcode
- fragP
->fr_literal
);
836 /* This is the size of the opcode that isn't. */
837 delta
= (fragP
->fr_subtype
- opfixsize
);
839 tprintf (" -> opfixsize %d delta %d\n", opfixsize
, delta
);
843 /* Given the new addresses for this relax pass, figure out how big
844 each opcode must be. We store the total number of bytes needed in
845 fr_subtype. The return value is the difference between the size
846 after the last pass and the size after this pass, so we use the old
847 fr_subtype to calculate the difference. */
850 rl78_relax_frag (segT segment ATTRIBUTE_UNUSED
, fragS
* fragP
, long stretch
)
852 addressT addr0
, sym_addr
;
855 int oldsize
= fragP
->fr_subtype
;
856 int newsize
= oldsize
;
860 mypc
= fragP
->fr_address
+ (fragP
->fr_opcode
- fragP
->fr_literal
);
862 /* If we ever get more than one reloc per opcode, this is the one
866 optype
= rl78_opcode_type (fragP
->fr_opcode
);
867 /* Try to get the target address. */
868 if (rl78_frag_fix_value (fragP
, segment
, ri
, & addr0
,
869 fragP
->tc_frag_data
->relax
[ri
].type
!= RL78_RELAX_BRANCH
,
872 /* If we don't, we must use the maximum size for the linker. */
873 switch (fragP
->tc_frag_data
->relax
[ri
].type
)
875 case RL78_RELAX_BRANCH
:
898 fragP
->fr_subtype
= newsize
;
899 tprintf (" -> new %d old %d delta %d (external)\n", newsize
, oldsize
, newsize
-oldsize
);
900 return newsize
- oldsize
;
906 switch (fragP
->tc_frag_data
->relax
[ri
].type
)
908 case RL78_RELAX_BRANCH
:
909 disp
= (int) addr0
- (int) mypc
;
914 if (disp
>= -128 && (disp
- (oldsize
-2)) <= 127)
921 if (disp
>= -128 && (disp
- (oldsize
-3)) <= 127)
927 if (disp
>= -128 && (disp
- (oldsize
-1)) <= 127)
933 if (disp
>= -128 && (disp
- (oldsize
-2)) <= 127)
945 /* This prevents infinite loops in align-heavy sources. */
946 if (newsize
< oldsize
)
948 if (fragP
->tc_frag_data
->times_shrank
> 10
949 && fragP
->tc_frag_data
->times_grown
> 10)
951 if (fragP
->tc_frag_data
->times_shrank
< 20)
952 fragP
->tc_frag_data
->times_shrank
++;
954 else if (newsize
> oldsize
)
956 if (fragP
->tc_frag_data
->times_grown
< 20)
957 fragP
->tc_frag_data
->times_grown
++;
960 fragP
->fr_subtype
= newsize
;
961 tprintf (" -> new %d old %d delta %d\n", newsize
, oldsize
, newsize
-oldsize
);
962 return newsize
- oldsize
;
965 /* This lets us test for the opcode type and the desired size in a
967 #define OPCODE(type,size) ((type) * 16 + (size))
969 /* Given the opcode stored in fr_opcode and the number of bytes we
970 think we need, encode a new opcode. We stored a pointer to the
971 fixup for this opcode in the tc_frag_data structure. If we can do
972 the fixup here, we change the relocation type to "none" (we test
973 for that in tc_gen_reloc) else we change it to the right type for
974 the new (biggest) opcode. */
977 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
978 segT segment ATTRIBUTE_UNUSED
,
979 fragS
* fragP ATTRIBUTE_UNUSED
)
981 rl78_bytesT
* rl78b
= fragP
->tc_frag_data
;
982 addressT addr0
, mypc
;
984 int reloc_type
, reloc_adjust
;
985 char * op
= fragP
->fr_opcode
;
988 int fi
= (rl78b
->n_fixups
> 1) ? 1 : 0;
989 fixS
* fix
= rl78b
->fixups
[fi
].fixP
;
991 /* If we ever get more than one reloc per opcode, this is the one
995 /* We used a new frag for this opcode, so the opcode address should
996 be the frag address. */
997 mypc
= fragP
->fr_address
+ (fragP
->fr_opcode
- fragP
->fr_literal
);
998 tprintf("\033[32mmypc: 0x%x\033[0m\n", (int)mypc
);
1000 /* Try to get the target address. If we fail here, we just use the
1002 if (rl78_frag_fix_value (fragP
, segment
, 0, & addr0
,
1003 fragP
->tc_frag_data
->relax
[ri
].type
!= RL78_RELAX_BRANCH
, 0))
1005 /* We don't know the target address. */
1009 tprintf ("unknown addr ? - %x = ?\n", (int)mypc
);
1013 /* We know the target address, and it's in addr0. */
1014 disp
= (int) addr0
- (int) mypc
;
1015 tprintf ("known addr %x - %x = %d\n", (int)addr0
, (int)mypc
, disp
);
1021 reloc_type
= BFD_RELOC_NONE
;
1024 switch (fragP
->tc_frag_data
->relax
[ri
].type
)
1026 case RL78_RELAX_BRANCH
:
1027 switch (OPCODE (rl78_opcode_type (fragP
->fr_opcode
), fragP
->fr_subtype
))
1030 case OPCODE (OT_bt
, 3): /* BT A,$ - no change. */
1035 case OPCODE (OT_bt
, 6): /* BT A,$ - long version. */
1037 op
[1] ^= 0x06; /* toggle conditional. */
1038 op
[2] = 3; /* displacement over long branch. */
1040 op
[3] = 0xEE; /* BR $!addr20 */
1041 op
[4] = disp
& 0xff;
1043 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1047 case OPCODE (OT_bt_sfr
, 4): /* BT PSW,$ - no change. */
1052 case OPCODE (OT_bt_sfr
, 7): /* BT PSW,$ - long version. */
1054 op
[1] ^= 0x06; /* toggle conditional. */
1055 op
[3] = 3; /* displacement over long branch. */
1057 op
[4] = 0xEE; /* BR $!addr20 */
1058 op
[5] = disp
& 0xff;
1060 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1064 case OPCODE (OT_bt_es
, 4): /* BT ES:[HL],$ - no change. */
1069 case OPCODE (OT_bt_es
, 7): /* BT PSW,$ - long version. */
1071 op
[2] ^= 0x06; /* toggle conditional. */
1072 op
[3] = 3; /* displacement over long branch. */
1074 op
[4] = 0xEE; /* BR $!addr20 */
1075 op
[5] = disp
& 0xff;
1077 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1081 case OPCODE (OT_bc
, 2): /* BC $ - no change. */
1086 case OPCODE (OT_bc
, 5): /* BC $ - long version. */
1088 op
[0] ^= 0x02; /* toggle conditional. */
1091 op
[2] = 0xEE; /* BR $!addr20 */
1092 op
[3] = disp
& 0xff;
1094 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1098 case OPCODE (OT_bh
, 3): /* BH $ - no change. */
1103 case OPCODE (OT_bh
, 6): /* BC $ - long version. */
1105 op
[1] ^= 0x10; /* toggle conditional. */
1108 op
[3] = 0xEE; /* BR $!addr20 */
1109 op
[4] = disp
& 0xff;
1111 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1116 fprintf(stderr
, "Missed case %d %d at 0x%lx\n",
1117 rl78_opcode_type (fragP
->fr_opcode
), fragP
->fr_subtype
, mypc
);
1124 if (rl78b
->n_fixups
)
1126 reloc_type
= fix
->fx_r_type
;
1132 if (rl78b
->n_fixups
)
1135 fix
->fx_r_type
= reloc_type
;
1136 fix
->fx_where
+= reloc_adjust
;
1139 case BFD_RELOC_NONE
:
1145 case BFD_RELOC_16_PCREL
:
1151 fragP
->fr_fix
= fragP
->fr_subtype
+ (fragP
->fr_opcode
- fragP
->fr_literal
);
1152 tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP
->fr_fix
,
1153 fragP
->fr_subtype
, fragP
->fr_opcode
, fragP
->fr_literal
);
1156 tprintf ("compare 0x%lx vs 0x%lx - 0x%lx = 0x%lx (%p)\n",
1157 (long)fragP
->fr_fix
,
1158 (long)fragP
->fr_next
->fr_address
, (long)fragP
->fr_address
,
1159 (long)(fragP
->fr_next
->fr_address
- fragP
->fr_address
),
1162 if (fragP
->fr_next
!= NULL
1163 && ((offsetT
) (fragP
->fr_next
->fr_address
- fragP
->fr_address
)
1165 as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP
,
1166 (long) fragP
->fr_fix
,
1167 (long) fragP
->fr_address
, (long) fragP
->fr_next
->fr_address
);
1170 /* End of relaxation code.
1171 ----------------------------------------------------------------------*/
1175 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
1177 static arelent
* reloc
[8];
1180 if (fixp
->fx_r_type
== BFD_RELOC_NONE
)
1187 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
1189 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
1190 fixp
->fx_subsy
= NULL
;
1193 reloc
[0] = (arelent
*) xmalloc (sizeof (arelent
));
1194 reloc
[0]->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1195 * reloc
[0]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1196 reloc
[0]->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1197 reloc
[0]->addend
= fixp
->fx_offset
;
1199 if (fixp
->fx_r_type
== BFD_RELOC_RL78_32_OP
1202 fixp
->fx_r_type
= BFD_RELOC_RL78_DIFF
;
1205 #define OPX(REL,SYM,ADD) \
1206 reloc[rp] = (arelent *) xmalloc (sizeof (arelent)); \
1207 reloc[rp]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); \
1208 reloc[rp]->howto = bfd_reloc_type_lookup (stdoutput, REL); \
1209 reloc[rp]->addend = ADD; \
1210 * reloc[rp]->sym_ptr_ptr = SYM; \
1211 reloc[rp]->address = fixp->fx_frag->fr_address + fixp->fx_where; \
1213 #define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
1214 #define OPIMM(IMM) OPX(BFD_RELOC_RL78_SYM, abs_symbol.bsym, IMM)
1215 #define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
1216 #define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
1220 /* Certain BFD relocations cannot be translated directly into
1221 a single (non-Red Hat) RL78 relocation, but instead need
1222 multiple RL78 relocations - handle them here. */
1223 switch (fixp
->fx_r_type
)
1225 case BFD_RELOC_RL78_DIFF
:
1227 OPSYM (symbol_get_bfdsym (fixp
->fx_subsy
));
1230 switch (fixp
->fx_size
)
1244 case BFD_RELOC_RL78_NEG32
:
1250 case BFD_RELOC_RL78_CODE
:
1251 reloc
[0]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_RL78_16U
);
1255 case BFD_RELOC_RL78_LO16
:
1262 case BFD_RELOC_RL78_HI16
:
1269 case BFD_RELOC_RL78_HI8
:
1279 reloc
[0]->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1288 rl78_validate_fix_sub (struct fix
* f
)
1290 /* We permit the subtraction of two symbols in a few cases. */
1291 /* mov #sym1-sym2, R3 */
1292 if (f
->fx_r_type
== BFD_RELOC_RL78_32_OP
)
1294 /* .long sym1-sym2 */
1295 if (f
->fx_r_type
== BFD_RELOC_RL78_DIFF
1297 && (f
->fx_size
== 4 || f
->fx_size
== 2 || f
->fx_size
== 1))
1303 md_pcrel_from_section (fixS
* fixP
, segT sec
)
1307 if (fixP
->fx_addsy
!= NULL
1308 && (! S_IS_DEFINED (fixP
->fx_addsy
)
1309 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
1310 /* The symbol is undefined (or is defined but not in this section).
1311 Let the linker figure it out. */
1314 rv
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1315 switch (fixP
->fx_r_type
)
1317 case BFD_RELOC_8_PCREL
:
1320 case BFD_RELOC_16_PCREL
:
1330 md_apply_fix (struct fix
* f ATTRIBUTE_UNUSED
,
1331 valueT
* t ATTRIBUTE_UNUSED
,
1332 segT s ATTRIBUTE_UNUSED
)
1337 if (f
->fx_addsy
&& S_FORCE_RELOC (f
->fx_addsy
, 1))
1339 if (f
->fx_subsy
&& S_FORCE_RELOC (f
->fx_subsy
, 1))
1342 op
= f
->fx_frag
->fr_literal
+ f
->fx_where
;
1343 val
= (unsigned long) * t
;
1345 switch (f
->fx_r_type
)
1347 case BFD_RELOC_NONE
:
1350 case BFD_RELOC_RL78_RELAX
:
1354 case BFD_RELOC_8_PCREL
:
1355 if ((long)val
< -128 || (long)val
> 127)
1356 as_bad_where (f
->fx_file
, f
->fx_line
,
1357 _("value of %ld too large for 8-bit branch"),
1364 case BFD_RELOC_16_PCREL
:
1365 if ((long)val
< -32768 || (long)val
> 32767)
1366 as_bad_where (f
->fx_file
, f
->fx_line
,
1367 _("value of %ld too large for 16-bit branch"),
1371 case BFD_RELOC_RL78_CODE
:
1389 case BFD_RELOC_RL78_DIFF
:
1399 case BFD_RELOC_RL78_HI8
:
1404 case BFD_RELOC_RL78_HI16
:
1410 case BFD_RELOC_RL78_LO16
:
1416 as_bad (_("Unknown reloc in md_apply_fix: %s"),
1417 bfd_get_reloc_code_name (f
->fx_r_type
));
1421 if (f
->fx_addsy
== NULL
)
1426 md_section_align (segT segment
, valueT size
)
1428 int align
= bfd_get_section_alignment (stdoutput
, segment
);
1429 return ((size
+ (1 << align
) - 1) & (-1 << align
));