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