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