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