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