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