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