This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.git] / gas / config / tc-dlx.c
1 /* tc-ldx.c -- Assemble for the DLX
2    Copyright 2002, 2003, 2004, 2005 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 2, 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;
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 = input_line_pointer;
645   input_line_pointer = save;
646   return new;
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.
979
980    Turn a string in input_line_pointer into a floating point constant
981    of type TYPE, and store the appropriate bytes in *LITP.  The number
982    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
983    returned, or NULL on OK.  */
984 /* Dlx will not use it anyway, so I just leave it here for now.  */
985
986 /* Equal to MAX_PRECISION in atof-ieee.c.  */
987 #define MAX_LITTLENUMS 6
988
989 char *
990 md_atof (int type, char *litP, int *sizeP)
991 {
992   int prec;
993   LITTLENUM_TYPE words[MAX_LITTLENUMS];
994   LITTLENUM_TYPE *wordP;
995   char *t;
996
997   switch (type)
998     {
999     case 'f':
1000     case 'F':
1001     case 's':
1002     case 'S':
1003       prec = 2;
1004       break;
1005
1006     case 'd':
1007     case 'D':
1008     case 'r':
1009     case 'R':
1010       prec = 4;
1011       break;
1012
1013     case 'x':
1014     case 'X':
1015       prec = 6;
1016       break;
1017
1018     case 'p':
1019     case 'P':
1020       prec = 6;
1021       break;
1022
1023     default:
1024       *sizeP = 0;
1025       return "Bad call to MD_ATOF()";
1026     }
1027
1028   t = atof_ieee (input_line_pointer, type, words);
1029   if (t)
1030     input_line_pointer = t;
1031
1032   *sizeP = prec * sizeof (LITTLENUM_TYPE);
1033
1034   for (wordP = words; prec--;)
1035     {
1036       md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
1037       litP += sizeof (LITTLENUM_TYPE);
1038     }
1039
1040   return 0;
1041 }
1042
1043 /* Write out big-endian.  */
1044 void
1045 md_number_to_chars (char *buf, valueT val, int n)
1046 {
1047   number_to_chars_bigendian (buf, val, n);
1048 }
1049
1050 bfd_boolean
1051 md_dlx_fix_adjustable (fixS *fixP)
1052 {
1053   /* We need the symbol name for the VTABLE entries.  */
1054   return (fixP->fx_r_type != BFD_RELOC_VTABLE_INHERIT
1055           && fixP->fx_r_type != BFD_RELOC_VTABLE_ENTRY);
1056 }
1057
1058 void
1059 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
1060 {
1061   long val = *valP;
1062   char *place = fixP->fx_where + fixP->fx_frag->fr_literal;
1063
1064   switch (fixP->fx_r_type)
1065     {
1066     case RELOC_DLX_LO16:
1067     case RELOC_DLX_REL16:
1068       if (fixP->fx_bit_fixP != NULL)
1069         {
1070           val = (val & 0x0000FFFF) | fixP->fx_bit_fixP->fx_bit_base;
1071           free (fixP->fx_bit_fixP);
1072           fixP->fx_bit_fixP = NULL;
1073         }
1074 #ifdef DEBUG
1075       else
1076         know ((fixP->fx_bit_fixP != NULL));
1077 #endif
1078       break;
1079
1080     case RELOC_DLX_HI16:
1081       if (fixP->fx_bit_fixP != NULL)
1082         {
1083           val = (val >> 16) | fixP->fx_bit_fixP->fx_bit_base;
1084           free (fixP->fx_bit_fixP);
1085           fixP->fx_bit_fixP = NULL;
1086         }
1087 #ifdef DEBUG
1088       else
1089         know ((fixP->fx_bit_fixP != NULL));
1090 #endif
1091       break;
1092
1093     case RELOC_DLX_REL26:
1094       if (fixP->fx_bit_fixP != NULL)
1095         {
1096           val = (val & 0x03FFFFFF) | fixP->fx_bit_fixP->fx_bit_base;
1097           free (fixP->fx_bit_fixP);
1098           fixP->fx_bit_fixP = NULL;
1099         }
1100 #ifdef DEBUG
1101       else
1102         know ((fixP->fx_bit_fixP != NULL));
1103 #endif
1104       break;
1105
1106     case BFD_RELOC_VTABLE_INHERIT:
1107       /* This borrowed from tc-ppc.c on a whim.  */
1108       fixP->fx_done = 0;
1109       if (fixP->fx_addsy
1110           && !S_IS_DEFINED (fixP->fx_addsy)
1111           && !S_IS_WEAK (fixP->fx_addsy))
1112         S_SET_WEAK (fixP->fx_addsy);
1113       return;
1114
1115     case BFD_RELOC_VTABLE_ENTRY:
1116       fixP->fx_done = 0;
1117       return;
1118
1119     default:
1120       break;
1121     }
1122
1123   number_to_chars_bigendian (place, val, fixP->fx_size);
1124   if (fixP->fx_addsy == NULL)
1125     fixP->fx_done = 1;
1126 }
1127
1128 const char *md_shortopts = "";
1129
1130 struct option md_longopts[] =
1131   {
1132     {NULL, no_argument, NULL, 0}
1133   };
1134
1135 size_t md_longopts_size = sizeof (md_longopts);
1136
1137 int
1138 md_parse_option (int c     ATTRIBUTE_UNUSED,
1139                  char *arg ATTRIBUTE_UNUSED)
1140 {
1141   return 0;
1142 }
1143
1144 void
1145 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
1146 {
1147 }
1148
1149 /* This is called when a line is unrecognized.  */
1150
1151 int
1152 dlx_unrecognized_line (int c)
1153 {
1154   int lab;
1155   char *s;
1156
1157   if (c != '$' || ! ISDIGIT ((unsigned char) input_line_pointer[0]))
1158     return 0;
1159
1160   s = input_line_pointer;
1161
1162   lab = 0;
1163   while (ISDIGIT ((unsigned char) *s))
1164     {
1165       lab = lab * 10 + *s - '0';
1166       ++s;
1167     }
1168
1169   if (*s != ':')
1170     /* Not a label definition.  */
1171     return 0;
1172
1173   if (dollar_label_defined (lab))
1174     {
1175       as_bad (_("label \"$%d\" redefined"), lab);
1176       return 0;
1177     }
1178
1179   define_dollar_label (lab);
1180   colon (dollar_label_name (lab, 0));
1181   input_line_pointer = s + 1;
1182
1183   return 1;
1184 }
1185
1186 /* Default the values of symbols known that should be "predefined".  We
1187    don't bother to predefine them unless you actually use one, since there
1188    are a lot of them.  */
1189
1190 symbolS *
1191 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1192 {
1193   return NULL;
1194 }
1195
1196 /* Parse an operand that is machine-specific, the function was called
1197    in expr.c by operand() function, when everything failed before it
1198    call a quit.  */
1199
1200 void
1201 md_operand (expressionS* expressionP)
1202 {
1203   /* Check for the #number representation    */
1204   if (input_line_pointer[0] == '#' &&
1205       ISDIGIT ((unsigned char) input_line_pointer[1]))
1206     {
1207       /* We have a numeric number expression.  No biggy.  */
1208       input_line_pointer += 1;  /* Skip # */
1209
1210       (void) expression (expressionP);
1211
1212       if (expressionP->X_op != O_constant)
1213         as_bad (_("Invalid expression after # number\n"));
1214     }
1215
1216   return;
1217 }
1218
1219 /* Round up a section size to the appropriate boundary.  */
1220
1221 valueT
1222 md_section_align (segT segment ATTRIBUTE_UNUSED,
1223                   valueT size)
1224 {
1225   /* Byte alignment is fine.  */
1226   return size;
1227 }
1228
1229 /* Exactly what point is a PC-relative offset relative TO?
1230    On the 29000, they're relative to the address of the instruction,
1231    which we have set up as the address of the fixup too.  */
1232
1233 long
1234 md_pcrel_from (fixS* fixP)
1235 {
1236   return 4 + fixP->fx_where + fixP->fx_frag->fr_address;
1237 }
1238
1239 /* Translate internal representation of relocation info to BFD target
1240    format.
1241    FIXME: To what extent can we get all relevant targets to use this?
1242    The above FIXME is from a29k, but I think it is also needed here.    */
1243
1244 arelent *
1245 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
1246               fixS *fixP)
1247 {
1248   arelent * reloc;
1249
1250   reloc = xmalloc (sizeof (arelent));
1251   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
1252
1253   if (reloc->howto == NULL)
1254     {
1255       as_bad_where (fixP->fx_file, fixP->fx_line,
1256                     "internal error: can't export reloc type %d (`%s')",
1257                     fixP->fx_r_type,
1258                     bfd_get_reloc_code_name (fixP->fx_r_type));
1259       return NULL;
1260     }
1261
1262   assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);
1263
1264   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
1265   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
1266   reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
1267
1268   if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
1269     reloc->address = fixP->fx_offset;
1270   reloc->addend = 0;
1271
1272   return reloc;
1273 }
1274
1275 const pseudo_typeS
1276 dlx_pseudo_table[] =
1277 {
1278   /* Some additional ops that are used by gcc-dlx.  */
1279   {"asciiz", stringer, 1},
1280   {"half", cons, 2},
1281   {"dword", cons, 8},
1282   {"word", cons, 4},
1283   {"proc", s_proc, 0},
1284   {"endproc", s_proc, 1},
1285   {NULL, NULL, 0}
1286 };
1287
1288 void
1289 dlx_pop_insert (void)
1290 {
1291   pop_insert (dlx_pseudo_table);
1292   return ;
1293 }
1294