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