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