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