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