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