* config/tc-rx.c (rx_bytesT): Add grown/shrank counters for
[deliverable/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 /* When relaxing, we need to output a reloc for any .align directive
1123 so that we can retain this alignment as we adjust opcode sizes. */
1124 void
1125 rx_handle_align (fragS * frag)
1126 {
1127 if (linkrelax
1128 && (frag->fr_type == rs_align
1129 || frag->fr_type == rs_align_code)
1130 && frag->fr_address + frag->fr_fix > 0
1131 && frag->fr_offset > 0
1132 && now_seg != bss_section)
1133 {
1134 fix_new (frag, frag->fr_fix, 0,
1135 &abs_symbol, RX_RELAXA_ALIGN + frag->fr_offset,
1136 0, BFD_RELOC_RX_RELAX);
1137 /* For the purposes of relaxation, this relocation is attached
1138 to the byte *after* the alignment - i.e. the byte that must
1139 remain aligned. */
1140 fix_new (frag->fr_next, 0, 0,
1141 &abs_symbol, RX_RELAXA_ELIGN + frag->fr_offset,
1142 0, BFD_RELOC_RX_RELAX);
1143 }
1144 }
1145
1146 char *
1147 md_atof (int type, char * litP, int * sizeP)
1148 {
1149 return ieee_md_atof (type, litP, sizeP, target_big_endian);
1150 }
1151
1152 symbolS *
1153 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1154 {
1155 return NULL;
1156 }
1157
1158 /*----------------------------------------------------------------------*/
1159 /* To recap: we estimate everything based on md_estimate_size, then
1160 adjust based on rx_relax_frag. When it all settles, we call
1161 md_convert frag to update the bytes. The relaxation types and
1162 relocations are in fragP->tc_frag_data, which is a copy of that
1163 rx_bytes.
1164
1165 Our scheme is as follows: fr_fix has the size of the smallest
1166 opcode (like BRA.S). We store the number of total bytes we need in
1167 fr_subtype. When we're done relaxing, we use fr_subtype and the
1168 existing opcode bytes to figure out what actual opcode we need to
1169 put in there. If the fixup isn't resolvable now, we use the
1170 maximal size. */
1171
1172 #define TRACE_RELAX 0
1173 #define tprintf if (TRACE_RELAX) printf
1174
1175 typedef enum
1176 {
1177 OT_other,
1178 OT_bra,
1179 OT_beq,
1180 OT_bne,
1181 OT_bsr,
1182 OT_bcc
1183 } op_type_T;
1184
1185 /* We're looking for these types of relaxations:
1186
1187 BRA.S 00001dsp
1188 BRA.B 00101110 dspppppp
1189 BRA.W 00111000 dspppppp pppppppp
1190 BRA.A 00000100 dspppppp pppppppp pppppppp
1191
1192 BEQ.S 00010dsp
1193 BEQ.B 00100000 dspppppp
1194 BEQ.W 00111010 dspppppp pppppppp
1195
1196 BNE.S 00011dsp
1197 BNE.B 00100001 dspppppp
1198 BNE.W 00111011 dspppppp pppppppp
1199
1200 BSR.W 00111001 dspppppp pppppppp
1201 BSR.A 00000101 dspppppp pppppppp pppppppp
1202
1203 Bcc.B 0010cond dspppppp
1204
1205 Additionally, we can synthesize longer conditional branches using
1206 pairs of opcodes, one with an inverted conditional (flip LSB):
1207
1208 Bcc.W 0010ncnd 00000110 00111000 dspppppp pppppppp
1209 Bcc.A 0010ncnd 00000111 00000100 dspppppp pppppppp pppppppp
1210 BEQ.A 00011100 00000100 dspppppp pppppppp pppppppp
1211 BNE.A 00010100 00000100 dspppppp pppppppp pppppppp */
1212
1213 /* Given the opcode bytes at OP, figure out which opcode it is and
1214 return the type of opcode. We use this to re-encode the opcode as
1215 a different size later. */
1216
1217 static op_type_T
1218 rx_opcode_type (char * op)
1219 {
1220 unsigned char b = (unsigned char) op[0];
1221
1222 switch (b & 0xf8)
1223 {
1224 case 0x08: return OT_bra;
1225 case 0x10: return OT_beq;
1226 case 0x18: return OT_bne;
1227 }
1228
1229 switch (b)
1230 {
1231 case 0x2e: return OT_bra;
1232 case 0x38: return OT_bra;
1233 case 0x04: return OT_bra;
1234
1235 case 0x20: return OT_beq;
1236 case 0x3a: return OT_beq;
1237
1238 case 0x21: return OT_bne;
1239 case 0x3b: return OT_bne;
1240
1241 case 0x39: return OT_bsr;
1242 case 0x05: return OT_bsr;
1243 }
1244
1245 if ((b & 0xf0) == 0x20)
1246 return OT_bcc;
1247
1248 return OT_other;
1249 }
1250
1251 /* Returns zero if *addrP has the target address. Else returns nonzero
1252 if we cannot compute the target address yet. */
1253
1254 static int
1255 rx_frag_fix_value (fragS * fragP,
1256 segT segment,
1257 int which,
1258 addressT * addrP,
1259 int need_diff,
1260 addressT * sym_addr)
1261 {
1262 addressT addr = 0;
1263 rx_bytesT * b = fragP->tc_frag_data;
1264 expressionS * exp = & b->fixups[which].exp;
1265
1266 if (need_diff && exp->X_op != O_subtract)
1267 return 1;
1268
1269 if (exp->X_add_symbol)
1270 {
1271 if (S_FORCE_RELOC (exp->X_add_symbol, 1))
1272 return 1;
1273 if (S_GET_SEGMENT (exp->X_add_symbol) != segment)
1274 return 1;
1275 addr += S_GET_VALUE (exp->X_add_symbol);
1276 }
1277
1278 if (exp->X_op_symbol)
1279 {
1280 if (exp->X_op != O_subtract)
1281 return 1;
1282 if (S_FORCE_RELOC (exp->X_op_symbol, 1))
1283 return 1;
1284 if (S_GET_SEGMENT (exp->X_op_symbol) != segment)
1285 return 1;
1286 addr -= S_GET_VALUE (exp->X_op_symbol);
1287 }
1288 if (sym_addr)
1289 * sym_addr = addr;
1290 addr += exp->X_add_number;
1291 * addrP = addr;
1292 return 0;
1293 }
1294
1295 /* Estimate how big the opcode is after this relax pass. The return
1296 value is the difference between fr_fix and the actual size. We
1297 compute the total size in rx_relax_frag and store it in fr_subtype,
1298 sowe only need to subtract fx_fix and return it. */
1299
1300 int
1301 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
1302 {
1303 int opfixsize;
1304 int delta;
1305
1306 tprintf ("\033[32m est frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1307 fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal),
1308 fragP->fr_fix, fragP->fr_var, fragP->fr_offset,
1309 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype);
1310
1311 /* This is the size of the opcode that's accounted for in fr_fix. */
1312 opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal);
1313 /* This is the size of the opcode that isn't. */
1314 delta = (fragP->fr_subtype - opfixsize);
1315
1316 tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta);
1317 return delta;
1318 }
1319
1320 /* Given the new addresses for this relax pass, figure out how big
1321 each opcode must be. We store the total number of bytes needed in
1322 fr_subtype. The return value is the difference between the size
1323 after the last pass and the size after this pass, so we use the old
1324 fr_subtype to calculate the difference. */
1325
1326 int
1327 rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
1328 {
1329 addressT addr0, sym_addr;
1330 addressT mypc;
1331 int disp;
1332 int oldsize = fragP->fr_subtype;
1333 int newsize = oldsize;
1334 op_type_T optype;
1335 /* Index of relaxation we care about. */
1336 int ri;
1337
1338 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",
1339 fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal),
1340 fragP->fr_fix, fragP->fr_var, fragP->fr_offset,
1341 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype, stretch);
1342
1343 optype = rx_opcode_type (fragP->fr_opcode);
1344
1345 /* In the one case where we have both a disp and imm relaxation, we want
1346 the imm relaxation here. */
1347 ri = 0;
1348 if (fragP->tc_frag_data->n_relax > 1
1349 && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1350 ri = 1;
1351
1352 /* Try to get the target address. */
1353 if (rx_frag_fix_value (fragP, segment, ri, & addr0,
1354 fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH,
1355 & sym_addr))
1356 {
1357 /* If we don't, we must use the maximum size for the linker.
1358 Note that we don't use synthetically expanded conditionals
1359 for this. */
1360 switch (fragP->tc_frag_data->relax[ri].type)
1361 {
1362 case RX_RELAX_BRANCH:
1363 switch (optype)
1364 {
1365 case OT_bra:
1366 case OT_bsr:
1367 newsize = 4;
1368 break;
1369 case OT_beq:
1370 case OT_bne:
1371 newsize = 3;
1372 break;
1373 case OT_bcc:
1374 newsize = 2;
1375 break;
1376 case OT_other:
1377 newsize = oldsize;
1378 break;
1379 }
1380 break;
1381
1382 case RX_RELAX_IMM:
1383 newsize = fragP->tc_frag_data->relax[ri].val_ofs + 4;
1384 break;
1385 }
1386 fragP->fr_subtype = newsize;
1387 tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize);
1388 return newsize - oldsize;
1389 }
1390
1391 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1392 if (sym_addr > mypc)
1393 addr0 += stretch;
1394
1395 switch (fragP->tc_frag_data->relax[ri].type)
1396 {
1397 case RX_RELAX_BRANCH:
1398 tprintf ("branch, addr %08lx pc %08lx disp %ld\n", addr0, mypc, addr0-mypc);
1399 disp = (int) addr0 - (int) mypc;
1400
1401 switch (optype)
1402 {
1403 case OT_bcc:
1404 if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1405 /* bcc.b */
1406 newsize = 2;
1407 else if (disp >= -32768 && (disp - (oldsize-5)) <= 32767)
1408 /* bncc.b/bra.w */
1409 newsize = 5;
1410 else
1411 /* bncc.b/bra.a */
1412 newsize = 6;
1413 break;
1414
1415 case OT_beq:
1416 case OT_bne:
1417 if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1418 /* beq.s */
1419 newsize = 1;
1420 else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1421 /* beq.b */
1422 newsize = 2;
1423 else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1424 /* beq.w */
1425 newsize = 3;
1426 else
1427 /* bne.s/bra.a */
1428 newsize = 5;
1429 break;
1430
1431 case OT_bra:
1432 case OT_bsr:
1433 if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1434 /* bra.s */
1435 newsize = 1;
1436 else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1437 /* bra.b */
1438 newsize = 2;
1439 else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1440 /* bra.w */
1441 newsize = 3;
1442 else
1443 /* bra.a */
1444 newsize = 4;
1445 break;
1446
1447 case OT_other:
1448 break;
1449 }
1450 tprintf (" - newsize %d\n", newsize);
1451 break;
1452
1453 case RX_RELAX_IMM:
1454 tprintf ("other, addr %08lx pc %08lx LI %d OF %d\n", addr0, mypc,
1455 fragP->tc_frag_data->relax[ri].field_pos,
1456 fragP->tc_frag_data->relax[ri].val_ofs);
1457
1458 newsize = fragP->tc_frag_data->relax[ri].val_ofs;
1459
1460 if ((long) addr0 >= -128 && (long) addr0 <= 127)
1461 newsize += 1;
1462 else if ((long) addr0 >= -32768 && (long) addr0 <= 32767)
1463 newsize += 2;
1464 else if ((long) addr0 >= -8388608 && (long) addr0 <= 8388607)
1465 newsize += 3;
1466 else
1467 newsize += 4;
1468 break;
1469
1470 default:
1471 break;
1472 }
1473
1474 if (fragP->tc_frag_data->relax[ri].type == RX_RELAX_BRANCH)
1475 switch (optype)
1476 {
1477 case OT_bra:
1478 case OT_bcc:
1479 case OT_beq:
1480 case OT_bne:
1481 break;
1482 case OT_bsr:
1483 if (newsize < 3)
1484 newsize = 3;
1485 break;
1486 case OT_other:
1487 break;
1488 }
1489
1490 /* This prevents infinite loops in align-heavy sources. */
1491 if (newsize < oldsize)
1492 {
1493 if (fragP->tc_frag_data->times_shrank > 10
1494 && fragP->tc_frag_data->times_grown > 10)
1495 newsize = oldsize;
1496 if (fragP->tc_frag_data->times_shrank < 20)
1497 fragP->tc_frag_data->times_shrank ++;
1498 }
1499 else if (newsize > oldsize)
1500 {
1501 if (fragP->tc_frag_data->times_grown < 20)
1502 fragP->tc_frag_data->times_grown ++;
1503 }
1504
1505 fragP->fr_subtype = newsize;
1506 tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
1507 return newsize - oldsize;
1508 }
1509
1510 /* This lets us test for the opcode type and the desired size in a
1511 switch statement. */
1512 #define OPCODE(type,size) ((type) * 16 + (size))
1513
1514 /* Given the opcode stored in fr_opcode and the number of bytes we
1515 think we need, encode a new opcode. We stored a pointer to the
1516 fixup for this opcode in the tc_frag_data structure. If we can do
1517 the fixup here, we change the relocation type to "none" (we test
1518 for that in tc_gen_reloc) else we change it to the right type for
1519 the new (biggest) opcode. */
1520
1521 void
1522 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1523 segT segment ATTRIBUTE_UNUSED,
1524 fragS * fragP ATTRIBUTE_UNUSED)
1525 {
1526 rx_bytesT * rxb = fragP->tc_frag_data;
1527 addressT addr0, mypc;
1528 int disp;
1529 int reloc_type, reloc_adjust;
1530 char * op = fragP->fr_opcode;
1531 int keep_reloc = 0;
1532 int ri;
1533 int fi = (rxb->n_fixups > 1) ? 1 : 0;
1534 fixS * fix = rxb->fixups[fi].fixP;
1535
1536 tprintf ("\033[31mconvrt frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1537 fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal),
1538 fragP->fr_fix, fragP->fr_var, fragP->fr_offset,
1539 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype);
1540
1541 #if TRACE_RELAX
1542 {
1543 int i;
1544
1545 printf ("lit %08x opc %08x", (int) fragP->fr_literal, (int) fragP->fr_opcode);
1546 for (i = 0; i < 10; i++)
1547 printf (" %02x", (unsigned char) (fragP->fr_opcode[i]));
1548 printf ("\n");
1549 }
1550 #endif
1551
1552 /* In the one case where we have both a disp and imm relaxation, we want
1553 the imm relaxation here. */
1554 ri = 0;
1555 if (fragP->tc_frag_data->n_relax > 1
1556 && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1557 ri = 1;
1558
1559 /* Try to get the target address. If we fail here, we just use the
1560 largest format. */
1561 if (rx_frag_fix_value (fragP, segment, 0, & addr0,
1562 fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH, 0))
1563 keep_reloc = 1;
1564
1565 if (linkrelax)
1566 keep_reloc = 1;
1567
1568 /* We used a new frag for this opcode, so the opcode address should
1569 be the frag address. */
1570 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1571 disp = (int) addr0 - (int) mypc;
1572
1573 reloc_type = BFD_RELOC_NONE;
1574 reloc_adjust = 0;
1575
1576 tprintf ("convert, op is %d, disp %d (%lx-%lx)\n", rx_opcode_type (fragP->fr_opcode), disp, addr0, mypc);
1577 switch (fragP->tc_frag_data->relax[ri].type)
1578 {
1579 case RX_RELAX_BRANCH:
1580 switch (OPCODE (rx_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
1581 {
1582 case OPCODE (OT_bra, 1): /* BRA.S - no change. */
1583 op[0] = 0x08 + (disp & 7);
1584 break;
1585 case OPCODE (OT_bra, 2): /* BRA.B - 8 bit. */
1586 op[0] = 0x2e;
1587 op[1] = disp;
1588 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1589 reloc_adjust = 1;
1590 break;
1591 case OPCODE (OT_bra, 3): /* BRA.W - 16 bit. */
1592 op[0] = 0x38;
1593 #if RX_OPCODE_BIG_ENDIAN
1594 op[1] = (disp >> 8) & 0xff;
1595 op[2] = disp;
1596 #else
1597 op[2] = (disp >> 8) & 0xff;
1598 op[1] = disp;
1599 #endif
1600 reloc_adjust = 1;
1601 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1602 break;
1603 case OPCODE (OT_bra, 4): /* BRA.A - 24 bit. */
1604 op[0] = 0x04;
1605 #if RX_OPCODE_BIG_ENDIAN
1606 op[1] = (disp >> 16) & 0xff;
1607 op[2] = (disp >> 8) & 0xff;
1608 op[3] = disp;
1609 #else
1610 op[3] = (disp >> 16) & 0xff;
1611 op[2] = (disp >> 8) & 0xff;
1612 op[1] = disp;
1613 #endif
1614 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1615 reloc_adjust = 1;
1616 break;
1617
1618 case OPCODE (OT_beq, 1): /* BEQ.S - no change. */
1619 op[0] = 0x10 + (disp & 7);
1620 break;
1621 case OPCODE (OT_beq, 2): /* BEQ.B - 8 bit. */
1622 op[0] = 0x20;
1623 op[1] = disp;
1624 reloc_adjust = 1;
1625 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1626 break;
1627 case OPCODE (OT_beq, 3): /* BEQ.W - 16 bit. */
1628 op[0] = 0x3a;
1629 #if RX_OPCODE_BIG_ENDIAN
1630 op[1] = (disp >> 8) & 0xff;
1631 op[2] = disp;
1632 #else
1633 op[2] = (disp >> 8) & 0xff;
1634 op[1] = disp;
1635 #endif
1636 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1637 reloc_adjust = 1;
1638 break;
1639 case OPCODE (OT_beq, 5): /* BEQ.A - synthetic. */
1640 op[0] = 0x1e; /* bne.s .+4. */
1641 op[1] = 0x04; /* bra.a dsp:24. */
1642 disp -= 1;
1643 #if RX_OPCODE_BIG_ENDIAN
1644 op[2] = (disp >> 16) & 0xff;
1645 op[3] = (disp >> 8) & 0xff;
1646 op[4] = disp;
1647 #else
1648 op[4] = (disp >> 16) & 0xff;
1649 op[3] = (disp >> 8) & 0xff;
1650 op[2] = disp;
1651 #endif
1652 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1653 reloc_adjust = 2;
1654 break;
1655
1656 case OPCODE (OT_bne, 1): /* BNE.S - no change. */
1657 op[0] = 0x18 + (disp & 7);
1658 break;
1659 case OPCODE (OT_bne, 2): /* BNE.B - 8 bit. */
1660 op[0] = 0x21;
1661 op[1] = disp;
1662 reloc_adjust = 1;
1663 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1664 break;
1665 case OPCODE (OT_bne, 3): /* BNE.W - 16 bit. */
1666 op[0] = 0x3b;
1667 #if RX_OPCODE_BIG_ENDIAN
1668 op[1] = (disp >> 8) & 0xff;
1669 op[2] = disp;
1670 #else
1671 op[2] = (disp >> 8) & 0xff;
1672 op[1] = disp;
1673 #endif
1674 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1675 reloc_adjust = 1;
1676 break;
1677 case OPCODE (OT_bne, 5): /* BNE.A - synthetic. */
1678 op[0] = 0x15; /* beq.s .+4. */
1679 op[1] = 0x04; /* bra.a dsp:24. */
1680 disp -= 1;
1681 #if RX_OPCODE_BIG_ENDIAN
1682 op[2] = (disp >> 16) & 0xff;
1683 op[3] = (disp >> 8) & 0xff;
1684 op[4] = disp;
1685 #else
1686 op[4] = (disp >> 16) & 0xff;
1687 op[3] = (disp >> 8) & 0xff;
1688 op[2] = disp;
1689 #endif
1690 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1691 reloc_adjust = 2;
1692 break;
1693
1694 case OPCODE (OT_bsr, 3): /* BSR.W - 16 bit. */
1695 op[0] = 0x39;
1696 #if RX_OPCODE_BIG_ENDIAN
1697 op[1] = (disp >> 8) & 0xff;
1698 op[2] = disp;
1699 #else
1700 op[2] = (disp >> 8) & 0xff;
1701 op[1] = disp;
1702 #endif
1703 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1704 reloc_adjust = 0;
1705 break;
1706 case OPCODE (OT_bsr, 4): /* BSR.A - 24 bit. */
1707 op[0] = 0x05;
1708 #if RX_OPCODE_BIG_ENDIAN
1709 op[1] = (disp >> 16) & 0xff;
1710 op[2] = (disp >> 8) & 0xff;
1711 op[3] = disp;
1712 #else
1713 op[3] = (disp >> 16) & 0xff;
1714 op[2] = (disp >> 8) & 0xff;
1715 op[1] = disp;
1716 #endif
1717 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1718 reloc_adjust = 0;
1719 break;
1720
1721 case OPCODE (OT_bcc, 2): /* Bcond.B - 8 bit. */
1722 op[1] = disp;
1723 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1724 break;
1725 case OPCODE (OT_bcc, 5): /* Bcond.W - synthetic. */
1726 op[0] ^= 1; /* Invert condition. */
1727 op[1] = 5; /* Displacement. */
1728 op[2] = 0x38;
1729 disp -= 2;
1730 #if RX_OPCODE_BIG_ENDIAN
1731 op[3] = (disp >> 8) & 0xff;
1732 op[4] = disp;
1733 #else
1734 op[4] = (disp >> 8) & 0xff;
1735 op[3] = disp;
1736 #endif
1737 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1738 reloc_adjust = 2;
1739 break;
1740 case OPCODE (OT_bcc, 6): /* Bcond.S - synthetic. */
1741 op[0] ^= 1; /* Invert condition. */
1742 op[1] = 6; /* Displacement. */
1743 op[2] = 0x04;
1744 disp -= 2;
1745 #if RX_OPCODE_BIG_ENDIAN
1746 op[3] = (disp >> 16) & 0xff;
1747 op[4] = (disp >> 8) & 0xff;
1748 op[5] = disp;
1749 #else
1750 op[5] = (disp >> 16) & 0xff;
1751 op[4] = (disp >> 8) & 0xff;
1752 op[3] = disp;
1753 #endif
1754 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1755 reloc_adjust = 2;
1756 break;
1757
1758 default:
1759 /* These are opcodes we'll relax in th linker, later. */
1760 if (rxb->n_fixups)
1761 reloc_type = rxb->fixups[ri].fixP->fx_r_type;
1762 break;
1763 }
1764 break;
1765
1766 case RX_RELAX_IMM:
1767 {
1768 int nbytes = fragP->fr_subtype - fragP->tc_frag_data->relax[ri].val_ofs;
1769 int li;
1770 char * imm = op + fragP->tc_frag_data->relax[ri].val_ofs;
1771
1772 switch (nbytes)
1773 {
1774 case 1:
1775 li = 1;
1776 imm[0] = addr0;
1777 reloc_type = BFD_RELOC_8;
1778 break;
1779 case 2:
1780 li = 2;
1781 #if RX_OPCODE_BIG_ENDIAN
1782 imm[1] = addr0;
1783 imm[0] = addr0 >> 8;
1784 #else
1785 imm[0] = addr0;
1786 imm[1] = addr0 >> 8;
1787 #endif
1788 reloc_type = BFD_RELOC_RX_16_OP;
1789 break;
1790 case 3:
1791 li = 3;
1792 #if RX_OPCODE_BIG_ENDIAN
1793 imm[2] = addr0;
1794 imm[1] = addr0 >> 8;
1795 imm[0] = addr0 >> 16;
1796 #else
1797 imm[0] = addr0;
1798 imm[1] = addr0 >> 8;
1799 imm[2] = addr0 >> 16;
1800 #endif
1801 reloc_type = BFD_RELOC_RX_24_OP;
1802 break;
1803 case 4:
1804 li = 0;
1805 #if RX_OPCODE_BIG_ENDIAN
1806 imm[3] = addr0;
1807 imm[2] = addr0 >> 8;
1808 imm[1] = addr0 >> 16;
1809 imm[0] = addr0 >> 24;
1810 #else
1811 imm[0] = addr0;
1812 imm[1] = addr0 >> 8;
1813 imm[2] = addr0 >> 16;
1814 imm[3] = addr0 >> 24;
1815 #endif
1816 reloc_type = BFD_RELOC_RX_32_OP;
1817 break;
1818 default:
1819 as_bad (_("invalid immediate size"));
1820 li = -1;
1821 }
1822
1823 switch (fragP->tc_frag_data->relax[ri].field_pos)
1824 {
1825 case 6:
1826 op[0] &= 0xfc;
1827 op[0] |= li;
1828 break;
1829 case 12:
1830 op[1] &= 0xf3;
1831 op[1] |= li << 2;
1832 break;
1833 case 20:
1834 op[2] &= 0xf3;
1835 op[2] |= li << 2;
1836 break;
1837 default:
1838 as_bad (_("invalid immediate field position"));
1839 }
1840 }
1841 break;
1842
1843 default:
1844 if (rxb->n_fixups)
1845 {
1846 reloc_type = fix->fx_r_type;
1847 reloc_adjust = 0;
1848 }
1849 break;
1850 }
1851
1852 if (rxb->n_fixups)
1853 {
1854
1855 fix->fx_r_type = reloc_type;
1856 fix->fx_where += reloc_adjust;
1857 switch (reloc_type)
1858 {
1859 case BFD_RELOC_NONE:
1860 fix->fx_size = 0;
1861 break;
1862 case BFD_RELOC_8:
1863 fix->fx_size = 1;
1864 break;
1865 case BFD_RELOC_16_PCREL:
1866 case BFD_RELOC_RX_16_OP:
1867 fix->fx_size = 2;
1868 break;
1869 case BFD_RELOC_24_PCREL:
1870 case BFD_RELOC_RX_24_OP:
1871 fix->fx_size = 3;
1872 break;
1873 case BFD_RELOC_RX_32_OP:
1874 fix->fx_size = 4;
1875 break;
1876 }
1877 }
1878
1879 fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
1880 tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", fragP->fr_fix,
1881 fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
1882 fragP->fr_var = 0;
1883
1884 if (fragP->fr_next != NULL
1885 && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
1886 != fragP->fr_fix))
1887 as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
1888 fragP->fr_fix, fragP->fr_address, fragP->fr_next->fr_address);
1889 }
1890
1891 #undef OPCODE
1892 \f
1893 int
1894 rx_validate_fix_sub (struct fix * f)
1895 {
1896 /* We permit the subtraction of two symbols as a 32-bit relocation. */
1897 if (f->fx_r_type == BFD_RELOC_RX_DIFF
1898 && ! f->fx_pcrel
1899 && f->fx_size == 4)
1900 return 1;
1901 return 0;
1902 }
1903
1904 long
1905 md_pcrel_from_section (fixS * fixP, segT sec)
1906 {
1907 long rv;
1908
1909 if (fixP->fx_addsy != NULL
1910 && (! S_IS_DEFINED (fixP->fx_addsy)
1911 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
1912 /* The symbol is undefined (or is defined but not in this section).
1913 Let the linker figure it out. */
1914 return 0;
1915
1916 rv = fixP->fx_frag->fr_address + fixP->fx_where;
1917 switch (fixP->fx_r_type)
1918 {
1919 case BFD_RELOC_RX_DIR3U_PCREL:
1920 return rv;
1921 default:
1922 return rv - 1;
1923 }
1924 }
1925
1926 void
1927 rx_cons_fix_new (fragS * frag,
1928 int where,
1929 int size,
1930 expressionS * exp)
1931 {
1932 bfd_reloc_code_real_type type;
1933
1934 switch (size)
1935 {
1936 case 1:
1937 type = BFD_RELOC_8;
1938 break;
1939 case 2:
1940 type = BFD_RELOC_16;
1941 break;
1942 case 3:
1943 type = BFD_RELOC_24;
1944 break;
1945 case 4:
1946 type = BFD_RELOC_32;
1947 break;
1948 default:
1949 as_bad (_("unsupported constant size %d\n"), size);
1950 return;
1951 }
1952
1953 if (exp->X_op == O_subtract && exp->X_op_symbol)
1954 {
1955 if (size != 4 && size != 2 && size != 1)
1956 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
1957 else
1958 type = BFD_RELOC_RX_DIFF;
1959 }
1960
1961 fix_new_exp (frag, where, (int) size, exp, 0, type);
1962 }
1963
1964 void
1965 md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
1966 valueT * t ATTRIBUTE_UNUSED,
1967 segT s ATTRIBUTE_UNUSED)
1968 {
1969 /* Instruction bytes are always little endian. */
1970 char * op;
1971 unsigned long val;
1972
1973 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
1974 return;
1975 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
1976 return;
1977
1978 #define OP2(x) op[target_big_endian ? 1-x : x]
1979 #define OP3(x) op[target_big_endian ? 2-x : x]
1980 #define OP4(x) op[target_big_endian ? 3-x : x]
1981
1982 op = f->fx_frag->fr_literal + f->fx_where;
1983 val = (unsigned long) * t;
1984
1985 /* Opcode words are always the same endian. Data words are either
1986 big or little endian. */
1987
1988 switch (f->fx_r_type)
1989 {
1990 case BFD_RELOC_NONE:
1991 break;
1992
1993 case BFD_RELOC_RX_RELAX:
1994 f->fx_done = 1;
1995 break;
1996
1997 case BFD_RELOC_RX_DIR3U_PCREL:
1998 if (val < 3 || val > 10)
1999 as_bad_where (f->fx_file, f->fx_line,
2000 _("jump not 3..10 bytes away (is %d)"), (int) val);
2001 op[0] &= 0xf8;
2002 op[0] |= val & 0x07;
2003 break;
2004
2005 case BFD_RELOC_8:
2006 case BFD_RELOC_8_PCREL:
2007 case BFD_RELOC_RX_8U:
2008 op[0] = val;
2009 break;
2010
2011 case BFD_RELOC_16:
2012 OP2(1) = val & 0xff;
2013 OP2(0) = (val >> 8) & 0xff;
2014 break;
2015
2016 case BFD_RELOC_16_PCREL:
2017 case BFD_RELOC_RX_16_OP:
2018 case BFD_RELOC_RX_16U:
2019 #if RX_OPCODE_BIG_ENDIAN
2020 op[1] = val & 0xff;
2021 op[0] = (val >> 8) & 0xff;
2022 #else
2023 op[0] = val & 0xff;
2024 op[1] = (val >> 8) & 0xff;
2025 #endif
2026 break;
2027
2028 case BFD_RELOC_24:
2029 OP3(0) = val & 0xff;
2030 OP3(1) = (val >> 8) & 0xff;
2031 OP3(2) = (val >> 16) & 0xff;
2032 break;
2033
2034 case BFD_RELOC_24_PCREL:
2035 case BFD_RELOC_RX_24_OP:
2036 case BFD_RELOC_RX_24U:
2037 #if RX_OPCODE_BIG_ENDIAN
2038 op[2] = val & 0xff;
2039 op[1] = (val >> 8) & 0xff;
2040 op[0] = (val >> 16) & 0xff;
2041 #else
2042 op[0] = val & 0xff;
2043 op[1] = (val >> 8) & 0xff;
2044 op[2] = (val >> 16) & 0xff;
2045 #endif
2046 break;
2047
2048 case BFD_RELOC_RX_DIFF:
2049 switch (f->fx_size)
2050 {
2051 case 1:
2052 op[0] = val & 0xff;
2053 break;
2054 case 2:
2055 OP2(0) = val & 0xff;
2056 OP2(1) = (val >> 8) & 0xff;
2057 break;
2058 case 4:
2059 OP4(0) = val & 0xff;
2060 OP4(1) = (val >> 8) & 0xff;
2061 OP4(2) = (val >> 16) & 0xff;
2062 OP4(3) = (val >> 24) & 0xff;
2063 break;
2064 }
2065 break;
2066
2067 case BFD_RELOC_32:
2068 OP4(0) = val & 0xff;
2069 OP4(1) = (val >> 8) & 0xff;
2070 OP4(2) = (val >> 16) & 0xff;
2071 OP4(3) = (val >> 24) & 0xff;
2072 break;
2073
2074 case BFD_RELOC_RX_32_OP:
2075 #if RX_OPCODE_BIG_ENDIAN
2076 op[3] = val & 0xff;
2077 op[2] = (val >> 8) & 0xff;
2078 op[1] = (val >> 16) & 0xff;
2079 op[0] = (val >> 24) & 0xff;
2080 #else
2081 op[0] = val & 0xff;
2082 op[1] = (val >> 8) & 0xff;
2083 op[2] = (val >> 16) & 0xff;
2084 op[3] = (val >> 24) & 0xff;
2085 #endif
2086 break;
2087
2088 case BFD_RELOC_RX_NEG8:
2089 op[0] = - val;
2090 break;
2091
2092 case BFD_RELOC_RX_NEG16:
2093 val = -val;
2094 #if RX_OPCODE_BIG_ENDIAN
2095 op[1] = val & 0xff;
2096 op[0] = (val >> 8) & 0xff;
2097 #else
2098 op[0] = val & 0xff;
2099 op[1] = (val >> 8) & 0xff;
2100 #endif
2101 break;
2102
2103 case BFD_RELOC_RX_NEG24:
2104 val = -val;
2105 #if RX_OPCODE_BIG_ENDIAN
2106 op[2] = val & 0xff;
2107 op[1] = (val >> 8) & 0xff;
2108 op[0] = (val >> 16) & 0xff;
2109 #else
2110 op[0] = val & 0xff;
2111 op[1] = (val >> 8) & 0xff;
2112 op[2] = (val >> 16) & 0xff;
2113 #endif
2114 break;
2115
2116 case BFD_RELOC_RX_NEG32:
2117 val = -val;
2118 #if RX_OPCODE_BIG_ENDIAN
2119 op[3] = val & 0xff;
2120 op[2] = (val >> 8) & 0xff;
2121 op[1] = (val >> 16) & 0xff;
2122 op[0] = (val >> 24) & 0xff;
2123 #else
2124 op[0] = val & 0xff;
2125 op[1] = (val >> 8) & 0xff;
2126 op[2] = (val >> 16) & 0xff;
2127 op[3] = (val >> 24) & 0xff;
2128 #endif
2129 break;
2130
2131 case BFD_RELOC_RX_GPRELL:
2132 val >>= 1;
2133 case BFD_RELOC_RX_GPRELW:
2134 val >>= 1;
2135 case BFD_RELOC_RX_GPRELB:
2136 #if RX_OPCODE_BIG_ENDIAN
2137 op[1] = val & 0xff;
2138 op[0] = (val >> 8) & 0xff;
2139 #else
2140 op[0] = val & 0xff;
2141 op[1] = (val >> 8) & 0xff;
2142 #endif
2143 break;
2144
2145 default:
2146 as_bad (_("Unknown reloc in md_apply_fix: %s"),
2147 bfd_get_reloc_code_name (f->fx_r_type));
2148 break;
2149 }
2150
2151 if (f->fx_addsy == NULL)
2152 f->fx_done = 1;
2153 }
2154
2155 arelent **
2156 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
2157 {
2158 static arelent * reloc[5];
2159
2160 if (fixp->fx_r_type == BFD_RELOC_NONE)
2161 {
2162 reloc[0] = NULL;
2163 return reloc;
2164 }
2165
2166 if (fixp->fx_subsy
2167 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
2168 {
2169 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
2170 fixp->fx_subsy = NULL;
2171 }
2172
2173 reloc[0] = (arelent *) xmalloc (sizeof (arelent));
2174 reloc[0]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2175 * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2176 reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2177 reloc[0]->addend = fixp->fx_offset;
2178
2179 /* Certain BFD relocations cannot be translated directly into
2180 a single (non-Red Hat) RX relocation, but instead need
2181 multiple RX relocations - handle them here. */
2182 switch (fixp->fx_r_type)
2183 {
2184 case BFD_RELOC_RX_DIFF:
2185 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2186
2187 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2188 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2189 * reloc[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2190 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2191 reloc[1]->addend = 0;
2192 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2193
2194 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2195 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2196 reloc[2]->addend = 0;
2197 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2198 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2199
2200 reloc[3] = (arelent *) xmalloc (sizeof (arelent));
2201 switch (fixp->fx_size)
2202 {
2203 case 1:
2204 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS8);
2205 break;
2206 case 2:
2207 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16);
2208 break;
2209 case 4:
2210 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
2211 break;
2212 }
2213 reloc[3]->addend = 0;
2214 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2215 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2216
2217 reloc[4] = NULL;
2218 break;
2219
2220 case BFD_RELOC_RX_GPRELL:
2221 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2222
2223 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2224 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2225 if (gp_symbol == NULL)
2226 {
2227 if (symbol_table_frozen)
2228 {
2229 symbolS * gp;
2230
2231 gp = symbol_find ("__gp");
2232 if (gp == NULL)
2233 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2234 else
2235 gp_symbol = symbol_get_bfdsym (gp);
2236 }
2237 else
2238 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2239 }
2240 * reloc[1]->sym_ptr_ptr = gp_symbol;
2241 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2242 reloc[1]->addend = 0;
2243 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2244
2245 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2246 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2247 reloc[2]->addend = 0;
2248 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2249 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2250
2251 reloc[3] = (arelent *) xmalloc (sizeof (arelent));
2252 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL);
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_GPRELW:
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_ABS16UW);
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_GPRELB:
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_ABS16U);
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 default:
2341 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2342 reloc[1] = NULL;
2343 break;
2344 }
2345
2346 return reloc;
2347 }
2348
2349 /* Set the ELF specific flags. */
2350
2351 void
2352 rx_elf_final_processing (void)
2353 {
2354 elf_elfheader (stdoutput)->e_flags |= elf_flags;
2355 }
2356
2357 /* Scan the current input line for occurances of Renesas
2358 local labels and replace them with the GAS version. */
2359
2360 void
2361 rx_start_line (void)
2362 {
2363 int in_double_quote = 0;
2364 int in_single_quote = 0;
2365 int done = 0;
2366 char * p = input_line_pointer;
2367
2368 /* Scan the line looking for question marks. Skip past quote enclosed regions. */
2369 do
2370 {
2371 switch (*p)
2372 {
2373 case '\n':
2374 case 0:
2375 done = 1;
2376 break;
2377
2378 case '"':
2379 in_double_quote = ! in_double_quote;
2380 break;
2381
2382 case '\'':
2383 in_single_quote = ! in_single_quote;
2384 break;
2385
2386 case '?':
2387 if (in_double_quote || in_single_quote)
2388 break;
2389
2390 if (p[1] == ':')
2391 *p = '1';
2392 else if (p[1] == '+')
2393 {
2394 p[0] = '1';
2395 p[1] = 'f';
2396 }
2397 else if (p[1] == '-')
2398 {
2399 p[0] = '1';
2400 p[1] = 'b';
2401 }
2402 break;
2403
2404 default:
2405 break;
2406 }
2407
2408 p ++;
2409 }
2410 while (! done);
2411 }
This page took 0.081251 seconds and 5 git commands to generate.