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