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