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