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