v9 stuff.
[deliverable/binutils-gdb.git] / gas / config / tc-sparc.c
1 /* tc-sparc.c -- Assemble for the SPARC
2 Copyright (C) 1989, 1990, 1991 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 1, 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 /* static const char rcsid[] = "$Id$"; */
21
22 #include <stdio.h>
23 #include <ctype.h>
24
25 #include "as.h"
26
27 /* careful, this file includes data *declarations* */
28 #include "sparc-opcode.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 = 1;
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 #ifdef __STDC__
116 #if 0
117 static void print_insn(struct sparc_it *insn);
118 #endif
119 static int getExpression(char *str);
120 #else
121 #if 0
122 static void print_insn();
123 #endif
124 static int getExpression();
125 #endif
126 static char *expr_end;
127 static int special_case;
128
129 /*
130 * Instructions that require wierd handling because they're longer than
131 * 4 bytes.
132 */
133 #define SPECIAL_CASE_SET 1
134 #define SPECIAL_CASE_FDIV 2
135
136 /*
137 * sort of like s_lcomm
138 *
139 */
140 static void s_reserve() {
141 char *name;
142 char c;
143 char *p;
144 int temp;
145 symbolS *symbolP;
146
147 name = input_line_pointer;
148 c = get_symbol_end();
149 p = input_line_pointer;
150 *p = c;
151 SKIP_WHITESPACE();
152 if (* input_line_pointer != ',') {
153 as_bad("Expected comma after name");
154 ignore_rest_of_line();
155 return;
156 }
157 input_line_pointer ++;
158 if ((temp = get_absolute_expression()) < 0) {
159 as_bad("BSS length (%d.) <0! Ignored.", temp);
160 ignore_rest_of_line();
161 return;
162 }
163 *p = 0;
164 symbolP = symbol_find_or_make(name);
165 *p = c;
166 if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0) {
167 as_bad("bad .reserve segment: `%s'", input_line_pointer);
168 return;
169 }
170 input_line_pointer += 6;
171 if (S_GET_OTHER(symbolP) == 0
172 && S_GET_DESC(symbolP) == 0
173 && ((S_GET_TYPE(symbolP) == N_BSS
174 && S_GET_VALUE(symbolP) == local_bss_counter)
175 || !S_IS_DEFINED(symbolP))) {
176 S_SET_VALUE(symbolP, local_bss_counter);
177 S_SET_SEGMENT(symbolP, SEG_BSS);
178 symbolP->sy_frag = & bss_address_frag;
179 local_bss_counter += temp;
180 } else {
181 as_warn("Ignoring attempt to re-define symbol from %d. to %d.",
182 S_GET_VALUE(symbolP), local_bss_counter);
183 }
184 demand_empty_rest_of_line();
185 return;
186 } /* s_reserve() */
187
188 static void s_common() {
189 register char *name;
190 register char c;
191 register char *p;
192 register int temp;
193 register symbolS * symbolP;
194
195 name = input_line_pointer;
196 c = get_symbol_end();
197 /* just after name is now '\0' */
198 p = input_line_pointer;
199 *p = c;
200 SKIP_WHITESPACE();
201 if (* input_line_pointer != ',') {
202 as_bad("Expected comma after symbol-name");
203 ignore_rest_of_line();
204 return;
205 }
206 input_line_pointer ++; /* skip ',' */
207 if ((temp = get_absolute_expression ()) < 0) {
208 as_bad(".COMMon length (%d.) <0! Ignored.", temp);
209 ignore_rest_of_line();
210 return;
211 }
212 *p = 0;
213 symbolP = symbol_find_or_make(name);
214 *p = c;
215 if (S_IS_DEFINED(symbolP)) {
216 as_bad("Ignoring attempt to re-define symbol");
217 ignore_rest_of_line();
218 return;
219 }
220 if (S_GET_VALUE(symbolP) != 0) {
221 if (S_GET_VALUE(symbolP) != temp) {
222 as_warn("Length of .comm \"%s\" is already %d. Not changed to %d.",
223 S_GET_NAME(symbolP), S_GET_VALUE(symbolP), temp);
224 }
225 } else {
226 S_SET_VALUE(symbolP, temp);
227 S_SET_EXTERNAL(symbolP);
228 }
229 know(symbolP->sy_frag == &zero_address_frag);
230 if (strncmp(input_line_pointer, ",\"bss\"", 6) != 0
231 && strncmp(input_line_pointer, ",\"data\"", 7) != 0) {
232 p=input_line_pointer;
233 while(*p && *p!='\n')
234 p++;
235 c= *p;
236 *p='\0';
237 as_bad("bad .common segment: `%s'", input_line_pointer);
238 *p=c;
239 return;
240 }
241 input_line_pointer += 6 + (input_line_pointer[2] == 'd'); /* Skip either */
242 demand_empty_rest_of_line();
243 return;
244 } /* s_common() */
245
246 static void s_seg() {
247
248 if (strncmp(input_line_pointer, "\"text\"", 6) == 0) {
249 input_line_pointer += 6;
250 s_text();
251 return;
252 }
253 if (strncmp(input_line_pointer, "\"data\"", 6) == 0) {
254 input_line_pointer += 6;
255 s_data();
256 return;
257 }
258 if (strncmp(input_line_pointer, "\"data1\"", 7) == 0) {
259 input_line_pointer += 7;
260 s_data1();
261 return;
262 }
263 if (strncmp(input_line_pointer, "\"bss\"", 5) == 0) {
264 input_line_pointer += 5;
265 /* We only support 2 segments -- text and data -- for now, so
266 things in the "bss segment" will have to go into data for now.
267 You can still allocate SEG_BSS stuff with .lcomm or .reserve. */
268 subseg_new(SEG_DATA, 255); /* FIXME-SOMEDAY */
269 return;
270 }
271 as_bad("Unknown segment type");
272 demand_empty_rest_of_line();
273 return;
274 } /* s_seg() */
275
276 static void s_data1() {
277 subseg_new(SEG_DATA, 1);
278 demand_empty_rest_of_line();
279 return;
280 } /* s_data1() */
281
282 static void s_proc() {
283 extern char is_end_of_line[];
284
285 while (!is_end_of_line[*input_line_pointer]) {
286 ++input_line_pointer;
287 }
288 ++input_line_pointer;
289 return;
290 } /* s_proc() */
291
292 /* This function is called once, at assembler startup time. It should
293 set up all the tables, etc. that the MD part of the assembler will need. */
294 void md_begin() {
295 register char *retval = NULL;
296 int lose = 0;
297 register unsigned int i = 0;
298
299 op_hash = hash_new();
300 if (op_hash == NULL)
301 as_fatal("Virtual memory exhausted");
302
303 while (i < NUMOPCODES) {
304 const char *name = sparc_opcodes[i].name;
305 retval = hash_insert(op_hash, name, &sparc_opcodes[i]);
306 if(retval != NULL && *retval != '\0') {
307 fprintf (stderr, "internal error: can't hash `%s': %s\n",
308 sparc_opcodes[i].name, retval);
309 lose = 1;
310 }
311 do
312 {
313 if (sparc_opcodes[i].match & sparc_opcodes[i].lose) {
314 fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n",
315 sparc_opcodes[i].name, sparc_opcodes[i].args);
316 lose = 1;
317 }
318 ++i;
319 } while (i < NUMOPCODES
320 && !strcmp(sparc_opcodes[i].name, name));
321 }
322
323 if (lose)
324 as_fatal("Broken assembler. No assembly attempted.");
325
326 for (i = '0'; i < '8'; ++i)
327 octal[i] = 1;
328 for (i = '0'; i <= '9'; ++i)
329 toHex[i] = i - '0';
330 for (i = 'a'; i <= 'f'; ++i)
331 toHex[i] = i + 10 - 'a';
332 for (i = 'A'; i <= 'F'; ++i)
333 toHex[i] = i + 10 - 'A';
334 } /* md_begin() */
335
336 void md_end() {
337 return;
338 } /* md_end() */
339
340 void md_assemble(str)
341 char *str;
342 {
343 char *toP;
344 int rsd;
345
346 know(str);
347 sparc_ip(str);
348
349 /* See if "set" operand is absolute and small; skip sethi if so. */
350 if (special_case == SPECIAL_CASE_SET && the_insn.exp.X_seg == SEG_ABSOLUTE) {
351 if (the_insn.exp.X_add_number >= -(1<<12)
352 && the_insn.exp.X_add_number < (1<<12)) {
353 the_insn.opcode = 0x80102000 /* or %g0,imm,... */
354 | (the_insn.opcode & 0x3E000000) /* dest reg */
355 | (the_insn.exp.X_add_number & 0x1FFF); /* imm */
356 special_case = 0; /* No longer special */
357 the_insn.reloc = NO_RELOC; /* No longer relocated */
358 }
359 }
360
361 toP = frag_more(4);
362 /* put out the opcode */
363 md_number_to_chars(toP, the_insn.opcode, 4);
364
365 /* put out the symbol-dependent stuff */
366 if (the_insn.reloc != NO_RELOC) {
367 fix_new(frag_now, /* which frag */
368 (toP - frag_now->fr_literal), /* where */
369 4, /* size */
370 the_insn.exp.X_add_symbol,
371 the_insn.exp.X_subtract_symbol,
372 the_insn.exp.X_add_number,
373 the_insn.pcrel,
374 the_insn.reloc);
375 }
376 switch (special_case) {
377
378 case SPECIAL_CASE_SET:
379 special_case = 0;
380 assert(the_insn.reloc == RELOC_HI22);
381 /* See if "set" operand has no low-order bits; skip OR if so. */
382 if (the_insn.exp.X_seg == SEG_ABSOLUTE
383 && ((the_insn.exp.X_add_number & 0x3FF) == 0))
384 return;
385 toP = frag_more(4);
386 rsd = (the_insn.opcode >> 25) & 0x1f;
387 the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14);
388 md_number_to_chars(toP, the_insn.opcode, 4);
389 fix_new(frag_now, /* which frag */
390 (toP - frag_now->fr_literal), /* where */
391 4, /* size */
392 the_insn.exp.X_add_symbol,
393 the_insn.exp.X_subtract_symbol,
394 the_insn.exp.X_add_number,
395 the_insn.pcrel,
396 RELOC_LO10);
397 return;
398
399 case SPECIAL_CASE_FDIV:
400 /* According to information leaked from Sun, the "fdiv" instructions
401 on early SPARC machines would produce incorrect results sometimes.
402 The workaround is to add an fmovs of the destination register to
403 itself just after the instruction. This was true on machines
404 with Weitek 1165 float chips, such as the Sun-4/260 and /280. */
405 special_case = 0;
406 assert(the_insn.reloc == NO_RELOC);
407 toP = frag_more(4);
408 rsd = (the_insn.opcode >> 25) & 0x1f;
409 the_insn.opcode = 0x81A00020 | (rsd << 25) | rsd; /* fmovs dest,dest */
410 md_number_to_chars(toP, the_insn.opcode, 4);
411 return;
412
413 case 0:
414 return;
415
416 default:
417 abort();
418 }
419 } /* md_assemble() */
420
421 static void sparc_ip(str)
422 char *str;
423 {
424 char *error_message = "";
425 char *s;
426 const char *args;
427 char c;
428 struct sparc_opcode *insn;
429 char *argsStart;
430 unsigned long opcode;
431 unsigned int mask;
432 int match = 0;
433 int comma = 0;
434
435 for (s = str; islower(*s) || (*s >= '0' && *s <= '3'); ++s)
436 ;
437 switch (*s) {
438
439 case '\0':
440 break;
441
442 case ',':
443 comma = 1;
444
445 /*FALLTHROUGH */
446
447 case ' ':
448 *s++ = '\0';
449 break;
450
451 default:
452 as_bad("Unknown opcode: `%s'", str);
453 exit(1);
454 }
455 if ((insn = (struct sparc_opcode *) hash_find(op_hash, str)) == NULL) {
456 as_bad("Unknown opcode: `%s'", str);
457 return;
458 }
459 if (comma) {
460 *--s = ',';
461 }
462 argsStart = s;
463 for (;;) {
464 opcode = insn->match;
465 bzero(&the_insn, sizeof(the_insn));
466 the_insn.reloc = NO_RELOC;
467
468 /*
469 * Build the opcode, checking as we go to make
470 * sure that the operands match
471 */
472 for (args = insn->args; ; ++args) {
473 switch (*args) {
474
475 case 'M':
476 case 'm':
477 if (strncmp(s, "%asr", 4) == 0) {
478 s += 4;
479
480 if (isdigit(*s)) {
481 long num = 0;
482
483 while (isdigit(*s)) {
484 num = num*10 + *s-'0';
485 ++s;
486 }
487
488 if (num < 16 || 31 < num) {
489 error_message = ": asr number must be between 15 and 31";
490 goto error;
491 } /* out of range */
492
493 opcode |= (*args == 'M' ? RS1(num) : RD(num));
494 continue;
495 } else {
496 error_message = ": expecting %asrN";
497 goto error;
498 } /* if %asr followed by a number. */
499
500 } /* if %asr */
501 break;
502
503 #ifndef NO_V9
504 case 'k':
505 the_insn.reloc = RELOC_WDISP14;
506 the_insn.pcrel = 1;
507 goto immediate;
508
509 case 'K':
510 the_insn.reloc = RELOC_WDISP21;
511 the_insn.pcrel = 1;
512 goto immediate;
513
514 case 'N':
515 if (*s == 'p' && s[1] == 'n') {
516 s += 2;
517 continue;
518 }
519 break;
520
521 case 'T':
522 if (*s == 'p' && s[1] == 't') {
523 s += 2;
524 continue;
525 }
526 break;
527
528 case 'Y':
529 if (strncmp(s, "%amr", 4) == 0) {
530 s += 4;
531 continue;
532 }
533 break;
534
535 #endif /* NO_V9 */
536
537 case '\0': /* end of args */
538 if (*s == '\0') {
539 match = 1;
540 }
541 break;
542
543 case '+':
544 if (*s == '+') {
545 ++s;
546 continue;
547 }
548 if (*s == '-') {
549 continue;
550 }
551 break;
552
553 case '[': /* these must match exactly */
554 case ']':
555 case ',':
556 case ' ':
557 if (*s++ == *args)
558 continue;
559 break;
560
561 case '#': /* must be at least one digit */
562 if (isdigit(*s++)) {
563 while (isdigit(*s)) {
564 ++s;
565 }
566 continue;
567 }
568 break;
569
570 case 'C': /* coprocessor state register */
571 if (strncmp(s, "%csr", 4) == 0) {
572 s += 4;
573 continue;
574 }
575 break;
576
577 case 'b': /* next operand is a coprocessor register */
578 case 'c':
579 case 'D':
580 if (*s++ == '%' && *s++ == 'c' && isdigit(*s)) {
581 mask = *s++;
582 if (isdigit(*s)) {
583 mask = 10 * (mask - '0') + (*s++ - '0');
584 if (mask >= 32) {
585 break;
586 }
587 } else {
588 mask -= '0';
589 }
590 switch (*args) {
591
592 case 'b':
593 opcode |= mask << 14;
594 continue;
595
596 case 'c':
597 opcode |= mask;
598 continue;
599
600 case 'D':
601 opcode |= mask << 25;
602 continue;
603 }
604 }
605 break;
606
607 case 'r': /* next operand must be a register */
608 case '1':
609 case '2':
610 case 'd':
611 if (*s++ == '%') {
612 switch (c = *s++) {
613
614 case 'f': /* frame pointer */
615 if (*s++ == 'p') {
616 mask = 0x1e;
617 break;
618 }
619 goto error;
620
621 case 'g': /* global register */
622 if (isoctal(c = *s++)) {
623 mask = c - '0';
624 break;
625 }
626 goto error;
627
628 case 'i': /* in register */
629 if (isoctal(c = *s++)) {
630 mask = c - '0' + 24;
631 break;
632 }
633 goto error;
634
635 case 'l': /* local register */
636 if (isoctal(c = *s++)) {
637 mask= (c - '0' + 16) ;
638 break;
639 }
640 goto error;
641
642 case 'o': /* out register */
643 if (isoctal(c = *s++)) {
644 mask= (c - '0' + 8) ;
645 break;
646 }
647 goto error;
648
649 case 's': /* stack pointer */
650 if (*s++ == 'p') {
651 mask= 0xe;
652 break;
653 }
654 goto error;
655
656 case 'r': /* any register */
657 if (!isdigit(c = *s++)) {
658 goto error;
659 }
660 /* FALLTHROUGH */
661 case '0': case '1': case '2': case '3': case '4':
662 case '5': case '6': case '7': case '8': case '9':
663 if (isdigit(*s)) {
664 if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) {
665 goto error;
666 }
667 } else {
668 c -= '0';
669 }
670 mask= c;
671 break;
672
673 default:
674 goto error;
675 }
676 /*
677 * Got the register, now figure out where
678 * it goes in the opcode.
679 */
680 switch (*args) {
681
682 case '1':
683 opcode |= mask << 14;
684 continue;
685
686 case '2':
687 opcode |= mask;
688 continue;
689
690 case 'd':
691 opcode |= mask << 25;
692 continue;
693
694 case 'r':
695 opcode |= (mask << 25) | (mask << 14);
696 continue;
697 }
698 }
699 break;
700
701 case 'e': /* next operand is a floating point register */
702 case 'f':
703 case 'g':
704 if (*s++ == '%' && *s++ == 'f' && isdigit(*s)) {
705 mask = *s++;
706 if (isdigit(*s)) {
707 mask = 10 * (mask - '0') + (*s++ - '0');
708 if (mask >= 32) {
709 break;
710 }
711 } else {
712 mask -= '0';
713 }
714 switch (*args) {
715
716 case 'e':
717 opcode |= mask << 14;
718 continue;
719
720 case 'f':
721 opcode |= mask;
722 continue;
723
724 case 'g':
725 opcode |= mask << 25;
726 continue;
727 }
728 }
729 break;
730
731 case 'F':
732 if (strncmp(s, "%fsr", 4) == 0) {
733 s += 4;
734 continue;
735 }
736 break;
737
738 case 'h': /* high 22 bits */
739 the_insn.reloc = RELOC_HI22;
740 goto immediate;
741
742 case 'l': /* 22 bit PC relative immediate */
743 the_insn.reloc = RELOC_WDISP22;
744 the_insn.pcrel = 1;
745 goto immediate;
746
747 case 'L': /* 30 bit immediate */
748 the_insn.reloc = RELOC_WDISP30;
749 the_insn.pcrel = 1;
750 goto immediate;
751
752 case 'i': /* 13 bit immediate */
753 the_insn.reloc = RELOC_BASE13;
754
755 /*FALLTHROUGH */
756
757 immediate:
758 if(*s==' ')
759 s++;
760 if (*s == '%') {
761 if ((c = s[1]) == 'h' && s[2] == 'i') {
762 the_insn.reloc = RELOC_HI22;
763 s+=3;
764 } else if (c == 'l' && s[2] == 'o') {
765 the_insn.reloc = RELOC_LO10;
766 s+=3;
767 } else
768 break;
769 }
770 /* Note that if the getExpression() fails, we will still have
771 created U entries in the symbol table for the 'symbols'
772 in the input string. Try not to create U symbols for
773 registers, etc. */
774 {
775 /* This stuff checks to see if the expression ends
776 in +%reg If it does, it removes the register from
777 the expression, and re-sets 's' to point to the
778 right place */
779
780 char *s1;
781
782 for(s1=s;*s1 && *s1!=','&& *s1!=']';s1++)
783 ;
784
785 if(s1!=s && isdigit(s1[-1])) {
786 if(s1[-2]=='%' && s1[-3]=='+') {
787 s1-=3;
788 *s1='\0';
789 (void)getExpression(s);
790 *s1='+';
791 s=s1;
792 continue;
793 } else if(strchr("goli0123456789",s1[-2]) && s1[-3]=='%' && s1[-4]=='+') {
794 s1-=4;
795 *s1='\0';
796 (void)getExpression(s);
797 *s1='+';
798 s=s1;
799 continue;
800 }
801 }
802 }
803 (void)getExpression(s);
804 s = expr_end;
805 continue;
806
807 case 'a':
808 if (*s++ == 'a') {
809 opcode |= ANNUL;
810 continue;
811 }
812 break;
813
814 case 'A': /* alternate space */
815 if (isdigit(*s)) {
816 long num;
817
818 num=0;
819 while (isdigit(*s)) {
820 num= num*10 + *s-'0';
821 ++s;
822 }
823 opcode |= num<<5;
824 continue;
825 }
826 break;
827 /* abort(); */
828
829 case 'p':
830 if (strncmp(s, "%psr", 4) == 0) {
831 s += 4;
832 continue;
833 }
834 break;
835
836 case 'q': /* floating point queue */
837 if (strncmp(s, "%fq", 3) == 0) {
838 s += 3;
839 continue;
840 }
841 break;
842
843 case 'Q': /* coprocessor queue */
844 if (strncmp(s, "%cq", 3) == 0) {
845 s += 3;
846 continue;
847 }
848 break;
849
850 case 'S':
851 if (strcmp(str, "set") == 0) {
852 special_case = SPECIAL_CASE_SET;
853 continue;
854 } else if (strncmp(str, "fdiv", 4) == 0) {
855 special_case = SPECIAL_CASE_FDIV;
856 continue;
857 }
858 break;
859
860 case 't':
861 if (strncmp(s, "%tbr", 4) != 0)
862 break;
863 s += 4;
864 continue;
865
866 case 'w':
867 if (strncmp(s, "%wim", 4) != 0)
868 break;
869 s += 4;
870 continue;
871
872 case 'y':
873 if (strncmp(s, "%y", 2) != 0)
874 break;
875 s += 2;
876 continue;
877
878 default:
879 abort();
880 } /* switch on arg code */
881 break;
882 } /* for each arg that we expect */
883 error:
884 if (match == 0) {
885 /* Args don't match. */
886 if (((unsigned) (&insn[1] - sparc_opcodes)) < NUMOPCODES
887 && !strcmp(insn->name, insn[1].name)) {
888 ++insn;
889 s = argsStart;
890 continue;
891 } else {
892 as_bad("Illegal operands%s", error_message);
893 return;
894 }
895 } else {
896 if (insn->architecture > current_architecture) {
897 if (current_architecture != cypress
898 && (!architecture_requested || warn_on_bump)) {
899
900 if (warn_on_bump) {
901 as_warn("architecture bumped from \"%s\" to \"%s\" on \"%s\"",
902 architecture_pname[current_architecture],
903 architecture_pname[insn->architecture],
904 str);
905 } /* if warning */
906
907 current_architecture = insn->architecture;
908 } else {
909 as_bad("architecture mismatch on \"%s\" (\"%s\"). current architecture is \"%s\"",
910 str,
911 architecture_pname[insn->architecture],
912 architecture_pname[current_architecture]);
913 return;
914 } /* if bump ok else error */
915 } /* if architecture higher */
916 } /* if no match */
917
918 break;
919 } /* forever looking for a match */
920
921 the_insn.opcode = opcode;
922 return;
923 } /* sparc_ip() */
924
925 static int getExpression(str)
926 char *str;
927 {
928 char *save_in;
929 segT seg;
930
931 save_in = input_line_pointer;
932 input_line_pointer = str;
933 switch (seg = expression(&the_insn.exp)) {
934
935 case SEG_ABSOLUTE:
936 case SEG_TEXT:
937 case SEG_DATA:
938 case SEG_BSS:
939 case SEG_UNKNOWN:
940 case SEG_DIFFERENCE:
941 case SEG_BIG:
942 case SEG_ABSENT:
943 break;
944
945 default:
946 the_insn.error = "bad segment";
947 expr_end = input_line_pointer;
948 input_line_pointer=save_in;
949 return 1;
950 }
951 expr_end = input_line_pointer;
952 input_line_pointer = save_in;
953 return 0;
954 } /* getExpression() */
955
956
957 /*
958 This is identical to the md_atof in m68k.c. I think this is right,
959 but I'm not sure.
960
961 Turn a string in input_line_pointer into a floating point constant of type
962 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
963 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
964 */
965
966 /* Equal to MAX_PRECISION in atof-ieee.c */
967 #define MAX_LITTLENUMS 6
968
969 char *md_atof(type,litP,sizeP)
970 char type;
971 char *litP;
972 int *sizeP;
973 {
974 int prec;
975 LITTLENUM_TYPE words[MAX_LITTLENUMS];
976 LITTLENUM_TYPE *wordP;
977 char *t;
978 char *atof_ieee();
979
980 switch(type) {
981
982 case 'f':
983 case 'F':
984 case 's':
985 case 'S':
986 prec = 2;
987 break;
988
989 case 'd':
990 case 'D':
991 case 'r':
992 case 'R':
993 prec = 4;
994 break;
995
996 case 'x':
997 case 'X':
998 prec = 6;
999 break;
1000
1001 case 'p':
1002 case 'P':
1003 prec = 6;
1004 break;
1005
1006 default:
1007 *sizeP=0;
1008 return "Bad call to MD_ATOF()";
1009 }
1010 t=atof_ieee(input_line_pointer,type,words);
1011 if(t)
1012 input_line_pointer=t;
1013 *sizeP=prec * sizeof(LITTLENUM_TYPE);
1014 for(wordP=words;prec--;) {
1015 md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
1016 litP+=sizeof(LITTLENUM_TYPE);
1017 }
1018 return ""; /* Someone should teach Dean about null pointers */
1019 } /* md_atof() */
1020
1021 /*
1022 * Write out big-endian.
1023 */
1024 void md_number_to_chars(buf,val,n)
1025 char *buf;
1026 long val;
1027 int n;
1028 {
1029
1030 switch(n) {
1031
1032 case 4:
1033 *buf++ = val >> 24;
1034 *buf++ = val >> 16;
1035 case 2:
1036 *buf++ = val >> 8;
1037 case 1:
1038 *buf = val;
1039 break;
1040
1041 default:
1042 abort();
1043 }
1044 return;
1045 } /* md_number_to_chars() */
1046
1047 /* Apply a fixS to the frags, now that we know the value it ought to
1048 hold. */
1049
1050 void md_apply_fix(fixP, val)
1051 fixS *fixP;
1052 long val;
1053 {
1054 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1055
1056 assert(fixP->fx_size == 4);
1057 assert(fixP->fx_r_type < NO_RELOC);
1058
1059 fixP->fx_addnumber = val; /* Remember value for emit_reloc */
1060
1061 /*
1062 * This is a hack. There should be a better way to
1063 * handle this.
1064 */
1065 if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy) {
1066 val += fixP->fx_where + fixP->fx_frag->fr_address;
1067 }
1068
1069 switch (fixP->fx_r_type) {
1070
1071 case RELOC_32:
1072 buf[0] = 0; /* val >> 24; */
1073 buf[1] = 0; /* val >> 16; */
1074 buf[2] = 0; /* val >> 8; */
1075 buf[3] = 0; /* val; */
1076 break;
1077
1078 #if 0
1079 case RELOC_8: /* These don't seem to ever be needed. */
1080 case RELOC_16:
1081 case RELOC_DISP8:
1082 case RELOC_DISP16:
1083 case RELOC_DISP32:
1084 #endif
1085 case RELOC_WDISP30:
1086 val = (val >>= 2) + 1;
1087 buf[0] |= (val >> 24) & 0x3f;
1088 buf[1]= (val >> 16);
1089 buf[2] = val >> 8;
1090 buf[3] = val;
1091 break;
1092
1093 #ifndef NO_V9
1094 case RELOC_WDISP14:
1095 val = (val >>= 2) + 1;
1096 buf[2] |= (val >> 8) & 0x3f ;
1097 buf[3] = val;
1098 break;
1099
1100 case RELOC_WDISP21:
1101 val = (val >>= 2) + 1;
1102 buf[1] |= (val >> 16) & 0x1f;
1103 buf[2] = val >> 8;
1104 buf[3] = val;
1105 break;
1106 #endif /* NO_V9 */
1107
1108 case RELOC_HI22:
1109 if(!fixP->fx_addsy) {
1110 buf[1] |= (val >> 26) & 0x3f;
1111 buf[2] = val >> 18;
1112 buf[3] = val >> 10;
1113 } else {
1114 buf[2]=0;
1115 buf[3]=0;
1116 }
1117 break;
1118 #if 0
1119 case RELOC_22:
1120 case RELOC_13:
1121 #endif
1122 case RELOC_LO10:
1123 if(!fixP->fx_addsy) {
1124 buf[2] |= (val >> 8) & 0x03;
1125 buf[3] = val;
1126 } else
1127 buf[3]=0;
1128 break;
1129 #if 0
1130 case RELOC_SFA_BASE:
1131 case RELOC_SFA_OFF13:
1132 case RELOC_BASE10:
1133 #endif
1134 case RELOC_BASE13:
1135 buf[2] |= (val >> 8) & 0x1f;
1136 buf[3] = val;
1137 break;
1138
1139 case RELOC_WDISP22:
1140 val = (val >>= 2) + 1;
1141 /* FALLTHROUGH */
1142 case RELOC_BASE22:
1143 buf[1] |= (val >> 16) & 0x3f;
1144 buf[2] = val >> 8;
1145 buf[3] = val;
1146 break;
1147
1148 #if 0
1149 case RELOC_PC10:
1150 case RELOC_PC22:
1151 case RELOC_JMP_TBL:
1152 case RELOC_SEGOFF16:
1153 case RELOC_GLOB_DAT:
1154 case RELOC_JMP_SLOT:
1155 case RELOC_RELATIVE:
1156 #endif
1157
1158 case NO_RELOC:
1159 default:
1160 as_bad("bad relocation type: 0x%02x", fixP->fx_r_type);
1161 break;
1162 }
1163 } /* md_apply_fix() */
1164
1165 /* should never be called for sparc */
1166 void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)
1167 char *ptr;
1168 long from_addr;
1169 long to_addr;
1170 fragS *frag;
1171 symbolS *to_symbol;
1172 {
1173 fprintf(stderr, "sparc_create_short_jmp\n");
1174 abort();
1175 } /* md_create_short_jump() */
1176
1177 /* Translate internal representation of relocation info to target format.
1178
1179 On sparc: first 4 bytes are normal unsigned long address, next three
1180 bytes are index, most sig. byte first. Byte 7 is broken up with
1181 bit 7 as external, bits 6 & 5 unused, and the lower
1182 five bits as relocation type. Next 4 bytes are long addend. */
1183 /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
1184 void md_ri_to_chars(the_bytes, ri)
1185 char *the_bytes;
1186 struct reloc_info_generic *ri;
1187 {
1188 /* this is easy */
1189 md_number_to_chars(the_bytes, ri->r_address, 4);
1190 /* now the fun stuff */
1191 the_bytes[4] = (ri->r_index >> 16) & 0x0ff;
1192 the_bytes[5] = (ri->r_index >> 8) & 0x0ff;
1193 the_bytes[6] = ri->r_index & 0x0ff;
1194 the_bytes[7] = ((ri->r_extern << 7) & 0x80) | (0 & 0x60) | (ri->r_type & 0x1F);
1195 /* Also easy */
1196 md_number_to_chars(&the_bytes[8], ri->r_addend, 4);
1197 } /* md_ri_to_chars() */
1198
1199 /* should never be called for sparc */
1200 void md_convert_frag(fragP)
1201 register fragS *fragP;
1202 {
1203 fprintf(stderr, "sparc_convert_frag\n");
1204 abort();
1205 } /* md_convert_frag() */
1206
1207 /* should never be called for sparc */
1208 void md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol)
1209 char *ptr;
1210 long from_addr, to_addr;
1211 fragS *frag;
1212 symbolS *to_symbol;
1213 {
1214 fprintf(stderr, "sparc_create_long_jump\n");
1215 abort();
1216 } /* md_create_long_jump() */
1217
1218 /* should never be called for sparc */
1219 int md_estimate_size_before_relax(fragP, segtype)
1220 fragS *fragP;
1221 segT segtype;
1222 {
1223 fprintf(stderr, "sparc_estimate_size_before_relax\n");
1224 abort();
1225 return 0;
1226 } /* md_estimate_size_before_relax() */
1227
1228 #if 0
1229 /* for debugging only */
1230 static void print_insn(insn)
1231 struct sparc_it *insn;
1232 {
1233 char *Reloc[] = {
1234 "RELOC_8",
1235 "RELOC_16",
1236 "RELOC_32",
1237 "RELOC_DISP8",
1238 "RELOC_DISP16",
1239 "RELOC_DISP32",
1240 "RELOC_WDISP30",
1241 "RELOC_WDISP22",
1242 "RELOC_HI22",
1243 "RELOC_22",
1244 "RELOC_13",
1245 "RELOC_LO10",
1246 "RELOC_SFA_BASE",
1247 "RELOC_SFA_OFF13",
1248 "RELOC_BASE10",
1249 "RELOC_BASE13",
1250 "RELOC_BASE22",
1251 "RELOC_PC10",
1252 "RELOC_PC22",
1253 "RELOC_JMP_TBL",
1254 "RELOC_SEGOFF16",
1255 "RELOC_GLOB_DAT",
1256 "RELOC_JMP_SLOT",
1257 "RELOC_RELATIVE",
1258 "NO_RELOC"
1259 };
1260
1261 if (insn->error) {
1262 fprintf(stderr, "ERROR: %s\n");
1263 }
1264 fprintf(stderr, "opcode=0x%08x\n", insn->opcode);
1265 fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]);
1266 fprintf(stderr, "exp = {
1267 \n");
1268 fprintf(stderr, "\t\tX_add_symbol = %s\n",
1269 ((insn->exp.X_add_symbol != NULL)
1270 ? ((S_GET_NAME(insn->exp.X_add_symbol) != NULL)
1271 ? S_GET_NAME(insn->exp.X_add_symbol)
1272 : "???")
1273 : "0"));
1274 fprintf(stderr, "\t\tX_sub_symbol = %s\n",
1275 ((insn->exp.X_subtract_symbol != NULL)
1276 ? (S_GET_NAME(insn->exp.X_subtract_symbol)
1277 ? S_GET_NAME(insn->exp.X_subtract_symbol)
1278 : "???")
1279 : "0"));
1280 fprintf(stderr, "\t\tX_add_number = %d\n",
1281 insn->exp.X_add_number);
1282 fprintf(stderr, "}\n");
1283 return;
1284 } /* print_insn() */
1285 #endif
1286
1287 /* Set the hook... */
1288
1289 void emit_sparc_reloc();
1290 void (*md_emit_relocations)() = emit_sparc_reloc;
1291
1292 /*
1293 * Sparc/AM29K relocations are completely different, so it needs
1294 * this machine dependent routine to emit them.
1295 */
1296 #if defined(OBJ_AOUT) || defined(OBJ_BOUT)
1297 void emit_sparc_reloc(fixP, segment_address_in_file)
1298 register fixS *fixP;
1299 relax_addressT segment_address_in_file;
1300 {
1301 struct reloc_info_generic ri;
1302 register symbolS *symbolP;
1303 extern char *next_object_file_charP;
1304 /* long add_number; */
1305
1306 bzero((char *) &ri, sizeof(ri));
1307 for (; fixP; fixP = fixP->fx_next) {
1308
1309 if (fixP->fx_r_type >= NO_RELOC) {
1310 fprintf(stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type);
1311 abort();
1312 }
1313
1314 if ((symbolP = fixP->fx_addsy) != NULL) {
1315 ri.r_address = fixP->fx_frag->fr_address +
1316 fixP->fx_where - segment_address_in_file;
1317 if ((S_GET_TYPE(symbolP)) == N_UNDF) {
1318 ri.r_extern = 1;
1319 ri.r_index = symbolP->sy_number;
1320 } else {
1321 ri.r_extern = 0;
1322 ri.r_index = S_GET_TYPE(symbolP);
1323 }
1324 if (symbolP && symbolP->sy_frag) {
1325 ri.r_addend = symbolP->sy_frag->fr_address;
1326 }
1327 ri.r_type = fixP->fx_r_type;
1328 if (fixP->fx_pcrel) {
1329 /* ri.r_addend -= fixP->fx_where; */
1330 ri.r_addend -= ri.r_address;
1331 } else {
1332 ri.r_addend = fixP->fx_addnumber;
1333 }
1334
1335 md_ri_to_chars(next_object_file_charP, &ri);
1336 next_object_file_charP += md_reloc_size;
1337 }
1338 }
1339 return;
1340 } /* emit_sparc_reloc() */
1341 #endif /* aout or bout */
1342
1343 /*
1344 * md_parse_option
1345 * Invocation line includes a switch not recognized by the base assembler.
1346 * See if it's a processor-specific option. These are:
1347 *
1348 * -bump
1349 * Warn on architecture bumps. See also -A.
1350 *
1351 * -Av6, -Av7, -Acypress, -Av8
1352 * -Av9
1353 * Select the architecture. Instructions or features not
1354 * supported by the selected architecture cause fatal errors.
1355 *
1356 * The default is to start at v6, and bump the architecture up
1357 * whenever an instruction is seen at a higher level.
1358 *
1359 * If -bump is specified, a warning is printing when bumping to
1360 * higher levels.
1361 *
1362 * If an architecture is specified, all instructions must match
1363 * that architecture. Any higher level instructions are flagged
1364 * as errors.
1365 *
1366 * if both an architecture and -bump are specified, the
1367 * architecture starts at the specified level, but bumps are
1368 * warnings.
1369 *
1370 * Note that where cypress specific instructions conflict with
1371 * other instructions, the other instruction is assumed. Nothing
1372 * is upward compatible with cypress. Thus, to get the cypress
1373 * instruction set you MUST -Acypress.
1374 *
1375 */
1376
1377 int md_parse_option(argP, cntP, vecP)
1378 char **argP;
1379 int *cntP;
1380 char ***vecP;
1381 {
1382 char *p;
1383 const char **arch;
1384
1385 if (!strcmp(*argP,"bump")){
1386 warn_on_bump = 1;
1387
1388 } else if (**argP == 'A'){
1389 p = (*argP) + 1;
1390
1391 for (arch = architecture_pname; *arch != NULL; ++arch){
1392 if (strcmp(p, *arch) == 0){
1393 break;
1394 } /* found a match */
1395 } /* walk the pname table */
1396
1397 if (*arch == NULL){
1398 as_bad("unknown architecture: %s", p);
1399 } else {
1400 current_architecture = (enum sparc_architecture) (arch - architecture_pname);
1401 architecture_requested = 1;
1402 }
1403 } else {
1404 /* Unknown option */
1405 (*argP)++;
1406 return 0;
1407 }
1408 **argP = '\0'; /* Done parsing this switch */
1409 return 1;
1410 } /* md_parse_option() */
1411
1412 /* We have no need to default values of symbols. */
1413
1414 /* ARGSUSED */
1415 symbolS *md_undefined_symbol(name)
1416 char *name;
1417 {
1418 return 0;
1419 } /* md_undefined_symbol() */
1420
1421 /* Parse an operand that is machine-specific.
1422 We just return without modifying the expression if we have nothing
1423 to do. */
1424
1425 /* ARGSUSED */
1426 void md_operand(expressionP)
1427 expressionS *expressionP;
1428 {
1429 } /* md_operand() */
1430
1431 /* Round up a section size to the appropriate boundary. */
1432 long md_section_align (segment, size)
1433 segT segment;
1434 long size;
1435 {
1436 return (size + 7) & ~7; /* Round all sects to multiple of 8 */
1437 } /* md_section_align() */
1438
1439 /* Exactly what point is a PC-relative offset relative TO?
1440 On the sparc, they're relative to the address of the offset, plus
1441 its size. This gets us to the following instruction.
1442 (??? Is this right? FIXME-SOON) */
1443 long md_pcrel_from(fixP)
1444 fixS *fixP;
1445 {
1446 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
1447 } /* md_pcrel_from() */
1448
1449 /*
1450 * Local Variables:
1451 * comment-column: 0
1452 * fill-column: 131
1453 * End:
1454 */
1455
1456 /* end of tp-sparc.c */
This page took 0.077848 seconds and 4 git commands to generate.