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