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