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