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