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