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