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