]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-rl78.c
Add opcode relaxation for rl78-elf
[thirdparty/binutils-gdb.git] / gas / config / tc-rl78.c
1 /* tc-rl78.c -- Assembler for the Renesas RL78
2 Copyright (C) 2011-2014 Free Software Foundation, Inc.
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
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
41 other syntax. */
42 const char line_separator_chars[] = "@";
43
44 const char EXP_CHARS[] = "eE";
45 const char FLT_CHARS[] = "dD";
46
47 /* ELF flags to set in the output file header. */
48 static int elf_flags = 0;
49
50 /*------------------------------------------------------------------*/
51
52 char * rl78_lex_start;
53 char * rl78_lex_end;
54
55 typedef 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
86 static rl78_bytesT rl78_bytes;
87
88 void
89 rl78_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
97 void
98 rl78_linkrelax_addr16 (void)
99 {
100 rl78_bytes.link_relax |= RL78_RELAXA_ADDR16;
101 }
102
103 void
104 rl78_linkrelax_branch (void)
105 {
106 rl78_bytes.link_relax |= RL78_RELAXA_BRA;
107 }
108
109 static void
110 rl78_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
126 void
127 rl78_prefix (int p)
128 {
129 rl78_bytes.prefix[0] = p;
130 rl78_bytes.n_prefix = 1;
131 }
132
133 int
134 rl78_has_prefix ()
135 {
136 return rl78_bytes.n_prefix;
137 }
138
139 void
140 rl78_base1 (int b1)
141 {
142 rl78_bytes.base[0] = b1;
143 rl78_bytes.n_base = 1;
144 }
145
146 void
147 rl78_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
154 void
155 rl78_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
163 void
164 rl78_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
175 void
176 rl78_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 {
208 if (nbytes > 2
209 && exp.X_md == BFD_RELOC_RL78_CODE)
210 exp.X_md = 0;
211 rl78_op_fixup (exp, rl78_bytes.n_ops * 8, nbytes * 8, type);
212 memset (rl78_bytes.ops + rl78_bytes.n_ops, 0, nbytes);
213 rl78_bytes.n_ops += nbytes;
214 }
215 }
216
217 /* This gets complicated when the field spans bytes, because fields
218 are numbered from the MSB of the first byte as zero, and bits are
219 stored LSB towards the LSB of the byte. Thus, a simple four-bit
220 insertion of 12 at position 4 of 0x00 yields: 0x0b. A three-bit
221 insertion of b'MXL at position 7 is like this:
222
223 - - - - - - - - - - - - - - - -
224 M X L */
225
226 void
227 rl78_field (int val, int pos, int sz)
228 {
229 int valm;
230 int bytep, bitp;
231
232 if (sz > 0)
233 {
234 if (val < 0 || val >= (1 << sz))
235 as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz);
236 }
237 else
238 {
239 sz = - sz;
240 if (val < -(1 << (sz - 1)) || val >= (1 << (sz - 1)))
241 as_bad (_("Value %d doesn't fit in signed %d-bit field"), val, sz);
242 }
243
244 /* This code points at 'M' in the above example. */
245 bytep = pos / 8;
246 bitp = pos % 8;
247
248 while (bitp + sz > 8)
249 {
250 int ssz = 8 - bitp;
251 int svalm;
252
253 svalm = val >> (sz - ssz);
254 svalm = svalm & ((1 << ssz) - 1);
255 svalm = svalm << (8 - bitp - ssz);
256 gas_assert (bytep < rl78_bytes.n_base);
257 rl78_bytes.base[bytep] |= svalm;
258
259 bitp = 0;
260 sz -= ssz;
261 bytep ++;
262 }
263 valm = val & ((1 << sz) - 1);
264 valm = valm << (8 - bitp - sz);
265 gas_assert (bytep < rl78_bytes.n_base);
266 rl78_bytes.base[bytep] |= valm;
267 }
268
269 /*------------------------------------------------------------------*/
270
271 enum options
272 {
273 OPTION_RELAX = OPTION_MD_BASE,
274 OPTION_G10,
275 };
276
277 #define RL78_SHORTOPTS ""
278 const char * md_shortopts = RL78_SHORTOPTS;
279
280 /* Assembler options. */
281 struct option md_longopts[] =
282 {
283 {"relax", no_argument, NULL, OPTION_RELAX},
284 {"mg10", no_argument, NULL, OPTION_G10},
285 {NULL, no_argument, NULL, 0}
286 };
287 size_t md_longopts_size = sizeof (md_longopts);
288
289 int
290 md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
291 {
292 switch (c)
293 {
294 case OPTION_RELAX:
295 linkrelax = 1;
296 return 1;
297
298 case OPTION_G10:
299 elf_flags |= E_FLAG_RL78_G10;
300 return 1;
301 }
302 return 0;
303 }
304
305 void
306 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
307 {
308 }
309
310
311 static void
312 s_bss (int ignore ATTRIBUTE_UNUSED)
313 {
314 int temp;
315
316 temp = get_absolute_expression ();
317 subseg_set (bss_section, (subsegT) temp);
318 demand_empty_rest_of_line ();
319 }
320
321 /* The target specific pseudo-ops which we support. */
322 const pseudo_typeS md_pseudo_table[] =
323 {
324 /* Our "standard" pseudos. */
325 { "double", float_cons, 'd' },
326 { "bss", s_bss, 0 },
327 { "3byte", cons, 3 },
328 { "int", cons, 4 },
329 { "word", cons, 4 },
330
331 /* End of list marker. */
332 { NULL, NULL, 0 }
333 };
334
335 void
336 md_begin (void)
337 {
338 }
339
340 void
341 rl78_md_end (void)
342 {
343 }
344
345 /* Set the ELF specific flags. */
346 void
347 rl78_elf_final_processing (void)
348 {
349 elf_elfheader (stdoutput)->e_flags |= elf_flags;
350 }
351
352 /* Write a value out to the object file, using the appropriate endianness. */
353 void
354 md_number_to_chars (char * buf, valueT val, int n)
355 {
356 number_to_chars_littleendian (buf, val, n);
357 }
358
359 static void
360 require_end_of_expr (char *fname)
361 {
362 while (* input_line_pointer == ' '
363 || * input_line_pointer == '\t')
364 input_line_pointer ++;
365
366 if (! * input_line_pointer
367 || strchr ("\n\r,", * input_line_pointer)
368 || strchr (comment_chars, * input_line_pointer)
369 || strchr (line_comment_chars, * input_line_pointer)
370 || strchr (line_separator_chars, * input_line_pointer))
371 return;
372
373 as_bad (_("%%%s() must be outermost term in expression"), fname);
374 }
375
376 static struct
377 {
378 char * fname;
379 int reloc;
380 }
381 reloc_functions[] =
382 {
383 { "code", BFD_RELOC_RL78_CODE },
384 { "lo16", BFD_RELOC_RL78_LO16 },
385 { "hi16", BFD_RELOC_RL78_HI16 },
386 { "hi8", BFD_RELOC_RL78_HI8 },
387 { 0, 0 }
388 };
389
390 void
391 md_operand (expressionS * exp ATTRIBUTE_UNUSED)
392 {
393 int reloc = 0;
394 int i;
395
396 for (i = 0; reloc_functions[i].fname; i++)
397 {
398 int flen = strlen (reloc_functions[i].fname);
399
400 if (input_line_pointer[0] == '%'
401 && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
402 && input_line_pointer[flen + 1] == '(')
403 {
404 reloc = reloc_functions[i].reloc;
405 input_line_pointer += flen + 2;
406 break;
407 }
408 }
409 if (reloc == 0)
410 return;
411
412 expression (exp);
413 if (* input_line_pointer == ')')
414 input_line_pointer ++;
415
416 exp->X_md = reloc;
417
418 require_end_of_expr (reloc_functions[i].fname);
419 }
420
421 void
422 rl78_frag_init (fragS * fragP)
423 {
424 if (rl78_bytes.n_relax || rl78_bytes.link_relax)
425 {
426 fragP->tc_frag_data = malloc (sizeof (rl78_bytesT));
427 memcpy (fragP->tc_frag_data, & rl78_bytes, sizeof (rl78_bytesT));
428 }
429 else
430 fragP->tc_frag_data = 0;
431 }
432
433 /* When relaxing, we need to output a reloc for any .align directive
434 so that we can retain this alignment as we adjust opcode sizes. */
435 void
436 rl78_handle_align (fragS * frag)
437 {
438 if (linkrelax
439 && (frag->fr_type == rs_align
440 || frag->fr_type == rs_align_code)
441 && frag->fr_address + frag->fr_fix > 0
442 && frag->fr_offset > 0
443 && now_seg != bss_section)
444 {
445 fix_new (frag, frag->fr_fix, 0,
446 &abs_symbol, RL78_RELAXA_ALIGN + frag->fr_offset,
447 0, BFD_RELOC_RL78_RELAX);
448 /* For the purposes of relaxation, this relocation is attached
449 to the byte *after* the alignment - i.e. the byte that must
450 remain aligned. */
451 fix_new (frag->fr_next, 0, 0,
452 &abs_symbol, RL78_RELAXA_ELIGN + frag->fr_offset,
453 0, BFD_RELOC_RL78_RELAX);
454 }
455 }
456
457 char *
458 md_atof (int type, char * litP, int * sizeP)
459 {
460 return ieee_md_atof (type, litP, sizeP, target_big_endian);
461 }
462
463 symbolS *
464 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
465 {
466 return NULL;
467 }
468
469 #define APPEND(B, N_B) \
470 if (rl78_bytes.N_B) \
471 { \
472 memcpy (bytes + idx, rl78_bytes.B, rl78_bytes.N_B); \
473 idx += rl78_bytes.N_B; \
474 }
475
476
477 void
478 md_assemble (char * str)
479 {
480 char * bytes;
481 fragS * frag_then = frag_now;
482 int idx = 0;
483 int i;
484 int rel;
485 expressionS *exp;
486
487 /*printf("\033[32mASM: %s\033[0m\n", str);*/
488
489 dwarf2_emit_insn (0);
490
491 memset (& rl78_bytes, 0, sizeof (rl78_bytes));
492
493 rl78_lex_init (str, str + strlen (str));
494
495 rl78_parse ();
496
497 /* This simplifies the relaxation code. */
498 if (rl78_bytes.n_relax || rl78_bytes.link_relax)
499 {
500 int olen = rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops;
501 /* We do it this way because we want the frag to have the
502 rl78_bytes in it, which we initialize above. The extra bytes
503 are for relaxing. */
504 bytes = frag_more (olen + 3);
505 frag_then = frag_now;
506 frag_variant (rs_machine_dependent,
507 olen /* max_chars */,
508 0 /* var */,
509 olen /* subtype */,
510 0 /* symbol */,
511 0 /* offset */,
512 0 /* opcode */);
513 frag_then->fr_opcode = bytes;
514 frag_then->fr_fix = olen + (bytes - frag_then->fr_literal);
515 frag_then->fr_subtype = olen;
516 frag_then->fr_var = 0;
517 }
518 else
519 {
520 bytes = frag_more (rl78_bytes.n_prefix + rl78_bytes.n_base + rl78_bytes.n_ops);
521 frag_then = frag_now;
522 }
523
524 APPEND (prefix, n_prefix);
525 APPEND (base, n_base);
526 APPEND (ops, n_ops);
527
528 if (rl78_bytes.link_relax)
529 {
530 fixS * f;
531
532 f = fix_new (frag_then,
533 (char *) bytes - frag_then->fr_literal,
534 0,
535 abs_section_sym,
536 rl78_bytes.link_relax | rl78_bytes.n_fixups,
537 0,
538 BFD_RELOC_RL78_RELAX);
539 frag_then->tc_frag_data->link_relax_fixP = f;
540 }
541
542 for (i = 0; i < rl78_bytes.n_fixups; i ++)
543 {
544 /* index: [nbytes][type] */
545 static int reloc_map[5][4] =
546 {
547 { 0, 0 },
548 { BFD_RELOC_8, BFD_RELOC_8_PCREL },
549 { BFD_RELOC_16, BFD_RELOC_16_PCREL },
550 { BFD_RELOC_24, BFD_RELOC_24_PCREL },
551 { BFD_RELOC_32, BFD_RELOC_32_PCREL },
552 };
553 fixS * f;
554
555 idx = rl78_bytes.fixups[i].offset / 8;
556 rel = reloc_map [rl78_bytes.fixups[i].nbits / 8][(int) rl78_bytes.fixups[i].type];
557
558 if (rl78_bytes.fixups[i].reloc)
559 rel = rl78_bytes.fixups[i].reloc;
560
561 if (frag_then->tc_frag_data)
562 exp = & frag_then->tc_frag_data->fixups[i].exp;
563 else
564 exp = & rl78_bytes.fixups[i].exp;
565
566 f = fix_new_exp (frag_then,
567 (char *) bytes + idx - frag_then->fr_literal,
568 rl78_bytes.fixups[i].nbits / 8,
569 exp,
570 rl78_bytes.fixups[i].type == RL78REL_PCREL ? 1 : 0,
571 rel);
572 if (frag_then->tc_frag_data)
573 frag_then->tc_frag_data->fixups[i].fixP = f;
574 }
575 }
576
577 void
578 rl78_cons_fix_new (fragS * frag,
579 int where,
580 int size,
581 expressionS * exp)
582 {
583 bfd_reloc_code_real_type type;
584 fixS *fixP;
585
586 switch (size)
587 {
588 case 1:
589 type = BFD_RELOC_8;
590 break;
591 case 2:
592 type = BFD_RELOC_16;
593 break;
594 case 3:
595 type = BFD_RELOC_24;
596 break;
597 case 4:
598 type = BFD_RELOC_32;
599 break;
600 default:
601 as_bad (_("unsupported constant size %d\n"), size);
602 return;
603 }
604
605 switch (exp->X_md)
606 {
607 case BFD_RELOC_RL78_CODE:
608 if (size == 2)
609 type = exp->X_md;
610 break;
611 case BFD_RELOC_RL78_LO16:
612 case BFD_RELOC_RL78_HI16:
613 if (size != 2)
614 as_bad (_("%%hi16/%%lo16 only applies to .short or .hword"));
615 type = exp->X_md;
616 break;
617 case BFD_RELOC_RL78_HI8:
618 if (size != 1)
619 as_bad (_("%%hi8 only applies to .byte"));
620 type = exp->X_md;
621 break;
622 default:
623 break;
624 }
625
626 if (exp->X_op == O_subtract && exp->X_op_symbol)
627 {
628 if (size != 4 && size != 2 && size != 1)
629 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
630 else
631 type = BFD_RELOC_RL78_DIFF;
632 }
633
634 fixP = fix_new_exp (frag, where, (int) size, exp, 0, type);
635 switch (exp->X_md)
636 {
637 /* These are intended to have values larger than the container,
638 since the backend puts only the portion we need in it.
639 However, we don't have a backend-specific reloc for them as
640 they're handled with complex relocations. */
641 case BFD_RELOC_RL78_LO16:
642 case BFD_RELOC_RL78_HI16:
643 case BFD_RELOC_RL78_HI8:
644 fixP->fx_no_overflow = 1;
645 break;
646 default:
647 break;
648 }
649 }
650
651 \f
652 /*----------------------------------------------------------------------*/
653 /* To recap: we estimate everything based on md_estimate_size, then
654 adjust based on rl78_relax_frag. When it all settles, we call
655 md_convert frag to update the bytes. The relaxation types and
656 relocations are in fragP->tc_frag_data, which is a copy of that
657 rl78_bytes.
658
659 Our scheme is as follows: fr_fix has the size of the smallest
660 opcode (like BRA.S). We store the number of total bytes we need in
661 fr_subtype. When we're done relaxing, we use fr_subtype and the
662 existing opcode bytes to figure out what actual opcode we need to
663 put in there. If the fixup isn't resolvable now, we use the
664 maximal size. */
665
666 #define TRACE_RELAX 0
667 #define tprintf if (TRACE_RELAX) printf
668
669
670 typedef enum
671 {
672 OT_other,
673 OT_bt,
674 OT_bt_sfr,
675 OT_bt_es,
676 OT_bc,
677 OT_bh
678 } op_type_T;
679
680 /* We're looking for these types of relaxations:
681
682 BT 00110001 sbit0cc1 addr---- (cc is 10 (BF) or 01 (BT))
683 B~T 00110001 sbit0cc1 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
684
685 BT sfr 00110001 sbit0cc0 sfr----- addr----
686 BT ES: 00010001 00101110 sbit0cc1 addr----
687
688 BC 110111cc addr----
689 B~C 110111cc 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
690
691 BH 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
692 B~H 01100001 110c0011 00000011 11101110 pcrel16- -------- (BR $!pcrel20)
693 */
694
695 /* Given the opcode bytes at OP, figure out which opcode it is and
696 return the type of opcode. We use this to re-encode the opcode as
697 a different size later. */
698
699 static op_type_T
700 rl78_opcode_type (char * op)
701 {
702 if (op[0] == 0x31
703 && ((op[1] & 0x0f) == 0x05
704 || (op[1] & 0x0f) == 0x03))
705 return OT_bt;
706
707 if (op[0] == 0x31
708 && ((op[1] & 0x0f) == 0x04
709 || (op[1] & 0x0f) == 0x02))
710 return OT_bt_sfr;
711
712 if (op[0] == 0x11
713 && op[1] == 0x31
714 && ((op[2] & 0x0f) == 0x05
715 || (op[2] & 0x0f) == 0x03))
716 return OT_bt_es;
717
718 if ((op[0] & 0xfc) == 0xdc)
719 return OT_bc;
720
721 if (op[0] == 0x61
722 && (op[1] & 0xef) == 0xc3)
723 return OT_bh;
724
725 return OT_other;
726 }
727
728 /* Returns zero if *addrP has the target address. Else returns nonzero
729 if we cannot compute the target address yet. */
730
731 static int
732 rl78_frag_fix_value (fragS * fragP,
733 segT segment,
734 int which,
735 addressT * addrP,
736 int need_diff,
737 addressT * sym_addr)
738 {
739 addressT addr = 0;
740 rl78_bytesT * b = fragP->tc_frag_data;
741 expressionS * exp = & b->fixups[which].exp;
742
743 if (need_diff && exp->X_op != O_subtract)
744 return 1;
745
746 if (exp->X_add_symbol)
747 {
748 if (S_FORCE_RELOC (exp->X_add_symbol, 1))
749 return 1;
750 if (S_GET_SEGMENT (exp->X_add_symbol) != segment)
751 return 1;
752 addr += S_GET_VALUE (exp->X_add_symbol);
753 }
754
755 if (exp->X_op_symbol)
756 {
757 if (exp->X_op != O_subtract)
758 return 1;
759 if (S_FORCE_RELOC (exp->X_op_symbol, 1))
760 return 1;
761 if (S_GET_SEGMENT (exp->X_op_symbol) != segment)
762 return 1;
763 addr -= S_GET_VALUE (exp->X_op_symbol);
764 }
765 if (sym_addr)
766 * sym_addr = addr;
767 addr += exp->X_add_number;
768 * addrP = addr;
769 return 0;
770 }
771
772 /* Estimate how big the opcode is after this relax pass. The return
773 value is the difference between fr_fix and the actual size. We
774 compute the total size in rl78_relax_frag and store it in fr_subtype,
775 sowe only need to subtract fx_fix and return it. */
776
777 int
778 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
779 {
780 int opfixsize;
781 int delta;
782
783 /* This is the size of the opcode that's accounted for in fr_fix. */
784 opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal);
785 /* This is the size of the opcode that isn't. */
786 delta = (fragP->fr_subtype - opfixsize);
787
788 tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta);
789 return delta;
790 }
791
792 /* Given the new addresses for this relax pass, figure out how big
793 each opcode must be. We store the total number of bytes needed in
794 fr_subtype. The return value is the difference between the size
795 after the last pass and the size after this pass, so we use the old
796 fr_subtype to calculate the difference. */
797
798 int
799 rl78_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
800 {
801 addressT addr0, sym_addr;
802 addressT mypc;
803 int disp;
804 int oldsize = fragP->fr_subtype;
805 int newsize = oldsize;
806 op_type_T optype;
807 int ri;
808
809 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
810
811 /* If we ever get more than one reloc per opcode, this is the one
812 we're relaxing. */
813 ri = 0;
814
815 optype = rl78_opcode_type (fragP->fr_opcode);
816 /* Try to get the target address. */
817 if (rl78_frag_fix_value (fragP, segment, ri, & addr0,
818 fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH,
819 & sym_addr))
820 {
821 /* If we don't, we must use the maximum size for the linker. */
822 switch (fragP->tc_frag_data->relax[ri].type)
823 {
824 case RL78_RELAX_BRANCH:
825 switch (optype)
826 {
827 case OT_bt:
828 newsize = 6;
829 break;
830 case OT_bt_sfr:
831 case OT_bt_es:
832 newsize = 7;
833 break;
834 case OT_bc:
835 newsize = 5;
836 break;
837 case OT_bh:
838 newsize = 6;
839 break;
840 case OT_other:
841 newsize = oldsize;
842 break;
843 }
844 break;
845
846 }
847 fragP->fr_subtype = newsize;
848 tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize);
849 return newsize - oldsize;
850 }
851
852 if (sym_addr > mypc)
853 addr0 += stretch;
854
855 switch (fragP->tc_frag_data->relax[ri].type)
856 {
857 case RL78_RELAX_BRANCH:
858 disp = (int) addr0 - (int) mypc;
859
860 switch (optype)
861 {
862 case OT_bt:
863 if (disp >= -128 && (disp - (oldsize-2)) <= 127)
864 newsize = 3;
865 else
866 newsize = 6;
867 break;
868 case OT_bt_sfr:
869 case OT_bt_es:
870 if (disp >= -128 && (disp - (oldsize-3)) <= 127)
871 newsize = 4;
872 else
873 newsize = 7;
874 break;
875 case OT_bc:
876 if (disp >= -128 && (disp - (oldsize-1)) <= 127)
877 newsize = 2;
878 else
879 newsize = 5;
880 break;
881 case OT_bh:
882 if (disp >= -128 && (disp - (oldsize-2)) <= 127)
883 newsize = 3;
884 else
885 newsize = 6;
886 break;
887 case OT_other:
888 newsize = oldsize;
889 break;
890 }
891 break;
892 }
893
894 /* This prevents infinite loops in align-heavy sources. */
895 if (newsize < oldsize)
896 {
897 if (fragP->tc_frag_data->times_shrank > 10
898 && fragP->tc_frag_data->times_grown > 10)
899 newsize = oldsize;
900 if (fragP->tc_frag_data->times_shrank < 20)
901 fragP->tc_frag_data->times_shrank ++;
902 }
903 else if (newsize > oldsize)
904 {
905 if (fragP->tc_frag_data->times_grown < 20)
906 fragP->tc_frag_data->times_grown ++;
907 }
908
909 fragP->fr_subtype = newsize;
910 tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
911 return newsize - oldsize;
912 }
913
914 /* This lets us test for the opcode type and the desired size in a
915 switch statement. */
916 #define OPCODE(type,size) ((type) * 16 + (size))
917
918 /* Given the opcode stored in fr_opcode and the number of bytes we
919 think we need, encode a new opcode. We stored a pointer to the
920 fixup for this opcode in the tc_frag_data structure. If we can do
921 the fixup here, we change the relocation type to "none" (we test
922 for that in tc_gen_reloc) else we change it to the right type for
923 the new (biggest) opcode. */
924
925 void
926 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
927 segT segment ATTRIBUTE_UNUSED,
928 fragS * fragP ATTRIBUTE_UNUSED)
929 {
930 rl78_bytesT * rl78b = fragP->tc_frag_data;
931 addressT addr0, mypc;
932 int disp;
933 int reloc_type, reloc_adjust;
934 char * op = fragP->fr_opcode;
935 int keep_reloc = 0;
936 int ri;
937 int fi = (rl78b->n_fixups > 1) ? 1 : 0;
938 fixS * fix = rl78b->fixups[fi].fixP;
939
940 /* If we ever get more than one reloc per opcode, this is the one
941 we're relaxing. */
942 ri = 0;
943
944 /* We used a new frag for this opcode, so the opcode address should
945 be the frag address. */
946 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
947 tprintf("\033[32mmypc: 0x%x\033[0m\n", (int)mypc);
948
949 /* Try to get the target address. If we fail here, we just use the
950 largest format. */
951 if (rl78_frag_fix_value (fragP, segment, 0, & addr0,
952 fragP->tc_frag_data->relax[ri].type != RL78_RELAX_BRANCH, 0))
953 {
954 /* We don't know the target address. */
955 keep_reloc = 1;
956 addr0 = 0;
957 disp = 0;
958 tprintf ("unknown addr ? - %x = ?\n", (int)mypc);
959 }
960 else
961 {
962 /* We know the target address, and it's in addr0. */
963 disp = (int) addr0 - (int) mypc;
964 tprintf ("known addr %x - %x = %d\n", (int)addr0, (int)mypc, disp);
965 }
966
967 if (linkrelax)
968 keep_reloc = 1;
969
970 reloc_type = BFD_RELOC_NONE;
971 reloc_adjust = 0;
972
973 switch (fragP->tc_frag_data->relax[ri].type)
974 {
975 case RL78_RELAX_BRANCH:
976 switch (OPCODE (rl78_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
977 {
978
979 case OPCODE (OT_bt, 3): /* BT A,$ - no change. */
980 disp -= 3;
981 op[2] = disp;
982 break;
983
984 case OPCODE (OT_bt, 6): /* BT A,$ - long version. */
985 disp -= 3;
986 op[1] ^= 0x06; /* toggle conditional. */
987 op[2] = 3; /* displacement over long branch. */
988 disp -= 3;
989 op[3] = 0xEE; /* BR $!addr20 */
990 op[4] = disp & 0xff;
991 op[5] = disp >> 8;
992 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
993 reloc_adjust = 2;
994 break;
995
996 case OPCODE (OT_bt_sfr, 4): /* BT PSW,$ - no change. */
997 disp -= 4;
998 op[3] = disp;
999 break;
1000
1001 case OPCODE (OT_bt_sfr, 7): /* BT PSW,$ - long version. */
1002 disp -= 4;
1003 op[1] ^= 0x06; /* toggle conditional. */
1004 op[3] = 3; /* displacement over long branch. */
1005 disp -= 3;
1006 op[4] = 0xEE; /* BR $!addr20 */
1007 op[5] = disp & 0xff;
1008 op[6] = disp >> 8;
1009 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1010 reloc_adjust = 2;
1011 break;
1012
1013 case OPCODE (OT_bt_es, 4): /* BT ES:[HL],$ - no change. */
1014 disp -= 4;
1015 op[3] = disp;
1016 break;
1017
1018 case OPCODE (OT_bt_es, 7): /* BT PSW,$ - long version. */
1019 disp -= 4;
1020 op[2] ^= 0x06; /* toggle conditional. */
1021 op[3] = 3; /* displacement over long branch. */
1022 disp -= 3;
1023 op[4] = 0xEE; /* BR $!addr20 */
1024 op[5] = disp & 0xff;
1025 op[6] = disp >> 8;
1026 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1027 reloc_adjust = 2;
1028 break;
1029
1030 case OPCODE (OT_bc, 2): /* BC $ - no change. */
1031 disp -= 2;
1032 op[1] = disp;
1033 break;
1034
1035 case OPCODE (OT_bc, 5): /* BC $ - long version. */
1036 disp -= 2;
1037 op[0] ^= 0x02; /* toggle conditional. */
1038 op[1] = 3;
1039 disp -= 3;
1040 op[2] = 0xEE; /* BR $!addr20 */
1041 op[3] = disp & 0xff;
1042 op[4] = disp >> 8;
1043 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1044 reloc_adjust = 2;
1045 break;
1046
1047 case OPCODE (OT_bh, 3): /* BH $ - no change. */
1048 disp -= 3;
1049 op[2] = disp;
1050 break;
1051
1052 case OPCODE (OT_bh, 6): /* BC $ - long version. */
1053 disp -= 3;
1054 op[1] ^= 0x10; /* toggle conditional. */
1055 op[2] = 3;
1056 disp -= 3;
1057 op[3] = 0xEE; /* BR $!addr20 */
1058 op[4] = disp & 0xff;
1059 op[5] = disp >> 8;
1060 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1061 reloc_adjust = 2;
1062 break;
1063
1064 default:
1065 fprintf(stderr, "Missed case %d %d at 0x%lx\n",
1066 rl78_opcode_type (fragP->fr_opcode), fragP->fr_subtype, mypc);
1067 abort ();
1068
1069 }
1070 break;
1071
1072 default:
1073 if (rl78b->n_fixups)
1074 {
1075 reloc_type = fix->fx_r_type;
1076 reloc_adjust = 0;
1077 }
1078 break;
1079 }
1080
1081 if (rl78b->n_fixups)
1082 {
1083
1084 fix->fx_r_type = reloc_type;
1085 fix->fx_where += reloc_adjust;
1086 switch (reloc_type)
1087 {
1088 case BFD_RELOC_NONE:
1089 fix->fx_size = 0;
1090 break;
1091 case BFD_RELOC_8:
1092 fix->fx_size = 1;
1093 break;
1094 case BFD_RELOC_16_PCREL:
1095 fix->fx_size = 2;
1096 break;
1097 }
1098 }
1099
1100 fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
1101 tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix,
1102 fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
1103 fragP->fr_var = 0;
1104
1105 tprintf ("compare 0x%lx vs 0x%lx - 0x%lx = 0x%lx (%p)\n",
1106 (long)fragP->fr_fix,
1107 (long)fragP->fr_next->fr_address, (long)fragP->fr_address,
1108 (long)(fragP->fr_next->fr_address - fragP->fr_address),
1109 fragP->fr_next);
1110
1111 if (fragP->fr_next != NULL
1112 && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
1113 != fragP->fr_fix))
1114 as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
1115 (long) fragP->fr_fix,
1116 (long) fragP->fr_address, (long) fragP->fr_next->fr_address);
1117 }
1118
1119 /* End of relaxation code.
1120 ----------------------------------------------------------------------*/
1121 \f
1122
1123 arelent **
1124 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
1125 {
1126 static arelent * reloc[8];
1127 int rp;
1128
1129 if (fixp->fx_r_type == BFD_RELOC_NONE)
1130 {
1131 reloc[0] = NULL;
1132 return reloc;
1133 }
1134
1135 if (fixp->fx_subsy
1136 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
1137 {
1138 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
1139 fixp->fx_subsy = NULL;
1140 }
1141
1142 reloc[0] = (arelent *) xmalloc (sizeof (arelent));
1143 reloc[0]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1144 * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1145 reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
1146 reloc[0]->addend = fixp->fx_offset;
1147
1148 if (fixp->fx_r_type == BFD_RELOC_RL78_32_OP
1149 && fixp->fx_subsy)
1150 {
1151 fixp->fx_r_type = BFD_RELOC_RL78_DIFF;
1152 }
1153
1154 #define OPX(REL,SYM,ADD) \
1155 reloc[rp] = (arelent *) xmalloc (sizeof (arelent)); \
1156 reloc[rp]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); \
1157 reloc[rp]->howto = bfd_reloc_type_lookup (stdoutput, REL); \
1158 reloc[rp]->addend = ADD; \
1159 * reloc[rp]->sym_ptr_ptr = SYM; \
1160 reloc[rp]->address = fixp->fx_frag->fr_address + fixp->fx_where; \
1161 reloc[++rp] = NULL
1162 #define OPSYM(SYM) OPX(BFD_RELOC_RL78_SYM, SYM, 0)
1163 #define OPIMM(IMM) OPX(BFD_RELOC_RL78_SYM, abs_symbol.bsym, IMM)
1164 #define OP(OP) OPX(BFD_RELOC_RL78_##OP, *reloc[0]->sym_ptr_ptr, 0)
1165 #define SYM0() reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RL78_SYM)
1166
1167 rp = 1;
1168
1169 /* Certain BFD relocations cannot be translated directly into
1170 a single (non-Red Hat) RL78 relocation, but instead need
1171 multiple RL78 relocations - handle them here. */
1172 switch (fixp->fx_r_type)
1173 {
1174 case BFD_RELOC_RL78_DIFF:
1175 SYM0 ();
1176 OPSYM (symbol_get_bfdsym (fixp->fx_subsy));
1177 OP(OP_SUBTRACT);
1178
1179 switch (fixp->fx_size)
1180 {
1181 case 1:
1182 OP(ABS8);
1183 break;
1184 case 2:
1185 OP (ABS16);
1186 break;
1187 case 4:
1188 OP (ABS32);
1189 break;
1190 }
1191 break;
1192
1193 case BFD_RELOC_RL78_NEG32:
1194 SYM0 ();
1195 OP (OP_NEG);
1196 OP (ABS32);
1197 break;
1198
1199 case BFD_RELOC_RL78_CODE:
1200 SYM0 ();
1201 OP (ABS16);
1202 break;
1203
1204 case BFD_RELOC_RL78_LO16:
1205 SYM0 ();
1206 OPIMM (0xffff);
1207 OP (OP_AND);
1208 OP (ABS16);
1209 break;
1210
1211 case BFD_RELOC_RL78_HI16:
1212 SYM0 ();
1213 OPIMM (16);
1214 OP (OP_SHRA);
1215 OP (ABS16);
1216 break;
1217
1218 case BFD_RELOC_RL78_HI8:
1219 SYM0 ();
1220 OPIMM (16);
1221 OP (OP_SHRA);
1222 OPIMM (0xff);
1223 OP (OP_AND);
1224 OP (ABS8);
1225 break;
1226
1227 default:
1228 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1229 reloc[1] = NULL;
1230 break;
1231 }
1232
1233 return reloc;
1234 }
1235
1236 int
1237 rl78_validate_fix_sub (struct fix * f)
1238 {
1239 /* We permit the subtraction of two symbols in a few cases. */
1240 /* mov #sym1-sym2, R3 */
1241 if (f->fx_r_type == BFD_RELOC_RL78_32_OP)
1242 return 1;
1243 /* .long sym1-sym2 */
1244 if (f->fx_r_type == BFD_RELOC_RL78_DIFF
1245 && ! f->fx_pcrel
1246 && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
1247 return 1;
1248 return 0;
1249 }
1250
1251 long
1252 md_pcrel_from_section (fixS * fixP, segT sec)
1253 {
1254 long rv;
1255
1256 if (fixP->fx_addsy != NULL
1257 && (! S_IS_DEFINED (fixP->fx_addsy)
1258 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
1259 /* The symbol is undefined (or is defined but not in this section).
1260 Let the linker figure it out. */
1261 return 0;
1262
1263 rv = fixP->fx_frag->fr_address + fixP->fx_where;
1264 switch (fixP->fx_r_type)
1265 {
1266 case BFD_RELOC_8_PCREL:
1267 rv += 1;
1268 break;
1269 case BFD_RELOC_16_PCREL:
1270 rv += 2;
1271 break;
1272 default:
1273 break;
1274 }
1275 return rv;
1276 }
1277
1278 void
1279 md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
1280 valueT * t ATTRIBUTE_UNUSED,
1281 segT s ATTRIBUTE_UNUSED)
1282 {
1283 char * op;
1284 unsigned long val;
1285
1286 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
1287 return;
1288 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
1289 return;
1290
1291 op = f->fx_frag->fr_literal + f->fx_where;
1292 val = (unsigned long) * t;
1293
1294 switch (f->fx_r_type)
1295 {
1296 case BFD_RELOC_NONE:
1297 break;
1298
1299 case BFD_RELOC_RL78_RELAX:
1300 f->fx_done = 1;
1301 break;
1302
1303 case BFD_RELOC_8:
1304 case BFD_RELOC_8_PCREL:
1305 op[0] = val;
1306 break;
1307
1308 case BFD_RELOC_16:
1309 case BFD_RELOC_16_PCREL:
1310 case BFD_RELOC_RL78_CODE:
1311 op[0] = val;
1312 op[1] = val >> 8;
1313 break;
1314
1315 case BFD_RELOC_24:
1316 op[0] = val;
1317 op[1] = val >> 8;
1318 op[2] = val >> 16;
1319 break;
1320
1321 case BFD_RELOC_32:
1322 case BFD_RELOC_RL78_DIFF:
1323 op[0] = val;
1324 op[1] = val >> 8;
1325 op[2] = val >> 16;
1326 op[3] = val >> 24;
1327 break;
1328
1329 default:
1330 as_bad (_("Unknown reloc in md_apply_fix: %s"),
1331 bfd_get_reloc_code_name (f->fx_r_type));
1332 break;
1333 }
1334
1335 if (f->fx_addsy == NULL)
1336 f->fx_done = 1;
1337 }
1338
1339 valueT
1340 md_section_align (segT segment, valueT size)
1341 {
1342 int align = bfd_get_section_alignment (stdoutput, segment);
1343 return ((size + (1 << align) - 1) & (-1 << align));
1344 }