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