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