Initial revision
[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 const relax_typeS md_relax_table[] = {
44 0 };
45
46 /* handle of the OPCODE hash table */
47 static struct hash_control *op_hash = NULL;
48
49 static void s_seg(), s_proc(), s_data1(), s_reserve(), s_common();
50 extern void s_globl(), s_long(), s_short(), s_space(), cons();
51 extern void s_align_bytes(), s_ignore();
52
53 const pseudo_typeS md_pseudo_table[] = {
54 { "align", s_align_bytes, 0 }, /* Defaulting is invalid (0) */
55 { "common", s_common, 0 },
56 { "global", s_globl, 0 },
57 { "half", cons, 2 },
58 { "optim", s_ignore, 0 },
59 { "proc", s_proc, 0 },
60 { "reserve", s_reserve, 0 },
61 { "seg", s_seg, 0 },
62 { "skip", s_space, 0 },
63 { "word", cons, 4 },
64 { NULL, 0, 0 },
65 };
66
67 int md_short_jump_size = 4;
68 int md_long_jump_size = 4;
69 int md_reloc_size = 12; /* Size of relocation record */
70
71 /* This array holds the chars that always start a comment. If the
72 pre-processor is disabled, these aren't very useful */
73 char comment_chars[] = "!"; /* JF removed '|' from comment_chars */
74
75 /* This array holds the chars that only start a comment at the beginning of
76 a line. If the line seems to have the form '# 123 filename'
77 .line and .file directives will appear in the pre-processed output */
78 /* Note that input_file.c hand checks for '#' at the beginning of the
79 first line of the input file. This is because the compiler outputs
80 #NO_APP at the beginning of its output. */
81 /* Also note that comments started like this one will always work */
82 char line_comment_chars[] = "#";
83
84 /* Chars that can be used to separate mant from exp in floating point nums */
85 char EXP_CHARS[] = "eE";
86
87 /* Chars that mean this number is a floating point constant */
88 /* As in 0f12.456 */
89 /* or 0d1.2345e12 */
90 char FLT_CHARS[] = "rRsSfFdDxXpP";
91
92 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
93 changed in read.c . Ideally it shouldn't have to know about it at all,
94 but nothing is ideal around here.
95 */
96
97 static unsigned char octal[256];
98 #define isoctal(c) octal[c]
99 static unsigned char toHex[256];
100
101 /*
102 * anull bit - causes the branch delay slot instructions to not be executed
103 */
104 #define ANNUL (1 << 29)
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 *s;
425 const char *args;
426 char c;
427 struct sparc_opcode *insn;
428 char *argsStart;
429 unsigned long opcode;
430 unsigned int mask;
431 int match = 0;
432 int comma = 0;
433
434 for (s = str; islower(*s) || (*s >= '0' && *s <= '3'); ++s)
435 ;
436 switch (*s) {
437
438 case '\0':
439 break;
440
441 case ',':
442 comma = 1;
443
444 /*FALLTHROUGH */
445
446 case ' ':
447 *s++ = '\0';
448 break;
449
450 default:
451 as_bad("Unknown opcode: `%s'", str);
452 exit(1);
453 }
454 if ((insn = (struct sparc_opcode *) hash_find(op_hash, str)) == NULL) {
455 as_bad("Unknown opcode: `%s'", str);
456 return;
457 }
458 if (comma) {
459 *--s = ',';
460 }
461 argsStart = s;
462 for (;;) {
463 opcode = insn->match;
464 bzero(&the_insn, sizeof(the_insn));
465 the_insn.reloc = NO_RELOC;
466
467 /*
468 * Build the opcode, checking as we go to make
469 * sure that the operands match
470 */
471 for (args = insn->args; ; ++args) {
472 switch (*args) {
473
474 case '\0': /* end of args */
475 if (*s == '\0') {
476 match = 1;
477 }
478 break;
479
480 case '+':
481 if (*s == '+') {
482 ++s;
483 continue;
484 }
485 if (*s == '-') {
486 continue;
487 }
488 break;
489
490 case '[': /* these must match exactly */
491 case ']':
492 case ',':
493 case ' ':
494 if (*s++ == *args)
495 continue;
496 break;
497
498 case '#': /* must be at least one digit */
499 if (isdigit(*s++)) {
500 while (isdigit(*s)) {
501 ++s;
502 }
503 continue;
504 }
505 break;
506
507 case 'C': /* coprocessor state register */
508 if (strncmp(s, "%csr", 4) == 0) {
509 s += 4;
510 continue;
511 }
512 break;
513
514 case 'b': /* next operand is a coprocessor register */
515 case 'c':
516 case 'D':
517 if (*s++ == '%' && *s++ == 'c' && isdigit(*s)) {
518 mask = *s++;
519 if (isdigit(*s)) {
520 mask = 10 * (mask - '0') + (*s++ - '0');
521 if (mask >= 32) {
522 break;
523 }
524 } else {
525 mask -= '0';
526 }
527 switch (*args) {
528
529 case 'b':
530 opcode |= mask << 14;
531 continue;
532
533 case 'c':
534 opcode |= mask;
535 continue;
536
537 case 'D':
538 opcode |= mask << 25;
539 continue;
540 }
541 }
542 break;
543
544 case 'r': /* next operand must be a register */
545 case '1':
546 case '2':
547 case 'd':
548 if (*s++ == '%') {
549 switch (c = *s++) {
550
551 case 'f': /* frame pointer */
552 if (*s++ == 'p') {
553 mask = 0x1e;
554 break;
555 }
556 goto error;
557
558 case 'g': /* global register */
559 if (isoctal(c = *s++)) {
560 mask = c - '0';
561 break;
562 }
563 goto error;
564
565 case 'i': /* in register */
566 if (isoctal(c = *s++)) {
567 mask = c - '0' + 24;
568 break;
569 }
570 goto error;
571
572 case 'l': /* local register */
573 if (isoctal(c = *s++)) {
574 mask= (c - '0' + 16) ;
575 break;
576 }
577 goto error;
578
579 case 'o': /* out register */
580 if (isoctal(c = *s++)) {
581 mask= (c - '0' + 8) ;
582 break;
583 }
584 goto error;
585
586 case 's': /* stack pointer */
587 if (*s++ == 'p') {
588 mask= 0xe;
589 break;
590 }
591 goto error;
592
593 case 'r': /* any register */
594 if (!isdigit(c = *s++)) {
595 goto error;
596 }
597 /* FALLTHROUGH */
598 case '0': case '1': case '2': case '3': case '4':
599 case '5': case '6': case '7': case '8': case '9':
600 if (isdigit(*s)) {
601 if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) {
602 goto error;
603 }
604 } else {
605 c -= '0';
606 }
607 mask= c;
608 break;
609
610 default:
611 goto error;
612 }
613 /*
614 * Got the register, now figure out where
615 * it goes in the opcode.
616 */
617 switch (*args) {
618
619 case '1':
620 opcode |= mask << 14;
621 continue;
622
623 case '2':
624 opcode |= mask;
625 continue;
626
627 case 'd':
628 opcode |= mask << 25;
629 continue;
630
631 case 'r':
632 opcode |= (mask << 25) | (mask << 14);
633 continue;
634 }
635 }
636 break;
637
638 case 'e': /* next operand is a floating point register */
639 case 'f':
640 case 'g':
641 if (*s++ == '%' && *s++ == 'f' && isdigit(*s)) {
642 mask = *s++;
643 if (isdigit(*s)) {
644 mask = 10 * (mask - '0') + (*s++ - '0');
645 if (mask >= 32) {
646 break;
647 }
648 } else {
649 mask -= '0';
650 }
651 switch (*args) {
652
653 case 'e':
654 opcode |= mask << 14;
655 continue;
656
657 case 'f':
658 opcode |= mask;
659 continue;
660
661 case 'g':
662 opcode |= mask << 25;
663 continue;
664 }
665 }
666 break;
667
668 case 'F':
669 if (strncmp(s, "%fsr", 4) == 0) {
670 s += 4;
671 continue;
672 }
673 break;
674
675 case 'h': /* high 22 bits */
676 the_insn.reloc = RELOC_HI22;
677 goto immediate;
678
679 case 'l': /* 22 bit PC relative immediate */
680 the_insn.reloc = RELOC_WDISP22;
681 the_insn.pcrel = 1;
682 goto immediate;
683
684 case 'L': /* 30 bit immediate */
685 the_insn.reloc = RELOC_WDISP30;
686 the_insn.pcrel = 1;
687 goto immediate;
688
689 case 'i': /* 13 bit immediate */
690 the_insn.reloc = RELOC_BASE13;
691
692 /*FALLTHROUGH */
693
694 immediate:
695 if(*s==' ')
696 s++;
697 if (*s == '%') {
698 if ((c = s[1]) == 'h' && s[2] == 'i') {
699 the_insn.reloc = RELOC_HI22;
700 s+=3;
701 } else if (c == 'l' && s[2] == 'o') {
702 the_insn.reloc = RELOC_LO10;
703 s+=3;
704 } else
705 break;
706 }
707 /* Note that if the getExpression() fails, we will still have
708 created U entries in the symbol table for the 'symbols'
709 in the input string. Try not to create U symbols for
710 registers, etc. */
711 {
712 /* This stuff checks to see if the expression ends
713 in +%reg If it does, it removes the register from
714 the expression, and re-sets 's' to point to the
715 right place */
716
717 char *s1;
718
719 for(s1=s;*s1 && *s1!=','&& *s1!=']';s1++)
720 ;
721
722 if(s1!=s && isdigit(s1[-1])) {
723 if(s1[-2]=='%' && s1[-3]=='+') {
724 s1-=3;
725 *s1='\0';
726 (void)getExpression(s);
727 *s1='+';
728 s=s1;
729 continue;
730 } else if(strchr("goli0123456789",s1[-2]) && s1[-3]=='%' && s1[-4]=='+') {
731 s1-=4;
732 *s1='\0';
733 (void)getExpression(s);
734 *s1='+';
735 s=s1;
736 continue;
737 }
738 }
739 }
740 (void)getExpression(s);
741 s = expr_end;
742 continue;
743
744 case 'a':
745 if (*s++ == 'a') {
746 opcode |= ANNUL;
747 continue;
748 }
749 break;
750
751 case 'A': /* alternate space */
752 if (isdigit(*s)) {
753 long num;
754
755 num=0;
756 while (isdigit(*s)) {
757 num= num*10 + *s-'0';
758 ++s;
759 }
760 opcode |= num<<5;
761 continue;
762 }
763 break;
764 /* abort(); */
765
766 case 'p':
767 if (strncmp(s, "%psr", 4) == 0) {
768 s += 4;
769 continue;
770 }
771 break;
772
773 case 'q': /* floating point queue */
774 if (strncmp(s, "%fq", 3) == 0) {
775 s += 3;
776 continue;
777 }
778 break;
779
780 case 'Q': /* coprocessor queue */
781 if (strncmp(s, "%cq", 3) == 0) {
782 s += 3;
783 continue;
784 }
785 break;
786
787 case 'S':
788 if (strcmp(str, "set") == 0) {
789 special_case = SPECIAL_CASE_SET;
790 continue;
791 } else if (strncmp(str, "fdiv", 4) == 0) {
792 special_case = SPECIAL_CASE_FDIV;
793 continue;
794 }
795 break;
796
797 case 't':
798 if (strncmp(s, "%tbr", 4) != 0)
799 break;
800 s += 4;
801 continue;
802
803 case 'w':
804 if (strncmp(s, "%wim", 4) != 0)
805 break;
806 s += 4;
807 continue;
808
809 case 'y':
810 if (strncmp(s, "%y", 2) != 0)
811 break;
812 s += 2;
813 continue;
814
815 default:
816 abort();
817 }
818 break;
819 }
820 error:
821 if (match == 0) {
822 /* Args don't match. */
823 if (((unsigned) (&insn[1] - sparc_opcodes)) < NUMOPCODES
824 && !strcmp(insn->name, insn[1].name)) {
825 ++insn;
826 s = argsStart;
827 continue;
828 }
829 else
830 {
831 as_bad("Illegal operands");
832 return;
833 }
834 }
835 break;
836 }
837
838 the_insn.opcode = opcode;
839 return;
840 } /* sparc_ip() */
841
842 static int getExpression(str)
843 char *str;
844 {
845 char *save_in;
846 segT seg;
847
848 save_in = input_line_pointer;
849 input_line_pointer = str;
850 switch (seg = expression(&the_insn.exp)) {
851
852 case SEG_ABSOLUTE:
853 case SEG_TEXT:
854 case SEG_DATA:
855 case SEG_BSS:
856 case SEG_UNKNOWN:
857 case SEG_DIFFERENCE:
858 case SEG_BIG:
859 case SEG_ABSENT:
860 break;
861
862 default:
863 the_insn.error = "bad segment";
864 expr_end = input_line_pointer;
865 input_line_pointer=save_in;
866 return 1;
867 }
868 expr_end = input_line_pointer;
869 input_line_pointer = save_in;
870 return 0;
871 } /* getExpression() */
872
873
874 /*
875 This is identical to the md_atof in m68k.c. I think this is right,
876 but I'm not sure.
877
878 Turn a string in input_line_pointer into a floating point constant of type
879 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
880 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
881 */
882
883 /* Equal to MAX_PRECISION in atof-ieee.c */
884 #define MAX_LITTLENUMS 6
885
886 char *md_atof(type,litP,sizeP)
887 char type;
888 char *litP;
889 int *sizeP;
890 {
891 int prec;
892 LITTLENUM_TYPE words[MAX_LITTLENUMS];
893 LITTLENUM_TYPE *wordP;
894 char *t;
895 char *atof_ieee();
896
897 switch(type) {
898
899 case 'f':
900 case 'F':
901 case 's':
902 case 'S':
903 prec = 2;
904 break;
905
906 case 'd':
907 case 'D':
908 case 'r':
909 case 'R':
910 prec = 4;
911 break;
912
913 case 'x':
914 case 'X':
915 prec = 6;
916 break;
917
918 case 'p':
919 case 'P':
920 prec = 6;
921 break;
922
923 default:
924 *sizeP=0;
925 return "Bad call to MD_ATOF()";
926 }
927 t=atof_ieee(input_line_pointer,type,words);
928 if(t)
929 input_line_pointer=t;
930 *sizeP=prec * sizeof(LITTLENUM_TYPE);
931 for(wordP=words;prec--;) {
932 md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
933 litP+=sizeof(LITTLENUM_TYPE);
934 }
935 return ""; /* Someone should teach Dean about null pointers */
936 } /* md_atof() */
937
938 /*
939 * Write out big-endian.
940 */
941 void md_number_to_chars(buf,val,n)
942 char *buf;
943 long val;
944 int n;
945 {
946
947 switch(n) {
948
949 case 4:
950 *buf++ = val >> 24;
951 *buf++ = val >> 16;
952 case 2:
953 *buf++ = val >> 8;
954 case 1:
955 *buf = val;
956 break;
957
958 default:
959 abort();
960 }
961 return;
962 } /* md_number_to_chars() */
963
964 /* Apply a fixS to the frags, now that we know the value it ought to
965 hold. */
966
967 void md_apply_fix(fixP, val)
968 fixS *fixP;
969 long val;
970 {
971 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
972
973 assert(fixP->fx_size == 4);
974 assert(fixP->fx_r_type < NO_RELOC);
975
976 fixP->fx_addnumber = val; /* Remember value for emit_reloc */
977
978 /*
979 * This is a hack. There should be a better way to
980 * handle this.
981 */
982 if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy) {
983 val += fixP->fx_where + fixP->fx_frag->fr_address;
984 }
985
986 switch (fixP->fx_r_type) {
987
988 case RELOC_32:
989 buf[0] = 0; /* val >> 24; */
990 buf[1] = 0; /* val >> 16; */
991 buf[2] = 0; /* val >> 8; */
992 buf[3] = 0; /* val; */
993 break;
994
995 #if 0
996 case RELOC_8: /* These don't seem to ever be needed. */
997 case RELOC_16:
998 case RELOC_DISP8:
999 case RELOC_DISP16:
1000 case RELOC_DISP32:
1001 #endif
1002 case RELOC_WDISP30:
1003 val = (val >>= 2) + 1;
1004 buf[0] |= (val >> 24) & 0x3f;
1005 buf[1]= (val >> 16);
1006 buf[2] = val >> 8;
1007 buf[3] = val;
1008 break;
1009
1010 case RELOC_HI22:
1011 if(!fixP->fx_addsy) {
1012 buf[1] |= (val >> 26) & 0x3f;
1013 buf[2] = val >> 18;
1014 buf[3] = val >> 10;
1015 } else {
1016 buf[2]=0;
1017 buf[3]=0;
1018 }
1019 break;
1020 #if 0
1021 case RELOC_22:
1022 case RELOC_13:
1023 #endif
1024 case RELOC_LO10:
1025 if(!fixP->fx_addsy) {
1026 buf[2] |= (val >> 8) & 0x03;
1027 buf[3] = val;
1028 } else
1029 buf[3]=0;
1030 break;
1031 #if 0
1032 case RELOC_SFA_BASE:
1033 case RELOC_SFA_OFF13:
1034 case RELOC_BASE10:
1035 #endif
1036 case RELOC_BASE13:
1037 buf[2] |= (val >> 8) & 0x1f;
1038 buf[3] = val;
1039 break;
1040
1041 case RELOC_WDISP22:
1042 val = (val >>= 2) + 1;
1043 /* FALLTHROUGH */
1044 case RELOC_BASE22:
1045 buf[1] |= (val >> 16) & 0x3f;
1046 buf[2] = val >> 8;
1047 buf[3] = val;
1048 break;
1049
1050 #if 0
1051 case RELOC_PC10:
1052 case RELOC_PC22:
1053 case RELOC_JMP_TBL:
1054 case RELOC_SEGOFF16:
1055 case RELOC_GLOB_DAT:
1056 case RELOC_JMP_SLOT:
1057 case RELOC_RELATIVE:
1058 #endif
1059
1060 case NO_RELOC:
1061 default:
1062 as_bad("bad relocation type: 0x%02x", fixP->fx_r_type);
1063 break;
1064 }
1065 } /* md_apply_fix() */
1066
1067 /* should never be called for sparc */
1068 void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)
1069 char *ptr;
1070 long from_addr;
1071 long to_addr;
1072 fragS *frag;
1073 symbolS *to_symbol;
1074 {
1075 fprintf(stderr, "sparc_create_short_jmp\n");
1076 abort();
1077 } /* md_create_short_jump() */
1078
1079 /* Translate internal representation of relocation info to target format.
1080
1081 On sparc: first 4 bytes are normal unsigned long address, next three
1082 bytes are index, most sig. byte first. Byte 7 is broken up with
1083 bit 7 as external, bits 6 & 5 unused, and the lower
1084 five bits as relocation type. Next 4 bytes are long addend. */
1085 /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
1086 void md_ri_to_chars(the_bytes, ri)
1087 char *the_bytes;
1088 struct reloc_info_generic *ri;
1089 {
1090 /* this is easy */
1091 md_number_to_chars(the_bytes, ri->r_address, 4);
1092 /* now the fun stuff */
1093 the_bytes[4] = (ri->r_index >> 16) & 0x0ff;
1094 the_bytes[5] = (ri->r_index >> 8) & 0x0ff;
1095 the_bytes[6] = ri->r_index & 0x0ff;
1096 the_bytes[7] = ((ri->r_extern << 7) & 0x80) | (0 & 0x60) | (ri->r_type & 0x1F);
1097 /* Also easy */
1098 md_number_to_chars(&the_bytes[8], ri->r_addend, 4);
1099 } /* md_ri_to_chars() */
1100
1101 /* should never be called for sparc */
1102 void md_convert_frag(fragP)
1103 register fragS *fragP;
1104 {
1105 fprintf(stderr, "sparc_convert_frag\n");
1106 abort();
1107 } /* md_convert_frag() */
1108
1109 /* should never be called for sparc */
1110 void md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol)
1111 char *ptr;
1112 long from_addr, to_addr;
1113 fragS *frag;
1114 symbolS *to_symbol;
1115 {
1116 fprintf(stderr, "sparc_create_long_jump\n");
1117 abort();
1118 } /* md_create_long_jump() */
1119
1120 /* should never be called for sparc */
1121 int md_estimate_size_before_relax(fragP, segtype)
1122 fragS *fragP;
1123 segT segtype;
1124 {
1125 fprintf(stderr, "sparc_estimate_size_before_relax\n");
1126 abort();
1127 return 0;
1128 } /* md_estimate_size_before_relax() */
1129
1130 #if 0
1131 /* for debugging only */
1132 static void print_insn(insn)
1133 struct sparc_it *insn;
1134 {
1135 char *Reloc[] = {
1136 "RELOC_8",
1137 "RELOC_16",
1138 "RELOC_32",
1139 "RELOC_DISP8",
1140 "RELOC_DISP16",
1141 "RELOC_DISP32",
1142 "RELOC_WDISP30",
1143 "RELOC_WDISP22",
1144 "RELOC_HI22",
1145 "RELOC_22",
1146 "RELOC_13",
1147 "RELOC_LO10",
1148 "RELOC_SFA_BASE",
1149 "RELOC_SFA_OFF13",
1150 "RELOC_BASE10",
1151 "RELOC_BASE13",
1152 "RELOC_BASE22",
1153 "RELOC_PC10",
1154 "RELOC_PC22",
1155 "RELOC_JMP_TBL",
1156 "RELOC_SEGOFF16",
1157 "RELOC_GLOB_DAT",
1158 "RELOC_JMP_SLOT",
1159 "RELOC_RELATIVE",
1160 "NO_RELOC"
1161 };
1162
1163 if (insn->error) {
1164 fprintf(stderr, "ERROR: %s\n");
1165 }
1166 fprintf(stderr, "opcode=0x%08x\n", insn->opcode);
1167 fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]);
1168 fprintf(stderr, "exp = {
1169 \n");
1170 fprintf(stderr, "\t\tX_add_symbol = %s\n",
1171 ((insn->exp.X_add_symbol != NULL)
1172 ? ((S_GET_NAME(insn->exp.X_add_symbol) != NULL)
1173 ? S_GET_NAME(insn->exp.X_add_symbol)
1174 : "???")
1175 : "0"));
1176 fprintf(stderr, "\t\tX_sub_symbol = %s\n",
1177 ((insn->exp.X_subtract_symbol != NULL)
1178 ? (S_GET_NAME(insn->exp.X_subtract_symbol)
1179 ? S_GET_NAME(insn->exp.X_subtract_symbol)
1180 : "???")
1181 : "0"));
1182 fprintf(stderr, "\t\tX_add_number = %d\n",
1183 insn->exp.X_add_number);
1184 fprintf(stderr, "}\n");
1185 return;
1186 } /* print_insn() */
1187 #endif
1188
1189 /* Set the hook... */
1190
1191 void emit_sparc_reloc();
1192 void (*md_emit_relocations)() = emit_sparc_reloc;
1193
1194 /*
1195 * Sparc/AM29K relocations are completely different, so it needs
1196 * this machine dependent routine to emit them.
1197 */
1198 #if defined(OBJ_AOUT) || defined(OBJ_BOUT)
1199 void emit_sparc_reloc(fixP, segment_address_in_file)
1200 register fixS *fixP;
1201 relax_addressT segment_address_in_file;
1202 {
1203 struct reloc_info_generic ri;
1204 register symbolS *symbolP;
1205 extern char *next_object_file_charP;
1206 /* long add_number; */
1207
1208 bzero((char *) &ri, sizeof(ri));
1209 for (; fixP; fixP = fixP->fx_next) {
1210
1211 if (fixP->fx_r_type >= NO_RELOC) {
1212 fprintf(stderr, "fixP->fx_r_type = %d\n", fixP->fx_r_type);
1213 abort();
1214 }
1215
1216 if ((symbolP = fixP->fx_addsy) != NULL) {
1217 ri.r_address = fixP->fx_frag->fr_address +
1218 fixP->fx_where - segment_address_in_file;
1219 if ((S_GET_TYPE(symbolP)) == N_UNDF) {
1220 ri.r_extern = 1;
1221 ri.r_index = symbolP->sy_number;
1222 } else {
1223 ri.r_extern = 0;
1224 ri.r_index = S_GET_TYPE(symbolP);
1225 }
1226 if (symbolP && symbolP->sy_frag) {
1227 ri.r_addend = symbolP->sy_frag->fr_address;
1228 }
1229 ri.r_type = fixP->fx_r_type;
1230 if (fixP->fx_pcrel) {
1231 /* ri.r_addend -= fixP->fx_where; */
1232 ri.r_addend -= ri.r_address;
1233 } else {
1234 ri.r_addend = fixP->fx_addnumber;
1235 }
1236
1237 md_ri_to_chars(next_object_file_charP, &ri);
1238 next_object_file_charP += md_reloc_size;
1239 }
1240 }
1241 return;
1242 } /* emit_sparc_reloc() */
1243 #endif /* aout or bout */
1244
1245 int md_parse_option(argP,cntP,vecP)
1246 char **argP;
1247 int *cntP;
1248 char ***vecP;
1249 {
1250 return 1;
1251 } /* md_parse_option() */
1252
1253 /* We have no need to default values of symbols. */
1254
1255 /* ARGSUSED */
1256 symbolS *md_undefined_symbol(name)
1257 char *name;
1258 {
1259 return 0;
1260 } /* md_undefined_symbol() */
1261
1262 /* Parse an operand that is machine-specific.
1263 We just return without modifying the expression if we have nothing
1264 to do. */
1265
1266 /* ARGSUSED */
1267 void md_operand(expressionP)
1268 expressionS *expressionP;
1269 {
1270 } /* md_operand() */
1271
1272 /* Round up a section size to the appropriate boundary. */
1273 long md_section_align (segment, size)
1274 segT segment;
1275 long size;
1276 {
1277 return (size + 7) & ~7; /* Round all sects to multiple of 8 */
1278 } /* md_section_align() */
1279
1280 /* Exactly what point is a PC-relative offset relative TO?
1281 On the sparc, they're relative to the address of the offset, plus
1282 its size. This gets us to the following instruction.
1283 (??? Is this right? FIXME-SOON) */
1284 long md_pcrel_from(fixP)
1285 fixS *fixP;
1286 {
1287 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
1288 } /* md_pcrel_from() */
1289
1290 /*
1291 * Local Variables:
1292 * comment-column: 0
1293 * fill-column: 131
1294 * End:
1295 */
1296
1297 /* end of tp-sparc.c */
This page took 0.058968 seconds and 5 git commands to generate.