* config/tc-sparc.c (sparc_ip): Use strtol to parse membar
[external/binutils.git] / gas / config / tc-sparc.c
1 /* tc-sparc.c -- Assemble for the SPARC
2    Copyright (C) 1989, 1990, 1991, 1992 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
18    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #define cypress 1234
21
22 #include <stdio.h>
23 #include <ctype.h>
24
25 #include "as.h"
26
27 /* careful, this file includes data *declarations* */
28 #include "opcode/sparc.h"
29
30 static void sparc_ip PARAMS ((char *));
31
32 static enum sparc_architecture current_architecture = v6;
33 static int architecture_requested;
34 static int warn_on_bump;
35
36 extern int target_big_endian;
37
38 const relax_typeS md_relax_table[1];
39
40 /* handle of the OPCODE hash table */
41 static struct hash_control *op_hash = NULL;
42
43 static void s_data1 PARAMS ((void));
44 static void s_seg PARAMS ((int));
45 static void s_proc PARAMS ((int));
46 static void s_reserve PARAMS ((int));
47 static void s_common PARAMS ((int));
48
49 const pseudo_typeS md_pseudo_table[] =
50 {
51   {"align", s_align_bytes, 0},  /* Defaulting is invalid (0) */
52   {"common", s_common, 0},
53   {"global", s_globl, 0},
54   {"half", cons, 2},
55   {"optim", s_ignore, 0},
56   {"proc", s_proc, 0},
57   {"reserve", s_reserve, 0},
58   {"seg", s_seg, 0},
59   {"skip", s_space, 0},
60   {"word", cons, 4},
61 /* start-sanitize-v9 */
62 #ifndef NO_V9
63   {"xword", cons, 8},
64 #ifdef OBJ_ELF
65   {"uaxword", cons, 8},
66 #endif
67 #endif
68 /* end-sanitize-v9 */
69 #ifdef OBJ_ELF
70   /* these are specific to sparc/svr4 */
71   {"pushsection", obj_elf_section, 0},
72   {"popsection", obj_elf_previous, 0},
73   {"uaword", cons, 4},
74   {"uahalf", cons, 2},
75 #endif
76   {NULL, 0, 0},
77 };
78
79 const int md_short_jump_size = 4;
80 const int md_long_jump_size = 4;
81 const int md_reloc_size = 12;   /* Size of relocation record */
82
83 /* This array holds the chars that always start a comment.  If the
84    pre-processor is disabled, these aren't very useful */
85 const char comment_chars[] = "!";       /* JF removed '|' from comment_chars */
86
87 /* This array holds the chars that only start a comment at the beginning of
88    a line.  If the line seems to have the form '# 123 filename'
89    .line and .file directives will appear in the pre-processed output */
90 /* Note that input_file.c hand checks for '#' at the beginning of the
91    first line of the input file.  This is because the compiler outputs
92    #NO_APP at the beginning of its output. */
93 /* Also note that comments started like this one will always
94    work if '/' isn't otherwise defined. */
95 const char line_comment_chars[] = "#";
96
97 const char line_separator_chars[] = "";
98
99 /* Chars that can be used to separate mant from exp in floating point nums */
100 const char EXP_CHARS[] = "eE";
101
102 /* Chars that mean this number is a floating point constant */
103 /* As in 0f12.456 */
104 /* or    0d1.2345e12 */
105 const char FLT_CHARS[] = "rRsSfFdDxXpP";
106
107 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
108    changed in read.c.  Ideally it shouldn't have to know about it at all,
109    but nothing is ideal around here.  */
110
111 static unsigned char octal[256];
112 #define isoctal(c)  octal[(unsigned char) (c)]
113 static unsigned char toHex[256];
114
115 struct sparc_it
116   {
117     char *error;
118     unsigned long opcode;
119     struct nlist *nlistp;
120     expressionS exp;
121     int pcrel;
122     bfd_reloc_code_real_type reloc;
123   };
124
125 struct sparc_it the_insn, set_insn;
126
127 #if 0
128 static void print_insn PARAMS ((struct sparc_it *insn));
129 #endif
130 static int getExpression PARAMS ((char *str));
131
132 static char *expr_end;
133 static int special_case;
134
135 /*
136  * Instructions that require wierd handling because they're longer than
137  * 4 bytes.
138  */
139 #define SPECIAL_CASE_SET        1
140 #define SPECIAL_CASE_FDIV       2
141
142 /*
143  * sort of like s_lcomm
144  *
145  */
146 #ifndef OBJ_ELF
147 static int max_alignment = 15;
148 #endif
149
150 static void
151 s_reserve (ignore)
152      int ignore;
153 {
154   char *name;
155   char *p;
156   char c;
157   int align;
158   int size;
159   int temp;
160   symbolS *symbolP;
161
162   name = input_line_pointer;
163   c = get_symbol_end ();
164   p = input_line_pointer;
165   *p = c;
166   SKIP_WHITESPACE ();
167
168   if (*input_line_pointer != ',')
169     {
170       as_bad ("Expected comma after name");
171       ignore_rest_of_line ();
172       return;
173     }
174
175   ++input_line_pointer;
176
177   if ((size = get_absolute_expression ()) < 0)
178     {
179       as_bad ("BSS length (%d.) <0! Ignored.", size);
180       ignore_rest_of_line ();
181       return;
182     }                           /* bad length */
183
184   *p = 0;
185   symbolP = symbol_find_or_make (name);
186   *p = c;
187
188   if (strncmp (input_line_pointer, ",\"bss\"", 6) != 0
189       && strncmp (input_line_pointer, ",\".bss\"", 7) != 0)
190     {
191       as_bad ("bad .reserve segment: `%s'", input_line_pointer);
192       return;
193     }
194
195   if (input_line_pointer[2] == '.')
196     input_line_pointer += 7;
197   else
198     input_line_pointer += 6;
199   SKIP_WHITESPACE ();
200
201   if (*input_line_pointer == ',')
202     {
203       ++input_line_pointer;
204
205       SKIP_WHITESPACE ();
206       if (*input_line_pointer == '\n')
207         {
208           as_bad ("Missing alignment");
209           return;
210         }
211
212       align = get_absolute_expression ();
213 #ifndef OBJ_ELF
214       if (align > max_alignment)
215         {
216           align = max_alignment;
217           as_warn ("Alignment too large: %d. assumed.", align);
218         }
219 #endif
220       if (align < 0)
221         {
222           align = 0;
223           as_warn ("Alignment negative. 0 assumed.");
224         }
225
226       record_alignment (bss_section, align);
227
228       /* convert to a power of 2 alignment */
229       for (temp = 0; (align & 1) == 0; align >>= 1, ++temp);;
230
231       if (align != 1)
232         {
233           as_bad ("Alignment not a power of 2");
234           ignore_rest_of_line ();
235           return;
236         }                       /* not a power of two */
237
238       align = temp;
239     }                           /* if has optional alignment */
240   else
241     align = 0;
242
243   if ((S_GET_SEGMENT (symbolP) == bss_section
244        || !S_IS_DEFINED (symbolP))
245 #ifdef OBJ_AOUT
246       && S_GET_OTHER (symbolP) == 0
247       && S_GET_DESC (symbolP) == 0
248 #endif
249       )
250     {
251       if (! need_pass_2)
252         {
253           char *pfrag;
254           segT current_seg = now_seg;
255           subsegT current_subseg = now_subseg;
256
257           subseg_set (bss_section, 1); /* switch to bss */
258
259           if (align)
260             frag_align (align, 0); /* do alignment */
261
262           /* detach from old frag */
263           if (S_GET_SEGMENT(symbolP) == bss_section)
264             symbolP->sy_frag->fr_symbol = NULL;
265
266           symbolP->sy_frag = frag_now;
267           pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
268                             size, (char *)0);
269           *pfrag = 0;
270
271           S_SET_SEGMENT (symbolP, bss_section);
272
273           subseg_set (current_seg, current_subseg);
274         }
275     }
276   else
277     {
278       as_warn("Ignoring attempt to re-define symbol %s.", name);
279     }                           /* if not redefining */
280
281   demand_empty_rest_of_line ();
282 }
283
284 static void
285 s_common (ignore)
286      int ignore;
287 {
288   char *name;
289   char c;
290   char *p;
291   int temp, size;
292   symbolS *symbolP;
293
294   name = input_line_pointer;
295   c = get_symbol_end ();
296   /* just after name is now '\0' */
297   p = input_line_pointer;
298   *p = c;
299   SKIP_WHITESPACE ();
300   if (*input_line_pointer != ',')
301     {
302       as_bad ("Expected comma after symbol-name");
303       ignore_rest_of_line ();
304       return;
305     }
306   input_line_pointer++;         /* skip ',' */
307   if ((temp = get_absolute_expression ()) < 0)
308     {
309       as_bad (".COMMon length (%d.) <0! Ignored.", temp);
310       ignore_rest_of_line ();
311       return;
312     }
313   size = temp;
314   *p = 0;
315   symbolP = symbol_find_or_make (name);
316   *p = c;
317   if (S_IS_DEFINED (symbolP))
318     {
319       as_bad ("Ignoring attempt to re-define symbol");
320       ignore_rest_of_line ();
321       return;
322     }
323   if (S_GET_VALUE (symbolP) != 0)
324     {
325       if (S_GET_VALUE (symbolP) != size)
326         {
327           as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
328                    S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
329         }
330     }
331   else
332     {
333 #ifndef OBJ_ELF
334       S_SET_VALUE (symbolP, (valueT) size);
335       S_SET_EXTERNAL (symbolP);
336 #endif
337     }
338   know (symbolP->sy_frag == &zero_address_frag);
339   if (*input_line_pointer != ',')
340     {
341       as_bad ("Expected comma after common length");
342       ignore_rest_of_line ();
343       return;
344     }
345   input_line_pointer++;
346   SKIP_WHITESPACE ();
347   if (*input_line_pointer != '"')
348     {
349       temp = get_absolute_expression ();
350 #ifndef OBJ_ELF
351       if (temp > max_alignment)
352         {
353           temp = max_alignment;
354           as_warn ("Common alignment too large: %d. assumed", temp);
355         }
356 #endif
357       if (temp < 0)
358         {
359           temp = 0;
360           as_warn ("Common alignment negative; 0 assumed");
361         }
362 #ifdef OBJ_ELF
363       if (symbolP->local)
364         {
365           segT old_sec;
366           int old_subsec;
367           char *p;
368           int align;
369
370         allocate_bss:
371           old_sec = now_seg;
372           old_subsec = now_subseg;
373           align = temp;
374           record_alignment (bss_section, align);
375           subseg_set (bss_section, 0);
376           if (align)
377             frag_align (align, 0);
378           if (S_GET_SEGMENT (symbolP) == bss_section)
379             symbolP->sy_frag->fr_symbol = 0;
380           symbolP->sy_frag = frag_now;
381           p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
382                         (char *) 0);
383           *p = 0;
384           S_SET_SEGMENT (symbolP, bss_section);
385           S_CLEAR_EXTERNAL (symbolP);
386           subseg_set (old_sec, old_subsec);
387         }
388       else
389 #endif
390         {
391         allocate_common:
392           S_SET_VALUE (symbolP, (valueT) size);
393           S_SET_EXTERNAL (symbolP);
394           /* should be common, but this is how gas does it for now */
395           S_SET_SEGMENT (symbolP, &bfd_und_section);
396         }
397     }
398   else
399     {
400       input_line_pointer++;
401       /* @@ Some use the dot, some don't.  Can we get some consistency??  */
402       if (*input_line_pointer == '.')
403         input_line_pointer++;
404       /* @@ Some say data, some say bss.  */
405       if (strncmp (input_line_pointer, "bss\"", 4)
406           && strncmp (input_line_pointer, "data\"", 5))
407         {
408           while (*--input_line_pointer != '"')
409             ;
410           input_line_pointer--;
411           goto bad_common_segment;
412         }
413       while (*input_line_pointer++ != '"')
414         ;
415       goto allocate_common;
416     }
417   demand_empty_rest_of_line ();
418   return;
419
420   {
421   bad_common_segment:
422     p = input_line_pointer;
423     while (*p && *p != '\n')
424       p++;
425     c = *p;
426     *p = '\0';
427     as_bad ("bad .common segment %s", input_line_pointer + 1);
428     *p = c;
429     input_line_pointer = p;
430     ignore_rest_of_line ();
431     return;
432   }
433 }
434
435 static void
436 s_seg (ignore)
437      int ignore;
438 {
439
440   if (strncmp (input_line_pointer, "\"text\"", 6) == 0)
441     {
442       input_line_pointer += 6;
443       s_text (0);
444       return;
445     }
446   if (strncmp (input_line_pointer, "\"data\"", 6) == 0)
447     {
448       input_line_pointer += 6;
449       s_data (0);
450       return;
451     }
452   if (strncmp (input_line_pointer, "\"data1\"", 7) == 0)
453     {
454       input_line_pointer += 7;
455       s_data1 ();
456       return;
457     }
458   if (strncmp (input_line_pointer, "\"bss\"", 5) == 0)
459     {
460       input_line_pointer += 5;
461       /* We only support 2 segments -- text and data -- for now, so
462          things in the "bss segment" will have to go into data for now.
463          You can still allocate SEG_BSS stuff with .lcomm or .reserve. */
464       subseg_set (data_section, 255);   /* FIXME-SOMEDAY */
465       return;
466     }
467   as_bad ("Unknown segment type");
468   demand_empty_rest_of_line ();
469   return;
470 }                               /* s_seg() */
471
472 static void
473 s_data1 ()
474 {
475   subseg_set (data_section, 1);
476   demand_empty_rest_of_line ();
477   return;
478 }                               /* s_data1() */
479
480 static void
481 s_proc (ignore)
482      int ignore;
483 {
484   while (!is_end_of_line[(unsigned char) *input_line_pointer])
485     {
486       ++input_line_pointer;
487     }
488   ++input_line_pointer;
489   return;
490 }                               /* s_proc() */
491
492 /* start-sanitize-v9 */
493 #ifndef NO_V9
494
495 struct priv_reg_entry
496   {
497     char *name;
498     int regnum;
499   };
500
501 struct priv_reg_entry priv_reg_table[] =
502 {
503   {"tpc", 0},
504   {"tnpc", 1},
505   {"tstate", 2},
506   {"tt", 3},
507   {"tick", 4},
508   {"tba", 5},
509   {"pstate", 6},
510   {"tl", 7},
511   {"pil", 8},
512   {"cwp", 9},
513   {"cansave", 10},
514   {"canrestore", 11},
515   {"cleanwin", 12},
516   {"otherwin", 13},
517   {"wstate", 14},
518   {"fq", 15},
519   {"ver", 31},
520   {"", -1},                     /* end marker */
521 };
522
523 struct membar_masks
524 {
525   char *name;
526   unsigned int len;
527   unsigned int mask;
528 };
529
530 #define MEMBAR_MASKS_SIZE 7
531
532 struct membar_masks membar_masks[MEMBAR_MASKS_SIZE] =
533 {
534   {"Sync", 4, 0x40},
535   {"MemIssue", 8, 0x20},
536   {"Lookaside", 9, 0x10},
537   {"StoreStore", 10, 0x08},
538   {"LoadStore", 9, 0x04},
539   {"StoreLoad", 9, 0x02},
540   {"LoadLoad", 8, 0x01},
541 };
542
543 static int
544 cmp_reg_entry (p, q)
545      struct priv_reg_entry *p, *q;
546 {
547   return strcmp (q->name, p->name);
548 }
549
550 #endif
551 /* end-sanitize-v9 */
552
553 /* This function is called once, at assembler startup time.  It should
554    set up all the tables, etc. that the MD part of the assembler will need. */
555 void
556 md_begin ()
557 {
558   register const char *retval = NULL;
559   int lose = 0;
560   register unsigned int i = 0;
561
562   op_hash = hash_new ();
563   if (op_hash == NULL)
564     as_fatal ("Virtual memory exhausted");
565
566   while (i < NUMOPCODES)
567     {
568       const char *name = sparc_opcodes[i].name;
569       retval = hash_insert (op_hash, name, &sparc_opcodes[i]);
570       if (retval != NULL)
571         {
572           fprintf (stderr, "internal error: can't hash `%s': %s\n",
573                    sparc_opcodes[i].name, retval);
574           lose = 1;
575         }
576       do
577         {
578           if (sparc_opcodes[i].match & sparc_opcodes[i].lose)
579             {
580               fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n",
581                        sparc_opcodes[i].name, sparc_opcodes[i].args);
582               lose = 1;
583             }
584           ++i;
585         }
586       while (i < NUMOPCODES
587              && !strcmp (sparc_opcodes[i].name, name));
588     }
589
590   if (lose)
591     as_fatal ("Broken assembler.  No assembly attempted.");
592
593   for (i = '0'; i < '8'; ++i)
594     octal[i] = 1;
595   for (i = '0'; i <= '9'; ++i)
596     toHex[i] = i - '0';
597   for (i = 'a'; i <= 'f'; ++i)
598     toHex[i] = i + 10 - 'a';
599   for (i = 'A'; i <= 'F'; ++i)
600     toHex[i] = i + 10 - 'A';
601
602   /* start-sanitize-v9 */
603 #ifndef NO_V9
604 #ifdef sparcv9
605   current_architecture = v9;
606 #endif
607
608   qsort (priv_reg_table, sizeof (priv_reg_table) / sizeof (priv_reg_table[0]),
609          sizeof (priv_reg_table[0]), cmp_reg_entry);
610 #endif
611   /* end-sanitize-v9 */
612
613   target_big_endian = 1;
614 }
615
616 void
617 md_assemble (str)
618      char *str;
619 {
620   char *toP;
621   int rsd;
622
623   know (str);
624   sparc_ip (str);
625
626   /* See if "set" operand is absolute and small; skip sethi if so. */
627   if (special_case == SPECIAL_CASE_SET
628       && the_insn.exp.X_op == O_constant)
629     {
630       if (the_insn.exp.X_add_number >= -(1 << 12)
631           && the_insn.exp.X_add_number < (1 << 12))
632         {
633           the_insn.opcode = 0x80102000  /* or %g0,imm,... */
634             | (the_insn.opcode & 0x3E000000)    /* dest reg */
635             | (the_insn.exp.X_add_number & 0x1FFF);     /* imm */
636           special_case = 0;     /* No longer special */
637           the_insn.reloc = BFD_RELOC_NONE;      /* No longer relocated */
638         }
639     }
640
641   toP = frag_more (4);
642   /* put out the opcode */
643   md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
644
645   /* put out the symbol-dependent stuff */
646   if (the_insn.reloc != BFD_RELOC_NONE)
647     {
648       fix_new_exp (frag_now,    /* which frag */
649                    (toP - frag_now->fr_literal),        /* where */
650                    4,           /* size */
651                    &the_insn.exp,
652                    the_insn.pcrel,
653                    the_insn.reloc);
654     }
655
656   switch (special_case)
657     {
658     case SPECIAL_CASE_SET:
659       special_case = 0;
660       assert (the_insn.reloc == BFD_RELOC_HI22);
661       /* See if "set" operand has no low-order bits; skip OR if so. */
662       if (the_insn.exp.X_op == O_constant
663           && ((the_insn.exp.X_add_number & 0x3FF) == 0))
664         return;
665       toP = frag_more (4);
666       rsd = (the_insn.opcode >> 25) & 0x1f;
667       the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14);
668       md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
669       fix_new_exp (frag_now,    /* which frag */
670                    (toP - frag_now->fr_literal),        /* where */
671                    4,           /* size */
672                    &the_insn.exp,
673                    the_insn.pcrel,
674                    BFD_RELOC_LO10);
675       return;
676
677     case SPECIAL_CASE_FDIV:
678       /* According to information leaked from Sun, the "fdiv" instructions
679          on early SPARC machines would produce incorrect results sometimes.
680          The workaround is to add an fmovs of the destination register to
681          itself just after the instruction.  This was true on machines
682          with Weitek 1165 float chips, such as the Sun-4/260 and /280. */
683       special_case = 0;
684       assert (the_insn.reloc == BFD_RELOC_NONE);
685       toP = frag_more (4);
686       rsd = (the_insn.opcode >> 25) & 0x1f;
687       the_insn.opcode = 0x81A00020 | (rsd << 25) | rsd; /* fmovs dest,dest */
688       md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
689       return;
690
691     case 0:
692       return;
693
694     default:
695       as_fatal ("failed sanity check.");
696     }
697 }
698
699 static void
700 sparc_ip (str)
701      char *str;
702 {
703   char *error_message = "";
704   char *s;
705   const char *args;
706   char c;
707   struct sparc_opcode *insn;
708   char *argsStart;
709   unsigned long opcode;
710   unsigned int mask = 0;
711   int match = 0;
712   int comma = 0;
713   long immediate_max = 0;
714
715   for (s = str; islower (*s) || (*s >= '0' && *s <= '3'); ++s)
716     ;
717   switch (*s)
718     {
719
720     case '\0':
721       break;
722
723     case ',':
724       comma = 1;
725
726       /*FALLTHROUGH */
727
728     case ' ':
729       *s++ = '\0';
730       break;
731
732     default:
733       as_bad ("Unknown opcode: `%s'", str);
734       exit (1);
735     }
736   if ((insn = (struct sparc_opcode *) hash_find (op_hash, str)) == NULL)
737     {
738       as_bad ("Unknown opcode: `%s'", str);
739       return;
740     }
741   if (comma)
742     {
743       *--s = ',';
744     }
745   argsStart = s;
746   for (;;)
747     {
748       opcode = insn->match;
749       memset (&the_insn, '\0', sizeof (the_insn));
750       the_insn.reloc = BFD_RELOC_NONE;
751
752       /*
753        * Build the opcode, checking as we go to make
754        * sure that the operands match
755        */
756       for (args = insn->args;; ++args)
757         {
758           switch (*args)
759             {
760
761               /* start-sanitize-v9 */
762 #ifndef NO_V9
763             case 'K':
764               {
765                 int kmask = 0;
766                 int i;
767
768                 /* Parse a series of masks.  */
769                 if (*s == '#')
770                   {
771                     while (*s == '#')
772                       {
773                         ++s;
774                         for (i = 0; i < MEMBAR_MASKS_SIZE; i++)
775                           if (!strncmp (s, membar_masks[i].name,
776                                         membar_masks[i].len))
777                             break;
778                         if (i < MEMBAR_MASKS_SIZE)
779                           {
780                             kmask |= membar_masks[i].mask;
781                             s += membar_masks[i].len;
782                           }
783                         else
784                           {
785                             error_message = ": invalid membar mask name";
786                             goto error;
787                           }
788                         if (*s == '|')
789                           ++s;
790                       }
791                   }
792                 else if (isdigit (*s))
793                   {
794                     char *send;
795
796                     kmask = strtol (s, &send, 0);
797                     if (kmask < 0 || kmask > 127)
798                       {
799                         error_message = ": invalid membar mask number";
800                         goto error;
801                       }
802                     s = send;
803                   }
804                 else
805                   {
806                     error_message = ": unrecognizable membar mask";
807                     goto error;
808                   }
809                 opcode |= SIMM13 (kmask);
810                 continue;
811               }
812
813             case '*':
814               {
815                 int prefetch_fcn = 0;
816
817                 /* Parse a prefetch function.  */
818                 if (*s == '#')
819                   {
820                     s += 1;
821                     if (!strncmp (s, "n_reads", 7))
822                       prefetch_fcn = 0, s += 7;
823                     else if (!strncmp (s, "one_read", 8))
824                       prefetch_fcn = 1, s += 8;
825                     else if (!strncmp (s, "n_writes", 8))
826                       prefetch_fcn = 2, s += 8;
827                     else if (!strncmp (s, "one_write", 9))
828                       prefetch_fcn = 3, s += 9;
829                     else if (!strncmp (s, "page", 4))
830                       prefetch_fcn = 4, s += 4;
831                     else
832                       {
833                         error_message = ": invalid prefetch function name";
834                         goto error;
835                       }
836                   }
837                 else if (isdigit (*s))
838                   {
839                     while (isdigit (*s))
840                       {
841                         prefetch_fcn = prefetch_fcn * 10 + *s - '0';
842                         ++s;
843                       }
844
845                     if (prefetch_fcn < 0 || prefetch_fcn > 31)
846                       {
847                         error_message = ": invalid prefetch function number";
848                         goto error;
849                       }
850                   }
851                 else
852                   {
853                     error_message = ": unrecognizable prefetch function";
854                     goto error;
855                   }
856                 opcode |= RD (prefetch_fcn);
857                 continue;
858               }
859
860             case '!':
861             case '?':
862               /* Parse a privileged register.  */
863               if (*s == '%')
864                 {
865                   struct priv_reg_entry *p = priv_reg_table;
866                   unsigned int len = 9999999; /* init to make gcc happy */
867
868                   s += 1;
869                   while (p->name[0] > s[0])
870                     p++;
871                   while (p->name[0] == s[0])
872                     {
873                       len = strlen (p->name);
874                       if (strncmp (p->name, s, len) == 0)
875                         break;
876                       p++;
877                     }
878                   if (p->name[0] != s[0])
879                     {
880                       error_message = ": unrecognizable privileged register";
881                       goto error;
882                     }
883                   if (*args == '?')
884                     opcode |= (p->regnum << 14);
885                   else
886                     opcode |= (p->regnum << 25);
887                   s += len;
888                   continue;
889                 }
890               else
891                 {
892                   error_message = ": unrecognizable privileged register";
893                   goto error;
894                 }
895 #endif
896               /* end-sanitize-v9 */
897
898             case 'M':
899             case 'm':
900               if (strncmp (s, "%asr", 4) == 0)
901                 {
902                   s += 4;
903
904                   if (isdigit (*s))
905                     {
906                       long num = 0;
907
908                       while (isdigit (*s))
909                         {
910                           num = num * 10 + *s - '0';
911                           ++s;
912                         }
913
914                       if (num < 16 || 31 < num)
915                         {
916                           error_message = ": asr number must be between 15 and 31";
917                           goto error;
918                         }       /* out of range */
919
920                       opcode |= (*args == 'M' ? RS1 (num) : RD (num));
921                       continue;
922                     }
923                   else
924                     {
925                       error_message = ": expecting %asrN";
926                       goto error;
927                     }           /* if %asr followed by a number. */
928
929                 }               /* if %asr */
930               break;
931
932               /* start-sanitize-v9 */
933 #ifndef NO_V9
934             case 'I':
935               the_insn.reloc = BFD_RELOC_SPARC_11;
936               immediate_max = 0x03FF;
937               goto immediate;
938
939             case 'j':
940               the_insn.reloc = BFD_RELOC_SPARC_10;
941               immediate_max = 0x01FF;
942               goto immediate;
943
944             case 'k':
945               the_insn.reloc = /* RELOC_WDISP2_14 */ BFD_RELOC_SPARC_WDISP16;
946               the_insn.pcrel = 1;
947               goto immediate;
948
949             case 'G':
950               the_insn.reloc = BFD_RELOC_SPARC_WDISP19;
951               the_insn.pcrel = 1;
952               goto immediate;
953
954             case 'N':
955               if (*s == 'p' && s[1] == 'n')
956                 {
957                   s += 2;
958                   continue;
959                 }
960               break;
961
962             case 'T':
963               if (*s == 'p' && s[1] == 't')
964                 {
965                   s += 2;
966                   continue;
967                 }
968               break;
969
970             case 'z':
971               if (*s == ' ')
972                 {
973                   ++s;
974                 }
975               if (strncmp (s, "%icc", 4) == 0)
976                 {
977                   s += 4;
978                   continue;
979                 }
980               break;
981
982             case 'Z':
983               if (*s == ' ')
984                 {
985                   ++s;
986                 }
987               if (strncmp (s, "%xcc", 4) == 0)
988                 {
989                   s += 4;
990                   continue;
991                 }
992               break;
993
994             case '6':
995               if (*s == ' ')
996                 {
997                   ++s;
998                 }
999               if (strncmp (s, "%fcc0", 5) == 0)
1000                 {
1001                   s += 5;
1002                   continue;
1003                 }
1004               break;
1005
1006             case '7':
1007               if (*s == ' ')
1008                 {
1009                   ++s;
1010                 }
1011               if (strncmp (s, "%fcc1", 5) == 0)
1012                 {
1013                   s += 5;
1014                   continue;
1015                 }
1016               break;
1017
1018             case '8':
1019               if (*s == ' ')
1020                 {
1021                   ++s;
1022                 }
1023               if (strncmp (s, "%fcc2", 5) == 0)
1024                 {
1025                   s += 5;
1026                   continue;
1027                 }
1028               break;
1029
1030             case '9':
1031               if (*s == ' ')
1032                 {
1033                   ++s;
1034                 }
1035               if (strncmp (s, "%fcc3", 5) == 0)
1036                 {
1037                   s += 5;
1038                   continue;
1039                 }
1040               break;
1041
1042             case 'P':
1043               if (strncmp (s, "%pc", 3) == 0)
1044                 {
1045                   s += 3;
1046                   continue;
1047                 }
1048               break;
1049
1050             case 'W':
1051               if (strncmp (s, "%tick", 5) == 0)
1052                 {
1053                   s += 5;
1054                   continue;
1055                 }
1056               break;
1057 #endif /* NO_V9 */
1058               /* end-sanitize-v9 */
1059
1060             case '\0':          /* end of args */
1061               if (*s == '\0')
1062                 {
1063                   match = 1;
1064                 }
1065               break;
1066
1067             case '+':
1068               if (*s == '+')
1069                 {
1070                   ++s;
1071                   continue;
1072                 }
1073               if (*s == '-')
1074                 {
1075                   continue;
1076                 }
1077               break;
1078
1079             case '[':           /* these must match exactly */
1080             case ']':
1081             case ',':
1082             case ' ':
1083               if (*s++ == *args)
1084                 continue;
1085               break;
1086
1087             case '#':           /* must be at least one digit */
1088               if (isdigit (*s++))
1089                 {
1090                   while (isdigit (*s))
1091                     {
1092                       ++s;
1093                     }
1094                   continue;
1095                 }
1096               break;
1097
1098             case 'C':           /* coprocessor state register */
1099               if (strncmp (s, "%csr", 4) == 0)
1100                 {
1101                   s += 4;
1102                   continue;
1103                 }
1104               break;
1105
1106             case 'b':           /* next operand is a coprocessor register */
1107             case 'c':
1108             case 'D':
1109               if (*s++ == '%' && *s++ == 'c' && isdigit (*s))
1110                 {
1111                   mask = *s++;
1112                   if (isdigit (*s))
1113                     {
1114                       mask = 10 * (mask - '0') + (*s++ - '0');
1115                       if (mask >= 32)
1116                         {
1117                           break;
1118                         }
1119                     }
1120                   else
1121                     {
1122                       mask -= '0';
1123                     }
1124                   switch (*args)
1125                     {
1126
1127                     case 'b':
1128                       opcode |= mask << 14;
1129                       continue;
1130
1131                     case 'c':
1132                       opcode |= mask;
1133                       continue;
1134
1135                     case 'D':
1136                       opcode |= mask << 25;
1137                       continue;
1138                     }
1139                 }
1140               break;
1141
1142             case 'r':           /* next operand must be a register */
1143             case '1':
1144             case '2':
1145             case 'd':
1146               if (*s++ == '%')
1147                 {
1148                   switch (c = *s++)
1149                     {
1150
1151                     case 'f':   /* frame pointer */
1152                       if (*s++ == 'p')
1153                         {
1154                           mask = 0x1e;
1155                           break;
1156                         }
1157                       goto error;
1158
1159                     case 'g':   /* global register */
1160                       if (isoctal (c = *s++))
1161                         {
1162                           mask = c - '0';
1163                           break;
1164                         }
1165                       goto error;
1166
1167                     case 'i':   /* in register */
1168                       if (isoctal (c = *s++))
1169                         {
1170                           mask = c - '0' + 24;
1171                           break;
1172                         }
1173                       goto error;
1174
1175                     case 'l':   /* local register */
1176                       if (isoctal (c = *s++))
1177                         {
1178                           mask = (c - '0' + 16);
1179                           break;
1180                         }
1181                       goto error;
1182
1183                     case 'o':   /* out register */
1184                       if (isoctal (c = *s++))
1185                         {
1186                           mask = (c - '0' + 8);
1187                           break;
1188                         }
1189                       goto error;
1190
1191                     case 's':   /* stack pointer */
1192                       if (*s++ == 'p')
1193                         {
1194                           mask = 0xe;
1195                           break;
1196                         }
1197                       goto error;
1198
1199                     case 'r':   /* any register */
1200                       if (!isdigit (c = *s++))
1201                         {
1202                           goto error;
1203                         }
1204                       /* FALLTHROUGH */
1205                     case '0':
1206                     case '1':
1207                     case '2':
1208                     case '3':
1209                     case '4':
1210                     case '5':
1211                     case '6':
1212                     case '7':
1213                     case '8':
1214                     case '9':
1215                       if (isdigit (*s))
1216                         {
1217                           if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
1218                             {
1219                               goto error;
1220                             }
1221                         }
1222                       else
1223                         {
1224                           c -= '0';
1225                         }
1226                       mask = c;
1227                       break;
1228
1229                     default:
1230                       goto error;
1231                     }
1232                   /*
1233                                          * Got the register, now figure out where
1234                                          * it goes in the opcode.
1235                                          */
1236                   switch (*args)
1237                     {
1238
1239                     case '1':
1240                       opcode |= mask << 14;
1241                       continue;
1242
1243                     case '2':
1244                       opcode |= mask;
1245                       continue;
1246
1247                     case 'd':
1248                       opcode |= mask << 25;
1249                       continue;
1250
1251                     case 'r':
1252                       opcode |= (mask << 25) | (mask << 14);
1253                       continue;
1254                     }
1255                 }
1256               break;
1257
1258             case 'e':           /* next operand is a floating point register */
1259             case 'v':
1260             case 'V':
1261
1262             case 'f':
1263             case 'B':
1264             case 'R':
1265
1266             case 'g':
1267             case 'H':
1268             case 'J':
1269               {
1270                 char format;
1271
1272                 if (*s++ == '%'
1273                     && ((format = *s) == 'f')
1274                     && isdigit (*++s))
1275                   {
1276                     for (mask = 0; isdigit (*s); ++s)
1277                       {
1278                         mask = 10 * mask + (*s - '0');
1279                       }         /* read the number */
1280
1281                     if ((*args == 'v'
1282                          || *args == 'B'
1283                          || *args == 'H')
1284                         && (mask & 1))
1285                       {
1286                         break;
1287                       }         /* register must be even numbered */
1288
1289                     if ((*args == 'V'
1290                          || *args == 'R'
1291                          || *args == 'J')
1292                         && (mask & 3))
1293                       {
1294                         break;
1295                       }         /* register must be multiple of 4 */
1296
1297 /* start-sanitize-v9 */
1298 #ifndef NO_V9
1299                     if (mask >= 64)
1300                       {
1301                         error_message = ": There are only 64 f registers; [0-63]";
1302                         goto error;
1303                       } /* on error */
1304                     if (mask >= 32)
1305                       {
1306                         mask -= 31;
1307                       } /* wrap high bit */
1308 #else
1309 /* end-sanitize-v9 */
1310                     if (mask >= 32)
1311                       {
1312                         error_message = ": There are only 32 f registers; [0-31]";
1313                         goto error;
1314                       } /* on error */
1315 /* start-sanitize-v9 */
1316 #endif
1317 /* end-sanitize-v9 */
1318                   }
1319                 else
1320                   {
1321                     break;
1322                   }     /* if not an 'f' register. */
1323
1324                 switch (*args)
1325                   {
1326
1327                   case 'v':
1328                   case 'V':
1329                   case 'e':
1330                     opcode |= RS1 (mask);
1331                     continue;
1332
1333
1334                   case 'f':
1335                   case 'B':
1336                   case 'R':
1337                     opcode |= RS2 (mask);
1338                     continue;
1339
1340                   case 'g':
1341                   case 'H':
1342                   case 'J':
1343                     opcode |= RD (mask);
1344                     continue;
1345                   }             /* pack it in. */
1346
1347                 know (0);
1348                 break;
1349               }                 /* float arg */
1350
1351             case 'F':
1352               if (strncmp (s, "%fsr", 4) == 0)
1353                 {
1354                   s += 4;
1355                   continue;
1356                 }
1357               break;
1358
1359             case 'h':           /* high 22 bits */
1360               the_insn.reloc = BFD_RELOC_HI22;
1361               goto immediate;
1362
1363             case 'l':           /* 22 bit PC relative immediate */
1364               the_insn.reloc = BFD_RELOC_SPARC_WDISP22;
1365               the_insn.pcrel = 1;
1366               goto immediate;
1367
1368             case 'L':           /* 30 bit immediate */
1369               the_insn.reloc = BFD_RELOC_32_PCREL_S2;
1370               the_insn.pcrel = 1;
1371               goto immediate;
1372
1373             case 'n':           /* 22 bit immediate */
1374               the_insn.reloc = BFD_RELOC_SPARC22;
1375               goto immediate;
1376
1377             case 'i':           /* 13 bit immediate */
1378               /* What's the difference between base13 and 13?  */
1379               the_insn.reloc = BFD_RELOC_SPARC_BASE13;
1380               immediate_max = 0x0FFF;
1381
1382               /*FALLTHROUGH */
1383
1384             immediate:
1385               if (*s == ' ')
1386                 s++;
1387               if (*s == '%')
1388                 {
1389                   if ((c = s[1]) == 'h' && s[2] == 'i')
1390                     {
1391                       the_insn.reloc = BFD_RELOC_HI22;
1392                       s += 3;
1393                     }
1394                   else if (c == 'l' && s[2] == 'o')
1395                     {
1396                       the_insn.reloc = BFD_RELOC_LO10;
1397                       s += 3;
1398                     }
1399                   /* start-sanitize-v9 */
1400 #ifndef NO_V9
1401                   else if (c == 'u'
1402                            && s[2] == 'h'
1403                            && s[3] == 'i')
1404                     {
1405                       the_insn.reloc = BFD_RELOC_SPARC_HH22;
1406                       s += 4;
1407                     }
1408                   else if (c == 'u'
1409                            && s[2] == 'l'
1410                            && s[3] == 'o')
1411                     {
1412                       the_insn.reloc = BFD_RELOC_SPARC_HM10;
1413                       s += 4;
1414                     }
1415 #endif /* NO_V9 */
1416                   /* end-sanitize-v9 */
1417                   else
1418                     break;
1419                 }
1420               /* Note that if the getExpression() fails, we will still
1421                  have created U entries in the symbol table for the
1422                  'symbols' in the input string.  Try not to create U
1423                  symbols for registers, etc.  */
1424               {
1425                 /* This stuff checks to see if the expression ends in
1426                    +%reg.  If it does, it removes the register from
1427                    the expression, and re-sets 's' to point to the
1428                    right place.  */
1429
1430                 char *s1;
1431
1432                 for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++);;
1433
1434                 if (s1 != s && isdigit (s1[-1]))
1435                   {
1436                     if (s1[-2] == '%' && s1[-3] == '+')
1437                       {
1438                         s1 -= 3;
1439                         *s1 = '\0';
1440                         (void) getExpression (s);
1441                         *s1 = '+';
1442                         s = s1;
1443                         continue;
1444                       }
1445                     else if (strchr ("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+')
1446                       {
1447                         s1 -= 4;
1448                         *s1 = '\0';
1449                         (void) getExpression (s);
1450                         *s1 = '+';
1451                         s = s1;
1452                         continue;
1453                       }
1454                   }
1455               }
1456               (void) getExpression (s);
1457               s = expr_end;
1458
1459               if (the_insn.exp.X_op == O_constant
1460                   && the_insn.exp.X_add_symbol == 0
1461                   && the_insn.exp.X_op_symbol == 0)
1462                 {
1463                   /* start-sanitize-v9 */
1464 #ifndef NO_V9
1465                   switch (the_insn.reloc)
1466                     {
1467                     case BFD_RELOC_SPARC_HH22:
1468                       the_insn.reloc = BFD_RELOC_HI22;
1469                       the_insn.exp.X_add_number >>= 32;
1470                       break;
1471                     case BFD_RELOC_SPARC_HM10:
1472                       the_insn.reloc = BFD_RELOC_LO10;
1473                       the_insn.exp.X_add_number >>= 32;
1474                       break;
1475                     }
1476 #endif
1477                   /* end-sanitize-v9 */
1478                   /* Check for invalid constant values.  Don't warn if
1479                      constant was inside %hi or %lo, since these
1480                      truncate the constant to fit.  */
1481                   if (immediate_max != 0
1482                       && the_insn.reloc != BFD_RELOC_LO10
1483                       && the_insn.reloc != BFD_RELOC_HI22
1484                       && (the_insn.exp.X_add_number > immediate_max
1485                           || the_insn.exp.X_add_number < ~immediate_max))
1486                     as_bad ("constant value must be between %ld and %ld",
1487                             ~immediate_max, immediate_max);
1488                 }
1489
1490               /* Reset to prevent extraneous range check.  */
1491               immediate_max = 0;
1492
1493               continue;
1494
1495             case 'a':
1496               if (*s++ == 'a')
1497                 {
1498                   opcode |= ANNUL;
1499                   continue;
1500                 }
1501               break;
1502
1503             case 'A':
1504               {
1505 /* start-sanitize-v9 */
1506 #ifdef NO_V9
1507 /* end-sanitize-v9 */
1508                 char *push = input_line_pointer;
1509                 expressionS e;
1510
1511                 input_line_pointer = s;
1512
1513                 expression (&e);
1514                 if (e.X_op == O_constant)
1515                   {
1516                     opcode |= e.X_add_number << 5;
1517                     s = input_line_pointer;
1518                     input_line_pointer = push;
1519                     continue;
1520                   }             /* if absolute */
1521
1522                 break;
1523 /* start-sanitize-v9 */
1524 #else
1525                 int asi = 0;
1526
1527                 /* Parse an asi.  */
1528                 if (*s == '#')
1529                   {
1530                     s += 1;
1531                     if (!strncmp (s, "ASI_AIUP", 8))
1532                       asi = 0x10, s += 8;
1533                     else if (!strncmp (s, "ASI_AIUS", 8))
1534                       asi = 0x11, s += 8;
1535                     else if (!strncmp (s, "ASI_PNF", 7))
1536                       asi = 0x82, s += 7;
1537                     else if (!strncmp (s, "ASI_SNF", 7))
1538                       asi = 0x83, s += 7;
1539                     else if (!strncmp (s, "ASI_P", 5))
1540                       asi = 0x80, s += 5;
1541                     else if (!strncmp (s, "ASI_S", 5))
1542                       asi = 0x81, s += 5;
1543                     else
1544                       {
1545                         error_message = ": invalid asi name";
1546                         goto error;
1547                       }
1548                   }
1549                 else if (isdigit (*s))
1550                   {
1551                     char *push = input_line_pointer;
1552                     input_line_pointer = s;
1553                     asi = get_absolute_expression ();
1554                     s = input_line_pointer;
1555                     input_line_pointer = push;
1556                     
1557                     if (asi < 0 || asi > 255)
1558                       {
1559                         error_message = ": invalid asi number";
1560                         goto error;
1561                       }
1562                   }
1563                 else
1564                   {
1565                     error_message = ": unrecognizable asi";
1566                     goto error;
1567                   }
1568                 opcode |= ASI (asi);
1569                 continue;
1570 #endif
1571 /* end-sanitize-v9 */
1572               }                 /* alternate space */
1573
1574             case 'p':
1575               if (strncmp (s, "%psr", 4) == 0)
1576                 {
1577                   s += 4;
1578                   continue;
1579                 }
1580               break;
1581
1582             case 'q':           /* floating point queue */
1583               if (strncmp (s, "%fq", 3) == 0)
1584                 {
1585                   s += 3;
1586                   continue;
1587                 }
1588               break;
1589
1590             case 'Q':           /* coprocessor queue */
1591               if (strncmp (s, "%cq", 3) == 0)
1592                 {
1593                   s += 3;
1594                   continue;
1595                 }
1596               break;
1597
1598             case 'S':
1599               if (strcmp (str, "set") == 0)
1600                 {
1601                   special_case = SPECIAL_CASE_SET;
1602                   continue;
1603                 }
1604               else if (strncmp (str, "fdiv", 4) == 0)
1605                 {
1606                   special_case = SPECIAL_CASE_FDIV;
1607                   continue;
1608                 }
1609               break;
1610
1611               /* start-sanitize-v9 */
1612 #ifndef NO_V9
1613             case 'o':
1614               if (strncmp (s, "%asi", 4) != 0)
1615                 break;
1616               s += 4;
1617               continue;
1618
1619             case 's':
1620               if (strncmp (s, "%fprs", 5) != 0)
1621                 break;
1622               s += 5;
1623               continue;
1624
1625             case 'E':
1626               if (strncmp (s, "%ccr", 4) != 0)
1627                 break;
1628               s += 4;
1629               continue;
1630 #endif /* NO_V9 */
1631               /* end-sanitize-v9 */
1632
1633             case 't':
1634               if (strncmp (s, "%tbr", 4) != 0)
1635                 break;
1636               s += 4;
1637               continue;
1638
1639             case 'w':
1640               if (strncmp (s, "%wim", 4) != 0)
1641                 break;
1642               s += 4;
1643               continue;
1644
1645             case 'y':
1646               if (strncmp (s, "%y", 2) != 0)
1647                 break;
1648               s += 2;
1649               continue;
1650
1651             default:
1652               as_fatal ("failed sanity check.");
1653             }                   /* switch on arg code */
1654           break;
1655         }                       /* for each arg that we expect */
1656     error:
1657       if (match == 0)
1658         {
1659           /* Args don't match. */
1660           if (((unsigned) (&insn[1] - sparc_opcodes)) < NUMOPCODES
1661               && !strcmp (insn->name, insn[1].name))
1662             {
1663               ++insn;
1664               s = argsStart;
1665               continue;
1666             }
1667           else
1668             {
1669               as_bad ("Illegal operands%s", error_message);
1670               return;
1671             }
1672         }
1673       else
1674         {
1675           if (insn->architecture > current_architecture)
1676             {
1677               if ((!architecture_requested || warn_on_bump)
1678                   &&
1679               /* start-sanitize-v9 */
1680 #ifndef NO_V9
1681                   !ARCHITECTURES_CONFLICT_P (current_architecture,
1682                                              insn->architecture)
1683 #else
1684               /* end-sanitize-v9 */
1685                   1
1686               /* start-sanitize-v9 */
1687 #endif
1688               /* end-sanitize-v9 */
1689                 )
1690                 {
1691                   if (warn_on_bump)
1692                     {
1693                       as_warn ("architecture bumped from \"%s\" to \"%s\" on \"%s\"",
1694                                architecture_pname[current_architecture],
1695                                architecture_pname[insn->architecture],
1696                                str);
1697                     }           /* if warning */
1698
1699                   current_architecture = insn->architecture;
1700                 }
1701               else
1702                 {
1703                   as_bad ("architecture mismatch on \"%s\" (\"%s\").  current architecture is \"%s\"",
1704                           str,
1705                           architecture_pname[insn->architecture],
1706                           architecture_pname[current_architecture]);
1707                   return;
1708                 }               /* if bump ok else error */
1709             }                   /* if architecture higher */
1710         }                       /* if no match */
1711
1712       break;
1713     }                           /* forever looking for a match */
1714
1715   the_insn.opcode = opcode;
1716   return;
1717 }                               /* sparc_ip() */
1718
1719 static int
1720 getExpression (str)
1721      char *str;
1722 {
1723   char *save_in;
1724   segT seg;
1725
1726   save_in = input_line_pointer;
1727   input_line_pointer = str;
1728   seg = expression (&the_insn.exp);
1729   if (seg != absolute_section
1730       && seg != text_section
1731       && seg != data_section
1732       && seg != bss_section
1733       && seg != undefined_section)
1734     {
1735       the_insn.error = "bad segment";
1736       expr_end = input_line_pointer;
1737       input_line_pointer = save_in;
1738       return 1;
1739     }
1740   expr_end = input_line_pointer;
1741   input_line_pointer = save_in;
1742   return 0;
1743 }                               /* getExpression() */
1744
1745
1746 /*
1747   This is identical to the md_atof in m68k.c.  I think this is right,
1748   but I'm not sure.
1749
1750   Turn a string in input_line_pointer into a floating point constant of type
1751   type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
1752   emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
1753   */
1754
1755 /* Equal to MAX_PRECISION in atof-ieee.c */
1756 #define MAX_LITTLENUMS 6
1757
1758 char *
1759 md_atof (type, litP, sizeP)
1760      char type;
1761      char *litP;
1762      int *sizeP;
1763 {
1764   int prec;
1765   LITTLENUM_TYPE words[MAX_LITTLENUMS];
1766   LITTLENUM_TYPE *wordP;
1767   char *t;
1768   char *atof_ieee ();
1769
1770   switch (type)
1771     {
1772
1773     case 'f':
1774     case 'F':
1775     case 's':
1776     case 'S':
1777       prec = 2;
1778       break;
1779
1780     case 'd':
1781     case 'D':
1782     case 'r':
1783     case 'R':
1784       prec = 4;
1785       break;
1786
1787     case 'x':
1788     case 'X':
1789       prec = 6;
1790       break;
1791
1792     case 'p':
1793     case 'P':
1794       prec = 6;
1795       break;
1796
1797     default:
1798       *sizeP = 0;
1799       return "Bad call to MD_ATOF()";
1800     }
1801   t = atof_ieee (input_line_pointer, type, words);
1802   if (t)
1803     input_line_pointer = t;
1804   *sizeP = prec * sizeof (LITTLENUM_TYPE);
1805   for (wordP = words; prec--;)
1806     {
1807       md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
1808       litP += sizeof (LITTLENUM_TYPE);
1809     }
1810   return 0;
1811 }
1812
1813 /*
1814  * Write out big-endian.
1815  */
1816 void
1817 md_number_to_chars (buf, val, n)
1818      char *buf;
1819      valueT val;
1820      int n;
1821 {
1822
1823   switch (n)
1824     {
1825       /* start-sanitize-v9 */
1826     case 8:
1827       *buf++ = val >> 56;
1828       *buf++ = val >> 48;
1829       *buf++ = val >> 40;
1830       *buf++ = val >> 32;
1831       /* end-sanitize-v9 */
1832     case 4:
1833       *buf++ = val >> 24;
1834       *buf++ = val >> 16;
1835     case 2:
1836       *buf++ = val >> 8;
1837     case 1:
1838       *buf = val;
1839       break;
1840
1841     default:
1842       as_fatal ("failed sanity check.");
1843     }
1844   return;
1845 }                               /* md_number_to_chars() */
1846
1847 /* Apply a fixS to the frags, now that we know the value it ought to
1848    hold. */
1849
1850 int
1851 md_apply_fix (fixP, value)
1852      fixS *fixP;
1853      valueT *value;
1854 {
1855   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1856   offsetT val;
1857
1858   val = *value;
1859
1860   assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
1861
1862   fixP->fx_addnumber = val;     /* Remember value for emit_reloc */
1863
1864 #ifdef OBJ_ELF
1865   /* FIXME: SPARC ELF relocations don't use an addend in the data
1866      field itself.  This whole approach should be somehow combined
1867      with the calls to bfd_perform_relocation.  */
1868   if (fixP->fx_addsy != NULL)
1869     return 1;
1870 #endif
1871
1872   /*
1873    * This is a hack.  There should be a better way to
1874    * handle this.
1875    */
1876   if (fixP->fx_r_type == BFD_RELOC_32_PCREL_S2 && fixP->fx_addsy)
1877     {
1878       val += fixP->fx_where + fixP->fx_frag->fr_address;
1879     }
1880
1881   switch (fixP->fx_r_type)
1882     {
1883
1884     case BFD_RELOC_16:
1885       buf[0] = val >> 8;
1886       buf[1] = val;
1887       break;
1888
1889     case BFD_RELOC_32:
1890       buf[0] = val >> 24;
1891       buf[1] = val >> 16;
1892       buf[2] = val >> 8;
1893       buf[3] = val;
1894       break;
1895
1896     case BFD_RELOC_32_PCREL_S2:
1897       val = (val >>= 2) + 1;
1898       buf[0] |= (val >> 24) & 0x3f;
1899       buf[1] = (val >> 16);
1900       buf[2] = val >> 8;
1901       buf[3] = val;
1902       break;
1903
1904       /* start-sanitize-v9 */
1905 #ifndef NO_V9
1906     case BFD_RELOC_64:
1907       buf[0] = val >> 56;
1908       buf[1] = val >> 48;
1909       buf[2] = val >> 40;
1910       buf[3] = val >> 32;
1911       buf[4] = val >> 24;
1912       buf[5] = val >> 16;
1913       buf[6] = val >> 8;
1914       buf[7] = val;
1915       break;
1916
1917     case BFD_RELOC_SPARC_11:
1918       if (((val > 0) && (val & ~0x7ff))
1919           || ((val < 0) && (~(val - 1) & ~0x7ff)))
1920         {
1921           as_bad ("relocation overflow.");
1922         }                       /* on overflow */
1923
1924       buf[2] |= (val >> 8) & 0x7;
1925       buf[3] = val & 0xff;
1926       break;
1927
1928     case BFD_RELOC_SPARC_10:
1929       if (((val > 0) && (val & ~0x3ff))
1930           || ((val < 0) && (~(val - 1) & ~0x3ff)))
1931         {
1932           as_bad ("relocation overflow.");
1933         }                       /* on overflow */
1934
1935       buf[2] |= (val >> 8) & 0x3;
1936       buf[3] = val & 0xff;
1937       break;
1938
1939     case BFD_RELOC_SPARC_WDISP16:
1940       if (((val > 0) && (val & ~0x3fffc))
1941           || ((val < 0) && (~(val - 1) & ~0x3fffc)))
1942         {
1943           as_bad ("relocation overflow.");
1944         }                       /* on overflow */
1945
1946       val = (val >>= 2) + 1;
1947       buf[1] |= ((val >> 14) & 0x3) << 4;
1948       buf[2] |= (val >> 8) & 0x3f;
1949       buf[3] = val & 0xff;
1950       break;
1951
1952     case BFD_RELOC_SPARC_WDISP19:
1953       if (((val > 0) && (val & ~0x1ffffc))
1954           || ((val < 0) && (~(val - 1) & ~0x1ffffc)))
1955         {
1956           as_bad ("relocation overflow.");
1957         }                       /* on overflow */
1958
1959       val = (val >>= 2) + 1;
1960       buf[1] |= (val >> 16) & 0x7;
1961       buf[2] = (val >> 8) & 0xff;
1962       buf[3] = val & 0xff;
1963       break;
1964
1965     case BFD_RELOC_SPARC_HH22:
1966       val >>= 32;
1967       /* intentional fallthrough */
1968 #endif /* NO_V9 */
1969       /* end-sanitize-v9 */
1970
1971       /* start-sanitize-v9 */
1972 #ifndef NO_V9
1973     case BFD_RELOC_SPARC_LM22:
1974 #endif
1975       /* end-sanitize-v9 */
1976     case BFD_RELOC_HI22:
1977       if (!fixP->fx_addsy)
1978         {
1979           buf[1] |= (val >> 26) & 0x3f;
1980           buf[2] = val >> 18;
1981           buf[3] = val >> 10;
1982         }
1983       else
1984         {
1985           buf[2] = 0;
1986           buf[3] = 0;
1987         }
1988       break;
1989
1990     case BFD_RELOC_SPARC22:
1991       if (val & ~0x003fffff)
1992         {
1993           as_bad ("relocation overflow");
1994         }                       /* on overflow */
1995       buf[1] |= (val >> 16) & 0x3f;
1996       buf[2] = val >> 8;
1997       buf[3] = val & 0xff;
1998       break;
1999
2000     case BFD_RELOC_SPARC13:
2001       if (val & ~0x00001fff)
2002         {
2003           as_bad ("relocation overflow");
2004         }                       /* on overflow */
2005       buf[2] |= (val >> 8) & 0x1f;
2006       buf[3] = val & 0xff;
2007       break;
2008
2009       /* start-sanitize-v9 */
2010 #ifndef NO_V9
2011     case BFD_RELOC_SPARC_HM10:
2012       val >>= 32;
2013       /* intentional fallthrough */
2014 #endif /* NO_V9 */
2015       /* end-sanitize-v9 */
2016
2017     case BFD_RELOC_LO10:
2018       if (!fixP->fx_addsy)
2019         {
2020           buf[2] |= (val >> 8) & 0x03;
2021           buf[3] = val;
2022         }
2023       else
2024         buf[3] = 0;
2025       break;
2026     case BFD_RELOC_SPARC_BASE13:
2027       if (((val > 0) && (val & ~(offsetT)0x00001fff))
2028           || ((val < 0) && (~(val - 1) & ~(offsetT)0x00001fff)))
2029         {
2030           as_bad ("relocation overflow");
2031         }
2032       buf[2] |= (val >> 8) & 0x1f;
2033       buf[3] = val;
2034       break;
2035
2036     case BFD_RELOC_SPARC_WDISP22:
2037       val = (val >>= 2) + 1;
2038       /* FALLTHROUGH */
2039     case BFD_RELOC_SPARC_BASE22:
2040       buf[1] |= (val >> 16) & 0x3f;
2041       buf[2] = val >> 8;
2042       buf[3] = val;
2043       break;
2044
2045     case BFD_RELOC_NONE:
2046     default:
2047       as_bad ("bad or unhandled relocation type: 0x%02x", fixP->fx_r_type);
2048       break;
2049     }
2050
2051   return 1;
2052 }
2053
2054 /* should never be called for sparc */
2055 void
2056 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
2057      char *ptr;
2058      addressT from_addr;
2059      addressT to_addr;
2060      fragS *frag;
2061      symbolS *to_symbol;
2062 {
2063   as_fatal ("sparc_create_short_jmp\n");
2064 }
2065
2066 /* Translate internal representation of relocation info to BFD target
2067    format.  */
2068 arelent *
2069 tc_gen_reloc (section, fixp)
2070      asection *section;
2071      fixS *fixp;
2072 {
2073   arelent *reloc;
2074   bfd_reloc_code_real_type code;
2075
2076   reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
2077   assert (reloc != 0);
2078
2079   reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
2080   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2081   reloc->addend = 0;
2082   if (fixp->fx_pcrel == 0)
2083     reloc->addend += fixp->fx_addnumber;
2084   else
2085     {
2086       reloc->addend += fixp->fx_offset;
2087       switch (OUTPUT_FLAVOR)
2088         {
2089         case bfd_target_elf_flavour:
2090           break;
2091         case bfd_target_aout_flavour:
2092           reloc->addend -= reloc->address;
2093           break;
2094         default:
2095           /* What's a good default here?  Is there any??  */
2096           abort ();
2097         }
2098     }
2099
2100   switch (fixp->fx_r_type)
2101     {
2102     case BFD_RELOC_16:
2103     case BFD_RELOC_32:
2104     case BFD_RELOC_HI22:
2105     case BFD_RELOC_LO10:
2106     case BFD_RELOC_32_PCREL_S2:
2107     case BFD_RELOC_SPARC_BASE13:
2108     case BFD_RELOC_SPARC_WDISP22:
2109       /* start-sanitize-v9 */
2110     case BFD_RELOC_64:
2111     case BFD_RELOC_SPARC_10:
2112     case BFD_RELOC_SPARC_11:
2113     case BFD_RELOC_SPARC_HH22:
2114     case BFD_RELOC_SPARC_HM10:
2115     case BFD_RELOC_SPARC_LM22:
2116     case BFD_RELOC_SPARC_PC_HH22:
2117     case BFD_RELOC_SPARC_PC_HM10:
2118     case BFD_RELOC_SPARC_PC_LM22:
2119       /* end-sanitize-v9 */
2120       code = fixp->fx_r_type;
2121       break;
2122     default:
2123       abort ();
2124     }
2125   reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
2126   assert (reloc->howto != 0);
2127
2128   return reloc;
2129 }
2130
2131 /* should never be called for sparc */
2132 void
2133 md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
2134      char *ptr;
2135      addressT from_addr, to_addr;
2136      fragS *frag;
2137      symbolS *to_symbol;
2138 {
2139   as_fatal ("sparc_create_long_jump\n");
2140 }                               /* md_create_long_jump() */
2141
2142 /* should never be called for sparc */
2143 int
2144 md_estimate_size_before_relax (fragP, segtype)
2145      fragS *fragP;
2146      segT segtype;
2147 {
2148   as_fatal ("sparc_estimate_size_before_relax\n");
2149   return (1);
2150 }                               /* md_estimate_size_before_relax() */
2151
2152 #if 0
2153 /* for debugging only */
2154 static void
2155 print_insn (insn)
2156      struct sparc_it *insn;
2157 {
2158   char *Reloc[] =
2159   {
2160     "RELOC_8",
2161     "RELOC_16",
2162     "RELOC_32",
2163     "RELOC_DISP8",
2164     "RELOC_DISP16",
2165     "RELOC_DISP32",
2166     "RELOC_WDISP30",
2167     "RELOC_WDISP22",
2168     "RELOC_HI22",
2169     "RELOC_22",
2170     "RELOC_13",
2171     "RELOC_LO10",
2172     "RELOC_SFA_BASE",
2173     "RELOC_SFA_OFF13",
2174     "RELOC_BASE10",
2175     "RELOC_BASE13",
2176     "RELOC_BASE22",
2177     "RELOC_PC10",
2178     "RELOC_PC22",
2179     "RELOC_JMP_TBL",
2180     "RELOC_SEGOFF16",
2181     "RELOC_GLOB_DAT",
2182     "RELOC_JMP_SLOT",
2183     "RELOC_RELATIVE",
2184     "NO_RELOC"
2185   };
2186
2187   if (insn->error)
2188     {
2189       fprintf (stderr, "ERROR: %s\n");
2190     }
2191   fprintf (stderr, "opcode=0x%08x\n", insn->opcode);
2192   fprintf (stderr, "reloc = %s\n", Reloc[insn->reloc]);
2193   fprintf (stderr, "exp = {\n");
2194   fprintf (stderr, "\t\tX_add_symbol = %s\n",
2195            ((insn->exp.X_add_symbol != NULL)
2196             ? ((S_GET_NAME (insn->exp.X_add_symbol) != NULL)
2197                ? S_GET_NAME (insn->exp.X_add_symbol)
2198                : "???")
2199             : "0"));
2200   fprintf (stderr, "\t\tX_sub_symbol = %s\n",
2201            ((insn->exp.X_op_symbol != NULL)
2202             ? (S_GET_NAME (insn->exp.X_op_symbol)
2203                ? S_GET_NAME (insn->exp.X_op_symbol)
2204                : "???")
2205             : "0"));
2206   fprintf (stderr, "\t\tX_add_number = %d\n",
2207            insn->exp.X_add_number);
2208   fprintf (stderr, "}\n");
2209   return;
2210 }                               /* print_insn() */
2211
2212 #endif
2213
2214 /*
2215  * md_parse_option
2216  *      Invocation line includes a switch not recognized by the base assembler.
2217  *      See if it's a processor-specific option.  These are:
2218  *
2219  *      -bump
2220  *              Warn on architecture bumps.  See also -A.
2221  *
2222  *      -Av6, -Av7, -Av8, -Asparclite
2223  *              Select the architecture.  Instructions or features not
2224  *              supported by the selected architecture cause fatal errors.
2225  *
2226  *              The default is to start at v6, and bump the architecture up
2227  *              whenever an instruction is seen at a higher level.
2228  *
2229  *              If -bump is specified, a warning is printing when bumping to
2230  *              higher levels.
2231  *
2232  *              If an architecture is specified, all instructions must match
2233  *              that architecture.  Any higher level instructions are flagged
2234  *              as errors.
2235  *
2236  *              if both an architecture and -bump are specified, the
2237  *              architecture starts at the specified level, but bumps are
2238  *              warnings.
2239  *
2240  * start-sanitize-v9
2241  *      -Av9
2242  *              Another architecture switch.
2243  *
2244  * Note:
2245  *              Bumping between incompatible architectures is always an
2246  *              error.  For example, from sparclite to v9.
2247  * end-sanitize-v9
2248  */
2249
2250 int 
2251 md_parse_option (argP, cntP, vecP)
2252      char **argP;
2253      int *cntP;
2254      char ***vecP;
2255 {
2256   char *p;
2257   const char **arch;
2258
2259   if (!strcmp (*argP, "bump"))
2260     {
2261       warn_on_bump = 1;
2262
2263     }
2264   else if (**argP == 'A')
2265     {
2266       p = (*argP) + 1;
2267
2268       for (arch = architecture_pname; *arch != NULL; ++arch)
2269         {
2270           if (strcmp (p, *arch) == 0)
2271             {
2272               break;
2273             }                   /* found a match */
2274         }                       /* walk the pname table */
2275
2276       if (*arch == NULL)
2277         {
2278           as_bad ("unknown architecture: %s", p);
2279         }
2280       else
2281         {
2282           current_architecture = (enum sparc_architecture) (arch - architecture_pname);
2283           architecture_requested = 1;
2284         }
2285     }
2286 #ifdef OBJ_ELF
2287   else if (**argP == 'V')
2288     {
2289       print_version_id ();
2290     }
2291   else if (**argP == 'Q')
2292     {
2293       /* Qy - do emit .comment
2294          Qn - do not emit .comment */
2295     }
2296   else if (**argP == 's')
2297     {
2298       /* use .stab instead of .stab.excl */
2299     }
2300 #endif
2301   else if (strcmp (*argP, "sparc") == 0)
2302     {
2303       /* Ignore -sparc, used by SunOS make default .s.o rule.  */
2304     }
2305   else
2306     {
2307       /* Unknown option */
2308       (*argP)++;
2309       return 0;
2310     }
2311   **argP = '\0';                /* Done parsing this switch */
2312   return 1;
2313 }                               /* md_parse_option() */
2314
2315 /* We have no need to default values of symbols. */
2316
2317 /* ARGSUSED */
2318 symbolS *
2319 md_undefined_symbol (name)
2320      char *name;
2321 {
2322   return 0;
2323 }                               /* md_undefined_symbol() */
2324
2325 /* Parse an operand that is machine-specific.
2326    We just return without modifying the expression if we have nothing
2327    to do. */
2328
2329 /* ARGSUSED */
2330 void 
2331 md_operand (expressionP)
2332      expressionS *expressionP;
2333 {
2334 }
2335
2336 /* Round up a section size to the appropriate boundary. */
2337 valueT
2338 md_section_align (segment, size)
2339      segT segment;
2340      valueT size;
2341 {
2342 #ifdef OBJ_AOUT
2343   /* Round all sects to multiple of 8 */
2344   size = (size + 7) & (valueT) ~7;
2345 #endif
2346   return size;
2347 }
2348
2349 /* Exactly what point is a PC-relative offset relative TO?
2350    On the sparc, they're relative to the address of the offset, plus
2351    its size.  This gets us to the following instruction.
2352    (??? Is this right?  FIXME-SOON) */
2353 long 
2354 md_pcrel_from (fixP)
2355      fixS *fixP;
2356 {
2357   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
2358 }
2359
2360 /* end of tc-sparc.c */