tc-rx.c revision 1.1.1.1.8.1 1 /* tc-rx.c -- Assembler for the Renesas RX
2 Copyright 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
21
22 #include "as.h"
23 #include "struc-symbol.h"
24 #include "obstack.h"
25 #include "safe-ctype.h"
26 #include "dwarf2dbg.h"
27 #include "libbfd.h"
28 #include "elf/common.h"
29 #include "elf/rx.h"
30 #include "rx-defs.h"
31 #include "filenames.h"
32 #include "listing.h"
33 #include "sb.h"
34 #include "macro.h"
35
36 #define RX_OPCODE_BIG_ENDIAN 0
37
38 const char comment_chars[] = ";";
39 /* Note that input_file.c hand checks for '#' at the beginning of the
40 first line of the input file. This is because the compiler outputs
41 #NO_APP at the beginning of its output. */
42 const char line_comment_chars[] = "#";
43 const char line_separator_chars[] = "!";
44
45 const char EXP_CHARS[] = "eE";
46 const char FLT_CHARS[] = "dD";
47
48 /* ELF flags to set in the output file header. */
50 static int elf_flags = 0;
51
52 bfd_boolean rx_use_conventional_section_names = FALSE;
53 static bfd_boolean rx_use_small_data_limit = FALSE;
54
55 static bfd_boolean rx_pid_mode = FALSE;
56 static int rx_num_int_regs = 0;
57 int rx_pid_register;
58 int rx_gp_register;
59
60 static void rx_fetchalign (int ignore ATTRIBUTE_UNUSED);
61
62 enum options
63 {
64 OPTION_BIG = OPTION_MD_BASE,
65 OPTION_LITTLE,
66 OPTION_32BIT_DOUBLES,
67 OPTION_64BIT_DOUBLES,
68 OPTION_CONVENTIONAL_SECTION_NAMES,
69 OPTION_RENESAS_SECTION_NAMES,
70 OPTION_SMALL_DATA_LIMIT,
71 OPTION_RELAX,
72 OPTION_PID,
73 OPTION_INT_REGS,
74 };
75
76 #define RX_SHORTOPTS ""
77 const char * md_shortopts = RX_SHORTOPTS;
78
79 /* Assembler options. */
80 struct option md_longopts[] =
81 {
82 {"mbig-endian-data", no_argument, NULL, OPTION_BIG},
83 {"mlittle-endian-data", no_argument, NULL, OPTION_LITTLE},
84 /* The next two switches are here because the
85 generic parts of the linker testsuite uses them. */
86 {"EB", no_argument, NULL, OPTION_BIG},
87 {"EL", no_argument, NULL, OPTION_LITTLE},
88 {"m32bit-doubles", no_argument, NULL, OPTION_32BIT_DOUBLES},
89 {"m64bit-doubles", no_argument, NULL, OPTION_64BIT_DOUBLES},
90 /* This option is here mainly for the binutils testsuites,
91 as many of their tests assume conventional section naming. */
92 {"muse-conventional-section-names", no_argument, NULL, OPTION_CONVENTIONAL_SECTION_NAMES},
93 {"muse-renesas-section-names", no_argument, NULL, OPTION_RENESAS_SECTION_NAMES},
94 {"msmall-data-limit", no_argument, NULL, OPTION_SMALL_DATA_LIMIT},
95 {"relax", no_argument, NULL, OPTION_RELAX},
96 {"mpid", no_argument, NULL, OPTION_PID},
97 {"mint-register", required_argument, NULL, OPTION_INT_REGS},
98 {NULL, no_argument, NULL, 0}
99 };
100 size_t md_longopts_size = sizeof (md_longopts);
101
102 int
103 md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED)
104 {
105 switch (c)
106 {
107 case OPTION_BIG:
108 target_big_endian = 1;
109 return 1;
110
111 case OPTION_LITTLE:
112 target_big_endian = 0;
113 return 1;
114
115 case OPTION_32BIT_DOUBLES:
116 elf_flags &= ~ E_FLAG_RX_64BIT_DOUBLES;
117 return 1;
118
119 case OPTION_64BIT_DOUBLES:
120 elf_flags |= E_FLAG_RX_64BIT_DOUBLES;
121 return 1;
122
123 case OPTION_CONVENTIONAL_SECTION_NAMES:
124 rx_use_conventional_section_names = TRUE;
125 return 1;
126
127 case OPTION_RENESAS_SECTION_NAMES:
128 rx_use_conventional_section_names = FALSE;
129 return 1;
130
131 case OPTION_SMALL_DATA_LIMIT:
132 rx_use_small_data_limit = TRUE;
133 return 1;
134
135 case OPTION_RELAX:
136 linkrelax = 1;
137 return 1;
138
139 case OPTION_PID:
140 rx_pid_mode = TRUE;
141 elf_flags |= E_FLAG_RX_PID;
142 return 1;
143
144 case OPTION_INT_REGS:
145 rx_num_int_regs = atoi (optarg);
146 return 1;
147 }
148 return 0;
149 }
150
151 void
152 md_show_usage (FILE * stream)
153 {
154 fprintf (stream, _(" RX specific command line options:\n"));
155 fprintf (stream, _(" --mbig-endian-data\n"));
156 fprintf (stream, _(" --mlittle-endian-data [default]\n"));
157 fprintf (stream, _(" --m32bit-doubles [default]\n"));
158 fprintf (stream, _(" --m64bit-doubles\n"));
159 fprintf (stream, _(" --muse-conventional-section-names\n"));
160 fprintf (stream, _(" --muse-renesas-section-names [default]\n"));
161 fprintf (stream, _(" --msmall-data-limit\n"));
162 fprintf (stream, _(" --mrelax\n"));
163 fprintf (stream, _(" --mpid\n"));
164 fprintf (stream, _(" --mint-register=<value>\n"));
165 }
166
167 static void
168 s_bss (int ignore ATTRIBUTE_UNUSED)
169 {
170 int temp;
171
172 temp = get_absolute_expression ();
173 subseg_set (bss_section, (subsegT) temp);
174 demand_empty_rest_of_line ();
175 }
176
177 static void
178 rx_float_cons (int ignore ATTRIBUTE_UNUSED)
179 {
180 if (elf_flags & E_FLAG_RX_64BIT_DOUBLES)
181 return float_cons ('d');
182 return float_cons ('f');
183 }
184
185 static char *
186 rx_strcasestr (const char *string, const char *sub)
187 {
188 int subl;
189 int strl;
190
191 if (!sub || !sub[0])
192 return (char *)string;
193
194 subl = strlen (sub);
195 strl = strlen (string);
196
197 while (strl >= subl)
198 {
199 /* strncasecmp is in libiberty. */
200 if (strncasecmp (string, sub, subl) == 0)
201 return (char *)string;
202
203 string ++;
204 strl --;
205 }
206 return NULL;
207 }
208
209 static void
210 rx_include (int ignore)
211 {
212 FILE * try;
213 char * path;
214 char * filename;
215 char * current_filename;
216 char * eof;
217 char * p;
218 char * d;
219 char * f;
220 char end_char;
221 size_t len;
222
223 /* The RX version of the .INCLUDE pseudo-op does not
224 have to have the filename inside double quotes. */
225 SKIP_WHITESPACE ();
226 if (*input_line_pointer == '"')
227 {
228 /* Treat as the normal GAS .include pseudo-op. */
229 s_include (ignore);
230 return;
231 }
232
233 /* Get the filename. Spaces are allowed, NUL characters are not. */
234 filename = input_line_pointer;
235 eof = find_end_of_line (filename, FALSE);
236 input_line_pointer = eof;
237
238 while (eof >= filename && (* eof == ' ' || * eof == '\n'))
239 -- eof;
240 end_char = *(++ eof);
241 * eof = 0;
242 if (eof == filename)
243 {
244 as_bad (_("no filename following .INCLUDE pseudo-op"));
245 * eof = end_char;
246 return;
247 }
248
249 as_where (& current_filename, NULL);
250 f = (char *) xmalloc (strlen (current_filename) + strlen (filename) + 1);
251
252 /* Check the filename. If [@]..FILE[@] is found then replace
253 this with the current assembler source filename, stripped
254 of any directory prefixes or extensions. */
255 if ((p = rx_strcasestr (filename, "..file")) != NULL)
256 {
257 char * c;
258
259 len = 6; /* strlen ("..file"); */
260
261 if (p > filename && p[-1] == '@')
262 -- p, ++len;
263
264 if (p[len] == '@')
265 len ++;
266
267 for (d = c = current_filename; *c; c++)
268 if (IS_DIR_SEPARATOR (* c))
269 d = c + 1;
270 for (c = d; *c; c++)
271 if (*c == '.')
272 break;
273
274 sprintf (f, "%.*s%.*s%.*s", (int) (p - filename), filename,
275 (int) (c - d), d,
276 (int) (strlen (filename) - ((p + len) - filename)),
277 p + len);
278 }
279 else
280 strcpy (f, filename);
281
282 /* RX .INCLUDE semantics say that 'filename' is located by:
283
284 1. If filename is absolute, just try that. Otherwise...
285
286 2. If the current source file includes a directory component
287 then prepend that to the filename and try. Otherwise...
288
289 3. Try any directories specified by the -I command line
290 option(s).
291
292 4 .Try a directory specifed by the INC100 environment variable. */
293
294 if (IS_ABSOLUTE_PATH (f))
295 try = fopen (path = f, FOPEN_RT);
296 else
297 {
298 char * env = getenv ("INC100");
299
300 try = NULL;
301
302 len = strlen (current_filename);
303 if ((size_t) include_dir_maxlen > len)
304 len = include_dir_maxlen;
305 if (env && strlen (env) > len)
306 len = strlen (env);
307
308 path = (char *) xmalloc (strlen (f) + len + 5);
309
310 if (current_filename != NULL)
311 {
312 for (d = NULL, p = current_filename; *p; p++)
313 if (IS_DIR_SEPARATOR (* p))
314 d = p;
315
316 if (d != NULL)
317 {
318 sprintf (path, "%.*s/%s", (int) (d - current_filename), current_filename,
319 f);
320 try = fopen (path, FOPEN_RT);
321 }
322 }
323
324 if (try == NULL)
325 {
326 int i;
327
328 for (i = 0; i < include_dir_count; i++)
329 {
330 sprintf (path, "%s/%s", include_dirs[i], f);
331 if ((try = fopen (path, FOPEN_RT)) != NULL)
332 break;
333 }
334 }
335
336 if (try == NULL && env != NULL)
337 {
338 sprintf (path, "%s/%s", env, f);
339 try = fopen (path, FOPEN_RT);
340 }
341
342 free (f);
343 }
344
345 if (try == NULL)
346 {
347 as_bad (_("unable to locate include file: %s"), filename);
348 free (path);
349 }
350 else
351 {
352 fclose (try);
353 register_dependency (path);
354 input_scrub_insert_file (path);
355 }
356
357 * eof = end_char;
358 }
359
360 static void
361 parse_rx_section (char * name)
362 {
363 asection * sec;
364 int type;
365 int attr = SHF_ALLOC | SHF_EXECINSTR;
366 int align = 2;
367 char end_char;
368
369 do
370 {
371 char * p;
372
373 SKIP_WHITESPACE ();
374 for (p = input_line_pointer; *p && strchr ("\n\t, =", *p) == NULL; p++)
375 ;
376 end_char = *p;
377 *p = 0;
378
379 if (strcasecmp (input_line_pointer, "ALIGN") == 0)
380 {
381 *p = end_char;
382
383 if (end_char == ' ')
384 while (ISSPACE (*p))
385 p++;
386
387 if (*p == '=')
388 {
389 ++ p;
390 while (ISSPACE (*p))
391 p++;
392 switch (*p)
393 {
394 case '2': align = 2; break;
395 case '4': align = 4; break;
396 case '8': align = 8; break;
397 default:
398 as_bad (_("unrecognised alignment value in .SECTION directive: %s"), p);
399 ignore_rest_of_line ();
400 return;
401 }
402 ++ p;
403 }
404
405 end_char = *p;
406 }
407 else if (strcasecmp (input_line_pointer, "CODE") == 0)
408 attr = SHF_ALLOC | SHF_EXECINSTR;
409 else if (strcasecmp (input_line_pointer, "DATA") == 0)
410 attr = SHF_ALLOC | SHF_WRITE;
411 else if (strcasecmp (input_line_pointer, "ROMDATA") == 0)
412 attr = SHF_ALLOC;
413 else
414 {
415 as_bad (_("unknown parameter following .SECTION directive: %s"),
416 input_line_pointer);
417
418 *p = end_char;
419 input_line_pointer = p + 1;
420 ignore_rest_of_line ();
421 return;
422 }
423
424 *p = end_char;
425 input_line_pointer = p + 1;
426 }
427 while (end_char != '\n' && end_char != 0);
428
429 if ((sec = bfd_get_section_by_name (stdoutput, name)) == NULL)
430 {
431 if (strcmp (name, "B") && strcmp (name, "B_1") && strcmp (name, "B_2"))
432 type = SHT_NULL;
433 else
434 type = SHT_NOBITS;
435
436 obj_elf_change_section (name, type, attr, 0, NULL, FALSE, FALSE);
437 }
438 else /* Try not to redefine a section, especially B_1. */
439 {
440 int flags = sec->flags;
441
442 type = elf_section_type (sec);
443
444 attr = ((flags & SEC_READONLY) ? 0 : SHF_WRITE)
445 | ((flags & SEC_ALLOC) ? SHF_ALLOC : 0)
446 | ((flags & SEC_CODE) ? SHF_EXECINSTR : 0)
447 | ((flags & SEC_MERGE) ? SHF_MERGE : 0)
448 | ((flags & SEC_STRINGS) ? SHF_STRINGS : 0)
449 | ((flags & SEC_THREAD_LOCAL) ? SHF_TLS : 0);
450
451 obj_elf_change_section (name, type, attr, 0, NULL, FALSE, FALSE);
452 }
453
454 bfd_set_section_alignment (stdoutput, now_seg, align);
455 }
456
457 static void
458 rx_section (int ignore)
459 {
460 char * p;
461
462 /* The as100 assembler supports a different syntax for the .section
463 pseudo-op. So check for it and handle it here if necessary. */
464 SKIP_WHITESPACE ();
465
466 /* Peek past the section name to see if arguments follow. */
467 for (p = input_line_pointer; *p; p++)
468 if (*p == ',' || *p == '\n')
469 break;
470
471 if (*p == ',')
472 {
473 int len = p - input_line_pointer;
474
475 while (ISSPACE (*++p))
476 ;
477
478 if (*p != '"' && *p != '#')
479 {
480 char * name = (char *) xmalloc (len + 1);
481
482 strncpy (name, input_line_pointer, len);
483 name[len] = 0;
484
485 input_line_pointer = p;
486 parse_rx_section (name);
487 return;
488 }
489 }
490
491 obj_elf_section (ignore);
492 }
493
494 static void
495 rx_list (int ignore ATTRIBUTE_UNUSED)
496 {
497 SKIP_WHITESPACE ();
498
499 if (strncasecmp (input_line_pointer, "OFF", 3))
500 listing_list (0);
501 else if (strncasecmp (input_line_pointer, "ON", 2))
502 listing_list (1);
503 else
504 as_warn (_("expecting either ON or OFF after .list"));
505 }
506
507 /* Like the .rept pseudo op, but supports the
508 use of ..MACREP inside the repeated region. */
509
510 static void
511 rx_rept (int ignore ATTRIBUTE_UNUSED)
512 {
513 int count = get_absolute_expression ();
514
515 do_repeat_with_expander (count, "MREPEAT", "ENDR", "..MACREP");
516 }
517
518 /* Like cons() accept that strings are allowed. */
519
520 static void
521 rx_cons (int size)
522 {
523 SKIP_WHITESPACE ();
524
525 if (* input_line_pointer == '"')
526 stringer (8+0);
527 else
528 cons (size);
529 }
530
531 static void
532 rx_nop (int ignore ATTRIBUTE_UNUSED)
533 {
534 ignore_rest_of_line ();
535 }
536
537 static void
538 rx_unimp (int idx)
539 {
540 as_warn (_("The \".%s\" pseudo-op is not implemented\n"),
541 md_pseudo_table[idx].poc_name);
542 ignore_rest_of_line ();
543 }
544
545 /* The target specific pseudo-ops which we support. */
546 const pseudo_typeS md_pseudo_table[] =
547 {
548 /* These are unimplemented. They're listed first so that we can use
549 the poc_value as the index into this array, to get the name of
550 the pseudo. So, keep these (1) first, and (2) in order, with (3)
551 the poc_value's in sequence. */
552 { "btglb", rx_unimp, 0 },
553 { "call", rx_unimp, 1 },
554 { "einsf", rx_unimp, 2 },
555 { "fb", rx_unimp, 3 },
556 { "fbsym", rx_unimp, 4 },
557 { "id", rx_unimp, 5 },
558 { "initsct", rx_unimp, 6 },
559 { "insf", rx_unimp, 7 },
560 { "instr", rx_unimp, 8 },
561 { "lbba", rx_unimp, 9 },
562 { "len", rx_unimp, 10 },
563 { "optj", rx_unimp, 11 },
564 { "rvector", rx_unimp, 12 },
565 { "sb", rx_unimp, 13 },
566 { "sbbit", rx_unimp, 14 },
567 { "sbsym", rx_unimp, 15 },
568 { "sbsym16", rx_unimp, 16 },
569
570 /* These are the do-nothing pseudos. */
571 { "stk", rx_nop, 0 },
572 /* The manual documents ".stk" but the compiler emits ".stack". */
573 { "stack", rx_nop, 0 },
574
575 /* These are Renesas as100 assembler pseudo-ops that we do support. */
576 { "addr", rx_cons, 3 },
577 { "align", s_align_bytes, 2 },
578 { "byte", rx_cons, 1 },
579 { "fixed", float_cons, 'f' },
580 { "form", listing_psize, 0 },
581 { "glb", s_globl, 0 },
582 { "include", rx_include, 0 },
583 { "list", rx_list, 0 },
584 { "lword", rx_cons, 4 },
585 { "mrepeat", rx_rept, 0 },
586 { "section", rx_section, 0 },
587
588 /* FIXME: The following pseudo-ops place their values (and associated
589 label if present) in the data section, regardless of whatever
590 section we are currently in. At the moment this code does not
591 implement that part of the semantics. */
592 { "blka", s_space, 3 },
593 { "blkb", s_space, 1 },
594 { "blkd", s_space, 8 },
595 { "blkf", s_space, 4 },
596 { "blkl", s_space, 4 },
597 { "blkw", s_space, 2 },
598
599 /* Our "standard" pseudos. */
600 { "double", rx_float_cons, 0 },
601 { "bss", s_bss, 0 },
602 { "3byte", cons, 3 },
603 { "int", cons, 4 },
604 { "word", cons, 4 },
605
606 { "fetchalign", rx_fetchalign, 0 },
607
608 /* End of list marker. */
609 { NULL, NULL, 0 }
610 };
611
612 static asymbol * gp_symbol;
613 static asymbol * rx_pid_symbol;
614
615 static symbolS * rx_pidreg_symbol;
616 static symbolS * rx_gpreg_symbol;
617
618 void
619 md_begin (void)
620 {
621 /* Make the __gp and __pid_base symbols now rather
622 than after the symbol table is frozen. We only do this
623 when supporting small data limits because otherwise we
624 pollute the symbol table. */
625
626 /* The meta-registers %pidreg and %gpreg depend on what other
627 options are specified. The __rx_*_defined symbols exist so we
628 can .ifdef asm code based on what options were passed to gas,
629 without needing a preprocessor */
630
631 if (rx_pid_mode)
632 {
633 rx_pid_register = 13 - rx_num_int_regs;
634 rx_pid_symbol = symbol_get_bfdsym (symbol_find_or_make ("__pid_base"));
635 rx_pidreg_symbol = symbol_find_or_make ("__rx_pidreg_defined");
636 S_SET_VALUE (rx_pidreg_symbol, rx_pid_register);
637 S_SET_SEGMENT (rx_pidreg_symbol, absolute_section);
638 }
639
640 if (rx_use_small_data_limit)
641 {
642 if (rx_pid_mode)
643 rx_gp_register = rx_pid_register - 1;
644 else
645 rx_gp_register = 13 - rx_num_int_regs;
646 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
647 rx_gpreg_symbol = symbol_find_or_make ("__rx_gpreg_defined");
648 S_SET_VALUE (rx_gpreg_symbol, rx_gp_register);
649 S_SET_SEGMENT (rx_gpreg_symbol, absolute_section);
650 }
651 }
652
653 char * rx_lex_start;
654 char * rx_lex_end;
655
656 /* These negative numbers are found in rx_bytesT.n_base for non-opcode
657 md_frags */
658 #define RX_NBASE_FETCHALIGN -1
659
660 typedef struct rx_bytesT
661 {
662 char base[4];
663 /* If this is negative, it's a special-purpose frag as per the defines above. */
664 int n_base;
665 char ops[8];
666 int n_ops;
667 struct
668 {
669 expressionS exp;
670 char offset;
671 char nbits;
672 char type; /* RXREL_*. */
673 int reloc;
674 fixS * fixP;
675 } fixups[2];
676 int n_fixups;
677 struct
678 {
679 char type;
680 char field_pos;
681 char val_ofs;
682 } relax[2];
683 int n_relax;
684 int link_relax;
685 fixS *link_relax_fixP;
686 char times_grown;
687 char times_shrank;
688 } rx_bytesT;
689
690 static rx_bytesT rx_bytes;
691 /* We set n_ops to be "size of next opcode" if the next opcode doesn't relax. */
692 static rx_bytesT *fetchalign_bytes = NULL;
693
694 static void
695 rx_fetchalign (int ignore ATTRIBUTE_UNUSED)
696 {
697 char * bytes;
698 fragS * frag_then;
699
700 memset (& rx_bytes, 0, sizeof (rx_bytes));
701 rx_bytes.n_base = RX_NBASE_FETCHALIGN;
702
703 bytes = frag_more (8);
704 frag_then = frag_now;
705 frag_variant (rs_machine_dependent,
706 0 /* max_chars */,
707 0 /* var */,
708 0 /* subtype */,
709 0 /* symbol */,
710 0 /* offset */,
711 0 /* opcode */);
712 frag_then->fr_opcode = bytes;
713 frag_then->fr_subtype = 0;
714 fetchalign_bytes = frag_then->tc_frag_data;
715 }
716
717 void
718 rx_relax (int type, int pos)
719 {
720 rx_bytes.relax[rx_bytes.n_relax].type = type;
721 rx_bytes.relax[rx_bytes.n_relax].field_pos = pos;
722 rx_bytes.relax[rx_bytes.n_relax].val_ofs = rx_bytes.n_base + rx_bytes.n_ops;
723 rx_bytes.n_relax ++;
724 }
725
726 void
727 rx_linkrelax_dsp (int pos)
728 {
729 switch (pos)
730 {
731 case 4:
732 rx_bytes.link_relax |= RX_RELAXA_DSP4;
733 break;
734 case 6:
735 rx_bytes.link_relax |= RX_RELAXA_DSP6;
736 break;
737 case 14:
738 rx_bytes.link_relax |= RX_RELAXA_DSP14;
739 break;
740 }
741 }
742
743 void
744 rx_linkrelax_imm (int pos)
745 {
746 switch (pos)
747 {
748 case 6:
749 rx_bytes.link_relax |= RX_RELAXA_IMM6;
750 break;
751 case 12:
752 rx_bytes.link_relax |= RX_RELAXA_IMM12;
753 break;
754 }
755 }
756
757 void
758 rx_linkrelax_branch (void)
759 {
760 rx_bytes.link_relax |= RX_RELAXA_BRA;
761 }
762
763 static void
764 rx_fixup (expressionS exp, int offsetbits, int nbits, int type)
765 {
766 rx_bytes.fixups[rx_bytes.n_fixups].exp = exp;
767 rx_bytes.fixups[rx_bytes.n_fixups].offset = offsetbits;
768 rx_bytes.fixups[rx_bytes.n_fixups].nbits = nbits;
769 rx_bytes.fixups[rx_bytes.n_fixups].type = type;
770 rx_bytes.fixups[rx_bytes.n_fixups].reloc = exp.X_md;
771 rx_bytes.n_fixups ++;
772 }
773
774 #define rx_field_fixup(exp, offset, nbits, type) \
775 rx_fixup (exp, offset, nbits, type)
776
777 #define rx_op_fixup(exp, offset, nbits, type) \
778 rx_fixup (exp, offset + 8 * rx_bytes.n_base, nbits, type)
779
780 void
781 rx_base1 (int b1)
782 {
783 rx_bytes.base[0] = b1;
784 rx_bytes.n_base = 1;
785 }
786
787 void
788 rx_base2 (int b1, int b2)
789 {
790 rx_bytes.base[0] = b1;
791 rx_bytes.base[1] = b2;
792 rx_bytes.n_base = 2;
793 }
794
795 void
796 rx_base3 (int b1, int b2, int b3)
797 {
798 rx_bytes.base[0] = b1;
799 rx_bytes.base[1] = b2;
800 rx_bytes.base[2] = b3;
801 rx_bytes.n_base = 3;
802 }
803
804 void
805 rx_base4 (int b1, int b2, int b3, int b4)
806 {
807 rx_bytes.base[0] = b1;
808 rx_bytes.base[1] = b2;
809 rx_bytes.base[2] = b3;
810 rx_bytes.base[3] = b4;
811 rx_bytes.n_base = 4;
812 }
813
814 /* This gets complicated when the field spans bytes, because fields
815 are numbered from the MSB of the first byte as zero, and bits are
816 stored LSB towards the LSB of the byte. Thus, a simple four-bit
817 insertion of 12 at position 4 of 0x00 yields: 0x0b. A three-bit
818 insertion of b'MXL at position 7 is like this:
819
820 - - - - - - - - - - - - - - - -
821 M X L */
822
823 void
824 rx_field (int val, int pos, int sz)
825 {
826 int valm;
827 int bytep, bitp;
828
829 if (sz > 0)
830 {
831 if (val < 0 || val >= (1 << sz))
832 as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz);
833 }
834 else
835 {
836 sz = - sz;
837 if (val < -(1 << (sz - 1)) || val >= (1 << (sz - 1)))
838 as_bad (_("Value %d doesn't fit in signed %d-bit field"), val, sz);
839 }
840
841 /* This code points at 'M' in the above example. */
842 bytep = pos / 8;
843 bitp = pos % 8;
844
845 while (bitp + sz > 8)
846 {
847 int ssz = 8 - bitp;
848 int svalm;
849
850 svalm = val >> (sz - ssz);
851 svalm = svalm & ((1 << ssz) - 1);
852 svalm = svalm << (8 - bitp - ssz);
853 gas_assert (bytep < rx_bytes.n_base);
854 rx_bytes.base[bytep] |= svalm;
855
856 bitp = 0;
857 sz -= ssz;
858 bytep ++;
859 }
860 valm = val & ((1 << sz) - 1);
861 valm = valm << (8 - bitp - sz);
862 gas_assert (bytep < rx_bytes.n_base);
863 rx_bytes.base[bytep] |= valm;
864 }
865
866 /* Special case of the above, for 3-bit displacements of 2..9. */
867
868 void
869 rx_disp3 (expressionS exp, int pos)
870 {
871 rx_field_fixup (exp, pos, 3, RXREL_PCREL);
872 }
873
874 /* Special case of the above, for split 5-bit displacements. Assumes
875 the displacement has been checked with rx_disp5op. */
876 /* ---- -432 1--- 0--- */
877
878 void
879 rx_field5s (expressionS exp)
880 {
881 int val;
882
883 val = exp.X_add_number;
884 rx_bytes.base[0] |= val >> 2;
885 rx_bytes.base[1] |= (val << 6) & 0x80;
886 rx_bytes.base[1] |= (val << 3) & 0x08;
887 }
888
889 /* ---- ---- 4--- 3210 */
890
891 void
892 rx_field5s2 (expressionS exp)
893 {
894 int val;
895
896 val = exp.X_add_number;
897 rx_bytes.base[1] |= (val << 3) & 0x80;
898 rx_bytes.base[1] |= (val ) & 0x0f;
899 }
900
901 #define OP(x) rx_bytes.ops[rx_bytes.n_ops++] = (x)
902
903 #define F_PRECISION 2
904
905 void
906 rx_op (expressionS exp, int nbytes, int type)
907 {
908 int v = 0;
909
910 if ((exp.X_op == O_constant || exp.X_op == O_big)
911 && type != RXREL_PCREL)
912 {
913 if (exp.X_op == O_big && exp.X_add_number <= 0)
914 {
915 LITTLENUM_TYPE w[2];
916 char * ip = rx_bytes.ops + rx_bytes.n_ops;
917
918 gen_to_words (w, F_PRECISION, 8);
919 #if RX_OPCODE_BIG_ENDIAN
920 ip[0] = w[0] >> 8;
921 ip[1] = w[0];
922 ip[2] = w[1] >> 8;
923 ip[3] = w[1];
924 #else
925 ip[3] = w[0] >> 8;
926 ip[2] = w[0];
927 ip[1] = w[1] >> 8;
928 ip[0] = w[1];
929 #endif
930 rx_bytes.n_ops += 4;
931 }
932 else
933 {
934 v = exp.X_add_number;
935 while (nbytes)
936 {
937 #if RX_OPCODE_BIG_ENDIAN
938 OP ((v >> (8 * (nbytes - 1))) & 0xff);
939 #else
940 OP (v & 0xff);
941 v >>= 8;
942 #endif
943 nbytes --;
944 }
945 }
946 }
947 else
948 {
949 rx_op_fixup (exp, rx_bytes.n_ops * 8, nbytes * 8, type);
950 memset (rx_bytes.ops + rx_bytes.n_ops, 0, nbytes);
951 rx_bytes.n_ops += nbytes;
952 }
953 }
954
955 int
956 rx_wrap (void)
957 {
958 return 0;
959 }
960
961 #define APPEND(B, N_B) \
962 if (rx_bytes.N_B) \
963 { \
964 memcpy (bytes + idx, rx_bytes.B, rx_bytes.N_B); \
965 idx += rx_bytes.N_B; \
966 }
967
968 void
969 rx_frag_init (fragS * fragP)
970 {
971 if (rx_bytes.n_relax || rx_bytes.link_relax || rx_bytes.n_base < 0)
972 {
973 fragP->tc_frag_data = malloc (sizeof (rx_bytesT));
974 memcpy (fragP->tc_frag_data, & rx_bytes, sizeof (rx_bytesT));
975 }
976 else
977 fragP->tc_frag_data = 0;
978 }
979
980 /* Handle the as100's version of the .equ pseudo-op. It has the syntax:
981 <symbol_name> .equ <expression> */
982
983 static void
984 rx_equ (char * name, char * expression)
985 {
986 char saved_name_end_char;
987 char * name_end;
988 char * saved_ilp;
989
990 while (ISSPACE (* name))
991 name ++;
992
993 for (name_end = name + 1; *name_end; name_end ++)
994 if (! ISALNUM (* name_end))
995 break;
996
997 saved_name_end_char = * name_end;
998 * name_end = 0;
999
1000 saved_ilp = input_line_pointer;
1001 input_line_pointer = expression;
1002
1003 equals (name, 1);
1004
1005 input_line_pointer = saved_ilp;
1006 * name_end = saved_name_end_char;
1007 }
1008
1009 /* Look for Renesas as100 pseudo-ops that occur after a symbol name
1010 rather than at the start of a line. (eg .EQU or .DEFINE). If one
1011 is found, process it and return TRUE otherwise return FALSE. */
1012
1013 static bfd_boolean
1014 scan_for_infix_rx_pseudo_ops (char * str)
1015 {
1016 char * p;
1017 char * pseudo_op;
1018 char * dot = strchr (str, '.');
1019
1020 if (dot == NULL || dot == str)
1021 return FALSE;
1022
1023 /* A real pseudo-op must be preceeded by whitespace. */
1024 if (dot[-1] != ' ' && dot[-1] != '\t')
1025 return FALSE;
1026
1027 pseudo_op = dot + 1;
1028
1029 if (!ISALNUM (* pseudo_op))
1030 return FALSE;
1031
1032 for (p = pseudo_op + 1; ISALNUM (* p); p++)
1033 ;
1034
1035 if (strncasecmp ("EQU", pseudo_op, p - pseudo_op) == 0)
1036 rx_equ (str, p);
1037 else if (strncasecmp ("DEFINE", pseudo_op, p - pseudo_op) == 0)
1038 as_warn (_("The .DEFINE pseudo-op is not implemented"));
1039 else if (strncasecmp ("MACRO", pseudo_op, p - pseudo_op) == 0)
1040 as_warn (_("The .MACRO pseudo-op is not implemented"));
1041 else if (strncasecmp ("BTEQU", pseudo_op, p - pseudo_op) == 0)
1042 as_warn (_("The .BTEQU pseudo-op is not implemented."));
1043 else
1044 return FALSE;
1045
1046 return TRUE;
1047 }
1048
1049 void
1050 md_assemble (char * str)
1051 {
1052 char * bytes;
1053 int idx = 0;
1054 int i, rel;
1055 fragS * frag_then = frag_now;
1056 expressionS *exp;
1057
1058 memset (& rx_bytes, 0, sizeof (rx_bytes));
1059
1060 rx_lex_init (str, str + strlen (str));
1061 if (scan_for_infix_rx_pseudo_ops (str))
1062 return;
1063 rx_parse ();
1064
1065 /* This simplifies the relaxation code. */
1066 if (rx_bytes.n_relax || rx_bytes.link_relax)
1067 {
1068 /* We do it this way because we want the frag to have the
1069 rx_bytes in it, which we initialize above. */
1070 bytes = frag_more (12);
1071 frag_then = frag_now;
1072 frag_variant (rs_machine_dependent,
1073 0 /* max_chars */,
1074 0 /* var */,
1075 0 /* subtype */,
1076 0 /* symbol */,
1077 0 /* offset */,
1078 0 /* opcode */);
1079 frag_then->fr_opcode = bytes;
1080 frag_then->fr_fix += rx_bytes.n_base + rx_bytes.n_ops;
1081 frag_then->fr_subtype = rx_bytes.n_base + rx_bytes.n_ops;
1082 }
1083 else
1084 {
1085 bytes = frag_more (rx_bytes.n_base + rx_bytes.n_ops);
1086 frag_then = frag_now;
1087 if (fetchalign_bytes)
1088 fetchalign_bytes->n_ops = rx_bytes.n_base + rx_bytes.n_ops;
1089 }
1090
1091 fetchalign_bytes = NULL;
1092
1093 APPEND (base, n_base);
1094 APPEND (ops, n_ops);
1095
1096 if (rx_bytes.link_relax && rx_bytes.n_fixups)
1097 {
1098 fixS * f;
1099
1100 f = fix_new (frag_then,
1101 (char *) bytes - frag_then->fr_literal,
1102 0,
1103 abs_section_sym,
1104 rx_bytes.link_relax | rx_bytes.n_fixups,
1105 0,
1106 BFD_RELOC_RX_RELAX);
1107 frag_then->tc_frag_data->link_relax_fixP = f;
1108 }
1109
1110 for (i = 0; i < rx_bytes.n_fixups; i ++)
1111 {
1112 /* index: [nbytes][type] */
1113 static int reloc_map[5][4] =
1114 {
1115 { 0, 0, 0, BFD_RELOC_RX_DIR3U_PCREL },
1116 { BFD_RELOC_8, BFD_RELOC_RX_8U, BFD_RELOC_RX_NEG8, BFD_RELOC_8_PCREL },
1117 { BFD_RELOC_RX_16_OP, BFD_RELOC_RX_16U, BFD_RELOC_RX_NEG16, BFD_RELOC_16_PCREL },
1118 { BFD_RELOC_RX_24_OP, BFD_RELOC_RX_24U, BFD_RELOC_RX_NEG24, BFD_RELOC_24_PCREL },
1119 { BFD_RELOC_RX_32_OP, BFD_RELOC_32, BFD_RELOC_RX_NEG32, BFD_RELOC_32_PCREL },
1120 };
1121 fixS * f;
1122
1123 idx = rx_bytes.fixups[i].offset / 8;
1124 rel = reloc_map [rx_bytes.fixups[i].nbits / 8][(int) rx_bytes.fixups[i].type];
1125
1126 if (rx_bytes.fixups[i].reloc)
1127 rel = rx_bytes.fixups[i].reloc;
1128
1129 if (frag_then->tc_frag_data)
1130 exp = & frag_then->tc_frag_data->fixups[i].exp;
1131 else
1132 exp = & rx_bytes.fixups[i].exp;
1133
1134 f = fix_new_exp (frag_then,
1135 (char *) bytes + idx - frag_then->fr_literal,
1136 rx_bytes.fixups[i].nbits / 8,
1137 exp,
1138 rx_bytes.fixups[i].type == RXREL_PCREL ? 1 : 0,
1139 rel);
1140 if (frag_then->tc_frag_data)
1141 frag_then->tc_frag_data->fixups[i].fixP = f;
1142 }
1143
1144 dwarf2_emit_insn (idx);
1145 }
1146
1147 void
1148 rx_md_end (void)
1149 {
1150 }
1151
1152 /* Write a value out to the object file, using the appropriate endianness. */
1153
1154 void
1155 md_number_to_chars (char * buf, valueT val, int n)
1156 {
1157 if (target_big_endian)
1158 number_to_chars_bigendian (buf, val, n);
1159 else
1160 number_to_chars_littleendian (buf, val, n);
1161 }
1162
1163 static struct
1164 {
1165 char * fname;
1166 int reloc;
1167 }
1168 reloc_functions[] =
1169 {
1170 { "gp", BFD_RELOC_GPREL16 },
1171 { 0, 0 }
1172 };
1173
1174 void
1175 md_operand (expressionS * exp ATTRIBUTE_UNUSED)
1176 {
1177 int reloc = 0;
1178 int i;
1179
1180 for (i = 0; reloc_functions[i].fname; i++)
1181 {
1182 int flen = strlen (reloc_functions[i].fname);
1183
1184 if (input_line_pointer[0] == '%'
1185 && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
1186 && input_line_pointer[flen + 1] == '(')
1187 {
1188 reloc = reloc_functions[i].reloc;
1189 input_line_pointer += flen + 2;
1190 break;
1191 }
1192 }
1193 if (reloc == 0)
1194 return;
1195
1196 expression (exp);
1197 if (* input_line_pointer == ')')
1198 input_line_pointer ++;
1199
1200 exp->X_md = reloc;
1201 }
1202
1203 valueT
1204 md_section_align (segT segment, valueT size)
1205 {
1206 int align = bfd_get_section_alignment (stdoutput, segment);
1207 return ((size + (1 << align) - 1) & (-1 << align));
1208 }
1209
1210 /* NOP - 1 cycle */
1211 static unsigned char nop_1[] = { 0x03};
1212 /* MOV.L R0,R0 - 1 cycle */
1213 static unsigned char nop_2[] = { 0xef, 0x00};
1214 /* MAX R0,R0 - 1 cycle */
1215 static unsigned char nop_3[] = { 0xfc, 0x13, 0x00 };
1216 /* MUL #1,R0 - 1 cycle */
1217 static unsigned char nop_4[] = { 0x76, 0x10, 0x01, 0x00 };
1218 /* MUL #1,R0 - 1 cycle */
1219 static unsigned char nop_5[] = { 0x77, 0x10, 0x01, 0x00, 0x00 };
1220 /* MUL #1,R0 - 1 cycle */
1221 static unsigned char nop_6[] = { 0x74, 0x10, 0x01, 0x00, 0x00, 0x00 };
1222 /* BRA.S .+7 - 1 cycle */
1223 static unsigned char nop_7[] = { 0x0F, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
1224
1225 static unsigned char *nops[] = { NULL, nop_1, nop_2, nop_3, nop_4, nop_5, nop_6, nop_7 };
1226 #define BIGGEST_NOP 7
1227
1228 /* When relaxing, we need to output a reloc for any .align directive
1229 so that we can retain this alignment as we adjust opcode sizes. */
1230 void
1231 rx_handle_align (fragS * frag)
1232 {
1233 /* If handling an alignment frag, use an optimal NOP pattern.
1234 Only do this if a fill value has not already been provided.
1235 FIXME: This test fails if the provided fill value is zero. */
1236 if ((frag->fr_type == rs_align
1237 || frag->fr_type == rs_align_code)
1238 && subseg_text_p (now_seg))
1239 {
1240 int count = (frag->fr_next->fr_address
1241 - frag->fr_address
1242 - frag->fr_fix);
1243 unsigned char *base = (unsigned char *)frag->fr_literal + frag->fr_fix;
1244
1245 if (* base == 0)
1246 {
1247 if (count > BIGGEST_NOP)
1248 {
1249 base[0] = 0x2e;
1250 base[1] = count;
1251 frag->fr_var = 2;
1252 }
1253 else if (count > 0)
1254 {
1255 memcpy (base, nops[count], count);
1256 frag->fr_var = count;
1257 }
1258 }
1259 }
1260
1261 if (linkrelax
1262 && (frag->fr_type == rs_align
1263 || frag->fr_type == rs_align_code)
1264 && frag->fr_address + frag->fr_fix > 0
1265 && frag->fr_offset > 0
1266 && now_seg != bss_section)
1267 {
1268 fix_new (frag, frag->fr_fix, 0,
1269 &abs_symbol, RX_RELAXA_ALIGN + frag->fr_offset,
1270 0, BFD_RELOC_RX_RELAX);
1271 /* For the purposes of relaxation, this relocation is attached
1272 to the byte *after* the alignment - i.e. the byte that must
1273 remain aligned. */
1274 fix_new (frag->fr_next, 0, 0,
1275 &abs_symbol, RX_RELAXA_ELIGN + frag->fr_offset,
1276 0, BFD_RELOC_RX_RELAX);
1277 }
1278 }
1279
1280 char *
1281 md_atof (int type, char * litP, int * sizeP)
1282 {
1283 return ieee_md_atof (type, litP, sizeP, target_big_endian);
1284 }
1285
1286 symbolS *
1287 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1288 {
1289 return NULL;
1290 }
1291
1292 /*----------------------------------------------------------------------*/
1293 /* To recap: we estimate everything based on md_estimate_size, then
1294 adjust based on rx_relax_frag. When it all settles, we call
1295 md_convert frag to update the bytes. The relaxation types and
1296 relocations are in fragP->tc_frag_data, which is a copy of that
1297 rx_bytes.
1298
1299 Our scheme is as follows: fr_fix has the size of the smallest
1300 opcode (like BRA.S). We store the number of total bytes we need in
1301 fr_subtype. When we're done relaxing, we use fr_subtype and the
1302 existing opcode bytes to figure out what actual opcode we need to
1303 put in there. If the fixup isn't resolvable now, we use the
1304 maximal size. */
1305
1306 #define TRACE_RELAX 0
1307 #define tprintf if (TRACE_RELAX) printf
1308
1309 typedef enum
1310 {
1311 OT_other,
1312 OT_bra,
1313 OT_beq,
1314 OT_bne,
1315 OT_bsr,
1316 OT_bcc
1317 } op_type_T;
1318
1319 /* We're looking for these types of relaxations:
1320
1321 BRA.S 00001dsp
1322 BRA.B 00101110 dspppppp
1323 BRA.W 00111000 dspppppp pppppppp
1324 BRA.A 00000100 dspppppp pppppppp pppppppp
1325
1326 BEQ.S 00010dsp
1327 BEQ.B 00100000 dspppppp
1328 BEQ.W 00111010 dspppppp pppppppp
1329
1330 BNE.S 00011dsp
1331 BNE.B 00100001 dspppppp
1332 BNE.W 00111011 dspppppp pppppppp
1333
1334 BSR.W 00111001 dspppppp pppppppp
1335 BSR.A 00000101 dspppppp pppppppp pppppppp
1336
1337 Bcc.B 0010cond dspppppp
1338
1339 Additionally, we can synthesize longer conditional branches using
1340 pairs of opcodes, one with an inverted conditional (flip LSB):
1341
1342 Bcc.W 0010ncnd 00000110 00111000 dspppppp pppppppp
1343 Bcc.A 0010ncnd 00000111 00000100 dspppppp pppppppp pppppppp
1344 BEQ.A 00011100 00000100 dspppppp pppppppp pppppppp
1345 BNE.A 00010100 00000100 dspppppp pppppppp pppppppp */
1346
1347 /* Given the opcode bytes at OP, figure out which opcode it is and
1348 return the type of opcode. We use this to re-encode the opcode as
1349 a different size later. */
1350
1351 static op_type_T
1352 rx_opcode_type (char * op)
1353 {
1354 unsigned char b = (unsigned char) op[0];
1355
1356 switch (b & 0xf8)
1357 {
1358 case 0x08: return OT_bra;
1359 case 0x10: return OT_beq;
1360 case 0x18: return OT_bne;
1361 }
1362
1363 switch (b)
1364 {
1365 case 0x2e: return OT_bra;
1366 case 0x38: return OT_bra;
1367 case 0x04: return OT_bra;
1368
1369 case 0x20: return OT_beq;
1370 case 0x3a: return OT_beq;
1371
1372 case 0x21: return OT_bne;
1373 case 0x3b: return OT_bne;
1374
1375 case 0x39: return OT_bsr;
1376 case 0x05: return OT_bsr;
1377 }
1378
1379 if ((b & 0xf0) == 0x20)
1380 return OT_bcc;
1381
1382 return OT_other;
1383 }
1384
1385 /* Returns zero if *addrP has the target address. Else returns nonzero
1386 if we cannot compute the target address yet. */
1387
1388 static int
1389 rx_frag_fix_value (fragS * fragP,
1390 segT segment,
1391 int which,
1392 addressT * addrP,
1393 int need_diff,
1394 addressT * sym_addr)
1395 {
1396 addressT addr = 0;
1397 rx_bytesT * b = fragP->tc_frag_data;
1398 expressionS * exp = & b->fixups[which].exp;
1399
1400 if (need_diff && exp->X_op != O_subtract)
1401 return 1;
1402
1403 if (exp->X_add_symbol)
1404 {
1405 if (S_FORCE_RELOC (exp->X_add_symbol, 1))
1406 return 1;
1407 if (S_GET_SEGMENT (exp->X_add_symbol) != segment)
1408 return 1;
1409 addr += S_GET_VALUE (exp->X_add_symbol);
1410 }
1411
1412 if (exp->X_op_symbol)
1413 {
1414 if (exp->X_op != O_subtract)
1415 return 1;
1416 if (S_FORCE_RELOC (exp->X_op_symbol, 1))
1417 return 1;
1418 if (S_GET_SEGMENT (exp->X_op_symbol) != segment)
1419 return 1;
1420 addr -= S_GET_VALUE (exp->X_op_symbol);
1421 }
1422 if (sym_addr)
1423 * sym_addr = addr;
1424 addr += exp->X_add_number;
1425 * addrP = addr;
1426 return 0;
1427 }
1428
1429 /* Estimate how big the opcode is after this relax pass. The return
1430 value is the difference between fr_fix and the actual size. We
1431 compute the total size in rx_relax_frag and store it in fr_subtype,
1432 sowe only need to subtract fx_fix and return it. */
1433
1434 int
1435 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
1436 {
1437 int opfixsize;
1438 int delta;
1439
1440 tprintf ("\033[32m est frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1441 (unsigned long) (fragP->fr_address
1442 + (fragP->fr_opcode - fragP->fr_literal)),
1443 (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1444 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype);
1445
1446 /* This is the size of the opcode that's accounted for in fr_fix. */
1447 opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal);
1448 /* This is the size of the opcode that isn't. */
1449 delta = (fragP->fr_subtype - opfixsize);
1450
1451 tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta);
1452 return delta;
1453 }
1454
1455 /* Given a frag FRAGP, return the "next" frag that contains an
1456 opcode. Assumes the next opcode is relaxable, and thus rs_machine_dependent. */
1457
1458 static fragS *
1459 rx_next_opcode (fragS *fragP)
1460 {
1461 do {
1462 fragP = fragP->fr_next;
1463 } while (fragP && fragP->fr_type != rs_machine_dependent);
1464 return fragP;
1465 }
1466
1467 /* Given the new addresses for this relax pass, figure out how big
1468 each opcode must be. We store the total number of bytes needed in
1469 fr_subtype. The return value is the difference between the size
1470 after the last pass and the size after this pass, so we use the old
1471 fr_subtype to calculate the difference. */
1472
1473 int
1474 rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
1475 {
1476 addressT addr0, sym_addr;
1477 addressT mypc;
1478 int disp;
1479 int oldsize = fragP->fr_subtype;
1480 int newsize = oldsize;
1481 op_type_T optype;
1482 /* Index of relaxation we care about. */
1483 int ri;
1484
1485 tprintf ("\033[36mrelax frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d str %ld\033[0m\n",
1486 (unsigned long) (fragP->fr_address
1487 + (fragP->fr_opcode - fragP->fr_literal)),
1488 (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1489 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype, stretch);
1490
1491 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1492
1493 if (fragP->tc_frag_data->n_base == RX_NBASE_FETCHALIGN)
1494 {
1495 unsigned int next_size;
1496 if (fragP->fr_next == NULL)
1497 return 0;
1498
1499 next_size = fragP->tc_frag_data->n_ops;
1500 if (next_size == 0)
1501 {
1502 fragS *n = rx_next_opcode (fragP);
1503 next_size = n->fr_subtype;
1504 }
1505
1506 fragP->fr_subtype = (8-(mypc & 7)) & 7;
1507 tprintf("subtype %u\n", fragP->fr_subtype);
1508 if (fragP->fr_subtype >= next_size)
1509 fragP->fr_subtype = 0;
1510 tprintf ("\033[34m -> mypc %lu next_size %u new %d old %d delta %d (fetchalign)\033[0m\n",
1511 mypc & 7,
1512 next_size, fragP->fr_subtype, oldsize, fragP->fr_subtype-oldsize);
1513
1514 newsize = fragP->fr_subtype;
1515
1516 return newsize - oldsize;
1517 }
1518
1519 optype = rx_opcode_type (fragP->fr_opcode);
1520
1521 /* In the one case where we have both a disp and imm relaxation, we want
1522 the imm relaxation here. */
1523 ri = 0;
1524 if (fragP->tc_frag_data->n_relax > 1
1525 && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1526 ri = 1;
1527
1528 /* Try to get the target address. */
1529 if (rx_frag_fix_value (fragP, segment, ri, & addr0,
1530 fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH,
1531 & sym_addr))
1532 {
1533 /* If we don't, we must use the maximum size for the linker.
1534 Note that we don't use synthetically expanded conditionals
1535 for this. */
1536 switch (fragP->tc_frag_data->relax[ri].type)
1537 {
1538 case RX_RELAX_BRANCH:
1539 switch (optype)
1540 {
1541 case OT_bra:
1542 case OT_bsr:
1543 newsize = 4;
1544 break;
1545 case OT_beq:
1546 case OT_bne:
1547 newsize = 3;
1548 break;
1549 case OT_bcc:
1550 newsize = 2;
1551 break;
1552 case OT_other:
1553 newsize = oldsize;
1554 break;
1555 }
1556 break;
1557
1558 case RX_RELAX_IMM:
1559 newsize = fragP->tc_frag_data->relax[ri].val_ofs + 4;
1560 break;
1561 }
1562 fragP->fr_subtype = newsize;
1563 tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize);
1564 return newsize - oldsize;
1565 }
1566
1567 if (sym_addr > mypc)
1568 addr0 += stretch;
1569
1570 switch (fragP->tc_frag_data->relax[ri].type)
1571 {
1572 case RX_RELAX_BRANCH:
1573 tprintf ("branch, addr %08lx pc %08lx disp %ld\n",
1574 (unsigned long) addr0, (unsigned long) mypc,
1575 (long) (addr0 - mypc));
1576 disp = (int) addr0 - (int) mypc;
1577
1578 switch (optype)
1579 {
1580 case OT_bcc:
1581 if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1582 /* bcc.b */
1583 newsize = 2;
1584 else if (disp >= -32768 && (disp - (oldsize-5)) <= 32767)
1585 /* bncc.b/bra.w */
1586 newsize = 5;
1587 else
1588 /* bncc.b/bra.a */
1589 newsize = 6;
1590 break;
1591
1592 case OT_beq:
1593 case OT_bne:
1594 if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1595 /* beq.s */
1596 newsize = 1;
1597 else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1598 /* beq.b */
1599 newsize = 2;
1600 else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1601 /* beq.w */
1602 newsize = 3;
1603 else
1604 /* bne.s/bra.a */
1605 newsize = 5;
1606 break;
1607
1608 case OT_bra:
1609 case OT_bsr:
1610 if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1611 /* bra.s */
1612 newsize = 1;
1613 else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1614 /* bra.b */
1615 newsize = 2;
1616 else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1617 /* bra.w */
1618 newsize = 3;
1619 else
1620 /* bra.a */
1621 newsize = 4;
1622 break;
1623
1624 case OT_other:
1625 break;
1626 }
1627 tprintf (" - newsize %d\n", newsize);
1628 break;
1629
1630 case RX_RELAX_IMM:
1631 tprintf ("other, addr %08lx pc %08lx LI %d OF %d\n",
1632 (unsigned long) addr0, (unsigned long) mypc,
1633 fragP->tc_frag_data->relax[ri].field_pos,
1634 fragP->tc_frag_data->relax[ri].val_ofs);
1635
1636 newsize = fragP->tc_frag_data->relax[ri].val_ofs;
1637
1638 if ((long) addr0 >= -128 && (long) addr0 <= 127)
1639 newsize += 1;
1640 else if ((long) addr0 >= -32768 && (long) addr0 <= 32767)
1641 newsize += 2;
1642 else if ((long) addr0 >= -8388608 && (long) addr0 <= 8388607)
1643 newsize += 3;
1644 else
1645 newsize += 4;
1646 break;
1647
1648 default:
1649 break;
1650 }
1651
1652 if (fragP->tc_frag_data->relax[ri].type == RX_RELAX_BRANCH)
1653 switch (optype)
1654 {
1655 case OT_bra:
1656 case OT_bcc:
1657 case OT_beq:
1658 case OT_bne:
1659 break;
1660 case OT_bsr:
1661 if (newsize < 3)
1662 newsize = 3;
1663 break;
1664 case OT_other:
1665 break;
1666 }
1667
1668 /* This prevents infinite loops in align-heavy sources. */
1669 if (newsize < oldsize)
1670 {
1671 if (fragP->tc_frag_data->times_shrank > 10
1672 && fragP->tc_frag_data->times_grown > 10)
1673 newsize = oldsize;
1674 if (fragP->tc_frag_data->times_shrank < 20)
1675 fragP->tc_frag_data->times_shrank ++;
1676 }
1677 else if (newsize > oldsize)
1678 {
1679 if (fragP->tc_frag_data->times_grown < 20)
1680 fragP->tc_frag_data->times_grown ++;
1681 }
1682
1683 fragP->fr_subtype = newsize;
1684 tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
1685 return newsize - oldsize;
1686 }
1687
1688 /* This lets us test for the opcode type and the desired size in a
1689 switch statement. */
1690 #define OPCODE(type,size) ((type) * 16 + (size))
1691
1692 /* Given the opcode stored in fr_opcode and the number of bytes we
1693 think we need, encode a new opcode. We stored a pointer to the
1694 fixup for this opcode in the tc_frag_data structure. If we can do
1695 the fixup here, we change the relocation type to "none" (we test
1696 for that in tc_gen_reloc) else we change it to the right type for
1697 the new (biggest) opcode. */
1698
1699 void
1700 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1701 segT segment ATTRIBUTE_UNUSED,
1702 fragS * fragP ATTRIBUTE_UNUSED)
1703 {
1704 rx_bytesT * rxb = fragP->tc_frag_data;
1705 addressT addr0, mypc;
1706 int disp;
1707 int reloc_type, reloc_adjust;
1708 char * op = fragP->fr_opcode;
1709 int keep_reloc = 0;
1710 int ri;
1711 int fi = (rxb->n_fixups > 1) ? 1 : 0;
1712 fixS * fix = rxb->fixups[fi].fixP;
1713
1714 tprintf ("\033[31mconvrt frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1715 (unsigned long) (fragP->fr_address
1716 + (fragP->fr_opcode - fragP->fr_literal)),
1717 (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1718 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type,
1719 fragP->fr_subtype);
1720
1721 #if TRACE_RELAX
1722 {
1723 int i;
1724
1725 printf ("lit 0x%p opc 0x%p", fragP->fr_literal, fragP->fr_opcode);
1726 for (i = 0; i < 10; i++)
1727 printf (" %02x", (unsigned char) (fragP->fr_opcode[i]));
1728 printf ("\n");
1729 }
1730 #endif
1731
1732 if (fragP->tc_frag_data->n_base == RX_NBASE_FETCHALIGN)
1733 {
1734 int count = fragP->fr_subtype;
1735 if (count == 0)
1736 ;
1737 else if (count > BIGGEST_NOP)
1738 {
1739 op[0] = 0x2e;
1740 op[1] = count;
1741 }
1742 else if (count > 0)
1743 {
1744 memcpy (op, nops[count], count);
1745 }
1746 }
1747
1748 /* In the one case where we have both a disp and imm relaxation, we want
1749 the imm relaxation here. */
1750 ri = 0;
1751 if (fragP->tc_frag_data->n_relax > 1
1752 && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1753 ri = 1;
1754
1755 /* We used a new frag for this opcode, so the opcode address should
1756 be the frag address. */
1757 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1758
1759 /* Try to get the target address. If we fail here, we just use the
1760 largest format. */
1761 if (rx_frag_fix_value (fragP, segment, 0, & addr0,
1762 fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH, 0))
1763 {
1764 /* We don't know the target address. */
1765 keep_reloc = 1;
1766 addr0 = 0;
1767 disp = 0;
1768 }
1769 else
1770 {
1771 /* We know the target address, and it's in addr0. */
1772 disp = (int) addr0 - (int) mypc;
1773 }
1774
1775 if (linkrelax)
1776 keep_reloc = 1;
1777
1778 reloc_type = BFD_RELOC_NONE;
1779 reloc_adjust = 0;
1780
1781 tprintf ("convert, op is %d, disp %d (%lx-%lx)\n",
1782 rx_opcode_type (fragP->fr_opcode), disp,
1783 (unsigned long) addr0, (unsigned long) mypc);
1784 switch (fragP->tc_frag_data->relax[ri].type)
1785 {
1786 case RX_RELAX_BRANCH:
1787 switch (OPCODE (rx_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
1788 {
1789 case OPCODE (OT_bra, 1): /* BRA.S - no change. */
1790 op[0] = 0x08 + (disp & 7);
1791 break;
1792 case OPCODE (OT_bra, 2): /* BRA.B - 8 bit. */
1793 op[0] = 0x2e;
1794 op[1] = disp;
1795 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1796 reloc_adjust = 1;
1797 break;
1798 case OPCODE (OT_bra, 3): /* BRA.W - 16 bit. */
1799 op[0] = 0x38;
1800 #if RX_OPCODE_BIG_ENDIAN
1801 op[1] = (disp >> 8) & 0xff;
1802 op[2] = disp;
1803 #else
1804 op[2] = (disp >> 8) & 0xff;
1805 op[1] = disp;
1806 #endif
1807 reloc_adjust = 1;
1808 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1809 break;
1810 case OPCODE (OT_bra, 4): /* BRA.A - 24 bit. */
1811 op[0] = 0x04;
1812 #if RX_OPCODE_BIG_ENDIAN
1813 op[1] = (disp >> 16) & 0xff;
1814 op[2] = (disp >> 8) & 0xff;
1815 op[3] = disp;
1816 #else
1817 op[3] = (disp >> 16) & 0xff;
1818 op[2] = (disp >> 8) & 0xff;
1819 op[1] = disp;
1820 #endif
1821 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1822 reloc_adjust = 1;
1823 break;
1824
1825 case OPCODE (OT_beq, 1): /* BEQ.S - no change. */
1826 op[0] = 0x10 + (disp & 7);
1827 break;
1828 case OPCODE (OT_beq, 2): /* BEQ.B - 8 bit. */
1829 op[0] = 0x20;
1830 op[1] = disp;
1831 reloc_adjust = 1;
1832 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1833 break;
1834 case OPCODE (OT_beq, 3): /* BEQ.W - 16 bit. */
1835 op[0] = 0x3a;
1836 #if RX_OPCODE_BIG_ENDIAN
1837 op[1] = (disp >> 8) & 0xff;
1838 op[2] = disp;
1839 #else
1840 op[2] = (disp >> 8) & 0xff;
1841 op[1] = disp;
1842 #endif
1843 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1844 reloc_adjust = 1;
1845 break;
1846 case OPCODE (OT_beq, 5): /* BEQ.A - synthetic. */
1847 op[0] = 0x1d; /* bne.s .+5. */
1848 op[1] = 0x04; /* bra.a dsp:24. */
1849 disp -= 1;
1850 #if RX_OPCODE_BIG_ENDIAN
1851 op[2] = (disp >> 16) & 0xff;
1852 op[3] = (disp >> 8) & 0xff;
1853 op[4] = disp;
1854 #else
1855 op[4] = (disp >> 16) & 0xff;
1856 op[3] = (disp >> 8) & 0xff;
1857 op[2] = disp;
1858 #endif
1859 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1860 reloc_adjust = 2;
1861 break;
1862
1863 case OPCODE (OT_bne, 1): /* BNE.S - no change. */
1864 op[0] = 0x18 + (disp & 7);
1865 break;
1866 case OPCODE (OT_bne, 2): /* BNE.B - 8 bit. */
1867 op[0] = 0x21;
1868 op[1] = disp;
1869 reloc_adjust = 1;
1870 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1871 break;
1872 case OPCODE (OT_bne, 3): /* BNE.W - 16 bit. */
1873 op[0] = 0x3b;
1874 #if RX_OPCODE_BIG_ENDIAN
1875 op[1] = (disp >> 8) & 0xff;
1876 op[2] = disp;
1877 #else
1878 op[2] = (disp >> 8) & 0xff;
1879 op[1] = disp;
1880 #endif
1881 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1882 reloc_adjust = 1;
1883 break;
1884 case OPCODE (OT_bne, 5): /* BNE.A - synthetic. */
1885 op[0] = 0x15; /* beq.s .+5. */
1886 op[1] = 0x04; /* bra.a dsp:24. */
1887 disp -= 1;
1888 #if RX_OPCODE_BIG_ENDIAN
1889 op[2] = (disp >> 16) & 0xff;
1890 op[3] = (disp >> 8) & 0xff;
1891 op[4] = disp;
1892 #else
1893 op[4] = (disp >> 16) & 0xff;
1894 op[3] = (disp >> 8) & 0xff;
1895 op[2] = disp;
1896 #endif
1897 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1898 reloc_adjust = 2;
1899 break;
1900
1901 case OPCODE (OT_bsr, 3): /* BSR.W - 16 bit. */
1902 op[0] = 0x39;
1903 #if RX_OPCODE_BIG_ENDIAN
1904 op[1] = (disp >> 8) & 0xff;
1905 op[2] = disp;
1906 #else
1907 op[2] = (disp >> 8) & 0xff;
1908 op[1] = disp;
1909 #endif
1910 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1911 reloc_adjust = 0;
1912 break;
1913 case OPCODE (OT_bsr, 4): /* BSR.A - 24 bit. */
1914 op[0] = 0x05;
1915 #if RX_OPCODE_BIG_ENDIAN
1916 op[1] = (disp >> 16) & 0xff;
1917 op[2] = (disp >> 8) & 0xff;
1918 op[3] = disp;
1919 #else
1920 op[3] = (disp >> 16) & 0xff;
1921 op[2] = (disp >> 8) & 0xff;
1922 op[1] = disp;
1923 #endif
1924 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1925 reloc_adjust = 0;
1926 break;
1927
1928 case OPCODE (OT_bcc, 2): /* Bcond.B - 8 bit. */
1929 op[1] = disp;
1930 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1931 break;
1932 case OPCODE (OT_bcc, 5): /* Bcond.W - synthetic. */
1933 op[0] ^= 1; /* Invert condition. */
1934 op[1] = 5; /* Displacement. */
1935 op[2] = 0x38;
1936 disp -= 2;
1937 #if RX_OPCODE_BIG_ENDIAN
1938 op[3] = (disp >> 8) & 0xff;
1939 op[4] = disp;
1940 #else
1941 op[4] = (disp >> 8) & 0xff;
1942 op[3] = disp;
1943 #endif
1944 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1945 reloc_adjust = 2;
1946 break;
1947 case OPCODE (OT_bcc, 6): /* Bcond.S - synthetic. */
1948 op[0] ^= 1; /* Invert condition. */
1949 op[1] = 6; /* Displacement. */
1950 op[2] = 0x04;
1951 disp -= 2;
1952 #if RX_OPCODE_BIG_ENDIAN
1953 op[3] = (disp >> 16) & 0xff;
1954 op[4] = (disp >> 8) & 0xff;
1955 op[5] = disp;
1956 #else
1957 op[5] = (disp >> 16) & 0xff;
1958 op[4] = (disp >> 8) & 0xff;
1959 op[3] = disp;
1960 #endif
1961 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1962 reloc_adjust = 2;
1963 break;
1964
1965 default:
1966 /* These are opcodes we'll relax in th linker, later. */
1967 if (rxb->n_fixups)
1968 reloc_type = rxb->fixups[ri].fixP->fx_r_type;
1969 break;
1970 }
1971 break;
1972
1973 case RX_RELAX_IMM:
1974 {
1975 int nbytes = fragP->fr_subtype - fragP->tc_frag_data->relax[ri].val_ofs;
1976 int li;
1977 char * imm = op + fragP->tc_frag_data->relax[ri].val_ofs;
1978
1979 switch (nbytes)
1980 {
1981 case 1:
1982 li = 1;
1983 imm[0] = addr0;
1984 reloc_type = BFD_RELOC_8;
1985 break;
1986 case 2:
1987 li = 2;
1988 #if RX_OPCODE_BIG_ENDIAN
1989 imm[1] = addr0;
1990 imm[0] = addr0 >> 8;
1991 #else
1992 imm[0] = addr0;
1993 imm[1] = addr0 >> 8;
1994 #endif
1995 reloc_type = BFD_RELOC_RX_16_OP;
1996 break;
1997 case 3:
1998 li = 3;
1999 #if RX_OPCODE_BIG_ENDIAN
2000 imm[2] = addr0;
2001 imm[1] = addr0 >> 8;
2002 imm[0] = addr0 >> 16;
2003 #else
2004 imm[0] = addr0;
2005 imm[1] = addr0 >> 8;
2006 imm[2] = addr0 >> 16;
2007 #endif
2008 reloc_type = BFD_RELOC_RX_24_OP;
2009 break;
2010 case 4:
2011 li = 0;
2012 #if RX_OPCODE_BIG_ENDIAN
2013 imm[3] = addr0;
2014 imm[2] = addr0 >> 8;
2015 imm[1] = addr0 >> 16;
2016 imm[0] = addr0 >> 24;
2017 #else
2018 imm[0] = addr0;
2019 imm[1] = addr0 >> 8;
2020 imm[2] = addr0 >> 16;
2021 imm[3] = addr0 >> 24;
2022 #endif
2023 reloc_type = BFD_RELOC_RX_32_OP;
2024 break;
2025 default:
2026 as_bad (_("invalid immediate size"));
2027 li = -1;
2028 }
2029
2030 switch (fragP->tc_frag_data->relax[ri].field_pos)
2031 {
2032 case 6:
2033 op[0] &= 0xfc;
2034 op[0] |= li;
2035 break;
2036 case 12:
2037 op[1] &= 0xf3;
2038 op[1] |= li << 2;
2039 break;
2040 case 20:
2041 op[2] &= 0xf3;
2042 op[2] |= li << 2;
2043 break;
2044 default:
2045 as_bad (_("invalid immediate field position"));
2046 }
2047 }
2048 break;
2049
2050 default:
2051 if (rxb->n_fixups)
2052 {
2053 reloc_type = fix->fx_r_type;
2054 reloc_adjust = 0;
2055 }
2056 break;
2057 }
2058
2059 if (rxb->n_fixups)
2060 {
2061
2062 fix->fx_r_type = reloc_type;
2063 fix->fx_where += reloc_adjust;
2064 switch (reloc_type)
2065 {
2066 case BFD_RELOC_NONE:
2067 fix->fx_size = 0;
2068 break;
2069 case BFD_RELOC_8:
2070 fix->fx_size = 1;
2071 break;
2072 case BFD_RELOC_16_PCREL:
2073 case BFD_RELOC_RX_16_OP:
2074 fix->fx_size = 2;
2075 break;
2076 case BFD_RELOC_24_PCREL:
2077 case BFD_RELOC_RX_24_OP:
2078 fix->fx_size = 3;
2079 break;
2080 case BFD_RELOC_RX_32_OP:
2081 fix->fx_size = 4;
2082 break;
2083 }
2084 }
2085
2086 fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
2087 tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix,
2088 fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
2089 fragP->fr_var = 0;
2090
2091 if (fragP->fr_next != NULL
2092 && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
2093 != fragP->fr_fix))
2094 as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
2095 (long) fragP->fr_fix,
2096 (long) fragP->fr_address, (long) fragP->fr_next->fr_address);
2097 }
2098
2099 #undef OPCODE
2100
2101 int
2103 rx_validate_fix_sub (struct fix * f)
2104 {
2105 /* We permit the subtraction of two symbols in a few cases. */
2106 /* mov #sym1-sym2, R3 */
2107 if (f->fx_r_type == BFD_RELOC_RX_32_OP)
2108 return 1;
2109 /* .long sym1-sym2 */
2110 if (f->fx_r_type == BFD_RELOC_RX_DIFF
2111 && ! f->fx_pcrel
2112 && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
2113 return 1;
2114 return 0;
2115 }
2116
2117 long
2118 md_pcrel_from_section (fixS * fixP, segT sec)
2119 {
2120 long rv;
2121
2122 if (fixP->fx_addsy != NULL
2123 && (! S_IS_DEFINED (fixP->fx_addsy)
2124 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
2125 /* The symbol is undefined (or is defined but not in this section).
2126 Let the linker figure it out. */
2127 return 0;
2128
2129 rv = fixP->fx_frag->fr_address + fixP->fx_where;
2130 switch (fixP->fx_r_type)
2131 {
2132 case BFD_RELOC_RX_DIR3U_PCREL:
2133 return rv;
2134 default:
2135 return rv - 1;
2136 }
2137 }
2138
2139 void
2140 rx_cons_fix_new (fragS * frag,
2141 int where,
2142 int size,
2143 expressionS * exp)
2144 {
2145 bfd_reloc_code_real_type type;
2146
2147 switch (size)
2148 {
2149 case 1:
2150 type = BFD_RELOC_8;
2151 break;
2152 case 2:
2153 type = BFD_RELOC_16;
2154 break;
2155 case 3:
2156 type = BFD_RELOC_24;
2157 break;
2158 case 4:
2159 type = BFD_RELOC_32;
2160 break;
2161 default:
2162 as_bad (_("unsupported constant size %d\n"), size);
2163 return;
2164 }
2165
2166 if (exp->X_op == O_subtract && exp->X_op_symbol)
2167 {
2168 if (size != 4 && size != 2 && size != 1)
2169 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
2170 else
2171 type = BFD_RELOC_RX_DIFF;
2172 }
2173
2174 fix_new_exp (frag, where, (int) size, exp, 0, type);
2175 }
2176
2177 void
2178 md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
2179 valueT * t ATTRIBUTE_UNUSED,
2180 segT s ATTRIBUTE_UNUSED)
2181 {
2182 /* Instruction bytes are always little endian. */
2183 char * op;
2184 unsigned long val;
2185
2186 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
2187 return;
2188 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
2189 return;
2190
2191 #define OP2(x) op[target_big_endian ? 1-x : x]
2192 #define OP3(x) op[target_big_endian ? 2-x : x]
2193 #define OP4(x) op[target_big_endian ? 3-x : x]
2194
2195 op = f->fx_frag->fr_literal + f->fx_where;
2196 val = (unsigned long) * t;
2197
2198 /* Opcode words are always the same endian. Data words are either
2199 big or little endian. */
2200
2201 switch (f->fx_r_type)
2202 {
2203 case BFD_RELOC_NONE:
2204 break;
2205
2206 case BFD_RELOC_RX_RELAX:
2207 f->fx_done = 1;
2208 break;
2209
2210 case BFD_RELOC_RX_DIR3U_PCREL:
2211 if (val < 3 || val > 10)
2212 as_bad_where (f->fx_file, f->fx_line,
2213 _("jump not 3..10 bytes away (is %d)"), (int) val);
2214 op[0] &= 0xf8;
2215 op[0] |= val & 0x07;
2216 break;
2217
2218 case BFD_RELOC_8:
2219 case BFD_RELOC_8_PCREL:
2220 case BFD_RELOC_RX_8U:
2221 op[0] = val;
2222 break;
2223
2224 case BFD_RELOC_16:
2225 OP2(1) = val & 0xff;
2226 OP2(0) = (val >> 8) & 0xff;
2227 break;
2228
2229 case BFD_RELOC_16_PCREL:
2230 case BFD_RELOC_RX_16_OP:
2231 case BFD_RELOC_RX_16U:
2232 #if RX_OPCODE_BIG_ENDIAN
2233 op[1] = val & 0xff;
2234 op[0] = (val >> 8) & 0xff;
2235 #else
2236 op[0] = val & 0xff;
2237 op[1] = (val >> 8) & 0xff;
2238 #endif
2239 break;
2240
2241 case BFD_RELOC_24:
2242 OP3(0) = val & 0xff;
2243 OP3(1) = (val >> 8) & 0xff;
2244 OP3(2) = (val >> 16) & 0xff;
2245 break;
2246
2247 case BFD_RELOC_24_PCREL:
2248 case BFD_RELOC_RX_24_OP:
2249 case BFD_RELOC_RX_24U:
2250 #if RX_OPCODE_BIG_ENDIAN
2251 op[2] = val & 0xff;
2252 op[1] = (val >> 8) & 0xff;
2253 op[0] = (val >> 16) & 0xff;
2254 #else
2255 op[0] = val & 0xff;
2256 op[1] = (val >> 8) & 0xff;
2257 op[2] = (val >> 16) & 0xff;
2258 #endif
2259 break;
2260
2261 case BFD_RELOC_RX_DIFF:
2262 switch (f->fx_size)
2263 {
2264 case 1:
2265 op[0] = val & 0xff;
2266 break;
2267 case 2:
2268 OP2(0) = val & 0xff;
2269 OP2(1) = (val >> 8) & 0xff;
2270 break;
2271 case 4:
2272 OP4(0) = val & 0xff;
2273 OP4(1) = (val >> 8) & 0xff;
2274 OP4(2) = (val >> 16) & 0xff;
2275 OP4(3) = (val >> 24) & 0xff;
2276 break;
2277 }
2278 break;
2279
2280 case BFD_RELOC_32:
2281 OP4(0) = val & 0xff;
2282 OP4(1) = (val >> 8) & 0xff;
2283 OP4(2) = (val >> 16) & 0xff;
2284 OP4(3) = (val >> 24) & 0xff;
2285 break;
2286
2287 case BFD_RELOC_RX_32_OP:
2288 #if RX_OPCODE_BIG_ENDIAN
2289 op[3] = val & 0xff;
2290 op[2] = (val >> 8) & 0xff;
2291 op[1] = (val >> 16) & 0xff;
2292 op[0] = (val >> 24) & 0xff;
2293 #else
2294 op[0] = val & 0xff;
2295 op[1] = (val >> 8) & 0xff;
2296 op[2] = (val >> 16) & 0xff;
2297 op[3] = (val >> 24) & 0xff;
2298 #endif
2299 break;
2300
2301 case BFD_RELOC_RX_NEG8:
2302 op[0] = - val;
2303 break;
2304
2305 case BFD_RELOC_RX_NEG16:
2306 val = -val;
2307 #if RX_OPCODE_BIG_ENDIAN
2308 op[1] = val & 0xff;
2309 op[0] = (val >> 8) & 0xff;
2310 #else
2311 op[0] = val & 0xff;
2312 op[1] = (val >> 8) & 0xff;
2313 #endif
2314 break;
2315
2316 case BFD_RELOC_RX_NEG24:
2317 val = -val;
2318 #if RX_OPCODE_BIG_ENDIAN
2319 op[2] = val & 0xff;
2320 op[1] = (val >> 8) & 0xff;
2321 op[0] = (val >> 16) & 0xff;
2322 #else
2323 op[0] = val & 0xff;
2324 op[1] = (val >> 8) & 0xff;
2325 op[2] = (val >> 16) & 0xff;
2326 #endif
2327 break;
2328
2329 case BFD_RELOC_RX_NEG32:
2330 val = -val;
2331 #if RX_OPCODE_BIG_ENDIAN
2332 op[3] = val & 0xff;
2333 op[2] = (val >> 8) & 0xff;
2334 op[1] = (val >> 16) & 0xff;
2335 op[0] = (val >> 24) & 0xff;
2336 #else
2337 op[0] = val & 0xff;
2338 op[1] = (val >> 8) & 0xff;
2339 op[2] = (val >> 16) & 0xff;
2340 op[3] = (val >> 24) & 0xff;
2341 #endif
2342 break;
2343
2344 case BFD_RELOC_RX_GPRELL:
2345 val >>= 1;
2346 case BFD_RELOC_RX_GPRELW:
2347 val >>= 1;
2348 case BFD_RELOC_RX_GPRELB:
2349 #if RX_OPCODE_BIG_ENDIAN
2350 op[1] = val & 0xff;
2351 op[0] = (val >> 8) & 0xff;
2352 #else
2353 op[0] = val & 0xff;
2354 op[1] = (val >> 8) & 0xff;
2355 #endif
2356 break;
2357
2358 default:
2359 as_bad (_("Unknown reloc in md_apply_fix: %s"),
2360 bfd_get_reloc_code_name (f->fx_r_type));
2361 break;
2362 }
2363
2364 if (f->fx_addsy == NULL)
2365 f->fx_done = 1;
2366 }
2367
2368 arelent **
2369 tc_gen_reloc (asection * sec ATTRIBUTE_UNUSED, fixS * fixp)
2370 {
2371 static arelent * reloc[5];
2372 bfd_boolean is_opcode = FALSE;
2373
2374 if (fixp->fx_r_type == BFD_RELOC_NONE)
2375 {
2376 reloc[0] = NULL;
2377 return reloc;
2378 }
2379
2380 if (fixp->fx_subsy
2381 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
2382 {
2383 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
2384 fixp->fx_subsy = NULL;
2385 }
2386
2387 reloc[0] = (arelent *) xmalloc (sizeof (arelent));
2388 reloc[0]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2389 * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2390 reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2391 reloc[0]->addend = fixp->fx_offset;
2392
2393 if (fixp->fx_r_type == BFD_RELOC_RX_32_OP
2394 && fixp->fx_subsy)
2395 {
2396 fixp->fx_r_type = BFD_RELOC_RX_DIFF;
2397 is_opcode = TRUE;
2398 }
2399 else if (sec)
2400 is_opcode = sec->flags & SEC_CODE;
2401
2402 /* Certain BFD relocations cannot be translated directly into
2403 a single (non-Red Hat) RX relocation, but instead need
2404 multiple RX relocations - handle them here. */
2405 switch (fixp->fx_r_type)
2406 {
2407 case BFD_RELOC_RX_DIFF:
2408 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2409
2410 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2411 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2412 * reloc[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2413 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2414 reloc[1]->addend = 0;
2415 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2416
2417 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2418 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2419 reloc[2]->addend = 0;
2420 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2421 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2422
2423 reloc[3] = (arelent *) xmalloc (sizeof (arelent));
2424 switch (fixp->fx_size)
2425 {
2426 case 1:
2427 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS8);
2428 break;
2429 case 2:
2430 if (!is_opcode && target_big_endian)
2431 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16_REV);
2432 else if (is_opcode)
2433 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL);
2434 else
2435 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16);
2436 break;
2437 case 4:
2438 if (!is_opcode && target_big_endian)
2439 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32_REV);
2440 else
2441 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
2442 break;
2443 }
2444 reloc[3]->addend = 0;
2445 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2446 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2447
2448 reloc[4] = NULL;
2449 break;
2450
2451 case BFD_RELOC_RX_GPRELL:
2452 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2453
2454 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2455 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2456 if (gp_symbol == NULL)
2457 {
2458 if (symbol_table_frozen)
2459 {
2460 symbolS * gp;
2461
2462 gp = symbol_find ("__gp");
2463 if (gp == NULL)
2464 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2465 else
2466 gp_symbol = symbol_get_bfdsym (gp);
2467 }
2468 else
2469 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2470 }
2471 * reloc[1]->sym_ptr_ptr = gp_symbol;
2472 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2473 reloc[1]->addend = 0;
2474 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2475
2476 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2477 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2478 reloc[2]->addend = 0;
2479 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2480 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2481
2482 reloc[3] = (arelent *) xmalloc (sizeof (arelent));
2483 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL);
2484 reloc[3]->addend = 0;
2485 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2486 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2487
2488 reloc[4] = NULL;
2489 break;
2490
2491 case BFD_RELOC_RX_GPRELW:
2492 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2493
2494 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2495 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2496 if (gp_symbol == NULL)
2497 {
2498 if (symbol_table_frozen)
2499 {
2500 symbolS * gp;
2501
2502 gp = symbol_find ("__gp");
2503 if (gp == NULL)
2504 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2505 else
2506 gp_symbol = symbol_get_bfdsym (gp);
2507 }
2508 else
2509 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2510 }
2511 * reloc[1]->sym_ptr_ptr = gp_symbol;
2512 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2513 reloc[1]->addend = 0;
2514 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2515
2516 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2517 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2518 reloc[2]->addend = 0;
2519 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2520 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2521
2522 reloc[3] = (arelent *) xmalloc (sizeof (arelent));
2523 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UW);
2524 reloc[3]->addend = 0;
2525 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2526 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2527
2528 reloc[4] = NULL;
2529 break;
2530
2531 case BFD_RELOC_RX_GPRELB:
2532 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2533
2534 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2535 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2536 if (gp_symbol == NULL)
2537 {
2538 if (symbol_table_frozen)
2539 {
2540 symbolS * gp;
2541
2542 gp = symbol_find ("__gp");
2543 if (gp == NULL)
2544 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2545 else
2546 gp_symbol = symbol_get_bfdsym (gp);
2547 }
2548 else
2549 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2550 }
2551 * reloc[1]->sym_ptr_ptr = gp_symbol;
2552 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2553 reloc[1]->addend = 0;
2554 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2555
2556 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2557 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2558 reloc[2]->addend = 0;
2559 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2560 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2561
2562 reloc[3] = (arelent *) xmalloc (sizeof (arelent));
2563 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16U);
2564 reloc[3]->addend = 0;
2565 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2566 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2567
2568 reloc[4] = NULL;
2569 break;
2570
2571 case BFD_RELOC_RX_NEG32:
2572 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2573
2574 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2575 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_NEG);
2576 reloc[1]->addend = 0;
2577 reloc[1]->sym_ptr_ptr = reloc[0]->sym_ptr_ptr;
2578 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2579
2580 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2581 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
2582 reloc[2]->addend = 0;
2583 reloc[2]->sym_ptr_ptr = reloc[0]->sym_ptr_ptr;
2584 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2585
2586 reloc[3] = NULL;
2587 break;
2588
2589 default:
2590 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2591 reloc[1] = NULL;
2592 break;
2593 }
2594
2595 return reloc;
2596 }
2597
2598 /* Set the ELF specific flags. */
2599
2600 void
2601 rx_elf_final_processing (void)
2602 {
2603 elf_elfheader (stdoutput)->e_flags |= elf_flags;
2604 }
2605
2606 /* Scan the current input line for occurances of Renesas
2607 local labels and replace them with the GAS version. */
2608
2609 void
2610 rx_start_line (void)
2611 {
2612 int in_double_quote = 0;
2613 int in_single_quote = 0;
2614 int done = 0;
2615 char * p = input_line_pointer;
2616
2617 /* Scan the line looking for question marks. Skip past quote enclosed regions. */
2618 do
2619 {
2620 switch (*p)
2621 {
2622 case '\n':
2623 case 0:
2624 done = 1;
2625 break;
2626
2627 case '"':
2628 in_double_quote = ! in_double_quote;
2629 break;
2630
2631 case '\'':
2632 in_single_quote = ! in_single_quote;
2633 break;
2634
2635 case '?':
2636 if (in_double_quote || in_single_quote)
2637 break;
2638
2639 if (p[1] == ':')
2640 *p = '1';
2641 else if (p[1] == '+')
2642 {
2643 p[0] = '1';
2644 p[1] = 'f';
2645 }
2646 else if (p[1] == '-')
2647 {
2648 p[0] = '1';
2649 p[1] = 'b';
2650 }
2651 break;
2652
2653 default:
2654 break;
2655 }
2656
2657 p ++;
2658 }
2659 while (! done);
2660 }
2661