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