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