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