Home | History | Annotate | Download | only in config
      1 /* tc-dlx.c -- Assemble for the DLX
      2    Copyright (C) 2002-2014 Free Software Foundation, Inc.
      3 
      4    This file is part of GAS, the GNU Assembler.
      5 
      6    GAS is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3, or (at your option)
      9    any later version.
     10 
     11    GAS is distributed in the hope that it will be useful,
     12    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with GAS; see the file COPYING.  If not, write to the Free
     18    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     19    02110-1301, USA.  */
     20 
     21 /* Initially created by Kuang Hwa Lin, 3/20/2002.  */
     22 
     23 #include "as.h"
     24 #include "safe-ctype.h"
     25 #include "tc-dlx.h"
     26 #include "opcode/dlx.h"
     27 
     28 /* Make it easier to clone this machine desc into another one.  */
     29 #define	machine_opcode      dlx_opcode
     30 #define	machine_opcodes     dlx_opcodes
     31 #define	machine_ip          dlx_ip
     32 #define	machine_it          dlx_it
     33 
     34 #define NO_RELOC            BFD_RELOC_NONE
     35 #define RELOC_DLX_REL26     BFD_RELOC_DLX_JMP26
     36 #define RELOC_DLX_16        BFD_RELOC_16
     37 #define RELOC_DLX_REL16     BFD_RELOC_16_PCREL_S2
     38 #define RELOC_DLX_HI16      BFD_RELOC_HI16_S
     39 #define RELOC_DLX_LO16      BFD_RELOC_LO16
     40 #define RELOC_DLX_VTINHERIT BFD_RELOC_VTABLE_INHERIT
     41 #define RELOC_DLX_VTENTRY   BFD_RELOC_VTABLE_ENTRY
     42 
     43 /* handle of the OPCODE hash table */
     44 static struct hash_control *op_hash = NULL;
     45 
     46 struct machine_it
     47 {
     48   char *error;
     49   unsigned long opcode;
     50   struct nlist *nlistp;
     51   expressionS exp;
     52   int pcrel;
     53   int size;
     54   int reloc_offset;		/* Offset of reloc within insn.  */
     55   int reloc;
     56   int HI;
     57   int LO;
     58 }
     59 the_insn;
     60 
     61 /* This array holds the chars that always start a comment.  If the
     62    pre-processor is disabled, these aren't very useful.  */
     63 const char comment_chars[] = ";";
     64 
     65 /* This array holds the chars that only start a comment at the beginning of
     66    a line.  If the line seems to have the form '# 123 filename'
     67    .line and .file directives will appear in the pre-processed output.  */
     68 /* Note that input_file.c hand checks for '#' at the beginning of the
     69    first line of the input file.  This is because the compiler outputs
     70    #NO_APP at the beginning of its output.  */
     71 /* Also note that comments like this one will always work.  */
     72 const char line_comment_chars[] = "#";
     73 
     74 /* We needed an unused char for line separation to work around the
     75    lack of macros, using sed and such.  */
     76 const char line_separator_chars[] = "@";
     77 
     78 /* Chars that can be used to separate mant from exp in floating point nums.  */
     79 const char EXP_CHARS[] = "eE";
     80 
     81 /* Chars that mean this number is a floating point constant.
     82    As in 0f12.456
     83    or    0d1.2345e12.  */
     84 const char FLT_CHARS[] = "rRsSfFdDxXpP";
     85 
     86 static void
     87 insert_sreg (char *regname, int regnum)
     88 {
     89   /* Must be large enough to hold the names of the special registers.  */
     90   char buf[80];
     91   int i;
     92 
     93   symbol_table_insert (symbol_new (regname, reg_section, (valueT) regnum,
     94 				   &zero_address_frag));
     95   for (i = 0; regname[i]; i++)
     96     buf[i] = ISLOWER (regname[i]) ? TOUPPER (regname[i]) : regname[i];
     97   buf[i] = '\0';
     98 
     99   symbol_table_insert (symbol_new (buf, reg_section, (valueT) regnum,
    100 				   &zero_address_frag));
    101 }
    102 
    103 /* Install symbol definitions for assorted special registers.
    104    See MIPS Assembly Language Programmer's Guide page 1-4   */
    105 
    106 static void
    107 define_some_regs (void)
    108 {
    109   /* Software representation.  */
    110   insert_sreg ("zero",  0);
    111   insert_sreg ("at",    1);
    112   insert_sreg ("v0",    2);
    113   insert_sreg ("v1",    3);
    114   insert_sreg ("a0",    4);
    115   insert_sreg ("a1",    5);
    116   insert_sreg ("a2",    6);
    117   insert_sreg ("a3",    7);
    118   insert_sreg ("t0",    8);
    119   insert_sreg ("t1",    9);
    120   insert_sreg ("t2",    10);
    121   insert_sreg ("t3",    11);
    122   insert_sreg ("t4",    12);
    123   insert_sreg ("t5",    13);
    124   insert_sreg ("t6",    14);
    125   insert_sreg ("t7",    15);
    126   insert_sreg ("s0",    16);
    127   insert_sreg ("s1",    17);
    128   insert_sreg ("s2",    18);
    129   insert_sreg ("s3",    19);
    130   insert_sreg ("s4",    20);
    131   insert_sreg ("s5",    21);
    132   insert_sreg ("s6",    22);
    133   insert_sreg ("s7",    23);
    134   insert_sreg ("t8",    24);
    135   insert_sreg ("t9",    25);
    136   insert_sreg ("k0",    26);
    137   insert_sreg ("k1",    27);
    138   insert_sreg ("gp",    28);
    139   insert_sreg ("sp",    29);
    140   insert_sreg ("fp",    30);
    141   insert_sreg ("ra",    31);
    142   /* Special registers.  */
    143   insert_sreg ("pc",    0);
    144   insert_sreg ("npc",   1);
    145   insert_sreg ("iad",   2);
    146 }
    147 
    148 /* Subroutine check the string to match an register.  */
    149 
    150 static int
    151 match_sft_register (char *name)
    152 {
    153 #define MAX_REG_NO  35
    154 /* Currently we have 35 software registers defined -
    155    we borrowed from MIPS.   */
    156   static char *soft_reg[] =
    157     {
    158       "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
    159       "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9",
    160       "s0", "s1", "s2", "s3", "s4", "s5", "s7", "k0", "k1",
    161       "gp", "sp", "fp", "ra", "pc", "npc", "iad",
    162       "EndofTab"  /* End of the Table indicator */
    163     };
    164   char low_name[21], *ptr;
    165   int idx;
    166 
    167   for (ptr = name,idx = 0; *ptr != '\0'; ptr++)
    168     low_name[idx++] = TOLOWER (*ptr);
    169 
    170   low_name[idx] = '\0';
    171   idx = 0;
    172 
    173   while (idx < MAX_REG_NO && strcmp (soft_reg[idx], & low_name [0]))
    174     idx += 1;
    175 
    176   return idx < MAX_REG_NO;
    177 }
    178 
    179 /* Subroutine check the string to match an register.  */
    180 
    181 static int
    182 is_ldst_registers (char *name)
    183 {
    184   char *ptr = name;
    185 
    186   /* The first character of the register name got to be either %, $, r of R.  */
    187   if ((ptr[0] == '%' || ptr[0] == '$' || ptr[0] == 'r' || ptr[0] == 'R')
    188       && ISDIGIT ((unsigned char) ptr[1]))
    189     return 1;
    190 
    191   /* Now check the software register representation.  */
    192   return match_sft_register (ptr);
    193 }
    194 
    195 /* Subroutine of s_proc so targets can choose a different default prefix.
    196    If DEFAULT_PREFIX is NULL, use the target's "leading char".  */
    197 
    198 static void
    199 s_proc (int end_p)
    200 {
    201   /* Record the current function so that we can issue an error message for
    202      misplaced .func,.endfunc, and also so that .endfunc needs no
    203      arguments.  */
    204   static char *current_name;
    205   static char *current_label;
    206 
    207   if (end_p)
    208     {
    209       if (current_name == NULL)
    210 	{
    211 	  as_bad (_("missing .proc"));
    212 	  ignore_rest_of_line ();
    213 	  return;
    214 	}
    215 
    216       current_name = current_label = NULL;
    217       SKIP_WHITESPACE ();
    218       while (!is_end_of_line[(unsigned char) *input_line_pointer])
    219         input_line_pointer++;
    220     }
    221   else
    222     {
    223       char *name, *label;
    224       char delim1, delim2;
    225 
    226       if (current_name != NULL)
    227 	{
    228 	  as_bad (_(".endfunc missing for previous .proc"));
    229 	  ignore_rest_of_line ();
    230 	  return;
    231 	}
    232 
    233       name = input_line_pointer;
    234       delim1 = get_symbol_end ();
    235       name = xstrdup (name);
    236       *input_line_pointer = delim1;
    237       SKIP_WHITESPACE ();
    238 
    239       if (*input_line_pointer != ',')
    240 	{
    241 	  char leading_char = 0;
    242 
    243 	  leading_char = bfd_get_symbol_leading_char (stdoutput);
    244 	  /* Missing entry point, use function's name with the leading
    245 	     char prepended.  */
    246 	  if (leading_char)
    247 	    {
    248 	      unsigned len = strlen (name) + 1;
    249 	      label = xmalloc (len + 1);
    250 	      label[0] = leading_char;
    251 	      memcpy (label + 1, name, len);
    252 	    }
    253 	  else
    254 	    label = name;
    255 	}
    256       else
    257 	{
    258 	  ++input_line_pointer;
    259 	  SKIP_WHITESPACE ();
    260 	  label = input_line_pointer;
    261 	  delim2 = get_symbol_end ();
    262 	  label = xstrdup (label);
    263 	  *input_line_pointer = delim2;
    264 	}
    265 
    266       current_name = name;
    267       current_label = label;
    268     }
    269   demand_empty_rest_of_line ();
    270 }
    271 
    272 /* This function is called once, at assembler startup time.  It should
    273    set up all the tables, etc., that the MD part of the assembler will
    274    need.  */
    275 
    276 void
    277 md_begin (void)
    278 {
    279   const char *retval = NULL;
    280   int lose = 0;
    281   unsigned int i;
    282 
    283   /* Create a new hash table.  */
    284   op_hash = hash_new ();
    285 
    286   /* Hash up all the opcodes for fast use later.  */
    287   for (i = 0; i < num_dlx_opcodes; i++)
    288     {
    289       const char *name = machine_opcodes[i].name;
    290 
    291       retval = hash_insert (op_hash, name, (void *) &machine_opcodes[i]);
    292 
    293       if (retval != NULL)
    294 	{
    295 	  fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
    296 		   machine_opcodes[i].name, retval);
    297 	  lose = 1;
    298 	}
    299     }
    300 
    301   if (lose)
    302     as_fatal (_("Broken assembler.  No assembly attempted."));
    303 
    304   define_some_regs ();
    305 }
    306 
    307 /* This function will check the opcode and return 1 if the opcode is one
    308    of the load/store instruction, and it will fix the operand string to
    309    the standard form so we can use the standard parse_operand routine.  */
    310 
    311 #define READ_OP     0x100
    312 #define WRITE_OP    0x200
    313 static char iBuf[81];
    314 
    315 static char *
    316 dlx_parse_loadop (char * str)
    317 {
    318   char *ptr = str;
    319   int   idx = 0;
    320 
    321   /* The last pair of ()/[] is the register, all other are the
    322      reloc displacement, and if there is a register then it ought
    323      to have a pair of ()/[]
    324      This is not necessarily true, what if the load instruction come
    325      without the register and with %hi/%lo modifier?  */
    326   for (idx = 0; idx < 72 && ptr[idx] != '\0'; idx++)
    327     ;
    328 
    329   if (idx == 72)
    330     {
    331     badoperand_load:
    332       as_bad (_("Bad operand for a load instruction: <%s>"), str);
    333       return NULL;
    334     }
    335   else
    336     {
    337       int i, pb = 0;
    338       int m2 = 0;
    339       char rs1[7], rd[7], endm, match = '0';
    340       char imm[72];
    341 
    342       idx -= 1;
    343       switch (str[idx])
    344 	{
    345 	case ')':
    346 	  match = '(';
    347 	  endm  = ')';
    348 	  break;
    349 	case ']':
    350 	  match = '[';
    351 	  endm  = ']';
    352 	  break;
    353 	default:
    354 	  /* No register indicated, fill in zero.  */
    355 	  rs1[0] = 'r';
    356 	  rs1[1] = '0';
    357 	  rs1[2] = '\0';
    358 	  match  = 0;
    359 	  endm = 0;
    360 	  m2 = 1;
    361 	}
    362 
    363       if (!m2)
    364 	{
    365 	  /* Searching for (/[ which will match the ]/).  */
    366 	  for (pb = idx - 1; str[pb] != match; pb -= 1)
    367 	    /* Match can only be either '[' or '(', if it is
    368 	       '(' then this can be a normal expression, we'll treat
    369 	       it as an operand.  */
    370 	    if (str[pb] == endm || pb < (idx - 5))
    371 	      goto load_no_rs1;
    372 	  pb += 1;
    373 
    374 	  for (i = 0; (pb + i) < idx; i++)
    375 	    rs1[i] = str[pb+i];
    376 
    377 	  rs1[i] = '\0';
    378 
    379 	  if (is_ldst_registers (& rs1[0]))
    380 	    /* Point to the last character of the imm.  */
    381 	    pb -= 1;
    382 	  else
    383 	    {
    384 	    load_no_rs1:
    385 	      if (match == '[')
    386 		goto badoperand_load;
    387 	      /* No register indicated, fill in zero and restore the imm.  */
    388 	      rs1[0] = 'r';
    389 	      rs1[1] = '0';
    390 	      rs1[2] = '\0';
    391 	      m2 = 1;
    392 	    }
    393 	}
    394 
    395       /* Duplicate the first register.  */
    396       for (i = 0; i < 7 && str[i] != ','; i++)
    397 	rd[i] = ptr[i];
    398 
    399       if (str[i] != ',')
    400 	goto badoperand_load;
    401       else
    402 	rd[i] = '\0';
    403 
    404       /* Copy the immd.  */
    405       if (m2)
    406 	/* Put the '\0' back in.  */
    407 	pb = idx + 1;
    408 
    409       for (i++, m2 = 0; i < pb; m2++,i++)
    410 	imm[m2] = ptr[i];
    411 
    412       imm[m2] = '\0';
    413 
    414       /* Assemble the instruction to gas internal format.  */
    415       for (i = 0; rd[i] != '\0'; i++)
    416 	iBuf[i] = rd[i];
    417 
    418       iBuf[i++] = ',';
    419 
    420       for (pb = 0 ; rs1[pb] != '\0'; i++, pb++)
    421 	iBuf[i] = rs1[pb];
    422 
    423       iBuf[i++] = ',';
    424 
    425       for (pb = 0; imm[pb] != '\0'; i++, pb++)
    426 	iBuf[i] = imm[pb];
    427 
    428       iBuf[i] = '\0';
    429       return iBuf;
    430     }
    431 }
    432 
    433 static char *
    434 dlx_parse_storeop (char * str)
    435 {
    436   char *ptr = str;
    437   int   idx = 0;
    438 
    439   /* Search for the ','.  */
    440   for (idx = 0; idx < 72 && ptr[idx] != ','; idx++)
    441     ;
    442 
    443   if (idx == 72)
    444     {
    445     badoperand_store:
    446       as_bad (_("Bad operand for a store instruction: <%s>"), str);
    447       return NULL;
    448     }
    449   else
    450     {
    451       /* idx now points to the ','.  */
    452       int i, pb = 0;
    453       int comma = idx;
    454       int m2 = 0;
    455       char rs1[7], rd[7], endm, match = '0';
    456       char imm[72];
    457 
    458       /* Now parse the '(' and ')', and make idx point to ')'.  */
    459       idx -= 1;
    460       switch (str[idx])
    461 	{
    462 	case ')':
    463 	  match = '(';
    464 	  endm  = ')';
    465 	  break;
    466 	case ']':
    467 	  match = '[';
    468 	  endm  = ']';
    469 	  break;
    470 	default:
    471 	  /* No register indicated, fill in zero.  */
    472 	  rs1[0] = 'r';
    473 	  rs1[1] = '0';
    474 	  rs1[2] = '\0';
    475 	  match  = 0;
    476 	  endm = 0;
    477 	  m2 = 1;
    478 	}
    479 
    480       if (!m2)
    481 	{
    482 	  /* Searching for (/[ which will match the ]/).  */
    483 	  for (pb = idx - 1; str[pb] != match; pb -= 1)
    484 	    if (pb < (idx - 5) || str[pb] == endm)
    485 	      goto store_no_rs1;
    486 	  pb += 1;
    487 
    488 	  for (i = 0; (pb + i) < idx; i++)
    489 	    rs1[i] = str[pb + i];
    490 
    491 	  rs1[i] = '\0';
    492 
    493 	  if (is_ldst_registers (& rs1[0]))
    494 	    /* Point to the last character of the imm.  */
    495 	    pb -= 1;
    496 	  else
    497 	    {
    498 	    store_no_rs1:
    499 	      if (match == '[')
    500 		goto badoperand_store;
    501 
    502 	      /* No register indicated, fill in zero and restore the imm.  */
    503 	      rs1[0] = 'r';
    504 	      rs1[1] = '0';
    505 	      rs1[2] = '\0';
    506 	      pb = comma;
    507 	    }
    508 	}
    509       else
    510 	/* No register was specified.  */
    511 	pb = comma;
    512 
    513       /* Duplicate the first register.  */
    514       for (i = comma + 1; (str[i] == ' ' || str[i] == '\t'); i++)
    515 	;
    516 
    517       for (m2 = 0; (m2 < 7 && str[i] != '\0'); i++, m2++)
    518 	{
    519 	  if (str[i] != ' ' && str[i] != '\t')
    520 	    rd[m2] = str[i];
    521 	  else
    522 	    goto badoperand_store;
    523 	}
    524 
    525       if (str[i] != '\0')
    526 	goto badoperand_store;
    527       else
    528 	rd[m2] = '\0';
    529 
    530       /* Copy the immd.  */
    531       for (i = 0; i < pb; i++)
    532 	imm[i] = ptr[i];
    533 
    534       imm[i] = '\0';
    535 
    536       /* Assemble the instruction to gas internal format.  */
    537       for (i = 0; rd[i] != '\0'; i++)
    538 	iBuf[i] = rd[i];
    539       iBuf[i++] = ',';
    540       for (pb = 0 ; rs1[pb] != '\0'; i++, pb++)
    541 	iBuf[i] = rs1[pb];
    542       iBuf[i++] = ',';
    543       for (pb = 0; imm[pb] != '\0'; i++, pb++)
    544 	iBuf[i] = imm[pb];
    545       iBuf[i] = '\0';
    546       return iBuf;
    547     }
    548 }
    549 
    550 static char *
    551 fix_ld_st_operand (unsigned long opcode, char* str)
    552 {
    553   /* Check the opcode.  */
    554   switch ((int) opcode)
    555     {
    556     case  LBOP:
    557     case  LBUOP:
    558     case  LSBUOP:
    559     case  LHOP:
    560     case  LHUOP:
    561     case  LSHUOP:
    562     case  LWOP:
    563     case  LSWOP:
    564       return dlx_parse_loadop (str);
    565     case  SBOP:
    566     case  SHOP:
    567     case  SWOP:
    568       return dlx_parse_storeop (str);
    569     default:
    570       return str;
    571     }
    572 }
    573 
    574 static int
    575 hilo_modifier_ok (char *s)
    576 {
    577   char *ptr = s;
    578   int   idx, count = 1;
    579 
    580   if (*ptr != '(')
    581     return 1;
    582 
    583   for (idx = 1; ptr[idx] != '\0' && ptr[idx] != '[' && idx < 73; idx += 1)
    584     {
    585       if (count == 0)
    586 	return count;
    587 
    588       if (ptr[idx] == '(')
    589 	count += 1;
    590 
    591       if (ptr[idx] == ')')
    592 	count -= 1;
    593     }
    594 
    595   return (count == 0) ? 1:0;
    596 }
    597 
    598 static char *
    599 parse_operand (char *s, expressionS *operandp)
    600 {
    601   char *save = input_line_pointer;
    602   char *new_pos;
    603 
    604   the_insn.HI = the_insn.LO = 0;
    605 
    606   /* Search for %hi and %lo, make a mark and skip it.  */
    607   if (strncmp (s, "%hi", 3) == 0)
    608     {
    609       s += 3;
    610       the_insn.HI = 1;
    611     }
    612   else
    613     {
    614       if (strncmp (s, "%lo", 3) == 0)
    615 	{
    616 	  s += 3;
    617 	  the_insn.LO = 1;
    618 	}
    619       else
    620 	the_insn.LO = 0;
    621     }
    622 
    623   if (the_insn.HI || the_insn.LO)
    624     {
    625       if (!hilo_modifier_ok (s))
    626 	as_bad (_("Expression Error for operand modifier %%hi/%%lo\n"));
    627     }
    628 
    629   /* Check for the % and $ register representation    */
    630   if ((s[0] == '%' || s[0] == '$' || s[0] == 'r' || s[0] == 'R')
    631       && ISDIGIT ((unsigned char) s[1]))
    632     {
    633       /* We have a numeric register expression.  No biggy.  */
    634       s += 1;
    635       input_line_pointer = s;
    636       (void) expression (operandp);
    637       if (operandp->X_op != O_constant
    638 	  || operandp->X_add_number > 31)
    639 	as_bad (_("Invalid expression after %%%%\n"));
    640       operandp->X_op = O_register;
    641     }
    642   else
    643     {
    644       /* Normal operand parsing.  */
    645       input_line_pointer = s;
    646       (void) expression (operandp);
    647     }
    648 
    649   new_pos = input_line_pointer;
    650   input_line_pointer = save;
    651   return new_pos;
    652 }
    653 
    654 /* Instruction parsing.  Takes a string containing the opcode.
    655    Operands are at input_line_pointer.  Output is in the_insn.
    656    Warnings or errors are generated.  */
    657 
    658 static void
    659 machine_ip (char *str)
    660 {
    661   char *s;
    662   const char *args;
    663   struct machine_opcode *insn;
    664   unsigned long opcode;
    665   expressionS the_operand;
    666   expressionS *operand = &the_operand;
    667   unsigned int reg, reg_shift = 0;
    668 
    669   memset (&the_insn, '\0', sizeof (the_insn));
    670   the_insn.reloc = NO_RELOC;
    671 
    672   /* Fixup the opcode string to all lower cases, and also
    673      allow numerical digits.  */
    674   s = str;
    675 
    676   if (ISALPHA (*s))
    677     for (; ISALNUM (*s); ++s)
    678       if (ISUPPER (*s))
    679 	*s = TOLOWER (*s);
    680 
    681   switch (*s)
    682     {
    683     case '\0':
    684       break;
    685 
    686       /* FIXME-SOMEDAY more whitespace.  */
    687     case ' ':
    688       *s++ = '\0';
    689       break;
    690 
    691     default:
    692       as_bad (_("Unknown opcode: `%s'"), str);
    693       return;
    694     }
    695 
    696   /* Hash the opcode, insn will have the string from opcode table.  */
    697   if ((insn = (struct machine_opcode *) hash_find (op_hash, str)) == NULL)
    698     {
    699       /* Handle the ret and return macro here.  */
    700       if ((strcmp (str, "ret") == 0) || (strcmp (str, "return") == 0))
    701 	the_insn.opcode = JROP | 0x03e00000;    /* 0x03e00000 = r31 << 21 */
    702       else
    703 	as_bad (_("Unknown opcode `%s'."), str);
    704 
    705       return;
    706     }
    707 
    708   opcode = insn->opcode;
    709 
    710   /* Set the sip reloc HI16 flag.  */
    711   if (!set_dlx_skip_hi16_flag (1))
    712     as_bad (_("Can not set dlx_skip_hi16_flag"));
    713 
    714   /* Fix the operand string if it is one of load store instructions.  */
    715   s = fix_ld_st_operand (opcode, s);
    716 
    717   /* Build the opcode, checking as we go to make sure that the
    718      operands match.
    719      If an operand matches, we modify the_insn or opcode appropriately,
    720      and do a "continue".  If an operand fails to match, we "break".  */
    721   if (insn->args[0] != '\0' && insn->args[0] != 'N')
    722     {
    723       /* Prime the pump.  */
    724       if (*s == '\0')
    725 	{
    726 	  as_bad (_("Missing arguments for opcode <%s>."), str);
    727 	  return;
    728 	}
    729       else
    730 	s = parse_operand (s, operand);
    731     }
    732   else if (insn->args[0] == 'N')
    733     {
    734       /* Clean up the insn and done!  */
    735       the_insn.opcode = opcode;
    736       return;
    737     }
    738 
    739   /* Parse through the args (this is from opcode table), *s point to
    740      the current character of the instruction stream.  */
    741   for (args = insn->args;; ++args)
    742     {
    743       switch (*args)
    744 	{
    745 	  /* End of Line.  */
    746 	case '\0':
    747 	  /* End of args.  */
    748 	  if (*s == '\0')
    749 	    {
    750 	      /* We are truly done.  */
    751 	      the_insn.opcode = opcode;
    752 	      /* Clean up the HI and LO mark.  */
    753 	      the_insn.HI = 0;
    754 	      the_insn.LO = 0;
    755 	      return;
    756 	    }
    757 
    758 	  the_insn.HI = 0;
    759 	  the_insn.LO = 0;
    760 	  as_bad (_("Too many operands: %s"), s);
    761 	  break;
    762 
    763 	  /* ',' Args separator */
    764 	case ',':
    765 	  /* Must match a comma.  */
    766 	  if (*s++ == ',')
    767 	    {
    768 	      /* Parse next operand.  */
    769 	      s = parse_operand (s, operand);
    770 	      continue;
    771 	    }
    772 	  break;
    773 
    774 	  /* It can be a 'a' register or 'i' operand.  */
    775 	case 'P':
    776 	  /* Macro move operand/reg.  */
    777 	  if (operand->X_op == O_register)
    778 	    {
    779 	      /* Its a register.  */
    780 	      reg_shift = 21;
    781 	      goto general_reg;
    782 	    }
    783 
    784 	  /* The immediate 16 bits literal, bit 0-15.  */
    785 	case 'i':
    786 	  /* offset, unsigned.  */
    787 	case 'I':
    788 	  /* offset, signed.  */
    789 	  if (operand->X_op == O_constant)
    790 	    {
    791 	      if (the_insn.HI)
    792 		operand->X_add_number >>= 16;
    793 
    794 	      opcode |= operand->X_add_number & 0xFFFF;
    795 
    796 	      if (the_insn.HI && the_insn.LO)
    797 		as_bad (_("Both the_insn.HI and the_insn.LO are set : %s"), s);
    798 	      else
    799 		{
    800 		  the_insn.HI = 0;
    801 		  the_insn.LO = 0;
    802 		}
    803 	      continue;
    804 	    }
    805 
    806 	  the_insn.reloc        = (the_insn.HI) ? RELOC_DLX_HI16
    807 	    : (the_insn.LO ? RELOC_DLX_LO16 : RELOC_DLX_16);
    808 	  the_insn.reloc_offset = 2;
    809 	  the_insn.size         = 2;
    810 	  the_insn.pcrel        = 0;
    811 	  the_insn.exp          = * operand;
    812 	  the_insn.HI           = 0;
    813 	  the_insn.LO           = 0;
    814 	  continue;
    815 
    816 	case 'd':
    817 	  /* offset, signed.  */
    818 	  if (operand->X_op == O_constant)
    819 	    {
    820 	      opcode |= operand->X_add_number & 0xFFFF;
    821 	      continue;
    822 	    }
    823 	  the_insn.reloc        = RELOC_DLX_REL16;
    824 	  the_insn.reloc_offset = 0;    /* BIG-ENDIAN Byte 3 of insn.  */
    825 	  the_insn.size         = 4;
    826 	  the_insn.pcrel        = 1;
    827 	  the_insn.exp          = *operand;
    828 	  continue;
    829 
    830 	  /* The immediate 26 bits literal, bit 0-25.  */
    831 	case 'D':
    832 	  /* offset, signed.  */
    833 	  if (operand->X_op == O_constant)
    834 	    {
    835 	      opcode |= operand->X_add_number & 0x3FFFFFF;
    836 	      continue;
    837 	    }
    838 	  the_insn.reloc = RELOC_DLX_REL26;
    839 	  the_insn.reloc_offset = 0;    /* BIG-ENDIAN Byte 3 of insn.  */
    840 	  the_insn.size  = 4;
    841 	  the_insn.pcrel = 1;
    842 	  the_insn.exp = *operand;
    843 	  continue;
    844 
    845 	  /* Type 'a' Register.  */
    846 	case 'a':
    847 	  /* A general register at bits 21-25, rs1.  */
    848 	  reg_shift = 21;
    849 	  goto general_reg;
    850 
    851 	  /* Type 'b' Register.  */
    852 	case 'b':
    853 	  /* A general register at bits 16-20, rs2/rd.  */
    854 	  reg_shift = 16;
    855 	  goto general_reg;
    856 
    857 	  /* Type 'c' Register.  */
    858 	case 'c':
    859 	  /* A general register at bits 11-15, rd.  */
    860 	  reg_shift = 11;
    861 
    862 	general_reg:
    863 	  know (operand->X_add_symbol == 0);
    864 	  know (operand->X_op_symbol == 0);
    865 	  reg = operand->X_add_number;
    866 	  if (reg & 0xffffffe0)
    867 	    as_fatal (_("failed regnum sanity check."));
    868 	  else
    869 	    /* Got the register, now figure out where it goes in the opcode.  */
    870 	    opcode |= reg << reg_shift;
    871 
    872 	  switch (*args)
    873 	    {
    874 	    case 'a':
    875 	    case 'b':
    876 	    case 'c':
    877 	    case 'P':
    878 	      continue;
    879 	    }
    880 	  as_fatal (_("failed general register sanity check."));
    881 	  break;
    882 
    883 	default:
    884 	  BAD_CASE (*args);
    885 	}
    886 
    887       /* Types or values of args don't match.  */
    888       as_bad (_("Invalid operands"));
    889       return;
    890     }
    891 }
    892 
    893 /* Assemble a single instruction.  Its label has already been handled
    894    by the generic front end.  We just parse opcode and operands, and
    895    produce the bytes of data and relocation.  */
    896 
    897 void
    898 md_assemble (char *str)
    899 {
    900   char *toP;
    901   fixS *fixP;
    902   bit_fixS *bitP;
    903 
    904   know (str);
    905   machine_ip (str);
    906   toP = frag_more (4);
    907   dwarf2_emit_insn (4);
    908 
    909   /* Put out the opcode.  */
    910   md_number_to_chars (toP, the_insn.opcode, 4);
    911 
    912   /* Put out the symbol-dependent stuff.  */
    913   if (the_insn.reloc != NO_RELOC)
    914     {
    915       fixP = fix_new_exp (frag_now,
    916 			  (toP - frag_now->fr_literal + the_insn.reloc_offset),
    917 			  the_insn.size, & the_insn.exp, the_insn.pcrel,
    918 			  the_insn.reloc);
    919 
    920       /* Turn off complaints that the addend is
    921 	 too large for things like foo+100000@ha.  */
    922       switch (the_insn.reloc)
    923 	{
    924 	case RELOC_DLX_HI16:
    925 	case RELOC_DLX_LO16:
    926 	  fixP->fx_no_overflow = 1;
    927 	  break;
    928 	default:
    929 	  break;
    930 	}
    931 
    932       switch (fixP->fx_r_type)
    933 	{
    934 	case RELOC_DLX_REL26:
    935 	  bitP = malloc (sizeof (bit_fixS));
    936 	  bitP->fx_bit_size = 26;
    937 	  bitP->fx_bit_offset = 25;
    938 	  bitP->fx_bit_base = the_insn.opcode & 0xFC000000;
    939 	  bitP->fx_bit_base_adj = 0;
    940 	  bitP->fx_bit_max = 0;
    941 	  bitP->fx_bit_min = 0;
    942 	  bitP->fx_bit_add = 0x03FFFFFF;
    943 	  fixP->fx_bit_fixP = bitP;
    944 	  break;
    945 	case RELOC_DLX_LO16:
    946 	case RELOC_DLX_REL16:
    947 	  bitP = malloc (sizeof (bit_fixS));
    948 	  bitP->fx_bit_size = 16;
    949 	  bitP->fx_bit_offset = 15;
    950 	  bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000;
    951 	  bitP->fx_bit_base_adj = 0;
    952 	  bitP->fx_bit_max = 0;
    953 	  bitP->fx_bit_min = 0;
    954 	  bitP->fx_bit_add = 0x0000FFFF;
    955 	  fixP->fx_bit_fixP = bitP;
    956 	  break;
    957 	case RELOC_DLX_HI16:
    958 	  bitP = malloc (sizeof (bit_fixS));
    959 	  bitP->fx_bit_size = 16;
    960 	  bitP->fx_bit_offset = 15;
    961 	  bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000;
    962 	  bitP->fx_bit_base_adj = 0;
    963 	  bitP->fx_bit_max = 0;
    964 	  bitP->fx_bit_min = 0;
    965 	  bitP->fx_bit_add = 0x0000FFFF;
    966 	  fixP->fx_bit_fixP = bitP;
    967 	  break;
    968 	default:
    969 	  fixP->fx_bit_fixP = NULL;
    970 	  break;
    971 	}
    972     }
    973 }
    974 
    975 /* This is identical to the md_atof in m68k.c.  I think this is right,
    976    but I'm not sure.  Dlx will not use it anyway, so I just leave it
    977    here for now.  */
    978 
    979 char *
    980 md_atof (int type, char *litP, int *sizeP)
    981 {
    982   return ieee_md_atof (type, litP, sizeP, TRUE);
    983 }
    984 
    985 /* Write out big-endian.  */
    986 void
    987 md_number_to_chars (char *buf, valueT val, int n)
    988 {
    989   number_to_chars_bigendian (buf, val, n);
    990 }
    991 
    992 bfd_boolean
    993 md_dlx_fix_adjustable (fixS *fixP)
    994 {
    995   /* We need the symbol name for the VTABLE entries.  */
    996   return (fixP->fx_r_type != BFD_RELOC_VTABLE_INHERIT
    997           && fixP->fx_r_type != BFD_RELOC_VTABLE_ENTRY);
    998 }
    999 
   1000 void
   1001 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   1002 {
   1003   long val = *valP;
   1004   char *place = fixP->fx_where + fixP->fx_frag->fr_literal;
   1005 
   1006   switch (fixP->fx_r_type)
   1007     {
   1008     case RELOC_DLX_LO16:
   1009     case RELOC_DLX_REL16:
   1010       if (fixP->fx_bit_fixP != NULL)
   1011 	{
   1012 	  val = (val & 0x0000FFFF) | fixP->fx_bit_fixP->fx_bit_base;
   1013 	  free (fixP->fx_bit_fixP);
   1014 	  fixP->fx_bit_fixP = NULL;
   1015 	}
   1016 #ifdef DEBUG
   1017       else
   1018 	know ((fixP->fx_bit_fixP != NULL));
   1019 #endif
   1020       break;
   1021 
   1022     case RELOC_DLX_HI16:
   1023       if (fixP->fx_bit_fixP != NULL)
   1024 	{
   1025 	  val = (val >> 16) | fixP->fx_bit_fixP->fx_bit_base;
   1026 	  free (fixP->fx_bit_fixP);
   1027 	  fixP->fx_bit_fixP = NULL;
   1028 	}
   1029 #ifdef DEBUG
   1030       else
   1031 	know ((fixP->fx_bit_fixP != NULL));
   1032 #endif
   1033       break;
   1034 
   1035     case RELOC_DLX_REL26:
   1036       if (fixP->fx_bit_fixP != NULL)
   1037 	{
   1038 	  val = (val & 0x03FFFFFF) | fixP->fx_bit_fixP->fx_bit_base;
   1039 	  free (fixP->fx_bit_fixP);
   1040 	  fixP->fx_bit_fixP = NULL;
   1041 	}
   1042 #ifdef DEBUG
   1043       else
   1044 	know ((fixP->fx_bit_fixP != NULL));
   1045 #endif
   1046       break;
   1047 
   1048     case BFD_RELOC_VTABLE_INHERIT:
   1049       /* This borrowed from tc-ppc.c on a whim.  */
   1050       fixP->fx_done = 0;
   1051       if (fixP->fx_addsy
   1052 	  && !S_IS_DEFINED (fixP->fx_addsy)
   1053 	  && !S_IS_WEAK (fixP->fx_addsy))
   1054 	S_SET_WEAK (fixP->fx_addsy);
   1055       return;
   1056 
   1057     case BFD_RELOC_VTABLE_ENTRY:
   1058       fixP->fx_done = 0;
   1059       return;
   1060 
   1061     default:
   1062       break;
   1063     }
   1064 
   1065   number_to_chars_bigendian (place, val, fixP->fx_size);
   1066   if (fixP->fx_addsy == NULL)
   1067     fixP->fx_done = 1;
   1068 }
   1069 
   1070 const char *md_shortopts = "";
   1071 
   1072 struct option md_longopts[] =
   1073   {
   1074     {NULL, no_argument, NULL, 0}
   1075   };
   1076 
   1077 size_t md_longopts_size = sizeof (md_longopts);
   1078 
   1079 int
   1080 md_parse_option (int c     ATTRIBUTE_UNUSED,
   1081 		 char *arg ATTRIBUTE_UNUSED)
   1082 {
   1083   return 0;
   1084 }
   1085 
   1086 void
   1087 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
   1088 {
   1089 }
   1090 
   1091 /* This is called when a line is unrecognized.  */
   1092 
   1093 int
   1094 dlx_unrecognized_line (int c)
   1095 {
   1096   int lab;
   1097   char *s;
   1098 
   1099   if (c != '$' || ! ISDIGIT ((unsigned char) input_line_pointer[0]))
   1100     return 0;
   1101 
   1102   s = input_line_pointer;
   1103 
   1104   lab = 0;
   1105   while (ISDIGIT ((unsigned char) *s))
   1106     {
   1107       lab = lab * 10 + *s - '0';
   1108       ++s;
   1109     }
   1110 
   1111   if (*s != ':')
   1112     /* Not a label definition.  */
   1113     return 0;
   1114 
   1115   if (dollar_label_defined (lab))
   1116     {
   1117       as_bad (_("label \"$%d\" redefined"), lab);
   1118       return 0;
   1119     }
   1120 
   1121   define_dollar_label (lab);
   1122   colon (dollar_label_name (lab, 0));
   1123   input_line_pointer = s + 1;
   1124 
   1125   return 1;
   1126 }
   1127 
   1128 /* Default the values of symbols known that should be "predefined".  We
   1129    don't bother to predefine them unless you actually use one, since there
   1130    are a lot of them.  */
   1131 
   1132 symbolS *
   1133 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   1134 {
   1135   return NULL;
   1136 }
   1137 
   1138 /* Parse an operand that is machine-specific, the function was called
   1139    in expr.c by operand() function, when everything failed before it
   1140    call a quit.  */
   1141 
   1142 void
   1143 md_operand (expressionS* expressionP)
   1144 {
   1145   /* Check for the #number representation    */
   1146   if (input_line_pointer[0] == '#' &&
   1147       ISDIGIT ((unsigned char) input_line_pointer[1]))
   1148     {
   1149       /* We have a numeric number expression.  No biggy.  */
   1150       input_line_pointer += 1;	/* Skip # */
   1151 
   1152       (void) expression (expressionP);
   1153 
   1154       if (expressionP->X_op != O_constant)
   1155 	as_bad (_("Invalid expression after # number\n"));
   1156     }
   1157 
   1158   return;
   1159 }
   1160 
   1161 /* Round up a section size to the appropriate boundary.  */
   1162 
   1163 valueT
   1164 md_section_align (segT segment ATTRIBUTE_UNUSED,
   1165 		  valueT size)
   1166 {
   1167   /* Byte alignment is fine.  */
   1168   return size;
   1169 }
   1170 
   1171 /* Exactly what point is a PC-relative offset relative TO?
   1172    On the 29000, they're relative to the address of the instruction,
   1173    which we have set up as the address of the fixup too.  */
   1174 
   1175 long
   1176 md_pcrel_from (fixS* fixP)
   1177 {
   1178   return 4 + fixP->fx_where + fixP->fx_frag->fr_address;
   1179 }
   1180 
   1181 /* Translate internal representation of relocation info to BFD target
   1182    format.
   1183    FIXME: To what extent can we get all relevant targets to use this?
   1184    The above FIXME is from a29k, but I think it is also needed here.    */
   1185 
   1186 arelent *
   1187 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
   1188 	      fixS *fixP)
   1189 {
   1190   arelent * reloc;
   1191 
   1192   reloc = xmalloc (sizeof (arelent));
   1193   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
   1194 
   1195   if (reloc->howto == NULL)
   1196     {
   1197       as_bad_where (fixP->fx_file, fixP->fx_line,
   1198 		    _("internal error: can't export reloc type %d (`%s')"),
   1199 		    fixP->fx_r_type,
   1200 		    bfd_get_reloc_code_name (fixP->fx_r_type));
   1201       return NULL;
   1202     }
   1203 
   1204   gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
   1205 
   1206   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
   1207   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
   1208   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
   1209 
   1210   if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
   1211     reloc->address = fixP->fx_offset;
   1212   reloc->addend = 0;
   1213 
   1214   return reloc;
   1215 }
   1216 
   1217 const pseudo_typeS
   1218 dlx_pseudo_table[] =
   1219 {
   1220   /* Some additional ops that are used by gcc-dlx.  */
   1221   {"asciiz", stringer, 8 + 1},
   1222   {"half", cons, 2},
   1223   {"dword", cons, 8},
   1224   {"word", cons, 4},
   1225   {"proc", s_proc, 0},
   1226   {"endproc", s_proc, 1},
   1227   {NULL, NULL, 0}
   1228 };
   1229 
   1230 void
   1231 dlx_pop_insert (void)
   1232 {
   1233   pop_insert (dlx_pseudo_table);
   1234   return ;
   1235 }
   1236