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