xref: /netbsd-src/external/gpl3/binutils.old/dist/gas/config/tc-rx.c (revision cef8759bd76c1b621f8eab8faa6f208faabc2e15)
1 /* tc-rx.c -- Assembler for the Renesas RX
2    Copyright (C) 2008-2018 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 
35 const 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.  */
39 const char line_comment_chars[]   = "#";
40 const char line_separator_chars[] = "!";
41 
42 const char EXP_CHARS[]            = "eE";
43 const char FLT_CHARS[]            = "dD";
44 
45 /* ELF flags to set in the output file header.  */
46 static int elf_flags = E_FLAG_RX_ABI;
47 
48 bfd_boolean rx_use_conventional_section_names = FALSE;
49 static bfd_boolean rx_use_small_data_limit = FALSE;
50 
51 static bfd_boolean rx_pid_mode = FALSE;
52 static int rx_num_int_regs = 0;
53 int rx_pid_register;
54 int rx_gp_register;
55 
56 enum rx_cpu_types rx_cpu = RX600;
57 
58 static void rx_fetchalign (int ignore ATTRIBUTE_UNUSED);
59 
60 enum 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 ""
79 const char * md_shortopts = RX_SHORTOPTS;
80 
81 /* Assembler options.  */
82 struct 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 };
106 size_t md_longopts_size = sizeof (md_longopts);
107 
108 struct cpu_type
109 {
110   const char *cpu_name;
111   enum rx_cpu_types type;
112 };
113 
114 struct cpu_type  cpu_type_list[] =
115 {
116   {"rx100",RX100},
117   {"rx200",RX200},
118   {"rx600",RX600},
119   {"rx610",RX610},
120   {"rxv2",RXV2}
121 };
122 
123 int
124 md_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 
202 void
203 md_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 
220 static void
221 s_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 
230 static void
231 rx_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 
238 static char *
239 rx_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 
262 static void
263 rx_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 specified 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 
413 static void
414 parse_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, 0, 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, 0, attr, 0, NULL, FALSE, FALSE);
505     }
506 
507   bfd_set_section_alignment (stdoutput, now_seg, align);
508 }
509 
510 static void
511 rx_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 
544 static void
545 rx_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 
560 static void
561 rx_rept (int ignore ATTRIBUTE_UNUSED)
562 {
563   size_t 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 
570 static void
571 rx_cons (int size)
572 {
573   SKIP_WHITESPACE ();
574 
575   if (* input_line_pointer == '"')
576     stringer (8+0);
577   else
578     cons (size);
579 }
580 
581 static void
582 rx_nop (int ignore ATTRIBUTE_UNUSED)
583 {
584   ignore_rest_of_line ();
585 }
586 
587 static void
588 rx_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.  */
596 const 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 
662 static asymbol * gp_symbol;
663 static asymbol * rx_pid_symbol;
664 
665 static symbolS * rx_pidreg_symbol;
666 static symbolS * rx_gpreg_symbol;
667 
668 void
669 md_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 
703 char * rx_lex_start;
704 char * 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 
710 typedef 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 
740 static rx_bytesT rx_bytes;
741 /* We set n_ops to be "size of next opcode" if the next opcode doesn't relax.  */
742 static rx_bytesT *fetchalign_bytes = NULL;
743 
744 static void
745 rx_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 
767 void
768 rx_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 
776 void
777 rx_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 
793 void
794 rx_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 
807 void
808 rx_linkrelax_branch (void)
809 {
810   rx_bytes.link_relax |= RX_RELAXA_BRA;
811 }
812 
813 static void
814 rx_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 
830 void
831 rx_base1 (int b1)
832 {
833   rx_bytes.base[0] = b1;
834   rx_bytes.n_base = 1;
835 }
836 
837 void
838 rx_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 
845 void
846 rx_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 
854 void
855 rx_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 
873 void
874 rx_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 
918 void
919 rx_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 
928 void
929 rx_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 
941 void
942 rx_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 
955 void
956 rx_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 
1012 int
1013 rx_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 
1025 void
1026 rx_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 
1040 static void
1041 rx_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 
1070 static bfd_boolean
1071 scan_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 
1106 void
1107 md_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 
1204 void
1205 rx_md_end (void)
1206 {
1207 }
1208 
1209 /* Write a value out to the object file, using the appropriate endianness.  */
1210 
1211 void
1212 md_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 
1220 static struct
1221 {
1222   const char * fname;
1223   int    reloc;
1224 }
1225 reloc_functions[] =
1226 {
1227   { "gp", BFD_RELOC_GPREL16 },
1228   { 0, 0 }
1229 };
1230 
1231 void
1232 md_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 
1260 valueT
1261 md_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 */
1268 static unsigned char nop_1[] = { 0x03};
1269 				/* MOV.L R0,R0 - 1 cycle */
1270 static unsigned char nop_2[] = { 0xef, 0x00};
1271 				/* MAX R0,R0 - 1 cycle */
1272 static unsigned char nop_3[] = { 0xfc, 0x13, 0x00 };
1273 				/* MUL #1,R0 - 1 cycle */
1274 static unsigned char nop_4[] = { 0x76, 0x10, 0x01, 0x00 };
1275 				/* MUL #1,R0 - 1 cycle */
1276 static unsigned char nop_5[] = { 0x77, 0x10, 0x01, 0x00, 0x00 };
1277 				/* MUL #1,R0 - 1 cycle */
1278 static unsigned char nop_6[] = { 0x74, 0x10, 0x01, 0x00, 0x00, 0x00 };
1279 				/* MAX 0x80000000,R0 - 1 cycle */
1280 static unsigned char nop_7[] = { 0xFD, 0x70, 0x40, 0x00, 0x00, 0x00, 0x80 };
1281 
1282 static 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.  */
1287 void
1288 rx_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 
1337 const char *
1338 md_atof (int type, char * litP, int * sizeP)
1339 {
1340   return ieee_md_atof (type, litP, sizeP, target_big_endian);
1341 }
1342 
1343 symbolS *
1344 md_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 
1366 typedef 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 
1408 static op_type_T
1409 rx_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 
1445 static int
1446 rx_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    so we only need to subtract fx_fix and return it.  */
1490 
1491 int
1492 md_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 
1515 static fragS *
1516 rx_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 
1530 int
1531 rx_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 
1756 void
1757 md_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 
2161 int
2162 rx_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 
2176 long
2177 md_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 
2198 void
2199 rx_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 
2235 void
2236 md_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 
2428 arelent **
2429 tc_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 
2658 void
2659 rx_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 
2668 void
2669 rx_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 
2677 void
2678 rx_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   char prev_char = 0;
2685 
2686   /* Scan the line looking for question marks.  Skip past quote enclosed regions.  */
2687   do
2688     {
2689       switch (*p)
2690 	{
2691 	case '\n':
2692 	case 0:
2693 	  done = 1;
2694 	  break;
2695 
2696 	case '"':
2697 	  /* Handle escaped double quote \" inside a string.  */
2698 	  if (prev_char != '\\')
2699 	    in_double_quote = ! in_double_quote;
2700 	  break;
2701 
2702 	case '\'':
2703 	  in_single_quote = ! in_single_quote;
2704 	  break;
2705 
2706 	case '?':
2707 	  if (in_double_quote || in_single_quote)
2708 	    break;
2709 
2710 	  if (p[1] == ':')
2711 	    *p = '1';
2712 	  else if (p[1] == '+')
2713 	    {
2714 	      p[0] = '1';
2715 	      p[1] = 'f';
2716 	    }
2717 	  else if (p[1] == '-')
2718 	    {
2719 	      p[0] = '1';
2720 	      p[1] = 'b';
2721 	    }
2722 	  break;
2723 
2724 	default:
2725 	  break;
2726 	}
2727 
2728       prev_char = *p++;
2729     }
2730   while (! done);
2731 }
2732