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