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