Extend objdump's --show-all-symbols option so that it also shows the extra symbols...
[binutils-gdb.git] / gas / config / tc-rx.c
blob157f8958e199d0d3a2032f172938559c13df751f
1 /* tc-rx.c -- Assembler for the Renesas RX
2 Copyright (C) 2008-2024 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to the Free
18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19 02110-1301, USA. */
21 #include "as.h"
22 #include "safe-ctype.h"
23 #include "dwarf2dbg.h"
24 #include "elf/common.h"
25 #include "elf/rx.h"
26 #include "rx-defs.h"
27 #include "filenames.h"
28 #include "listing.h"
29 #include "sb.h"
30 #include "macro.h"
32 #define RX_OPCODE_BIG_ENDIAN 0
34 const char comment_chars[] = ";";
35 /* Note that input_file.c hand checks for '#' at the beginning of the
36 first line of the input file. This is because the compiler outputs
37 #NO_APP at the beginning of its output. */
38 const char line_comment_chars[] = "#";
39 const char line_separator_chars[] = "!";
41 const char EXP_CHARS[] = "eE";
42 const char FLT_CHARS[] = "dD";
44 #ifndef TE_LINUX
45 bool rx_use_conventional_section_names = false;
46 static int elf_flags = E_FLAG_RX_ABI;
47 #else
48 bool rx_use_conventional_section_names = true;
49 static int elf_flags;
50 #endif
52 static bool rx_use_small_data_limit = false;
53 static bool rx_pid_mode = false;
54 static int rx_num_int_regs = 0;
55 int rx_pid_register;
56 int rx_gp_register;
58 enum rx_cpu_types rx_cpu = RX600;
60 static void rx_fetchalign (int ignore ATTRIBUTE_UNUSED);
62 enum options
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 OPTION_USES_GCC_ABI,
75 OPTION_USES_RX_ABI,
76 OPTION_CPU,
77 OPTION_DISALLOW_STRING_INSNS,
80 #define RX_SHORTOPTS ""
81 const char * md_shortopts = RX_SHORTOPTS;
83 /* Assembler options. */
84 struct option md_longopts[] =
86 {"mbig-endian-data", no_argument, NULL, OPTION_BIG},
87 {"mlittle-endian-data", no_argument, NULL, OPTION_LITTLE},
88 /* The next two switches are here because the
89 generic parts of the linker testsuite uses them. */
90 {"EB", no_argument, NULL, OPTION_BIG},
91 {"EL", no_argument, NULL, OPTION_LITTLE},
92 {"m32bit-doubles", no_argument, NULL, OPTION_32BIT_DOUBLES},
93 {"m64bit-doubles", no_argument, NULL, OPTION_64BIT_DOUBLES},
94 /* This option is here mainly for the binutils testsuites,
95 as many of their tests assume conventional section naming. */
96 {"muse-conventional-section-names", no_argument, NULL, OPTION_CONVENTIONAL_SECTION_NAMES},
97 {"muse-renesas-section-names", no_argument, NULL, OPTION_RENESAS_SECTION_NAMES},
98 {"msmall-data-limit", no_argument, NULL, OPTION_SMALL_DATA_LIMIT},
99 {"relax", no_argument, NULL, OPTION_RELAX},
100 {"mpid", no_argument, NULL, OPTION_PID},
101 {"mint-register", required_argument, NULL, OPTION_INT_REGS},
102 {"mgcc-abi", no_argument, NULL, OPTION_USES_GCC_ABI},
103 {"mrx-abi", no_argument, NULL, OPTION_USES_RX_ABI},
104 {"mcpu", required_argument, NULL, OPTION_CPU},
105 {"mno-allow-string-insns", no_argument, NULL, OPTION_DISALLOW_STRING_INSNS},
106 {NULL, no_argument, NULL, 0}
108 size_t md_longopts_size = sizeof (md_longopts);
110 struct cpu_type
112 const char *cpu_name;
113 enum rx_cpu_types type;
114 int flag;
117 struct cpu_type cpu_type_list[] =
119 {"rx100", RX100, 0},
120 {"rx200", RX200, 0},
121 {"rx600", RX600, 0},
122 {"rx610", RX610, 0},
123 {"rxv2", RXV2, E_FLAG_RX_V2},
124 {"rxv3", RXV3, E_FLAG_RX_V3},
125 {"rxv3-dfpu", RXV3FPU, E_FLAG_RX_V3},
129 md_parse_option (int c ATTRIBUTE_UNUSED, const char * arg ATTRIBUTE_UNUSED)
131 switch (c)
133 case OPTION_BIG:
134 target_big_endian = 1;
135 return 1;
137 case OPTION_LITTLE:
138 target_big_endian = 0;
139 return 1;
141 case OPTION_32BIT_DOUBLES:
142 elf_flags &= ~ E_FLAG_RX_64BIT_DOUBLES;
143 return 1;
145 case OPTION_64BIT_DOUBLES:
146 elf_flags |= E_FLAG_RX_64BIT_DOUBLES;
147 return 1;
149 case OPTION_CONVENTIONAL_SECTION_NAMES:
150 rx_use_conventional_section_names = true;
151 return 1;
153 case OPTION_RENESAS_SECTION_NAMES:
154 rx_use_conventional_section_names = false;
155 return 1;
157 case OPTION_SMALL_DATA_LIMIT:
158 rx_use_small_data_limit = true;
159 return 1;
161 case OPTION_RELAX:
162 linkrelax = 1;
163 return 1;
165 case OPTION_PID:
166 rx_pid_mode = true;
167 elf_flags |= E_FLAG_RX_PID;
168 return 1;
170 case OPTION_INT_REGS:
171 rx_num_int_regs = atoi (optarg);
172 return 1;
174 case OPTION_USES_GCC_ABI:
175 elf_flags &= ~ E_FLAG_RX_ABI;
176 return 1;
178 case OPTION_USES_RX_ABI:
179 elf_flags |= E_FLAG_RX_ABI;
180 return 1;
182 case OPTION_CPU:
184 unsigned int i;
185 for (i = 0; i < ARRAY_SIZE (cpu_type_list); i++)
187 if (strcasecmp (arg, cpu_type_list[i].cpu_name) == 0)
189 rx_cpu = cpu_type_list[i].type;
190 elf_flags |= cpu_type_list[i].flag;
191 return 1;
194 as_warn (_("unrecognised RX CPU type %s"), arg);
195 break;
198 case OPTION_DISALLOW_STRING_INSNS:
199 elf_flags |= E_FLAG_RX_SINSNS_SET | E_FLAG_RX_SINSNS_NO;
200 return 1;
203 return 0;
206 void
207 md_show_usage (FILE * stream)
209 fprintf (stream, _(" RX specific command line options:\n"));
210 fprintf (stream, _(" --mbig-endian-data\n"));
211 fprintf (stream, _(" --mlittle-endian-data [default]\n"));
212 fprintf (stream, _(" --m32bit-doubles [default]\n"));
213 fprintf (stream, _(" --m64bit-doubles\n"));
214 fprintf (stream, _(" --muse-conventional-section-names\n"));
215 fprintf (stream, _(" --muse-renesas-section-names [default]\n"));
216 fprintf (stream, _(" --msmall-data-limit\n"));
217 fprintf (stream, _(" --mrelax\n"));
218 fprintf (stream, _(" --mpid\n"));
219 fprintf (stream, _(" --mint-register=<value>\n"));
220 fprintf (stream, _(" --mcpu=<rx100|rx200|rx600|rx610|rxv2|rxv3|rxv3-dfpu>\n"));
221 fprintf (stream, _(" --mno-allow-string-insns"));
224 static void
225 rx_float_cons (int ignore ATTRIBUTE_UNUSED)
227 if (elf_flags & E_FLAG_RX_64BIT_DOUBLES)
228 return float_cons ('d');
229 return float_cons ('f');
232 static char *
233 rx_strcasestr (const char *string, const char *sub)
235 int subl;
236 int strl;
238 if (!sub || !sub[0])
239 return (char *)string;
241 subl = strlen (sub);
242 strl = strlen (string);
244 while (strl >= subl)
246 /* strncasecmp is in libiberty. */
247 if (strncasecmp (string, sub, subl) == 0)
248 return (char *)string;
250 string ++;
251 strl --;
253 return NULL;
256 static void
257 rx_include (int ignore)
259 FILE * try;
260 char * path;
261 char * filename;
262 const char * current_filename;
263 char * last_char;
264 const char * p;
265 const char * d;
266 char * f;
267 char end_char;
268 size_t len;
270 /* The RX version of the .INCLUDE pseudo-op does not
271 have to have the filename inside double quotes. */
272 SKIP_WHITESPACE ();
273 if (*input_line_pointer == '"')
275 /* Treat as the normal GAS .include pseudo-op. */
276 s_include (ignore);
277 return;
280 /* Get the filename. Spaces are allowed, NUL characters are not. */
281 filename = input_line_pointer;
282 last_char = find_end_of_line (filename, false);
283 input_line_pointer = last_char;
285 while (last_char >= filename && (* last_char == ' ' || * last_char == '\n'))
286 -- last_char;
287 end_char = *(++ last_char);
288 * last_char = 0;
289 if (last_char == filename)
291 as_bad (_("no filename following .INCLUDE pseudo-op"));
292 * last_char = end_char;
293 return;
296 current_filename = as_where (NULL);
297 f = XNEWVEC (char, strlen (current_filename) + strlen (filename) + 1);
299 /* Check the filename. If [@]..FILE[@] is found then replace
300 this with the current assembler source filename, stripped
301 of any directory prefixes or extensions. */
302 if ((p = rx_strcasestr (filename, "..file")) != NULL)
304 const char * c;
306 len = 6; /* strlen ("..file"); */
308 if (p > filename && p[-1] == '@')
309 -- p, ++len;
311 if (p[len] == '@')
312 len ++;
314 for (d = c = current_filename; *c; c++)
315 if (IS_DIR_SEPARATOR (* c))
316 d = c + 1;
317 for (c = d; *c; c++)
318 if (*c == '.')
319 break;
321 sprintf (f, "%.*s%.*s%.*s", (int) (p - filename), filename,
322 (int) (c - d), d,
323 (int) (strlen (filename) - ((p + len) - filename)),
324 p + len);
326 else
327 strcpy (f, filename);
329 /* RX .INCLUDE semantics say that 'filename' is located by:
331 1. If filename is absolute, just try that. Otherwise...
333 2. If the current source file includes a directory component
334 then prepend that to the filename and try. Otherwise...
336 3. Try any directories specified by the -I command line
337 option(s).
339 4 .Try a directory specified by the INC100 environment variable. */
341 if (IS_ABSOLUTE_PATH (f))
342 try = fopen (path = f, FOPEN_RT);
343 else
345 char * env = getenv ("INC100");
347 try = NULL;
349 len = strlen (current_filename);
350 if ((size_t) include_dir_maxlen > len)
351 len = include_dir_maxlen;
352 if (env && strlen (env) > len)
353 len = strlen (env);
355 path = XNEWVEC (char, strlen (f) + len + 5);
357 if (current_filename != NULL)
359 for (d = NULL, p = current_filename; *p; p++)
360 if (IS_DIR_SEPARATOR (* p))
361 d = p;
363 if (d != NULL)
365 sprintf (path, "%.*s/%s", (int) (d - current_filename), current_filename,
367 try = fopen (path, FOPEN_RT);
371 if (try == NULL)
373 for (size_t i = 0; i < include_dir_count; i++)
375 sprintf (path, "%s/%s", include_dirs[i], f);
376 if ((try = fopen (path, FOPEN_RT)) != NULL)
377 break;
381 if (try == NULL && env != NULL)
383 sprintf (path, "%s/%s", env, f);
384 try = fopen (path, FOPEN_RT);
387 free (f);
390 if (try == NULL)
392 as_bad (_("unable to locate include file: %s"), filename);
393 free (path);
395 else
397 fclose (try);
398 register_dependency (path);
399 input_scrub_insert_file (path);
402 * last_char = end_char;
405 static void
406 parse_rx_section (char * name)
408 asection * sec;
409 int type;
410 int attr = SHF_ALLOC | SHF_EXECINSTR;
411 int align = 1;
412 char end_char;
416 char * p;
418 SKIP_WHITESPACE ();
419 for (p = input_line_pointer; *p && strchr ("\n\t, =", *p) == NULL; p++)
421 end_char = *p;
422 *p = 0;
424 if (strcasecmp (input_line_pointer, "ALIGN") == 0)
426 *p = end_char;
428 if (end_char == ' ')
429 while (ISSPACE (*p))
430 p++;
432 if (*p == '=')
434 ++ p;
435 while (ISSPACE (*p))
436 p++;
437 switch (*p)
439 case '2': align = 1; break;
440 case '4': align = 2; break;
441 case '8': align = 3; break;
442 default:
443 as_bad (_("unrecognised alignment value in .SECTION directive: %s"), p);
444 ignore_rest_of_line ();
445 return;
447 ++ p;
450 end_char = *p;
452 else if (strcasecmp (input_line_pointer, "CODE") == 0)
453 attr = SHF_ALLOC | SHF_EXECINSTR;
454 else if (strcasecmp (input_line_pointer, "DATA") == 0)
455 attr = SHF_ALLOC | SHF_WRITE;
456 else if (strcasecmp (input_line_pointer, "ROMDATA") == 0)
457 attr = SHF_ALLOC;
458 else
460 as_bad (_("unknown parameter following .SECTION directive: %s"),
461 input_line_pointer);
463 *p = end_char;
464 input_line_pointer = p + 1;
465 ignore_rest_of_line ();
466 return;
469 *p = end_char;
470 input_line_pointer = p + 1;
472 while (end_char != '\n' && end_char != 0);
474 if ((sec = bfd_get_section_by_name (stdoutput, name)) == NULL)
476 if (strcmp (name, "B") && strcmp (name, "B_1") && strcmp (name, "B_2"))
477 type = SHT_NULL;
478 else
479 type = SHT_NOBITS;
481 obj_elf_change_section (name, type, attr, 0, NULL, false);
483 else /* Try not to redefine a section, especially B_1. */
485 int flags = sec->flags;
487 type = elf_section_type (sec);
489 attr = ((flags & SEC_READONLY) ? 0 : SHF_WRITE)
490 | ((flags & SEC_ALLOC) ? SHF_ALLOC : 0)
491 | ((flags & SEC_CODE) ? SHF_EXECINSTR : 0)
492 | ((flags & SEC_MERGE) ? SHF_MERGE : 0)
493 | ((flags & SEC_STRINGS) ? SHF_STRINGS : 0)
494 | ((flags & SEC_THREAD_LOCAL) ? SHF_TLS : 0);
496 obj_elf_change_section (name, type, attr, 0, NULL, false);
499 bfd_set_section_alignment (now_seg, align);
502 static void
503 rx_section (int ignore)
505 char * p;
507 /* The as100 assembler supports a different syntax for the .section
508 pseudo-op. So check for it and handle it here if necessary. */
509 SKIP_WHITESPACE ();
511 /* Peek past the section name to see if arguments follow. */
512 for (p = input_line_pointer; *p; p++)
513 if (*p == ',' || *p == '\n')
514 break;
516 if (*p == ',')
518 int len = p - input_line_pointer;
520 while (ISSPACE (*++p))
523 if (*p != '"' && *p != '#')
525 char *name = xmemdup0 (input_line_pointer, len);
527 input_line_pointer = p;
528 parse_rx_section (name);
529 return;
533 obj_elf_section (ignore);
536 static void
537 rx_list (int ignore ATTRIBUTE_UNUSED)
539 SKIP_WHITESPACE ();
541 if (strncasecmp (input_line_pointer, "OFF", 3))
542 listing_list (0);
543 else if (strncasecmp (input_line_pointer, "ON", 2))
544 listing_list (1);
545 else
546 as_warn (_("expecting either ON or OFF after .list"));
549 /* Like the .rept pseudo op, but supports the
550 use of ..MACREP inside the repeated region. */
552 static void
553 rx_rept (int ignore ATTRIBUTE_UNUSED)
555 size_t count = get_absolute_expression ();
557 do_repeat (count, "MREPEAT", "ENDR", "..MACREP");
560 /* Like cons() accept that strings are allowed. */
562 static void
563 rx_cons (int size)
565 SKIP_WHITESPACE ();
567 if (* input_line_pointer == '"')
568 stringer (8+0);
569 else
570 cons (size);
573 static void
574 rx_nop (int ignore ATTRIBUTE_UNUSED)
576 ignore_rest_of_line ();
579 static void
580 rx_unimp (int idx)
582 as_warn (_("The \".%s\" pseudo-op is not implemented\n"),
583 md_pseudo_table[idx].poc_name);
584 ignore_rest_of_line ();
587 /* The target specific pseudo-ops which we support. */
588 const pseudo_typeS md_pseudo_table[] =
590 /* These are unimplemented. They're listed first so that we can use
591 the poc_value as the index into this array, to get the name of
592 the pseudo. So, keep these (1) first, and (2) in order, with (3)
593 the poc_value's in sequence. */
594 { "btglb", rx_unimp, 0 },
595 { "call", rx_unimp, 1 },
596 { "einsf", rx_unimp, 2 },
597 { "fb", rx_unimp, 3 },
598 { "fbsym", rx_unimp, 4 },
599 { "id", rx_unimp, 5 },
600 { "initsct", rx_unimp, 6 },
601 { "insf", rx_unimp, 7 },
602 { "instr", rx_unimp, 8 },
603 { "lbba", rx_unimp, 9 },
604 { "len", rx_unimp, 10 },
605 { "optj", rx_unimp, 11 },
606 { "rvector", rx_unimp, 12 },
607 { "sb", rx_unimp, 13 },
608 { "sbbit", rx_unimp, 14 },
609 { "sbsym", rx_unimp, 15 },
610 { "sbsym16", rx_unimp, 16 },
612 /* These are the do-nothing pseudos. */
613 { "stk", rx_nop, 0 },
614 /* The manual documents ".stk" but the compiler emits ".stack". */
615 { "stack", rx_nop, 0 },
617 /* These are Renesas as100 assembler pseudo-ops that we do support. */
618 { "addr", rx_cons, 3 },
619 { "align", s_align_bytes, 2 },
620 { "byte", rx_cons, 1 },
621 { "fixed", float_cons, 'f' },
622 { "form", listing_psize, 0 },
623 { "glb", s_globl, 0 },
624 { "include", rx_include, 0 },
625 { "list", rx_list, 0 },
626 { "lword", rx_cons, 4 },
627 { "mrepeat", rx_rept, 0 },
628 { "section", rx_section, 0 },
630 /* FIXME: The following pseudo-ops place their values (and associated
631 label if present) in the data section, regardless of whatever
632 section we are currently in. At the moment this code does not
633 implement that part of the semantics. */
634 { "blka", s_space, 3 },
635 { "blkb", s_space, 1 },
636 { "blkd", s_space, 8 },
637 { "blkf", s_space, 4 },
638 { "blkl", s_space, 4 },
639 { "blkw", s_space, 2 },
641 /* Our "standard" pseudos. */
642 { "double", rx_float_cons, 0 },
643 { "3byte", cons, 3 },
644 { "int", cons, 4 },
645 { "word", cons, 4 },
647 { "fetchalign", rx_fetchalign, 0 },
649 /* End of list marker. */
650 { NULL, NULL, 0 }
653 static asymbol * gp_symbol;
654 static asymbol * rx_pid_symbol;
656 static symbolS * rx_pidreg_symbol;
657 static symbolS * rx_gpreg_symbol;
659 void
660 md_begin (void)
662 /* Make the __gp and __pid_base symbols now rather
663 than after the symbol table is frozen. We only do this
664 when supporting small data limits because otherwise we
665 pollute the symbol table. */
667 /* The meta-registers %pidreg and %gpreg depend on what other
668 options are specified. The __rx_*_defined symbols exist so we
669 can .ifdef asm code based on what options were passed to gas,
670 without needing a preprocessor */
672 if (rx_pid_mode)
674 rx_pid_register = 13 - rx_num_int_regs;
675 rx_pid_symbol = symbol_get_bfdsym (symbol_find_or_make ("__pid_base"));
676 rx_pidreg_symbol = symbol_find_or_make ("__rx_pidreg_defined");
677 S_SET_VALUE (rx_pidreg_symbol, rx_pid_register);
678 S_SET_SEGMENT (rx_pidreg_symbol, absolute_section);
681 if (rx_use_small_data_limit)
683 if (rx_pid_mode)
684 rx_gp_register = rx_pid_register - 1;
685 else
686 rx_gp_register = 13 - rx_num_int_regs;
687 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
688 rx_gpreg_symbol = symbol_find_or_make ("__rx_gpreg_defined");
689 S_SET_VALUE (rx_gpreg_symbol, rx_gp_register);
690 S_SET_SEGMENT (rx_gpreg_symbol, absolute_section);
694 char * rx_lex_start;
695 char * rx_lex_end;
697 /* These negative numbers are found in rx_bytesT.n_base for non-opcode
698 md_frags */
699 #define RX_NBASE_FETCHALIGN -1
701 typedef struct rx_bytesT
703 char base[4];
704 /* If this is negative, it's a special-purpose frag as per the defines above. */
705 int n_base;
706 char ops[8];
707 int n_ops;
708 struct
710 expressionS exp;
711 char offset;
712 char nbits;
713 char type; /* RXREL_*. */
714 int reloc;
715 fixS * fixP;
716 } fixups[2];
717 int n_fixups;
718 char post[1];
719 int n_post;
720 struct
722 char type;
723 char field_pos;
724 char val_ofs;
725 } relax[2];
726 int n_relax;
727 int link_relax;
728 fixS *link_relax_fixP;
729 unsigned long times_grown;
730 unsigned long times_shrank;
731 } rx_bytesT;
733 static rx_bytesT rx_bytes;
734 /* We set n_ops to be "size of next opcode" if the next opcode doesn't relax. */
735 static rx_bytesT *fetchalign_bytes = NULL;
737 static void
738 rx_fetchalign (int ignore ATTRIBUTE_UNUSED)
740 char * bytes;
741 fragS * frag_then;
743 memset (& rx_bytes, 0, sizeof (rx_bytes));
744 rx_bytes.n_base = RX_NBASE_FETCHALIGN;
746 bytes = frag_more (8);
747 frag_then = frag_now;
748 frag_variant (rs_machine_dependent,
749 0 /* max_chars */,
750 0 /* var */,
751 0 /* subtype */,
752 0 /* symbol */,
753 0 /* offset */,
754 0 /* opcode */);
755 frag_then->fr_opcode = bytes;
756 frag_then->fr_subtype = 0;
757 fetchalign_bytes = frag_then->tc_frag_data;
760 void
761 rx_relax (int type, int pos)
763 rx_bytes.relax[rx_bytes.n_relax].type = type;
764 rx_bytes.relax[rx_bytes.n_relax].field_pos = pos;
765 rx_bytes.relax[rx_bytes.n_relax].val_ofs = rx_bytes.n_base + rx_bytes.n_ops;
766 rx_bytes.n_relax ++;
769 void
770 rx_linkrelax_dsp (int pos)
772 switch (pos)
774 case 4:
775 rx_bytes.link_relax |= RX_RELAXA_DSP4;
776 break;
777 case 6:
778 rx_bytes.link_relax |= RX_RELAXA_DSP6;
779 break;
780 case 14:
781 rx_bytes.link_relax |= RX_RELAXA_DSP14;
782 break;
786 void
787 rx_linkrelax_imm (int pos)
789 switch (pos)
791 case 6:
792 rx_bytes.link_relax |= RX_RELAXA_IMM6;
793 break;
794 case 12:
795 rx_bytes.link_relax |= RX_RELAXA_IMM12;
796 break;
800 void
801 rx_linkrelax_branch (void)
803 rx_bytes.link_relax |= RX_RELAXA_BRA;
806 static void
807 rx_fixup (expressionS exp, int offsetbits, int nbits, int type)
809 rx_bytes.fixups[rx_bytes.n_fixups].exp = exp;
810 rx_bytes.fixups[rx_bytes.n_fixups].offset = offsetbits;
811 rx_bytes.fixups[rx_bytes.n_fixups].nbits = nbits;
812 rx_bytes.fixups[rx_bytes.n_fixups].type = type;
813 rx_bytes.fixups[rx_bytes.n_fixups].reloc = exp.X_md;
814 rx_bytes.n_fixups ++;
817 #define rx_field_fixup(exp, offset, nbits, type) \
818 rx_fixup (exp, offset, nbits, type)
820 #define rx_op_fixup(exp, offset, nbits, type) \
821 rx_fixup (exp, offset + 8 * rx_bytes.n_base, nbits, type)
823 void
824 rx_base1 (int b1)
826 rx_bytes.base[0] = b1;
827 rx_bytes.n_base = 1;
830 void
831 rx_base2 (int b1, int b2)
833 rx_bytes.base[0] = b1;
834 rx_bytes.base[1] = b2;
835 rx_bytes.n_base = 2;
838 void
839 rx_base3 (int b1, int b2, int b3)
841 rx_bytes.base[0] = b1;
842 rx_bytes.base[1] = b2;
843 rx_bytes.base[2] = b3;
844 rx_bytes.n_base = 3;
847 void
848 rx_base4 (int b1, int b2, int b3, int b4)
850 rx_bytes.base[0] = b1;
851 rx_bytes.base[1] = b2;
852 rx_bytes.base[2] = b3;
853 rx_bytes.base[3] = b4;
854 rx_bytes.n_base = 4;
857 /* This gets complicated when the field spans bytes, because fields
858 are numbered from the MSB of the first byte as zero, and bits are
859 stored LSB towards the LSB of the byte. Thus, a simple four-bit
860 insertion of 12 at position 4 of 0x00 yields: 0x0b. A three-bit
861 insertion of b'MXL at position 7 is like this:
863 - - - - - - - - - - - - - - - -
864 M X L */
866 void
867 rx_field (int val, int pos, int sz)
869 int valm;
870 int bytep, bitp;
872 if (sz > 0)
874 if (val < 0 || val >= (1 << sz))
875 as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz);
877 else
879 sz = - sz;
880 if (val < -(1 << (sz - 1)) || val >= (1 << (sz - 1)))
881 as_bad (_("Value %d doesn't fit in signed %d-bit field"), val, sz);
884 /* This code points at 'M' in the above example. */
885 bytep = pos / 8;
886 bitp = pos % 8;
888 while (bitp + sz > 8)
890 int ssz = 8 - bitp;
891 int svalm;
893 svalm = val >> (sz - ssz);
894 svalm = svalm & ((1 << ssz) - 1);
895 svalm = svalm << (8 - bitp - ssz);
896 gas_assert (bytep < rx_bytes.n_base);
897 rx_bytes.base[bytep] |= svalm;
899 bitp = 0;
900 sz -= ssz;
901 bytep ++;
903 valm = val & ((1 << sz) - 1);
904 valm = valm << (8 - bitp - sz);
905 gas_assert (bytep < rx_bytes.n_base);
906 rx_bytes.base[bytep] |= valm;
909 /* Special case of the above, for 3-bit displacements of 2..9. */
911 void
912 rx_disp3 (expressionS exp, int pos)
914 rx_field_fixup (exp, pos, 3, RXREL_PCREL);
917 /* Special case of the above, for split 5-bit displacements. Assumes
918 the displacement has been checked with rx_disp5op. */
919 /* ---- -432 1--- 0--- */
921 void
922 rx_field5s (expressionS exp)
924 int val;
926 val = exp.X_add_number;
927 rx_bytes.base[0] |= val >> 2;
928 rx_bytes.base[1] |= (val << 6) & 0x80;
929 rx_bytes.base[1] |= (val << 3) & 0x08;
932 /* ---- ---- 4--- 3210 */
934 void
935 rx_field5s2 (expressionS exp)
937 int val;
939 val = exp.X_add_number;
940 rx_bytes.base[1] |= (val << 3) & 0x80;
941 rx_bytes.base[1] |= (val ) & 0x0f;
944 void
945 rx_bfield(expressionS s, expressionS d, expressionS w)
947 int slsb = s.X_add_number;
948 int dlsb = d.X_add_number;
949 int width = w.X_add_number;
950 unsigned int imm =
951 (((dlsb + width) & 0x1f) << 10 | (dlsb << 5) |
952 ((dlsb - slsb) & 0x1f));
953 if ((slsb + width) > 32)
954 as_warn (_("Value %d and %d out of range"), slsb, width);
955 if ((dlsb + width) > 32)
956 as_warn (_("Value %d and %d out of range"), dlsb, width);
957 rx_bytes.ops[0] = imm & 0xff;
958 rx_bytes.ops[1] = (imm >> 8);
959 rx_bytes.n_ops = 2;
962 #define OP(x) rx_bytes.ops[rx_bytes.n_ops++] = (x)
964 #define F_PRECISION 2
966 void
967 rx_op (expressionS exp, int nbytes, int type)
969 offsetT v = 0;
971 if ((exp.X_op == O_constant || exp.X_op == O_big)
972 && type != RXREL_PCREL)
974 if (exp.X_op == O_big)
976 if (exp.X_add_number == -1)
978 LITTLENUM_TYPE w[2];
979 char * ip = rx_bytes.ops + rx_bytes.n_ops;
981 gen_to_words (w, F_PRECISION, 8);
982 #if RX_OPCODE_BIG_ENDIAN
983 ip[0] = w[0] >> 8;
984 ip[1] = w[0];
985 ip[2] = w[1] >> 8;
986 ip[3] = w[1];
987 #else
988 ip[3] = w[0] >> 8;
989 ip[2] = w[0];
990 ip[1] = w[1] >> 8;
991 ip[0] = w[1];
992 #endif
993 rx_bytes.n_ops += 4;
994 return;
997 v = ((generic_bignum[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
998 | (generic_bignum[0] & LITTLENUM_MASK);
1001 else
1002 v = exp.X_add_number;
1004 while (nbytes)
1006 #if RX_OPCODE_BIG_ENDIAN
1007 OP ((v >> (8 * (nbytes - 1))) & 0xff);
1008 #else
1009 OP (v & 0xff);
1010 v >>= 8;
1011 #endif
1012 nbytes --;
1015 else
1017 rx_op_fixup (exp, rx_bytes.n_ops * 8, nbytes * 8, type);
1018 memset (rx_bytes.ops + rx_bytes.n_ops, 0, nbytes);
1019 rx_bytes.n_ops += nbytes;
1023 void rx_post(char byte)
1025 rx_bytes.post[rx_bytes.n_post++] = byte;
1029 rx_wrap (void)
1031 return 0;
1034 #define APPEND(B, N_B) \
1035 if (rx_bytes.N_B) \
1037 memcpy (bytes + idx, rx_bytes.B, rx_bytes.N_B); \
1038 idx += rx_bytes.N_B; \
1041 void
1042 rx_frag_init (fragS * fragP)
1044 if (rx_bytes.n_relax || rx_bytes.link_relax || rx_bytes.n_base < 0)
1046 fragP->tc_frag_data = XNEW (rx_bytesT);
1047 memcpy (fragP->tc_frag_data, & rx_bytes, sizeof (rx_bytesT));
1049 else
1050 fragP->tc_frag_data = 0;
1053 /* Handle the as100's version of the .equ pseudo-op. It has the syntax:
1054 <symbol_name> .equ <expression> */
1056 static void
1057 rx_equ (char * name, char * expression)
1059 char saved_name_end_char;
1060 char * name_end;
1061 char * saved_ilp;
1063 while (ISSPACE (* name))
1064 name ++;
1066 for (name_end = name + 1; *name_end; name_end ++)
1067 if (! ISALNUM (* name_end))
1068 break;
1070 saved_name_end_char = * name_end;
1071 * name_end = 0;
1073 saved_ilp = input_line_pointer;
1074 input_line_pointer = expression;
1076 equals (name, 1);
1078 input_line_pointer = saved_ilp;
1079 * name_end = saved_name_end_char;
1082 /* Look for Renesas as100 pseudo-ops that occur after a symbol name
1083 rather than at the start of a line. (eg .EQU or .DEFINE). If one
1084 is found, process it and return TRUE otherwise return FALSE. */
1086 static bool
1087 scan_for_infix_rx_pseudo_ops (char * str)
1089 char * p;
1090 char * pseudo_op;
1091 char * dot = strchr (str, '.');
1093 if (dot == NULL || dot == str)
1094 return false;
1096 /* A real pseudo-op must be preceded by whitespace. */
1097 if (dot[-1] != ' ' && dot[-1] != '\t')
1098 return false;
1100 pseudo_op = dot + 1;
1102 if (!ISALNUM (* pseudo_op))
1103 return false;
1105 for (p = pseudo_op + 1; ISALNUM (* p); p++)
1108 if (strncasecmp ("EQU", pseudo_op, p - pseudo_op) == 0)
1109 rx_equ (str, p);
1110 else if (strncasecmp ("DEFINE", pseudo_op, p - pseudo_op) == 0)
1111 as_warn (_("The .DEFINE pseudo-op is not implemented"));
1112 else if (strncasecmp ("MACRO", pseudo_op, p - pseudo_op) == 0)
1113 as_warn (_("The .MACRO pseudo-op is not implemented"));
1114 else if (strncasecmp ("BTEQU", pseudo_op, p - pseudo_op) == 0)
1115 as_warn (_("The .BTEQU pseudo-op is not implemented."));
1116 else
1117 return false;
1119 return true;
1122 void
1123 md_assemble (char * str)
1125 char * bytes;
1126 int idx = 0;
1127 int i, rel;
1128 fragS * frag_then = frag_now;
1129 expressionS *exp;
1131 memset (& rx_bytes, 0, sizeof (rx_bytes));
1133 rx_lex_init (str, str + strlen (str));
1134 if (scan_for_infix_rx_pseudo_ops (str))
1135 return;
1136 rx_parse ();
1138 /* This simplifies the relaxation code. */
1139 if (rx_bytes.n_relax || rx_bytes.link_relax)
1141 /* We do it this way because we want the frag to have the
1142 rx_bytes in it, which we initialize above. */
1143 bytes = frag_more (12);
1144 frag_then = frag_now;
1145 frag_variant (rs_machine_dependent,
1146 0 /* max_chars */,
1147 0 /* var */,
1148 0 /* subtype */,
1149 0 /* symbol */,
1150 0 /* offset */,
1151 0 /* opcode */);
1152 frag_then->fr_opcode = bytes;
1153 frag_then->fr_fix += rx_bytes.n_base + rx_bytes.n_ops + rx_bytes.n_post;
1154 frag_then->fr_subtype = rx_bytes.n_base + rx_bytes.n_ops + rx_bytes.n_post;
1156 else
1158 bytes = frag_more (rx_bytes.n_base + rx_bytes.n_ops + rx_bytes.n_post);
1159 frag_then = frag_now;
1160 if (fetchalign_bytes)
1161 fetchalign_bytes->n_ops = rx_bytes.n_base + rx_bytes.n_ops + rx_bytes.n_post;
1164 fetchalign_bytes = NULL;
1166 APPEND (base, n_base);
1167 APPEND (ops, n_ops);
1168 APPEND (post, n_post);
1170 if (rx_bytes.link_relax && rx_bytes.n_fixups)
1172 fixS * f;
1174 f = fix_new (frag_then,
1175 (char *) bytes - frag_then->fr_literal,
1177 abs_section_sym,
1178 rx_bytes.link_relax | rx_bytes.n_fixups,
1180 BFD_RELOC_RX_RELAX);
1181 frag_then->tc_frag_data->link_relax_fixP = f;
1184 for (i = 0; i < rx_bytes.n_fixups; i ++)
1186 /* index: [nbytes][type] */
1187 static int reloc_map[5][4] =
1189 { 0, 0, 0, BFD_RELOC_RX_DIR3U_PCREL },
1190 { BFD_RELOC_8, BFD_RELOC_RX_8U, BFD_RELOC_RX_NEG8, BFD_RELOC_8_PCREL },
1191 { BFD_RELOC_RX_16_OP, BFD_RELOC_RX_16U, BFD_RELOC_RX_NEG16, BFD_RELOC_16_PCREL },
1192 { BFD_RELOC_RX_24_OP, BFD_RELOC_RX_24U, BFD_RELOC_RX_NEG24, BFD_RELOC_24_PCREL },
1193 { BFD_RELOC_RX_32_OP, BFD_RELOC_32, BFD_RELOC_RX_NEG32, BFD_RELOC_32_PCREL },
1195 fixS * f;
1197 idx = rx_bytes.fixups[i].offset / 8;
1198 rel = reloc_map [rx_bytes.fixups[i].nbits / 8][(int) rx_bytes.fixups[i].type];
1200 if (rx_bytes.fixups[i].reloc)
1201 rel = rx_bytes.fixups[i].reloc;
1203 if (frag_then->tc_frag_data)
1204 exp = & frag_then->tc_frag_data->fixups[i].exp;
1205 else
1206 exp = & rx_bytes.fixups[i].exp;
1208 f = fix_new_exp (frag_then,
1209 (char *) bytes + idx - frag_then->fr_literal,
1210 rx_bytes.fixups[i].nbits / 8,
1211 exp,
1212 rx_bytes.fixups[i].type == RXREL_PCREL ? 1 : 0,
1213 rel);
1214 if (frag_then->tc_frag_data)
1215 frag_then->tc_frag_data->fixups[i].fixP = f;
1217 dwarf2_emit_insn (idx);
1220 void
1221 rx_md_end (void)
1225 /* Write a value out to the object file, using the appropriate endianness. */
1227 void
1228 md_number_to_chars (char * buf, valueT val, int n)
1230 if (target_big_endian)
1231 number_to_chars_bigendian (buf, val, n);
1232 else
1233 number_to_chars_littleendian (buf, val, n);
1236 static struct
1238 const char * fname;
1239 int reloc;
1241 reloc_functions[] =
1243 { "gp", BFD_RELOC_GPREL16 },
1244 { 0, 0 }
1247 void
1248 md_operand (expressionS * exp ATTRIBUTE_UNUSED)
1250 int reloc = 0;
1251 int i;
1253 for (i = 0; reloc_functions[i].fname; i++)
1255 int flen = strlen (reloc_functions[i].fname);
1257 if (input_line_pointer[0] == '%'
1258 && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
1259 && input_line_pointer[flen + 1] == '(')
1261 reloc = reloc_functions[i].reloc;
1262 input_line_pointer += flen + 2;
1263 break;
1266 if (reloc == 0)
1267 return;
1269 expression (exp);
1270 if (* input_line_pointer == ')')
1271 input_line_pointer ++;
1273 exp->X_md = reloc;
1276 valueT
1277 md_section_align (segT segment, valueT size)
1279 int align = bfd_section_alignment (segment);
1280 return ((size + (1 << align) - 1) & -(1 << align));
1283 /* NOP - 1 cycle */
1284 static unsigned char nop_1[] = { 0x03};
1285 /* MOV.L R0,R0 - 1 cycle */
1286 static unsigned char nop_2[] = { 0xef, 0x00};
1287 /* MAX R0,R0 - 1 cycle */
1288 static unsigned char nop_3[] = { 0xfc, 0x13, 0x00 };
1289 /* MUL #1,R0 - 1 cycle */
1290 static unsigned char nop_4[] = { 0x76, 0x10, 0x01, 0x00 };
1291 /* MUL #1,R0 - 1 cycle */
1292 static unsigned char nop_5[] = { 0x77, 0x10, 0x01, 0x00, 0x00 };
1293 /* MUL #1,R0 - 1 cycle */
1294 static unsigned char nop_6[] = { 0x74, 0x10, 0x01, 0x00, 0x00, 0x00 };
1295 /* MAX 0x80000000,R0 - 1 cycle */
1296 static unsigned char nop_7[] = { 0xFD, 0x70, 0x40, 0x00, 0x00, 0x00, 0x80 };
1298 static unsigned char *nops[] = { NULL, nop_1, nop_2, nop_3, nop_4, nop_5, nop_6, nop_7 };
1299 #define BIGGEST_NOP 7
1301 /* When relaxing, we need to output a reloc for any .align directive
1302 so that we can retain this alignment as we adjust opcode sizes. */
1303 void
1304 rx_handle_align (fragS * frag)
1306 /* If handling an alignment frag, use an optimal NOP pattern.
1307 Only do this if a fill value has not already been provided.
1308 FIXME: This test fails if the provided fill value is zero. */
1309 if ((frag->fr_type == rs_align
1310 || frag->fr_type == rs_align_code)
1311 && subseg_text_p (now_seg))
1313 int count = (frag->fr_next->fr_address
1314 - frag->fr_address
1315 - frag->fr_fix);
1316 unsigned char *base = (unsigned char *)frag->fr_literal + frag->fr_fix;
1318 if (* base == 0)
1320 if (count > BIGGEST_NOP)
1322 base[0] = 0x2e;
1323 base[1] = count;
1324 frag->fr_var = 2;
1326 else if (count > 0)
1328 memcpy (base, nops[count], count);
1329 frag->fr_var = count;
1334 if (linkrelax
1335 && (frag->fr_type == rs_align
1336 || frag->fr_type == rs_align_code)
1337 && frag->fr_address + frag->fr_fix > 0
1338 && frag->fr_offset > 0
1339 && now_seg != bss_section)
1341 fix_new (frag, frag->fr_fix, 0,
1342 &abs_symbol, RX_RELAXA_ALIGN + frag->fr_offset,
1343 0, BFD_RELOC_RX_RELAX);
1344 /* For the purposes of relaxation, this relocation is attached
1345 to the byte *after* the alignment - i.e. the byte that must
1346 remain aligned. */
1347 fix_new (frag->fr_next, 0, 0,
1348 &abs_symbol, RX_RELAXA_ELIGN + frag->fr_offset,
1349 0, BFD_RELOC_RX_RELAX);
1353 const char *
1354 md_atof (int type, char * litP, int * sizeP)
1356 return ieee_md_atof (type, litP, sizeP, target_big_endian);
1359 symbolS *
1360 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1362 return NULL;
1365 /*----------------------------------------------------------------------*/
1366 /* To recap: we estimate everything based on md_estimate_size, then
1367 adjust based on rx_relax_frag. When it all settles, we call
1368 md_convert frag to update the bytes. The relaxation types and
1369 relocations are in fragP->tc_frag_data, which is a copy of that
1370 rx_bytes.
1372 Our scheme is as follows: fr_fix has the size of the smallest
1373 opcode (like BRA.S). We store the number of total bytes we need in
1374 fr_subtype. When we're done relaxing, we use fr_subtype and the
1375 existing opcode bytes to figure out what actual opcode we need to
1376 put in there. If the fixup isn't resolvable now, we use the
1377 maximal size. */
1379 #define TRACE_RELAX 0
1380 #define tprintf if (TRACE_RELAX) printf
1382 typedef enum
1384 OT_other,
1385 OT_bra,
1386 OT_beq,
1387 OT_bne,
1388 OT_bsr,
1389 OT_bcc
1390 } op_type_T;
1392 /* We're looking for these types of relaxations:
1394 BRA.S 00001dsp
1395 BRA.B 00101110 dspppppp
1396 BRA.W 00111000 dspppppp pppppppp
1397 BRA.A 00000100 dspppppp pppppppp pppppppp
1399 BEQ.S 00010dsp
1400 BEQ.B 00100000 dspppppp
1401 BEQ.W 00111010 dspppppp pppppppp
1403 BNE.S 00011dsp
1404 BNE.B 00100001 dspppppp
1405 BNE.W 00111011 dspppppp pppppppp
1407 BSR.W 00111001 dspppppp pppppppp
1408 BSR.A 00000101 dspppppp pppppppp pppppppp
1410 Bcc.B 0010cond dspppppp
1412 Additionally, we can synthesize longer conditional branches using
1413 pairs of opcodes, one with an inverted conditional (flip LSB):
1415 Bcc.W 0010ncnd 00000110 00111000 dspppppp pppppppp
1416 Bcc.A 0010ncnd 00000111 00000100 dspppppp pppppppp pppppppp
1417 BEQ.A 00011100 00000100 dspppppp pppppppp pppppppp
1418 BNE.A 00010100 00000100 dspppppp pppppppp pppppppp */
1420 /* Given the opcode bytes at OP, figure out which opcode it is and
1421 return the type of opcode. We use this to re-encode the opcode as
1422 a different size later. */
1424 static op_type_T
1425 rx_opcode_type (char * op)
1427 unsigned char b = (unsigned char) op[0];
1429 switch (b & 0xf8)
1431 case 0x08: return OT_bra;
1432 case 0x10: return OT_beq;
1433 case 0x18: return OT_bne;
1436 switch (b)
1438 case 0x2e: return OT_bra;
1439 case 0x38: return OT_bra;
1440 case 0x04: return OT_bra;
1442 case 0x20: return OT_beq;
1443 case 0x3a: return OT_beq;
1445 case 0x21: return OT_bne;
1446 case 0x3b: return OT_bne;
1448 case 0x39: return OT_bsr;
1449 case 0x05: return OT_bsr;
1452 if ((b & 0xf0) == 0x20)
1453 return OT_bcc;
1455 return OT_other;
1458 /* Returns zero if *addrP has the target address. Else returns nonzero
1459 if we cannot compute the target address yet. */
1461 static int
1462 rx_frag_fix_value (fragS * fragP,
1463 segT segment,
1464 int which,
1465 addressT * addrP,
1466 int need_diff,
1467 addressT * sym_addr)
1469 addressT addr = 0;
1470 rx_bytesT * b = fragP->tc_frag_data;
1471 expressionS * exp = & b->fixups[which].exp;
1473 if (need_diff && exp->X_op != O_subtract)
1474 return 1;
1476 if (exp->X_add_symbol)
1478 if (S_FORCE_RELOC (exp->X_add_symbol, 1))
1479 return 1;
1480 if (S_GET_SEGMENT (exp->X_add_symbol) != segment)
1481 return 1;
1482 addr += S_GET_VALUE (exp->X_add_symbol);
1485 if (exp->X_op_symbol)
1487 if (exp->X_op != O_subtract)
1488 return 1;
1489 if (S_FORCE_RELOC (exp->X_op_symbol, 1))
1490 return 1;
1491 if (S_GET_SEGMENT (exp->X_op_symbol) != segment)
1492 return 1;
1493 addr -= S_GET_VALUE (exp->X_op_symbol);
1495 if (sym_addr)
1496 * sym_addr = addr;
1497 addr += exp->X_add_number;
1498 * addrP = addr;
1499 return 0;
1502 /* Estimate how big the opcode is after this relax pass. The return
1503 value is the difference between fr_fix and the actual size. We
1504 compute the total size in rx_relax_frag and store it in fr_subtype,
1505 so we only need to subtract fx_fix and return it. */
1508 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
1510 int opfixsize;
1511 int delta;
1513 tprintf ("\033[32m est frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1514 (unsigned long) (fragP->fr_address
1515 + (fragP->fr_opcode - fragP->fr_literal)),
1516 (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1517 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype);
1519 /* This is the size of the opcode that's accounted for in fr_fix. */
1520 opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal);
1521 /* This is the size of the opcode that isn't. */
1522 delta = (fragP->fr_subtype - opfixsize);
1524 tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta);
1525 return delta;
1528 /* Given a frag FRAGP, return the "next" frag that contains an
1529 opcode. Assumes the next opcode is relaxable, and thus rs_machine_dependent. */
1531 static fragS *
1532 rx_next_opcode (fragS *fragP)
1534 do {
1535 fragP = fragP->fr_next;
1536 } while (fragP && fragP->fr_type != rs_machine_dependent);
1537 return fragP;
1540 /* Given the new addresses for this relax pass, figure out how big
1541 each opcode must be. We store the total number of bytes needed in
1542 fr_subtype. The return value is the difference between the size
1543 after the last pass and the size after this pass, so we use the old
1544 fr_subtype to calculate the difference. */
1547 rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch, unsigned long max_iterations)
1549 addressT addr0, sym_addr;
1550 addressT mypc;
1551 int disp;
1552 int oldsize = fragP->fr_subtype;
1553 int newsize = oldsize;
1554 op_type_T optype;
1555 /* Index of relaxation we care about. */
1556 int ri;
1558 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",
1559 (unsigned long) (fragP->fr_address
1560 + (fragP->fr_opcode - fragP->fr_literal)),
1561 (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1562 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype, stretch);
1564 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1566 if (fragP->tc_frag_data->n_base == RX_NBASE_FETCHALIGN)
1568 unsigned int next_size;
1569 if (fragP->fr_next == NULL)
1570 return 0;
1572 next_size = fragP->tc_frag_data->n_ops;
1573 if (next_size == 0)
1575 fragS *n = rx_next_opcode (fragP);
1576 next_size = n->fr_subtype;
1579 fragP->fr_subtype = (8-(mypc & 7)) & 7;
1580 tprintf("subtype %u\n", fragP->fr_subtype);
1581 if (fragP->fr_subtype >= next_size)
1582 fragP->fr_subtype = 0;
1583 tprintf ("\033[34m -> mypc %lu next_size %u new %d old %d delta %d (fetchalign)\033[0m\n",
1584 (unsigned long) (mypc & 7),
1585 next_size, fragP->fr_subtype, oldsize, fragP->fr_subtype-oldsize);
1587 newsize = fragP->fr_subtype;
1589 return newsize - oldsize;
1592 optype = rx_opcode_type (fragP->fr_opcode);
1594 /* In the one case where we have both a disp and imm relaxation, we want
1595 the imm relaxation here. */
1596 ri = 0;
1597 if (fragP->tc_frag_data->n_relax > 1
1598 && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1599 ri = 1;
1601 /* Try to get the target address. */
1602 if (rx_frag_fix_value (fragP, segment, ri, & addr0,
1603 fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH,
1604 & sym_addr))
1606 /* If we don't, we must use the maximum size for the linker.
1607 Note that we don't use synthetically expanded conditionals
1608 for this. */
1609 switch (fragP->tc_frag_data->relax[ri].type)
1611 case RX_RELAX_BRANCH:
1612 switch (optype)
1614 case OT_bra:
1615 case OT_bsr:
1616 newsize = 4;
1617 break;
1618 case OT_beq:
1619 case OT_bne:
1620 newsize = 3;
1621 break;
1622 case OT_bcc:
1623 newsize = 2;
1624 break;
1625 case OT_other:
1626 newsize = oldsize;
1627 break;
1629 break;
1631 case RX_RELAX_IMM:
1632 newsize = fragP->tc_frag_data->relax[ri].val_ofs + 4;
1633 break;
1635 fragP->fr_subtype = newsize;
1636 tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize);
1637 return newsize - oldsize;
1640 if (sym_addr > mypc)
1641 addr0 += stretch;
1643 switch (fragP->tc_frag_data->relax[ri].type)
1645 case RX_RELAX_BRANCH:
1646 tprintf ("branch, addr %08lx pc %08lx disp %ld\n",
1647 (unsigned long) addr0, (unsigned long) mypc,
1648 (long) (addr0 - mypc));
1649 disp = (int) addr0 - (int) mypc;
1651 switch (optype)
1653 case OT_bcc:
1654 if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1655 /* bcc.b */
1656 newsize = 2;
1657 else if (disp >= -32768 && (disp - (oldsize-5)) <= 32767)
1658 /* bncc.b/bra.w */
1659 newsize = 5;
1660 else
1661 /* bncc.b/bra.a */
1662 newsize = 6;
1663 break;
1665 case OT_beq:
1666 case OT_bne:
1667 if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1668 /* beq.s */
1669 newsize = 1;
1670 else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1671 /* beq.b */
1672 newsize = 2;
1673 else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1674 /* beq.w */
1675 newsize = 3;
1676 else
1677 /* bne.s/bra.a */
1678 newsize = 5;
1679 break;
1681 case OT_bra:
1682 case OT_bsr:
1683 if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1684 /* bra.s */
1685 newsize = 1;
1686 else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1687 /* bra.b */
1688 newsize = 2;
1689 else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1690 /* bra.w */
1691 newsize = 3;
1692 else
1693 /* bra.a */
1694 newsize = 4;
1695 break;
1697 case OT_other:
1698 break;
1700 tprintf (" - newsize %d\n", newsize);
1701 break;
1703 case RX_RELAX_IMM:
1704 tprintf ("other, addr %08lx pc %08lx LI %d OF %d\n",
1705 (unsigned long) addr0, (unsigned long) mypc,
1706 fragP->tc_frag_data->relax[ri].field_pos,
1707 fragP->tc_frag_data->relax[ri].val_ofs);
1709 newsize = fragP->tc_frag_data->relax[ri].val_ofs;
1711 if ((long) addr0 >= -128 && (long) addr0 <= 127)
1712 newsize += 1;
1713 else if ((long) addr0 >= -32768 && (long) addr0 <= 32767)
1714 newsize += 2;
1715 else if ((long) addr0 >= -8388608 && (long) addr0 <= 8388607)
1716 newsize += 3;
1717 else
1718 newsize += 4;
1719 break;
1721 default:
1722 break;
1725 if (fragP->tc_frag_data->relax[ri].type == RX_RELAX_BRANCH)
1726 switch (optype)
1728 case OT_bra:
1729 case OT_bcc:
1730 case OT_beq:
1731 case OT_bne:
1732 break;
1733 case OT_bsr:
1734 if (newsize < 3)
1735 newsize = 3;
1736 break;
1737 case OT_other:
1738 break;
1741 /* This prevents infinite loops in align-heavy sources. */
1742 if (newsize < oldsize)
1744 /* Make sure that our iteration limit is no bigger than the one being
1745 used inside write.c:relax_segment(). Otherwise we can end up
1746 iterating for too long, and triggering a fatal error there. See
1747 PR 24464 for more details. */
1748 unsigned long limit = max_iterations > 10 ? 10 : max_iterations;
1750 if (fragP->tc_frag_data->times_shrank > limit
1751 && fragP->tc_frag_data->times_grown > limit)
1752 newsize = oldsize;
1754 if (fragP->tc_frag_data->times_shrank < 20)
1755 fragP->tc_frag_data->times_shrank ++;
1757 else if (newsize > oldsize)
1759 if (fragP->tc_frag_data->times_grown < 20)
1760 fragP->tc_frag_data->times_grown ++;
1763 fragP->fr_subtype = newsize;
1764 tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
1765 return newsize - oldsize;
1768 /* This lets us test for the opcode type and the desired size in a
1769 switch statement. */
1770 #define OPCODE(type,size) ((type) * 16 + (size))
1772 /* Given the opcode stored in fr_opcode and the number of bytes we
1773 think we need, encode a new opcode. We stored a pointer to the
1774 fixup for this opcode in the tc_frag_data structure. If we can do
1775 the fixup here, we change the relocation type to "none" (we test
1776 for that in tc_gen_reloc) else we change it to the right type for
1777 the new (biggest) opcode. */
1779 void
1780 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1781 segT segment ATTRIBUTE_UNUSED,
1782 fragS * fragP ATTRIBUTE_UNUSED)
1784 rx_bytesT * rxb = fragP->tc_frag_data;
1785 addressT addr0, mypc;
1786 int disp;
1787 int reloc_adjust;
1788 bfd_reloc_code_real_type reloc_type;
1789 char * op = fragP->fr_opcode;
1790 int keep_reloc = 0;
1791 int ri;
1792 int fi = (rxb->n_fixups > 1) ? 1 : 0;
1793 fixS * fix = rxb->fixups[fi].fixP;
1795 tprintf ("\033[31mconvrt frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1796 (unsigned long) (fragP->fr_address
1797 + (fragP->fr_opcode - fragP->fr_literal)),
1798 (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1799 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type,
1800 fragP->fr_subtype);
1802 #if TRACE_RELAX
1804 int i;
1806 printf ("lit 0x%p opc 0x%p", fragP->fr_literal, fragP->fr_opcode);
1807 for (i = 0; i < 10; i++)
1808 printf (" %02x", (unsigned char) (fragP->fr_opcode[i]));
1809 printf ("\n");
1811 #endif
1813 if (fragP->tc_frag_data->n_base == RX_NBASE_FETCHALIGN)
1815 int count = fragP->fr_subtype;
1816 if (count == 0)
1818 else if (count > BIGGEST_NOP)
1820 op[0] = 0x2e;
1821 op[1] = count;
1823 else if (count > 0)
1825 memcpy (op, nops[count], count);
1829 /* In the one case where we have both a disp and imm relaxation, we want
1830 the imm relaxation here. */
1831 ri = 0;
1832 if (fragP->tc_frag_data->n_relax > 1
1833 && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1834 ri = 1;
1836 /* We used a new frag for this opcode, so the opcode address should
1837 be the frag address. */
1838 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1840 /* Try to get the target address. If we fail here, we just use the
1841 largest format. */
1842 if (rx_frag_fix_value (fragP, segment, 0, & addr0,
1843 fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH, 0))
1845 /* We don't know the target address. */
1846 keep_reloc = 1;
1847 addr0 = 0;
1848 disp = 0;
1850 else
1852 /* We know the target address, and it's in addr0. */
1853 disp = (int) addr0 - (int) mypc;
1856 if (linkrelax)
1857 keep_reloc = 1;
1859 reloc_type = BFD_RELOC_NONE;
1860 reloc_adjust = 0;
1862 tprintf ("convert, op is %d, disp %d (%lx-%lx)\n",
1863 rx_opcode_type (fragP->fr_opcode), disp,
1864 (unsigned long) addr0, (unsigned long) mypc);
1865 switch (fragP->tc_frag_data->relax[ri].type)
1867 case RX_RELAX_BRANCH:
1868 switch (OPCODE (rx_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
1870 case OPCODE (OT_bra, 1): /* BRA.S - no change. */
1871 op[0] = 0x08 + (disp & 7);
1872 break;
1873 case OPCODE (OT_bra, 2): /* BRA.B - 8 bit. */
1874 op[0] = 0x2e;
1875 op[1] = disp;
1876 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1877 reloc_adjust = 1;
1878 break;
1879 case OPCODE (OT_bra, 3): /* BRA.W - 16 bit. */
1880 op[0] = 0x38;
1881 #if RX_OPCODE_BIG_ENDIAN
1882 op[1] = (disp >> 8) & 0xff;
1883 op[2] = disp;
1884 #else
1885 op[2] = (disp >> 8) & 0xff;
1886 op[1] = disp;
1887 #endif
1888 reloc_adjust = 1;
1889 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1890 break;
1891 case OPCODE (OT_bra, 4): /* BRA.A - 24 bit. */
1892 op[0] = 0x04;
1893 #if RX_OPCODE_BIG_ENDIAN
1894 op[1] = (disp >> 16) & 0xff;
1895 op[2] = (disp >> 8) & 0xff;
1896 op[3] = disp;
1897 #else
1898 op[3] = (disp >> 16) & 0xff;
1899 op[2] = (disp >> 8) & 0xff;
1900 op[1] = disp;
1901 #endif
1902 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1903 reloc_adjust = 1;
1904 break;
1906 case OPCODE (OT_beq, 1): /* BEQ.S - no change. */
1907 op[0] = 0x10 + (disp & 7);
1908 break;
1909 case OPCODE (OT_beq, 2): /* BEQ.B - 8 bit. */
1910 op[0] = 0x20;
1911 op[1] = disp;
1912 reloc_adjust = 1;
1913 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1914 break;
1915 case OPCODE (OT_beq, 3): /* BEQ.W - 16 bit. */
1916 op[0] = 0x3a;
1917 #if RX_OPCODE_BIG_ENDIAN
1918 op[1] = (disp >> 8) & 0xff;
1919 op[2] = disp;
1920 #else
1921 op[2] = (disp >> 8) & 0xff;
1922 op[1] = disp;
1923 #endif
1924 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1925 reloc_adjust = 1;
1926 break;
1927 case OPCODE (OT_beq, 5): /* BEQ.A - synthetic. */
1928 op[0] = 0x1d; /* bne.s .+5. */
1929 op[1] = 0x04; /* bra.a dsp:24. */
1930 disp -= 1;
1931 #if RX_OPCODE_BIG_ENDIAN
1932 op[2] = (disp >> 16) & 0xff;
1933 op[3] = (disp >> 8) & 0xff;
1934 op[4] = disp;
1935 #else
1936 op[4] = (disp >> 16) & 0xff;
1937 op[3] = (disp >> 8) & 0xff;
1938 op[2] = disp;
1939 #endif
1940 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1941 reloc_adjust = 2;
1942 break;
1944 case OPCODE (OT_bne, 1): /* BNE.S - no change. */
1945 op[0] = 0x18 + (disp & 7);
1946 break;
1947 case OPCODE (OT_bne, 2): /* BNE.B - 8 bit. */
1948 op[0] = 0x21;
1949 op[1] = disp;
1950 reloc_adjust = 1;
1951 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1952 break;
1953 case OPCODE (OT_bne, 3): /* BNE.W - 16 bit. */
1954 op[0] = 0x3b;
1955 #if RX_OPCODE_BIG_ENDIAN
1956 op[1] = (disp >> 8) & 0xff;
1957 op[2] = disp;
1958 #else
1959 op[2] = (disp >> 8) & 0xff;
1960 op[1] = disp;
1961 #endif
1962 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1963 reloc_adjust = 1;
1964 break;
1965 case OPCODE (OT_bne, 5): /* BNE.A - synthetic. */
1966 op[0] = 0x15; /* beq.s .+5. */
1967 op[1] = 0x04; /* bra.a dsp:24. */
1968 disp -= 1;
1969 #if RX_OPCODE_BIG_ENDIAN
1970 op[2] = (disp >> 16) & 0xff;
1971 op[3] = (disp >> 8) & 0xff;
1972 op[4] = disp;
1973 #else
1974 op[4] = (disp >> 16) & 0xff;
1975 op[3] = (disp >> 8) & 0xff;
1976 op[2] = disp;
1977 #endif
1978 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1979 reloc_adjust = 2;
1980 break;
1982 case OPCODE (OT_bsr, 3): /* BSR.W - 16 bit. */
1983 op[0] = 0x39;
1984 #if RX_OPCODE_BIG_ENDIAN
1985 op[1] = (disp >> 8) & 0xff;
1986 op[2] = disp;
1987 #else
1988 op[2] = (disp >> 8) & 0xff;
1989 op[1] = disp;
1990 #endif
1991 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1992 reloc_adjust = 0;
1993 break;
1994 case OPCODE (OT_bsr, 4): /* BSR.A - 24 bit. */
1995 op[0] = 0x05;
1996 #if RX_OPCODE_BIG_ENDIAN
1997 op[1] = (disp >> 16) & 0xff;
1998 op[2] = (disp >> 8) & 0xff;
1999 op[3] = disp;
2000 #else
2001 op[3] = (disp >> 16) & 0xff;
2002 op[2] = (disp >> 8) & 0xff;
2003 op[1] = disp;
2004 #endif
2005 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
2006 reloc_adjust = 0;
2007 break;
2009 case OPCODE (OT_bcc, 2): /* Bcond.B - 8 bit. */
2010 op[1] = disp;
2011 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
2012 break;
2013 case OPCODE (OT_bcc, 5): /* Bcond.W - synthetic. */
2014 op[0] ^= 1; /* Invert condition. */
2015 op[1] = 5; /* Displacement. */
2016 op[2] = 0x38;
2017 disp -= 2;
2018 #if RX_OPCODE_BIG_ENDIAN
2019 op[3] = (disp >> 8) & 0xff;
2020 op[4] = disp;
2021 #else
2022 op[4] = (disp >> 8) & 0xff;
2023 op[3] = disp;
2024 #endif
2025 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
2026 reloc_adjust = 2;
2027 break;
2028 case OPCODE (OT_bcc, 6): /* Bcond.S - synthetic. */
2029 op[0] ^= 1; /* Invert condition. */
2030 op[1] = 6; /* Displacement. */
2031 op[2] = 0x04;
2032 disp -= 2;
2033 #if RX_OPCODE_BIG_ENDIAN
2034 op[3] = (disp >> 16) & 0xff;
2035 op[4] = (disp >> 8) & 0xff;
2036 op[5] = disp;
2037 #else
2038 op[5] = (disp >> 16) & 0xff;
2039 op[4] = (disp >> 8) & 0xff;
2040 op[3] = disp;
2041 #endif
2042 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
2043 reloc_adjust = 2;
2044 break;
2046 default:
2047 /* These are opcodes we'll relax in th linker, later. */
2048 if (rxb->n_fixups)
2049 reloc_type = rxb->fixups[ri].fixP->fx_r_type;
2050 break;
2052 break;
2054 case RX_RELAX_IMM:
2056 int nbytes = fragP->fr_subtype - fragP->tc_frag_data->relax[ri].val_ofs;
2057 int li;
2058 char * imm = op + fragP->tc_frag_data->relax[ri].val_ofs;
2060 switch (nbytes)
2062 case 1:
2063 li = 1;
2064 imm[0] = addr0;
2065 reloc_type = BFD_RELOC_8;
2066 break;
2067 case 2:
2068 li = 2;
2069 #if RX_OPCODE_BIG_ENDIAN
2070 imm[1] = addr0;
2071 imm[0] = addr0 >> 8;
2072 #else
2073 imm[0] = addr0;
2074 imm[1] = addr0 >> 8;
2075 #endif
2076 reloc_type = BFD_RELOC_RX_16_OP;
2077 break;
2078 case 3:
2079 li = 3;
2080 #if RX_OPCODE_BIG_ENDIAN
2081 imm[2] = addr0;
2082 imm[1] = addr0 >> 8;
2083 imm[0] = addr0 >> 16;
2084 #else
2085 imm[0] = addr0;
2086 imm[1] = addr0 >> 8;
2087 imm[2] = addr0 >> 16;
2088 #endif
2089 reloc_type = BFD_RELOC_RX_24_OP;
2090 break;
2091 case 4:
2092 li = 0;
2093 #if RX_OPCODE_BIG_ENDIAN
2094 imm[3] = addr0;
2095 imm[2] = addr0 >> 8;
2096 imm[1] = addr0 >> 16;
2097 imm[0] = addr0 >> 24;
2098 #else
2099 imm[0] = addr0;
2100 imm[1] = addr0 >> 8;
2101 imm[2] = addr0 >> 16;
2102 imm[3] = addr0 >> 24;
2103 #endif
2104 reloc_type = BFD_RELOC_RX_32_OP;
2105 break;
2106 default:
2107 as_bad (_("invalid immediate size"));
2108 li = -1;
2111 switch (fragP->tc_frag_data->relax[ri].field_pos)
2113 case 6:
2114 op[0] &= 0xfc;
2115 op[0] |= li;
2116 break;
2117 case 12:
2118 op[1] &= 0xf3;
2119 op[1] |= li << 2;
2120 break;
2121 case 20:
2122 op[2] &= 0xf3;
2123 op[2] |= li << 2;
2124 break;
2125 default:
2126 as_bad (_("invalid immediate field position"));
2129 break;
2131 default:
2132 if (rxb->n_fixups)
2134 reloc_type = fix->fx_r_type;
2135 reloc_adjust = 0;
2137 break;
2140 if (rxb->n_fixups)
2143 fix->fx_r_type = reloc_type;
2144 fix->fx_where += reloc_adjust;
2145 switch (reloc_type)
2147 case BFD_RELOC_NONE:
2148 fix->fx_size = 0;
2149 break;
2150 case BFD_RELOC_8:
2151 fix->fx_size = 1;
2152 break;
2153 case BFD_RELOC_16_PCREL:
2154 case BFD_RELOC_RX_16_OP:
2155 fix->fx_size = 2;
2156 break;
2157 case BFD_RELOC_24_PCREL:
2158 case BFD_RELOC_RX_24_OP:
2159 fix->fx_size = 3;
2160 break;
2161 case BFD_RELOC_RX_32_OP:
2162 fix->fx_size = 4;
2163 break;
2164 default:
2165 break;
2169 fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
2170 tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix,
2171 fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
2172 fragP->fr_var = 0;
2174 if (fragP->fr_next != NULL
2175 && fragP->fr_next->fr_address - fragP->fr_address != fragP->fr_fix)
2176 as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
2177 (long) fragP->fr_fix,
2178 (long) fragP->fr_address, (long) fragP->fr_next->fr_address);
2181 #undef OPCODE
2184 rx_validate_fix_sub (struct fix * f)
2186 /* We permit the subtraction of two symbols in a few cases. */
2187 /* mov #sym1-sym2, R3 */
2188 if (f->fx_r_type == BFD_RELOC_RX_32_OP)
2189 return 1;
2190 /* .long sym1-sym2 */
2191 if (f->fx_r_type == BFD_RELOC_RX_DIFF
2192 && ! f->fx_pcrel
2193 && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
2194 return 1;
2195 return 0;
2198 long
2199 md_pcrel_from_section (fixS * fixP, segT sec)
2201 long rv;
2203 if (fixP->fx_addsy != NULL
2204 && (! S_IS_DEFINED (fixP->fx_addsy)
2205 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
2206 /* The symbol is undefined (or is defined but not in this section).
2207 Let the linker figure it out. */
2208 return 0;
2210 rv = fixP->fx_frag->fr_address + fixP->fx_where;
2211 switch (fixP->fx_r_type)
2213 case BFD_RELOC_RX_DIR3U_PCREL:
2214 return rv;
2215 default:
2216 return rv - 1;
2220 void
2221 rx_cons_fix_new (fragS * frag,
2222 int where,
2223 int size,
2224 expressionS * exp,
2225 bfd_reloc_code_real_type type)
2227 switch (size)
2229 case 1:
2230 type = BFD_RELOC_8;
2231 break;
2232 case 2:
2233 type = BFD_RELOC_16;
2234 break;
2235 case 3:
2236 type = BFD_RELOC_24;
2237 break;
2238 case 4:
2239 type = BFD_RELOC_32;
2240 break;
2241 default:
2242 as_bad (_("unsupported constant size %d\n"), size);
2243 return;
2246 if (exp->X_op == O_subtract && exp->X_op_symbol)
2248 if (size != 4 && size != 2 && size != 1)
2249 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
2250 else
2251 type = BFD_RELOC_RX_DIFF;
2254 fix_new_exp (frag, where, (int) size, exp, 0, type);
2257 void
2258 md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
2259 valueT * t ATTRIBUTE_UNUSED,
2260 segT s ATTRIBUTE_UNUSED)
2262 /* Instruction bytes are always little endian. */
2263 char * op;
2264 unsigned long val;
2266 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
2267 return;
2268 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
2269 return;
2271 #define OP2(x) op[target_big_endian ? 1-x : x]
2272 #define OP3(x) op[target_big_endian ? 2-x : x]
2273 #define OP4(x) op[target_big_endian ? 3-x : x]
2275 op = f->fx_frag->fr_literal + f->fx_where;
2276 val = (unsigned long) * t;
2278 /* Opcode words are always the same endian. Data words are either
2279 big or little endian. */
2281 switch (f->fx_r_type)
2283 case BFD_RELOC_NONE:
2284 break;
2286 case BFD_RELOC_RX_RELAX:
2287 f->fx_done = 1;
2288 break;
2290 case BFD_RELOC_RX_DIR3U_PCREL:
2291 if (val < 3 || val > 10)
2292 as_bad_where (f->fx_file, f->fx_line,
2293 _("jump not 3..10 bytes away (is %d)"), (int) val);
2294 op[0] &= 0xf8;
2295 op[0] |= val & 0x07;
2296 break;
2298 case BFD_RELOC_8:
2299 case BFD_RELOC_8_PCREL:
2300 case BFD_RELOC_RX_8U:
2301 op[0] = val;
2302 break;
2304 case BFD_RELOC_16:
2305 OP2(1) = val & 0xff;
2306 OP2(0) = (val >> 8) & 0xff;
2307 break;
2309 case BFD_RELOC_16_PCREL:
2310 case BFD_RELOC_RX_16_OP:
2311 case BFD_RELOC_RX_16U:
2312 #if RX_OPCODE_BIG_ENDIAN
2313 op[1] = val & 0xff;
2314 op[0] = (val >> 8) & 0xff;
2315 #else
2316 op[0] = val & 0xff;
2317 op[1] = (val >> 8) & 0xff;
2318 #endif
2319 break;
2321 case BFD_RELOC_24:
2322 OP3(0) = val & 0xff;
2323 OP3(1) = (val >> 8) & 0xff;
2324 OP3(2) = (val >> 16) & 0xff;
2325 break;
2327 case BFD_RELOC_24_PCREL:
2328 case BFD_RELOC_RX_24_OP:
2329 case BFD_RELOC_RX_24U:
2330 #if RX_OPCODE_BIG_ENDIAN
2331 op[2] = val & 0xff;
2332 op[1] = (val >> 8) & 0xff;
2333 op[0] = (val >> 16) & 0xff;
2334 #else
2335 op[0] = val & 0xff;
2336 op[1] = (val >> 8) & 0xff;
2337 op[2] = (val >> 16) & 0xff;
2338 #endif
2339 break;
2341 case BFD_RELOC_RX_DIFF:
2342 switch (f->fx_size)
2344 case 1:
2345 op[0] = val & 0xff;
2346 break;
2347 case 2:
2348 OP2(0) = val & 0xff;
2349 OP2(1) = (val >> 8) & 0xff;
2350 break;
2351 case 4:
2352 OP4(0) = val & 0xff;
2353 OP4(1) = (val >> 8) & 0xff;
2354 OP4(2) = (val >> 16) & 0xff;
2355 OP4(3) = (val >> 24) & 0xff;
2356 break;
2358 break;
2360 case BFD_RELOC_32:
2361 OP4(0) = val & 0xff;
2362 OP4(1) = (val >> 8) & 0xff;
2363 OP4(2) = (val >> 16) & 0xff;
2364 OP4(3) = (val >> 24) & 0xff;
2365 break;
2367 case BFD_RELOC_RX_32_OP:
2368 #if RX_OPCODE_BIG_ENDIAN
2369 op[3] = val & 0xff;
2370 op[2] = (val >> 8) & 0xff;
2371 op[1] = (val >> 16) & 0xff;
2372 op[0] = (val >> 24) & 0xff;
2373 #else
2374 op[0] = val & 0xff;
2375 op[1] = (val >> 8) & 0xff;
2376 op[2] = (val >> 16) & 0xff;
2377 op[3] = (val >> 24) & 0xff;
2378 #endif
2379 break;
2381 case BFD_RELOC_RX_NEG8:
2382 op[0] = - val;
2383 break;
2385 case BFD_RELOC_RX_NEG16:
2386 val = -val;
2387 #if RX_OPCODE_BIG_ENDIAN
2388 op[1] = val & 0xff;
2389 op[0] = (val >> 8) & 0xff;
2390 #else
2391 op[0] = val & 0xff;
2392 op[1] = (val >> 8) & 0xff;
2393 #endif
2394 break;
2396 case BFD_RELOC_RX_NEG24:
2397 val = -val;
2398 #if RX_OPCODE_BIG_ENDIAN
2399 op[2] = val & 0xff;
2400 op[1] = (val >> 8) & 0xff;
2401 op[0] = (val >> 16) & 0xff;
2402 #else
2403 op[0] = val & 0xff;
2404 op[1] = (val >> 8) & 0xff;
2405 op[2] = (val >> 16) & 0xff;
2406 #endif
2407 break;
2409 case BFD_RELOC_RX_NEG32:
2410 val = -val;
2411 #if RX_OPCODE_BIG_ENDIAN
2412 op[3] = val & 0xff;
2413 op[2] = (val >> 8) & 0xff;
2414 op[1] = (val >> 16) & 0xff;
2415 op[0] = (val >> 24) & 0xff;
2416 #else
2417 op[0] = val & 0xff;
2418 op[1] = (val >> 8) & 0xff;
2419 op[2] = (val >> 16) & 0xff;
2420 op[3] = (val >> 24) & 0xff;
2421 #endif
2422 break;
2424 case BFD_RELOC_RX_GPRELL:
2425 val >>= 1;
2426 /* Fall through. */
2427 case BFD_RELOC_RX_GPRELW:
2428 val >>= 1;
2429 /* Fall through. */
2430 case BFD_RELOC_RX_GPRELB:
2431 #if RX_OPCODE_BIG_ENDIAN
2432 op[1] = val & 0xff;
2433 op[0] = (val >> 8) & 0xff;
2434 #else
2435 op[0] = val & 0xff;
2436 op[1] = (val >> 8) & 0xff;
2437 #endif
2438 break;
2440 default:
2441 as_bad (_("Unknown reloc in md_apply_fix: %s"),
2442 bfd_get_reloc_code_name (f->fx_r_type));
2443 break;
2446 if (f->fx_addsy == NULL)
2447 f->fx_done = 1;
2450 arelent **
2451 tc_gen_reloc (asection * sec ATTRIBUTE_UNUSED, fixS * fixp)
2453 static arelent * reloc[5];
2454 bool is_opcode = false;
2456 if (fixp->fx_r_type == BFD_RELOC_NONE)
2458 reloc[0] = NULL;
2459 return reloc;
2462 if (fixp->fx_subsy
2463 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
2465 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
2466 fixp->fx_subsy = NULL;
2469 reloc[0] = XNEW (arelent);
2470 reloc[0]->sym_ptr_ptr = XNEW (asymbol *);
2471 * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2472 reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2473 reloc[0]->addend = fixp->fx_offset;
2475 if (fixp->fx_r_type == BFD_RELOC_RX_32_OP
2476 && fixp->fx_subsy)
2478 fixp->fx_r_type = BFD_RELOC_RX_DIFF;
2479 is_opcode = true;
2481 else if (sec)
2482 is_opcode = sec->flags & SEC_CODE;
2484 /* Certain BFD relocations cannot be translated directly into
2485 a single (non-Red Hat) RX relocation, but instead need
2486 multiple RX relocations - handle them here. */
2487 switch (fixp->fx_r_type)
2489 case BFD_RELOC_RX_DIFF:
2490 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2492 reloc[1] = XNEW (arelent);
2493 reloc[1]->sym_ptr_ptr = XNEW (asymbol *);
2494 * reloc[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2495 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2496 reloc[1]->addend = 0;
2497 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2499 reloc[2] = XNEW (arelent);
2500 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2501 reloc[2]->addend = 0;
2502 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2503 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2505 reloc[3] = XNEW (arelent);
2506 switch (fixp->fx_size)
2508 case 1:
2509 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS8);
2510 break;
2511 case 2:
2512 if (!is_opcode && target_big_endian)
2513 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16_REV);
2514 else if (is_opcode)
2515 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL);
2516 else
2517 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16);
2518 break;
2519 case 4:
2520 if (!is_opcode && target_big_endian)
2521 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32_REV);
2522 else
2523 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
2524 break;
2526 reloc[3]->addend = 0;
2527 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2528 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2530 reloc[4] = NULL;
2531 break;
2533 case BFD_RELOC_RX_GPRELL:
2534 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2536 reloc[1] = XNEW (arelent);
2537 reloc[1]->sym_ptr_ptr = XNEW (asymbol *);
2538 if (gp_symbol == NULL)
2540 if (symbol_table_frozen)
2542 symbolS * gp;
2544 gp = symbol_find ("__gp");
2545 if (gp == NULL)
2546 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2547 else
2548 gp_symbol = symbol_get_bfdsym (gp);
2550 else
2551 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2553 * reloc[1]->sym_ptr_ptr = gp_symbol;
2554 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2555 reloc[1]->addend = 0;
2556 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2558 reloc[2] = XNEW (arelent);
2559 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2560 reloc[2]->addend = 0;
2561 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2562 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2564 reloc[3] = XNEW (arelent);
2565 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL);
2566 reloc[3]->addend = 0;
2567 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2568 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2570 reloc[4] = NULL;
2571 break;
2573 case BFD_RELOC_RX_GPRELW:
2574 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2576 reloc[1] = XNEW (arelent);
2577 reloc[1]->sym_ptr_ptr = XNEW (asymbol *);
2578 if (gp_symbol == NULL)
2580 if (symbol_table_frozen)
2582 symbolS * gp;
2584 gp = symbol_find ("__gp");
2585 if (gp == NULL)
2586 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2587 else
2588 gp_symbol = symbol_get_bfdsym (gp);
2590 else
2591 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2593 * reloc[1]->sym_ptr_ptr = gp_symbol;
2594 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2595 reloc[1]->addend = 0;
2596 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2598 reloc[2] = XNEW (arelent);
2599 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2600 reloc[2]->addend = 0;
2601 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2602 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2604 reloc[3] = XNEW (arelent);
2605 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UW);
2606 reloc[3]->addend = 0;
2607 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2608 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2610 reloc[4] = NULL;
2611 break;
2613 case BFD_RELOC_RX_GPRELB:
2614 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2616 reloc[1] = XNEW (arelent);
2617 reloc[1]->sym_ptr_ptr = XNEW (asymbol *);
2618 if (gp_symbol == NULL)
2620 if (symbol_table_frozen)
2622 symbolS * gp;
2624 gp = symbol_find ("__gp");
2625 if (gp == NULL)
2626 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2627 else
2628 gp_symbol = symbol_get_bfdsym (gp);
2630 else
2631 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2633 * reloc[1]->sym_ptr_ptr = gp_symbol;
2634 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2635 reloc[1]->addend = 0;
2636 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2638 reloc[2] = XNEW (arelent);
2639 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2640 reloc[2]->addend = 0;
2641 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2642 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2644 reloc[3] = XNEW (arelent);
2645 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16U);
2646 reloc[3]->addend = 0;
2647 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2648 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2650 reloc[4] = NULL;
2651 break;
2653 case BFD_RELOC_RX_NEG32:
2654 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2656 reloc[1] = XNEW (arelent);
2657 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_NEG);
2658 reloc[1]->addend = 0;
2659 reloc[1]->sym_ptr_ptr = reloc[0]->sym_ptr_ptr;
2660 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2662 reloc[2] = XNEW (arelent);
2663 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
2664 reloc[2]->addend = 0;
2665 reloc[2]->sym_ptr_ptr = reloc[0]->sym_ptr_ptr;
2666 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2668 reloc[3] = NULL;
2669 break;
2671 default:
2672 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2673 reloc[1] = NULL;
2674 break;
2677 return reloc;
2680 void
2681 rx_note_string_insn_use (void)
2683 if ((elf_flags & E_FLAG_RX_SINSNS_MASK) == (E_FLAG_RX_SINSNS_SET | E_FLAG_RX_SINSNS_NO))
2684 as_bad (_("Use of an RX string instruction detected in a file being assembled without string instruction support"));
2685 elf_flags |= E_FLAG_RX_SINSNS_SET | E_FLAG_RX_SINSNS_YES;
2688 /* Set the ELF specific flags. */
2690 void
2691 rx_elf_final_processing (void)
2693 elf_elfheader (stdoutput)->e_flags |= elf_flags;
2696 /* Scan the current input line for occurrences of Renesas
2697 local labels and replace them with the GAS version. */
2699 void
2700 rx_start_line (void)
2702 int in_double_quote = 0;
2703 int in_single_quote = 0;
2704 int done = 0;
2705 char * p = input_line_pointer;
2706 char prev_char = 0;
2708 /* Scan the line looking for question marks. Skip past quote enclosed regions. */
2711 switch (*p)
2713 case '\n':
2714 case 0:
2715 done = 1;
2716 break;
2718 case '"':
2719 /* Handle escaped double quote \" inside a string. */
2720 if (prev_char != '\\')
2721 in_double_quote = ! in_double_quote;
2722 break;
2724 case '\'':
2725 in_single_quote = ! in_single_quote;
2726 break;
2728 case '?':
2729 if (in_double_quote || in_single_quote)
2730 break;
2732 if (p[1] == ':')
2733 *p = '1';
2734 else if (p[1] == '+')
2736 p[0] = '1';
2737 p[1] = 'f';
2739 else if (p[1] == '-')
2741 p[0] = '1';
2742 p[1] = 'b';
2744 break;
2746 default:
2747 break;
2750 prev_char = *p++;
2752 while (! done);