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