-Wimplicit-fallthrough noreturn fixes
[external/binutils.git] / gas / config / tc-dlx.c
1 /* tc-dlx.c -- Assemble for the DLX
2    Copyright (C) 2002-2016 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 #include "elf/dlx.h"
28 #include "bfd/elf32-dlx.h"
29
30 /* Make it easier to clone this machine desc into another one.  */
31 #define machine_opcode      dlx_opcode
32 #define machine_opcodes     dlx_opcodes
33 #define machine_ip          dlx_ip
34 #define machine_it          dlx_it
35
36 #define NO_RELOC            BFD_RELOC_NONE
37 #define RELOC_DLX_REL26     BFD_RELOC_DLX_JMP26
38 #define RELOC_DLX_16        BFD_RELOC_16
39 #define RELOC_DLX_REL16     BFD_RELOC_16_PCREL_S2
40 #define RELOC_DLX_HI16      BFD_RELOC_HI16_S
41 #define RELOC_DLX_LO16      BFD_RELOC_LO16
42 #define RELOC_DLX_VTINHERIT BFD_RELOC_VTABLE_INHERIT
43 #define RELOC_DLX_VTENTRY   BFD_RELOC_VTABLE_ENTRY
44
45 /* handle of the OPCODE hash table */
46 static struct hash_control *op_hash = NULL;
47
48 struct machine_it
49 {
50   char *error;
51   unsigned long opcode;
52   struct nlist *nlistp;
53   expressionS exp;
54   int pcrel;
55   int size;
56   int reloc_offset;             /* Offset of reloc within insn.  */
57   bfd_reloc_code_real_type reloc;
58   int HI;
59   int LO;
60 }
61 the_insn;
62
63 /* This array holds the chars that always start a comment.  If the
64    pre-processor is disabled, these aren't very useful.  */
65 const char comment_chars[] = ";";
66
67 /* This array holds the chars that only start a comment at the beginning of
68    a line.  If the line seems to have the form '# 123 filename'
69    .line and .file directives will appear in the pre-processed output.  */
70 /* Note that input_file.c hand checks for '#' at the beginning of the
71    first line of the input file.  This is because the compiler outputs
72    #NO_APP at the beginning of its output.  */
73 /* Also note that comments like this one will always work.  */
74 const char line_comment_chars[] = "#";
75
76 /* We needed an unused char for line separation to work around the
77    lack of macros, using sed and such.  */
78 const char line_separator_chars[] = "@";
79
80 /* Chars that can be used to separate mant from exp in floating point nums.  */
81 const char EXP_CHARS[] = "eE";
82
83 /* Chars that mean this number is a floating point constant.
84    As in 0f12.456
85    or    0d1.2345e12.  */
86 const char FLT_CHARS[] = "rRsSfFdDxXpP";
87
88 static void
89 insert_sreg (const char *regname, int regnum)
90 {
91   /* Must be large enough to hold the names of the special registers.  */
92   char buf[80];
93   int i;
94
95   symbol_table_insert (symbol_new (regname, reg_section, (valueT) regnum,
96                                    &zero_address_frag));
97   for (i = 0; regname[i]; i++)
98     buf[i] = ISLOWER (regname[i]) ? TOUPPER (regname[i]) : regname[i];
99   buf[i] = '\0';
100
101   symbol_table_insert (symbol_new (buf, reg_section, (valueT) regnum,
102                                    &zero_address_frag));
103 }
104
105 /* Install symbol definitions for assorted special registers.
106    See MIPS Assembly Language Programmer's Guide page 1-4   */
107
108 static void
109 define_some_regs (void)
110 {
111   /* Software representation.  */
112   insert_sreg ("zero",  0);
113   insert_sreg ("at",    1);
114   insert_sreg ("v0",    2);
115   insert_sreg ("v1",    3);
116   insert_sreg ("a0",    4);
117   insert_sreg ("a1",    5);
118   insert_sreg ("a2",    6);
119   insert_sreg ("a3",    7);
120   insert_sreg ("t0",    8);
121   insert_sreg ("t1",    9);
122   insert_sreg ("t2",    10);
123   insert_sreg ("t3",    11);
124   insert_sreg ("t4",    12);
125   insert_sreg ("t5",    13);
126   insert_sreg ("t6",    14);
127   insert_sreg ("t7",    15);
128   insert_sreg ("s0",    16);
129   insert_sreg ("s1",    17);
130   insert_sreg ("s2",    18);
131   insert_sreg ("s3",    19);
132   insert_sreg ("s4",    20);
133   insert_sreg ("s5",    21);
134   insert_sreg ("s6",    22);
135   insert_sreg ("s7",    23);
136   insert_sreg ("t8",    24);
137   insert_sreg ("t9",    25);
138   insert_sreg ("k0",    26);
139   insert_sreg ("k1",    27);
140   insert_sreg ("gp",    28);
141   insert_sreg ("sp",    29);
142   insert_sreg ("fp",    30);
143   insert_sreg ("ra",    31);
144   /* Special registers.  */
145   insert_sreg ("pc",    0);
146   insert_sreg ("npc",   1);
147   insert_sreg ("iad",   2);
148 }
149
150 /* Subroutine check the string to match an register.  */
151
152 static int
153 match_sft_register (char *name)
154 {
155 #define MAX_REG_NO  35
156 /* Currently we have 35 software registers defined -
157    we borrowed from MIPS.   */
158   static const char *soft_reg[] =
159     {
160       "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
161       "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9",
162       "s0", "s1", "s2", "s3", "s4", "s5", "s7", "k0", "k1",
163       "gp", "sp", "fp", "ra", "pc", "npc", "iad",
164       "EndofTab"  /* End of the Table indicator */
165     };
166   char low_name[21], *ptr;
167   int idx;
168
169   for (ptr = name,idx = 0; *ptr != '\0'; ptr++)
170     low_name[idx++] = TOLOWER (*ptr);
171
172   low_name[idx] = '\0';
173   idx = 0;
174
175   while (idx < MAX_REG_NO && strcmp (soft_reg[idx], & low_name [0]))
176     idx += 1;
177
178   return idx < MAX_REG_NO;
179 }
180
181 /* Subroutine check the string to match an register.  */
182
183 static int
184 is_ldst_registers (char *name)
185 {
186   char *ptr = name;
187
188   /* The first character of the register name got to be either %, $, r of R.  */
189   if ((ptr[0] == '%' || ptr[0] == '$' || ptr[0] == 'r' || ptr[0] == 'R')
190       && ISDIGIT ((unsigned char) ptr[1]))
191     return 1;
192
193   /* Now check the software register representation.  */
194   return match_sft_register (ptr);
195 }
196
197 /* Subroutine of s_proc so targets can choose a different default prefix.
198    If DEFAULT_PREFIX is NULL, use the target's "leading char".  */
199
200 static void
201 s_proc (int end_p)
202 {
203   /* Record the current function so that we can issue an error message for
204      misplaced .func,.endfunc, and also so that .endfunc needs no
205      arguments.  */
206   static char *current_name;
207   static char *current_label;
208
209   if (end_p)
210     {
211       if (current_name == NULL)
212         {
213           as_bad (_("missing .proc"));
214           ignore_rest_of_line ();
215           return;
216         }
217
218       current_name = current_label = NULL;
219       SKIP_WHITESPACE ();
220       while (!is_end_of_line[(unsigned char) *input_line_pointer])
221         input_line_pointer++;
222     }
223   else
224     {
225       char *name, *label;
226       char delim1, delim2;
227
228       if (current_name != NULL)
229         {
230           as_bad (_(".endfunc missing for previous .proc"));
231           ignore_rest_of_line ();
232           return;
233         }
234
235       delim1 = get_symbol_name (&name);
236       name = xstrdup (name);
237       *input_line_pointer = delim1;
238       SKIP_WHITESPACE_AFTER_NAME ();
239
240       if (*input_line_pointer != ',')
241         {
242           char leading_char = 0;
243
244           leading_char = bfd_get_symbol_leading_char (stdoutput);
245           /* Missing entry point, use function's name with the leading
246              char prepended.  */
247           if (leading_char)
248             {
249               unsigned len = strlen (name) + 1;
250               label = XNEWVEC (char, len + 1);
251               label[0] = leading_char;
252               memcpy (label + 1, name, len);
253             }
254           else
255             label = name;
256         }
257       else
258         {
259           ++input_line_pointer;
260           SKIP_WHITESPACE ();
261           delim2 = get_symbol_name (&label);
262           label = xstrdup (label);
263           (void) restore_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 = XNEW (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 = XNEW (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 = XNEW (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 const 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                  const 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 = XNEW (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 = XNEW (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 }