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