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