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