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