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