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