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