Add support for DragonFlyBSD target.
[binutils.git] / gas / config / tc-rx.c
blob3daa7df4a857790783fa2f4137d26f9f76831f39
1 /* tc-rx.c -- Assembler for the Renesas RX
2 Copyright 2008, 2009, 2010
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 /* These 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 char times_grown;
628 char times_shrank;
629 } rx_bytesT;
631 static rx_bytesT rx_bytes;
633 void
634 rx_relax (int type, int pos)
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 ++;
642 void
643 rx_linkrelax_dsp (int pos)
645 switch (pos)
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;
659 void
660 rx_linkrelax_imm (int pos)
662 switch (pos)
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;
673 void
674 rx_linkrelax_branch (void)
676 rx_bytes.link_relax |= RX_RELAXA_BRA;
679 static void
680 rx_fixup (expressionS exp, int offsetbits, int nbits, int type)
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 ++;
690 #define rx_field_fixup(exp, offset, nbits, type) \
691 rx_fixup (exp, offset, nbits, type)
693 #define rx_op_fixup(exp, offset, nbits, type) \
694 rx_fixup (exp, offset + 8 * rx_bytes.n_base, nbits, type)
696 void
697 rx_base1 (int b1)
699 rx_bytes.base[0] = b1;
700 rx_bytes.n_base = 1;
703 void
704 rx_base2 (int b1, int b2)
706 rx_bytes.base[0] = b1;
707 rx_bytes.base[1] = b2;
708 rx_bytes.n_base = 2;
711 void
712 rx_base3 (int b1, int b2, int b3)
714 rx_bytes.base[0] = b1;
715 rx_bytes.base[1] = b2;
716 rx_bytes.base[2] = b3;
717 rx_bytes.n_base = 3;
720 void
721 rx_base4 (int b1, int b2, int b3, int b4)
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;
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:
736 - - - - - - - - - - - - - - - -
737 M X L */
739 void
740 rx_field (int val, int pos, int sz)
742 int valm;
743 int bytep, bitp;
745 if (sz > 0)
747 if (val < 0 || val >= (1 << sz))
748 as_bad (_("Value %d doesn't fit in unsigned %d-bit field"), val, sz);
750 else
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);
757 /* This code points at 'M' in the above example. */
758 bytep = pos / 8;
759 bitp = pos % 8;
761 while (bitp + sz > 8)
763 int ssz = 8 - bitp;
764 int svalm;
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;
772 bitp = 0;
773 sz -= ssz;
774 bytep ++;
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;
782 /* Special case of the above, for 3-bit displacements of 2..9. */
784 void
785 rx_disp3 (expressionS exp, int pos)
787 rx_field_fixup (exp, pos, 3, RXREL_PCREL);
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--- */
794 void
795 rx_field5s (expressionS exp)
797 int val;
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;
805 /* ---- ---- 4--- 3210 */
807 void
808 rx_field5s2 (expressionS exp)
810 int val;
812 val = exp.X_add_number;
813 rx_bytes.base[1] |= (val << 3) & 0x80;
814 rx_bytes.base[1] |= (val ) & 0x0f;
817 #define OP(x) rx_bytes.ops[rx_bytes.n_ops++] = (x)
819 #define F_PRECISION 2
821 void
822 rx_op (expressionS exp, int nbytes, int type)
824 int v = 0;
826 if ((exp.X_op == O_constant || exp.X_op == O_big)
827 && type != RXREL_PCREL)
829 if (exp.X_op == O_big && exp.X_add_number <= 0)
831 LITTLENUM_TYPE w[2];
832 char * ip = rx_bytes.ops + rx_bytes.n_ops;
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;
848 else
850 v = exp.X_add_number;
851 while (nbytes)
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 --;
863 else
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;
872 rx_wrap (void)
874 return 0;
877 #define APPEND(B, N_B) \
878 if (rx_bytes.N_B) \
880 memcpy (bytes + idx, rx_bytes.B, rx_bytes.N_B); \
881 idx += rx_bytes.N_B; \
884 void
885 rx_frag_init (fragS * fragP)
887 if (rx_bytes.n_relax || rx_bytes.link_relax)
889 fragP->tc_frag_data = malloc (sizeof (rx_bytesT));
890 memcpy (fragP->tc_frag_data, & rx_bytes, sizeof (rx_bytesT));
892 else
893 fragP->tc_frag_data = 0;
896 /* Handle the as100's version of the .equ pseudo-op. It has the syntax:
897 <symbol_name> .equ <expression> */
899 static void
900 rx_equ (char * name, char * expression)
902 char saved_name_end_char;
903 char * name_end;
904 char * saved_ilp;
906 while (ISSPACE (* name))
907 name ++;
909 for (name_end = name + 1; *name_end; name_end ++)
910 if (! ISALNUM (* name_end))
911 break;
913 saved_name_end_char = * name_end;
914 * name_end = 0;
916 saved_ilp = input_line_pointer;
917 input_line_pointer = expression;
919 equals (name, 1);
921 input_line_pointer = saved_ilp;
922 * name_end = saved_name_end_char;
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. */
929 static bfd_boolean
930 scan_for_infix_rx_pseudo_ops (char * str)
932 char * p;
933 char * pseudo_op;
934 char * dot = strchr (str, '.');
936 if (dot == NULL || dot == str)
937 return FALSE;
939 /* A real pseudo-op must be preceeded by whitespace. */
940 if (dot[-1] != ' ' && dot[-1] != '\t')
941 return FALSE;
943 pseudo_op = dot + 1;
945 if (!ISALNUM (* pseudo_op))
946 return FALSE;
948 for (p = pseudo_op + 1; ISALNUM (* p); p++)
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;
962 return TRUE;
965 void
966 md_assemble (char * str)
968 char * bytes;
969 int idx = 0;
970 int i, rel;
971 fragS * frag_then = frag_now;
972 expressionS *exp;
974 memset (& rx_bytes, 0, sizeof (rx_bytes));
976 rx_lex_init (str, str + strlen (str));
977 if (scan_for_infix_rx_pseudo_ops (str))
978 return;
979 rx_parse ();
981 /* This simplifies the relaxation code. */
982 if (rx_bytes.n_relax || rx_bytes.link_relax)
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;
999 else
1001 bytes = frag_more (rx_bytes.n_base + rx_bytes.n_ops);
1002 frag_then = frag_now;
1005 APPEND (base, n_base);
1006 APPEND (ops, n_ops);
1008 if (rx_bytes.link_relax && rx_bytes.n_fixups)
1010 fixS * f;
1012 f = fix_new (frag_then,
1013 (char *) bytes - frag_then->fr_literal,
1015 abs_section_sym,
1016 rx_bytes.link_relax | rx_bytes.n_fixups,
1018 BFD_RELOC_RX_RELAX);
1019 frag_then->tc_frag_data->link_relax_fixP = f;
1022 for (i = 0; i < rx_bytes.n_fixups; i ++)
1024 /* index: [nbytes][type] */
1025 static int reloc_map[5][4] =
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 },
1033 fixS * f;
1035 idx = rx_bytes.fixups[i].offset / 8;
1036 rel = reloc_map [rx_bytes.fixups[i].nbits / 8][(int) rx_bytes.fixups[i].type];
1038 if (rx_bytes.fixups[i].reloc)
1039 rel = rx_bytes.fixups[i].reloc;
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;
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;
1056 dwarf2_emit_insn (idx);
1059 void
1060 rx_md_end (void)
1064 /* Write a value out to the object file, using the appropriate endianness. */
1066 void
1067 md_number_to_chars (char * buf, valueT val, int n)
1069 if (target_big_endian)
1070 number_to_chars_bigendian (buf, val, n);
1071 else
1072 number_to_chars_littleendian (buf, val, n);
1075 static struct
1077 char * fname;
1078 int reloc;
1080 reloc_functions[] =
1082 { "gp", BFD_RELOC_GPREL16 },
1083 { 0, 0 }
1086 void
1087 md_operand (expressionS * exp ATTRIBUTE_UNUSED)
1089 int reloc = 0;
1090 int i;
1092 for (i = 0; reloc_functions[i].fname; i++)
1094 int flen = strlen (reloc_functions[i].fname);
1096 if (input_line_pointer[0] == '%'
1097 && strncasecmp (input_line_pointer + 1, reloc_functions[i].fname, flen) == 0
1098 && input_line_pointer[flen + 1] == '(')
1100 reloc = reloc_functions[i].reloc;
1101 input_line_pointer += flen + 2;
1102 break;
1105 if (reloc == 0)
1106 return;
1108 expression (exp);
1109 if (* input_line_pointer == ')')
1110 input_line_pointer ++;
1112 exp->X_md = reloc;
1115 valueT
1116 md_section_align (segT segment, valueT size)
1118 int align = bfd_get_section_alignment (stdoutput, segment);
1119 return ((size + (1 << align) - 1) & (-1 << align));
1122 /* NOP - 1 cycle */
1123 static unsigned char nop_1[] = { 0x03};
1124 /* MOV.L R0,R0 - 1 cycle */
1125 static unsigned char nop_2[] = { 0xef, 0x00};
1126 /* MAX R0,R0 - 1 cycle */
1127 static unsigned char nop_3[] = { 0xfc, 0x13, 0x00 };
1128 /* MUL #1,R0 - 1 cycle */
1129 static unsigned char nop_4[] = { 0x76, 0x10, 0x01, 0x00 };
1130 /* MUL #1,R0 - 1 cycle */
1131 static unsigned char nop_5[] = { 0x77, 0x10, 0x01, 0x00, 0x00 };
1132 /* MUL #1,R0 - 1 cycle */
1133 static unsigned char nop_6[] = { 0x74, 0x10, 0x01, 0x00, 0x00, 0x00 };
1134 /* BRA.S .+7 - 1 cycle */
1135 static unsigned char nop_7[] = { 0x0F, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
1137 static unsigned char *nops[] = { NULL, nop_1, nop_2, nop_3, nop_4, nop_5, nop_6, nop_7 };
1138 #define BIGGEST_NOP 7
1140 /* When relaxing, we need to output a reloc for any .align directive
1141 so that we can retain this alignment as we adjust opcode sizes. */
1142 void
1143 rx_handle_align (fragS * frag)
1145 /* If handling an alignment frag, use an optimal NOP pattern.
1146 Only do this if a fill value has not already been provided.
1147 FIXME: This test fails if the provided fill value is zero. */
1148 if ((frag->fr_type == rs_align
1149 || frag->fr_type == rs_align_code)
1150 && subseg_text_p (now_seg))
1152 int count = (frag->fr_next->fr_address
1153 - frag->fr_address
1154 - frag->fr_fix);
1155 unsigned char *base = (unsigned char *)frag->fr_literal + frag->fr_fix;
1157 if (* base == 0)
1159 if (count > BIGGEST_NOP)
1161 base[0] = 0x2e;
1162 base[1] = count;
1163 frag->fr_var = 2;
1165 else if (count > 0)
1167 memcpy (base, nops[count], count);
1168 frag->fr_var = count;
1173 if (linkrelax
1174 && (frag->fr_type == rs_align
1175 || frag->fr_type == rs_align_code)
1176 && frag->fr_address + frag->fr_fix > 0
1177 && frag->fr_offset > 0
1178 && now_seg != bss_section)
1180 fix_new (frag, frag->fr_fix, 0,
1181 &abs_symbol, RX_RELAXA_ALIGN + frag->fr_offset,
1182 0, BFD_RELOC_RX_RELAX);
1183 /* For the purposes of relaxation, this relocation is attached
1184 to the byte *after* the alignment - i.e. the byte that must
1185 remain aligned. */
1186 fix_new (frag->fr_next, 0, 0,
1187 &abs_symbol, RX_RELAXA_ELIGN + frag->fr_offset,
1188 0, BFD_RELOC_RX_RELAX);
1192 char *
1193 md_atof (int type, char * litP, int * sizeP)
1195 return ieee_md_atof (type, litP, sizeP, target_big_endian);
1198 symbolS *
1199 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1201 return NULL;
1204 /*----------------------------------------------------------------------*/
1205 /* To recap: we estimate everything based on md_estimate_size, then
1206 adjust based on rx_relax_frag. When it all settles, we call
1207 md_convert frag to update the bytes. The relaxation types and
1208 relocations are in fragP->tc_frag_data, which is a copy of that
1209 rx_bytes.
1211 Our scheme is as follows: fr_fix has the size of the smallest
1212 opcode (like BRA.S). We store the number of total bytes we need in
1213 fr_subtype. When we're done relaxing, we use fr_subtype and the
1214 existing opcode bytes to figure out what actual opcode we need to
1215 put in there. If the fixup isn't resolvable now, we use the
1216 maximal size. */
1218 #define TRACE_RELAX 0
1219 #define tprintf if (TRACE_RELAX) printf
1221 typedef enum
1223 OT_other,
1224 OT_bra,
1225 OT_beq,
1226 OT_bne,
1227 OT_bsr,
1228 OT_bcc
1229 } op_type_T;
1231 /* We're looking for these types of relaxations:
1233 BRA.S 00001dsp
1234 BRA.B 00101110 dspppppp
1235 BRA.W 00111000 dspppppp pppppppp
1236 BRA.A 00000100 dspppppp pppppppp pppppppp
1238 BEQ.S 00010dsp
1239 BEQ.B 00100000 dspppppp
1240 BEQ.W 00111010 dspppppp pppppppp
1242 BNE.S 00011dsp
1243 BNE.B 00100001 dspppppp
1244 BNE.W 00111011 dspppppp pppppppp
1246 BSR.W 00111001 dspppppp pppppppp
1247 BSR.A 00000101 dspppppp pppppppp pppppppp
1249 Bcc.B 0010cond dspppppp
1251 Additionally, we can synthesize longer conditional branches using
1252 pairs of opcodes, one with an inverted conditional (flip LSB):
1254 Bcc.W 0010ncnd 00000110 00111000 dspppppp pppppppp
1255 Bcc.A 0010ncnd 00000111 00000100 dspppppp pppppppp pppppppp
1256 BEQ.A 00011100 00000100 dspppppp pppppppp pppppppp
1257 BNE.A 00010100 00000100 dspppppp pppppppp pppppppp */
1259 /* Given the opcode bytes at OP, figure out which opcode it is and
1260 return the type of opcode. We use this to re-encode the opcode as
1261 a different size later. */
1263 static op_type_T
1264 rx_opcode_type (char * op)
1266 unsigned char b = (unsigned char) op[0];
1268 switch (b & 0xf8)
1270 case 0x08: return OT_bra;
1271 case 0x10: return OT_beq;
1272 case 0x18: return OT_bne;
1275 switch (b)
1277 case 0x2e: return OT_bra;
1278 case 0x38: return OT_bra;
1279 case 0x04: return OT_bra;
1281 case 0x20: return OT_beq;
1282 case 0x3a: return OT_beq;
1284 case 0x21: return OT_bne;
1285 case 0x3b: return OT_bne;
1287 case 0x39: return OT_bsr;
1288 case 0x05: return OT_bsr;
1291 if ((b & 0xf0) == 0x20)
1292 return OT_bcc;
1294 return OT_other;
1297 /* Returns zero if *addrP has the target address. Else returns nonzero
1298 if we cannot compute the target address yet. */
1300 static int
1301 rx_frag_fix_value (fragS * fragP,
1302 segT segment,
1303 int which,
1304 addressT * addrP,
1305 int need_diff,
1306 addressT * sym_addr)
1308 addressT addr = 0;
1309 rx_bytesT * b = fragP->tc_frag_data;
1310 expressionS * exp = & b->fixups[which].exp;
1312 if (need_diff && exp->X_op != O_subtract)
1313 return 1;
1315 if (exp->X_add_symbol)
1317 if (S_FORCE_RELOC (exp->X_add_symbol, 1))
1318 return 1;
1319 if (S_GET_SEGMENT (exp->X_add_symbol) != segment)
1320 return 1;
1321 addr += S_GET_VALUE (exp->X_add_symbol);
1324 if (exp->X_op_symbol)
1326 if (exp->X_op != O_subtract)
1327 return 1;
1328 if (S_FORCE_RELOC (exp->X_op_symbol, 1))
1329 return 1;
1330 if (S_GET_SEGMENT (exp->X_op_symbol) != segment)
1331 return 1;
1332 addr -= S_GET_VALUE (exp->X_op_symbol);
1334 if (sym_addr)
1335 * sym_addr = addr;
1336 addr += exp->X_add_number;
1337 * addrP = addr;
1338 return 0;
1341 /* Estimate how big the opcode is after this relax pass. The return
1342 value is the difference between fr_fix and the actual size. We
1343 compute the total size in rx_relax_frag and store it in fr_subtype,
1344 sowe only need to subtract fx_fix and return it. */
1347 md_estimate_size_before_relax (fragS * fragP ATTRIBUTE_UNUSED, segT segment ATTRIBUTE_UNUSED)
1349 int opfixsize;
1350 int delta;
1352 tprintf ("\033[32m est frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1353 (unsigned long) (fragP->fr_address
1354 + (fragP->fr_opcode - fragP->fr_literal)),
1355 (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1356 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype);
1358 /* This is the size of the opcode that's accounted for in fr_fix. */
1359 opfixsize = fragP->fr_fix - (fragP->fr_opcode - fragP->fr_literal);
1360 /* This is the size of the opcode that isn't. */
1361 delta = (fragP->fr_subtype - opfixsize);
1363 tprintf (" -> opfixsize %d delta %d\n", opfixsize, delta);
1364 return delta;
1367 /* Given the new addresses for this relax pass, figure out how big
1368 each opcode must be. We store the total number of bytes needed in
1369 fr_subtype. The return value is the difference between the size
1370 after the last pass and the size after this pass, so we use the old
1371 fr_subtype to calculate the difference. */
1374 rx_relax_frag (segT segment ATTRIBUTE_UNUSED, fragS * fragP, long stretch)
1376 addressT addr0, sym_addr;
1377 addressT mypc;
1378 int disp;
1379 int oldsize = fragP->fr_subtype;
1380 int newsize = oldsize;
1381 op_type_T optype;
1382 /* Index of relaxation we care about. */
1383 int ri;
1385 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",
1386 (unsigned long) (fragP->fr_address
1387 + (fragP->fr_opcode - fragP->fr_literal)),
1388 (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1389 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type, fragP->fr_subtype, stretch);
1391 optype = rx_opcode_type (fragP->fr_opcode);
1393 /* In the one case where we have both a disp and imm relaxation, we want
1394 the imm relaxation here. */
1395 ri = 0;
1396 if (fragP->tc_frag_data->n_relax > 1
1397 && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1398 ri = 1;
1400 /* Try to get the target address. */
1401 if (rx_frag_fix_value (fragP, segment, ri, & addr0,
1402 fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH,
1403 & sym_addr))
1405 /* If we don't, we must use the maximum size for the linker.
1406 Note that we don't use synthetically expanded conditionals
1407 for this. */
1408 switch (fragP->tc_frag_data->relax[ri].type)
1410 case RX_RELAX_BRANCH:
1411 switch (optype)
1413 case OT_bra:
1414 case OT_bsr:
1415 newsize = 4;
1416 break;
1417 case OT_beq:
1418 case OT_bne:
1419 newsize = 3;
1420 break;
1421 case OT_bcc:
1422 newsize = 2;
1423 break;
1424 case OT_other:
1425 newsize = oldsize;
1426 break;
1428 break;
1430 case RX_RELAX_IMM:
1431 newsize = fragP->tc_frag_data->relax[ri].val_ofs + 4;
1432 break;
1434 fragP->fr_subtype = newsize;
1435 tprintf (" -> new %d old %d delta %d (external)\n", newsize, oldsize, newsize-oldsize);
1436 return newsize - oldsize;
1439 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1440 if (sym_addr > mypc)
1441 addr0 += stretch;
1443 switch (fragP->tc_frag_data->relax[ri].type)
1445 case RX_RELAX_BRANCH:
1446 tprintf ("branch, addr %08lx pc %08lx disp %ld\n",
1447 (unsigned long) addr0, (unsigned long) mypc,
1448 (long) (addr0 - mypc));
1449 disp = (int) addr0 - (int) mypc;
1451 switch (optype)
1453 case OT_bcc:
1454 if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1455 /* bcc.b */
1456 newsize = 2;
1457 else if (disp >= -32768 && (disp - (oldsize-5)) <= 32767)
1458 /* bncc.b/bra.w */
1459 newsize = 5;
1460 else
1461 /* bncc.b/bra.a */
1462 newsize = 6;
1463 break;
1465 case OT_beq:
1466 case OT_bne:
1467 if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1468 /* beq.s */
1469 newsize = 1;
1470 else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1471 /* beq.b */
1472 newsize = 2;
1473 else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1474 /* beq.w */
1475 newsize = 3;
1476 else
1477 /* bne.s/bra.a */
1478 newsize = 5;
1479 break;
1481 case OT_bra:
1482 case OT_bsr:
1483 if ((disp - (oldsize-1)) >= 3 && (disp - (oldsize-1)) <= 10 && !linkrelax)
1484 /* bra.s */
1485 newsize = 1;
1486 else if (disp >= -128 && (disp - (oldsize-2)) <= 127)
1487 /* bra.b */
1488 newsize = 2;
1489 else if (disp >= -32768 && (disp - (oldsize-3)) <= 32767)
1490 /* bra.w */
1491 newsize = 3;
1492 else
1493 /* bra.a */
1494 newsize = 4;
1495 break;
1497 case OT_other:
1498 break;
1500 tprintf (" - newsize %d\n", newsize);
1501 break;
1503 case RX_RELAX_IMM:
1504 tprintf ("other, addr %08lx pc %08lx LI %d OF %d\n",
1505 (unsigned long) addr0, (unsigned long) mypc,
1506 fragP->tc_frag_data->relax[ri].field_pos,
1507 fragP->tc_frag_data->relax[ri].val_ofs);
1509 newsize = fragP->tc_frag_data->relax[ri].val_ofs;
1511 if ((long) addr0 >= -128 && (long) addr0 <= 127)
1512 newsize += 1;
1513 else if ((long) addr0 >= -32768 && (long) addr0 <= 32767)
1514 newsize += 2;
1515 else if ((long) addr0 >= -8388608 && (long) addr0 <= 8388607)
1516 newsize += 3;
1517 else
1518 newsize += 4;
1519 break;
1521 default:
1522 break;
1525 if (fragP->tc_frag_data->relax[ri].type == RX_RELAX_BRANCH)
1526 switch (optype)
1528 case OT_bra:
1529 case OT_bcc:
1530 case OT_beq:
1531 case OT_bne:
1532 break;
1533 case OT_bsr:
1534 if (newsize < 3)
1535 newsize = 3;
1536 break;
1537 case OT_other:
1538 break;
1541 /* This prevents infinite loops in align-heavy sources. */
1542 if (newsize < oldsize)
1544 if (fragP->tc_frag_data->times_shrank > 10
1545 && fragP->tc_frag_data->times_grown > 10)
1546 newsize = oldsize;
1547 if (fragP->tc_frag_data->times_shrank < 20)
1548 fragP->tc_frag_data->times_shrank ++;
1550 else if (newsize > oldsize)
1552 if (fragP->tc_frag_data->times_grown < 20)
1553 fragP->tc_frag_data->times_grown ++;
1556 fragP->fr_subtype = newsize;
1557 tprintf (" -> new %d old %d delta %d\n", newsize, oldsize, newsize-oldsize);
1558 return newsize - oldsize;
1561 /* This lets us test for the opcode type and the desired size in a
1562 switch statement. */
1563 #define OPCODE(type,size) ((type) * 16 + (size))
1565 /* Given the opcode stored in fr_opcode and the number of bytes we
1566 think we need, encode a new opcode. We stored a pointer to the
1567 fixup for this opcode in the tc_frag_data structure. If we can do
1568 the fixup here, we change the relocation type to "none" (we test
1569 for that in tc_gen_reloc) else we change it to the right type for
1570 the new (biggest) opcode. */
1572 void
1573 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1574 segT segment ATTRIBUTE_UNUSED,
1575 fragS * fragP ATTRIBUTE_UNUSED)
1577 rx_bytesT * rxb = fragP->tc_frag_data;
1578 addressT addr0, mypc;
1579 int disp;
1580 int reloc_type, reloc_adjust;
1581 char * op = fragP->fr_opcode;
1582 int keep_reloc = 0;
1583 int ri;
1584 int fi = (rxb->n_fixups > 1) ? 1 : 0;
1585 fixS * fix = rxb->fixups[fi].fixP;
1587 tprintf ("\033[31mconvrt frag: addr %08lx fix %ld var %ld ofs %ld lit %p opc %p type %d sub %d\033[0m\n",
1588 (unsigned long) (fragP->fr_address
1589 + (fragP->fr_opcode - fragP->fr_literal)),
1590 (long) fragP->fr_fix, (long) fragP->fr_var, (long) fragP->fr_offset,
1591 fragP->fr_literal, fragP->fr_opcode, fragP->fr_type,
1592 fragP->fr_subtype);
1594 #if TRACE_RELAX
1596 int i;
1598 printf ("lit %08x opc %08x", (int) fragP->fr_literal, (int) fragP->fr_opcode);
1599 for (i = 0; i < 10; i++)
1600 printf (" %02x", (unsigned char) (fragP->fr_opcode[i]));
1601 printf ("\n");
1603 #endif
1605 /* In the one case where we have both a disp and imm relaxation, we want
1606 the imm relaxation here. */
1607 ri = 0;
1608 if (fragP->tc_frag_data->n_relax > 1
1609 && fragP->tc_frag_data->relax[0].type == RX_RELAX_DISP)
1610 ri = 1;
1612 /* We used a new frag for this opcode, so the opcode address should
1613 be the frag address. */
1614 mypc = fragP->fr_address + (fragP->fr_opcode - fragP->fr_literal);
1616 /* Try to get the target address. If we fail here, we just use the
1617 largest format. */
1618 if (rx_frag_fix_value (fragP, segment, 0, & addr0,
1619 fragP->tc_frag_data->relax[ri].type != RX_RELAX_BRANCH, 0))
1621 /* We don't know the target address. */
1622 keep_reloc = 1;
1623 addr0 = 0;
1624 disp = 0;
1626 else
1628 /* We know the target address, and it's in addr0. */
1629 disp = (int) addr0 - (int) mypc;
1632 if (linkrelax)
1633 keep_reloc = 1;
1635 reloc_type = BFD_RELOC_NONE;
1636 reloc_adjust = 0;
1638 tprintf ("convert, op is %d, disp %d (%lx-%lx)\n",
1639 rx_opcode_type (fragP->fr_opcode), disp,
1640 (unsigned long) addr0, (unsigned long) mypc);
1641 switch (fragP->tc_frag_data->relax[ri].type)
1643 case RX_RELAX_BRANCH:
1644 switch (OPCODE (rx_opcode_type (fragP->fr_opcode), fragP->fr_subtype))
1646 case OPCODE (OT_bra, 1): /* BRA.S - no change. */
1647 op[0] = 0x08 + (disp & 7);
1648 break;
1649 case OPCODE (OT_bra, 2): /* BRA.B - 8 bit. */
1650 op[0] = 0x2e;
1651 op[1] = disp;
1652 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1653 reloc_adjust = 1;
1654 break;
1655 case OPCODE (OT_bra, 3): /* BRA.W - 16 bit. */
1656 op[0] = 0x38;
1657 #if RX_OPCODE_BIG_ENDIAN
1658 op[1] = (disp >> 8) & 0xff;
1659 op[2] = disp;
1660 #else
1661 op[2] = (disp >> 8) & 0xff;
1662 op[1] = disp;
1663 #endif
1664 reloc_adjust = 1;
1665 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1666 break;
1667 case OPCODE (OT_bra, 4): /* BRA.A - 24 bit. */
1668 op[0] = 0x04;
1669 #if RX_OPCODE_BIG_ENDIAN
1670 op[1] = (disp >> 16) & 0xff;
1671 op[2] = (disp >> 8) & 0xff;
1672 op[3] = disp;
1673 #else
1674 op[3] = (disp >> 16) & 0xff;
1675 op[2] = (disp >> 8) & 0xff;
1676 op[1] = disp;
1677 #endif
1678 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1679 reloc_adjust = 1;
1680 break;
1682 case OPCODE (OT_beq, 1): /* BEQ.S - no change. */
1683 op[0] = 0x10 + (disp & 7);
1684 break;
1685 case OPCODE (OT_beq, 2): /* BEQ.B - 8 bit. */
1686 op[0] = 0x20;
1687 op[1] = disp;
1688 reloc_adjust = 1;
1689 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1690 break;
1691 case OPCODE (OT_beq, 3): /* BEQ.W - 16 bit. */
1692 op[0] = 0x3a;
1693 #if RX_OPCODE_BIG_ENDIAN
1694 op[1] = (disp >> 8) & 0xff;
1695 op[2] = disp;
1696 #else
1697 op[2] = (disp >> 8) & 0xff;
1698 op[1] = disp;
1699 #endif
1700 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1701 reloc_adjust = 1;
1702 break;
1703 case OPCODE (OT_beq, 5): /* BEQ.A - synthetic. */
1704 op[0] = 0x1e; /* bne.s .+4. */
1705 op[1] = 0x04; /* bra.a dsp:24. */
1706 disp -= 1;
1707 #if RX_OPCODE_BIG_ENDIAN
1708 op[2] = (disp >> 16) & 0xff;
1709 op[3] = (disp >> 8) & 0xff;
1710 op[4] = disp;
1711 #else
1712 op[4] = (disp >> 16) & 0xff;
1713 op[3] = (disp >> 8) & 0xff;
1714 op[2] = disp;
1715 #endif
1716 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1717 reloc_adjust = 2;
1718 break;
1720 case OPCODE (OT_bne, 1): /* BNE.S - no change. */
1721 op[0] = 0x18 + (disp & 7);
1722 break;
1723 case OPCODE (OT_bne, 2): /* BNE.B - 8 bit. */
1724 op[0] = 0x21;
1725 op[1] = disp;
1726 reloc_adjust = 1;
1727 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1728 break;
1729 case OPCODE (OT_bne, 3): /* BNE.W - 16 bit. */
1730 op[0] = 0x3b;
1731 #if RX_OPCODE_BIG_ENDIAN
1732 op[1] = (disp >> 8) & 0xff;
1733 op[2] = disp;
1734 #else
1735 op[2] = (disp >> 8) & 0xff;
1736 op[1] = disp;
1737 #endif
1738 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1739 reloc_adjust = 1;
1740 break;
1741 case OPCODE (OT_bne, 5): /* BNE.A - synthetic. */
1742 op[0] = 0x15; /* beq.s .+4. */
1743 op[1] = 0x04; /* bra.a dsp:24. */
1744 disp -= 1;
1745 #if RX_OPCODE_BIG_ENDIAN
1746 op[2] = (disp >> 16) & 0xff;
1747 op[3] = (disp >> 8) & 0xff;
1748 op[4] = disp;
1749 #else
1750 op[4] = (disp >> 16) & 0xff;
1751 op[3] = (disp >> 8) & 0xff;
1752 op[2] = disp;
1753 #endif
1754 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1755 reloc_adjust = 2;
1756 break;
1758 case OPCODE (OT_bsr, 3): /* BSR.W - 16 bit. */
1759 op[0] = 0x39;
1760 #if RX_OPCODE_BIG_ENDIAN
1761 op[1] = (disp >> 8) & 0xff;
1762 op[2] = disp;
1763 #else
1764 op[2] = (disp >> 8) & 0xff;
1765 op[1] = disp;
1766 #endif
1767 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1768 reloc_adjust = 0;
1769 break;
1770 case OPCODE (OT_bsr, 4): /* BSR.A - 24 bit. */
1771 op[0] = 0x05;
1772 #if RX_OPCODE_BIG_ENDIAN
1773 op[1] = (disp >> 16) & 0xff;
1774 op[2] = (disp >> 8) & 0xff;
1775 op[3] = disp;
1776 #else
1777 op[3] = (disp >> 16) & 0xff;
1778 op[2] = (disp >> 8) & 0xff;
1779 op[1] = disp;
1780 #endif
1781 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1782 reloc_adjust = 0;
1783 break;
1785 case OPCODE (OT_bcc, 2): /* Bcond.B - 8 bit. */
1786 op[1] = disp;
1787 reloc_type = keep_reloc ? BFD_RELOC_8_PCREL : BFD_RELOC_NONE;
1788 break;
1789 case OPCODE (OT_bcc, 5): /* Bcond.W - synthetic. */
1790 op[0] ^= 1; /* Invert condition. */
1791 op[1] = 5; /* Displacement. */
1792 op[2] = 0x38;
1793 disp -= 2;
1794 #if RX_OPCODE_BIG_ENDIAN
1795 op[3] = (disp >> 8) & 0xff;
1796 op[4] = disp;
1797 #else
1798 op[4] = (disp >> 8) & 0xff;
1799 op[3] = disp;
1800 #endif
1801 reloc_type = keep_reloc ? BFD_RELOC_16_PCREL : BFD_RELOC_NONE;
1802 reloc_adjust = 2;
1803 break;
1804 case OPCODE (OT_bcc, 6): /* Bcond.S - synthetic. */
1805 op[0] ^= 1; /* Invert condition. */
1806 op[1] = 6; /* Displacement. */
1807 op[2] = 0x04;
1808 disp -= 2;
1809 #if RX_OPCODE_BIG_ENDIAN
1810 op[3] = (disp >> 16) & 0xff;
1811 op[4] = (disp >> 8) & 0xff;
1812 op[5] = disp;
1813 #else
1814 op[5] = (disp >> 16) & 0xff;
1815 op[4] = (disp >> 8) & 0xff;
1816 op[3] = disp;
1817 #endif
1818 reloc_type = keep_reloc ? BFD_RELOC_24_PCREL : BFD_RELOC_NONE;
1819 reloc_adjust = 2;
1820 break;
1822 default:
1823 /* These are opcodes we'll relax in th linker, later. */
1824 if (rxb->n_fixups)
1825 reloc_type = rxb->fixups[ri].fixP->fx_r_type;
1826 break;
1828 break;
1830 case RX_RELAX_IMM:
1832 int nbytes = fragP->fr_subtype - fragP->tc_frag_data->relax[ri].val_ofs;
1833 int li;
1834 char * imm = op + fragP->tc_frag_data->relax[ri].val_ofs;
1836 switch (nbytes)
1838 case 1:
1839 li = 1;
1840 imm[0] = addr0;
1841 reloc_type = BFD_RELOC_8;
1842 break;
1843 case 2:
1844 li = 2;
1845 #if RX_OPCODE_BIG_ENDIAN
1846 imm[1] = addr0;
1847 imm[0] = addr0 >> 8;
1848 #else
1849 imm[0] = addr0;
1850 imm[1] = addr0 >> 8;
1851 #endif
1852 reloc_type = BFD_RELOC_RX_16_OP;
1853 break;
1854 case 3:
1855 li = 3;
1856 #if RX_OPCODE_BIG_ENDIAN
1857 imm[2] = addr0;
1858 imm[1] = addr0 >> 8;
1859 imm[0] = addr0 >> 16;
1860 #else
1861 imm[0] = addr0;
1862 imm[1] = addr0 >> 8;
1863 imm[2] = addr0 >> 16;
1864 #endif
1865 reloc_type = BFD_RELOC_RX_24_OP;
1866 break;
1867 case 4:
1868 li = 0;
1869 #if RX_OPCODE_BIG_ENDIAN
1870 imm[3] = addr0;
1871 imm[2] = addr0 >> 8;
1872 imm[1] = addr0 >> 16;
1873 imm[0] = addr0 >> 24;
1874 #else
1875 imm[0] = addr0;
1876 imm[1] = addr0 >> 8;
1877 imm[2] = addr0 >> 16;
1878 imm[3] = addr0 >> 24;
1879 #endif
1880 reloc_type = BFD_RELOC_RX_32_OP;
1881 break;
1882 default:
1883 as_bad (_("invalid immediate size"));
1884 li = -1;
1887 switch (fragP->tc_frag_data->relax[ri].field_pos)
1889 case 6:
1890 op[0] &= 0xfc;
1891 op[0] |= li;
1892 break;
1893 case 12:
1894 op[1] &= 0xf3;
1895 op[1] |= li << 2;
1896 break;
1897 case 20:
1898 op[2] &= 0xf3;
1899 op[2] |= li << 2;
1900 break;
1901 default:
1902 as_bad (_("invalid immediate field position"));
1905 break;
1907 default:
1908 if (rxb->n_fixups)
1910 reloc_type = fix->fx_r_type;
1911 reloc_adjust = 0;
1913 break;
1916 if (rxb->n_fixups)
1919 fix->fx_r_type = reloc_type;
1920 fix->fx_where += reloc_adjust;
1921 switch (reloc_type)
1923 case BFD_RELOC_NONE:
1924 fix->fx_size = 0;
1925 break;
1926 case BFD_RELOC_8:
1927 fix->fx_size = 1;
1928 break;
1929 case BFD_RELOC_16_PCREL:
1930 case BFD_RELOC_RX_16_OP:
1931 fix->fx_size = 2;
1932 break;
1933 case BFD_RELOC_24_PCREL:
1934 case BFD_RELOC_RX_24_OP:
1935 fix->fx_size = 3;
1936 break;
1937 case BFD_RELOC_RX_32_OP:
1938 fix->fx_size = 4;
1939 break;
1943 fragP->fr_fix = fragP->fr_subtype + (fragP->fr_opcode - fragP->fr_literal);
1944 tprintf ("fragP->fr_fix now %ld (%d + (%p - %p)\n", (long) fragP->fr_fix,
1945 fragP->fr_subtype, fragP->fr_opcode, fragP->fr_literal);
1946 fragP->fr_var = 0;
1948 if (fragP->fr_next != NULL
1949 && ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
1950 != fragP->fr_fix))
1951 as_bad (_("bad frag at %p : fix %ld addr %ld %ld \n"), fragP,
1952 (long) fragP->fr_fix,
1953 (long) fragP->fr_address, (long) fragP->fr_next->fr_address);
1956 #undef OPCODE
1959 rx_validate_fix_sub (struct fix * f)
1961 /* We permit the subtraction of two symbols in a few cases. */
1962 /* mov #sym1-sym2, R3 */
1963 if (f->fx_r_type == BFD_RELOC_RX_32_OP)
1964 return 1;
1965 /* .long sym1-sym2 */
1966 if (f->fx_r_type == BFD_RELOC_RX_DIFF
1967 && ! f->fx_pcrel
1968 && (f->fx_size == 4 || f->fx_size == 2 || f->fx_size == 1))
1969 return 1;
1970 return 0;
1973 long
1974 md_pcrel_from_section (fixS * fixP, segT sec)
1976 long rv;
1978 if (fixP->fx_addsy != NULL
1979 && (! S_IS_DEFINED (fixP->fx_addsy)
1980 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
1981 /* The symbol is undefined (or is defined but not in this section).
1982 Let the linker figure it out. */
1983 return 0;
1985 rv = fixP->fx_frag->fr_address + fixP->fx_where;
1986 switch (fixP->fx_r_type)
1988 case BFD_RELOC_RX_DIR3U_PCREL:
1989 return rv;
1990 default:
1991 return rv - 1;
1995 void
1996 rx_cons_fix_new (fragS * frag,
1997 int where,
1998 int size,
1999 expressionS * exp)
2001 bfd_reloc_code_real_type type;
2003 switch (size)
2005 case 1:
2006 type = BFD_RELOC_8;
2007 break;
2008 case 2:
2009 type = BFD_RELOC_16;
2010 break;
2011 case 3:
2012 type = BFD_RELOC_24;
2013 break;
2014 case 4:
2015 type = BFD_RELOC_32;
2016 break;
2017 default:
2018 as_bad (_("unsupported constant size %d\n"), size);
2019 return;
2022 if (exp->X_op == O_subtract && exp->X_op_symbol)
2024 if (size != 4 && size != 2 && size != 1)
2025 as_bad (_("difference of two symbols only supported with .long, .short, or .byte"));
2026 else
2027 type = BFD_RELOC_RX_DIFF;
2030 fix_new_exp (frag, where, (int) size, exp, 0, type);
2033 void
2034 md_apply_fix (struct fix * f ATTRIBUTE_UNUSED,
2035 valueT * t ATTRIBUTE_UNUSED,
2036 segT s ATTRIBUTE_UNUSED)
2038 /* Instruction bytes are always little endian. */
2039 char * op;
2040 unsigned long val;
2042 if (f->fx_addsy && S_FORCE_RELOC (f->fx_addsy, 1))
2043 return;
2044 if (f->fx_subsy && S_FORCE_RELOC (f->fx_subsy, 1))
2045 return;
2047 #define OP2(x) op[target_big_endian ? 1-x : x]
2048 #define OP3(x) op[target_big_endian ? 2-x : x]
2049 #define OP4(x) op[target_big_endian ? 3-x : x]
2051 op = f->fx_frag->fr_literal + f->fx_where;
2052 val = (unsigned long) * t;
2054 /* Opcode words are always the same endian. Data words are either
2055 big or little endian. */
2057 switch (f->fx_r_type)
2059 case BFD_RELOC_NONE:
2060 break;
2062 case BFD_RELOC_RX_RELAX:
2063 f->fx_done = 1;
2064 break;
2066 case BFD_RELOC_RX_DIR3U_PCREL:
2067 if (val < 3 || val > 10)
2068 as_bad_where (f->fx_file, f->fx_line,
2069 _("jump not 3..10 bytes away (is %d)"), (int) val);
2070 op[0] &= 0xf8;
2071 op[0] |= val & 0x07;
2072 break;
2074 case BFD_RELOC_8:
2075 case BFD_RELOC_8_PCREL:
2076 case BFD_RELOC_RX_8U:
2077 op[0] = val;
2078 break;
2080 case BFD_RELOC_16:
2081 OP2(1) = val & 0xff;
2082 OP2(0) = (val >> 8) & 0xff;
2083 break;
2085 case BFD_RELOC_16_PCREL:
2086 case BFD_RELOC_RX_16_OP:
2087 case BFD_RELOC_RX_16U:
2088 #if RX_OPCODE_BIG_ENDIAN
2089 op[1] = val & 0xff;
2090 op[0] = (val >> 8) & 0xff;
2091 #else
2092 op[0] = val & 0xff;
2093 op[1] = (val >> 8) & 0xff;
2094 #endif
2095 break;
2097 case BFD_RELOC_24:
2098 OP3(0) = val & 0xff;
2099 OP3(1) = (val >> 8) & 0xff;
2100 OP3(2) = (val >> 16) & 0xff;
2101 break;
2103 case BFD_RELOC_24_PCREL:
2104 case BFD_RELOC_RX_24_OP:
2105 case BFD_RELOC_RX_24U:
2106 #if RX_OPCODE_BIG_ENDIAN
2107 op[2] = val & 0xff;
2108 op[1] = (val >> 8) & 0xff;
2109 op[0] = (val >> 16) & 0xff;
2110 #else
2111 op[0] = val & 0xff;
2112 op[1] = (val >> 8) & 0xff;
2113 op[2] = (val >> 16) & 0xff;
2114 #endif
2115 break;
2117 case BFD_RELOC_RX_DIFF:
2118 switch (f->fx_size)
2120 case 1:
2121 op[0] = val & 0xff;
2122 break;
2123 case 2:
2124 OP2(0) = val & 0xff;
2125 OP2(1) = (val >> 8) & 0xff;
2126 break;
2127 case 4:
2128 OP4(0) = val & 0xff;
2129 OP4(1) = (val >> 8) & 0xff;
2130 OP4(2) = (val >> 16) & 0xff;
2131 OP4(3) = (val >> 24) & 0xff;
2132 break;
2134 break;
2136 case BFD_RELOC_32:
2137 OP4(0) = val & 0xff;
2138 OP4(1) = (val >> 8) & 0xff;
2139 OP4(2) = (val >> 16) & 0xff;
2140 OP4(3) = (val >> 24) & 0xff;
2141 break;
2143 case BFD_RELOC_RX_32_OP:
2144 #if RX_OPCODE_BIG_ENDIAN
2145 op[3] = val & 0xff;
2146 op[2] = (val >> 8) & 0xff;
2147 op[1] = (val >> 16) & 0xff;
2148 op[0] = (val >> 24) & 0xff;
2149 #else
2150 op[0] = val & 0xff;
2151 op[1] = (val >> 8) & 0xff;
2152 op[2] = (val >> 16) & 0xff;
2153 op[3] = (val >> 24) & 0xff;
2154 #endif
2155 break;
2157 case BFD_RELOC_RX_NEG8:
2158 op[0] = - val;
2159 break;
2161 case BFD_RELOC_RX_NEG16:
2162 val = -val;
2163 #if RX_OPCODE_BIG_ENDIAN
2164 op[1] = val & 0xff;
2165 op[0] = (val >> 8) & 0xff;
2166 #else
2167 op[0] = val & 0xff;
2168 op[1] = (val >> 8) & 0xff;
2169 #endif
2170 break;
2172 case BFD_RELOC_RX_NEG24:
2173 val = -val;
2174 #if RX_OPCODE_BIG_ENDIAN
2175 op[2] = val & 0xff;
2176 op[1] = (val >> 8) & 0xff;
2177 op[0] = (val >> 16) & 0xff;
2178 #else
2179 op[0] = val & 0xff;
2180 op[1] = (val >> 8) & 0xff;
2181 op[2] = (val >> 16) & 0xff;
2182 #endif
2183 break;
2185 case BFD_RELOC_RX_NEG32:
2186 val = -val;
2187 #if RX_OPCODE_BIG_ENDIAN
2188 op[3] = val & 0xff;
2189 op[2] = (val >> 8) & 0xff;
2190 op[1] = (val >> 16) & 0xff;
2191 op[0] = (val >> 24) & 0xff;
2192 #else
2193 op[0] = val & 0xff;
2194 op[1] = (val >> 8) & 0xff;
2195 op[2] = (val >> 16) & 0xff;
2196 op[3] = (val >> 24) & 0xff;
2197 #endif
2198 break;
2200 case BFD_RELOC_RX_GPRELL:
2201 val >>= 1;
2202 case BFD_RELOC_RX_GPRELW:
2203 val >>= 1;
2204 case BFD_RELOC_RX_GPRELB:
2205 #if RX_OPCODE_BIG_ENDIAN
2206 op[1] = val & 0xff;
2207 op[0] = (val >> 8) & 0xff;
2208 #else
2209 op[0] = val & 0xff;
2210 op[1] = (val >> 8) & 0xff;
2211 #endif
2212 break;
2214 default:
2215 as_bad (_("Unknown reloc in md_apply_fix: %s"),
2216 bfd_get_reloc_code_name (f->fx_r_type));
2217 break;
2220 if (f->fx_addsy == NULL)
2221 f->fx_done = 1;
2224 arelent **
2225 tc_gen_reloc (asection * seg ATTRIBUTE_UNUSED, fixS * fixp)
2227 static arelent * reloc[5];
2228 int is_opcode = 0;
2230 if (fixp->fx_r_type == BFD_RELOC_NONE)
2232 reloc[0] = NULL;
2233 return reloc;
2236 if (fixp->fx_subsy
2237 && S_GET_SEGMENT (fixp->fx_subsy) == absolute_section)
2239 fixp->fx_offset -= S_GET_VALUE (fixp->fx_subsy);
2240 fixp->fx_subsy = NULL;
2243 reloc[0] = (arelent *) xmalloc (sizeof (arelent));
2244 reloc[0]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2245 * reloc[0]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2246 reloc[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2247 reloc[0]->addend = fixp->fx_offset;
2249 if (fixp->fx_r_type == BFD_RELOC_RX_32_OP
2250 && fixp->fx_subsy)
2252 fixp->fx_r_type = BFD_RELOC_RX_DIFF;
2253 is_opcode = 1;
2256 /* Certain BFD relocations cannot be translated directly into
2257 a single (non-Red Hat) RX relocation, but instead need
2258 multiple RX relocations - handle them here. */
2259 switch (fixp->fx_r_type)
2261 case BFD_RELOC_RX_DIFF:
2262 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2264 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2265 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2266 * reloc[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2267 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2268 reloc[1]->addend = 0;
2269 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2271 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2272 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2273 reloc[2]->addend = 0;
2274 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2275 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2277 reloc[3] = (arelent *) xmalloc (sizeof (arelent));
2278 switch (fixp->fx_size)
2280 case 1:
2281 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS8);
2282 break;
2283 case 2:
2284 if (!is_opcode && target_big_endian)
2285 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16_REV);
2286 else
2287 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16);
2288 break;
2289 case 4:
2290 if (!is_opcode && target_big_endian)
2291 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32_REV);
2292 else
2293 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
2294 break;
2296 reloc[3]->addend = 0;
2297 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2298 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2300 reloc[4] = NULL;
2301 break;
2303 case BFD_RELOC_RX_GPRELL:
2304 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2306 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2307 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2308 if (gp_symbol == NULL)
2310 if (symbol_table_frozen)
2312 symbolS * gp;
2314 gp = symbol_find ("__gp");
2315 if (gp == NULL)
2316 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2317 else
2318 gp_symbol = symbol_get_bfdsym (gp);
2320 else
2321 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2323 * reloc[1]->sym_ptr_ptr = gp_symbol;
2324 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2325 reloc[1]->addend = 0;
2326 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2328 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2329 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2330 reloc[2]->addend = 0;
2331 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2332 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2334 reloc[3] = (arelent *) xmalloc (sizeof (arelent));
2335 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UL);
2336 reloc[3]->addend = 0;
2337 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2338 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2340 reloc[4] = NULL;
2341 break;
2343 case BFD_RELOC_RX_GPRELW:
2344 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2346 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2347 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2348 if (gp_symbol == NULL)
2350 if (symbol_table_frozen)
2352 symbolS * gp;
2354 gp = symbol_find ("__gp");
2355 if (gp == NULL)
2356 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2357 else
2358 gp_symbol = symbol_get_bfdsym (gp);
2360 else
2361 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2363 * reloc[1]->sym_ptr_ptr = gp_symbol;
2364 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2365 reloc[1]->addend = 0;
2366 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2368 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2369 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2370 reloc[2]->addend = 0;
2371 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2372 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2374 reloc[3] = (arelent *) xmalloc (sizeof (arelent));
2375 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16UW);
2376 reloc[3]->addend = 0;
2377 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2378 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2380 reloc[4] = NULL;
2381 break;
2383 case BFD_RELOC_RX_GPRELB:
2384 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2386 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2387 reloc[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2388 if (gp_symbol == NULL)
2390 if (symbol_table_frozen)
2392 symbolS * gp;
2394 gp = symbol_find ("__gp");
2395 if (gp == NULL)
2396 as_bad (("unable to create __gp symbol: please re-assemble with the -msmall-data-limit option specified"));
2397 else
2398 gp_symbol = symbol_get_bfdsym (gp);
2400 else
2401 gp_symbol = symbol_get_bfdsym (symbol_find_or_make ("__gp"));
2403 * reloc[1]->sym_ptr_ptr = gp_symbol;
2404 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2405 reloc[1]->addend = 0;
2406 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2408 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2409 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_SUBTRACT);
2410 reloc[2]->addend = 0;
2411 reloc[2]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2412 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2414 reloc[3] = (arelent *) xmalloc (sizeof (arelent));
2415 reloc[3]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS16U);
2416 reloc[3]->addend = 0;
2417 reloc[3]->sym_ptr_ptr = reloc[1]->sym_ptr_ptr;
2418 reloc[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2420 reloc[4] = NULL;
2421 break;
2423 case BFD_RELOC_RX_NEG32:
2424 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_SYM);
2426 reloc[1] = (arelent *) xmalloc (sizeof (arelent));
2427 reloc[1]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_OP_NEG);
2428 reloc[1]->addend = 0;
2429 reloc[1]->sym_ptr_ptr = reloc[0]->sym_ptr_ptr;
2430 reloc[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2432 reloc[2] = (arelent *) xmalloc (sizeof (arelent));
2433 reloc[2]->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_RX_ABS32);
2434 reloc[2]->addend = 0;
2435 reloc[2]->sym_ptr_ptr = reloc[0]->sym_ptr_ptr;
2436 reloc[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
2438 reloc[3] = NULL;
2439 break;
2441 default:
2442 reloc[0]->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2443 reloc[1] = NULL;
2444 break;
2447 return reloc;
2450 /* Set the ELF specific flags. */
2452 void
2453 rx_elf_final_processing (void)
2455 elf_elfheader (stdoutput)->e_flags |= elf_flags;
2458 /* Scan the current input line for occurances of Renesas
2459 local labels and replace them with the GAS version. */
2461 void
2462 rx_start_line (void)
2464 int in_double_quote = 0;
2465 int in_single_quote = 0;
2466 int done = 0;
2467 char * p = input_line_pointer;
2469 /* Scan the line looking for question marks. Skip past quote enclosed regions. */
2472 switch (*p)
2474 case '\n':
2475 case 0:
2476 done = 1;
2477 break;
2479 case '"':
2480 in_double_quote = ! in_double_quote;
2481 break;
2483 case '\'':
2484 in_single_quote = ! in_single_quote;
2485 break;
2487 case '?':
2488 if (in_double_quote || in_single_quote)
2489 break;
2491 if (p[1] == ':')
2492 *p = '1';
2493 else if (p[1] == '+')
2495 p[0] = '1';
2496 p[1] = 'f';
2498 else if (p[1] == '-')
2500 p[0] = '1';
2501 p[1] = 'b';
2503 break;
2505 default:
2506 break;
2509 p ++;
2511 while (! done);