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