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