Prevent the V850 assembler from generating an internal error if it is asked to
[deliverable/binutils-gdb.git] / gas / config / tc-rl78.c
CommitLineData
99c513f6 1/* tc-rl78.c -- Assembler for the Renesas RL78
4b95cf5c 2 Copyright (C) 2011-2014 Free Software Foundation, Inc.
99c513f6
DD
3
4 This file is part of GAS, the GNU Assembler.
5
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)
9 any later version.
10
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.
15
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
19 02110-1301, USA. */
20
21#include "as.h"
22#include "struc-symbol.h"
23#include "obstack.h"
24#include "safe-ctype.h"
25#include "dwarf2dbg.h"
26#include "libbfd.h"
27#include "elf/common.h"
28#include "elf/rl78.h"
29#include "rl78-defs.h"
30#include "filenames.h"
31#include "listing.h"
32#include "sb.h"
33#include "macro.h"
34
35const 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. */
39const char line_comment_chars[] = "#";
cbf1fdc9
DD
40/* Use something that isn't going to be needed by any expressions or
41 other syntax. */
42const char line_separator_chars[] = "@";
99c513f6
DD
43
44const char EXP_CHARS[] = "eE";
45const char FLT_CHARS[] = "dD";
46
4046d87a
NC
47/* ELF flags to set in the output file header. */
48static int elf_flags = 0;
49
99c513f6
DD
50/*------------------------------------------------------------------*/
51
52char * rl78_lex_start;
53char * rl78_lex_end;
54
55typedef struct rl78_bytesT
56{
57 char prefix[1];
58 int n_prefix;
59 char base[4];
60 int n_base;
61 char ops[8];
62 int n_ops;
63 struct
64 {
65 expressionS exp;
66 char offset;
67 char nbits;
68 char type; /* RL78REL_*. */
69 int reloc;
70 fixS * fixP;
71 } fixups[2];
72 int n_fixups;
73 struct
74 {
75 char type;
76 char field_pos;
77 char val_ofs;
78 } relax[2];
79 int n_relax;
80 int link_relax;
81 fixS *link_relax_fixP;
82 char times_grown;
83 char times_shrank;
84} rl78_bytesT;
85
86static rl78_bytesT rl78_bytes;
87
0c315784
DD
88void
89rl78_relax (int type, int pos)
90{
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 ++;
95}
96
9cea966c
DD
97void
98rl78_linkrelax_addr16 (void)
99{
100 rl78_bytes.link_relax |= RL78_RELAXA_ADDR16;
101}
102
103void
104rl78_linkrelax_branch (void)
105{
106 rl78_bytes.link_relax |= RL78_RELAXA_BRA;
107}
108
99c513f6
DD
109static void
110rl78_fixup (expressionS exp, int offsetbits, int nbits, int type)
111{
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 ++;
118}
119
120#define rl78_field_fixup(exp, offset, nbits, type) \
121 rl78_fixup (exp, offset + 8 * rl78_bytes.n_prefix), nbits, type)
122
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)
125
126void
127rl78_prefix (int p)
128{
129 rl78_bytes.prefix[0] = p;
130 rl78_bytes.n_prefix = 1;
131}
132
133int
134rl78_has_prefix ()
135{
136 return rl78_bytes.n_prefix;
137}
138
139void
140rl78_base1 (int b1)
141{
142 rl78_bytes.base[0] = b1;
143 rl78_bytes.n_base = 1;
144}
145
146void
147rl78_base2 (int b1, int b2)
148{
149 rl78_bytes.base[0] = b1;
150 rl78_bytes.base[1] = b2;
151 rl78_bytes.n_base = 2;
152}
153
154void
155rl78_base3 (int b1, int b2, int b3)
156{
157 rl78_bytes.base[0] = b1;
158 rl78_bytes.base[1] = b2;
159 rl78_bytes.base[2] = b3;
160 rl78_bytes.n_base = 3;
161}
162
163void
164rl78_base4 (int b1, int b2, int b3, int b4)
165{
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;
171}
172
173#define F_PRECISION 2
174
175void
176rl78_op (expressionS exp, int nbytes, int type)
177{
178 int v = 0;
179
180 if ((exp.X_op == O_constant || exp.X_op == O_big)
181 && type != RL78REL_PCREL)
182 {
183 if (exp.X_op == O_big && exp.X_add_number <= 0)
184 {
185 LITTLENUM_TYPE w[2];
186 char * ip = rl78_bytes.ops + rl78_bytes.n_ops;
187
188 gen_to_words (w, F_PRECISION, 8);
189 ip[3] = w[0] >> 8;
190 ip[2] = w[0];
191 ip[1] = w[1] >> 8;
192 ip[0] = w[1];
193 rl78_bytes.n_ops += 4;
194 }
195 else
196 {
197 v = exp.X_add_number;
198 while (nbytes)
199 {
200 rl78_bytes.ops[rl78_bytes.n_ops++] =v & 0xff;
201 v >>= 8;
202 nbytes --;
203 }
204 }
205 }
206 else
207 {
4107ae22
DD
208 if (nbytes > 2
209 && exp.X_md == BFD_RELOC_RL78_CODE)
210 exp.X_md = 0;
b3fe4307
NC
211
212 if (nbytes == 1
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"));
216
217 if (nbytes == 2
218 && exp.X_md == BFD_RELOC_RL78_HI8)
219 as_bad (_("8-bit relocation used in 16-bit operand"));
220
99c513f6
DD
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;
224 }
225}
226
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:
232
233 - - - - - - - - - - - - - - - -
234 M X L */
235
236void
237rl78_field (int val, int pos, int sz)
238{
239 int valm;
240 int bytep, bitp;
241
242 if (sz > 0)
243 {
244 if (val < 0 || val >= (1 << sz))
245 as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz);
246 }
247 else
248 {
249 sz = - 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);
252 }
253
254 /* This code points at 'M' in the above example. */
255 bytep = pos / 8;
256 bitp = pos % 8;
257
258 while (bitp + sz > 8)
259 {
260 int ssz = 8 - bitp;
261 int svalm;
262
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;
268
269 bitp = 0;
270 sz -= ssz;
271 bytep ++;
272 }
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;
277}
278
279/*------------------------------------------------------------------*/
280
9cea966c
DD
281enum options
282{
283 OPTION_RELAX = OPTION_MD_BASE,
4046d87a 284 OPTION_G10,
856ea05c
KP
285 OPTION_32BIT_DOUBLES,
286 OPTION_64BIT_DOUBLES,
9cea966c
DD
287};
288
99c513f6
DD
289#define RL78_SHORTOPTS ""
290const char * md_shortopts = RL78_SHORTOPTS;
291
292/* Assembler options. */
293struct option md_longopts[] =
294{
9cea966c 295 {"relax", no_argument, NULL, OPTION_RELAX},
4046d87a 296 {"mg10", no_argument, NULL, OPTION_G10},
856ea05c
KP
297 {"m32bit-doubles", no_argument, NULL, OPTION_32BIT_DOUBLES},
298 {"m64bit-doubles", no_argument, NULL, OPTION_64BIT_DOUBLES},
99c513f6
DD
299 {NULL, no_argument, NULL, 0}
300};
301size_t md_longopts_size = sizeof (md_longopts);
302
303int
9cea966c 304md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
99c513f6 305{
9cea966c
DD
306 switch (c)
307 {
308 case OPTION_RELAX:
309 linkrelax = 1;
310 return 1;
311
4046d87a
NC
312 case OPTION_G10:
313 elf_flags |= E_FLAG_RL78_G10;
314 return 1;
856ea05c
KP
315
316 case OPTION_32BIT_DOUBLES:
317 elf_flags &= ~ E_FLAG_RL78_64BIT_DOUBLES;
318 return 1;
319
320 case OPTION_64BIT_DOUBLES:
321 elf_flags |= E_FLAG_RL78_64BIT_DOUBLES;
322 return 1;
9cea966c 323 }
99c513f6
DD
324 return 0;
325}
326
327void
328md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
329{
856ea05c
KP
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"));
99c513f6
DD
334}
335
99c513f6
DD
336static void
337s_bss (int ignore ATTRIBUTE_UNUSED)
338{
339 int temp;
340
341 temp = get_absolute_expression ();
342 subseg_set (bss_section, (subsegT) temp);
343 demand_empty_rest_of_line ();
344}
345
856ea05c
KP
346static void
347rl78_float_cons (int ignore ATTRIBUTE_UNUSED)
348{
349 if (elf_flags & E_FLAG_RL78_64BIT_DOUBLES)
350 return float_cons ('d');
351 return float_cons ('f');
352}
353
99c513f6
DD
354/* The target specific pseudo-ops which we support. */
355const pseudo_typeS md_pseudo_table[] =
356{
856ea05c
KP
357 /* Our "standard" pseudos. */
358 { "double", rl78_float_cons, 'd' },
359 { "bss", s_bss, 0 },
360 { "3byte", cons, 3 },
361 { "int", cons, 4 },
362 { "word", cons, 4 },
99c513f6
DD
363
364 /* End of list marker. */
365 { NULL, NULL, 0 }
366};
367
368void
369md_begin (void)
370{
371}
372
373void
374rl78_md_end (void)
375{
376}
377
4046d87a
NC
378/* Set the ELF specific flags. */
379void
380rl78_elf_final_processing (void)
381{
382 elf_elfheader (stdoutput)->e_flags |= elf_flags;
383}
384
99c513f6
DD
385/* Write a value out to the object file, using the appropriate endianness. */
386void
387md_number_to_chars (char * buf, valueT val, int n)
388{
389 number_to_chars_littleendian (buf, val, n);
390}
391
c9d66558
DD
392static void
393require_end_of_expr (char *fname)
394{
395 while (* input_line_pointer == ' '
396 || * input_line_pointer == '\t')
397 input_line_pointer ++;
398
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))
404 return;
405
406 as_bad (_("%%%s() must be outermost term in expression"), fname);
407}
408
99c513f6
DD
409static struct
410{
411 char * fname;
412 int reloc;
413}
414reloc_functions[] =
415{
4107ae22 416 { "code", BFD_RELOC_RL78_CODE },
99c513f6
DD
417 { "lo16", BFD_RELOC_RL78_LO16 },
418 { "hi16", BFD_RELOC_RL78_HI16 },
419 { "hi8", BFD_RELOC_RL78_HI8 },
420 { 0, 0 }
421};
422
423void
424md_operand (expressionS * exp ATTRIBUTE_UNUSED)
425{
426 int reloc = 0;
427 int i;
428
429 for (i = 0; reloc_functions[i].fname; i++)
430 {
431 int flen = strlen (reloc_functions[i].fname);
432
433 if (input_line_pointer[0] == '%'
434 && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
435 && input_line_pointer[flen + 1] == '(')
436 {
437 reloc = reloc_functions[i].reloc;
438 input_line_pointer += flen + 2;
439 break;
440 }
441 }
442 if (reloc == 0)
443 return;
444
445 expression (exp);
446 if (* input_line_pointer == ')')
447 input_line_pointer ++;
448
449 exp->X_md = reloc;
c9d66558
DD
450
451 require_end_of_expr (reloc_functions[i].fname);
99c513f6
DD
452}
453
454void
455rl78_frag_init (fragS * fragP)
456{
9cea966c
DD
457 if (rl78_bytes.n_relax || rl78_bytes.link_relax)
458 {
459 fragP->tc_frag_data = malloc (sizeof (rl78_bytesT));
460 memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT));
461 }
462 else
463 fragP->tc_frag_data = 0;
464}
465
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. */
468void
469rl78_handle_align (fragS * frag)
470{
471 if (linkrelax
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)
477 {
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
483 remain aligned. */
484 fix_new (frag->fr_next, 0, 0,
485 &abs_symbol, RL78_RELAXA_ELIGN + frag->fr_offset,
486 0, BFD_RELOC_RL78_RELAX);
487 }
99c513f6
DD
488}
489
490char *
491md_atof (int type, char * litP, int * sizeP)
492{
493 return ieee_md_atof (type, litP, sizeP, target_big_endian);
494}
495
496symbolS *
497md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
498{
499 return NULL;
500}
501
502#define APPEND(B, N_B) \
503 if (rl78_bytes.N_B) \
504 { \
505 memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B); \
506 idx += rl78_bytes.N_B; \
507 }
508
509
510void
511md_assemble (char * str)
512{
513 char * bytes;
514 fragS * frag_then = frag_now;
515 int idx = 0;
516 int i;
517 int rel;
518 expressionS *exp;
519
520 /*printf("\033[32mASM: %s\033[0m\n", str);*/
521
522 dwarf2_emit_insn (0);
523
524 memset (& rl78_bytes, 0, sizeof (rl78_bytes));
525
526 rl78_lex_init (str, str + strlen (str));
527
528 rl78_parse ();
529
9cea966c 530 /* This simplifies the relaxation code. */
0c315784 531 if (rl78_bytes.n_relax || rl78_bytes.link_relax)
9cea966c
DD
532 {
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
0c315784
DD
535 rl78_bytes in it, which we initialize above. The extra bytes
536 are for relaxing. */
537 bytes = frag_more (olen + 3);
9cea966c
DD
538 frag_then = frag_now;
539 frag_variant (rs_machine_dependent,
540 olen /* max_chars */,
541 0 /* var */,
542 olen /* subtype */,
543 0 /* symbol */,
544 0 /* offset */,
545 0 /* opcode */);
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;
550 }
551 else
552 {
553 bytes = frag_more (rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops);
554 frag_then = frag_now;
555 }
99c513f6
DD
556
557 APPEND (prefix, n_prefix);
558 APPEND (base, n_base);
559 APPEND (ops, n_ops);
560
9cea966c
DD
561 if (rl78_bytes.link_relax)
562 {
563 fixS * f;
564
565 f = fix_new (frag_then,
566 (char *) bytes - frag_then->fr_literal,
567 0,
568 abs_section_sym,
569 rl78_bytes.link_relax | rl78_bytes.n_fixups,
570 0,
571 BFD_RELOC_RL78_RELAX);
572 frag_then->tc_frag_data->link_relax_fixP = f;
573 }
574
99c513f6
DD
575 for (i = 0; i < rl78_bytes.n_fixups; i ++)
576 {
577 /* index: [nbytes][type] */
578 static int reloc_map[5][4] =
579 {
580 { 0, 0 },
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 },
585 };
586 fixS * f;
587
588 idx = rl78_bytes.fixups[i].offset / 8;
589 rel = reloc_map [rl78_bytes.fixups[i].nbits / 8][(int) rl78_bytes.fixups[i].type];
590
591 if (rl78_bytes.fixups[i].reloc)
592 rel = rl78_bytes.fixups[i].reloc;
593
594 if (frag_then->tc_frag_data)
595 exp = & frag_then->tc_frag_data->fixups[i].exp;
596 else
597 exp = & rl78_bytes.fixups[i].exp;
598
599 f = fix_new_exp (frag_then,
600 (char *) bytes + idx - frag_then->fr_literal,
601 rl78_bytes.fixups[i].nbits / 8,
602 exp,
603 rl78_bytes.fixups[i].type == RL78REL_PCREL ? 1 : 0,
604 rel);
605 if (frag_then->tc_frag_data)
606 frag_then->tc_frag_data->fixups[i].fixP = f;
607 }
608}
609
610void
611rl78_cons_fix_new (fragS * frag,
612 int where,
613 int size,
614 expressionS * exp)
615{
616 bfd_reloc_code_real_type type;
c9d66558 617 fixS *fixP;
99c513f6
DD
618
619 switch (size)
620 {
621 case 1:
622 type = BFD_RELOC_8;
623 break;
624 case 2:
625 type = BFD_RELOC_16;
626 break;
627 case 3:
628 type = BFD_RELOC_24;
629 break;
630 case 4:
631 type = BFD_RELOC_32;
632 break;
633 default:
634 as_bad (_("unsupported constant size %d\n"), size);
635 return;
636 }
637
392ca752
DD
638 switch (exp->X_md)
639 {
4107ae22
DD
640 case BFD_RELOC_RL78_CODE:
641 if (size == 2)
642 type = exp->X_md;
643 break;
392ca752
DD
644 case BFD_RELOC_RL78_LO16:
645 case BFD_RELOC_RL78_HI16:
646 if (size != 2)
647 as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
648 type = exp->X_md;
649 break;
650 case BFD_RELOC_RL78_HI8:
651 if (size != 1)
652 as_bad (_("%%hi8 only applies to .byte"));
653 type = exp->X_md;
654 break;
655 default:
656 break;
657 }
658
99c513f6
DD
659 if (exp->X_op == O_subtract && exp->X_op_symbol)
660 {
661 if (size != 4 && size != 2 && size != 1)
662 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
663 else
664 type = BFD_RELOC_RL78_DIFF;
665 }
666
c9d66558
DD
667 fixP = fix_new_exp (frag, where, (int) size, exp, 0, type);
668 switch (exp->X_md)
669 {
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;
678 break;
679 default:
680 break;
681 }
99c513f6
DD
682}
683
0c315784
DD
684\f
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
690 rl78_bytes.
691
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
697 maximal size. */
698
699#define TRACE_RELAX 0
700#define tprintf if (TRACE_RELAX) printf
701
702
703typedef enum
704{
705 OT_other,
706 OT_bt,
707 OT_bt_sfr,
708 OT_bt_es,
709 OT_bc,
710 OT_bh
711} op_type_T;
712
713/* We're looking for these types of relaxations:
714
715 BT 00110001 sbit0cc1 addr---- (cc is 10 (BF) or 01 (BT))
716 B~T 00110001 sbit0cc1 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
717
718 BT sfr 00110001 sbit0cc0 sfr----- addr----
719 BT ES: 00010001 00101110 sbit0cc1 addr----
720
721 BC 110111cc addr----
722 B~C 110111cc 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
723
724 BH 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
725 B~H 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
726*/
727
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. */
731
732static op_type_T
733rl78_opcode_type (char * op)
734{
735 if (op[0] == 0x31
736 && ((op[1] & 0x0f) == 0x05
737 || (op[1] & 0x0f) == 0x03))
738 return OT_bt;
739
740 if (op[0] == 0x31
741 && ((op[1] & 0x0f) == 0x04
742 || (op[1] & 0x0f) == 0x02))
743 return OT_bt_sfr;
744
745 if (op[0] == 0x11
746 && op[1] == 0x31
747 && ((op[2] & 0x0f) == 0x05
748 || (op[2] & 0x0f) == 0x03))
749 return OT_bt_es;
750
751 if ((op[0] & 0xfc) == 0xdc)
752 return OT_bc;
753
754 if (op[0] == 0x61
755 && (op[1] & 0xef) == 0xc3)
756 return OT_bh;
757
758 return OT_other;
759}
760
761/* Returns zero if *addrP has the target address. Else returns nonzero
762 if we cannot compute the target address yet. */
763
764static int
765rl78_frag_fix_value (fragS * fragP,
766 segT segment,
767 int which,
768 addressT * addrP,
769 int need_diff,
770 addressT * sym_addr)
771{
772 addressT addr = 0;
773 rl78_bytesT * b = fragP->tc_frag_data;
774 expressionS * exp = & b->fixups[which].exp;
775
776 if (need_diff && exp->X_op != O_subtract)
777 return 1;
778
779 if (exp->X_add_symbol)
780 {
781 if (S_FORCE_RELOC (exp->X_add_symbol, 1))
782 return 1;
783 if (S_GET_SEGMENT (exp->X_add_symbol) != segment)
784 return 1;
785 addr += S_GET_VALUE (exp->X_add_symbol);
786 }
787
788 if (exp->X_op_symbol)
789 {
790 if (exp->X_op != O_subtract)
791 return 1;
792 if (S_FORCE_RELOC (exp->X_op_symbol, 1))
793 return 1;
794 if (S_GET_SEGMENT (exp->X_op_symbol) != segment)
795 return 1;
796 addr -= S_GET_VALUE (exp->X_op_symbol);
797 }
798 if (sym_addr)
799 * sym_addr = addr;
800 addr += exp->X_add_number;
801 * addrP = addr;
802 return 0;
803}
804
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. */
809
99c513f6
DD
810int
811md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
812{
0c315784
DD
813 int opfixsize;
814 int delta;
815
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);
820
821 tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta);
822 return delta;
823}
824
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. */
830
831int
832rl78_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
833{
834 addressT addr0, sym_addr;
835 addressT mypc;
836 int disp;
837 int oldsize = fragP->fr_subtype;
838 int newsize = oldsize;
839 op_type_T optype;
840 int ri;
841
842 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
843
844 /* If we ever get more than one reloc per opcode, this is the one
845 we're relaxing. */
846 ri = 0;
847
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,
852 & sym_addr))
853 {
854 /* If we don't, we must use the maximum size for the linker. */
855 switch (fragP->tc_frag_data->relax[ri].type)
856 {
857 case RL78_RELAX_BRANCH:
858 switch (optype)
859 {
860 case OT_bt:
861 newsize = 6;
862 break;
863 case OT_bt_sfr:
864 case OT_bt_es:
865 newsize = 7;
866 break;
867 case OT_bc:
868 newsize = 5;
869 break;
870 case OT_bh:
871 newsize = 6;
872 break;
873 case OT_other:
874 newsize = oldsize;
875 break;
876 }
877 break;
878
879 }
880 fragP->fr_subtype = newsize;
881 tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize);
882 return newsize - oldsize;
883 }
884
885 if (sym_addr > mypc)
886 addr0 += stretch;
887
888 switch (fragP->tc_frag_data->relax[ri].type)
889 {
890 case RL78_RELAX_BRANCH:
891 disp = (int) addr0 - (int) mypc;
892
893 switch (optype)
894 {
895 case OT_bt:
896 if (disp >= -128 && (disp - (oldsize-2)) <= 127)
897 newsize = 3;
898 else
899 newsize = 6;
900 break;
901 case OT_bt_sfr:
902 case OT_bt_es:
903 if (disp >= -128 && (disp - (oldsize-3)) <= 127)
904 newsize = 4;
905 else
906 newsize = 7;
907 break;
908 case OT_bc:
909 if (disp >= -128 && (disp - (oldsize-1)) <= 127)
910 newsize = 2;
911 else
912 newsize = 5;
913 break;
914 case OT_bh:
915 if (disp >= -128 && (disp - (oldsize-2)) <= 127)
916 newsize = 3;
917 else
918 newsize = 6;
919 break;
920 case OT_other:
921 newsize = oldsize;
922 break;
923 }
924 break;
925 }
926
927 /* This prevents infinite loops in align-heavy sources. */
928 if (newsize < oldsize)
929 {
930 if (fragP->tc_frag_data->times_shrank > 10
931 && fragP->tc_frag_data->times_grown > 10)
932 newsize = oldsize;
933 if (fragP->tc_frag_data->times_shrank < 20)
934 fragP->tc_frag_data->times_shrank ++;
935 }
936 else if (newsize > oldsize)
937 {
938 if (fragP->tc_frag_data->times_grown < 20)
939 fragP->tc_frag_data->times_grown ++;
940 }
941
942 fragP->fr_subtype = newsize;
943 tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
944 return newsize - oldsize;
945 }
946
947/* This lets us test for the opcode type and the desired size in a
948 switch statement. */
949#define OPCODE(type,size) ((type) * 16 + (size))
950
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. */
957
958void
959md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
960 segT segment ATTRIBUTE_UNUSED,
961 fragS * fragP ATTRIBUTE_UNUSED)
962{
963 rl78_bytesT * rl78b = fragP->tc_frag_data;
964 addressT addr0, mypc;
965 int disp;
966 int reloc_type, reloc_adjust;
967 char * op = fragP->fr_opcode;
968 int keep_reloc = 0;
969 int ri;
970 int fi = (rl78b->n_fixups > 1) ? 1 : 0;
971 fixS * fix = rl78b->fixups[fi].fixP;
972
973 /* If we ever get more than one reloc per opcode, this is the one
974 we're relaxing. */
975 ri = 0;
976
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);
981
982 /* Try to get the target address. If we fail here, we just use the
983 largest format. */
984 if (rl78_frag_fix_value (fragP, segment, 0, & addr0,
985 fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH, 0))
986 {
987 /* We don't know the target address. */
988 keep_reloc = 1;
989 addr0 = 0;
990 disp = 0;
991 tprintf ("unknown addr ? - %x = ?\n", (int)mypc);
992 }
993 else
994 {
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);
998 }
999
1000 if (linkrelax)
1001 keep_reloc = 1;
1002
1003 reloc_type = BFD_RELOC_NONE;
1004 reloc_adjust = 0;
1005
1006 switch (fragP->tc_frag_data->relax[ri].type)
1007 {
1008 case RL78_RELAX_BRANCH:
1009 switch (OPCODE (rl78_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
1010 {
1011
1012 case OPCODE (OT_bt, 3): /* BT A,$ - no change. */
1013 disp -= 3;
1014 op[2] = disp;
1015 break;
1016
1017 case OPCODE (OT_bt, 6): /* BT A,$ - long version. */
1018 disp -= 3;
1019 op[1] ^= 0x06; /* toggle conditional. */
1020 op[2] = 3; /* displacement over long branch. */
1021 disp -= 3;
1022 op[3] = 0xEE; /* BR $!addr20 */
1023 op[4] = disp & 0xff;
1024 op[5] = disp >> 8;
1025 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1026 reloc_adjust = 2;
1027 break;
1028
1029 case OPCODE (OT_bt_sfr, 4): /* BT PSW,$ - no change. */
1030 disp -= 4;
1031 op[3] = disp;
1032 break;
1033
1034 case OPCODE (OT_bt_sfr, 7): /* BT PSW,$ - long version. */
1035 disp -= 4;
1036 op[1] ^= 0x06; /* toggle conditional. */
1037 op[3] = 3; /* displacement over long branch. */
1038 disp -= 3;
1039 op[4] = 0xEE; /* BR $!addr20 */
1040 op[5] = disp & 0xff;
1041 op[6] = disp >> 8;
1042 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1043 reloc_adjust = 2;
1044 break;
1045
1046 case OPCODE (OT_bt_es, 4): /* BT ES:[HL],$ - no change. */
1047 disp -= 4;
1048 op[3] = disp;
1049 break;
1050
1051 case OPCODE (OT_bt_es, 7): /* BT PSW,$ - long version. */
1052 disp -= 4;
1053 op[2] ^= 0x06; /* toggle conditional. */
1054 op[3] = 3; /* displacement over long branch. */
1055 disp -= 3;
1056 op[4] = 0xEE; /* BR $!addr20 */
1057 op[5] = disp & 0xff;
1058 op[6] = disp >> 8;
1059 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1060 reloc_adjust = 2;
1061 break;
1062
1063 case OPCODE (OT_bc, 2): /* BC $ - no change. */
1064 disp -= 2;
1065 op[1] = disp;
1066 break;
1067
1068 case OPCODE (OT_bc, 5): /* BC $ - long version. */
1069 disp -= 2;
1070 op[0] ^= 0x02; /* toggle conditional. */
1071 op[1] = 3;
1072 disp -= 3;
1073 op[2] = 0xEE; /* BR $!addr20 */
1074 op[3] = disp & 0xff;
1075 op[4] = disp >> 8;
1076 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1077 reloc_adjust = 2;
1078 break;
1079
1080 case OPCODE (OT_bh, 3): /* BH $ - no change. */
1081 disp -= 3;
1082 op[2] = disp;
1083 break;
1084
1085 case OPCODE (OT_bh, 6): /* BC $ - long version. */
1086 disp -= 3;
1087 op[1] ^= 0x10; /* toggle conditional. */
1088 op[2] = 3;
1089 disp -= 3;
1090 op[3] = 0xEE; /* BR $!addr20 */
1091 op[4] = disp & 0xff;
1092 op[5] = disp >> 8;
1093 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1094 reloc_adjust = 2;
1095 break;
1096
1097 default:
1098 fprintf(stderr, "Missed case %d %d at 0x%lx\n",
1099 rl78_opcode_type (fragP->fr_opcode), fragP->fr_subtype, mypc);
1100 abort ();
1101
1102 }
1103 break;
1104
1105 default:
1106 if (rl78b->n_fixups)
1107 {
1108 reloc_type = fix->fx_r_type;
1109 reloc_adjust = 0;
1110 }
1111 break;
1112 }
1113
1114 if (rl78b->n_fixups)
1115 {
1116
1117 fix->fx_r_type = reloc_type;
1118 fix->fx_where += reloc_adjust;
1119 switch (reloc_type)
1120 {
1121 case BFD_RELOC_NONE:
1122 fix->fx_size = 0;
1123 break;
1124 case BFD_RELOC_8:
1125 fix->fx_size = 1;
1126 break;
1127 case BFD_RELOC_16_PCREL:
1128 fix->fx_size = 2;
1129 break;
1130 }
1131 }
1132
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);
1136 fragP->fr_var = 0;
1137
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),
1142 fragP->fr_next);
1143
1144 if (fragP->fr_next != NULL
1145 && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
1146 != fragP->fr_fix))
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);
99c513f6 1150}
9cea966c 1151
0c315784
DD
1152/* End of relaxation code.
1153 ----------------------------------------------------------------------*/
1154\f
1155
99c513f6
DD
1156arelent **
1157tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
1158{
1159 static arelent * reloc[8];
1160 int rp;
99c513f6
DD
1161
1162 if (fixp->fx_r_type == BFD_RELOC_NONE)
1163 {
1164 reloc[0] = NULL;
1165 return reloc;
1166 }
1167
1168 if (fixp->fx_subsy
1169 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1170 {
1171 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
1172 fixp->fx_subsy = NULL;
1173 }
1174
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;
1180
1181 if (fixp->fx_r_type == BFD_RELOC_RL78_32_OP
1182 && fixp->fx_subsy)
1183 {
1184 fixp->fx_r_type = BFD_RELOC_RL78_DIFF;
99c513f6
DD
1185 }
1186
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; \
1194 reloc[++rp] = NULL
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)
1199
1200 rp = 1;
1201
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)
1206 {
1207 case BFD_RELOC_RL78_DIFF:
1208 SYM0 ();
1209 OPSYM (symbol_get_bfdsym (fixp->fx_subsy));
1210 OP(OP_SUBTRACT);
1211
1212 switch (fixp->fx_size)
1213 {
1214 case 1:
1215 OP(ABS8);
1216 break;
1217 case 2:
1218 OP (ABS16);
1219 break;
1220 case 4:
1221 OP (ABS32);
1222 break;
1223 }
1224 break;
1225
1226 case BFD_RELOC_RL78_NEG32:
1227 SYM0 ();
1228 OP (OP_NEG);
1229 OP (ABS32);
1230 break;
1231
4107ae22 1232 case BFD_RELOC_RL78_CODE:
b3fe4307
NC
1233 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_16U);
1234 reloc[1] = NULL;
4107ae22
DD
1235 break;
1236
99c513f6
DD
1237 case BFD_RELOC_RL78_LO16:
1238 SYM0 ();
1239 OPIMM (0xffff);
1240 OP (OP_AND);
1241 OP (ABS16);
1242 break;
1243
1244 case BFD_RELOC_RL78_HI16:
1245 SYM0 ();
1246 OPIMM (16);
1247 OP (OP_SHRA);
1248 OP (ABS16);
1249 break;
1250
1251 case BFD_RELOC_RL78_HI8:
1252 SYM0 ();
1253 OPIMM (16);
1254 OP (OP_SHRA);
1255 OPIMM (0xff);
1256 OP (OP_AND);
1257 OP (ABS8);
1258 break;
1259
1260 default:
1261 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1262 reloc[1] = NULL;
1263 break;
1264 }
1265
1266 return reloc;
1267}
1268
1269int
1270rl78_validate_fix_sub (struct fix * f)
1271{
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)
1275 return 1;
1276 /* .long sym1-sym2 */
1277 if (f->fx_r_type == BFD_RELOC_RL78_DIFF
1278 && ! f->fx_pcrel
1279 && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
1280 return 1;
1281 return 0;
1282}
1283
1284long
1285md_pcrel_from_section (fixS * fixP, segT sec)
1286{
1287 long rv;
1288
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. */
1294 return 0;
1295
1296 rv = fixP->fx_frag->fr_address + fixP->fx_where;
1297 switch (fixP->fx_r_type)
1298 {
1299 case BFD_RELOC_8_PCREL:
1300 rv += 1;
1301 break;
1302 case BFD_RELOC_16_PCREL:
1303 rv += 2;
1304 break;
1305 default:
1306 break;
1307 }
1308 return rv;
1309}
1310
1311void
1312md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
1313 valueT * t ATTRIBUTE_UNUSED,
1314 segT s ATTRIBUTE_UNUSED)
1315{
1316 char * op;
1317 unsigned long val;
1318
1319 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
1320 return;
1321 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
1322 return;
1323
1324 op = f->fx_frag->fr_literal + f->fx_where;
1325 val = (unsigned long) * t;
1326
1327 switch (f->fx_r_type)
1328 {
1329 case BFD_RELOC_NONE:
1330 break;
1331
9cea966c
DD
1332 case BFD_RELOC_RL78_RELAX:
1333 f->fx_done = 1;
1334 break;
1335
99c513f6 1336 case BFD_RELOC_8_PCREL:
0a899fd5
DD
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"),
1340 val);
1341 /* Fall through. */
1342 case BFD_RELOC_8:
99c513f6
DD
1343 op[0] = val;
1344 break;
1345
99c513f6 1346 case BFD_RELOC_16_PCREL:
0a899fd5
DD
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"),
1350 val);
1351 /* Fall through. */
1352 case BFD_RELOC_16:
4107ae22 1353 case BFD_RELOC_RL78_CODE:
99c513f6
DD
1354 op[0] = val;
1355 op[1] = val >> 8;
1356 break;
1357
1358 case BFD_RELOC_24:
1359 op[0] = val;
1360 op[1] = val >> 8;
1361 op[2] = val >> 16;
1362 break;
1363
1364 case BFD_RELOC_32:
1365 case BFD_RELOC_RL78_DIFF:
1366 op[0] = val;
1367 op[1] = val >> 8;
1368 op[2] = val >> 16;
1369 op[3] = val >> 24;
1370 break;
1371
b3fe4307
NC
1372 case BFD_RELOC_RL78_HI8:
1373 val = val >> 16;
1374 op[0] = val;
1375 break;
1376
1377 case BFD_RELOC_RL78_HI16:
1378 val = val >> 16;
1379 op[0] = val;
1380 op[1] = val >> 8;
1381 break;
1382
1383 case BFD_RELOC_RL78_LO16:
1384 op[0] = val;
1385 op[1] = val >> 8;
1386 break;
1387
99c513f6
DD
1388 default:
1389 as_bad (_("Unknown reloc in md_apply_fix: %s"),
1390 bfd_get_reloc_code_name (f->fx_r_type));
1391 break;
1392 }
1393
1394 if (f->fx_addsy == NULL)
1395 f->fx_done = 1;
1396}
1397
1398valueT
1399md_section_align (segT segment, valueT size)
1400{
1401 int align = bfd_get_section_alignment (stdoutput, segment);
1402 return ((size + (1 << align) - 1) & (-1 << align));
1403}
This page took 0.200354 seconds and 4 git commands to generate.