Home | History | Annotate | Line # | Download | only in config
      1      1.1  christos /* This is the machine dependent code of the Visium Assembler.
      2      1.1  christos 
      3  1.1.1.8  christos    Copyright (C) 2005-2026 Free Software Foundation, Inc.
      4      1.1  christos 
      5      1.1  christos    This file is part of GAS, the GNU Assembler.
      6      1.1  christos 
      7      1.1  christos    GAS is free software; you can redistribute it and/or modify
      8      1.1  christos    it under the terms of the GNU General Public License as published by
      9      1.1  christos    the Free Software Foundation; either version 2, or (at your option)
     10      1.1  christos    any later version.
     11      1.1  christos 
     12      1.1  christos    GAS is distributed in the hope that it will be useful,
     13      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  christos    GNU General Public License for more details.
     16      1.1  christos 
     17      1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1.1.3  christos    along with this program; if not, write to the Free Software
     19  1.1.1.3  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20  1.1.1.3  christos    MA 02110-1301, USA.  */
     21      1.1  christos 
     22      1.1  christos #include "as.h"
     23      1.1  christos #include "safe-ctype.h"
     24      1.1  christos #include "subsegs.h"
     25      1.1  christos #include "obstack.h"
     26      1.1  christos 
     27      1.1  christos #include "opcode/visium.h"
     28      1.1  christos #include "elf/visium.h"
     29      1.1  christos #include "dwarf2dbg.h"
     30      1.1  christos #include "dw2gencfi.h"
     31      1.1  christos 
     32      1.1  christos /* Relocations and fixups:
     33      1.1  christos 
     34      1.1  christos    There are two different cases where an instruction or data
     35      1.1  christos    directive operand requires relocation, or fixup.
     36      1.1  christos 
     37      1.1  christos    1. Relative branch instructions, take an 16-bit signed word
     38      1.1  christos    offset. The formula for computing the offset is this:
     39      1.1  christos 
     40      1.1  christos     offset = (destination - pc) / 4
     41      1.1  christos 
     42      1.1  christos    Branch instructions never branch to a label not declared
     43      1.1  christos    locally, so the actual offset can always be computed by the assembler.
     44      1.1  christos    However, we provide a relocation type to support this.
     45      1.1  christos 
     46      1.1  christos    2. Load literal instructions, such as MOVIU, which take a 16-bit
     47      1.1  christos    literal operand. The literal may be the top or bottom half of
     48      1.1  christos    a 32-bit value computed by the assembler, or by the linker. We provide
     49      1.1  christos    two relocation types here.
     50      1.1  christos 
     51      1.1  christos    3. Data items (long, word and byte) preset with a value computed by
     52      1.1  christos    the linker.  */
     53      1.1  christos 
     54      1.1  christos 
     55      1.1  christos /* This string holds the chars that always start a comment. If the
     56  1.1.1.7  christos    pre-processor is disabled, these aren't very useful.  */
     57  1.1.1.7  christos const char comment_chars[] = "!;";
     58      1.1  christos 
     59      1.1  christos /* This array holds the chars that only start a comment at the beginning
     60      1.1  christos    of a line.  If the line seems to have the form '# 123 filename' .line
     61      1.1  christos    and .file directives will appear in the pre-processed output. Note that
     62      1.1  christos    input_file.c hand checks for '#' at the beginning of the first line of
     63      1.1  christos    the input file. This is because the compiler outputs #NO_APP at the
     64      1.1  christos    beginning of its output. Also note that comments like this one will
     65      1.1  christos    always work.  */
     66      1.1  christos const char line_comment_chars[] = "#!;";
     67      1.1  christos const char line_separator_chars[] = "";
     68      1.1  christos 
     69      1.1  christos /* Chars that can be used to separate mantissa from exponent in floating point
     70      1.1  christos    numbers.  */
     71      1.1  christos const char EXP_CHARS[] = "eE";
     72      1.1  christos 
     73      1.1  christos /* Chars that mean this number is a floating point constant, as in
     74      1.1  christos    "0f12.456" or "0d1.2345e12".
     75      1.1  christos 
     76      1.1  christos    ...Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
     77      1.1  christos    changed in read.c. Ideally it shouldn't have to know about it at all,
     78      1.1  christos    but nothing is ideal around here.  */
     79      1.1  christos const char FLT_CHARS[] = "rRsSfFdDxXeE";
     80      1.1  christos 
     81      1.1  christos /* The size of a relocation record.  */
     82      1.1  christos const int md_reloc_size = 8;
     83      1.1  christos 
     84      1.1  christos /* The architecture for which we are assembling.  */
     85      1.1  christos enum visium_arch_val
     86      1.1  christos {
     87      1.1  christos   VISIUM_ARCH_DEF,
     88      1.1  christos   VISIUM_ARCH_MCM24,
     89      1.1  christos   VISIUM_ARCH_MCM,
     90      1.1  christos   VISIUM_ARCH_GR6
     91      1.1  christos };
     92      1.1  christos 
     93      1.1  christos static enum visium_arch_val visium_arch = VISIUM_ARCH_DEF;
     94      1.1  christos 
     95      1.1  christos /* The opcode architecture for which we are assembling.  In contrast to the
     96      1.1  christos    previous one, this only determines which instructions are supported.  */
     97      1.1  christos static enum visium_opcode_arch_val visium_opcode_arch = VISIUM_OPCODE_ARCH_DEF;
     98      1.1  christos 
     99      1.1  christos /* Flags to set in the ELF header e_flags field.  */
    100      1.1  christos static flagword visium_flags = 0;
    101      1.1  christos 
    102      1.1  christos /* More than this number of nops in an alignment op gets a branch instead.  */
    103      1.1  christos static unsigned int nop_limit = 5;
    104      1.1  christos 
    105      1.1  christos 
    106      1.1  christos /* Translate internal representation of relocation info to BFD target
    107      1.1  christos    format.  */
    108      1.1  christos arelent *
    109      1.1  christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
    110      1.1  christos {
    111      1.1  christos   arelent *reloc;
    112      1.1  christos   bfd_reloc_code_real_type code;
    113      1.1  christos 
    114  1.1.1.7  christos   reloc = notes_alloc (sizeof (arelent));
    115  1.1.1.7  christos   reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
    116      1.1  christos   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
    117      1.1  christos   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
    118      1.1  christos 
    119      1.1  christos   switch (fixp->fx_r_type)
    120      1.1  christos     {
    121      1.1  christos     case BFD_RELOC_8:
    122      1.1  christos     case BFD_RELOC_16:
    123      1.1  christos     case BFD_RELOC_32:
    124      1.1  christos     case BFD_RELOC_8_PCREL:
    125      1.1  christos     case BFD_RELOC_16_PCREL:
    126      1.1  christos     case BFD_RELOC_32_PCREL:
    127      1.1  christos     case BFD_RELOC_VISIUM_HI16:
    128      1.1  christos     case BFD_RELOC_VISIUM_LO16:
    129      1.1  christos     case BFD_RELOC_VISIUM_IM16:
    130      1.1  christos     case BFD_RELOC_VISIUM_REL16:
    131      1.1  christos     case BFD_RELOC_VISIUM_HI16_PCREL:
    132      1.1  christos     case BFD_RELOC_VISIUM_LO16_PCREL:
    133      1.1  christos     case BFD_RELOC_VISIUM_IM16_PCREL:
    134      1.1  christos     case BFD_RELOC_VTABLE_INHERIT:
    135      1.1  christos     case BFD_RELOC_VTABLE_ENTRY:
    136      1.1  christos       code = fixp->fx_r_type;
    137      1.1  christos       break;
    138      1.1  christos     default:
    139      1.1  christos       as_bad_where (fixp->fx_file, fixp->fx_line,
    140      1.1  christos 		    "internal error: unknown relocation type %d (`%s')",
    141      1.1  christos 		    fixp->fx_r_type,
    142      1.1  christos 		    bfd_get_reloc_code_name (fixp->fx_r_type));
    143      1.1  christos       return 0;
    144      1.1  christos     }
    145      1.1  christos 
    146      1.1  christos   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
    147      1.1  christos   if (reloc->howto == 0)
    148      1.1  christos     {
    149      1.1  christos       as_bad_where (fixp->fx_file, fixp->fx_line,
    150      1.1  christos 		    "internal error: can't export reloc type %d (`%s')",
    151      1.1  christos 		    fixp->fx_r_type, bfd_get_reloc_code_name (code));
    152      1.1  christos       return 0;
    153      1.1  christos     }
    154      1.1  christos 
    155      1.1  christos   /* Write the addend.  */
    156      1.1  christos   if (reloc->howto->pc_relative == 0)
    157      1.1  christos     reloc->addend = fixp->fx_addnumber;
    158      1.1  christos   else
    159      1.1  christos     reloc->addend = fixp->fx_offset;
    160      1.1  christos 
    161      1.1  christos   return reloc;
    162      1.1  christos }
    163      1.1  christos 
    164      1.1  christos static void visium_rdata (int);
    165      1.1  christos 
    166      1.1  christos static void visium_update_parity_bit (char *);
    167      1.1  christos static char *parse_exp (char *, expressionS *);
    168      1.1  christos 
    169      1.1  christos /* This table describes all the machine specific pseudo-ops the assembler
    170  1.1.1.6  christos    has to support, and that aren't handled elsewhere. The fields are:
    171      1.1  christos 
    172      1.1  christos    1: Pseudo-op name without dot.
    173      1.1  christos    2: Function to call to execute this pseudo-op.
    174      1.1  christos    3: Integer arg to pass to the function.  */
    175      1.1  christos const pseudo_typeS md_pseudo_table[] =
    176      1.1  christos {
    177      1.1  christos   {"align", s_align_bytes, 0},
    178      1.1  christos   {"noopt", s_ignore, 0},
    179      1.1  christos   {"optim", s_ignore, 0},
    180      1.1  christos   {"rdata", visium_rdata, 0},
    181      1.1  christos   {"rodata", visium_rdata, 0},
    182      1.1  christos   {0, 0, 0}
    183      1.1  christos };
    184      1.1  christos 
    185      1.1  christos 
    186      1.1  christos static void
    187      1.1  christos visium_rdata (int xxx)
    188      1.1  christos {
    189      1.1  christos   char *save_line = input_line_pointer;
    190      1.1  christos   static char section[] = ".rodata\n";
    191      1.1  christos 
    192      1.1  christos   /* Just pretend this is .section .rodata */
    193      1.1  christos   input_line_pointer = section;
    194      1.1  christos   obj_elf_section (xxx);
    195      1.1  christos   input_line_pointer = save_line;
    196      1.1  christos }
    197      1.1  christos 
    198      1.1  christos /* Align a section.  */
    199      1.1  christos valueT
    200      1.1  christos md_section_align (asection *seg, valueT addr)
    201      1.1  christos {
    202  1.1.1.4  christos   int align = bfd_section_alignment (seg);
    203      1.1  christos 
    204  1.1.1.7  christos   return (addr + ((valueT) 1 << align) - 1) & -((valueT) 1 << align);
    205      1.1  christos }
    206      1.1  christos 
    207      1.1  christos void
    208      1.1  christos md_number_to_chars (char *buf, valueT val, int n)
    209      1.1  christos {
    210      1.1  christos   number_to_chars_bigendian (buf, val, n);
    211      1.1  christos }
    212      1.1  christos 
    213      1.1  christos symbolS *
    214      1.1  christos md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
    215      1.1  christos {
    216      1.1  christos   return 0;
    217      1.1  christos }
    218      1.1  christos 
    219      1.1  christos /* The parse options.  */
    220  1.1.1.7  christos const char md_shortopts[] = "m:";
    221      1.1  christos 
    222  1.1.1.7  christos const struct option md_longopts[] =
    223      1.1  christos {
    224      1.1  christos   {NULL, no_argument, NULL, 0}
    225      1.1  christos };
    226      1.1  christos 
    227  1.1.1.7  christos const size_t md_longopts_size = sizeof (md_longopts);
    228      1.1  christos 
    229      1.1  christos struct visium_option_table
    230      1.1  christos {
    231      1.1  christos   char *option;			/* Option name to match.  */
    232      1.1  christos   char *help;			/* Help information.  */
    233      1.1  christos   int *var;			/* Variable to change.  */
    234      1.1  christos   int value;			/* To what to change it.  */
    235      1.1  christos   char *deprecated;		/* If non-null, print this message. */
    236      1.1  christos };
    237      1.1  christos 
    238      1.1  christos static struct visium_option_table visium_opts[] =
    239      1.1  christos {
    240      1.1  christos   {NULL, NULL, NULL, 0, NULL}
    241      1.1  christos };
    242      1.1  christos 
    243      1.1  christos struct visium_arch_option_table
    244      1.1  christos {
    245  1.1.1.2  christos   const char *name;
    246      1.1  christos   enum visium_arch_val value;
    247      1.1  christos };
    248      1.1  christos 
    249      1.1  christos static struct visium_arch_option_table visium_archs[] =
    250      1.1  christos {
    251      1.1  christos   {"mcm24", VISIUM_ARCH_MCM24},
    252      1.1  christos   {"mcm",   VISIUM_ARCH_MCM},
    253      1.1  christos   {"gr5",   VISIUM_ARCH_MCM},
    254      1.1  christos   {"gr6",   VISIUM_ARCH_GR6},
    255      1.1  christos };
    256      1.1  christos 
    257      1.1  christos struct visium_long_option_table
    258      1.1  christos {
    259  1.1.1.2  christos   const char *option;			/* Substring to match.  */
    260  1.1.1.2  christos   const char *help;			/* Help information.  */
    261  1.1.1.2  christos   int (*func) (const char *subopt);	/* Function to decode sub-option.  */
    262  1.1.1.2  christos   const char *deprecated;		/* If non-null, print this message.  */
    263      1.1  christos };
    264      1.1  christos 
    265      1.1  christos static int
    266  1.1.1.2  christos visium_parse_arch (const char *str)
    267      1.1  christos {
    268  1.1.1.2  christos   unsigned int i;
    269      1.1  christos 
    270      1.1  christos   if (strlen (str) == 0)
    271      1.1  christos     {
    272      1.1  christos       as_bad ("missing architecture name `%s'", str);
    273      1.1  christos       return 0;
    274      1.1  christos     }
    275      1.1  christos 
    276  1.1.1.2  christos   for (i = 0; i < ARRAY_SIZE (visium_archs); i++)
    277  1.1.1.2  christos     if (strcmp (visium_archs[i].name, str) == 0)
    278      1.1  christos       {
    279  1.1.1.2  christos 	visium_arch = visium_archs[i].value;
    280      1.1  christos 	return 1;
    281      1.1  christos       }
    282      1.1  christos 
    283      1.1  christos   as_bad ("unknown architecture `%s'\n", str);
    284      1.1  christos   return 0;
    285      1.1  christos }
    286      1.1  christos 
    287      1.1  christos static struct visium_long_option_table visium_long_opts[] =
    288      1.1  christos {
    289      1.1  christos   {"mtune=", "<arch_name>\t assemble for architecture <arch name>",
    290      1.1  christos    visium_parse_arch, NULL},
    291      1.1  christos   {NULL, NULL, NULL, NULL}
    292      1.1  christos };
    293      1.1  christos 
    294      1.1  christos int
    295  1.1.1.2  christos md_parse_option (int c, const char *arg)
    296      1.1  christos {
    297      1.1  christos   struct visium_option_table *opt;
    298      1.1  christos   struct visium_long_option_table *lopt;
    299      1.1  christos 
    300      1.1  christos   switch (c)
    301      1.1  christos     {
    302      1.1  christos     case 'a':
    303      1.1  christos       /* Listing option.  Just ignore these, we don't support additional
    304      1.1  christos          ones.  */
    305      1.1  christos       return 0;
    306      1.1  christos 
    307      1.1  christos     default:
    308      1.1  christos       for (opt = visium_opts; opt->option != NULL; opt++)
    309      1.1  christos 	{
    310      1.1  christos 	  if (c == opt->option[0]
    311      1.1  christos 	      && ((arg == NULL && opt->option[1] == 0)
    312      1.1  christos 		  || strcmp (arg, opt->option + 1) == 0))
    313      1.1  christos 	    {
    314      1.1  christos 	      /* If the option is deprecated, tell the user.  */
    315      1.1  christos 	      if (opt->deprecated != NULL)
    316      1.1  christos 		as_tsktsk ("option `-%c%s' is deprecated: %s", c,
    317      1.1  christos 			   arg ? arg : "", opt->deprecated);
    318      1.1  christos 
    319      1.1  christos 	      if (opt->var != NULL)
    320      1.1  christos 		*opt->var = opt->value;
    321      1.1  christos 
    322      1.1  christos 	      return 1;
    323      1.1  christos 	    }
    324      1.1  christos 	}
    325      1.1  christos 
    326      1.1  christos       for (lopt = visium_long_opts; lopt->option != NULL; lopt++)
    327      1.1  christos 	{
    328      1.1  christos 	  /* These options are expected to have an argument.  */
    329      1.1  christos 	  if (c == lopt->option[0]
    330      1.1  christos 	      && arg != NULL
    331      1.1  christos 	      && strncmp (arg, lopt->option + 1,
    332      1.1  christos 			  strlen (lopt->option + 1)) == 0)
    333      1.1  christos 	    {
    334      1.1  christos 	      /* If the option is deprecated, tell the user.  */
    335      1.1  christos 	      if (lopt->deprecated != NULL)
    336      1.1  christos 		as_tsktsk ("option `-%c%s' is deprecated: %s", c, arg,
    337      1.1  christos 			   lopt->deprecated);
    338      1.1  christos 
    339      1.1  christos 	      /* Call the sup-option parser.  */
    340      1.1  christos 	      return lopt->func (arg + strlen (lopt->option) - 1);
    341      1.1  christos 	    }
    342      1.1  christos 	}
    343      1.1  christos 
    344      1.1  christos       return 0;
    345      1.1  christos     }
    346      1.1  christos 
    347      1.1  christos   return 1;
    348      1.1  christos }
    349      1.1  christos 
    350      1.1  christos void
    351      1.1  christos md_show_usage (FILE * fp)
    352      1.1  christos {
    353      1.1  christos   struct visium_option_table *opt;
    354      1.1  christos   struct visium_long_option_table *lopt;
    355      1.1  christos 
    356      1.1  christos   fprintf (fp, " Visium-specific assembler options:\n");
    357      1.1  christos 
    358      1.1  christos   for (opt = visium_opts; opt->option != NULL; opt++)
    359      1.1  christos     if (opt->help != NULL)
    360      1.1  christos       fprintf (fp, "  -%-23s%s\n", opt->option, opt->help);
    361      1.1  christos 
    362      1.1  christos   for (lopt = visium_long_opts; lopt->option != NULL; lopt++)
    363      1.1  christos     if (lopt->help != NULL)
    364      1.1  christos       fprintf (fp, "  -%s%s\n", lopt->option, lopt->help);
    365      1.1  christos 
    366      1.1  christos }
    367      1.1  christos 
    368      1.1  christos /* Interface to relax_segment.  */
    369      1.1  christos 
    370      1.1  christos /* Return the estimate of the size of a machine dependent frag
    371      1.1  christos    before any relaxing is done.  It may also create any necessary
    372      1.1  christos    relocations.  */
    373      1.1  christos int
    374      1.1  christos md_estimate_size_before_relax (fragS * fragP,
    375      1.1  christos 			       segT segment ATTRIBUTE_UNUSED)
    376      1.1  christos {
    377      1.1  christos   fragP->fr_var = 4;
    378      1.1  christos   return 4;
    379      1.1  christos }
    380      1.1  christos 
    381      1.1  christos /* Get the address of a symbol during relaxation.  From tc-arm.c.  */
    382      1.1  christos static addressT
    383      1.1  christos relaxed_symbol_addr (fragS *fragp, long stretch)
    384      1.1  christos {
    385      1.1  christos   fragS *sym_frag;
    386      1.1  christos   addressT addr;
    387      1.1  christos   symbolS *sym;
    388      1.1  christos 
    389      1.1  christos   sym = fragp->fr_symbol;
    390      1.1  christos   sym_frag = symbol_get_frag (sym);
    391      1.1  christos   know (S_GET_SEGMENT (sym) != absolute_section
    392      1.1  christos 	|| sym_frag == &zero_address_frag);
    393      1.1  christos   addr = S_GET_VALUE (sym) + fragp->fr_offset;
    394      1.1  christos 
    395      1.1  christos   /* If frag has yet to be reached on this pass, assume it will
    396      1.1  christos      move by STRETCH just as we did.  If this is not so, it will
    397      1.1  christos      be because some frag between grows, and that will force
    398      1.1  christos      another pass.  */
    399      1.1  christos   if (stretch != 0
    400      1.1  christos       && sym_frag->relax_marker != fragp->relax_marker)
    401      1.1  christos     {
    402      1.1  christos       fragS *f;
    403      1.1  christos 
    404      1.1  christos       /* Adjust stretch for any alignment frag.  Note that if have
    405      1.1  christos 	 been expanding the earlier code, the symbol may be
    406      1.1  christos 	 defined in what appears to be an earlier frag.  FIXME:
    407      1.1  christos 	 This doesn't handle the fr_subtype field, which specifies
    408      1.1  christos 	 a maximum number of bytes to skip when doing an
    409      1.1  christos 	 alignment.  */
    410      1.1  christos       for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
    411      1.1  christos 	{
    412      1.1  christos 	  if (f->fr_type == rs_align || f->fr_type == rs_align_code)
    413      1.1  christos 	    {
    414      1.1  christos 	      if (stretch < 0)
    415  1.1.1.7  christos 		stretch = -(-stretch & ~((1ul << f->fr_offset) - 1));
    416      1.1  christos 	      else
    417  1.1.1.7  christos 		stretch &= ~((1ul << f->fr_offset) - 1);
    418      1.1  christos 	      if (stretch == 0)
    419      1.1  christos 		break;
    420      1.1  christos 	    }
    421      1.1  christos 	}
    422      1.1  christos       if (f != NULL)
    423      1.1  christos 	addr += stretch;
    424      1.1  christos     }
    425      1.1  christos 
    426      1.1  christos   return addr;
    427      1.1  christos }
    428      1.1  christos 
    429      1.1  christos /* Relax a machine dependent frag.  This returns the amount by which
    430      1.1  christos    the current size of the frag should change.  */
    431      1.1  christos int
    432      1.1  christos visium_relax_frag (asection *sec, fragS *fragP, long stretch)
    433      1.1  christos {
    434      1.1  christos   int old_size, new_size;
    435      1.1  christos   addressT addr;
    436      1.1  christos 
    437      1.1  christos   /* We only handle relaxation for the BRR instruction.  */
    438      1.1  christos   gas_assert (fragP->fr_subtype == mode_ci);
    439      1.1  christos 
    440      1.1  christos   if (!S_IS_DEFINED (fragP->fr_symbol)
    441      1.1  christos       || sec != S_GET_SEGMENT (fragP->fr_symbol)
    442      1.1  christos       || S_IS_WEAK (fragP->fr_symbol))
    443      1.1  christos     return 0;
    444      1.1  christos 
    445      1.1  christos   old_size = fragP->fr_var;
    446      1.1  christos   addr = relaxed_symbol_addr (fragP, stretch);
    447      1.1  christos 
    448      1.1  christos   /* If the target is the address of the instruction, we'll insert a NOP.  */
    449      1.1  christos   if (addr == fragP->fr_address + fragP->fr_fix)
    450      1.1  christos     new_size = 8;
    451      1.1  christos   else
    452      1.1  christos     new_size = 4;
    453      1.1  christos 
    454      1.1  christos   fragP->fr_var = new_size;
    455      1.1  christos   return new_size - old_size;
    456      1.1  christos }
    457      1.1  christos 
    458      1.1  christos /* Convert a machine dependent frag.  */
    459      1.1  christos void
    460      1.1  christos md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED,
    461      1.1  christos 		 fragS * fragP)
    462      1.1  christos {
    463  1.1.1.5  christos   char *buf = &fragP->fr_literal[0] + fragP->fr_fix;
    464      1.1  christos   expressionS exp;
    465      1.1  christos   fixS *fixP;
    466      1.1  christos 
    467      1.1  christos   /* We only handle relaxation for the BRR instruction.  */
    468      1.1  christos   gas_assert (fragP->fr_subtype == mode_ci);
    469      1.1  christos 
    470      1.1  christos   /* Insert the NOP if requested.  */
    471      1.1  christos   if (fragP->fr_var == 8)
    472      1.1  christos     {
    473      1.1  christos       memcpy (buf + 4, buf, 4);
    474      1.1  christos       memset (buf, 0, 4);
    475      1.1  christos       fragP->fr_fix += 4;
    476      1.1  christos     }
    477      1.1  christos 
    478      1.1  christos   exp.X_op = O_symbol;
    479      1.1  christos   exp.X_add_symbol = fragP->fr_symbol;
    480      1.1  christos   exp.X_add_number = fragP->fr_offset;
    481      1.1  christos 
    482      1.1  christos   /* Now we can create the relocation at the correct offset.  */
    483      1.1  christos   fixP = fix_new_exp (fragP, fragP->fr_fix, 4, &exp, 1, BFD_RELOC_VISIUM_REL16);
    484      1.1  christos   fixP->fx_file = fragP->fr_file;
    485      1.1  christos   fixP->fx_line = fragP->fr_line;
    486      1.1  christos   fragP->fr_fix += 4;
    487      1.1  christos   fragP->fr_var = 0;
    488      1.1  christos }
    489      1.1  christos 
    490      1.1  christos /* The location from which a PC relative jump should be calculated,
    491      1.1  christos    given a PC relative jump reloc.  */
    492      1.1  christos long
    493      1.1  christos visium_pcrel_from_section (fixS *fixP, segT sec)
    494      1.1  christos {
    495  1.1.1.7  christos   if (fixP->fx_addsy != NULL
    496      1.1  christos       && (!S_IS_DEFINED (fixP->fx_addsy)
    497      1.1  christos 	  || S_GET_SEGMENT (fixP->fx_addsy) != sec))
    498      1.1  christos     {
    499      1.1  christos       /* The symbol is undefined (or is defined but not in this section).
    500      1.1  christos          Let the linker figure it out.  */
    501      1.1  christos       return 0;
    502      1.1  christos     }
    503      1.1  christos 
    504      1.1  christos   /* Return the address of the instruction.  */
    505      1.1  christos   return fixP->fx_where + fixP->fx_frag->fr_address;
    506      1.1  christos }
    507      1.1  christos 
    508      1.1  christos /* Indicate whether a fixup against a locally defined
    509      1.1  christos    symbol should be adjusted to be against the section
    510      1.1  christos    symbol.  */
    511  1.1.1.5  christos bool
    512      1.1  christos visium_fix_adjustable (fixS *fix)
    513      1.1  christos {
    514      1.1  christos   /* We need the symbol name for the VTABLE entries.  */
    515      1.1  christos   return (fix->fx_r_type != BFD_RELOC_VTABLE_INHERIT
    516      1.1  christos 	  && fix->fx_r_type != BFD_RELOC_VTABLE_ENTRY);
    517      1.1  christos }
    518      1.1  christos 
    519      1.1  christos /* Update the parity bit of the 4-byte instruction in BUF.  */
    520      1.1  christos static void
    521      1.1  christos visium_update_parity_bit (char *buf)
    522      1.1  christos {
    523      1.1  christos   int p1 = (buf[0] & 0x7f) ^ buf[1] ^ buf[2] ^ buf[3];
    524      1.1  christos   int p2 = 0;
    525      1.1  christos   int i;
    526      1.1  christos 
    527      1.1  christos   for (i = 1; i <= 8; i++)
    528      1.1  christos     {
    529      1.1  christos       p2 ^= (p1 & 1);
    530      1.1  christos       p1 >>= 1;
    531      1.1  christos     }
    532      1.1  christos 
    533      1.1  christos   buf[0] = (buf[0] & 0x7f) | ((p2 << 7) & 0x80);
    534      1.1  christos }
    535      1.1  christos 
    536      1.1  christos /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
    537      1.1  christos    of an rs_align_code fragment.  */
    538      1.1  christos void
    539      1.1  christos visium_handle_align (fragS *fragP)
    540      1.1  christos {
    541      1.1  christos   valueT count
    542      1.1  christos     = fragP->fr_next->fr_address - (fragP->fr_address + fragP->fr_fix);
    543      1.1  christos   valueT fix = count & 3;
    544      1.1  christos   char *p = fragP->fr_literal + fragP->fr_fix;
    545      1.1  christos 
    546      1.1  christos   if (fix)
    547      1.1  christos     {
    548      1.1  christos       memset (p, 0, fix);
    549      1.1  christos       p += fix;
    550      1.1  christos       count -= fix;
    551      1.1  christos       fragP->fr_fix += fix;
    552      1.1  christos     }
    553      1.1  christos 
    554      1.1  christos   if (count == 0)
    555      1.1  christos     return;
    556      1.1  christos 
    557      1.1  christos   if (count > 4 * nop_limit && count <= 131068)
    558      1.1  christos     {
    559  1.1.1.7  christos       /* Make a branch, then follow with nops.  */
    560      1.1  christos       md_number_to_chars (p, 0x78000000 + (count >> 2), 4);
    561      1.1  christos       visium_update_parity_bit (p);
    562  1.1.1.7  christos       p += 4;
    563  1.1.1.7  christos       fragP->fr_fix += 4;
    564      1.1  christos     }
    565      1.1  christos 
    566  1.1.1.7  christos   *p = 0;
    567      1.1  christos }
    568      1.1  christos 
    569      1.1  christos /* Apply a fixS to the frags, now that we know the value it ought to
    570      1.1  christos    hold.  */
    571      1.1  christos void
    572      1.1  christos md_apply_fix (fixS * fixP, valueT * value, segT segment)
    573      1.1  christos {
    574      1.1  christos   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
    575      1.1  christos   offsetT val;
    576      1.1  christos   long insn;
    577      1.1  christos 
    578      1.1  christos   val = *value;
    579      1.1  christos 
    580      1.1  christos   gas_assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
    581      1.1  christos 
    582      1.1  christos   /* Remember value for tc_gen_reloc.  */
    583      1.1  christos   fixP->fx_addnumber = val;
    584      1.1  christos 
    585      1.1  christos   /* Since DIFF_EXPR_OK is defined, .-foo gets turned into PC
    586      1.1  christos      relative relocs. If this has happened, a non-PC relative
    587      1.1  christos      reloc must be reinstalled with its PC relative version here.  */
    588      1.1  christos   if (fixP->fx_pcrel)
    589      1.1  christos     {
    590      1.1  christos       switch (fixP->fx_r_type)
    591      1.1  christos 	{
    592      1.1  christos 	case BFD_RELOC_8:
    593      1.1  christos 	  fixP->fx_r_type = BFD_RELOC_8_PCREL;
    594      1.1  christos 	  break;
    595      1.1  christos 	case BFD_RELOC_16:
    596      1.1  christos 	  fixP->fx_r_type = BFD_RELOC_16_PCREL;
    597      1.1  christos 	  break;
    598      1.1  christos 	case BFD_RELOC_32:
    599      1.1  christos 	  fixP->fx_r_type = BFD_RELOC_32_PCREL;
    600      1.1  christos 	  break;
    601      1.1  christos 	case BFD_RELOC_VISIUM_HI16:
    602      1.1  christos 	  fixP->fx_r_type = BFD_RELOC_VISIUM_HI16_PCREL;
    603      1.1  christos 	  break;
    604      1.1  christos 	case BFD_RELOC_VISIUM_LO16:
    605      1.1  christos 	  fixP->fx_r_type = BFD_RELOC_VISIUM_LO16_PCREL;
    606      1.1  christos 	  break;
    607      1.1  christos 	case BFD_RELOC_VISIUM_IM16:
    608      1.1  christos 	  fixP->fx_r_type = BFD_RELOC_VISIUM_IM16_PCREL;
    609      1.1  christos 	  break;
    610      1.1  christos 	default:
    611      1.1  christos 	  break;
    612      1.1  christos 	}
    613      1.1  christos     }
    614      1.1  christos 
    615      1.1  christos   /* If this is a data relocation, just output VAL.  */
    616      1.1  christos   switch (fixP->fx_r_type)
    617      1.1  christos     {
    618      1.1  christos     case BFD_RELOC_8:
    619      1.1  christos     case BFD_RELOC_8_PCREL:
    620      1.1  christos       md_number_to_chars (buf, val, 1);
    621      1.1  christos       break;
    622      1.1  christos     case BFD_RELOC_16:
    623      1.1  christos     case BFD_RELOC_16_PCREL:
    624      1.1  christos       md_number_to_chars (buf, val, 2);
    625      1.1  christos       break;
    626      1.1  christos     case BFD_RELOC_32:
    627      1.1  christos     case BFD_RELOC_32_PCREL:
    628      1.1  christos       md_number_to_chars (buf, val, 4);
    629      1.1  christos       break;
    630      1.1  christos     case BFD_RELOC_VTABLE_INHERIT:
    631      1.1  christos     case BFD_RELOC_VTABLE_ENTRY:
    632      1.1  christos       fixP->fx_done = 0;
    633      1.1  christos       break;
    634      1.1  christos     default:
    635      1.1  christos       /* It's a relocation against an instruction.  */
    636  1.1.1.7  christos       insn = bfd_getb32 (buf);
    637      1.1  christos 
    638      1.1  christos       switch (fixP->fx_r_type)
    639      1.1  christos 	{
    640      1.1  christos 	case BFD_RELOC_VISIUM_REL16:
    641      1.1  christos 	  if (fixP->fx_addsy == NULL
    642      1.1  christos 	      || (S_IS_DEFINED (fixP->fx_addsy)
    643      1.1  christos 		  && S_GET_SEGMENT (fixP->fx_addsy) == segment))
    644      1.1  christos 	    {
    645      1.1  christos 	      if (val > 0x1fffc || val < -0x20000)
    646      1.1  christos 		as_bad_where
    647      1.1  christos 		 (fixP->fx_file, fixP->fx_line,
    648      1.1  christos 		  "16-bit word displacement out of range: value = %d",
    649      1.1  christos 		  (int) val);
    650      1.1  christos 	      val = (val >> 2);
    651      1.1  christos 
    652      1.1  christos 	      insn = (insn & 0xffff0000) | (val & 0x0000ffff);
    653      1.1  christos 	    }
    654      1.1  christos 	  break;
    655      1.1  christos 
    656      1.1  christos 	case BFD_RELOC_VISIUM_HI16:
    657      1.1  christos 	case BFD_RELOC_VISIUM_HI16_PCREL:
    658      1.1  christos 	  if (fixP->fx_addsy == NULL)
    659      1.1  christos 	    insn = (insn & 0xffff0000) | ((val >> 16) & 0x0000ffff);
    660      1.1  christos 	  break;
    661      1.1  christos 
    662      1.1  christos 	case BFD_RELOC_VISIUM_LO16:
    663      1.1  christos 	case BFD_RELOC_VISIUM_LO16_PCREL:
    664      1.1  christos 	  if (fixP->fx_addsy == NULL)
    665      1.1  christos 	    insn = (insn & 0xffff0000) | (val & 0x0000ffff);
    666      1.1  christos 	  break;
    667      1.1  christos 
    668      1.1  christos 	case BFD_RELOC_VISIUM_IM16:
    669      1.1  christos 	case BFD_RELOC_VISIUM_IM16_PCREL:
    670      1.1  christos 	  if (fixP->fx_addsy == NULL)
    671      1.1  christos 	    {
    672      1.1  christos 	      if ((val & 0xffff0000) != 0)
    673      1.1  christos 		as_bad_where (fixP->fx_file, fixP->fx_line,
    674      1.1  christos 			      "16-bit immediate out of range: value = %d",
    675      1.1  christos 			      (int) val);
    676      1.1  christos 
    677      1.1  christos 	      insn = (insn & 0xffff0000) | val;
    678      1.1  christos 	    }
    679      1.1  christos 	  break;
    680      1.1  christos 
    681      1.1  christos 	case BFD_RELOC_NONE:
    682      1.1  christos 	default:
    683      1.1  christos 	  as_bad_where (fixP->fx_file, fixP->fx_line,
    684      1.1  christos 			"bad or unhandled relocation type: 0x%02x",
    685  1.1.1.7  christos 			(unsigned int) fixP->fx_r_type);
    686      1.1  christos 	  break;
    687      1.1  christos 	}
    688      1.1  christos 
    689  1.1.1.7  christos       bfd_putb32 (insn, buf);
    690      1.1  christos       visium_update_parity_bit (buf);
    691      1.1  christos       break;
    692      1.1  christos     }
    693      1.1  christos 
    694      1.1  christos   /* Are we finished with this relocation now?  */
    695      1.1  christos   if (fixP->fx_addsy == NULL)
    696      1.1  christos     fixP->fx_done = 1;
    697      1.1  christos }
    698      1.1  christos 
    699      1.1  christos char *
    700      1.1  christos parse_exp (char *s, expressionS * op)
    701      1.1  christos {
    702      1.1  christos   char *save = input_line_pointer;
    703      1.1  christos   char *new;
    704      1.1  christos 
    705      1.1  christos   if (!s)
    706      1.1  christos     {
    707      1.1  christos       return s;
    708      1.1  christos     }
    709      1.1  christos 
    710      1.1  christos   input_line_pointer = s;
    711      1.1  christos   expression (op);
    712      1.1  christos   new = input_line_pointer;
    713      1.1  christos   input_line_pointer = save;
    714      1.1  christos   return new;
    715      1.1  christos }
    716      1.1  christos 
    717      1.1  christos /* If the given string is a Visium opcode mnemonic return the code
    718      1.1  christos    otherwise return -1. Use binary chop to find matching entry.  */
    719      1.1  christos static int
    720      1.1  christos get_opcode (int *code, enum addressing_mode *mode, char *flags, char *mnem)
    721      1.1  christos {
    722      1.1  christos   int l = 0;
    723      1.1  christos   int r = sizeof (opcode_table) / sizeof (struct opcode_entry) - 1;
    724      1.1  christos 
    725      1.1  christos   do
    726      1.1  christos     {
    727      1.1  christos       int mid = (l + r) / 2;
    728      1.1  christos       int ans = strcmp (mnem, opcode_table[mid].mnem);
    729      1.1  christos 
    730      1.1  christos       if (ans < 0)
    731      1.1  christos 	r = mid - 1;
    732      1.1  christos       else if (ans > 0)
    733      1.1  christos 	l = mid + 1;
    734      1.1  christos       else
    735      1.1  christos 	{
    736      1.1  christos 	  *code = opcode_table[mid].code;
    737      1.1  christos 	  *mode = opcode_table[mid].mode;
    738      1.1  christos 	  *flags = opcode_table[mid].flags;
    739      1.1  christos 
    740      1.1  christos 	  return 0;
    741      1.1  christos 	}
    742      1.1  christos     }
    743      1.1  christos   while (l <= r);
    744      1.1  christos 
    745      1.1  christos   return -1;
    746      1.1  christos }
    747      1.1  christos 
    748      1.1  christos /* This function is called when the assembler starts up. It is called
    749      1.1  christos    after the options have been parsed and the output file has been
    750      1.1  christos    opened.  */
    751      1.1  christos void
    752      1.1  christos md_begin (void)
    753      1.1  christos {
    754      1.1  christos   switch (visium_arch)
    755      1.1  christos     {
    756      1.1  christos     case VISIUM_ARCH_DEF:
    757      1.1  christos       break;
    758      1.1  christos     case VISIUM_ARCH_MCM24:
    759      1.1  christos       visium_opcode_arch = VISIUM_OPCODE_ARCH_GR5;
    760      1.1  christos       visium_flags |= EF_VISIUM_ARCH_MCM24;
    761      1.1  christos       break;
    762      1.1  christos     case VISIUM_ARCH_MCM:
    763      1.1  christos       visium_opcode_arch = VISIUM_OPCODE_ARCH_GR5;
    764      1.1  christos       visium_flags |= EF_VISIUM_ARCH_MCM;
    765      1.1  christos       break;
    766      1.1  christos     case VISIUM_ARCH_GR6:
    767      1.1  christos       visium_opcode_arch = VISIUM_OPCODE_ARCH_GR6;
    768      1.1  christos       visium_flags |= EF_VISIUM_ARCH_MCM | EF_VISIUM_ARCH_GR6;
    769      1.1  christos       nop_limit = 2;
    770      1.1  christos       break;
    771      1.1  christos     default:
    772      1.1  christos       gas_assert (0);
    773      1.1  christos     }
    774      1.1  christos 
    775      1.1  christos   bfd_set_private_flags (stdoutput, visium_flags);
    776      1.1  christos }
    777      1.1  christos 
    778      1.1  christos /* This is identical to the md_atof in m68k.c.  I think this is right,
    779      1.1  christos    but I'm not sure.
    780      1.1  christos 
    781      1.1  christos    Turn a string in input_line_pointer into a floating point constant of type
    782      1.1  christos    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
    783      1.1  christos    emitted is stored in *sizeP .  An error message is returned,
    784      1.1  christos    or NULL on OK.  */
    785      1.1  christos 
    786  1.1.1.2  christos const char *
    787      1.1  christos md_atof (int type, char *litP, int *sizeP)
    788      1.1  christos {
    789      1.1  christos   int i, prec;
    790      1.1  christos   LITTLENUM_TYPE words[MAX_LITTLENUMS];
    791      1.1  christos   char *t;
    792      1.1  christos 
    793      1.1  christos   switch (type)
    794      1.1  christos     {
    795      1.1  christos     case 'f':
    796      1.1  christos     case 'F':
    797      1.1  christos     case 's':
    798      1.1  christos     case 'S':
    799      1.1  christos       prec = 2;
    800      1.1  christos       break;
    801      1.1  christos 
    802      1.1  christos     case 'd':
    803      1.1  christos     case 'D':
    804      1.1  christos     case 'r':
    805      1.1  christos     case 'R':
    806      1.1  christos       prec = 4;
    807      1.1  christos       break;
    808      1.1  christos 
    809      1.1  christos     case 'x':
    810      1.1  christos     case 'X':
    811      1.1  christos       prec = 6;
    812      1.1  christos       break;
    813      1.1  christos 
    814      1.1  christos     case 'p':
    815      1.1  christos     case 'P':
    816      1.1  christos       prec = 6;
    817      1.1  christos       break;
    818      1.1  christos 
    819      1.1  christos     default:
    820      1.1  christos       *sizeP = 0;
    821  1.1.1.2  christos       return _("Bad call to MD_ATOF()");
    822      1.1  christos     }
    823      1.1  christos 
    824      1.1  christos   t = atof_ieee (input_line_pointer, type, words);
    825      1.1  christos   if (t)
    826      1.1  christos     input_line_pointer = t;
    827      1.1  christos   *sizeP = prec * sizeof (LITTLENUM_TYPE);
    828      1.1  christos 
    829      1.1  christos   if (target_big_endian)
    830      1.1  christos     {
    831      1.1  christos       for (i = 0; i < prec; i++)
    832      1.1  christos 	{
    833  1.1.1.7  christos 	  md_number_to_chars (litP, words[i], sizeof (LITTLENUM_TYPE));
    834      1.1  christos 	  litP += sizeof (LITTLENUM_TYPE);
    835      1.1  christos 	}
    836      1.1  christos     }
    837      1.1  christos   else
    838      1.1  christos     {
    839      1.1  christos       for (i = prec - 1; i >= 0; i--)
    840      1.1  christos 	{
    841  1.1.1.7  christos 	  md_number_to_chars (litP, words[i], sizeof (LITTLENUM_TYPE));
    842      1.1  christos 	  litP += sizeof (LITTLENUM_TYPE);
    843      1.1  christos 	}
    844      1.1  christos     }
    845      1.1  christos 
    846      1.1  christos   return 0;
    847      1.1  christos }
    848      1.1  christos 
    849      1.1  christos static inline char *
    850      1.1  christos skip_space (char *s)
    851      1.1  christos {
    852  1.1.1.7  christos   while (is_whitespace (*s))
    853      1.1  christos     ++s;
    854      1.1  christos 
    855      1.1  christos   return s;
    856      1.1  christos }
    857      1.1  christos 
    858      1.1  christos static int
    859      1.1  christos parse_gen_reg (char **sptr, int *rptr)
    860      1.1  christos {
    861      1.1  christos   char *s = skip_space (*sptr);
    862      1.1  christos   char buf[10];
    863      1.1  christos   int cnt;
    864      1.1  christos   int l, r;
    865      1.1  christos 
    866      1.1  christos   cnt = 0;
    867      1.1  christos   memset (buf, '\0', 10);
    868      1.1  christos   while ((ISALNUM (*s)) && cnt < 10)
    869      1.1  christos     buf[cnt++] = TOLOWER (*s++);
    870      1.1  christos 
    871      1.1  christos   l = 0;
    872      1.1  christos   r = sizeof (gen_reg_table) / sizeof (struct reg_entry) - 1;
    873      1.1  christos 
    874      1.1  christos   do
    875      1.1  christos     {
    876      1.1  christos       int mid = (l + r) / 2;
    877      1.1  christos       int ans = strcmp (buf, gen_reg_table[mid].name);
    878      1.1  christos 
    879      1.1  christos       if (ans < 0)
    880      1.1  christos 	r = mid - 1;
    881      1.1  christos       else if (ans > 0)
    882      1.1  christos 	l = mid + 1;
    883      1.1  christos       else
    884      1.1  christos 	{
    885      1.1  christos 	  *rptr = gen_reg_table[mid].code;
    886      1.1  christos 	  *sptr = s;
    887      1.1  christos 	  return 0;
    888      1.1  christos 	}
    889      1.1  christos     }
    890      1.1  christos   while (l <= r);
    891      1.1  christos 
    892      1.1  christos   return -1;
    893      1.1  christos }
    894      1.1  christos 
    895      1.1  christos static int
    896      1.1  christos parse_fp_reg (char **sptr, int *rptr)
    897      1.1  christos {
    898      1.1  christos   char *s = skip_space (*sptr);
    899      1.1  christos   char buf[10];
    900      1.1  christos   int cnt;
    901      1.1  christos   int l, r;
    902      1.1  christos 
    903      1.1  christos   cnt = 0;
    904      1.1  christos   memset (buf, '\0', 10);
    905      1.1  christos   while ((ISALNUM (*s)) && cnt < 10)
    906      1.1  christos     buf[cnt++] = TOLOWER (*s++);
    907      1.1  christos 
    908      1.1  christos   l = 0;
    909      1.1  christos   r = sizeof (fp_reg_table) / sizeof (struct reg_entry) - 1;
    910      1.1  christos 
    911      1.1  christos   do
    912      1.1  christos     {
    913      1.1  christos       int mid = (l + r) / 2;
    914      1.1  christos       int ans = strcmp (buf, fp_reg_table[mid].name);
    915      1.1  christos 
    916      1.1  christos       if (ans < 0)
    917      1.1  christos 	r = mid - 1;
    918      1.1  christos       else if (ans > 0)
    919      1.1  christos 	l = mid + 1;
    920      1.1  christos       else
    921      1.1  christos 	{
    922      1.1  christos 	  *rptr = fp_reg_table[mid].code;
    923      1.1  christos 	  *sptr = s;
    924      1.1  christos 	  return 0;
    925      1.1  christos 	}
    926      1.1  christos     }
    927      1.1  christos   while (l <= r);
    928      1.1  christos 
    929      1.1  christos   return -1;
    930      1.1  christos }
    931      1.1  christos 
    932      1.1  christos static int
    933      1.1  christos parse_cc (char **sptr, int *rptr)
    934      1.1  christos {
    935      1.1  christos   char *s = skip_space (*sptr);
    936      1.1  christos   char buf[10];
    937      1.1  christos   int cnt;
    938      1.1  christos   int l, r;
    939      1.1  christos 
    940      1.1  christos   cnt = 0;
    941      1.1  christos   memset (buf, '\0', 10);
    942      1.1  christos   while ((ISALNUM (*s)) && cnt < 10)
    943      1.1  christos     buf[cnt++] = TOLOWER (*s++);
    944      1.1  christos 
    945      1.1  christos   l = 0;
    946      1.1  christos   r = sizeof (cc_table) / sizeof (struct cc_entry) - 1;
    947      1.1  christos 
    948      1.1  christos   do
    949      1.1  christos     {
    950      1.1  christos       int mid = (l + r) / 2;
    951      1.1  christos       int ans = strcmp (buf, cc_table[mid].name);
    952      1.1  christos 
    953      1.1  christos       if (ans < 0)
    954      1.1  christos 	r = mid - 1;
    955      1.1  christos       else if (ans > 0)
    956      1.1  christos 	l = mid + 1;
    957      1.1  christos       else
    958      1.1  christos 	{
    959      1.1  christos 	  *rptr = cc_table[mid].code;
    960      1.1  christos 	  *sptr = s;
    961      1.1  christos 	  return 0;
    962      1.1  christos 	}
    963      1.1  christos     }
    964      1.1  christos   while (l <= r);
    965      1.1  christos 
    966      1.1  christos   return -1;
    967      1.1  christos }
    968      1.1  christos 
    969      1.1  christos /* Previous dest is the destination register number of the instruction
    970      1.1  christos    before the current one.  */
    971      1.1  christos static int previous_dest = 0;
    972      1.1  christos static int previous_mode = 0;
    973      1.1  christos static int condition_code = 0;
    974      1.1  christos static int this_dest = 0;
    975      1.1  christos static int this_mode = 0;
    976      1.1  christos 
    977      1.1  christos 
    978      1.1  christos /* This is the main function in this file. It takes a line of assembly language
    979      1.1  christos    source code and assembles it. Note, labels and pseudo ops have already
    980      1.1  christos    been removed, so too has leading white space. */
    981      1.1  christos void
    982      1.1  christos md_assemble (char *str0)
    983      1.1  christos {
    984      1.1  christos   char *str = str0;
    985      1.1  christos   int cnt;
    986      1.1  christos   char mnem[10];
    987      1.1  christos   int opcode;
    988      1.1  christos   enum addressing_mode amode;
    989      1.1  christos   char arch_flags;
    990      1.1  christos   int ans;
    991      1.1  christos 
    992      1.1  christos   char *output;
    993      1.1  christos   int reloc = 0;
    994      1.1  christos   relax_substateT relax = 0;
    995      1.1  christos   expressionS e1;
    996      1.1  christos   int r1, r2, r3;
    997      1.1  christos   int cc;
    998      1.1  christos   int indx;
    999      1.1  christos 
   1000      1.1  christos   /* Initialize the expression.  */
   1001      1.1  christos   e1.X_op = O_absent;
   1002      1.1  christos 
   1003      1.1  christos   /* Initialize destination register.
   1004      1.1  christos      If the instruction we just looked at is in the delay slot of an
   1005      1.1  christos      unconditional branch, then there is no index hazard.  */
   1006      1.1  christos   if ((previous_mode == mode_cad || previous_mode == mode_ci)
   1007      1.1  christos       && condition_code == 15)
   1008      1.1  christos     this_dest = 0;
   1009      1.1  christos 
   1010      1.1  christos   previous_dest = this_dest;
   1011      1.1  christos   previous_mode = this_mode;
   1012      1.1  christos   this_dest = 0;
   1013      1.1  christos 
   1014      1.1  christos   /* Drop leading whitespace (probably not required).  */
   1015  1.1.1.7  christos   while (is_whitespace (*str))
   1016      1.1  christos     str++;
   1017      1.1  christos 
   1018      1.1  christos   /* Get opcode mnemonic and make sure it's in lower case.  */
   1019      1.1  christos   cnt = 0;
   1020      1.1  christos   memset (mnem, '\0', 10);
   1021      1.1  christos   while ((ISALNUM (*str) || *str == '.' || *str == '_') && cnt < 10)
   1022      1.1  christos     mnem[cnt++] = TOLOWER (*str++);
   1023      1.1  christos 
   1024      1.1  christos   /* Look up mnemonic in opcode table, and get the code,
   1025      1.1  christos      the instruction format, and the flags that indicate
   1026  1.1.1.3  christos      which family members support this mnemonic.  */
   1027      1.1  christos   if (get_opcode (&opcode, &amode, &arch_flags, mnem) < 0)
   1028      1.1  christos     {
   1029  1.1.1.3  christos       as_bad ("Unknown instruction mnemonic `%s'", mnem);
   1030      1.1  christos       return;
   1031      1.1  christos     }
   1032      1.1  christos 
   1033      1.1  christos   if ((VISIUM_OPCODE_ARCH_MASK (visium_opcode_arch) & arch_flags) == 0)
   1034      1.1  christos     {
   1035      1.1  christos       as_bad ("Architecture mismatch on `%s'", mnem);
   1036      1.1  christos       return;
   1037      1.1  christos     }
   1038      1.1  christos 
   1039      1.1  christos   this_mode = amode;
   1040      1.1  christos 
   1041      1.1  christos   switch (amode)
   1042      1.1  christos     {
   1043      1.1  christos     case mode_d:
   1044      1.1  christos       /* register :=
   1045      1.1  christos          Example:
   1046      1.1  christos          readmda r1  */
   1047      1.1  christos       ans = parse_gen_reg (&str, &r1);
   1048      1.1  christos       if (ans < 0)
   1049      1.1  christos 	{
   1050      1.1  christos 	  as_bad ("Dest register required");
   1051      1.1  christos 	  return;
   1052      1.1  christos 	}
   1053      1.1  christos       opcode |= (r1 << 10);
   1054      1.1  christos       this_dest = r1;
   1055      1.1  christos       break;
   1056      1.1  christos 
   1057      1.1  christos     case mode_a:
   1058      1.1  christos       /* op= register
   1059      1.1  christos          Example: asld r1  */
   1060      1.1  christos       ans = parse_gen_reg (&str, &r1);
   1061      1.1  christos       if (ans < 0)
   1062      1.1  christos 	{
   1063      1.1  christos 	  as_bad ("SourceA register required");
   1064      1.1  christos 	  return;
   1065      1.1  christos 	}
   1066      1.1  christos       opcode |= (r1 << 16);
   1067      1.1  christos       break;
   1068      1.1  christos 
   1069      1.1  christos     case mode_ab:
   1070      1.1  christos       /* register * register
   1071      1.1  christos          Example:
   1072      1.1  christos          mults r1,r2  */
   1073      1.1  christos       ans = parse_gen_reg (&str, &r1);
   1074      1.1  christos       if (ans < 0)
   1075      1.1  christos 	{
   1076      1.1  christos 	  as_bad ("SourceA register required");
   1077      1.1  christos 	  return;
   1078      1.1  christos 	}
   1079      1.1  christos       str = skip_space (str);
   1080      1.1  christos       if (*str == ',')
   1081      1.1  christos 	{
   1082      1.1  christos 	  str++;
   1083      1.1  christos 	  ans = parse_gen_reg (&str, &r2);
   1084      1.1  christos 	  if (ans < 0)
   1085      1.1  christos 	    {
   1086      1.1  christos 	      as_bad ("SourceB register required");
   1087      1.1  christos 	      return;
   1088      1.1  christos 	    }
   1089      1.1  christos 	  opcode |= (r1 << 16) | (r2 << 4);
   1090      1.1  christos 	}
   1091      1.1  christos       else
   1092      1.1  christos 	{
   1093      1.1  christos 	  as_bad ("SourceB register required");
   1094      1.1  christos 	  return;
   1095      1.1  christos 	}
   1096      1.1  christos       break;
   1097      1.1  christos 
   1098      1.1  christos     case mode_da:
   1099      1.1  christos       /* register := register
   1100      1.1  christos          Example:
   1101      1.1  christos          extb.l  r1,r2  */
   1102      1.1  christos       ans = parse_gen_reg (&str, &r1);
   1103      1.1  christos       if (ans < 0)
   1104      1.1  christos 	{
   1105      1.1  christos 	  as_bad ("Dest register required");
   1106      1.1  christos 	  return;
   1107      1.1  christos 	}
   1108      1.1  christos       str = skip_space (str);
   1109      1.1  christos       if (*str == ',')
   1110      1.1  christos 	{
   1111      1.1  christos 	  str++;
   1112      1.1  christos 	  ans = parse_gen_reg (&str, &r2);
   1113      1.1  christos 	  if (ans < 0)
   1114      1.1  christos 	    {
   1115      1.1  christos 	      as_bad ("SourceA register required");
   1116      1.1  christos 	      return;
   1117      1.1  christos 	    }
   1118      1.1  christos 	  opcode |= (r1 << 10) | (r2 << 16);
   1119      1.1  christos 	}
   1120      1.1  christos       else
   1121      1.1  christos 	{
   1122      1.1  christos 	  as_bad ("SourceB register required");
   1123      1.1  christos 	  return;
   1124      1.1  christos 	}
   1125      1.1  christos       this_dest = r1;
   1126      1.1  christos       break;
   1127      1.1  christos 
   1128      1.1  christos     case mode_dab:
   1129      1.1  christos       /* register := register * register
   1130      1.1  christos          Example:
   1131      1.1  christos          add.l r1,r2,r3  */
   1132      1.1  christos       ans = parse_gen_reg (&str, &r1);
   1133      1.1  christos       if (ans < 0)
   1134      1.1  christos 	{
   1135      1.1  christos 	  as_bad ("Dest register required");
   1136      1.1  christos 	  return;
   1137      1.1  christos 	}
   1138      1.1  christos       str = skip_space (str);
   1139      1.1  christos       if (*str == ',')
   1140      1.1  christos 	{
   1141      1.1  christos 	  str++;
   1142      1.1  christos 	  ans = parse_gen_reg (&str, &r2);
   1143      1.1  christos 	  if (ans < 0)
   1144      1.1  christos 	    {
   1145      1.1  christos 	      as_bad ("SourceA register required");
   1146      1.1  christos 	      return;
   1147      1.1  christos 	    }
   1148      1.1  christos 	  str = skip_space (str);
   1149      1.1  christos 	  if (*str == ',')
   1150      1.1  christos 	    {
   1151      1.1  christos 	      str++;
   1152      1.1  christos 	      ans = parse_gen_reg (&str, &r3);
   1153      1.1  christos 	      if (ans < 0)
   1154      1.1  christos 		{
   1155      1.1  christos 		  as_bad ("SourceB register required");
   1156      1.1  christos 		  return;
   1157      1.1  christos 		}
   1158      1.1  christos 
   1159      1.1  christos 	      /* Got three regs, assemble instruction.  */
   1160      1.1  christos 	      opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
   1161      1.1  christos 	    }
   1162      1.1  christos 	  else
   1163      1.1  christos 	    {
   1164      1.1  christos 	      as_bad ("SourceA register required");
   1165      1.1  christos 	      return;
   1166      1.1  christos 	    }
   1167      1.1  christos 	}
   1168      1.1  christos       else
   1169      1.1  christos 	{
   1170      1.1  christos 	  as_bad ("Dest register required");
   1171      1.1  christos 	  return;
   1172      1.1  christos 	}
   1173      1.1  christos       this_dest = r1;
   1174      1.1  christos       break;
   1175      1.1  christos 
   1176      1.1  christos     case mode_iab:
   1177      1.1  christos       /* 5-bit immediate * register * register
   1178      1.1  christos          Example:
   1179      1.1  christos          eamwrite 3,r1,r2  */
   1180      1.1  christos       str = parse_exp (str, &e1);
   1181      1.1  christos       str = skip_space (str);
   1182      1.1  christos       if (e1.X_op != O_absent && *str == ',')
   1183      1.1  christos 	{
   1184      1.1  christos 	  int eam_op = e1.X_add_number;
   1185      1.1  christos 
   1186      1.1  christos 	  str = skip_space (str + 1);
   1187      1.1  christos 	  ans = parse_gen_reg (&str, &r2);
   1188      1.1  christos 	  if (ans < 0)
   1189      1.1  christos 	    {
   1190      1.1  christos 	      as_bad ("SourceA register required");
   1191      1.1  christos 	      return;
   1192      1.1  christos 	    }
   1193      1.1  christos 	  str = skip_space (str);
   1194      1.1  christos 	  if (*str == ',')
   1195      1.1  christos 	    {
   1196      1.1  christos 	      str++;
   1197      1.1  christos 	      ans = parse_gen_reg (&str, &r3);
   1198      1.1  christos 	      if (ans < 0)
   1199      1.1  christos 		{
   1200      1.1  christos 		  as_bad ("SourceB register required");
   1201      1.1  christos 		  return;
   1202      1.1  christos 		}
   1203      1.1  christos 
   1204      1.1  christos 	      /* Got three operands, assemble instruction.  */
   1205      1.1  christos 	      if (eam_op < 0 || eam_op > 31)
   1206      1.1  christos 		{
   1207      1.1  christos 		  as_bad ("eam_op out of range");
   1208      1.1  christos 		}
   1209      1.1  christos 	      opcode |= ((eam_op & 0x1f) << 10) | (r2 << 16) | (r3 << 4);
   1210      1.1  christos 	    }
   1211      1.1  christos 	}
   1212      1.1  christos       else
   1213      1.1  christos 	{
   1214      1.1  christos 	  as_bad ("EAM_OP required");
   1215      1.1  christos 	  return;
   1216      1.1  christos 	}
   1217      1.1  christos       break;
   1218      1.1  christos 
   1219      1.1  christos     case mode_0ab:
   1220      1.1  christos       /* zero * register * register
   1221      1.1  christos          Example:
   1222      1.1  christos          cmp.l  r1,r2 */
   1223      1.1  christos       ans = parse_gen_reg (&str, &r1);
   1224      1.1  christos       if (ans < 0)
   1225      1.1  christos 	{
   1226      1.1  christos 	  as_bad ("SourceA register required");
   1227      1.1  christos 	  return;
   1228      1.1  christos 	}
   1229      1.1  christos       str = skip_space (str);
   1230      1.1  christos       if (*str == ',')
   1231      1.1  christos 	{
   1232      1.1  christos 	  str++;
   1233      1.1  christos 	  ans = parse_gen_reg (&str, &r2);
   1234      1.1  christos 	  if (ans < 0)
   1235      1.1  christos 	    {
   1236      1.1  christos 	      as_bad ("SourceB register required");
   1237      1.1  christos 	      return;
   1238      1.1  christos 	    }
   1239      1.1  christos 	  opcode |= (r1 << 16) | (r2 << 4);
   1240      1.1  christos 	}
   1241      1.1  christos       else
   1242      1.1  christos 	{
   1243      1.1  christos 	  as_bad ("SourceB register required");
   1244      1.1  christos 	  return;
   1245      1.1  christos 	}
   1246      1.1  christos       break;
   1247      1.1  christos 
   1248      1.1  christos     case mode_da0:
   1249      1.1  christos       /* register * register * zero
   1250      1.1  christos          Example:
   1251      1.1  christos          move.l  r1,r2  */
   1252      1.1  christos       ans = parse_gen_reg (&str, &r1);
   1253      1.1  christos       if (ans < 0)
   1254      1.1  christos 	{
   1255      1.1  christos 	  as_bad ("Dest register required");
   1256      1.1  christos 	  return;
   1257      1.1  christos 	}
   1258      1.1  christos       str = skip_space (str);
   1259      1.1  christos       if (*str == ',')
   1260      1.1  christos 	{
   1261      1.1  christos 	  str++;
   1262      1.1  christos 	  ans = parse_gen_reg (&str, &r2);
   1263      1.1  christos 	  if (ans < 0)
   1264      1.1  christos 	    {
   1265      1.1  christos 	      as_bad ("SourceA register required");
   1266      1.1  christos 	      return;
   1267      1.1  christos 	    }
   1268      1.1  christos 	  opcode |= (r1 << 10) | (r2 << 16);
   1269      1.1  christos 	}
   1270      1.1  christos       else
   1271      1.1  christos 	{
   1272      1.1  christos 	  as_bad ("SourceA register required");
   1273      1.1  christos 	  return;
   1274      1.1  christos 	}
   1275      1.1  christos       this_dest = r1;
   1276      1.1  christos       break;
   1277      1.1  christos 
   1278      1.1  christos     case mode_cad:
   1279      1.1  christos       /* condition * register * register
   1280      1.1  christos          Example:
   1281      1.1  christos          bra  tr,r1,r2  */
   1282      1.1  christos       ans = parse_cc (&str, &cc);
   1283      1.1  christos       if (ans < 0)
   1284      1.1  christos 	{
   1285      1.1  christos 	  as_bad ("condition code required");
   1286      1.1  christos 	  return;
   1287      1.1  christos 	}
   1288      1.1  christos 
   1289      1.1  christos       str = skip_space (str);
   1290      1.1  christos       if (*str == ',')
   1291      1.1  christos 	{
   1292      1.1  christos 	  str = skip_space (str + 1);
   1293      1.1  christos 	  ans = parse_gen_reg (&str, &r2);
   1294      1.1  christos 	  if (ans < 0)
   1295      1.1  christos 	    {
   1296      1.1  christos 	      as_bad ("SourceA register required");
   1297      1.1  christos 	      return;
   1298      1.1  christos 	    }
   1299      1.1  christos 	  str = skip_space (str);
   1300      1.1  christos 	  if (*str == ',')
   1301      1.1  christos 	    {
   1302      1.1  christos 	      str++;
   1303      1.1  christos 	      ans = parse_gen_reg (&str, &r3);
   1304      1.1  christos 	      if (ans < 0)
   1305      1.1  christos 		{
   1306      1.1  christos 		  as_bad ("Dest register required");
   1307      1.1  christos 		  return;
   1308      1.1  christos 		}
   1309      1.1  christos 
   1310      1.1  christos 	      /* Got three operands, assemble instruction.  */
   1311      1.1  christos 	      opcode |= (cc << 27) | (r2 << 16) | (r3 << 10);
   1312      1.1  christos 	    }
   1313      1.1  christos 	  else
   1314      1.1  christos 	    {
   1315      1.1  christos 	      as_bad ("Dest register required");
   1316      1.1  christos 	      return;
   1317      1.1  christos 	    }
   1318      1.1  christos 	}
   1319      1.1  christos       else
   1320      1.1  christos 	{
   1321      1.1  christos 	  as_bad ("SourceA register required");
   1322      1.1  christos 	  return;
   1323      1.1  christos 	}
   1324      1.1  christos 
   1325      1.1  christos       if (previous_mode == mode_cad || previous_mode == mode_ci)
   1326      1.1  christos 	as_bad ("branch instruction in delay slot");
   1327      1.1  christos 
   1328  1.1.1.4  christos       /* For the GR6, BRA insns must be aligned on 64-bit boundaries.  */
   1329  1.1.1.4  christos       if (visium_arch == VISIUM_ARCH_GR6)
   1330  1.1.1.4  christos 	do_align (3, NULL, 0, 0);
   1331  1.1.1.4  christos 
   1332      1.1  christos       this_dest = r3;
   1333      1.1  christos       condition_code = cc;
   1334      1.1  christos       break;
   1335      1.1  christos 
   1336      1.1  christos     case mode_das:
   1337  1.1.1.3  christos       /* register := register * 5-bit immediate/register shift count
   1338      1.1  christos          Example:
   1339      1.1  christos          asl.l  r1,r2,4  */
   1340      1.1  christos       ans = parse_gen_reg (&str, &r1);
   1341      1.1  christos       if (ans < 0)
   1342      1.1  christos 	{
   1343      1.1  christos 	  as_bad ("Dest register required");
   1344      1.1  christos 	  return;
   1345      1.1  christos 	}
   1346      1.1  christos       str = skip_space (str);
   1347      1.1  christos       if (*str == ',')
   1348      1.1  christos 	{
   1349      1.1  christos 	  str++;
   1350      1.1  christos 	  ans = parse_gen_reg (&str, &r2);
   1351      1.1  christos 	  if (ans < 0)
   1352      1.1  christos 	    {
   1353      1.1  christos 	      as_bad ("SourceA register required");
   1354      1.1  christos 	      return;
   1355      1.1  christos 	    }
   1356      1.1  christos 	  str = skip_space (str);
   1357      1.1  christos 	  if (*str == ',')
   1358      1.1  christos 	    {
   1359      1.1  christos 	      str++;
   1360      1.1  christos 	      ans = parse_gen_reg (&str, &r3);
   1361      1.1  christos 	      if (ans == 0)
   1362      1.1  christos 		{
   1363      1.1  christos 		  opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
   1364      1.1  christos 		}
   1365      1.1  christos 	      else
   1366      1.1  christos 		{
   1367      1.1  christos 		  str = parse_exp (str, &e1);
   1368      1.1  christos 		  if (e1.X_op == O_constant)
   1369      1.1  christos 		    {
   1370      1.1  christos 		      int imm = e1.X_add_number;
   1371      1.1  christos 
   1372      1.1  christos 		      if (imm < 0 || imm > 31)
   1373      1.1  christos 			as_bad ("immediate value out of range");
   1374      1.1  christos 
   1375  1.1.1.7  christos 		      opcode |= ((r1 << 10) | (r2 << 16) | (1 << 9)
   1376  1.1.1.7  christos 				 | ((imm & 0x1f) << 4));
   1377      1.1  christos 		    }
   1378      1.1  christos 		  else
   1379      1.1  christos 		    {
   1380      1.1  christos 		      as_bad ("immediate operand required");
   1381      1.1  christos 		      return;
   1382      1.1  christos 		    }
   1383      1.1  christos 		}
   1384      1.1  christos 	    }
   1385      1.1  christos 	}
   1386      1.1  christos       else
   1387      1.1  christos 	{
   1388      1.1  christos 	  as_bad ("SourceA register required");
   1389      1.1  christos 	  return;
   1390      1.1  christos 	}
   1391      1.1  christos       this_dest = r1;
   1392      1.1  christos       break;
   1393      1.1  christos 
   1394      1.1  christos     case mode_di:
   1395      1.1  christos       /* register := 5-bit immediate
   1396      1.1  christos          Example:
   1397      1.1  christos          eamread r1,3  */
   1398      1.1  christos       ans = parse_gen_reg (&str, &r1);
   1399      1.1  christos       if (ans < 0)
   1400      1.1  christos 	{
   1401      1.1  christos 	  as_bad ("Dest register required");
   1402      1.1  christos 	  return;
   1403      1.1  christos 	}
   1404      1.1  christos       str = skip_space (str);
   1405      1.1  christos       if (*str == ',')
   1406      1.1  christos 	{
   1407      1.1  christos 	  str++;
   1408      1.1  christos 	  str = parse_exp (str, &e1);
   1409      1.1  christos 	  if (e1.X_op == O_constant)
   1410      1.1  christos 	    {
   1411      1.1  christos 	      int opnd2 = e1.X_add_number;
   1412      1.1  christos 
   1413      1.1  christos 	      if (opnd2 < 0 || opnd2 > 31)
   1414      1.1  christos 		{
   1415      1.1  christos 		  as_bad ("immediate operand out of range");
   1416      1.1  christos 		  return;
   1417      1.1  christos 		}
   1418      1.1  christos 	      opcode |= (r1 << 10) | ((opnd2 & 0x1f) << 4);
   1419      1.1  christos 	    }
   1420      1.1  christos 	  else
   1421      1.1  christos 	    {
   1422      1.1  christos 	      as_bad ("immediate operand required");
   1423      1.1  christos 	      return;
   1424      1.1  christos 	    }
   1425      1.1  christos 	}
   1426      1.1  christos       else
   1427      1.1  christos 	{
   1428      1.1  christos 	  as_bad ("immediate operand required");
   1429      1.1  christos 	  return;
   1430      1.1  christos 	}
   1431      1.1  christos       this_dest = r1;
   1432      1.1  christos       break;
   1433      1.1  christos 
   1434      1.1  christos     case mode_ir:
   1435      1.1  christos       /* 5-bit immediate * register, e.g. trace 1,r1  */
   1436      1.1  christos       str = parse_exp (str, &e1);
   1437      1.1  christos       str = skip_space (str);
   1438      1.1  christos       if (e1.X_op == O_constant && *str == ',')
   1439      1.1  christos 	{
   1440      1.1  christos 	  int opnd1 = e1.X_add_number;
   1441      1.1  christos 
   1442      1.1  christos 	  str = skip_space (str + 1);
   1443      1.1  christos 	  ans = parse_gen_reg (&str, &r2);
   1444      1.1  christos 	  if (ans < 0)
   1445      1.1  christos 	    {
   1446      1.1  christos 	      as_bad ("SourceA register required");
   1447      1.1  christos 	      return;
   1448      1.1  christos 	    }
   1449      1.1  christos 
   1450      1.1  christos 	  /* Got two operands, assemble instruction.  */
   1451      1.1  christos 	  if (opnd1 < 0 || opnd1 > 31)
   1452      1.1  christos 	    {
   1453      1.1  christos 	      as_bad ("1st operand out of range");
   1454      1.1  christos 	    }
   1455      1.1  christos 	  opcode |= ((opnd1 & 0x1f) << 10) | (r2 << 16);
   1456      1.1  christos 	}
   1457      1.1  christos       else
   1458      1.1  christos 	{
   1459      1.1  christos 	  as_bad ("Immediate operand required");
   1460      1.1  christos 	  return;
   1461      1.1  christos 	}
   1462      1.1  christos       break;
   1463      1.1  christos 
   1464      1.1  christos     case mode_ai:
   1465      1.1  christos       /* register *= 16-bit unsigned immediate
   1466      1.1  christos          Example:
   1467      1.1  christos          addi  r1,123  */
   1468      1.1  christos       ans = parse_gen_reg (&str, &r1);
   1469      1.1  christos       if (ans < 0)
   1470      1.1  christos 	{
   1471      1.1  christos 	  as_bad ("Dest register required");
   1472      1.1  christos 	  return;
   1473      1.1  christos 	}
   1474      1.1  christos       opcode |= (r1 << 16);
   1475      1.1  christos 
   1476      1.1  christos       str = skip_space (str);
   1477      1.1  christos       if (*str != ',')
   1478      1.1  christos 	{
   1479      1.1  christos 	  as_bad ("immediate value missing");
   1480      1.1  christos 	  return;
   1481      1.1  christos 	}
   1482      1.1  christos       this_dest = r1;
   1483  1.1.1.3  christos       /* Fall through.  */
   1484      1.1  christos 
   1485      1.1  christos     case mode_i:
   1486      1.1  christos       /* MOVIL/WRTL traditionally get an implicit "%l" applied
   1487      1.1  christos 	 to their immediate value.  For other opcodes, unless
   1488      1.1  christos 	 the immediate value is decorated with "%u" or "%l"
   1489      1.1  christos 	 it must be in the range 0 .. 65535.  */
   1490      1.1  christos       if ((opcode & 0x7fe00000) == 0x04800000
   1491      1.1  christos 	  || (opcode & 0x7fe00000) == 0x05000000)
   1492      1.1  christos 	reloc = BFD_RELOC_VISIUM_LO16;
   1493      1.1  christos       else
   1494      1.1  christos 	reloc = BFD_RELOC_VISIUM_IM16;
   1495      1.1  christos 
   1496      1.1  christos       str = skip_space (str + 1);
   1497      1.1  christos 
   1498      1.1  christos       if (*str == '%')
   1499      1.1  christos 	{
   1500      1.1  christos 	  if (str[1] == 'u')
   1501      1.1  christos 	    reloc = BFD_RELOC_VISIUM_HI16;
   1502      1.1  christos 	  else if (str[1] == 'l')
   1503      1.1  christos 	    reloc = BFD_RELOC_VISIUM_LO16;
   1504      1.1  christos 	  else
   1505      1.1  christos 	    {
   1506      1.1  christos 	      as_bad ("bad char after %%");
   1507      1.1  christos 	      return;
   1508      1.1  christos 	    }
   1509      1.1  christos 
   1510      1.1  christos 	  str += 2;
   1511      1.1  christos 	}
   1512      1.1  christos       str = parse_exp (str, &e1);
   1513      1.1  christos       if (e1.X_op != O_absent)
   1514      1.1  christos 	{
   1515      1.1  christos 	  if (e1.X_op == O_constant)
   1516      1.1  christos 	    {
   1517      1.1  christos 	      int imm = e1.X_add_number;
   1518      1.1  christos 
   1519      1.1  christos 	      if (reloc == BFD_RELOC_VISIUM_HI16)
   1520      1.1  christos 		opcode |= ((imm >> 16) & 0xffff);
   1521      1.1  christos 	      else if (reloc == BFD_RELOC_VISIUM_LO16)
   1522      1.1  christos 		opcode |= (imm & 0xffff);
   1523      1.1  christos 	      else
   1524      1.1  christos 		{
   1525      1.1  christos 		  if (imm < 0 || imm > 0xffff)
   1526      1.1  christos 		    as_bad ("immediate value out of range");
   1527      1.1  christos 
   1528      1.1  christos 		  opcode |= (imm & 0xffff);
   1529      1.1  christos 		}
   1530      1.1  christos 	      /* No relocation is needed.  */
   1531      1.1  christos 	      reloc = 0;
   1532      1.1  christos 	    }
   1533      1.1  christos 	}
   1534      1.1  christos       else
   1535      1.1  christos 	{
   1536      1.1  christos 	  as_bad ("immediate value missing");
   1537      1.1  christos 	  return;
   1538      1.1  christos 	}
   1539      1.1  christos       break;
   1540      1.1  christos 
   1541      1.1  christos     case mode_bax:
   1542      1.1  christos       /* register * register * 5-bit immediate,
   1543      1.1  christos          SourceB * SourceA * Index
   1544      1.1  christos          Examples
   1545      1.1  christos          write.l (r1),r2
   1546      1.1  christos          write.l 3(r1),r2  */
   1547      1.1  christos       str = skip_space (str);
   1548      1.1  christos 
   1549      1.1  christos       indx = 0;
   1550      1.1  christos       if (*str != '(')
   1551      1.1  christos 	{
   1552      1.1  christos 	  str = parse_exp (str, &e1);
   1553      1.1  christos 	  if (e1.X_op == O_constant)
   1554      1.1  christos 	    {
   1555      1.1  christos 	      indx = e1.X_add_number;
   1556      1.1  christos 
   1557      1.1  christos 	      if (indx < 0 || indx > 31)
   1558      1.1  christos 		{
   1559      1.1  christos 		  as_bad ("Index out of range");
   1560      1.1  christos 		  return;
   1561      1.1  christos 		}
   1562      1.1  christos 	    }
   1563      1.1  christos 	  else
   1564      1.1  christos 	    {
   1565      1.1  christos 	      as_bad ("Index(SourceA) required");
   1566      1.1  christos 	      return;
   1567      1.1  christos 	    }
   1568      1.1  christos 	}
   1569      1.1  christos 
   1570      1.1  christos       str = skip_space (str);
   1571      1.1  christos 
   1572      1.1  christos       if (*str != '(')
   1573      1.1  christos 	{
   1574      1.1  christos 	  as_bad ("Index(SourceA) required");
   1575      1.1  christos 	  return;
   1576      1.1  christos 	}
   1577      1.1  christos 
   1578      1.1  christos       str = skip_space (str + 1);
   1579      1.1  christos 
   1580      1.1  christos       ans = parse_gen_reg (&str, &r1);
   1581      1.1  christos       if (ans < 0)
   1582      1.1  christos 	{
   1583      1.1  christos 	  as_bad ("SourceA register required");
   1584      1.1  christos 	  return;
   1585      1.1  christos 	}
   1586      1.1  christos       str = skip_space (str);
   1587      1.1  christos       if (*str != ')')
   1588      1.1  christos 	{
   1589      1.1  christos 	  as_bad ("(SourceA) required");
   1590      1.1  christos 	  return;
   1591      1.1  christos 	}
   1592      1.1  christos       str = skip_space (str + 1);
   1593      1.1  christos 
   1594      1.1  christos       if (*str == ',')
   1595      1.1  christos 	{
   1596      1.1  christos 	  str = skip_space (str + 1);
   1597      1.1  christos 	  ans = parse_gen_reg (&str, &r2);
   1598      1.1  christos 	  if (ans < 0)
   1599      1.1  christos 	    {
   1600      1.1  christos 	      as_bad ("SourceB register required");
   1601      1.1  christos 	      return;
   1602      1.1  christos 	    }
   1603      1.1  christos 	}
   1604      1.1  christos       else
   1605      1.1  christos 	{
   1606      1.1  christos 	  as_bad ("SourceB register required");
   1607      1.1  christos 	  return;
   1608      1.1  christos 	}
   1609      1.1  christos 
   1610      1.1  christos       opcode |= (r1 << 16) | (r2 << 4) | ((indx & 0x1f) << 10);
   1611      1.1  christos 
   1612      1.1  christos       if (indx != 0 && previous_mode == mode_cad)
   1613      1.1  christos 	{
   1614      1.1  christos 	  /* We're in a delay slot.
   1615      1.1  christos 	     If the base reg is the destination of the branch, then issue
   1616      1.1  christos 	     an error message.
   1617      1.1  christos 	     Otherwise it is safe to use the base and index.  */
   1618      1.1  christos 	  if (previous_dest != 0 && r1 == previous_dest)
   1619      1.1  christos 	    {
   1620      1.1  christos 	      as_bad ("base register not ready");
   1621      1.1  christos 	      return;
   1622      1.1  christos 	    }
   1623      1.1  christos 	}
   1624      1.1  christos       else if (previous_dest != 0
   1625      1.1  christos 	       && r1 == previous_dest
   1626      1.1  christos 	       && (visium_arch == VISIUM_ARCH_MCM
   1627      1.1  christos 		   || visium_arch == VISIUM_ARCH_MCM24
   1628      1.1  christos 		   || (visium_arch == VISIUM_ARCH_DEF && indx != 0)))
   1629      1.1  christos 	{
   1630      1.1  christos 	  as_warn ("base register not ready, NOP inserted.");
   1631      1.1  christos 	  /* Insert a NOP before the write instruction.  */
   1632      1.1  christos 	  output = frag_more (4);
   1633      1.1  christos 	  memset (output, 0, 4);
   1634      1.1  christos 	}
   1635      1.1  christos       break;
   1636      1.1  christos 
   1637      1.1  christos     case mode_dax:
   1638      1.1  christos       /*  register := register * 5-bit immediate
   1639      1.1  christos          Examples:
   1640      1.1  christos          read.b  r1,(r2)
   1641      1.1  christos          read.w  r1,3(r2)  */
   1642      1.1  christos       ans = parse_gen_reg (&str, &r1);
   1643      1.1  christos       if (ans < 0)
   1644      1.1  christos 	{
   1645      1.1  christos 	  as_bad ("Dest register required");
   1646      1.1  christos 	  return;
   1647      1.1  christos 	}
   1648      1.1  christos       str = skip_space (str);
   1649      1.1  christos       if (*str != ',')
   1650      1.1  christos 	{
   1651      1.1  christos 	  as_bad ("SourceA required");
   1652      1.1  christos 	  return;
   1653      1.1  christos 	}
   1654      1.1  christos       str = skip_space (str + 1);
   1655      1.1  christos 
   1656      1.1  christos       indx = 0;
   1657      1.1  christos       if (*str != '(')
   1658      1.1  christos 	{
   1659      1.1  christos 	  str = parse_exp (str, &e1);
   1660      1.1  christos 	  if (e1.X_op == O_constant)
   1661      1.1  christos 	    {
   1662      1.1  christos 	      indx = e1.X_add_number;
   1663      1.1  christos 
   1664      1.1  christos 	      if (indx < 0 || indx > 31)
   1665      1.1  christos 		{
   1666      1.1  christos 		  as_bad ("Index out of range");
   1667      1.1  christos 		  return;
   1668      1.1  christos 		}
   1669      1.1  christos 	    }
   1670      1.1  christos 	  else
   1671      1.1  christos 	    {
   1672      1.1  christos 	      as_bad ("Immediate 0 to 31 required");
   1673      1.1  christos 	      return;
   1674      1.1  christos 	    }
   1675      1.1  christos 	}
   1676      1.1  christos       if (*str != '(')
   1677      1.1  christos 	{
   1678      1.1  christos 	  as_bad ("(SourceA) required");
   1679      1.1  christos 	  return;
   1680      1.1  christos 	}
   1681      1.1  christos       str++;
   1682      1.1  christos       ans = parse_gen_reg (&str, &r2);
   1683      1.1  christos       if (ans < 0)
   1684      1.1  christos 	{
   1685      1.1  christos 	  as_bad ("SourceA register required");
   1686      1.1  christos 	  return;
   1687      1.1  christos 	}
   1688      1.1  christos       str = skip_space (str);
   1689      1.1  christos       if (*str != ')')
   1690      1.1  christos 	{
   1691      1.1  christos 	  as_bad ("(SourceA) required");
   1692      1.1  christos 	  return;
   1693      1.1  christos 	}
   1694      1.1  christos       str++;
   1695      1.1  christos       opcode |= (r1 << 10) | (r2 << 16) | ((indx & 0x1f) << 4);
   1696      1.1  christos       this_dest = r1;
   1697      1.1  christos 
   1698      1.1  christos       if (indx != 0 && previous_mode == mode_cad)
   1699      1.1  christos 	{
   1700      1.1  christos 	  /* We're in a delay slot.
   1701      1.1  christos 	     If the base reg is the destination of the branch, then issue
   1702      1.1  christos 	     an error message.
   1703      1.1  christos 	     Otherwise it is safe to use the base and index.  */
   1704      1.1  christos 	  if (previous_dest != 0 && r2 == previous_dest)
   1705      1.1  christos 	    {
   1706      1.1  christos 	      as_bad ("base register not ready");
   1707      1.1  christos 	      return;
   1708      1.1  christos 	    }
   1709      1.1  christos 	}
   1710      1.1  christos       else if (previous_dest != 0
   1711      1.1  christos 	       && r2 == previous_dest
   1712      1.1  christos 	       && (visium_arch == VISIUM_ARCH_MCM
   1713      1.1  christos 		   || visium_arch == VISIUM_ARCH_MCM24
   1714      1.1  christos 		   || (visium_arch == VISIUM_ARCH_DEF && indx != 0)))
   1715      1.1  christos 	{
   1716      1.1  christos 	  as_warn ("base register not ready, NOP inserted.");
   1717      1.1  christos 	  /* Insert a NOP before the read instruction.  */
   1718      1.1  christos 	  output = frag_more (4);
   1719      1.1  christos 	  memset (output, 0, 4);
   1720      1.1  christos 	}
   1721      1.1  christos       break;
   1722      1.1  christos 
   1723      1.1  christos     case mode_s:
   1724      1.1  christos       /* special mode
   1725      1.1  christos          Example:
   1726      1.1  christos          nop  */
   1727      1.1  christos       str = skip_space (str);
   1728      1.1  christos       break;
   1729      1.1  christos 
   1730      1.1  christos     case mode_ci:
   1731      1.1  christos       /* condition * 16-bit signed word displacement
   1732      1.1  christos          Example:
   1733      1.1  christos          brr L1  */
   1734      1.1  christos       ans = parse_cc (&str, &cc);
   1735      1.1  christos       if (ans < 0)
   1736      1.1  christos 	{
   1737      1.1  christos 	  as_bad ("condition code required");
   1738      1.1  christos 	  return;
   1739      1.1  christos 	}
   1740      1.1  christos       opcode |= (cc << 27);
   1741      1.1  christos 
   1742      1.1  christos       str = skip_space (str);
   1743      1.1  christos       if (*str == ',')
   1744      1.1  christos 	{
   1745      1.1  christos 	  str = skip_space (str + 1);
   1746      1.1  christos 	  str = parse_exp (str, &e1);
   1747      1.1  christos 	  if (e1.X_op != O_absent)
   1748      1.1  christos 	    {
   1749      1.1  christos 	      if (e1.X_op == O_constant)
   1750      1.1  christos 		{
   1751      1.1  christos 		  int imm = e1.X_add_number;
   1752      1.1  christos 
   1753      1.1  christos 		  if (imm < -32768 || imm > 32767)
   1754      1.1  christos 		    as_bad ("immediate value out of range");
   1755      1.1  christos 
   1756      1.1  christos 		  /* The GR6 doesn't correctly handle a 0 displacement
   1757      1.1  christos 		     so we insert a NOP and change it to -1.  */
   1758      1.1  christos 		  if (imm == 0 && cc != 0 && visium_arch == VISIUM_ARCH_GR6)
   1759      1.1  christos 		    {
   1760      1.1  christos 		      output = frag_more (4);
   1761      1.1  christos 		      memset (output, 0, 4);
   1762      1.1  christos 		      imm = -1;
   1763      1.1  christos 		    }
   1764      1.1  christos 
   1765      1.1  christos 		  opcode |= (imm & 0xffff);
   1766      1.1  christos 		}
   1767      1.1  christos 	      else if (e1.X_op == O_symbol)
   1768      1.1  christos 		{
   1769      1.1  christos 		  /* The GR6 doesn't correctly handle a 0 displacement
   1770      1.1  christos 		     so the instruction requires relaxation.  */
   1771      1.1  christos 		  if (cc != 0 && visium_arch == VISIUM_ARCH_GR6)
   1772      1.1  christos 		    relax = amode;
   1773      1.1  christos 		  else
   1774      1.1  christos 		    reloc = BFD_RELOC_VISIUM_REL16;
   1775      1.1  christos 		}
   1776      1.1  christos 	      else
   1777      1.1  christos 		{
   1778      1.1  christos 		  as_bad ("immediate value missing");
   1779      1.1  christos 		  return;
   1780      1.1  christos 		}
   1781      1.1  christos 	    }
   1782      1.1  christos 	  else
   1783      1.1  christos 	    {
   1784      1.1  christos 	      as_bad ("immediate value missing");
   1785      1.1  christos 	      return;
   1786      1.1  christos 	    }
   1787      1.1  christos 	}
   1788      1.1  christos       else
   1789      1.1  christos 	{
   1790      1.1  christos 	  as_bad ("immediate value missing");
   1791      1.1  christos 	  return;
   1792      1.1  christos 	}
   1793      1.1  christos 
   1794      1.1  christos       if (previous_mode == mode_cad || previous_mode == mode_ci)
   1795      1.1  christos 	as_bad ("branch instruction in delay slot");
   1796      1.1  christos 
   1797      1.1  christos       condition_code = cc;
   1798      1.1  christos       break;
   1799      1.1  christos 
   1800      1.1  christos     case mode_fdab:
   1801      1.1  christos       /* float := float * float
   1802      1.1  christos          Example
   1803      1.1  christos          fadd    f4,f3,f2  */
   1804      1.1  christos       ans = parse_fp_reg (&str, &r1);
   1805      1.1  christos       if (ans < 0)
   1806      1.1  christos 	{
   1807      1.1  christos 	  as_bad ("floating point destination register required");
   1808      1.1  christos 	  return;
   1809      1.1  christos 	}
   1810      1.1  christos       str = skip_space (str);
   1811      1.1  christos       if (*str == ',')
   1812      1.1  christos 	{
   1813      1.1  christos 	  str++;
   1814      1.1  christos 	  ans = parse_fp_reg (&str, &r2);
   1815      1.1  christos 	  if (ans < 0)
   1816      1.1  christos 	    {
   1817      1.1  christos 	      as_bad ("floating point SourceA register required");
   1818      1.1  christos 	      return;
   1819      1.1  christos 	    }
   1820      1.1  christos 	  str = skip_space (str);
   1821      1.1  christos 	  if (*str == ',')
   1822      1.1  christos 	    {
   1823      1.1  christos 	      str++;
   1824      1.1  christos 	      ans = parse_fp_reg (&str, &r3);
   1825      1.1  christos 	      if (ans < 0)
   1826      1.1  christos 		{
   1827      1.1  christos 		  as_bad ("floating point SourceB register required");
   1828      1.1  christos 		  return;
   1829      1.1  christos 		}
   1830      1.1  christos 
   1831      1.1  christos 	      /* Got 3 floating regs, assemble instruction.  */
   1832      1.1  christos 	      opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
   1833      1.1  christos 	    }
   1834      1.1  christos 	  else
   1835      1.1  christos 	    {
   1836      1.1  christos 	      as_bad ("floating point SourceB register required");
   1837      1.1  christos 	      return;
   1838      1.1  christos 	    }
   1839      1.1  christos 	}
   1840      1.1  christos       else
   1841      1.1  christos 	{
   1842      1.1  christos 	  as_bad ("floating point SourceA register required");
   1843      1.1  christos 	  return;
   1844      1.1  christos 	}
   1845      1.1  christos       break;
   1846      1.1  christos 
   1847      1.1  christos     case mode_ifdab:
   1848      1.1  christos       /* 4-bit immediate * float * float * float
   1849      1.1  christos          Example
   1850      1.1  christos          fpinst   10,f1,f2,f3  */
   1851      1.1  christos       str = parse_exp (str, &e1);
   1852      1.1  christos       str = skip_space (str);
   1853      1.1  christos       if (e1.X_op != O_absent && *str == ',')
   1854      1.1  christos 	{
   1855      1.1  christos 	  int finst = e1.X_add_number;
   1856      1.1  christos 
   1857      1.1  christos 	  str = skip_space (str + 1);
   1858      1.1  christos 	  ans = parse_fp_reg (&str, &r1);
   1859      1.1  christos 	  if (ans < 0)
   1860      1.1  christos 	    {
   1861      1.1  christos 	      as_bad ("floating point destination register required");
   1862      1.1  christos 	      return;
   1863      1.1  christos 	    }
   1864      1.1  christos 	  str = skip_space (str);
   1865      1.1  christos 	  if (*str == ',')
   1866      1.1  christos 	    {
   1867      1.1  christos 	      str++;
   1868      1.1  christos 	      ans = parse_fp_reg (&str, &r2);
   1869      1.1  christos 	      if (ans < 0)
   1870      1.1  christos 		{
   1871      1.1  christos 		  as_bad ("floating point SourceA register required");
   1872      1.1  christos 		  return;
   1873      1.1  christos 		}
   1874      1.1  christos 	      str = skip_space (str);
   1875      1.1  christos 	      if (*str == ',')
   1876      1.1  christos 		{
   1877      1.1  christos 		  str++;
   1878      1.1  christos 		  ans = parse_fp_reg (&str, &r3);
   1879      1.1  christos 		  if (ans < 0)
   1880      1.1  christos 		    {
   1881      1.1  christos 		      as_bad ("floating point SourceB register required");
   1882      1.1  christos 		      return;
   1883      1.1  christos 		    }
   1884      1.1  christos 
   1885      1.1  christos 		  /* Got immediate and 3 floating regs,
   1886      1.1  christos 		     assemble instruction.  */
   1887      1.1  christos 		  if (finst < 0 || finst > 15)
   1888      1.1  christos 		    as_bad ("finst out of range");
   1889      1.1  christos 
   1890  1.1.1.7  christos 		  opcode |= (((finst & 0xf) << 27)
   1891  1.1.1.7  christos 			     | (r1 << 10) | (r2 << 16) | (r3 << 4));
   1892      1.1  christos 		}
   1893      1.1  christos 	      else
   1894      1.1  christos 		{
   1895      1.1  christos 		  as_bad ("floating point SourceB register required");
   1896      1.1  christos 		  return;
   1897      1.1  christos 		}
   1898      1.1  christos 	    }
   1899      1.1  christos 	  else
   1900      1.1  christos 	    {
   1901      1.1  christos 	      as_bad ("floating point SourceA register required");
   1902      1.1  christos 	      return;
   1903      1.1  christos 	    }
   1904      1.1  christos 	}
   1905      1.1  christos       else
   1906      1.1  christos 	{
   1907      1.1  christos 	  as_bad ("finst missing");
   1908      1.1  christos 	  return;
   1909      1.1  christos 	}
   1910      1.1  christos       break;
   1911      1.1  christos 
   1912      1.1  christos     case mode_idfab:
   1913      1.1  christos       /* 4-bit immediate * register * float * float
   1914      1.1  christos          Example
   1915      1.1  christos          fpuread   4,r25,f2,f3  */
   1916      1.1  christos       str = parse_exp (str, &e1);
   1917      1.1  christos       str = skip_space (str);
   1918      1.1  christos       if (e1.X_op != O_absent && *str == ',')
   1919      1.1  christos 	{
   1920      1.1  christos 	  int finst = e1.X_add_number;
   1921      1.1  christos 
   1922      1.1  christos 	  str = skip_space (str + 1);
   1923      1.1  christos 	  ans = parse_gen_reg (&str, &r1);
   1924      1.1  christos 	  if (ans < 0)
   1925      1.1  christos 	    {
   1926      1.1  christos 	      as_bad ("destination general register required");
   1927      1.1  christos 	      return;
   1928      1.1  christos 	    }
   1929      1.1  christos 	  str = skip_space (str);
   1930      1.1  christos 	  if (*str == ',')
   1931      1.1  christos 	    {
   1932      1.1  christos 	      str++;
   1933      1.1  christos 	      ans = parse_fp_reg (&str, &r2);
   1934      1.1  christos 	      if (ans < 0)
   1935      1.1  christos 		{
   1936      1.1  christos 		  as_bad ("floating point SourceA register required");
   1937      1.1  christos 		  return;
   1938      1.1  christos 		}
   1939      1.1  christos 	      str = skip_space (str);
   1940      1.1  christos 	      if (*str == ',')
   1941      1.1  christos 		{
   1942      1.1  christos 		  str++;
   1943      1.1  christos 		  ans = parse_fp_reg (&str, &r3);
   1944      1.1  christos 		  if (ans < 0)
   1945      1.1  christos 		    {
   1946      1.1  christos 		      as_bad ("floating point SourceB register required");
   1947      1.1  christos 		      return;
   1948      1.1  christos 		    }
   1949      1.1  christos 
   1950      1.1  christos 		  /* Got immediate and 3 floating regs,
   1951      1.1  christos 		     assemble instruction.  */
   1952      1.1  christos 		  if (finst < 0 || finst > 15)
   1953      1.1  christos 		    as_bad ("finst out of range");
   1954      1.1  christos 
   1955  1.1.1.7  christos 		  opcode |= (((finst & 0xf) << 27)
   1956  1.1.1.7  christos 			     | (r1 << 10) | (r2 << 16) | (r3 << 4));
   1957      1.1  christos 		}
   1958      1.1  christos 	      else
   1959      1.1  christos 		{
   1960      1.1  christos 		  as_bad ("floating point SourceB register required");
   1961      1.1  christos 		  return;
   1962      1.1  christos 		}
   1963      1.1  christos 	    }
   1964      1.1  christos 	  else
   1965      1.1  christos 	    {
   1966      1.1  christos 	      as_bad ("floating point SourceA register required");
   1967      1.1  christos 	      return;
   1968      1.1  christos 	    }
   1969      1.1  christos 	}
   1970      1.1  christos       else
   1971      1.1  christos 	{
   1972      1.1  christos 	  as_bad ("finst missing");
   1973      1.1  christos 	  return;
   1974      1.1  christos 	}
   1975      1.1  christos       break;
   1976      1.1  christos 
   1977      1.1  christos     case mode_fda:
   1978      1.1  christos       /* float := float
   1979      1.1  christos          Example
   1980      1.1  christos          fsqrt    f4,f3  */
   1981      1.1  christos       ans = parse_fp_reg (&str, &r1);
   1982      1.1  christos       if (ans < 0)
   1983      1.1  christos 	{
   1984      1.1  christos 	  as_bad ("floating point destination register required");
   1985      1.1  christos 	  return;
   1986      1.1  christos 	}
   1987      1.1  christos       str = skip_space (str);
   1988      1.1  christos       if (*str == ',')
   1989      1.1  christos 	{
   1990      1.1  christos 	  str++;
   1991      1.1  christos 	  ans = parse_fp_reg (&str, &r2);
   1992      1.1  christos 	  if (ans < 0)
   1993      1.1  christos 	    {
   1994      1.1  christos 	      as_bad ("floating point source register required");
   1995      1.1  christos 	      return;
   1996      1.1  christos 	    }
   1997      1.1  christos 
   1998      1.1  christos 	  /* Got 2 floating regs, assemble instruction.  */
   1999      1.1  christos 	  opcode |= (r1 << 10) | (r2 << 16);
   2000      1.1  christos 	}
   2001      1.1  christos       else
   2002      1.1  christos 	{
   2003      1.1  christos 	  as_bad ("floating point source register required");
   2004      1.1  christos 	  return;
   2005      1.1  christos 	}
   2006      1.1  christos       break;
   2007      1.1  christos 
   2008      1.1  christos     case mode_fdra:
   2009      1.1  christos       /* float := register
   2010      1.1  christos          Example
   2011      1.1  christos          fload   f15,r6  */
   2012      1.1  christos       ans = parse_fp_reg (&str, &r1);
   2013      1.1  christos       if (ans < 0)
   2014      1.1  christos 	{
   2015      1.1  christos 	  as_bad ("floating point destination register required");
   2016      1.1  christos 	  return;
   2017      1.1  christos 	}
   2018      1.1  christos       str = skip_space (str);
   2019      1.1  christos       if (*str == ',')
   2020      1.1  christos 	{
   2021      1.1  christos 	  str++;
   2022      1.1  christos 	  ans = parse_gen_reg (&str, &r2);
   2023      1.1  christos 	  if (ans < 0)
   2024      1.1  christos 	    {
   2025      1.1  christos 	      as_bad ("SourceA general register required");
   2026      1.1  christos 	      return;
   2027      1.1  christos 	    }
   2028      1.1  christos 
   2029      1.1  christos 	  /* Got 2 regs, assemble instruction.  */
   2030      1.1  christos 	  opcode |= (r1 << 10) | (r2 << 16);
   2031      1.1  christos 	}
   2032      1.1  christos       else
   2033      1.1  christos 	{
   2034      1.1  christos 	  as_bad ("SourceA general register required");
   2035      1.1  christos 	  return;
   2036      1.1  christos 	}
   2037      1.1  christos       break;
   2038      1.1  christos 
   2039      1.1  christos     case mode_rdfab:
   2040      1.1  christos       /* register := float * float
   2041      1.1  christos          Example
   2042      1.1  christos          fcmp    r0,f4,f8
   2043      1.1  christos          For the GR6, register must be r0 and can be omitted.  */
   2044      1.1  christos       ans = parse_gen_reg (&str, &r1);
   2045      1.1  christos       if (ans < 0)
   2046      1.1  christos 	{
   2047      1.1  christos 	  if (visium_opcode_arch == VISIUM_OPCODE_ARCH_GR5)
   2048      1.1  christos 	    {
   2049      1.1  christos 	      as_bad ("Dest general register required");
   2050      1.1  christos 	      return;
   2051      1.1  christos 	    }
   2052      1.1  christos 	  r1 = 0;
   2053      1.1  christos 	}
   2054      1.1  christos       else
   2055      1.1  christos 	{
   2056      1.1  christos 	  if (r1 != 0 && visium_opcode_arch != VISIUM_OPCODE_ARCH_GR5)
   2057      1.1  christos 	    {
   2058      1.1  christos 	      as_bad ("FCMP/FCMPE can only use r0 as Dest register");
   2059      1.1  christos 	      return;
   2060      1.1  christos 	     }
   2061      1.1  christos 
   2062      1.1  christos 	  str = skip_space (str);
   2063      1.1  christos 	  if (*str == ',')
   2064      1.1  christos 	    str++;
   2065      1.1  christos 	  else
   2066      1.1  christos 	    {
   2067      1.1  christos 	      as_bad ("floating point SourceA register required");
   2068      1.1  christos 	      return;
   2069      1.1  christos 	    }
   2070      1.1  christos 	}
   2071      1.1  christos 
   2072      1.1  christos       ans = parse_fp_reg (&str, &r2);
   2073      1.1  christos       if (ans < 0)
   2074      1.1  christos 	{
   2075      1.1  christos 	  as_bad ("floating point SourceA register required");
   2076      1.1  christos 	  return;
   2077      1.1  christos 	}
   2078      1.1  christos       str = skip_space (str);
   2079      1.1  christos       if (*str == ',')
   2080      1.1  christos 	{
   2081      1.1  christos 	  str++;
   2082      1.1  christos 	  ans = parse_fp_reg (&str, &r3);
   2083      1.1  christos 	  if (ans < 0)
   2084      1.1  christos 	    {
   2085      1.1  christos 	      as_bad ("floating point SourceB register required");
   2086      1.1  christos 	      return;
   2087      1.1  christos 	    }
   2088      1.1  christos 
   2089      1.1  christos 	  /* Got 3 regs, assemble instruction.  */
   2090      1.1  christos 	  opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
   2091      1.1  christos 	}
   2092      1.1  christos 
   2093      1.1  christos       this_dest = r1;
   2094      1.1  christos       break;
   2095      1.1  christos 
   2096      1.1  christos     case mode_rdfa:
   2097      1.1  christos       /* register := float
   2098      1.1  christos          Example
   2099      1.1  christos          fstore r5,f12  */
   2100      1.1  christos       ans = parse_gen_reg (&str, &r1);
   2101      1.1  christos       if (ans < 0)
   2102      1.1  christos 	{
   2103      1.1  christos 	  as_bad ("Dest general register required");
   2104      1.1  christos 	  return;
   2105      1.1  christos 	}
   2106      1.1  christos       str = skip_space (str);
   2107      1.1  christos       if (*str == ',')
   2108      1.1  christos 	{
   2109      1.1  christos 	  str++;
   2110      1.1  christos 	  ans = parse_fp_reg (&str, &r2);
   2111      1.1  christos 	  if (ans < 0)
   2112      1.1  christos 	    {
   2113      1.1  christos 	      as_bad ("floating point source register required");
   2114      1.1  christos 	      return;
   2115      1.1  christos 	    }
   2116      1.1  christos 
   2117      1.1  christos 	  /* Got 2 regs, assemble instruction.  */
   2118      1.1  christos 	  opcode |= (r1 << 10) | (r2 << 16);
   2119      1.1  christos 	}
   2120      1.1  christos       else
   2121      1.1  christos 	{
   2122      1.1  christos 	  as_bad ("floating point source register required");
   2123      1.1  christos 	  return;
   2124      1.1  christos 	}
   2125      1.1  christos 
   2126      1.1  christos       this_dest = r1;
   2127      1.1  christos       break;
   2128      1.1  christos 
   2129      1.1  christos     case mode_rrr:
   2130      1.1  christos       /* register register register, all sources and destinations
   2131      1.1  christos          Example:
   2132      1.1  christos          bmd   r1,r2,r3  */
   2133      1.1  christos 
   2134      1.1  christos       ans = parse_gen_reg (&str, &r1);
   2135      1.1  christos       if (ans < 0)
   2136      1.1  christos 	{
   2137      1.1  christos 	  as_bad ("destination address register required");
   2138      1.1  christos 	  return;
   2139      1.1  christos 	}
   2140      1.1  christos       str = skip_space (str);
   2141      1.1  christos       if (*str == ',')
   2142      1.1  christos 	{
   2143      1.1  christos 	  str++;
   2144      1.1  christos 	  ans = parse_gen_reg (&str, &r2);
   2145      1.1  christos 	  if (ans < 0)
   2146      1.1  christos 	    {
   2147      1.1  christos 	      as_bad ("source address register required");
   2148      1.1  christos 	      return;
   2149      1.1  christos 	    }
   2150      1.1  christos 	  str = skip_space (str);
   2151      1.1  christos 	  if (*str == ',')
   2152      1.1  christos 	    {
   2153      1.1  christos 	      str++;
   2154      1.1  christos 	      ans = parse_gen_reg (&str, &r3);
   2155      1.1  christos 	      if (ans < 0)
   2156      1.1  christos 		{
   2157      1.1  christos 		  as_bad ("count register required");
   2158      1.1  christos 		  return;
   2159      1.1  christos 		}
   2160      1.1  christos 
   2161      1.1  christos 	      /* We insist on three registers but the opcode can only use
   2162      1.1  christos 		 r1,r2,r3.  */
   2163      1.1  christos 	      if (r1 != 1 || r2 != 2 || r3 != 3)
   2164      1.1  christos 		{
   2165      1.1  christos 		  as_bad ("BMI/BMD can only use format op r1,r2,r3");
   2166      1.1  christos 		  return;
   2167      1.1  christos 		}
   2168      1.1  christos 
   2169      1.1  christos 	      /* Opcode is unmodified by what comes out of the table.  */
   2170      1.1  christos 	    }
   2171      1.1  christos 	  else
   2172      1.1  christos 	    {
   2173      1.1  christos 	      as_bad ("register required");
   2174      1.1  christos 	      return;
   2175      1.1  christos 	    }
   2176      1.1  christos 	}
   2177      1.1  christos       else
   2178      1.1  christos 	{
   2179      1.1  christos 	  as_bad ("register required");
   2180      1.1  christos 	  return;
   2181      1.1  christos 	}
   2182      1.1  christos 
   2183      1.1  christos       this_dest = r1;
   2184      1.1  christos       break;
   2185      1.1  christos 
   2186      1.1  christos     default:
   2187      1.1  christos       break;
   2188      1.1  christos     }
   2189      1.1  christos 
   2190      1.1  christos   if (relax)
   2191      1.1  christos     output = frag_var (rs_machine_dependent, 8, 4, relax, e1.X_add_symbol,
   2192      1.1  christos 		       e1.X_add_number, NULL);
   2193      1.1  christos   else
   2194      1.1  christos     output = frag_more (4);
   2195      1.1  christos 
   2196      1.1  christos   /* Build the 32-bit instruction in a host-endian-neutral fashion.  */
   2197      1.1  christos   output[0] = (opcode >> 24) & 0xff;
   2198      1.1  christos   output[1] = (opcode >> 16) & 0xff;
   2199      1.1  christos   output[2] = (opcode >> 8) & 0xff;
   2200      1.1  christos   output[3] = (opcode >> 0) & 0xff;
   2201      1.1  christos 
   2202      1.1  christos   if (relax)
   2203      1.1  christos     /* The size of the instruction is unknown, so tie the debug info to the
   2204      1.1  christos        start of the instruction.  */
   2205      1.1  christos     dwarf2_emit_insn (0);
   2206      1.1  christos   else
   2207      1.1  christos     {
   2208      1.1  christos       if (reloc)
   2209      1.1  christos 	fix_new_exp (frag_now, output - frag_now->fr_literal, 4, &e1,
   2210      1.1  christos 		     reloc == BFD_RELOC_VISIUM_REL16, reloc);
   2211      1.1  christos       else
   2212      1.1  christos 	visium_update_parity_bit (output);
   2213      1.1  christos 
   2214      1.1  christos       dwarf2_emit_insn (4);
   2215      1.1  christos     }
   2216      1.1  christos 
   2217      1.1  christos   if (*str != '\0')
   2218      1.1  christos     as_bad ("junk after instruction");
   2219      1.1  christos }
   2220      1.1  christos 
   2221      1.1  christos void
   2222      1.1  christos visium_cfi_frame_initial_instructions (void)
   2223      1.1  christos {
   2224      1.1  christos   /* The CFA is in SP on function entry.  */
   2225      1.1  christos   cfi_add_CFA_def_cfa (23, 0);
   2226      1.1  christos }
   2227      1.1  christos 
   2228      1.1  christos int
   2229      1.1  christos visium_regname_to_dw2regnum (char *regname)
   2230      1.1  christos {
   2231      1.1  christos   if (!regname[0])
   2232      1.1  christos     return -1;
   2233      1.1  christos 
   2234      1.1  christos   if (regname[0] == 'f' && regname[1] == 'p' && !regname[2])
   2235      1.1  christos     return 22;
   2236      1.1  christos 
   2237      1.1  christos   if (regname[0] == 's' && regname[1] == 'p' && !regname[2])
   2238      1.1  christos     return 23;
   2239      1.1  christos 
   2240      1.1  christos   if (regname[0] == 'm' && regname[1] == 'd' && !regname[3])
   2241      1.1  christos     switch (regname[2])
   2242      1.1  christos       {
   2243      1.1  christos       case 'b': return 32;
   2244      1.1  christos       case 'a': return 33;
   2245      1.1  christos       case 'c': return 34;
   2246      1.1  christos       default : return -1;
   2247      1.1  christos       }
   2248      1.1  christos 
   2249      1.1  christos   if (regname[0] == 'f' || regname[0] == 'r')
   2250      1.1  christos     {
   2251      1.1  christos       char *p;
   2252      1.1  christos       unsigned int regnum = strtoul (regname + 1, &p, 10);
   2253      1.1  christos       if (*p)
   2254      1.1  christos 	return -1;
   2255      1.1  christos       if (regnum >= (regname[0] == 'f' ? 16 : 32))
   2256      1.1  christos 	return -1;
   2257      1.1  christos       if (regname[0] == 'f')
   2258      1.1  christos 	regnum += 35;
   2259      1.1  christos       return regnum;
   2260      1.1  christos     }
   2261      1.1  christos 
   2262      1.1  christos   return -1;
   2263      1.1  christos }
   2264