OSDN Git Service

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