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