1 /* tc-rl78.c -- Assembler for the Renesas RL78
2 Copyright (C) 2011-2014 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
22 #include "struc-symbol.h"
24 #include "safe-ctype.h"
25 #include "dwarf2dbg.h"
27 #include "elf/common.h"
29 #include "rl78-defs.h"
30 #include "filenames.h"
35 const char comment_chars
[] = ";";
36 /* Note that input_file.c hand checks for '#' at the beginning of the
37 first line of the input file. This is because the compiler outputs
38 #NO_APP at the beginning of its output. */
39 const char line_comment_chars
[] = "#";
40 /* Use something that isn't going to be needed by any expressions or
42 const char line_separator_chars
[] = "@";
44 const char EXP_CHARS
[] = "eE";
45 const char FLT_CHARS
[] = "dD";
47 /* ELF flags to set in the output file header. */
48 static int elf_flags
= 0;
50 /*------------------------------------------------------------------*/
52 char * rl78_lex_start
;
55 typedef struct rl78_bytesT
68 char type
; /* RL78REL_*. */
81 fixS
*link_relax_fixP
;
86 static rl78_bytesT rl78_bytes
;
89 rl78_relax (int type
, int pos
)
91 rl78_bytes
.relax
[rl78_bytes
.n_relax
].type
= type
;
92 rl78_bytes
.relax
[rl78_bytes
.n_relax
].field_pos
= pos
;
93 rl78_bytes
.relax
[rl78_bytes
.n_relax
].val_ofs
= rl78_bytes
.n_base
+ rl78_bytes
.n_ops
;
94 rl78_bytes
.n_relax
++;
98 rl78_linkrelax_addr16 (void)
100 rl78_bytes
.link_relax
|= RL78_RELAXA_ADDR16
;
104 rl78_linkrelax_branch (void)
106 rl78_bytes
.link_relax
|= RL78_RELAXA_BRA
;
110 rl78_fixup (expressionS exp
, int offsetbits
, int nbits
, int type
)
112 rl78_bytes
.fixups
[rl78_bytes
.n_fixups
].exp
= exp
;
113 rl78_bytes
.fixups
[rl78_bytes
.n_fixups
].offset
= offsetbits
;
114 rl78_bytes
.fixups
[rl78_bytes
.n_fixups
].nbits
= nbits
;
115 rl78_bytes
.fixups
[rl78_bytes
.n_fixups
].type
= type
;
116 rl78_bytes
.fixups
[rl78_bytes
.n_fixups
].reloc
= exp
.X_md
;
117 rl78_bytes
.n_fixups
++;
120 #define rl78_field_fixup(exp, offset, nbits, type) \
121 rl78_fixup (exp, offset + 8 * rl78_bytes.n_prefix), nbits, type)
123 #define rl78_op_fixup(exp, offset, nbits, type) \
124 rl78_fixup (exp, offset + 8 * (rl78_bytes.n_prefix + rl78_bytes.n_base), nbits, type)
129 rl78_bytes
.prefix
[0] = p
;
130 rl78_bytes
.n_prefix
= 1;
136 return rl78_bytes
.n_prefix
;
142 rl78_bytes
.base
[0] = b1
;
143 rl78_bytes
.n_base
= 1;
147 rl78_base2 (int b1
, int b2
)
149 rl78_bytes
.base
[0] = b1
;
150 rl78_bytes
.base
[1] = b2
;
151 rl78_bytes
.n_base
= 2;
155 rl78_base3 (int b1
, int b2
, int b3
)
157 rl78_bytes
.base
[0] = b1
;
158 rl78_bytes
.base
[1] = b2
;
159 rl78_bytes
.base
[2] = b3
;
160 rl78_bytes
.n_base
= 3;
164 rl78_base4 (int b1
, int b2
, int b3
, int b4
)
166 rl78_bytes
.base
[0] = b1
;
167 rl78_bytes
.base
[1] = b2
;
168 rl78_bytes
.base
[2] = b3
;
169 rl78_bytes
.base
[3] = b4
;
170 rl78_bytes
.n_base
= 4;
173 #define F_PRECISION 2
176 rl78_op (expressionS exp
, int nbytes
, int type
)
180 if ((exp
.X_op
== O_constant
|| exp
.X_op
== O_big
)
181 && type
!= RL78REL_PCREL
)
183 if (exp
.X_op
== O_big
&& exp
.X_add_number
<= 0)
186 char * ip
= rl78_bytes
.ops
+ rl78_bytes
.n_ops
;
188 gen_to_words (w
, F_PRECISION
, 8);
193 rl78_bytes
.n_ops
+= 4;
197 v
= exp
.X_add_number
;
200 rl78_bytes
.ops
[rl78_bytes
.n_ops
++] =v
& 0xff;
209 && exp
.X_md
== BFD_RELOC_RL78_CODE
)
213 && (exp
.X_md
== BFD_RELOC_RL78_LO16
214 || exp
.X_md
== BFD_RELOC_RL78_HI16
))
215 as_bad (_("16-bit relocation used in 8-bit operand"));
218 && exp
.X_md
== BFD_RELOC_RL78_HI8
)
219 as_bad (_("8-bit relocation used in 16-bit operand"));
221 rl78_op_fixup (exp
, rl78_bytes
.n_ops
* 8, nbytes
* 8, type
);
222 memset (rl78_bytes
.ops
+ rl78_bytes
.n_ops
, 0, nbytes
);
223 rl78_bytes
.n_ops
+= nbytes
;
227 /* This gets complicated when the field spans bytes, because fields
228 are numbered from the MSB of the first byte as zero, and bits are
229 stored LSB towards the LSB of the byte. Thus, a simple four-bit
230 insertion of 12 at position 4 of 0x00 yields: 0x0b. A three-bit
231 insertion of b'MXL at position 7 is like this:
233 - - - - - - - - - - - - - - - -
237 rl78_field (int val
, int pos
, int sz
)
244 if (val
< 0 || val
>= (1 << sz
))
245 as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val
, sz
);
250 if (val
< -(1 << (sz
- 1)) || val
>= (1 << (sz
- 1)))
251 as_bad (_("Value %d doesn't fit in signed %d-bit field"), val
, sz
);
254 /* This code points at 'M' in the above example. */
258 while (bitp
+ sz
> 8)
263 svalm
= val
>> (sz
- ssz
);
264 svalm
= svalm
& ((1 << ssz
) - 1);
265 svalm
= svalm
<< (8 - bitp
- ssz
);
266 gas_assert (bytep
< rl78_bytes
.n_base
);
267 rl78_bytes
.base
[bytep
] |= svalm
;
273 valm
= val
& ((1 << sz
) - 1);
274 valm
= valm
<< (8 - bitp
- sz
);
275 gas_assert (bytep
< rl78_bytes
.n_base
);
276 rl78_bytes
.base
[bytep
] |= valm
;
279 /*------------------------------------------------------------------*/
283 OPTION_RELAX
= OPTION_MD_BASE
,
285 OPTION_32BIT_DOUBLES
,
286 OPTION_64BIT_DOUBLES
,
289 #define RL78_SHORTOPTS ""
290 const char * md_shortopts
= RL78_SHORTOPTS
;
292 /* Assembler options. */
293 struct option md_longopts
[] =
295 {"relax", no_argument
, NULL
, OPTION_RELAX
},
296 {"mg10", no_argument
, NULL
, OPTION_G10
},
297 {"m32bit-doubles", no_argument
, NULL
, OPTION_32BIT_DOUBLES
},
298 {"m64bit-doubles", no_argument
, NULL
, OPTION_64BIT_DOUBLES
},
299 {NULL
, no_argument
, NULL
, 0}
301 size_t md_longopts_size
= sizeof (md_longopts
);
304 md_parse_option (int c
, char * arg ATTRIBUTE_UNUSED
)
313 elf_flags
|= E_FLAG_RL78_G10
;
316 case OPTION_32BIT_DOUBLES
:
317 elf_flags
&= ~ E_FLAG_RL78_64BIT_DOUBLES
;
320 case OPTION_64BIT_DOUBLES
:
321 elf_flags
|= E_FLAG_RL78_64BIT_DOUBLES
;
328 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
330 fprintf (stream
, _(" RL78 specific command line options:\n"));
331 fprintf (stream
, _(" --mg10 Enable support for G10 variant\n"));
332 fprintf (stream
, _(" --m32bit-doubles [default]\n"));
333 fprintf (stream
, _(" --m64bit-doubles\n"));
337 s_bss (int ignore ATTRIBUTE_UNUSED
)
341 temp
= get_absolute_expression ();
342 subseg_set (bss_section
, (subsegT
) temp
);
343 demand_empty_rest_of_line ();
347 rl78_float_cons (int ignore ATTRIBUTE_UNUSED
)
349 if (elf_flags
& E_FLAG_RL78_64BIT_DOUBLES
)
350 return float_cons ('d');
351 return float_cons ('f');
354 /* The target specific pseudo-ops which we support. */
355 const pseudo_typeS md_pseudo_table
[] =
357 /* Our "standard" pseudos. */
358 { "double", rl78_float_cons
, 'd' },
360 { "3byte", cons
, 3 },
364 /* End of list marker. */
378 /* Set the ELF specific flags. */
380 rl78_elf_final_processing (void)
382 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;
385 /* Write a value out to the object file, using the appropriate endianness. */
387 md_number_to_chars (char * buf
, valueT val
, int n
)
389 number_to_chars_littleendian (buf
, val
, n
);
393 require_end_of_expr (char *fname
)
395 while (* input_line_pointer
== ' '
396 || * input_line_pointer
== '\t')
397 input_line_pointer
++;
399 if (! * input_line_pointer
400 || strchr ("\n\r,", * input_line_pointer
)
401 || strchr (comment_chars
, * input_line_pointer
)
402 || strchr (line_comment_chars
, * input_line_pointer
)
403 || strchr (line_separator_chars
, * input_line_pointer
))
406 as_bad (_("%%%s() must be outermost term in expression"), fname
);
416 { "code", BFD_RELOC_RL78_CODE
},
417 { "lo16", BFD_RELOC_RL78_LO16
},
418 { "hi16", BFD_RELOC_RL78_HI16
},
419 { "hi8", BFD_RELOC_RL78_HI8
},
424 md_operand (expressionS
* exp ATTRIBUTE_UNUSED
)
429 for (i
= 0; reloc_functions
[i
].fname
; i
++)
431 int flen
= strlen (reloc_functions
[i
].fname
);
433 if (input_line_pointer
[0] == '%'
434 && strncasecmp (input_line_pointer
+ 1, reloc_functions
[i
].fname
, flen
) == 0
435 && input_line_pointer
[flen
+ 1] == '(')
437 reloc
= reloc_functions
[i
].reloc
;
438 input_line_pointer
+= flen
+ 2;
446 if (* input_line_pointer
== ')')
447 input_line_pointer
++;
451 require_end_of_expr (reloc_functions
[i
].fname
);
455 rl78_frag_init (fragS
* fragP
)
457 if (rl78_bytes
.n_relax
|| rl78_bytes
.link_relax
)
459 fragP
->tc_frag_data
= malloc (sizeof (rl78_bytesT
));
460 memcpy (fragP
->tc_frag_data
, & rl78_bytes
, sizeof (rl78_bytesT
));
463 fragP
->tc_frag_data
= 0;
466 /* When relaxing, we need to output a reloc for any .align directive
467 so that we can retain this alignment as we adjust opcode sizes. */
469 rl78_handle_align (fragS
* frag
)
472 && (frag
->fr_type
== rs_align
473 || frag
->fr_type
== rs_align_code
)
474 && frag
->fr_address
+ frag
->fr_fix
> 0
475 && frag
->fr_offset
> 0
476 && now_seg
!= bss_section
)
478 fix_new (frag
, frag
->fr_fix
, 0,
479 &abs_symbol
, RL78_RELAXA_ALIGN
+ frag
->fr_offset
,
480 0, BFD_RELOC_RL78_RELAX
);
481 /* For the purposes of relaxation, this relocation is attached
482 to the byte *after* the alignment - i.e. the byte that must
484 fix_new (frag
->fr_next
, 0, 0,
485 &abs_symbol
, RL78_RELAXA_ELIGN
+ frag
->fr_offset
,
486 0, BFD_RELOC_RL78_RELAX
);
491 md_atof (int type
, char * litP
, int * sizeP
)
493 return ieee_md_atof (type
, litP
, sizeP
, target_big_endian
);
497 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
502 #define APPEND(B, N_B) \
503 if (rl78_bytes.N_B) \
505 memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B); \
506 idx += rl78_bytes.N_B; \
511 md_assemble (char * str
)
514 fragS
* frag_then
= frag_now
;
520 /*printf("\033[32mASM: %s\033[0m\n", str);*/
522 dwarf2_emit_insn (0);
524 memset (& rl78_bytes
, 0, sizeof (rl78_bytes
));
526 rl78_lex_init (str
, str
+ strlen (str
));
530 /* This simplifies the relaxation code. */
531 if (rl78_bytes
.n_relax
|| rl78_bytes
.link_relax
)
533 int olen
= rl78_bytes
.n_prefix
+ rl78_bytes
.n_base
+ rl78_bytes
.n_ops
;
534 /* We do it this way because we want the frag to have the
535 rl78_bytes in it, which we initialize above. The extra bytes
537 bytes
= frag_more (olen
+ 3);
538 frag_then
= frag_now
;
539 frag_variant (rs_machine_dependent
,
540 olen
/* max_chars */,
546 frag_then
->fr_opcode
= bytes
;
547 frag_then
->fr_fix
= olen
+ (bytes
- frag_then
->fr_literal
);
548 frag_then
->fr_subtype
= olen
;
549 frag_then
->fr_var
= 0;
553 bytes
= frag_more (rl78_bytes
.n_prefix
+ rl78_bytes
.n_base
+ rl78_bytes
.n_ops
);
554 frag_then
= frag_now
;
557 APPEND (prefix
, n_prefix
);
558 APPEND (base
, n_base
);
561 if (rl78_bytes
.link_relax
)
565 f
= fix_new (frag_then
,
566 (char *) bytes
- frag_then
->fr_literal
,
569 rl78_bytes
.link_relax
| rl78_bytes
.n_fixups
,
571 BFD_RELOC_RL78_RELAX
);
572 frag_then
->tc_frag_data
->link_relax_fixP
= f
;
575 for (i
= 0; i
< rl78_bytes
.n_fixups
; i
++)
577 /* index: [nbytes][type] */
578 static int reloc_map
[5][4] =
581 { BFD_RELOC_8
, BFD_RELOC_8_PCREL
},
582 { BFD_RELOC_16
, BFD_RELOC_16_PCREL
},
583 { BFD_RELOC_24
, BFD_RELOC_24_PCREL
},
584 { BFD_RELOC_32
, BFD_RELOC_32_PCREL
},
588 idx
= rl78_bytes
.fixups
[i
].offset
/ 8;
589 rel
= reloc_map
[rl78_bytes
.fixups
[i
].nbits
/ 8][(int) rl78_bytes
.fixups
[i
].type
];
591 if (rl78_bytes
.fixups
[i
].reloc
)
592 rel
= rl78_bytes
.fixups
[i
].reloc
;
594 if (frag_then
->tc_frag_data
)
595 exp
= & frag_then
->tc_frag_data
->fixups
[i
].exp
;
597 exp
= & rl78_bytes
.fixups
[i
].exp
;
599 f
= fix_new_exp (frag_then
,
600 (char *) bytes
+ idx
- frag_then
->fr_literal
,
601 rl78_bytes
.fixups
[i
].nbits
/ 8,
603 rl78_bytes
.fixups
[i
].type
== RL78REL_PCREL
? 1 : 0,
605 if (frag_then
->tc_frag_data
)
606 frag_then
->tc_frag_data
->fixups
[i
].fixP
= f
;
611 rl78_cons_fix_new (fragS
* frag
,
616 bfd_reloc_code_real_type type
;
634 as_bad (_("unsupported constant size %d\n"), size
);
640 case BFD_RELOC_RL78_CODE
:
644 case BFD_RELOC_RL78_LO16
:
645 case BFD_RELOC_RL78_HI16
:
647 as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
650 case BFD_RELOC_RL78_HI8
:
652 as_bad (_("%%hi8 only applies to .byte"));
659 if (exp
->X_op
== O_subtract
&& exp
->X_op_symbol
)
661 if (size
!= 4 && size
!= 2 && size
!= 1)
662 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
664 type
= BFD_RELOC_RL78_DIFF
;
667 fixP
= fix_new_exp (frag
, where
, (int) size
, exp
, 0, type
);
670 /* These are intended to have values larger than the container,
671 since the backend puts only the portion we need in it.
672 However, we don't have a backend-specific reloc for them as
673 they're handled with complex relocations. */
674 case BFD_RELOC_RL78_LO16
:
675 case BFD_RELOC_RL78_HI16
:
676 case BFD_RELOC_RL78_HI8
:
677 fixP
->fx_no_overflow
= 1;
685 /*----------------------------------------------------------------------*/
686 /* To recap: we estimate everything based on md_estimate_size, then
687 adjust based on rl78_relax_frag. When it all settles, we call
688 md_convert frag to update the bytes. The relaxation types and
689 relocations are in fragP->tc_frag_data, which is a copy of that
692 Our scheme is as follows: fr_fix has the size of the smallest
693 opcode (like BRA.S). We store the number of total bytes we need in
694 fr_subtype. When we're done relaxing, we use fr_subtype and the
695 existing opcode bytes to figure out what actual opcode we need to
696 put in there. If the fixup isn't resolvable now, we use the
699 #define TRACE_RELAX 0
700 #define tprintf if (TRACE_RELAX) printf
713 /* We're looking for these types of relaxations:
715 BT 00110001 sbit0cc1 addr---- (cc is 10 (BF) or 01 (BT))
716 B~T 00110001 sbit0cc1 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
718 BT sfr 00110001 sbit0cc0 sfr----- addr----
719 BT ES: 00010001 00101110 sbit0cc1 addr----
722 B~C 110111cc 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
724 BH 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
725 B~H 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
728 /* Given the opcode bytes at OP, figure out which opcode it is and
729 return the type of opcode. We use this to re-encode the opcode as
730 a different size later. */
733 rl78_opcode_type (char * op
)
736 && ((op
[1] & 0x0f) == 0x05
737 || (op
[1] & 0x0f) == 0x03))
741 && ((op
[1] & 0x0f) == 0x04
742 || (op
[1] & 0x0f) == 0x02))
747 && ((op
[2] & 0x0f) == 0x05
748 || (op
[2] & 0x0f) == 0x03))
751 if ((op
[0] & 0xfc) == 0xdc)
755 && (op
[1] & 0xef) == 0xc3)
761 /* Returns zero if *addrP has the target address. Else returns nonzero
762 if we cannot compute the target address yet. */
765 rl78_frag_fix_value (fragS
* fragP
,
773 rl78_bytesT
* b
= fragP
->tc_frag_data
;
774 expressionS
* exp
= & b
->fixups
[which
].exp
;
776 if (need_diff
&& exp
->X_op
!= O_subtract
)
779 if (exp
->X_add_symbol
)
781 if (S_FORCE_RELOC (exp
->X_add_symbol
, 1))
783 if (S_GET_SEGMENT (exp
->X_add_symbol
) != segment
)
785 addr
+= S_GET_VALUE (exp
->X_add_symbol
);
788 if (exp
->X_op_symbol
)
790 if (exp
->X_op
!= O_subtract
)
792 if (S_FORCE_RELOC (exp
->X_op_symbol
, 1))
794 if (S_GET_SEGMENT (exp
->X_op_symbol
) != segment
)
796 addr
-= S_GET_VALUE (exp
->X_op_symbol
);
800 addr
+= exp
->X_add_number
;
805 /* Estimate how big the opcode is after this relax pass. The return
806 value is the difference between fr_fix and the actual size. We
807 compute the total size in rl78_relax_frag and store it in fr_subtype,
808 sowe only need to subtract fx_fix and return it. */
811 md_estimate_size_before_relax (fragS
* fragP ATTRIBUTE_UNUSED
, segT segment ATTRIBUTE_UNUSED
)
816 /* This is the size of the opcode that's accounted for in fr_fix. */
817 opfixsize
= fragP
->fr_fix
- (fragP
->fr_opcode
- fragP
->fr_literal
);
818 /* This is the size of the opcode that isn't. */
819 delta
= (fragP
->fr_subtype
- opfixsize
);
821 tprintf (" -> opfixsize %d delta %d\n", opfixsize
, delta
);
825 /* Given the new addresses for this relax pass, figure out how big
826 each opcode must be. We store the total number of bytes needed in
827 fr_subtype. The return value is the difference between the size
828 after the last pass and the size after this pass, so we use the old
829 fr_subtype to calculate the difference. */
832 rl78_relax_frag (segT segment ATTRIBUTE_UNUSED
, fragS
* fragP
, long stretch
)
834 addressT addr0
, sym_addr
;
837 int oldsize
= fragP
->fr_subtype
;
838 int newsize
= oldsize
;
842 mypc
= fragP
->fr_address
+ (fragP
->fr_opcode
- fragP
->fr_literal
);
844 /* If we ever get more than one reloc per opcode, this is the one
848 optype
= rl78_opcode_type (fragP
->fr_opcode
);
849 /* Try to get the target address. */
850 if (rl78_frag_fix_value (fragP
, segment
, ri
, & addr0
,
851 fragP
->tc_frag_data
->relax
[ri
].type
!= RL78_RELAX_BRANCH
,
854 /* If we don't, we must use the maximum size for the linker. */
855 switch (fragP
->tc_frag_data
->relax
[ri
].type
)
857 case RL78_RELAX_BRANCH
:
880 fragP
->fr_subtype
= newsize
;
881 tprintf (" -> new %d old %d delta %d (external)\n", newsize
, oldsize
, newsize
-oldsize
);
882 return newsize
- oldsize
;
888 switch (fragP
->tc_frag_data
->relax
[ri
].type
)
890 case RL78_RELAX_BRANCH
:
891 disp
= (int) addr0
- (int) mypc
;
896 if (disp
>= -128 && (disp
- (oldsize
-2)) <= 127)
903 if (disp
>= -128 && (disp
- (oldsize
-3)) <= 127)
909 if (disp
>= -128 && (disp
- (oldsize
-1)) <= 127)
915 if (disp
>= -128 && (disp
- (oldsize
-2)) <= 127)
927 /* This prevents infinite loops in align-heavy sources. */
928 if (newsize
< oldsize
)
930 if (fragP
->tc_frag_data
->times_shrank
> 10
931 && fragP
->tc_frag_data
->times_grown
> 10)
933 if (fragP
->tc_frag_data
->times_shrank
< 20)
934 fragP
->tc_frag_data
->times_shrank
++;
936 else if (newsize
> oldsize
)
938 if (fragP
->tc_frag_data
->times_grown
< 20)
939 fragP
->tc_frag_data
->times_grown
++;
942 fragP
->fr_subtype
= newsize
;
943 tprintf (" -> new %d old %d delta %d\n", newsize
, oldsize
, newsize
-oldsize
);
944 return newsize
- oldsize
;
947 /* This lets us test for the opcode type and the desired size in a
949 #define OPCODE(type,size) ((type) * 16 + (size))
951 /* Given the opcode stored in fr_opcode and the number of bytes we
952 think we need, encode a new opcode. We stored a pointer to the
953 fixup for this opcode in the tc_frag_data structure. If we can do
954 the fixup here, we change the relocation type to "none" (we test
955 for that in tc_gen_reloc) else we change it to the right type for
956 the new (biggest) opcode. */
959 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
960 segT segment ATTRIBUTE_UNUSED
,
961 fragS
* fragP ATTRIBUTE_UNUSED
)
963 rl78_bytesT
* rl78b
= fragP
->tc_frag_data
;
964 addressT addr0
, mypc
;
966 int reloc_type
, reloc_adjust
;
967 char * op
= fragP
->fr_opcode
;
970 int fi
= (rl78b
->n_fixups
> 1) ? 1 : 0;
971 fixS
* fix
= rl78b
->fixups
[fi
].fixP
;
973 /* If we ever get more than one reloc per opcode, this is the one
977 /* We used a new frag for this opcode, so the opcode address should
978 be the frag address. */
979 mypc
= fragP
->fr_address
+ (fragP
->fr_opcode
- fragP
->fr_literal
);
980 tprintf("\033[32mmypc: 0x%x\033[0m\n", (int)mypc
);
982 /* Try to get the target address. If we fail here, we just use the
984 if (rl78_frag_fix_value (fragP
, segment
, 0, & addr0
,
985 fragP
->tc_frag_data
->relax
[ri
].type
!= RL78_RELAX_BRANCH
, 0))
987 /* We don't know the target address. */
991 tprintf ("unknown addr ? - %x = ?\n", (int)mypc
);
995 /* We know the target address, and it's in addr0. */
996 disp
= (int) addr0
- (int) mypc
;
997 tprintf ("known addr %x - %x = %d\n", (int)addr0
, (int)mypc
, disp
);
1003 reloc_type
= BFD_RELOC_NONE
;
1006 switch (fragP
->tc_frag_data
->relax
[ri
].type
)
1008 case RL78_RELAX_BRANCH
:
1009 switch (OPCODE (rl78_opcode_type (fragP
->fr_opcode
), fragP
->fr_subtype
))
1012 case OPCODE (OT_bt
, 3): /* BT A,$ - no change. */
1017 case OPCODE (OT_bt
, 6): /* BT A,$ - long version. */
1019 op
[1] ^= 0x06; /* toggle conditional. */
1020 op
[2] = 3; /* displacement over long branch. */
1022 op
[3] = 0xEE; /* BR $!addr20 */
1023 op
[4] = disp
& 0xff;
1025 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1029 case OPCODE (OT_bt_sfr
, 4): /* BT PSW,$ - no change. */
1034 case OPCODE (OT_bt_sfr
, 7): /* BT PSW,$ - long version. */
1036 op
[1] ^= 0x06; /* toggle conditional. */
1037 op
[3] = 3; /* displacement over long branch. */
1039 op
[4] = 0xEE; /* BR $!addr20 */
1040 op
[5] = disp
& 0xff;
1042 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1046 case OPCODE (OT_bt_es
, 4): /* BT ES:[HL],$ - no change. */
1051 case OPCODE (OT_bt_es
, 7): /* BT PSW,$ - long version. */
1053 op
[2] ^= 0x06; /* toggle conditional. */
1054 op
[3] = 3; /* displacement over long branch. */
1056 op
[4] = 0xEE; /* BR $!addr20 */
1057 op
[5] = disp
& 0xff;
1059 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1063 case OPCODE (OT_bc
, 2): /* BC $ - no change. */
1068 case OPCODE (OT_bc
, 5): /* BC $ - long version. */
1070 op
[0] ^= 0x02; /* toggle conditional. */
1073 op
[2] = 0xEE; /* BR $!addr20 */
1074 op
[3] = disp
& 0xff;
1076 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1080 case OPCODE (OT_bh
, 3): /* BH $ - no change. */
1085 case OPCODE (OT_bh
, 6): /* BC $ - long version. */
1087 op
[1] ^= 0x10; /* toggle conditional. */
1090 op
[3] = 0xEE; /* BR $!addr20 */
1091 op
[4] = disp
& 0xff;
1093 reloc_type
= keep_reloc
? BFD_RELOC_16_PCREL
: BFD_RELOC_NONE
;
1098 fprintf(stderr
, "Missed case %d %d at 0x%lx\n",
1099 rl78_opcode_type (fragP
->fr_opcode
), fragP
->fr_subtype
, mypc
);
1106 if (rl78b
->n_fixups
)
1108 reloc_type
= fix
->fx_r_type
;
1114 if (rl78b
->n_fixups
)
1117 fix
->fx_r_type
= reloc_type
;
1118 fix
->fx_where
+= reloc_adjust
;
1121 case BFD_RELOC_NONE
:
1127 case BFD_RELOC_16_PCREL
:
1133 fragP
->fr_fix
= fragP
->fr_subtype
+ (fragP
->fr_opcode
- fragP
->fr_literal
);
1134 tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP
->fr_fix
,
1135 fragP
->fr_subtype
, fragP
->fr_opcode
, fragP
->fr_literal
);
1138 tprintf ("compare 0x%lx vs 0x%lx - 0x%lx = 0x%lx (%p)\n",
1139 (long)fragP
->fr_fix
,
1140 (long)fragP
->fr_next
->fr_address
, (long)fragP
->fr_address
,
1141 (long)(fragP
->fr_next
->fr_address
- fragP
->fr_address
),
1144 if (fragP
->fr_next
!= NULL
1145 && ((offsetT
) (fragP
->fr_next
->fr_address
- fragP
->fr_address
)
1147 as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP
,
1148 (long) fragP
->fr_fix
,
1149 (long) fragP
->fr_address
, (long) fragP
->fr_next
->fr_address
);
1152 /* End of relaxation code.
1153 ----------------------------------------------------------------------*/
1157 tc_gen_reloc (asection
* seg ATTRIBUTE_UNUSED
, fixS
* fixp
)
1159 static arelent
* reloc
[8];
1162 if (fixp
->fx_r_type
== BFD_RELOC_NONE
)
1169 && S_GET_SEGMENT (fixp
->fx_subsy
) == absolute_section
)
1171 fixp
->fx_offset
-= S_GET_VALUE (fixp
->fx_subsy
);
1172 fixp
->fx_subsy
= NULL
;
1175 reloc
[0] = (arelent
*) xmalloc (sizeof (arelent
));
1176 reloc
[0]->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1177 * reloc
[0]->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1178 reloc
[0]->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1179 reloc
[0]->addend
= fixp
->fx_offset
;
1181 if (fixp
->fx_r_type
== BFD_RELOC_RL78_32_OP
1184 fixp
->fx_r_type
= BFD_RELOC_RL78_DIFF
;
1187 #define OPX(REL,SYM,ADD) \
1188 reloc[rp] = (arelent *) xmalloc (sizeof (arelent)); \
1189 reloc[rp]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); \
1190 reloc[rp]->howto = bfd_reloc_type_lookup (stdoutput, REL); \
1191 reloc[rp]->addend = ADD; \
1192 * reloc[rp]->sym_ptr_ptr = SYM; \
1193 reloc[rp]->address = fixp->fx_frag->fr_address + fixp->fx_where; \
1195 #define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
1196 #define OPIMM(IMM) OPX(BFD_RELOC_RL78_SYM, abs_symbol.bsym, IMM)
1197 #define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
1198 #define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
1202 /* Certain BFD relocations cannot be translated directly into
1203 a single (non-Red Hat) RL78 relocation, but instead need
1204 multiple RL78 relocations - handle them here. */
1205 switch (fixp
->fx_r_type
)
1207 case BFD_RELOC_RL78_DIFF
:
1209 OPSYM (symbol_get_bfdsym (fixp
->fx_subsy
));
1212 switch (fixp
->fx_size
)
1226 case BFD_RELOC_RL78_NEG32
:
1232 case BFD_RELOC_RL78_CODE
:
1233 reloc
[0]->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_RL78_16U
);
1237 case BFD_RELOC_RL78_LO16
:
1244 case BFD_RELOC_RL78_HI16
:
1251 case BFD_RELOC_RL78_HI8
:
1261 reloc
[0]->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1270 rl78_validate_fix_sub (struct fix
* f
)
1272 /* We permit the subtraction of two symbols in a few cases. */
1273 /* mov #sym1-sym2, R3 */
1274 if (f
->fx_r_type
== BFD_RELOC_RL78_32_OP
)
1276 /* .long sym1-sym2 */
1277 if (f
->fx_r_type
== BFD_RELOC_RL78_DIFF
1279 && (f
->fx_size
== 4 || f
->fx_size
== 2 || f
->fx_size
== 1))
1285 md_pcrel_from_section (fixS
* fixP
, segT sec
)
1289 if (fixP
->fx_addsy
!= NULL
1290 && (! S_IS_DEFINED (fixP
->fx_addsy
)
1291 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
1292 /* The symbol is undefined (or is defined but not in this section).
1293 Let the linker figure it out. */
1296 rv
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1297 switch (fixP
->fx_r_type
)
1299 case BFD_RELOC_8_PCREL
:
1302 case BFD_RELOC_16_PCREL
:
1312 md_apply_fix (struct fix
* f ATTRIBUTE_UNUSED
,
1313 valueT
* t ATTRIBUTE_UNUSED
,
1314 segT s ATTRIBUTE_UNUSED
)
1319 if (f
->fx_addsy
&& S_FORCE_RELOC (f
->fx_addsy
, 1))
1321 if (f
->fx_subsy
&& S_FORCE_RELOC (f
->fx_subsy
, 1))
1324 op
= f
->fx_frag
->fr_literal
+ f
->fx_where
;
1325 val
= (unsigned long) * t
;
1327 switch (f
->fx_r_type
)
1329 case BFD_RELOC_NONE
:
1332 case BFD_RELOC_RL78_RELAX
:
1336 case BFD_RELOC_8_PCREL
:
1337 if ((long)val
< -128 || (long)val
> 127)
1338 as_bad_where (f
->fx_file
, f
->fx_line
,
1339 _("value of %ld too large for 8-bit branch"),
1346 case BFD_RELOC_16_PCREL
:
1347 if ((long)val
< -32768 || (long)val
> 32767)
1348 as_bad_where (f
->fx_file
, f
->fx_line
,
1349 _("value of %ld too large for 16-bit branch"),
1353 case BFD_RELOC_RL78_CODE
:
1365 case BFD_RELOC_RL78_DIFF
:
1372 case BFD_RELOC_RL78_HI8
:
1377 case BFD_RELOC_RL78_HI16
:
1383 case BFD_RELOC_RL78_LO16
:
1389 as_bad (_("Unknown reloc in md_apply_fix: %s"),
1390 bfd_get_reloc_code_name (f
->fx_r_type
));
1394 if (f
->fx_addsy
== NULL
)
1399 md_section_align (segT segment
, valueT size
)
1401 int align
= bfd_get_section_alignment (stdoutput
, segment
);
1402 return ((size
+ (1 << align
) - 1) & (-1 << align
));