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