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