bfd
[binutils.git] / gas / config / tc-rx.c
blobf6353210f1841d0e6465629993f11eed4b10ca9f
1 /* tc-rx.c -- Assembler for the Renesas RX
2 Copyright 2008, 2009
3 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
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.
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.
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. */
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"
36 #define RX_OPCODE_BIG_ENDIAN 0
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[] = "!";
45 const char EXP_CHARS[] = "eE";
46 const char FLT_CHARS[] = "dD";
48 /* ELF flags to set in the output file header. */
49 static int elf_flags = 0;
51 bfd_boolean rx_use_conventional_section_names = FALSE;
52 static bfd_boolean rx_use_small_data_limit = FALSE;
54 enum options
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
66 #define RX_SHORTOPTS ""
67 const char * md_shortopts = RX_SHORTOPTS;
69 /* Assembler options. */
70 struct option md_longopts[] =
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}
88 size_t md_longopts_size = sizeof (md_longopts);
90 int
91 md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED)
93 switch (c)
95 case OPTION_BIG:
96 target_big_endian = 1;
97 return 1;
99 case OPTION_LITTLE:
100 target_big_endian = 0;
101 return 1;
103 case OPTION_32BIT_DOUBLES:
104 elf_flags &= ~ E_FLAG_RX_64BIT_DOUBLES;
105 return 1;
107 case OPTION_64BIT_DOUBLES:
108 elf_flags |= E_FLAG_RX_64BIT_DOUBLES;
109 return 1;
111 case OPTION_CONVENTIONAL_SECTION_NAMES:
112 rx_use_conventional_section_names = TRUE;
113 return 1;
115 case OPTION_RENESAS_SECTION_NAMES:
116 rx_use_conventional_section_names = FALSE;
117 return 1;
119 case OPTION_SMALL_DATA_LIMIT:
120 rx_use_small_data_limit = TRUE;
121 return 1;
123 case OPTION_RELAX:
124 linkrelax = 1;
125 return 1;
127 return 0;
130 void
131 md_show_usage (FILE * stream)
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"));
143 static void
144 s_bss (int ignore ATTRIBUTE_UNUSED)
146 int temp;
148 temp = get_absolute_expression ();
149 subseg_set (bss_section, (subsegT) temp);
150 demand_empty_rest_of_line ();
153 static void
154 rx_float_cons (int ignore ATTRIBUTE_UNUSED)
156 if (elf_flags & E_FLAG_RX_64BIT_DOUBLES)
157 return float_cons ('d');
158 return float_cons ('f');
161 static char *
162 rx_strcasestr (const char *string, const char *sub)
164 int subl;
165 int strl;
167 if (!sub || !sub[0])
168 return (char *)string;
170 subl = strlen (sub);
171 strl = strlen (string);
173 while (strl >= subl)
175 /* strncasecmp is in libiberty. */
176 if (strncasecmp (string, sub, subl) == 0)
177 return (char *)string;
179 string ++;
180 strl --;
182 return NULL;
185 static void
186 rx_include (int ignore)
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;
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 == '"')
204 /* Treat as the normal GAS .include pseudo-op. */
205 s_include (ignore);
206 return;
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;
214 while (eof >= filename && (* eof == ' ' || * eof == '\n'))
215 -- eof;
216 end_char = *(++ eof);
217 * eof = 0;
218 if (eof == filename)
220 as_bad (_("no filename following .INCLUDE pseudo-op"));
221 * eof = end_char;
222 return;
225 as_where (& current_filename, NULL);
226 f = (char *) xmalloc (strlen (current_filename) + strlen (filename) + 1);
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)
233 char * c;
235 len = 6; /* strlen ("..file"); */
237 if (p > filename && p[-1] == '@')
238 -- p, ++len;
240 if (p[len] == '@')
241 len ++;
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;
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);
255 else
256 strcpy (f, filename);
258 /* RX .INCLUDE semantics say that 'filename' is located by:
260 1. If filename is absolute, just try that. Otherwise...
262 2. If the current source file includes a directory component
263 then prepend that to the filename and try. Otherwise...
265 3. Try any directories specified by the -I command line
266 option(s).
268 4 .Try a directory specifed by the INC100 environment variable. */
270 if (IS_ABSOLUTE_PATH (f))
271 try = fopen (path = f, FOPEN_RT);
272 else
274 char * env = getenv ("INC100");
276 try = NULL;
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);
284 path = (char *) xmalloc (strlen (f) + len + 5);
286 if (current_filename != NULL)
288 for (d = NULL, p = current_filename; *p; p++)
289 if (IS_DIR_SEPARATOR (* p))
290 d = p;
292 if (d != NULL)
294 sprintf (path, "%.*s/%s", (int) (d - current_filename), current_filename,
296 try = fopen (path, FOPEN_RT);
300 if (try == NULL)
302 int i;
304 for (i = 0; i < include_dir_count; i++)
306 sprintf (path, "%s/%s", include_dirs[i], f);
307 if ((try = fopen (path, FOPEN_RT)) != NULL)
308 break;
312 if (try == NULL && env != NULL)
314 sprintf (path, "%s/%s", env, f);
315 try = fopen (path, FOPEN_RT);
318 free (f);
321 if (try == NULL)
323 as_bad (_("unable to locate include file: %s"), filename);
324 free (path);
326 else
328 fclose (try);
329 register_dependency (path);
330 input_scrub_insert_file (path);
333 * eof = end_char;
336 static void
337 parse_rx_section (char * name)
339 asection * sec;
340 int type;
341 int attr = SHF_ALLOC | SHF_EXECINSTR;
342 int align = 2;
343 char end_char;
347 char * p;
349 SKIP_WHITESPACE ();
350 for (p = input_line_pointer; *p && strchr ("\n\t, =", *p) == NULL; p++)
352 end_char = *p;
353 *p = 0;
355 if (strcasecmp (input_line_pointer, "ALIGN") == 0)
357 *p = end_char;
359 if (end_char == ' ')
360 while (ISSPACE (*p))
361 p++;
363 if (*p == '=')
365 ++ p;
366 while (ISSPACE (*p))
367 p++;
368 switch (*p)
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;
378 ++ p;
381 end_char = *p;
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
391 as_bad (_("unknown parameter following .SECTION directive: %s"),
392 input_line_pointer);
394 *p = end_char;
395 input_line_pointer = p + 1;
396 ignore_rest_of_line ();
397 return;
400 *p = end_char;
401 input_line_pointer = p + 1;
403 while (end_char != '\n' && end_char != 0);
405 if ((sec = bfd_get_section_by_name (stdoutput, name)) == NULL)
407 if (strcmp (name, "B") && strcmp (name, "B_1") && strcmp (name, "B_2"))
408 type = SHT_NULL;
409 else
410 type = SHT_NOBITS;
412 obj_elf_change_section (name, type, attr, 0, NULL, FALSE, FALSE);
414 else /* Try not to redefine a section, especially B_1. */
416 int flags = sec->flags;
418 type = elf_section_type (sec);
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);
427 obj_elf_change_section (name, type, attr, 0, NULL, FALSE, FALSE);
430 bfd_set_section_alignment (stdoutput, now_seg, align);
433 static void
434 rx_section (int ignore)
436 char * p;
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 ();
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;
447 if (*p == ',')
449 int len = p - input_line_pointer;
451 while (ISSPACE (*++p))
454 if (*p != '"' && *p != '#')
456 char * name = (char *) xmalloc (len + 1);
458 strncpy (name, input_line_pointer, len);
459 name[len] = 0;
461 input_line_pointer = p;
462 parse_rx_section (name);
463 return;
467 obj_elf_section (ignore);
470 static void
471 rx_list (int ignore ATTRIBUTE_UNUSED)
473 SKIP_WHITESPACE ();
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"));
483 /* Like the .rept pseudo op, but supports the
484 use of ..MACREP inside the repeated region. */
486 static void
487 rx_rept (int ignore ATTRIBUTE_UNUSED)
489 int count = get_absolute_expression ();
491 do_repeat_with_expander (count, "MREPEAT", "ENDR", "..MACREP");
494 /* Like cons() accept that strings are allowed. */
496 static void
497 rx_cons (int size)
499 SKIP_WHITESPACE ();
501 if (* input_line_pointer == '"')
502 stringer (8+0);
503 else
504 cons (size);
507 static void
508 rx_nop (int ignore ATTRIBUTE_UNUSED)
510 ignore_rest_of_line ();
513 static void
514 rx_unimp (int idx)
516 as_warn (_("The \".%s\" pseudo-op is not implemented\n"),
517 md_pseudo_table[idx].poc_name);
518 ignore_rest_of_line ();
521 /* The target specific pseudo-ops which we support. */
522 const pseudo_typeS md_pseudo_table[] =
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 },
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 },
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 },
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 },
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 },
582 /* End of list marker. */
583 { NULL, NULL, 0 }
586 static asymbol * gp_symbol;
588 void
589 md_begin (void)
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"));
599 char * rx_lex_start;
600 char * rx_lex_end;
602 typedef struct rx_bytesT
604 char base[4];
605 int n_base;
606 char ops[8];
607 int n_ops;
608 struct
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
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 } rx_bytesT;
629 static rx_bytesT rx_bytes;
631 void
632 rx_relax (int type, int pos)
634 rx_bytes.relax[rx_bytes.n_relax].type = type;
635 rx_bytes.relax[rx_bytes.n_relax].field_pos = pos;
636 rx_bytes.relax[rx_bytes.n_relax].val_ofs = rx_bytes.n_base + rx_bytes.n_ops;
637 rx_bytes.n_relax ++;
640 void
641 rx_linkrelax_dsp (int pos)
643 switch (pos)
645 case 4:
646 rx_bytes.link_relax |= RX_RELAXA_DSP4;
647 break;
648 case 6:
649 rx_bytes.link_relax |= RX_RELAXA_DSP6;
650 break;
651 case 14:
652 rx_bytes.link_relax |= RX_RELAXA_DSP14;
653 break;
657 void
658 rx_linkrelax_imm (int pos)
660 switch (pos)
662 case 6:
663 rx_bytes.link_relax |= RX_RELAXA_IMM6;
664 break;
665 case 12:
666 rx_bytes.link_relax |= RX_RELAXA_IMM12;
667 break;
671 void
672 rx_linkrelax_branch (void)
674 rx_bytes.link_relax |= RX_RELAXA_BRA;
677 static void
678 rx_fixup (expressionS exp, int offsetbits, int nbits, int type)
680 rx_bytes.fixups[rx_bytes.n_fixups].exp = exp;
681 rx_bytes.fixups[rx_bytes.n_fixups].offset = offsetbits;
682 rx_bytes.fixups[rx_bytes.n_fixups].nbits = nbits;
683 rx_bytes.fixups[rx_bytes.n_fixups].type = type;
684 rx_bytes.fixups[rx_bytes.n_fixups].reloc = exp.X_md;
685 rx_bytes.n_fixups ++;
688 #define rx_field_fixup(exp, offset, nbits, type) \
689 rx_fixup (exp, offset, nbits, type)
691 #define rx_op_fixup(exp, offset, nbits, type) \
692 rx_fixup (exp, offset + 8 * rx_bytes.n_base, nbits, type)
694 void
695 rx_base1 (int b1)
697 rx_bytes.base[0] = b1;
698 rx_bytes.n_base = 1;
701 void
702 rx_base2 (int b1, int b2)
704 rx_bytes.base[0] = b1;
705 rx_bytes.base[1] = b2;
706 rx_bytes.n_base = 2;
709 void
710 rx_base3 (int b1, int b2, int b3)
712 rx_bytes.base[0] = b1;
713 rx_bytes.base[1] = b2;
714 rx_bytes.base[2] = b3;
715 rx_bytes.n_base = 3;
718 void
719 rx_base4 (int b1, int b2, int b3, int b4)
721 rx_bytes.base[0] = b1;
722 rx_bytes.base[1] = b2;
723 rx_bytes.base[2] = b3;
724 rx_bytes.base[3] = b4;
725 rx_bytes.n_base = 4;
728 /* This gets complicated when the field spans bytes, because fields
729 are numbered from the MSB of the first byte as zero, and bits are
730 stored LSB towards the LSB of the byte. Thus, a simple four-bit
731 insertion of 12 at position 4 of 0x00 yields: 0x0b. A three-bit
732 insertion of b'MXL at position 7 is like this:
734 - - - - - - - - - - - - - - - -
735 M X L */
737 void
738 rx_field (int val, int pos, int sz)
740 int valm;
741 int bytep, bitp;
743 if (sz > 0)
745 if (val < 0 || val >= (1 << sz))
746 as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz);
748 else
750 sz = - sz;
751 if (val < -(1 << (sz - 1)) || val >= (1 << (sz - 1)))
752 as_bad (_("Value %d doesn't fit in signed %d-bit field"), val, sz);
755 /* This code points at 'M' in the above example. */
756 bytep = pos / 8;
757 bitp = pos % 8;
759 while (bitp + sz > 8)
761 int ssz = 8 - bitp;
762 int svalm;
764 svalm = val >> (sz - ssz);
765 svalm = svalm & ((1 << ssz) - 1);
766 svalm = svalm << (8 - bitp - ssz);
767 gas_assert (bytep < rx_bytes.n_base);
768 rx_bytes.base[bytep] |= svalm;
770 bitp = 0;
771 sz -= ssz;
772 bytep ++;
774 valm = val & ((1 << sz) - 1);
775 valm = valm << (8 - bitp - sz);
776 gas_assert (bytep < rx_bytes.n_base);
777 rx_bytes.base[bytep] |= valm;
780 /* Special case of the above, for 3-bit displacements of 2..9. */
782 void
783 rx_disp3 (expressionS exp, int pos)
785 rx_field_fixup (exp, pos, 3, RXREL_PCREL);
788 /* Special case of the above, for split 5-bit displacements. Assumes
789 the displacement has been checked with rx_disp5op. */
790 /* ---- -432 1--- 0--- */
792 void
793 rx_field5s (expressionS exp)
795 int val;
797 val = exp.X_add_number;
798 rx_bytes.base[0] |= val >> 2;
799 rx_bytes.base[1] |= (val << 6) & 0x80;
800 rx_bytes.base[1] |= (val << 3) & 0x08;
803 /* ---- ---- 4--- 3210 */
805 void
806 rx_field5s2 (expressionS exp)
808 int val;
810 val = exp.X_add_number;
811 rx_bytes.base[1] |= (val << 3) & 0x80;
812 rx_bytes.base[1] |= (val ) & 0x0f;
815 #define OP(x) rx_bytes.ops[rx_bytes.n_ops++] = (x)
817 #define F_PRECISION 2
819 void
820 rx_op (expressionS exp, int nbytes, int type)
822 int v = 0;
824 if ((exp.X_op == O_constant || exp.X_op == O_big)
825 && type != RXREL_PCREL)
827 if (exp.X_op == O_big && exp.X_add_number <= 0)
829 LITTLENUM_TYPE w[2];
830 char * ip = rx_bytes.ops + rx_bytes.n_ops;
832 gen_to_words (w, F_PRECISION, 8);
833 #if RX_OPCODE_BIG_ENDIAN
834 ip[0] = w[0] >> 8;
835 ip[1] = w[0];
836 ip[2] = w[1] >> 8;
837 ip[3] = w[1];
838 #else
839 ip[3] = w[0] >> 8;
840 ip[2] = w[0];
841 ip[1] = w[1] >> 8;
842 ip[0] = w[1];
843 #endif
844 rx_bytes.n_ops += 4;
846 else
848 v = exp.X_add_number;
849 while (nbytes)
851 #if RX_OPCODE_BIG_ENDIAN
852 OP ((v >> (8 * (nbytes - 1))) & 0xff);
853 #else
854 OP (v & 0xff);
855 v >>= 8;
856 #endif
857 nbytes --;
861 else
863 rx_op_fixup (exp, rx_bytes.n_ops * 8, nbytes * 8, type);
864 memset (rx_bytes.ops + rx_bytes.n_ops, 0, nbytes);
865 rx_bytes.n_ops += nbytes;
870 rx_wrap (void)
872 return 0;
875 #define APPEND(B, N_B) \
876 if (rx_bytes.N_B) \
878 memcpy (bytes + idx, rx_bytes.B, rx_bytes.N_B); \
879 idx += rx_bytes.N_B; \
882 void
883 rx_frag_init (fragS * fragP)
885 if (rx_bytes.n_relax || rx_bytes.link_relax)
887 fragP->tc_frag_data = malloc (sizeof (rx_bytesT));
888 memcpy (fragP->tc_frag_data, & rx_bytes, sizeof (rx_bytesT));
890 else
891 fragP->tc_frag_data = 0;
894 /* Handle the as100's version of the .equ pseudo-op. It has the syntax:
895 <symbol_name> .equ <expression> */
897 static void
898 rx_equ (char * name, char * expr)
900 char saved_name_end_char;
901 char * name_end;
902 char * saved_ilp;
904 while (ISSPACE (* name))
905 name ++;
907 for (name_end = name + 1; *name_end; name_end ++)
908 if (! ISALNUM (* name_end))
909 break;
911 saved_name_end_char = * name_end;
912 * name_end = 0;
914 saved_ilp = input_line_pointer;
915 input_line_pointer = expr;
917 equals (name, 1);
919 input_line_pointer = saved_ilp;
920 * name_end = saved_name_end_char;
923 /* Look for Renesas as100 pseudo-ops that occur after a symbol name
924 rather than at the start of a line. (eg .EQU or .DEFINE). If one
925 is found, process it and return TRUE otherwise return FALSE. */
927 static bfd_boolean
928 scan_for_infix_rx_pseudo_ops (char * str)
930 char * p;
931 char * pseudo_op;
932 char * dot = strchr (str, '.');
934 if (dot == NULL || dot == str)
935 return FALSE;
937 /* A real pseudo-op must be preceeded by whitespace. */
938 if (dot[-1] != ' ' && dot[-1] != '\t')
939 return FALSE;
941 pseudo_op = dot + 1;
943 if (!ISALNUM (* pseudo_op))
944 return FALSE;
946 for (p = pseudo_op + 1; ISALNUM (* p); p++)
949 if (strncasecmp ("EQU", pseudo_op, p - pseudo_op) == 0)
950 rx_equ (str, p);
951 else if (strncasecmp ("DEFINE", pseudo_op, p - pseudo_op) == 0)
952 as_warn (_("The .DEFINE pseudo-op is not implemented"));
953 else if (strncasecmp ("MACRO", pseudo_op, p - pseudo_op) == 0)
954 as_warn (_("The .MACRO pseudo-op is not implemented"));
955 else if (strncasecmp ("BTEQU", pseudo_op, p - pseudo_op) == 0)
956 as_warn (_("The .BTEQU pseudo-op is not implemented."));
957 else
958 return FALSE;
960 return TRUE;
963 void
964 md_assemble (char * str)
966 char * bytes;
967 int idx = 0;
968 int i, rel;
969 fragS * frag_then = frag_now;
970 expressionS *exp;
972 memset (& rx_bytes, 0, sizeof (rx_bytes));
974 rx_lex_init (str, str + strlen (str));
975 if (scan_for_infix_rx_pseudo_ops (str))
976 return;
977 rx_parse ();
979 /* This simplifies the relaxation code. */
980 if (rx_bytes.n_relax || rx_bytes.link_relax)
982 /* We do it this way because we want the frag to have the
983 rx_bytes in it, which we initialize above. */
984 bytes = frag_more (12);
985 frag_then = frag_now;
986 frag_variant (rs_machine_dependent,
987 0 /* max_chars */,
988 0 /* var */,
989 0 /* subtype */,
990 0 /* symbol */,
991 0 /* offset */,
992 0 /* opcode */);
993 frag_then->fr_opcode = bytes;
994 frag_then->fr_fix += rx_bytes.n_base + rx_bytes.n_ops;
995 frag_then->fr_subtype = rx_bytes.n_base + rx_bytes.n_ops;
997 else
999 bytes = frag_more (rx_bytes.n_base + rx_bytes.n_ops);
1000 frag_then = frag_now;
1003 APPEND (base, n_base);
1004 APPEND (ops, n_ops);
1006 if (rx_bytes.link_relax && rx_bytes.n_fixups)
1008 fixS * f;
1010 f = fix_new (frag_then,
1011 (char *) bytes - frag_then->fr_literal,
1013 abs_section_sym,
1014 rx_bytes.link_relax | rx_bytes.n_fixups,
1016 BFD_RELOC_RX_RELAX);
1017 frag_then->tc_frag_data->link_relax_fixP = f;
1020 for (i = 0; i < rx_bytes.n_fixups; i ++)
1022 /* index: [nbytes][type] */
1023 static int reloc_map[5][4] =
1025 { 0, 0, 0, BFD_RELOC_RX_DIR3U_PCREL },
1026 { BFD_RELOC_8, BFD_RELOC_RX_8U, BFD_RELOC_RX_NEG8, BFD_RELOC_8_PCREL },
1027 { BFD_RELOC_RX_16_OP, BFD_RELOC_RX_16U, BFD_RELOC_RX_NEG16, BFD_RELOC_16_PCREL },
1028 { BFD_RELOC_RX_24_OP, BFD_RELOC_RX_24U, BFD_RELOC_RX_NEG24, BFD_RELOC_24_PCREL },
1029 { BFD_RELOC_RX_32_OP, BFD_RELOC_32, BFD_RELOC_RX_NEG32, BFD_RELOC_32_PCREL },
1031 fixS * f;
1033 idx = rx_bytes.fixups[i].offset / 8;
1034 rel = reloc_map [rx_bytes.fixups[i].nbits / 8][(int) rx_bytes.fixups[i].type];
1036 if (rx_bytes.fixups[i].reloc)
1037 rel = rx_bytes.fixups[i].reloc;
1039 if (frag_then->tc_frag_data)
1040 exp = & frag_then->tc_frag_data->fixups[i].exp;
1041 else
1042 exp = & rx_bytes.fixups[i].exp;
1044 f = fix_new_exp (frag_then,
1045 (char *) bytes + idx - frag_then->fr_literal,
1046 rx_bytes.fixups[i].nbits / 8,
1047 exp,
1048 rx_bytes.fixups[i].type == RXREL_PCREL ? 1 : 0,
1049 rel);
1050 if (frag_then->tc_frag_data)
1051 frag_then->tc_frag_data->fixups[i].fixP = f;
1054 dwarf2_emit_insn (idx);
1057 void
1058 rx_md_end (void)
1062 /* Write a value out to the object file, using the appropriate endianness. */
1064 void
1065 md_number_to_chars (char * buf, valueT val, int n)
1067 if (target_big_endian)
1068 number_to_chars_bigendian (buf, val, n);
1069 else
1070 number_to_chars_littleendian (buf, val, n);
1073 static struct
1075 char * fname;
1076 int reloc;
1078 reloc_functions[] =
1080 { "gp", BFD_RELOC_GPREL16 },
1081 { 0, 0 }
1084 void
1085 md_operand (expressionS * exp ATTRIBUTE_UNUSED)
1087 int reloc = 0;
1088 int i;
1090 for (i = 0; reloc_functions[i].fname; i++)
1092 int flen = strlen (reloc_functions[i].fname);
1094 if (input_line_pointer[0] == '%'
1095 && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
1096 && input_line_pointer[flen + 1] == '(')
1098 reloc = reloc_functions[i].reloc;
1099 input_line_pointer += flen + 2;
1100 break;
1103 if (reloc == 0)
1104 return;
1106 expression (exp);
1107 if (* input_line_pointer == ')')
1108 input_line_pointer ++;
1110 exp->X_md = reloc;
1113 valueT
1114 md_section_align (segT segment, valueT size)
1116 int align = bfd_get_section_alignment (stdoutput, segment);
1117 return ((size + (1 << align) - 1) & (-1 << align));
1120 /* When relaxing, we need to output a reloc for any .align directive
1121 so that we can retain this alignment as we adjust opcode sizes. */
1122 void
1123 rx_handle_align (fragS * frag)
1125 if (linkrelax
1126 && (frag->fr_type == rs_align
1127 || frag->fr_type == rs_align_code)
1128 && frag->fr_address + frag->fr_fix > 0
1129 && frag->fr_offset > 0
1130 && now_seg != bss_section)
1132 fix_new (frag, frag->fr_fix, 0,
1133 &abs_symbol, RX_RELAXA_ALIGN + frag->fr_offset,
1134 0, BFD_RELOC_RX_RELAX);
1135 /* For the purposes of relaxation, this relocation is attached
1136 to the byte *after* the alignment - i.e. the byte that must
1137 remain aligned. */
1138 fix_new (frag->fr_next, 0, 0,
1139 &abs_symbol, RX_RELAXA_ELIGN + frag->fr_offset,
1140 0, BFD_RELOC_RX_RELAX);
1144 char *
1145 md_atof (int type, char * litP, int * sizeP)
1147 return ieee_md_atof (type, litP, sizeP, target_big_endian);
1150 symbolS *
1151 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1153 return NULL;
1156 /*----------------------------------------------------------------------*/
1157 /* To recap: we estimate everything based on md_estimate_size, then
1158 adjust based on rx_relax_frag. When it all settles, we call
1159 md_convert frag to update the bytes. The relaxation types and
1160 relocations are in fragP->tc_frag_data, which is a copy of that
1161 rx_bytes.
1163 Our scheme is as follows: fr_fix has the size of the smallest
1164 opcode (like BRA.S). We store the number of total bytes we need in
1165 fr_subtype. When we're done relaxing, we use fr_subtype and the
1166 existing opcode bytes to figure out what actual opcode we need to
1167 put in there. If the fixup isn't resolvable now, we use the
1168 maximal size. */
1170 #define TRACE_RELAX 0
1171 #define tprintf if (TRACE_RELAX) printf
1173 typedef enum
1175 OT_other,
1176 OT_bra,
1177 OT_beq,
1178 OT_bne,
1179 OT_bsr,
1180 OT_bcc
1181 } op_type_T;
1183 /* We're looking for these types of relaxations:
1185 BRA.S 00001dsp
1186 BRA.B 00101110 dspppppp
1187 BRA.W 00111000 dspppppp pppppppp
1188 BRA.A 00000100 dspppppp pppppppp pppppppp
1190 BEQ.S 00010dsp
1191 BEQ.B 00100000 dspppppp
1192 BEQ.W 00111010 dspppppp pppppppp
1194 BNE.S 00011dsp
1195 BNE.B 00100001 dspppppp
1196 BNE.W 00111011 dspppppp pppppppp
1198 BSR.W 00111001 dspppppp pppppppp
1199 BSR.A 00000101 dspppppp pppppppp pppppppp
1201 Bcc.B 0010cond dspppppp
1203 Additionally, we can synthesize longer conditional branches using
1204 pairs of opcodes, one with an inverted conditional (flip LSB):
1206 Bcc.W 0010ncnd 00000110 00111000 dspppppp pppppppp
1207 Bcc.A 0010ncnd 00000111 00000100 dspppppp pppppppp pppppppp
1208 BEQ.A 00011100 00000100 dspppppp pppppppp pppppppp
1209 BNE.A 00010100 00000100 dspppppp pppppppp pppppppp */
1211 /* Given the opcode bytes at OP, figure out which opcode it is and
1212 return the type of opcode. We use this to re-encode the opcode as
1213 a different size later. */
1215 static op_type_T
1216 rx_opcode_type (char * op)
1218 unsigned char b = (unsigned char) op[0];
1220 switch (b & 0xf8)
1222 case 0x08: return OT_bra;
1223 case 0x10: return OT_beq;
1224 case 0x18: return OT_bne;
1227 switch (b)
1229 case 0x2e: return OT_bra;
1230 case 0x38: return OT_bra;
1231 case 0x04: return OT_bra;
1233 case 0x20: return OT_beq;
1234 case 0x3a: return OT_beq;
1236 case 0x21: return OT_bne;
1237 case 0x3b: return OT_bne;
1239 case 0x39: return OT_bsr;
1240 case 0x05: return OT_bsr;
1243 if ((b & 0xf0) == 0x20)
1244 return OT_bcc;
1246 return OT_other;
1249 /* Returns zero if *addrP has the target address. Else returns nonzero
1250 if we cannot compute the target address yet. */
1252 static int
1253 rx_frag_fix_value (fragS * fragP,
1254 segT segment,
1255 int which,
1256 addressT * addrP,
1257 int need_diff,
1258 addressT * sym_addr)
1260 addressT addr = 0;
1261 rx_bytesT * b = fragP->tc_frag_data;
1262 expressionS * exp = & b->fixups[which].exp;
1264 if (need_diff && exp->X_op != O_subtract)
1265 return 1;
1267 if (exp->X_add_symbol)
1269 if (S_FORCE_RELOC (exp->X_add_symbol, 1))
1270 return 1;
1271 if (S_GET_SEGMENT (exp->X_add_symbol) != segment)
1272 return 1;
1273 addr += S_GET_VALUE (exp->X_add_symbol);
1276 if (exp->X_op_symbol)
1278 if (exp->X_op != O_subtract)
1279 return 1;
1280 if (S_FORCE_RELOC (exp->X_op_symbol, 1))
1281 return 1;
1282 if (S_GET_SEGMENT (exp->X_op_symbol) != segment)
1283 return 1;
1284 addr -= S_GET_VALUE (exp->X_op_symbol);
1286 if (sym_addr)
1287 * sym_addr = addr;
1288 addr += exp->X_add_number;
1289 * addrP = addr;
1290 return 0;
1293 /* Estimate how big the opcode is after this relax pass. The return
1294 value is the difference between fr_fix and the actual size. We
1295 compute the total size in rx_relax_frag and store it in fr_subtype,
1296 sowe only need to subtract fx_fix and return it. */
1299 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
1301 int opfixsize;
1302 int delta;
1304 tprintf ("\033[32m est frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1305 fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal),
1306 fragP->fr_fix, fragP->fr_var, fragP->fr_offset,
1307 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype);
1309 /* This is the size of the opcode that's accounted for in fr_fix. */
1310 opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal);
1311 /* This is the size of the opcode that isn't. */
1312 delta = (fragP->fr_subtype - opfixsize);
1314 tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta);
1315 return delta;
1318 /* Given the new addresses for this relax pass, figure out how big
1319 each opcode must be. We store the total number of bytes needed in
1320 fr_subtype. The return value is the difference between the size
1321 after the last pass and the size after this pass, so we use the old
1322 fr_subtype to calculate the difference. */
1325 rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
1327 addressT addr0, sym_addr;
1328 addressT mypc;
1329 int disp;
1330 int oldsize = fragP->fr_subtype;
1331 int newsize = oldsize;
1332 op_type_T optype;
1333 /* Index of relaxation we care about. */
1334 int ri;
1336 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",
1337 fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal),
1338 fragP->fr_fix, fragP->fr_var, fragP->fr_offset,
1339 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype, stretch);
1341 optype = rx_opcode_type (fragP->fr_opcode);
1343 /* In the one case where we have both a disp and imm relaxation, we want
1344 the imm relaxation here. */
1345 ri = 0;
1346 if (fragP->tc_frag_data->n_relax > 1
1347 && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1348 ri = 1;
1350 /* Try to get the target address. */
1351 if (rx_frag_fix_value (fragP, segment, ri, & addr0,
1352 fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH,
1353 & sym_addr))
1355 /* If we don't, we must use the maximum size for the linker.
1356 Note that we don't use synthetically expanded conditionals
1357 for this. */
1358 switch (fragP->tc_frag_data->relax[ri].type)
1360 case RX_RELAX_BRANCH:
1361 switch (optype)
1363 case OT_bra:
1364 case OT_bsr:
1365 newsize = 4;
1366 break;
1367 case OT_beq:
1368 case OT_bne:
1369 newsize = 3;
1370 break;
1371 case OT_bcc:
1372 newsize = 2;
1373 break;
1374 case OT_other:
1375 newsize = oldsize;
1376 break;
1378 break;
1380 case RX_RELAX_IMM:
1381 newsize = fragP->tc_frag_data->relax[ri].val_ofs + 4;
1382 break;
1384 fragP->fr_subtype = newsize;
1385 tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize);
1386 return newsize - oldsize;
1389 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1390 if (sym_addr > mypc)
1391 addr0 += stretch;
1393 switch (fragP->tc_frag_data->relax[ri].type)
1395 case RX_RELAX_BRANCH:
1396 tprintf ("branch, addr %08lx pc %08lx disp %ld\n", addr0, mypc, addr0-mypc);
1397 disp = (int) addr0 - (int) mypc;
1399 switch (optype)
1401 case OT_bcc:
1402 if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1403 /* bcc.b */
1404 newsize = 2;
1405 else if (disp >= -32768 && (disp - (oldsize-5)) <= 32767)
1406 /* bncc.b/bra.w */
1407 newsize = 5;
1408 else
1409 /* bncc.b/bra.a */
1410 newsize = 6;
1411 break;
1413 case OT_beq:
1414 case OT_bne:
1415 if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1416 /* beq.s */
1417 newsize = 1;
1418 else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1419 /* beq.b */
1420 newsize = 2;
1421 else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1422 /* beq.w */
1423 newsize = 3;
1424 else
1425 /* bne.s/bra.a */
1426 newsize = 5;
1427 break;
1429 case OT_bra:
1430 case OT_bsr:
1431 if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1432 /* bra.s */
1433 newsize = 1;
1434 else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1435 /* bra.b */
1436 newsize = 2;
1437 else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1438 /* bra.w */
1439 newsize = 3;
1440 else
1441 /* bra.a */
1442 newsize = 4;
1443 break;
1445 case OT_other:
1446 break;
1448 tprintf (" - newsize %d\n", newsize);
1449 break;
1451 case RX_RELAX_IMM:
1452 tprintf ("other, addr %08lx pc %08lx LI %d OF %d\n", addr0, mypc,
1453 fragP->tc_frag_data->relax[ri].field_pos,
1454 fragP->tc_frag_data->relax[ri].val_ofs);
1456 newsize = fragP->tc_frag_data->relax[ri].val_ofs;
1458 if ((long) addr0 >= -128 && (long) addr0 <= 127)
1459 newsize += 1;
1460 else if ((long) addr0 >= -32768 && (long) addr0 <= 32767)
1461 newsize += 2;
1462 else if ((long) addr0 >= -8388608 && (long) addr0 <= 8388607)
1463 newsize += 3;
1464 else
1465 newsize += 4;
1466 break;
1468 default:
1469 break;
1472 if (fragP->tc_frag_data->relax[ri].type == RX_RELAX_BRANCH)
1473 switch (optype)
1475 case OT_bra:
1476 case OT_bcc:
1477 case OT_beq:
1478 case OT_bne:
1479 break;
1480 case OT_bsr:
1481 if (newsize < 3)
1482 newsize = 3;
1483 break;
1484 case OT_other:
1485 break;
1488 fragP->fr_subtype = newsize;
1489 tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
1490 return newsize - oldsize;
1493 /* This lets us test for the opcode type and the desired size in a
1494 switch statement. */
1495 #define OPCODE(type,size) ((type) * 16 + (size))
1497 /* Given the opcode stored in fr_opcode and the number of bytes we
1498 think we need, encode a new opcode. We stored a pointer to the
1499 fixup for this opcode in the tc_frag_data structure. If we can do
1500 the fixup here, we change the relocation type to "none" (we test
1501 for that in tc_gen_reloc) else we change it to the right type for
1502 the new (biggest) opcode. */
1504 void
1505 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1506 segT segment ATTRIBUTE_UNUSED,
1507 fragS * fragP ATTRIBUTE_UNUSED)
1509 rx_bytesT * rxb = fragP->tc_frag_data;
1510 addressT addr0, mypc;
1511 int disp;
1512 int reloc_type, reloc_adjust;
1513 char * op = fragP->fr_opcode;
1514 int keep_reloc = 0;
1515 int ri;
1516 int fi = (rxb->n_fixups > 1) ? 1 : 0;
1517 fixS * fix = rxb->fixups[fi].fixP;
1519 tprintf ("\033[31mconvrt frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1520 fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal),
1521 fragP->fr_fix, fragP->fr_var, fragP->fr_offset,
1522 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype);
1524 #if TRACE_RELAX
1526 int i;
1528 printf ("lit %08x opc %08x", (int) fragP->fr_literal, (int) fragP->fr_opcode);
1529 for (i = 0; i < 10; i++)
1530 printf (" %02x", (unsigned char) (fragP->fr_opcode[i]));
1531 printf ("\n");
1533 #endif
1535 /* In the one case where we have both a disp and imm relaxation, we want
1536 the imm relaxation here. */
1537 ri = 0;
1538 if (fragP->tc_frag_data->n_relax > 1
1539 && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1540 ri = 1;
1542 /* Try to get the target address. If we fail here, we just use the
1543 largest format. */
1544 if (rx_frag_fix_value (fragP, segment, 0, & addr0,
1545 fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH, 0))
1546 keep_reloc = 1;
1548 if (linkrelax)
1549 keep_reloc = 1;
1551 /* We used a new frag for this opcode, so the opcode address should
1552 be the frag address. */
1553 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1554 disp = (int) addr0 - (int) mypc;
1556 reloc_type = BFD_RELOC_NONE;
1557 reloc_adjust = 0;
1559 tprintf ("convert, op is %d, disp %d (%lx-%lx)\n", rx_opcode_type (fragP->fr_opcode), disp, addr0, mypc);
1560 switch (fragP->tc_frag_data->relax[ri].type)
1562 case RX_RELAX_BRANCH:
1563 switch (OPCODE (rx_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
1565 case OPCODE (OT_bra, 1): /* BRA.S - no change. */
1566 op[0] = 0x08 + (disp & 7);
1567 break;
1568 case OPCODE (OT_bra, 2): /* BRA.B - 8 bit. */
1569 op[0] = 0x2e;
1570 op[1] = disp;
1571 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1572 reloc_adjust = 1;
1573 break;
1574 case OPCODE (OT_bra, 3): /* BRA.W - 16 bit. */
1575 op[0] = 0x38;
1576 #if RX_OPCODE_BIG_ENDIAN
1577 op[1] = (disp >> 8) & 0xff;
1578 op[2] = disp;
1579 #else
1580 op[2] = (disp >> 8) & 0xff;
1581 op[1] = disp;
1582 #endif
1583 reloc_adjust = 1;
1584 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1585 break;
1586 case OPCODE (OT_bra, 4): /* BRA.A - 24 bit. */
1587 op[0] = 0x04;
1588 #if RX_OPCODE_BIG_ENDIAN
1589 op[1] = (disp >> 16) & 0xff;
1590 op[2] = (disp >> 8) & 0xff;
1591 op[3] = disp;
1592 #else
1593 op[3] = (disp >> 16) & 0xff;
1594 op[2] = (disp >> 8) & 0xff;
1595 op[1] = disp;
1596 #endif
1597 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1598 reloc_adjust = 1;
1599 break;
1601 case OPCODE (OT_beq, 1): /* BEQ.S - no change. */
1602 op[0] = 0x10 + (disp & 7);
1603 break;
1604 case OPCODE (OT_beq, 2): /* BEQ.B - 8 bit. */
1605 op[0] = 0x20;
1606 op[1] = disp;
1607 reloc_adjust = 1;
1608 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1609 break;
1610 case OPCODE (OT_beq, 3): /* BEQ.W - 16 bit. */
1611 op[0] = 0x3a;
1612 #if RX_OPCODE_BIG_ENDIAN
1613 op[1] = (disp >> 8) & 0xff;
1614 op[2] = disp;
1615 #else
1616 op[2] = (disp >> 8) & 0xff;
1617 op[1] = disp;
1618 #endif
1619 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1620 reloc_adjust = 1;
1621 break;
1622 case OPCODE (OT_beq, 5): /* BEQ.A - synthetic. */
1623 op[0] = 0x1e; /* bne.s .+4. */
1624 op[1] = 0x04; /* bra.a dsp:24. */
1625 disp -= 1;
1626 #if RX_OPCODE_BIG_ENDIAN
1627 op[2] = (disp >> 16) & 0xff;
1628 op[3] = (disp >> 8) & 0xff;
1629 op[4] = disp;
1630 #else
1631 op[4] = (disp >> 16) & 0xff;
1632 op[3] = (disp >> 8) & 0xff;
1633 op[2] = disp;
1634 #endif
1635 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1636 reloc_adjust = 2;
1637 break;
1639 case OPCODE (OT_bne, 1): /* BNE.S - no change. */
1640 op[0] = 0x18 + (disp & 7);
1641 break;
1642 case OPCODE (OT_bne, 2): /* BNE.B - 8 bit. */
1643 op[0] = 0x21;
1644 op[1] = disp;
1645 reloc_adjust = 1;
1646 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1647 break;
1648 case OPCODE (OT_bne, 3): /* BNE.W - 16 bit. */
1649 op[0] = 0x3b;
1650 #if RX_OPCODE_BIG_ENDIAN
1651 op[1] = (disp >> 8) & 0xff;
1652 op[2] = disp;
1653 #else
1654 op[2] = (disp >> 8) & 0xff;
1655 op[1] = disp;
1656 #endif
1657 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1658 reloc_adjust = 1;
1659 break;
1660 case OPCODE (OT_bne, 5): /* BNE.A - synthetic. */
1661 op[0] = 0x15; /* beq.s .+4. */
1662 op[1] = 0x04; /* bra.a dsp:24. */
1663 disp -= 1;
1664 #if RX_OPCODE_BIG_ENDIAN
1665 op[2] = (disp >> 16) & 0xff;
1666 op[3] = (disp >> 8) & 0xff;
1667 op[4] = disp;
1668 #else
1669 op[4] = (disp >> 16) & 0xff;
1670 op[3] = (disp >> 8) & 0xff;
1671 op[2] = disp;
1672 #endif
1673 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1674 reloc_adjust = 2;
1675 break;
1677 case OPCODE (OT_bsr, 3): /* BSR.W - 16 bit. */
1678 op[0] = 0x39;
1679 #if RX_OPCODE_BIG_ENDIAN
1680 op[1] = (disp >> 8) & 0xff;
1681 op[2] = disp;
1682 #else
1683 op[2] = (disp >> 8) & 0xff;
1684 op[1] = disp;
1685 #endif
1686 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1687 reloc_adjust = 0;
1688 break;
1689 case OPCODE (OT_bsr, 4): /* BSR.A - 24 bit. */
1690 op[0] = 0x05;
1691 #if RX_OPCODE_BIG_ENDIAN
1692 op[1] = (disp >> 16) & 0xff;
1693 op[2] = (disp >> 8) & 0xff;
1694 op[3] = disp;
1695 #else
1696 op[3] = (disp >> 16) & 0xff;
1697 op[2] = (disp >> 8) & 0xff;
1698 op[1] = disp;
1699 #endif
1700 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1701 reloc_adjust = 0;
1702 break;
1704 case OPCODE (OT_bcc, 2): /* Bcond.B - 8 bit. */
1705 op[1] = disp;
1706 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1707 break;
1708 case OPCODE (OT_bcc, 5): /* Bcond.W - synthetic. */
1709 op[0] ^= 1; /* Invert condition. */
1710 op[1] = 5; /* Displacement. */
1711 op[2] = 0x38;
1712 disp -= 2;
1713 #if RX_OPCODE_BIG_ENDIAN
1714 op[3] = (disp >> 8) & 0xff;
1715 op[4] = disp;
1716 #else
1717 op[4] = (disp >> 8) & 0xff;
1718 op[3] = disp;
1719 #endif
1720 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1721 reloc_adjust = 2;
1722 break;
1723 case OPCODE (OT_bcc, 6): /* Bcond.S - synthetic. */
1724 op[0] ^= 1; /* Invert condition. */
1725 op[1] = 6; /* Displacement. */
1726 op[2] = 0x04;
1727 disp -= 2;
1728 #if RX_OPCODE_BIG_ENDIAN
1729 op[3] = (disp >> 16) & 0xff;
1730 op[4] = (disp >> 8) & 0xff;
1731 op[5] = disp;
1732 #else
1733 op[5] = (disp >> 16) & 0xff;
1734 op[4] = (disp >> 8) & 0xff;
1735 op[3] = disp;
1736 #endif
1737 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1738 reloc_adjust = 2;
1739 break;
1741 default:
1742 /* These are opcodes we'll relax in th linker, later. */
1743 if (rxb->n_fixups)
1744 reloc_type = rxb->fixups[ri].fixP->fx_r_type;
1745 break;
1747 break;
1749 case RX_RELAX_IMM:
1751 int nbytes = fragP->fr_subtype - fragP->tc_frag_data->relax[ri].val_ofs;
1752 int li;
1753 char * imm = op + fragP->tc_frag_data->relax[ri].val_ofs;
1755 switch (nbytes)
1757 case 1:
1758 li = 1;
1759 imm[0] = addr0;
1760 reloc_type = BFD_RELOC_8;
1761 break;
1762 case 2:
1763 li = 2;
1764 #if RX_OPCODE_BIG_ENDIAN
1765 imm[1] = addr0;
1766 imm[0] = addr0 >> 8;
1767 #else
1768 imm[0] = addr0;
1769 imm[1] = addr0 >> 8;
1770 #endif
1771 reloc_type = BFD_RELOC_RX_16_OP;
1772 break;
1773 case 3:
1774 li = 3;
1775 #if RX_OPCODE_BIG_ENDIAN
1776 imm[2] = addr0;
1777 imm[1] = addr0 >> 8;
1778 imm[0] = addr0 >> 16;
1779 #else
1780 imm[0] = addr0;
1781 imm[1] = addr0 >> 8;
1782 imm[2] = addr0 >> 16;
1783 #endif
1784 reloc_type = BFD_RELOC_RX_24_OP;
1785 break;
1786 case 4:
1787 li = 0;
1788 #if RX_OPCODE_BIG_ENDIAN
1789 imm[3] = addr0;
1790 imm[2] = addr0 >> 8;
1791 imm[1] = addr0 >> 16;
1792 imm[0] = addr0 >> 24;
1793 #else
1794 imm[0] = addr0;
1795 imm[1] = addr0 >> 8;
1796 imm[2] = addr0 >> 16;
1797 imm[3] = addr0 >> 24;
1798 #endif
1799 reloc_type = BFD_RELOC_RX_32_OP;
1800 break;
1801 default:
1802 as_bad (_("invalid immediate size"));
1803 li = -1;
1806 switch (fragP->tc_frag_data->relax[ri].field_pos)
1808 case 6:
1809 op[0] &= 0xfc;
1810 op[0] |= li;
1811 break;
1812 case 12:
1813 op[1] &= 0xf3;
1814 op[1] |= li << 2;
1815 break;
1816 case 20:
1817 op[2] &= 0xf3;
1818 op[2] |= li << 2;
1819 break;
1820 default:
1821 as_bad (_("invalid immediate field position"));
1824 break;
1826 default:
1827 if (rxb->n_fixups)
1829 reloc_type = fix->fx_r_type;
1830 reloc_adjust = 0;
1832 break;
1835 if (rxb->n_fixups)
1838 fix->fx_r_type = reloc_type;
1839 fix->fx_where += reloc_adjust;
1840 switch (reloc_type)
1842 case BFD_RELOC_NONE:
1843 fix->fx_size = 0;
1844 break;
1845 case BFD_RELOC_8:
1846 fix->fx_size = 1;
1847 break;
1848 case BFD_RELOC_16_PCREL:
1849 case BFD_RELOC_RX_16_OP:
1850 fix->fx_size = 2;
1851 break;
1852 case BFD_RELOC_24_PCREL:
1853 case BFD_RELOC_RX_24_OP:
1854 fix->fx_size = 3;
1855 break;
1856 case BFD_RELOC_RX_32_OP:
1857 fix->fx_size = 4;
1858 break;
1862 fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
1863 tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", fragP->fr_fix,
1864 fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
1865 fragP->fr_var = 0;
1867 if (fragP->fr_next != NULL
1868 && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
1869 != fragP->fr_fix))
1870 as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
1871 fragP->fr_fix, fragP->fr_address, fragP->fr_next->fr_address);
1874 #undef OPCODE
1877 rx_validate_fix_sub (struct fix * f)
1879 /* We permit the subtraction of two symbols as a 32-bit relocation. */
1880 if (f->fx_r_type == BFD_RELOC_RX_DIFF
1881 && ! f->fx_pcrel
1882 && f->fx_size == 4)
1883 return 1;
1884 return 0;
1887 long
1888 md_pcrel_from_section (fixS * fixP, segT sec)
1890 long rv;
1892 if (fixP->fx_addsy != NULL
1893 && (! S_IS_DEFINED (fixP->fx_addsy)
1894 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
1895 /* The symbol is undefined (or is defined but not in this section).
1896 Let the linker figure it out. */
1897 return 0;
1899 rv = fixP->fx_frag->fr_address + fixP->fx_where;
1900 switch (fixP->fx_r_type)
1902 case BFD_RELOC_RX_DIR3U_PCREL:
1903 return rv;
1904 default:
1905 return rv - 1;
1909 void
1910 rx_cons_fix_new (fragS * frag,
1911 int where,
1912 int size,
1913 expressionS * exp)
1915 bfd_reloc_code_real_type type;
1917 switch (size)
1919 case 1:
1920 type = BFD_RELOC_8;
1921 break;
1922 case 2:
1923 type = BFD_RELOC_16;
1924 break;
1925 case 3:
1926 type = BFD_RELOC_24;
1927 break;
1928 case 4:
1929 type = BFD_RELOC_32;
1930 break;
1931 default:
1932 as_bad (_("unsupported constant size %d\n"), size);
1933 return;
1936 if (exp->X_op == O_subtract && exp->X_op_symbol)
1938 if (size != 4 && size != 2 && size != 1)
1939 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
1940 else
1941 type = BFD_RELOC_RX_DIFF;
1944 fix_new_exp (frag, where, (int) size, exp, 0, type);
1947 void
1948 md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
1949 valueT * t ATTRIBUTE_UNUSED,
1950 segT s ATTRIBUTE_UNUSED)
1952 /* Instruction bytes are always little endian. */
1953 char * op;
1954 unsigned long val;
1956 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
1957 return;
1958 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
1959 return;
1961 #define OP2(x) op[target_big_endian ? 1-x : x]
1962 #define OP3(x) op[target_big_endian ? 2-x : x]
1963 #define OP4(x) op[target_big_endian ? 3-x : x]
1965 op = f->fx_frag->fr_literal + f->fx_where;
1966 val = (unsigned long) * t;
1968 /* Opcode words are always the same endian. Data words are either
1969 big or little endian. */
1971 switch (f->fx_r_type)
1973 case BFD_RELOC_NONE:
1974 break;
1976 case BFD_RELOC_RX_RELAX:
1977 f->fx_done = 1;
1978 break;
1980 case BFD_RELOC_RX_DIR3U_PCREL:
1981 if (val < 3 || val > 10)
1982 as_bad_where (f->fx_file, f->fx_line,
1983 _("jump not 3..10 bytes away (is %d)"), (int) val);
1984 op[0] &= 0xf8;
1985 op[0] |= val & 0x07;
1986 break;
1988 case BFD_RELOC_8:
1989 case BFD_RELOC_8_PCREL:
1990 case BFD_RELOC_RX_8U:
1991 op[0] = val;
1992 break;
1994 case BFD_RELOC_16:
1995 OP2(1) = val & 0xff;
1996 OP2(0) = (val >> 8) & 0xff;
1997 break;
1999 case BFD_RELOC_16_PCREL:
2000 case BFD_RELOC_RX_16_OP:
2001 case BFD_RELOC_RX_16U:
2002 #if RX_OPCODE_BIG_ENDIAN
2003 op[1] = val & 0xff;
2004 op[0] = (val >> 8) & 0xff;
2005 #else
2006 op[0] = val & 0xff;
2007 op[1] = (val >> 8) & 0xff;
2008 #endif
2009 break;
2011 case BFD_RELOC_24:
2012 OP3(0) = val & 0xff;
2013 OP3(1) = (val >> 8) & 0xff;
2014 OP3(2) = (val >> 16) & 0xff;
2015 break;
2017 case BFD_RELOC_24_PCREL:
2018 case BFD_RELOC_RX_24_OP:
2019 case BFD_RELOC_RX_24U:
2020 #if RX_OPCODE_BIG_ENDIAN
2021 op[2] = val & 0xff;
2022 op[1] = (val >> 8) & 0xff;
2023 op[0] = (val >> 16) & 0xff;
2024 #else
2025 op[0] = val & 0xff;
2026 op[1] = (val >> 8) & 0xff;
2027 op[2] = (val >> 16) & 0xff;
2028 #endif
2029 break;
2031 case BFD_RELOC_RX_DIFF:
2032 switch (f->fx_size)
2034 case 1:
2035 op[0] = val & 0xff;
2036 break;
2037 case 2:
2038 OP2(0) = val & 0xff;
2039 OP2(1) = (val >> 8) & 0xff;
2040 break;
2041 case 4:
2042 OP4(0) = val & 0xff;
2043 OP4(1) = (val >> 8) & 0xff;
2044 OP4(2) = (val >> 16) & 0xff;
2045 OP4(3) = (val >> 24) & 0xff;
2046 break;
2048 break;
2050 case BFD_RELOC_32:
2051 OP4(0) = val & 0xff;
2052 OP4(1) = (val >> 8) & 0xff;
2053 OP4(2) = (val >> 16) & 0xff;
2054 OP4(3) = (val >> 24) & 0xff;
2055 break;
2057 case BFD_RELOC_RX_32_OP:
2058 #if RX_OPCODE_BIG_ENDIAN
2059 op[3] = val & 0xff;
2060 op[2] = (val >> 8) & 0xff;
2061 op[1] = (val >> 16) & 0xff;
2062 op[0] = (val >> 24) & 0xff;
2063 #else
2064 op[0] = val & 0xff;
2065 op[1] = (val >> 8) & 0xff;
2066 op[2] = (val >> 16) & 0xff;
2067 op[3] = (val >> 24) & 0xff;
2068 #endif
2069 break;
2071 case BFD_RELOC_RX_NEG8:
2072 op[0] = - val;
2073 break;
2075 case BFD_RELOC_RX_NEG16:
2076 val = -val;
2077 #if RX_OPCODE_BIG_ENDIAN
2078 op[1] = val & 0xff;
2079 op[0] = (val >> 8) & 0xff;
2080 #else
2081 op[0] = val & 0xff;
2082 op[1] = (val >> 8) & 0xff;
2083 #endif
2084 break;
2086 case BFD_RELOC_RX_NEG24:
2087 val = -val;
2088 #if RX_OPCODE_BIG_ENDIAN
2089 op[2] = val & 0xff;
2090 op[1] = (val >> 8) & 0xff;
2091 op[0] = (val >> 16) & 0xff;
2092 #else
2093 op[0] = val & 0xff;
2094 op[1] = (val >> 8) & 0xff;
2095 op[2] = (val >> 16) & 0xff;
2096 #endif
2097 break;
2099 case BFD_RELOC_RX_NEG32:
2100 val = -val;
2101 #if RX_OPCODE_BIG_ENDIAN
2102 op[3] = val & 0xff;
2103 op[2] = (val >> 8) & 0xff;
2104 op[1] = (val >> 16) & 0xff;
2105 op[0] = (val >> 24) & 0xff;
2106 #else
2107 op[0] = val & 0xff;
2108 op[1] = (val >> 8) & 0xff;
2109 op[2] = (val >> 16) & 0xff;
2110 op[3] = (val >> 24) & 0xff;
2111 #endif
2112 break;
2114 case BFD_RELOC_RX_GPRELL:
2115 val >>= 1;
2116 case BFD_RELOC_RX_GPRELW:
2117 val >>= 1;
2118 case BFD_RELOC_RX_GPRELB:
2119 #if RX_OPCODE_BIG_ENDIAN
2120 op[1] = val & 0xff;
2121 op[0] = (val >> 8) & 0xff;
2122 #else
2123 op[0] = val & 0xff;
2124 op[1] = (val >> 8) & 0xff;
2125 #endif
2126 break;
2128 default:
2129 as_bad (_("Unknown reloc in md_apply_fix: %s"),
2130 bfd_get_reloc_code_name (f->fx_r_type));
2131 break;
2134 if (f->fx_addsy == NULL)
2135 f->fx_done = 1;
2138 arelent **
2139 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
2141 static arelent * reloc[5];
2143 if (fixp->fx_r_type == BFD_RELOC_NONE)
2145 reloc[0] = NULL;
2146 return reloc;
2149 if (fixp->fx_subsy
2150 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
2152 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
2153 fixp->fx_subsy = NULL;
2156 reloc[0] = (arelent *) xmalloc (sizeof (arelent));
2157 reloc[0]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2158 * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2159 reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2160 reloc[0]->addend = fixp->fx_offset;
2162 /* Certain BFD relocations cannot be translated directly into
2163 a single (non-Red Hat) RX relocation, but instead need
2164 multiple RX relocations - handle them here. */
2165 switch (fixp->fx_r_type)
2167 case BFD_RELOC_RX_DIFF:
2168 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2170 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2171 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2172 * reloc[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2173 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2174 reloc[1]->addend = 0;
2175 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2177 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2178 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2179 reloc[2]->addend = 0;
2180 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2181 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2183 reloc[3] = (arelent *) xmalloc (sizeof (arelent));
2184 switch (fixp->fx_size)
2186 case 1:
2187 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS8);
2188 break;
2189 case 2:
2190 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16);
2191 break;
2192 case 4:
2193 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
2194 break;
2196 reloc[3]->addend = 0;
2197 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2198 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2200 reloc[4] = NULL;
2201 break;
2203 case BFD_RELOC_RX_GPRELL:
2204 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2206 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2207 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2208 if (gp_symbol == NULL)
2210 if (symbol_table_frozen)
2212 symbolS * gp;
2214 gp = symbol_find ("__gp");
2215 if (gp == NULL)
2216 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2217 else
2218 gp_symbol = symbol_get_bfdsym (gp);
2220 else
2221 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2223 * reloc[1]->sym_ptr_ptr = gp_symbol;
2224 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2225 reloc[1]->addend = 0;
2226 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2228 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2229 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2230 reloc[2]->addend = 0;
2231 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2232 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2234 reloc[3] = (arelent *) xmalloc (sizeof (arelent));
2235 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL);
2236 reloc[3]->addend = 0;
2237 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2238 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2240 reloc[4] = NULL;
2241 break;
2243 case BFD_RELOC_RX_GPRELW:
2244 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2246 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2247 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2248 if (gp_symbol == NULL)
2250 if (symbol_table_frozen)
2252 symbolS * gp;
2254 gp = symbol_find ("__gp");
2255 if (gp == NULL)
2256 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2257 else
2258 gp_symbol = symbol_get_bfdsym (gp);
2260 else
2261 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2263 * reloc[1]->sym_ptr_ptr = gp_symbol;
2264 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2265 reloc[1]->addend = 0;
2266 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2268 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2269 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2270 reloc[2]->addend = 0;
2271 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2272 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2274 reloc[3] = (arelent *) xmalloc (sizeof (arelent));
2275 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UW);
2276 reloc[3]->addend = 0;
2277 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2278 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2280 reloc[4] = NULL;
2281 break;
2283 case BFD_RELOC_RX_GPRELB:
2284 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2286 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2287 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2288 if (gp_symbol == NULL)
2290 if (symbol_table_frozen)
2292 symbolS * gp;
2294 gp = symbol_find ("__gp");
2295 if (gp == NULL)
2296 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2297 else
2298 gp_symbol = symbol_get_bfdsym (gp);
2300 else
2301 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2303 * reloc[1]->sym_ptr_ptr = gp_symbol;
2304 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2305 reloc[1]->addend = 0;
2306 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2308 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2309 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2310 reloc[2]->addend = 0;
2311 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2312 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2314 reloc[3] = (arelent *) xmalloc (sizeof (arelent));
2315 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16U);
2316 reloc[3]->addend = 0;
2317 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2318 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2320 reloc[4] = NULL;
2321 break;
2323 default:
2324 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2325 reloc[1] = NULL;
2326 break;
2329 return reloc;
2332 /* Set the ELF specific flags. */
2334 void
2335 rx_elf_final_processing (void)
2337 elf_elfheader (stdoutput)->e_flags |= elf_flags;
2340 /* Scan the current input line for occurances of Renesas
2341 local labels and replace them with the GAS version. */
2343 void
2344 rx_start_line (void)
2346 int in_double_quote = 0;
2347 int in_single_quote = 0;
2348 int done = 0;
2349 char * p = input_line_pointer;
2351 /* Scan the line looking for question marks. Skip past quote enclosed regions. */
2354 switch (*p)
2356 case '\n':
2357 case 0:
2358 done = 1;
2359 break;
2361 case '"':
2362 in_double_quote = ! in_double_quote;
2363 break;
2365 case '\'':
2366 in_single_quote = ! in_single_quote;
2367 break;
2369 case '?':
2370 if (in_double_quote || in_single_quote)
2371 break;
2373 if (p[1] == ':')
2374 *p = '1';
2375 else if (p[1] == '+')
2377 p[0] = '1';
2378 p[1] = 'f';
2380 else if (p[1] == '-')
2382 p[0] = '1';
2383 p[1] = 'b';
2385 break;
2387 default:
2388 break;
2391 p ++;
2393 while (! done);