1 /* tc-ldx.c -- Assemble for the DLX
2    Copyright 2002, 2003, 2004, 2005 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 2, 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 "safe-ctype.h"
24 #include "as.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 	    asprintf (&label, "%c%s", leading_char, name);
248 	  else
249 	    label = name;
250 	}
251       else
252 	{
253 	  ++input_line_pointer;
254 	  SKIP_WHITESPACE ();
255 	  label = input_line_pointer;
256 	  delim2 = get_symbol_end ();
257 	  label = xstrdup (label);
258 	  *input_line_pointer = delim2;
259 	}
260 
261       current_name = name;
262       current_label = label;
263     }
264   demand_empty_rest_of_line ();
265 }
266 
267 /* This function is called once, at assembler startup time.  It should
268    set up all the tables, etc., that the MD part of the assembler will
269    need.  */
270 
271 void
272 md_begin (void)
273 {
274   const char *retval = NULL;
275   int lose = 0;
276   unsigned int i;
277 
278   /* Create a new hash table.  */
279   op_hash = hash_new ();
280 
281   /* Hash up all the opcodes for fast use later.  */
282   for (i = 0; i < num_dlx_opcodes; i++)
283     {
284       const char *name = machine_opcodes[i].name;
285 
286       retval = hash_insert (op_hash, name, (void *) &machine_opcodes[i]);
287 
288       if (retval != NULL)
289 	{
290 	  fprintf (stderr, "internal error: can't hash `%s': %s\n",
291 		   machine_opcodes[i].name, retval);
292 	  lose = 1;
293 	}
294     }
295 
296   if (lose)
297     as_fatal (_("Broken assembler.  No assembly attempted."));
298 
299   define_some_regs ();
300 }
301 
302 /* This function will check the opcode and return 1 if the opcode is one
303    of the load/store instruction, and it will fix the operand string to
304    the standard form so we can use the standard parse_operand routine.  */
305 
306 #define READ_OP     0x100
307 #define WRITE_OP    0x200
308 static char iBuf[81];
309 
310 static char *
311 dlx_parse_loadop (char * str)
312 {
313   char *ptr = str;
314   int   idx = 0;
315 
316   /* The last pair of ()/[] is the register, all other are the
317      reloc displacement, and if there is a register then it ought
318      to have a pair of ()/[]
319      This is not necessarily true, what if the load instruction come
320      without the register and with %hi/%lo modifier?  */
321   for (idx = 0; idx < 72 && ptr[idx] != '\0'; idx++)
322     ;
323 
324   if (idx == 72)
325     {
326     badoperand_load:
327       as_bad (_("Bad operand for a load instruction: <%s>"), str);
328       return NULL;
329     }
330   else
331     {
332       int i, pb = 0;
333       int m2 = 0;
334       char rs1[7], rd[7], endm, match = '0';
335       char imm[72];
336 
337       idx -= 1;
338       switch (str[idx])
339 	{
340 	case ')':
341 	  match = '(';
342 	  endm  = ')';
343 	  break;
344 	case ']':
345 	  match = '[';
346 	  endm  = ']';
347 	  break;
348 	default:
349 	  /* No register indicated, fill in zero.  */
350 	  rs1[0] = 'r';
351 	  rs1[1] = '0';
352 	  rs1[2] = '\0';
353 	  match  = 0;
354 	  endm = 0;
355 	  m2 = 1;
356 	}
357 
358       if (!m2)
359 	{
360 	  /* Searching for (/[ which will match the ]/).  */
361 	  for (pb = idx - 1; str[pb] != match; pb -= 1)
362 	    /* Match can only be either '[' or '(', if it is
363 	       '(' then this can be a normal expression, we'll treat
364 	       it as an operand.  */
365 	    if (str[pb] == endm || pb < (idx - 5))
366 	      goto load_no_rs1;
367 	  pb += 1;
368 
369 	  for (i = 0; (pb + i) < idx; i++)
370 	    rs1[i] = str[pb+i];
371 
372 	  rs1[i] = '\0';
373 
374 	  if (is_ldst_registers (& rs1[0]))
375 	    /* Point to the last character of the imm.  */
376 	    pb -= 1;
377 	  else
378 	    {
379 	    load_no_rs1:
380 	      if (match == '[')
381 		goto badoperand_load;
382 	      /* No register indicated, fill in zero and restore the imm.  */
383 	      rs1[0] = 'r';
384 	      rs1[1] = '0';
385 	      rs1[2] = '\0';
386 	      m2 = 1;
387 	    }
388 	}
389 
390       /* Duplicate the first register.  */
391       for (i = 0; i < 7 && str[i] != ','; i++)
392 	rd[i] = ptr[i];
393 
394       if (str[i] != ',')
395 	goto badoperand_load;
396       else
397 	rd[i] = '\0';
398 
399       /* Copy the immd.  */
400       if (m2)
401 	/* Put the '\0' back in.  */
402 	pb = idx + 1;
403 
404       for (i++, m2 = 0; i < pb; m2++,i++)
405 	imm[m2] = ptr[i];
406 
407       imm[m2] = '\0';
408 
409       /* Assemble the instruction to gas internal format.  */
410       for (i = 0; rd[i] != '\0'; i++)
411 	iBuf[i] = rd[i];
412 
413       iBuf[i++] = ',';
414 
415       for (pb = 0 ; rs1[pb] != '\0'; i++, pb++)
416 	iBuf[i] = rs1[pb];
417 
418       iBuf[i++] = ',';
419 
420       for (pb = 0; imm[pb] != '\0'; i++, pb++)
421 	iBuf[i] = imm[pb];
422 
423       iBuf[i] = '\0';
424       return iBuf;
425     }
426 }
427 
428 static char *
429 dlx_parse_storeop (char * str)
430 {
431   char *ptr = str;
432   int   idx = 0;
433 
434   /* Search for the ','.  */
435   for (idx = 0; idx < 72 && ptr[idx] != ','; idx++)
436     ;
437 
438   if (idx == 72)
439     {
440     badoperand_store:
441       as_bad (_("Bad operand for a store instruction: <%s>"), str);
442       return NULL;
443     }
444   else
445     {
446       /* idx now points to the ','.  */
447       int i, pb = 0;
448       int comma = idx;
449       int m2 = 0;
450       char rs1[7], rd[7], endm, match = '0';
451       char imm[72];
452 
453       /* Now parse the '(' and ')', and make idx point to ')'.  */
454       idx -= 1;
455       switch (str[idx])
456 	{
457 	case ')':
458 	  match = '(';
459 	  endm  = ')';
460 	  break;
461 	case ']':
462 	  match = '[';
463 	  endm  = ']';
464 	  break;
465 	default:
466 	  /* No register indicated, fill in zero.  */
467 	  rs1[0] = 'r';
468 	  rs1[1] = '0';
469 	  rs1[2] = '\0';
470 	  match  = 0;
471 	  endm = 0;
472 	  m2 = 1;
473 	}
474 
475       if (!m2)
476 	{
477 	  /* Searching for (/[ which will match the ]/).  */
478 	  for (pb = idx - 1; str[pb] != match; pb -= 1)
479 	    if (pb < (idx - 5) || str[pb] == endm)
480 	      goto store_no_rs1;
481 	  pb += 1;
482 
483 	  for (i = 0; (pb + i) < idx; i++)
484 	    rs1[i] = str[pb + i];
485 
486 	  rs1[i] = '\0';
487 
488 	  if (is_ldst_registers (& rs1[0]))
489 	    /* Point to the last character of the imm.  */
490 	    pb -= 1;
491 	  else
492 	    {
493 	    store_no_rs1:
494 	      if (match == '[')
495 		goto badoperand_store;
496 
497 	      /* No register indicated, fill in zero and restore the imm.  */
498 	      rs1[0] = 'r';
499 	      rs1[1] = '0';
500 	      rs1[2] = '\0';
501 	      pb = comma;
502 	    }
503 	}
504       else
505 	/* No register was specified.  */
506 	pb = comma;
507 
508       /* Duplicate the first register.  */
509       for (i = comma + 1; (str[i] == ' ' || str[i] == '\t'); i++)
510 	;
511 
512       for (m2 = 0; (m2 < 7 && str[i] != '\0'); i++, m2++)
513 	{
514 	  if (str[i] != ' ' && str[i] != '\t')
515 	    rd[m2] = str[i];
516 	  else
517 	    goto badoperand_store;
518 	}
519 
520       if (str[i] != '\0')
521 	goto badoperand_store;
522       else
523 	rd[m2] = '\0';
524 
525       /* Copy the immd.  */
526       for (i = 0; i < pb; i++)
527 	imm[i] = ptr[i];
528 
529       imm[i] = '\0';
530 
531       /* Assemble the instruction to gas internal format.  */
532       for (i = 0; rd[i] != '\0'; i++)
533 	iBuf[i] = rd[i];
534       iBuf[i++] = ',';
535       for (pb = 0 ; rs1[pb] != '\0'; i++, pb++)
536 	iBuf[i] = rs1[pb];
537       iBuf[i++] = ',';
538       for (pb = 0; imm[pb] != '\0'; i++, pb++)
539 	iBuf[i] = imm[pb];
540       iBuf[i] = '\0';
541       return iBuf;
542     }
543 }
544 
545 static char *
546 fix_ld_st_operand (unsigned long opcode, char* str)
547 {
548   /* Check the opcode.  */
549   switch ((int) opcode)
550     {
551     case  LBOP:
552     case  LBUOP:
553     case  LSBUOP:
554     case  LHOP:
555     case  LHUOP:
556     case  LSHUOP:
557     case  LWOP:
558     case  LSWOP:
559       return dlx_parse_loadop (str);
560     case  SBOP:
561     case  SHOP:
562     case  SWOP:
563       return dlx_parse_storeop (str);
564     default:
565       return str;
566     }
567 }
568 
569 static int
570 hilo_modifier_ok (char *s)
571 {
572   char *ptr = s;
573   int   idx, count = 1;
574 
575   if (*ptr != '(')
576     return 1;
577 
578   for (idx = 1; ptr[idx] != '\0' && ptr[idx] != '[' && idx < 73; idx += 1)
579     {
580       if (count == 0)
581 	return count;
582 
583       if (ptr[idx] == '(')
584 	count += 1;
585 
586       if (ptr[idx] == ')')
587 	count -= 1;
588     }
589 
590   return (count == 0) ? 1:0;
591 }
592 
593 static char *
594 parse_operand (char *s, expressionS *operandp)
595 {
596   char *save = input_line_pointer;
597   char *new;
598 
599   the_insn.HI = the_insn.LO = 0;
600 
601   /* Search for %hi and %lo, make a mark and skip it.  */
602   if (strncmp (s, "%hi", 3) == 0)
603     {
604       s += 3;
605       the_insn.HI = 1;
606     }
607   else
608     {
609       if (strncmp (s, "%lo", 3) == 0)
610 	{
611 	  s += 3;
612 	  the_insn.LO = 1;
613 	}
614       else
615 	the_insn.LO = 0;
616     }
617 
618   if (the_insn.HI || the_insn.LO)
619     {
620       if (!hilo_modifier_ok (s))
621 	as_bad (_("Expression Error for operand modifier %%hi/%%lo\n"));
622     }
623 
624   /* Check for the % and $ register representation    */
625   if ((s[0] == '%' || s[0] == '$' || s[0] == 'r' || s[0] == 'R')
626       && ISDIGIT ((unsigned char) s[1]))
627     {
628       /* We have a numeric register expression.  No biggy.  */
629       s += 1;
630       input_line_pointer = s;
631       (void) expression (operandp);
632       if (operandp->X_op != O_constant
633 	  || operandp->X_add_number > 31)
634 	as_bad (_("Invalid expression after %%%%\n"));
635       operandp->X_op = O_register;
636     }
637   else
638     {
639       /* Normal operand parsing.  */
640       input_line_pointer = s;
641       (void) expression (operandp);
642     }
643 
644   new = input_line_pointer;
645   input_line_pointer = save;
646   return new;
647 }
648 
649 /* Instruction parsing.  Takes a string containing the opcode.
650    Operands are at input_line_pointer.  Output is in the_insn.
651    Warnings or errors are generated.  */
652 
653 static void
654 machine_ip (char *str)
655 {
656   char *s;
657   const char *args;
658   struct machine_opcode *insn;
659   char *argsStart;
660   unsigned long opcode;
661   expressionS the_operand;
662   expressionS *operand = &the_operand;
663   unsigned int reg, reg_shift = 0;
664 
665   /* Fixup the opcode string to all lower cases, and also
666      allow numerical digits.  */
667   s = str;
668 
669   if (ISALPHA (*s))
670     for (; ISALNUM (*s); ++s)
671       if (ISUPPER (*s))
672 	*s = TOLOWER (*s);
673 
674   switch (*s)
675     {
676     case '\0':
677       break;
678 
679       /* FIXME-SOMEDAY more whitespace.  */
680     case ' ':
681       *s++ = '\0';
682       break;
683 
684     default:
685       as_bad (_("Unknown opcode: `%s'"), str);
686       return;
687     }
688 
689   /* Hash the opcode, insn will have the string from opcode table.
690      also initialized the_insn struct.  */
691   if ((insn = (struct machine_opcode *) hash_find (op_hash, str)) == NULL)
692     {
693       /* Handle the ret and return macro here.  */
694       if ((strcmp (str, "ret") == 0) || (strcmp (str, "return") == 0))
695 	{
696 	  memset (&the_insn, '\0', sizeof (the_insn));
697 	  the_insn.reloc = NO_RELOC;
698 	  the_insn.pcrel = 0;
699 	  the_insn.opcode =
700 	    (unsigned long)(JROP | 0x03e00000);    /* 0x03e00000 = r31 << 21 */
701 	}
702       else
703 	as_bad (_("Unknown opcode `%s'."), str);
704 
705       return;
706     }
707 
708   argsStart = s;
709   opcode = insn->opcode;
710   memset (&the_insn, '\0', sizeof (the_insn));
711   the_insn.reloc = NO_RELOC;
712   the_insn.pcrel = 0;
713 
714   /* Set the sip reloc HI16 flag.  */
715   if (!set_dlx_skip_hi16_flag (1))
716     as_bad (_("Can not set dlx_skip_hi16_flag"));
717 
718   /* Fix the operand string if it is one of load store instructions.  */
719   s = fix_ld_st_operand (opcode, s);
720 
721   /* Build the opcode, checking as we go to make sure that the
722      operands match.
723      If an operand matches, we modify the_insn or opcode appropriately,
724      and do a "continue".  If an operand fails to match, we "break".  */
725   if (insn->args[0] != '\0' && insn->args[0] != 'N')
726     {
727       /* Prime the pump.  */
728       if (*s == '\0')
729 	{
730 	  as_bad (_("Missing arguments for opcode <%s>."), str);
731 	  return;
732 	}
733       else
734 	s = parse_operand (s, operand);
735     }
736   else if (insn->args[0] == 'N')
737     {
738       /* Clean up the insn and done!  */
739       the_insn.opcode = opcode;
740       return;
741     }
742 
743   /* Parse through the args (this is from opcode table), *s point to
744      the current character of the instruction stream.  */
745   for (args = insn->args;; ++args)
746     {
747       switch (*args)
748 	{
749 	  /* End of Line.  */
750 	case '\0':
751 	  /* End of args.  */
752 	  if (*s == '\0')
753 	    {
754 	      /* We are truly done.  */
755 	      the_insn.opcode = opcode;
756 	      /* Clean up the HI and LO mark.  */
757 	      the_insn.HI = 0;
758 	      the_insn.LO = 0;
759 	      return;
760 	    }
761 
762 	  the_insn.HI = 0;
763 	  the_insn.LO = 0;
764 	  as_bad (_("Too many operands: %s"), s);
765 	  break;
766 
767 	  /* ',' Args separator */
768 	case ',':
769 	  /* Must match a comma.  */
770 	  if (*s++ == ',')
771 	    {
772 	      /* Parse next operand.  */
773 	      s = parse_operand (s, operand);
774 	      continue;
775 	    }
776 	  break;
777 
778 	  /* It can be a 'a' register or 'i' operand.  */
779 	case 'P':
780 	  /* Macro move operand/reg.  */
781 	  if (operand->X_op == O_register)
782 	    {
783 	      /* Its a register.  */
784 	      reg_shift = 21;
785 	      goto general_reg;
786 	    }
787 
788 	  /* The immediate 16 bits literal, bit 0-15.  */
789 	case 'i':
790 	  /* offset, unsigned.  */
791 	case 'I':
792 	  /* offset, signed.  */
793 	  if (operand->X_op == O_constant)
794 	    {
795 	      if (the_insn.HI)
796 		operand->X_add_number >>= 16;
797 
798 	      opcode |= operand->X_add_number & 0xFFFF;
799 
800 	      if (the_insn.HI && the_insn.LO)
801 		as_bad (_("Both the_insn.HI and the_insn.LO are set : %s"), s);
802 	      else
803 		{
804 		  the_insn.HI = 0;
805 		  the_insn.LO = 0;
806 		}
807 	      continue;
808 	    }
809 
810 	  the_insn.reloc        = (the_insn.HI) ? RELOC_DLX_HI16
811 	    : (the_insn.LO ? RELOC_DLX_LO16 : RELOC_DLX_16);
812 	  the_insn.reloc_offset = 2;
813 	  the_insn.size         = 2;
814 	  the_insn.pcrel        = 0;
815 	  the_insn.exp          = * operand;
816 	  the_insn.HI           = 0;
817 	  the_insn.LO           = 0;
818 	  continue;
819 
820 	case 'd':
821 	  /* offset, signed.  */
822 	  if (operand->X_op == O_constant)
823 	    {
824 	      opcode |= operand->X_add_number & 0xFFFF;
825 	      continue;
826 	    }
827 	  the_insn.reloc        = RELOC_DLX_REL16;
828 	  the_insn.reloc_offset = 0;    /* BIG-ENDIAN Byte 3 of insn.  */
829 	  the_insn.size         = 4;
830 	  the_insn.pcrel        = 1;
831 	  the_insn.exp          = *operand;
832 	  continue;
833 
834 	  /* The immediate 26 bits literal, bit 0-25.  */
835 	case 'D':
836 	  /* offset, signed.  */
837 	  if (operand->X_op == O_constant)
838 	    {
839 	      opcode |= operand->X_add_number & 0x3FFFFFF;
840 	      continue;
841 	    }
842 	  the_insn.reloc = RELOC_DLX_REL26;
843 	  the_insn.reloc_offset = 0;    /* BIG-ENDIAN Byte 3 of insn.  */
844 	  the_insn.size  = 4;
845 	  the_insn.pcrel = 1;
846 	  the_insn.exp = *operand;
847 	  continue;
848 
849 	  /* Type 'a' Register.  */
850 	case 'a':
851 	  /* A general register at bits 21-25, rs1.  */
852 	  reg_shift = 21;
853 	  goto general_reg;
854 
855 	  /* Type 'b' Register.  */
856 	case 'b':
857 	  /* A general register at bits 16-20, rs2/rd.  */
858 	  reg_shift = 16;
859 	  goto general_reg;
860 
861 	  /* Type 'c' Register.  */
862 	case 'c':
863 	  /* A general register at bits 11-15, rd.  */
864 	  reg_shift = 11;
865 
866 	general_reg:
867 	  know (operand->X_add_symbol == 0);
868 	  know (operand->X_op_symbol == 0);
869 	  reg = operand->X_add_number;
870 	  if (reg & 0xffffffe0)
871 	    as_fatal (_("failed regnum sanity check."));
872 	  else
873 	    /* Got the register, now figure out where it goes in the opcode.  */
874 	    opcode |= reg << reg_shift;
875 
876 	  switch (*args)
877 	    {
878 	    case 'a':
879 	    case 'b':
880 	    case 'c':
881 	    case 'P':
882 	      continue;
883 	    }
884 	  as_fatal (_("failed general register sanity check."));
885 	  break;
886 
887 	default:
888 	  BAD_CASE (*args);
889 	}
890 
891       /* Types or values of args don't match.  */
892       as_bad ("Invalid operands");
893       return;
894     }
895 }
896 
897 /* Assemble a single instruction.  Its label has already been handled
898    by the generic front end.  We just parse opcode and operands, and
899    produce the bytes of data and relocation.  */
900 
901 void
902 md_assemble (char *str)
903 {
904   char *toP;
905   fixS *fixP;
906   bit_fixS *bitP;
907 
908   know (str);
909   machine_ip (str);
910   toP = frag_more (4);
911   /* Put out the opcode.  */
912   md_number_to_chars (toP, the_insn.opcode, 4);
913 
914   /* Put out the symbol-dependent stuff.  */
915   if (the_insn.reloc != NO_RELOC)
916     {
917       fixP = fix_new_exp (frag_now,
918 			  (toP - frag_now->fr_literal + the_insn.reloc_offset),
919 			  the_insn.size, & the_insn.exp, the_insn.pcrel,
920 			  the_insn.reloc);
921 
922       /* Turn off complaints that the addend is
923 	 too large for things like foo+100000@ha.  */
924       switch (the_insn.reloc)
925 	{
926 	case RELOC_DLX_HI16:
927 	case RELOC_DLX_LO16:
928 	  fixP->fx_no_overflow = 1;
929 	  break;
930 	default:
931 	  break;
932 	}
933 
934       switch (fixP->fx_r_type)
935 	{
936 	case RELOC_DLX_REL26:
937 	  bitP = malloc (sizeof (bit_fixS));
938 	  bitP->fx_bit_size = 26;
939 	  bitP->fx_bit_offset = 25;
940 	  bitP->fx_bit_base = the_insn.opcode & 0xFC000000;
941 	  bitP->fx_bit_base_adj = 0;
942 	  bitP->fx_bit_max = 0;
943 	  bitP->fx_bit_min = 0;
944 	  bitP->fx_bit_add = 0x03FFFFFF;
945 	  fixP->fx_bit_fixP = bitP;
946 	  break;
947 	case RELOC_DLX_LO16:
948 	case RELOC_DLX_REL16:
949 	  bitP = malloc (sizeof (bit_fixS));
950 	  bitP->fx_bit_size = 16;
951 	  bitP->fx_bit_offset = 15;
952 	  bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000;
953 	  bitP->fx_bit_base_adj = 0;
954 	  bitP->fx_bit_max = 0;
955 	  bitP->fx_bit_min = 0;
956 	  bitP->fx_bit_add = 0x0000FFFF;
957 	  fixP->fx_bit_fixP = bitP;
958 	  break;
959 	case RELOC_DLX_HI16:
960 	  bitP = malloc (sizeof (bit_fixS));
961 	  bitP->fx_bit_size = 16;
962 	  bitP->fx_bit_offset = 15;
963 	  bitP->fx_bit_base = the_insn.opcode & 0xFFFF0000;
964 	  bitP->fx_bit_base_adj = 0;
965 	  bitP->fx_bit_max = 0;
966 	  bitP->fx_bit_min = 0;
967 	  bitP->fx_bit_add = 0x0000FFFF;
968 	  fixP->fx_bit_fixP = bitP;
969 	  break;
970 	default:
971 	  fixP->fx_bit_fixP = NULL;
972 	  break;
973 	}
974     }
975 }
976 
977 /* This is identical to the md_atof in m68k.c.  I think this is right,
978    but I'm not sure.
979 
980    Turn a string in input_line_pointer into a floating point constant
981    of type TYPE, and store the appropriate bytes in *LITP.  The number
982    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
983    returned, or NULL on OK.  */
984 /* Dlx will not use it anyway, so I just leave it here for now.  */
985 
986 /* Equal to MAX_PRECISION in atof-ieee.c.  */
987 #define MAX_LITTLENUMS 6
988 
989 char *
990 md_atof (int type, char *litP, int *sizeP)
991 {
992   int prec;
993   LITTLENUM_TYPE words[MAX_LITTLENUMS];
994   LITTLENUM_TYPE *wordP;
995   char *t;
996 
997   switch (type)
998     {
999     case 'f':
1000     case 'F':
1001     case 's':
1002     case 'S':
1003       prec = 2;
1004       break;
1005 
1006     case 'd':
1007     case 'D':
1008     case 'r':
1009     case 'R':
1010       prec = 4;
1011       break;
1012 
1013     case 'x':
1014     case 'X':
1015       prec = 6;
1016       break;
1017 
1018     case 'p':
1019     case 'P':
1020       prec = 6;
1021       break;
1022 
1023     default:
1024       *sizeP = 0;
1025       return "Bad call to MD_ATOF()";
1026     }
1027 
1028   t = atof_ieee (input_line_pointer, type, words);
1029   if (t)
1030     input_line_pointer = t;
1031 
1032   *sizeP = prec * sizeof (LITTLENUM_TYPE);
1033 
1034   for (wordP = words; prec--;)
1035     {
1036       md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
1037       litP += sizeof (LITTLENUM_TYPE);
1038     }
1039 
1040   return 0;
1041 }
1042 
1043 /* Write out big-endian.  */
1044 void
1045 md_number_to_chars (char *buf, valueT val, int n)
1046 {
1047   number_to_chars_bigendian (buf, val, n);
1048 }
1049 
1050 bfd_boolean
1051 md_dlx_fix_adjustable (fixS *fixP)
1052 {
1053   /* We need the symbol name for the VTABLE entries.  */
1054   return (fixP->fx_r_type != BFD_RELOC_VTABLE_INHERIT
1055           && fixP->fx_r_type != BFD_RELOC_VTABLE_ENTRY);
1056 }
1057 
1058 void
1059 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
1060 {
1061   long val = *valP;
1062   char *place = fixP->fx_where + fixP->fx_frag->fr_literal;
1063 
1064   switch (fixP->fx_r_type)
1065     {
1066     case RELOC_DLX_LO16:
1067     case RELOC_DLX_REL16:
1068       if (fixP->fx_bit_fixP != NULL)
1069 	{
1070 	  val = (val & 0x0000FFFF) | fixP->fx_bit_fixP->fx_bit_base;
1071 	  free (fixP->fx_bit_fixP);
1072 	  fixP->fx_bit_fixP = NULL;
1073 	}
1074 #ifdef DEBUG
1075       else
1076 	know ((fixP->fx_bit_fixP != NULL));
1077 #endif
1078       break;
1079 
1080     case RELOC_DLX_HI16:
1081       if (fixP->fx_bit_fixP != NULL)
1082 	{
1083 	  val = (val >> 16) | fixP->fx_bit_fixP->fx_bit_base;
1084 	  free (fixP->fx_bit_fixP);
1085 	  fixP->fx_bit_fixP = NULL;
1086 	}
1087 #ifdef DEBUG
1088       else
1089 	know ((fixP->fx_bit_fixP != NULL));
1090 #endif
1091       break;
1092 
1093     case RELOC_DLX_REL26:
1094       if (fixP->fx_bit_fixP != NULL)
1095 	{
1096 	  val = (val & 0x03FFFFFF) | fixP->fx_bit_fixP->fx_bit_base;
1097 	  free (fixP->fx_bit_fixP);
1098 	  fixP->fx_bit_fixP = NULL;
1099 	}
1100 #ifdef DEBUG
1101       else
1102 	know ((fixP->fx_bit_fixP != NULL));
1103 #endif
1104       break;
1105 
1106     case BFD_RELOC_VTABLE_INHERIT:
1107       /* This borrowed from tc-ppc.c on a whim.  */
1108       fixP->fx_done = 0;
1109       if (fixP->fx_addsy
1110 	  && !S_IS_DEFINED (fixP->fx_addsy)
1111 	  && !S_IS_WEAK (fixP->fx_addsy))
1112 	S_SET_WEAK (fixP->fx_addsy);
1113       return;
1114 
1115     case BFD_RELOC_VTABLE_ENTRY:
1116       fixP->fx_done = 0;
1117       return;
1118 
1119     default:
1120       break;
1121     }
1122 
1123   number_to_chars_bigendian (place, val, fixP->fx_size);
1124   if (fixP->fx_addsy == NULL)
1125     fixP->fx_done = 1;
1126 }
1127 
1128 const char *md_shortopts = "";
1129 
1130 struct option md_longopts[] =
1131   {
1132     {NULL, no_argument, NULL, 0}
1133   };
1134 
1135 size_t md_longopts_size = sizeof (md_longopts);
1136 
1137 int
1138 md_parse_option (int c     ATTRIBUTE_UNUSED,
1139 		 char *arg ATTRIBUTE_UNUSED)
1140 {
1141   return 0;
1142 }
1143 
1144 void
1145 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
1146 {
1147 }
1148 
1149 /* This is called when a line is unrecognized.  */
1150 
1151 int
1152 dlx_unrecognized_line (int c)
1153 {
1154   int lab;
1155   char *s;
1156 
1157   if (c != '$' || ! ISDIGIT ((unsigned char) input_line_pointer[0]))
1158     return 0;
1159 
1160   s = input_line_pointer;
1161 
1162   lab = 0;
1163   while (ISDIGIT ((unsigned char) *s))
1164     {
1165       lab = lab * 10 + *s - '0';
1166       ++s;
1167     }
1168 
1169   if (*s != ':')
1170     /* Not a label definition.  */
1171     return 0;
1172 
1173   if (dollar_label_defined (lab))
1174     {
1175       as_bad (_("label \"$%d\" redefined"), lab);
1176       return 0;
1177     }
1178 
1179   define_dollar_label (lab);
1180   colon (dollar_label_name (lab, 0));
1181   input_line_pointer = s + 1;
1182 
1183   return 1;
1184 }
1185 
1186 /* Default the values of symbols known that should be "predefined".  We
1187    don't bother to predefine them unless you actually use one, since there
1188    are a lot of them.  */
1189 
1190 symbolS *
1191 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1192 {
1193   return NULL;
1194 }
1195 
1196 /* Parse an operand that is machine-specific, the function was called
1197    in expr.c by operand() function, when everything failed before it
1198    call a quit.  */
1199 
1200 void
1201 md_operand (expressionS* expressionP)
1202 {
1203   /* Check for the #number representation    */
1204   if (input_line_pointer[0] == '#' &&
1205       ISDIGIT ((unsigned char) input_line_pointer[1]))
1206     {
1207       /* We have a numeric number expression.  No biggy.  */
1208       input_line_pointer += 1;	/* Skip # */
1209 
1210       (void) expression (expressionP);
1211 
1212       if (expressionP->X_op != O_constant)
1213 	as_bad (_("Invalid expression after # number\n"));
1214     }
1215 
1216   return;
1217 }
1218 
1219 /* Round up a section size to the appropriate boundary.  */
1220 
1221 valueT
1222 md_section_align (segT segment ATTRIBUTE_UNUSED,
1223 		  valueT size)
1224 {
1225   /* Byte alignment is fine.  */
1226   return size;
1227 }
1228 
1229 /* Exactly what point is a PC-relative offset relative TO?
1230    On the 29000, they're relative to the address of the instruction,
1231    which we have set up as the address of the fixup too.  */
1232 
1233 long
1234 md_pcrel_from (fixS* fixP)
1235 {
1236   return 4 + fixP->fx_where + fixP->fx_frag->fr_address;
1237 }
1238 
1239 /* Translate internal representation of relocation info to BFD target
1240    format.
1241    FIXME: To what extent can we get all relevant targets to use this?
1242    The above FIXME is from a29k, but I think it is also needed here.    */
1243 
1244 arelent *
1245 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1246 	      fixS *fixP)
1247 {
1248   arelent * reloc;
1249 
1250   reloc = xmalloc (sizeof (arelent));
1251   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
1252 
1253   if (reloc->howto == NULL)
1254     {
1255       as_bad_where (fixP->fx_file, fixP->fx_line,
1256 		    "internal error: can't export reloc type %d (`%s')",
1257 		    fixP->fx_r_type,
1258 		    bfd_get_reloc_code_name (fixP->fx_r_type));
1259       return NULL;
1260     }
1261 
1262   assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1263 
1264   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1265   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1266   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1267 
1268   if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1269     reloc->address = fixP->fx_offset;
1270   reloc->addend = 0;
1271 
1272   return reloc;
1273 }
1274 
1275 const pseudo_typeS
1276 dlx_pseudo_table[] =
1277 {
1278   /* Some additional ops that are used by gcc-dlx.  */
1279   {"asciiz", stringer, 1},
1280   {"half", cons, 2},
1281   {"dword", cons, 8},
1282   {"word", cons, 4},
1283   {"proc", s_proc, 0},
1284   {"endproc", s_proc, 1},
1285   {NULL, NULL, 0}
1286 };
1287 
1288 void
1289 dlx_pop_insert (void)
1290 {
1291   pop_insert (dlx_pseudo_table);
1292   return ;
1293 }
1294 
1295