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