Flag error if absolute constant is too large for an immediate field.
[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 long immediate_max = 0;
529
530 for (s = str; islower(*s) || (*s >= '0' && *s <= '3'); ++s)
531 ;
532 switch (*s) {
533
534 case '\0':
535 break;
536
537 case ',':
538 comma = 1;
539
540 /*FALLTHROUGH */
541
542 case ' ':
543 *s++ = '\0';
544 break;
545
546 default:
547 as_bad("Unknown opcode: `%s'", str);
548 exit(1);
549 }
550 if ((insn = (struct sparc_opcode *) hash_find(op_hash, str)) == NULL) {
551 as_bad("Unknown opcode: `%s'", str);
552 return;
553 }
554 if (comma) {
555 *--s = ',';
556 }
557 argsStart = s;
558 for (;;) {
559 opcode = insn->match;
560 memset(&the_insn, '\0', sizeof(the_insn));
561 the_insn.reloc = NO_RELOC;
562
563 /*
564 * Build the opcode, checking as we go to make
565 * sure that the operands match
566 */
567 for (args = insn->args; ; ++args) {
568 switch (*args) {
569
570 /* start-sanitize-v9 */
571 #ifndef NO_V9
572 case 'K':
573 {
574 /* Load is 0; Store is 1.
575 We compute the mask based on the values
576 we find in S. OK is set set
577 if we see something we don't like. */
578 int ok = 1;
579 int mask = 0;
580 while (ok == 1)
581 {
582 int lo = 0, hi = 0;
583 if (*s == '#')
584 {
585 s += 1;
586 if (! (lo = (s[0] == 'S')))
587 ok = (s[0] == 'L');
588 if (! (hi = (s[1] == 'S')))
589 ok = (s[1] == 'L');
590 mask |= (1 << ((hi<<1) | lo));
591 s += 2;
592 }
593 else
594 {
595 /* Parse a number, somehow. */
596 ok = 0;
597 }
598 if (s[2] != '|')
599 break;
600 }
601 if (! ok)
602 {
603 error_message = "unrecognizable mmask";
604 goto error;
605 }
606 opcode |= SIMM13(mask);
607 continue;
608 }
609
610 case '*':
611 /* Parse a prefetch function. */
612 if (*s == '#')
613 {
614 int prefetch_fcn = 0;
615
616 s += 1;
617 if (! strncmp (s, "n_reads", 7))
618 prefetch_fcn = 0, s += 7;
619 else if (! strncmp (s, "one_read", 8))
620 prefetch_fcn = 1, s += 8;
621 else if (! strncmp (s, "n_writes", 8))
622 prefetch_fcn = 2, s += 8;
623 else if (! strncmp (s, "one_write", 9))
624 prefetch_fcn = 3, s += 9;
625 else if (! strncmp (s, "page", 4))
626 prefetch_fcn = 4, s += 4;
627 else
628 {
629 error_message = "unrecognizable prefetch fucntion";
630 goto error;
631 }
632 }
633 else
634 {
635 /* Parse a number, somehow. */
636 error_message = "unrecognizable prefetch fucntion";
637 goto error;
638 }
639 continue;
640
641 case '!':
642 case '?':
643 /* Parse a privileged register. */
644 if (*s == '%')
645 {
646 struct priv_reg_entry *p = priv_reg_table;
647 int len;
648
649 s += 1;
650 while (p->name[0] > s[0])
651 p++;
652 while (p->name[0] == s[0])
653 {
654 len = strlen (p->name);
655 if (strncmp (p->name, s, len) == 0)
656 break;
657 p++;
658 }
659 if (p->name[0] != s[0])
660 {
661 error_message = "unrecognizable privileged register";
662 goto error;
663 }
664 if (*args == '?')
665 opcode |= (p->regnum << 14);
666 else
667 opcode |= (p->regnum << 25);
668 s += len;
669 continue;
670 }
671 else
672 {
673 error_message = "unrecognizable privileged register";
674 goto error;
675 }
676 #endif
677 /* end-sanitize-v9 */
678
679 case 'M':
680 case 'm':
681 if (strncmp(s, "%asr", 4) == 0) {
682 s += 4;
683
684 if (isdigit(*s)) {
685 long num = 0;
686
687 while (isdigit(*s)) {
688 num = num*10 + *s-'0';
689 ++s;
690 }
691
692 if (num < 16 || 31 < num) {
693 error_message = ": asr number must be between 15 and 31";
694 goto error;
695 } /* out of range */
696
697 opcode |= (*args == 'M' ? RS1(num) : RD(num));
698 continue;
699 } else {
700 error_message = ": expecting %asrN";
701 goto error;
702 } /* if %asr followed by a number. */
703
704 } /* if %asr */
705 break;
706
707 /* start-sanitize-v9 */
708 #ifndef NO_V9
709 case 'I':
710 the_insn.reloc = RELOC_11;
711 immediate_max = 0x03FF;
712 goto immediate;
713
714 case 'j':
715 the_insn.reloc = RELOC_10;
716 immediate_max = 0x01FF;
717 goto immediate;
718
719 case 'k':
720 the_insn.reloc = RELOC_WDISP2_14;
721 the_insn.pcrel = 1;
722 goto immediate;
723
724 case 'G':
725 the_insn.reloc = RELOC_WDISP19;
726 the_insn.pcrel = 1;
727 goto immediate;
728
729 case 'N':
730 if (*s == 'p' && s[1] == 'n') {
731 s += 2;
732 continue;
733 }
734 break;
735
736 case 'T':
737 if (*s == 'p' && s[1] == 't') {
738 s += 2;
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 'W':
811 if (strncmp(s, "%tick", 5) == 0) {
812 s += 5;
813 continue;
814 }
815 break;
816 #endif /* NO_V9 */
817 /* end-sanitize-v9 */
818
819 case '\0': /* end of args */
820 if (*s == '\0') {
821 match = 1;
822 }
823 break;
824
825 case '+':
826 if (*s == '+') {
827 ++s;
828 continue;
829 }
830 if (*s == '-') {
831 continue;
832 }
833 break;
834
835 case '[': /* these must match exactly */
836 case ']':
837 case ',':
838 case ' ':
839 if (*s++ == *args)
840 continue;
841 break;
842
843 case '#': /* must be at least one digit */
844 if (isdigit(*s++)) {
845 while (isdigit(*s)) {
846 ++s;
847 }
848 continue;
849 }
850 break;
851
852 case 'C': /* coprocessor state register */
853 if (strncmp(s, "%csr", 4) == 0) {
854 s += 4;
855 continue;
856 }
857 break;
858
859 case 'b': /* next operand is a coprocessor register */
860 case 'c':
861 case 'D':
862 if (*s++ == '%' && *s++ == 'c' && isdigit(*s)) {
863 mask = *s++;
864 if (isdigit(*s)) {
865 mask = 10 * (mask - '0') + (*s++ - '0');
866 if (mask >= 32) {
867 break;
868 }
869 } else {
870 mask -= '0';
871 }
872 switch (*args) {
873
874 case 'b':
875 opcode |= mask << 14;
876 continue;
877
878 case 'c':
879 opcode |= mask;
880 continue;
881
882 case 'D':
883 opcode |= mask << 25;
884 continue;
885 }
886 }
887 break;
888
889 case 'r': /* next operand must be a register */
890 case '1':
891 case '2':
892 case 'd':
893 if (*s++ == '%') {
894 switch (c = *s++) {
895
896 case 'f': /* frame pointer */
897 if (*s++ == 'p') {
898 mask = 0x1e;
899 break;
900 }
901 goto error;
902
903 case 'g': /* global register */
904 if (isoctal(c = *s++)) {
905 mask = c - '0';
906 break;
907 }
908 goto error;
909
910 case 'i': /* in register */
911 if (isoctal(c = *s++)) {
912 mask = c - '0' + 24;
913 break;
914 }
915 goto error;
916
917 case 'l': /* local register */
918 if (isoctal(c = *s++)) {
919 mask= (c - '0' + 16) ;
920 break;
921 }
922 goto error;
923
924 case 'o': /* out register */
925 if (isoctal(c = *s++)) {
926 mask= (c - '0' + 8) ;
927 break;
928 }
929 goto error;
930
931 case 's': /* stack pointer */
932 if (*s++ == 'p') {
933 mask= 0xe;
934 break;
935 }
936 goto error;
937
938 case 'r': /* any register */
939 if (!isdigit(c = *s++)) {
940 goto error;
941 }
942 /* FALLTHROUGH */
943 case '0': case '1': case '2': case '3': case '4':
944 case '5': case '6': case '7': case '8': case '9':
945 if (isdigit(*s)) {
946 if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32) {
947 goto error;
948 }
949 } else {
950 c -= '0';
951 }
952 mask= c;
953 break;
954
955 default:
956 goto error;
957 }
958 /*
959 * Got the register, now figure out where
960 * it goes in the opcode.
961 */
962 switch (*args) {
963
964 case '1':
965 opcode |= mask << 14;
966 continue;
967
968 case '2':
969 opcode |= mask;
970 continue;
971
972 case 'd':
973 opcode |= mask << 25;
974 continue;
975
976 case 'r':
977 opcode |= (mask << 25) | (mask << 14);
978 continue;
979 }
980 }
981 break;
982
983 case 'e': /* next operand is a floating point register */
984 case 'v':
985 case 'V':
986
987 case 'f':
988 case 'B':
989 case 'R':
990
991 case 'g':
992 case 'H':
993 case 'J': {
994 char format;
995
996 if (*s++ == '%'
997
998 /* start-sanitize-v9 */
999 #ifndef NO_V9
1000 && ((format = *s) == 'f'
1001 || *s == 'd'
1002 || *s == 'q')
1003 #else
1004 /* end-sanitize-v9 */
1005 && ((format = *s) == 'f')
1006
1007 /* start-sanitize-v9 */
1008 #endif /* NO_V9 */
1009 /* end-sanitize-v9 */
1010 && isdigit(*++s)) {
1011
1012
1013
1014 for (mask = 0; isdigit(*s); ++s) {
1015 mask = 10 * mask + (*s - '0');
1016 } /* read the number */
1017
1018 if ((*args == 'v'
1019 || *args == 'B'
1020 || *args == 'H')
1021 && (mask & 1)) {
1022 break;
1023 } /* register must be even numbered */
1024
1025 if ((*args == 'V'
1026 || *args == 'R'
1027 || *args == 'J')
1028 && (mask & 3)) {
1029 break;
1030 } /* register must be multiple of 4 */
1031
1032 if (format == 'f') {
1033 if (mask >= 32) {
1034 error_message = ": There are only 32 f registers; [0-31]";
1035 goto error;
1036 } /* on error */
1037 /* start-sanitize-v9 */
1038 #ifndef NO_V9
1039 } else {
1040 if (format == 'd') {
1041 if (mask >= 64) {
1042 error_message = ": There are only 32 d registers [0, 2, ... 62].";
1043 goto error;
1044 } else if (mask & 1) {
1045 error_message = ": Only even numbered d registers exist.";
1046 goto error;
1047 } /* on error */
1048
1049 } else if (format == 'q') {
1050 if (mask >= 64) {
1051 error_message =
1052 ": There are only 16 q registers [0, 4, ... 60].";
1053 goto error;
1054 } else if (mask & 3) {
1055 error_message =
1056 ": Only q registers evenly divisible by four exist.";
1057 goto error;
1058 } /* on error */
1059 } else {
1060 know(0);
1061 } /* depending on format */
1062
1063 if (mask >= 32) {
1064 mask -= 31;
1065 } /* wrap high bit */
1066 #endif /* NO_V9 */
1067 /* end-sanitize-v9 */
1068 } /* if not an 'f' register. */
1069 } /* on error */
1070
1071 switch (*args) {
1072
1073 case 'v':
1074 case 'V':
1075 case 'e':
1076 opcode |= RS1(mask);
1077 continue;
1078
1079
1080 case 'f':
1081 case 'B':
1082 case 'R':
1083 opcode |= RS2(mask);
1084 continue;
1085
1086 case 'g':
1087 case 'H':
1088 case 'J':
1089 opcode |= RD(mask);
1090 continue;
1091 } /* pack it in. */
1092
1093 know(0);
1094 break;
1095 } /* float arg */
1096
1097 case 'F':
1098 if (strncmp(s, "%fsr", 4) == 0) {
1099 s += 4;
1100 continue;
1101 }
1102 break;
1103
1104 case 'h': /* high 22 bits */
1105 the_insn.reloc = RELOC_HI22;
1106 goto immediate;
1107
1108 case 'l': /* 22 bit PC relative immediate */
1109 the_insn.reloc = RELOC_WDISP22;
1110 the_insn.pcrel = 1;
1111 goto immediate;
1112
1113 case 'L': /* 30 bit immediate */
1114 the_insn.reloc = RELOC_WDISP30;
1115 the_insn.pcrel = 1;
1116 goto immediate;
1117
1118 case 'n': /* 22 bit immediate */
1119 the_insn.reloc = RELOC_22;
1120 goto immediate;
1121
1122 case 'i': /* 13 bit immediate */
1123 the_insn.reloc = RELOC_BASE13;
1124 immediate_max = 0x0FFF;
1125
1126 /*FALLTHROUGH */
1127
1128 immediate:
1129 if(*s==' ')
1130 s++;
1131 if (*s == '%') {
1132 if ((c = s[1]) == 'h' && s[2] == 'i') {
1133 the_insn.reloc = RELOC_HI22;
1134 s+=3;
1135 } else if (c == 'l' && s[2] == 'o') {
1136 the_insn.reloc = RELOC_LO10;
1137 s+=3;
1138 /* start-sanitize-v9 */
1139 #ifndef NO_V9
1140 } else if (c == 'u'
1141 && s[2] == 'h'
1142 && s[3] == 'i') {
1143 the_insn.reloc = RELOC_HHI22;
1144 s += 4;
1145
1146 } else if (c == 'u'
1147 && s[2] == 'l'
1148 && s[3] == 'o') {
1149 the_insn.reloc = RELOC_HLO10;
1150 s += 4;
1151 #endif /* NO_V9 */
1152 /* end-sanitize-v9 */
1153 } else
1154 break;
1155 }
1156 /* Note that if the getExpression() fails, we
1157 will still have created U entries in the
1158 symbol table for the 'symbols' in the input
1159 string. Try not to create U symbols for
1160 registers, etc. */
1161 {
1162 /* This stuff checks to see if the
1163 expression ends in +%reg If it does,
1164 it removes the register from the
1165 expression, and re-sets 's' to point
1166 to the right place */
1167
1168 char *s1;
1169
1170 for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++) ;;
1171
1172 if (s1 != s && isdigit(s1[-1])) {
1173 if(s1[-2] == '%' && s1[-3] == '+') {
1174 s1 -= 3;
1175 *s1 = '\0';
1176 (void) getExpression(s);
1177 *s1 = '+';
1178 s = s1;
1179 continue;
1180 } else if (strchr("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+') {
1181 s1 -= 4;
1182 *s1 = '\0';
1183 (void) getExpression(s);
1184 *s1 = '+';
1185 s = s1;
1186 continue;
1187 }
1188 }
1189 }
1190 (void)getExpression(s);
1191 s = expr_end;
1192
1193 /* Check for invalid constant values. Don't
1194 warn if constant was inside %hi or %lo,
1195 since these truncate the constant to
1196 fit. */
1197 if (immediate_max != 0
1198 && the_insn.reloc != RELOC_LO10
1199 && the_insn.reloc != RELOC_HI22
1200 /* start-sanitize-v9 */
1201 #ifndef NO_V9
1202 && the_insn.reloc != RELOC_HLO10
1203 && the_insn.reloc != RELOC_HHI22
1204 #endif
1205 /* end-sanitize-v9 */
1206 && the_insn.exp.X_add_symbol == 0
1207 && the_insn.exp.X_subtract_symbol == 0
1208 && the_insn.exp.X_seg == SEG_ABSOLUTE
1209 && (the_insn.exp.X_add_number > immediate_max
1210 || the_insn.exp.X_add_number < ~immediate_max))
1211 as_bad ("constant value must be between %ld and %ld",
1212 ~immediate_max, immediate_max);
1213 /* Reset to prevent extraneous range check. */
1214 immediate_max = 0;
1215
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 'o':
1275 if (strncmp (s, "%asi", 4) != 0)
1276 break;
1277 s += 4;
1278 continue;
1279
1280 case 's':
1281 if (strncmp (s, "%fprs", 5) != 0)
1282 break;
1283 s+= 5;
1284 continue;
1285
1286 case 'E':
1287 if (strncmp (s, "%ccr", 4) != 0)
1288 break;
1289 s+= 4;
1290 continue;
1291 #endif /* NO_V9 */
1292 /* end-sanitize-v9 */
1293
1294 case 't':
1295 if (strncmp(s, "%tbr", 4) != 0)
1296 break;
1297 s += 4;
1298 continue;
1299
1300 case 'w':
1301 if (strncmp(s, "%wim", 4) != 0)
1302 break;
1303 s += 4;
1304 continue;
1305
1306 case 'y':
1307 if (strncmp(s, "%y", 2) != 0)
1308 break;
1309 s += 2;
1310 continue;
1311
1312 default:
1313 as_fatal("failed sanity check.");
1314 } /* switch on arg code */
1315 break;
1316 } /* for each arg that we expect */
1317 error:
1318 if (match == 0) {
1319 /* Args don't match. */
1320 if (((unsigned) (&insn[1] - sparc_opcodes)) < NUMOPCODES
1321 && !strcmp(insn->name, insn[1].name)) {
1322 ++insn;
1323 s = argsStart;
1324 continue;
1325 } else {
1326 as_bad("Illegal operands%s", error_message);
1327 return;
1328 }
1329 } else {
1330 if (insn->architecture > current_architecture) {
1331 if ((!architecture_requested || warn_on_bump)
1332 &&
1333 /* start-sanitize-v9 */
1334 #ifndef NO_V9
1335 ! ARCHITECTURES_CONFLICT_P (current_architecture,
1336 insn->architecture)
1337 #else
1338 /* end-sanitize-v9 */
1339 1
1340 /* start-sanitize-v9 */
1341 #endif
1342 /* end-sanitize-v9 */
1343 ) {
1344 if (warn_on_bump) {
1345 as_warn("architecture bumped from \"%s\" to \"%s\" on \"%s\"",
1346 architecture_pname[current_architecture],
1347 architecture_pname[insn->architecture],
1348 str);
1349 } /* if warning */
1350
1351 current_architecture = insn->architecture;
1352 } else {
1353 as_bad("architecture mismatch on \"%s\" (\"%s\"). current architecture is \"%s\"",
1354 str,
1355 architecture_pname[insn->architecture],
1356 architecture_pname[current_architecture]);
1357 return;
1358 } /* if bump ok else error */
1359 } /* if architecture higher */
1360 } /* if no match */
1361
1362 break;
1363 } /* forever looking for a match */
1364
1365 the_insn.opcode = opcode;
1366 return;
1367 } /* sparc_ip() */
1368
1369 static int getExpression(str)
1370 char *str;
1371 {
1372 char *save_in;
1373 segT seg;
1374
1375 save_in = input_line_pointer;
1376 input_line_pointer = str;
1377 switch (seg = expression(&the_insn.exp)) {
1378
1379 case SEG_ABSOLUTE:
1380 case SEG_TEXT:
1381 case SEG_DATA:
1382 case SEG_BSS:
1383 case SEG_UNKNOWN:
1384 case SEG_DIFFERENCE:
1385 case SEG_BIG:
1386 case SEG_ABSENT:
1387 break;
1388
1389 default:
1390 the_insn.error = "bad segment";
1391 expr_end = input_line_pointer;
1392 input_line_pointer=save_in;
1393 return 1;
1394 }
1395 expr_end = input_line_pointer;
1396 input_line_pointer = save_in;
1397 return 0;
1398 } /* getExpression() */
1399
1400
1401 /*
1402 This is identical to the md_atof in m68k.c. I think this is right,
1403 but I'm not sure.
1404
1405 Turn a string in input_line_pointer into a floating point constant of type
1406 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1407 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1408 */
1409
1410 /* Equal to MAX_PRECISION in atof-ieee.c */
1411 #define MAX_LITTLENUMS 6
1412
1413 char *md_atof(type,litP,sizeP)
1414 char type;
1415 char *litP;
1416 int *sizeP;
1417 {
1418 int prec;
1419 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1420 LITTLENUM_TYPE *wordP;
1421 char *t;
1422 char *atof_ieee();
1423
1424 switch(type) {
1425
1426 case 'f':
1427 case 'F':
1428 case 's':
1429 case 'S':
1430 prec = 2;
1431 break;
1432
1433 case 'd':
1434 case 'D':
1435 case 'r':
1436 case 'R':
1437 prec = 4;
1438 break;
1439
1440 case 'x':
1441 case 'X':
1442 prec = 6;
1443 break;
1444
1445 case 'p':
1446 case 'P':
1447 prec = 6;
1448 break;
1449
1450 default:
1451 *sizeP=0;
1452 return "Bad call to MD_ATOF()";
1453 }
1454 t=atof_ieee(input_line_pointer,type,words);
1455 if(t)
1456 input_line_pointer=t;
1457 *sizeP=prec * sizeof(LITTLENUM_TYPE);
1458 for(wordP=words;prec--;) {
1459 md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
1460 litP+=sizeof(LITTLENUM_TYPE);
1461 }
1462 return ""; /* Someone should teach Dean about null pointers */
1463 } /* md_atof() */
1464
1465 /*
1466 * Write out big-endian.
1467 */
1468 void md_number_to_chars(buf,val,n)
1469 char *buf;
1470 long val;
1471 int n;
1472 {
1473
1474 switch(n) {
1475
1476 case 4:
1477 *buf++ = val >> 24;
1478 *buf++ = val >> 16;
1479 case 2:
1480 *buf++ = val >> 8;
1481 case 1:
1482 *buf = val;
1483 break;
1484
1485 default:
1486 as_fatal("failed sanity check.");
1487 }
1488 return;
1489 } /* md_number_to_chars() */
1490
1491 /* Apply a fixS to the frags, now that we know the value it ought to
1492 hold. */
1493
1494 void md_apply_fix(fixP, val)
1495 fixS *fixP;
1496 long val;
1497 {
1498 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1499
1500 assert(fixP->fx_size == 4);
1501 assert(fixP->fx_r_type < NO_RELOC);
1502
1503 fixP->fx_addnumber = val; /* Remember value for emit_reloc */
1504
1505 /*
1506 * This is a hack. There should be a better way to
1507 * handle this.
1508 */
1509 if (fixP->fx_r_type == RELOC_WDISP30 && fixP->fx_addsy) {
1510 val += fixP->fx_where + fixP->fx_frag->fr_address;
1511 }
1512
1513 switch (fixP->fx_r_type) {
1514
1515 case RELOC_32:
1516 buf[0] = 0; /* val >> 24; */
1517 buf[1] = 0; /* val >> 16; */
1518 buf[2] = 0; /* val >> 8; */
1519 buf[3] = 0; /* val; */
1520 break;
1521
1522 #if 0
1523 case RELOC_8: /* These don't seem to ever be needed. */
1524 case RELOC_16:
1525 case RELOC_DISP8:
1526 case RELOC_DISP16:
1527 case RELOC_DISP32:
1528 #endif
1529 case RELOC_WDISP30:
1530 val = (val >>= 2) + 1;
1531 buf[0] |= (val >> 24) & 0x3f;
1532 buf[1]= (val >> 16);
1533 buf[2] = val >> 8;
1534 buf[3] = val;
1535 break;
1536
1537 /* start-sanitize-v9 */
1538 #ifndef NO_V9
1539 case RELOC_11:
1540 if (((val > 0) && (val & ~0x7ff))
1541 || ((val < 0) && (~(val - 1) & ~0x7ff))) {
1542 as_bad("relocation overflow.");
1543 } /* on overflow */
1544
1545 buf[2] |= (val >> 8) & 0x7;
1546 buf[3] = val & 0xff;
1547 break;
1548
1549 case RELOC_10:
1550 if (((val > 0) && (val & ~0x3ff))
1551 || ((val < 0) && (~(val - 1) & ~0x3ff))) {
1552 as_bad("relocation overflow.");
1553 } /* on overflow */
1554
1555 buf[2] |= (val >> 8) & 0x3;
1556 buf[3] = val & 0xff;
1557 break;
1558
1559 case RELOC_WDISP2_14:
1560 if (((val > 0) && (val & ~0x3fffc))
1561 || ((val < 0) && (~(val - 1) & ~0x3fffc))) {
1562 as_bad("relocation overflow.");
1563 } /* on overflow */
1564
1565 val = (val >>= 2) + 1;
1566 buf[1] |= ((val >> 14) & 0x3) << 3;
1567 buf[2] |= (val >> 8) & 0x3f ;
1568 buf[3] = val & 0xff;
1569 break;
1570
1571 case RELOC_WDISP19:
1572 if (((val > 0) && (val & ~0x1ffffc))
1573 || ((val < 0) && (~(val - 1) & ~0x1ffffc))) {
1574 as_bad("relocation overflow.");
1575 } /* on overflow */
1576
1577 val = (val >>= 2) + 1;
1578 buf[1] |= (val >> 16) & 0x7;
1579 buf[2] = (val >> 8) & 0xff;
1580 buf[3] = val & 0xff;
1581 break;
1582
1583 case RELOC_HHI22:
1584 val >>= 32;
1585 /* intentional fallthrough */
1586 #endif /* NO_V9 */
1587 /* end-sanitize-v9 */
1588
1589 case RELOC_HI22:
1590 if(!fixP->fx_addsy) {
1591 buf[1] |= (val >> 26) & 0x3f;
1592 buf[2] = val >> 18;
1593 buf[3] = val >> 10;
1594 } else {
1595 buf[2]=0;
1596 buf[3]=0;
1597 }
1598 break;
1599
1600 case RELOC_22:
1601 if (val & ~0x003fffff) {
1602 as_bad("relocation overflow");
1603 } /* on overflow */
1604 buf[1] |= (val >> 16) & 0x3f;
1605 buf[2] = val >> 8;
1606 buf[3] = val & 0xff;
1607 break;
1608
1609 case RELOC_13:
1610 if (val & ~0x00001fff) {
1611 as_bad("relocation overflow");
1612 } /* on overflow */
1613 buf[2] |= (val >> 8) & 0x1f;
1614 buf[3] = val & 0xff;
1615 break;
1616
1617 /* start-sanitize-v9 */
1618 #ifndef NO_V9
1619 case RELOC_HLO10:
1620 val >>= 32;
1621 /* intentional fallthrough */
1622 #endif /* NO_V9 */
1623 /* end-sanitize-v9 */
1624
1625 case RELOC_LO10:
1626 if(!fixP->fx_addsy) {
1627 buf[2] |= (val >> 8) & 0x03;
1628 buf[3] = val;
1629 } else
1630 buf[3]=0;
1631 break;
1632 #if 0
1633 case RELOC_SFA_BASE:
1634 case RELOC_SFA_OFF13:
1635 case RELOC_BASE10:
1636 #endif
1637 case RELOC_BASE13:
1638 if (((val > 0) && (val & ~0x00001fff))
1639 || ((val < 0) && (~(val - 1) & ~0x00001fff))) {
1640 as_bad("relocation overflow");
1641 } /* on overflow */
1642 buf[2] |= (val >> 8) & 0x1f;
1643 buf[3] = val;
1644 break;
1645
1646 case RELOC_WDISP22:
1647 val = (val >>= 2) + 1;
1648 /* FALLTHROUGH */
1649 case RELOC_BASE22:
1650 buf[1] |= (val >> 16) & 0x3f;
1651 buf[2] = val >> 8;
1652 buf[3] = val;
1653 break;
1654
1655 #if 0
1656 case RELOC_PC10:
1657 case RELOC_PC22:
1658 case RELOC_JMP_TBL:
1659 case RELOC_SEGOFF16:
1660 case RELOC_GLOB_DAT:
1661 case RELOC_JMP_SLOT:
1662 case RELOC_RELATIVE:
1663 #endif
1664
1665 case NO_RELOC:
1666 default:
1667 as_bad("bad relocation type: 0x%02x", fixP->fx_r_type);
1668 break;
1669 }
1670 } /* md_apply_fix() */
1671
1672 /* should never be called for sparc */
1673 void md_create_short_jump(ptr, from_addr, to_addr, frag, to_symbol)
1674 char *ptr;
1675 long from_addr;
1676 long to_addr;
1677 fragS *frag;
1678 symbolS *to_symbol;
1679 {
1680 as_fatal("sparc_create_short_jmp\n");
1681 } /* md_create_short_jump() */
1682
1683 /* Translate internal representation of relocation info to target format.
1684
1685 On sparc: first 4 bytes are normal unsigned long address, next three
1686 bytes are index, most sig. byte first. Byte 7 is broken up with
1687 bit 7 as external, bits 6 & 5 unused, and the lower
1688 five bits as relocation type. Next 4 bytes are long addend. */
1689 /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
1690 void
1691 tc_aout_fix_to_chars(where, fixP, segment_address_in_file)
1692 char *where;
1693 fixS *fixP;
1694 relax_addressT segment_address_in_file;
1695 {
1696 long r_index;
1697 long r_extern;
1698 long r_addend = 0;
1699 long r_address;
1700
1701 know(fixP->fx_addsy);
1702
1703 if (!S_IS_DEFINED(fixP->fx_addsy)) {
1704 r_extern = 1;
1705 r_index = fixP->fx_addsy->sy_number;
1706 } else {
1707 r_extern = 0;
1708 r_index = S_GET_TYPE(fixP->fx_addsy);
1709 }
1710
1711 /* this is easy */
1712 md_number_to_chars(where,
1713 r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
1714 4);
1715
1716 /* now the fun stuff */
1717 where[4] = (r_index >> 16) & 0x0ff;
1718 where[5] = (r_index >> 8) & 0x0ff;
1719 where[6] = r_index & 0x0ff;
1720 where[7] = ((r_extern << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F);
1721
1722 /* Also easy */
1723 if (fixP->fx_addsy->sy_frag) {
1724 r_addend = fixP->fx_addsy->sy_frag->fr_address;
1725 }
1726
1727 if (fixP->fx_pcrel) {
1728 r_addend += fixP->fx_offset - r_address;
1729 } else {
1730 r_addend = fixP->fx_addnumber;
1731 }
1732
1733 md_number_to_chars(&where[8], r_addend, 4);
1734
1735 return;
1736 } /* tc_aout_fix_to_chars() */
1737
1738 /* should never be called for sparc */
1739 void md_convert_frag(headers, fragP)
1740 object_headers *headers;
1741 register fragS *fragP;
1742 {
1743 as_fatal("sparc_convert_frag\n");
1744 } /* md_convert_frag() */
1745
1746 /* should never be called for sparc */
1747 void md_create_long_jump(ptr, from_addr, to_addr, frag, to_symbol)
1748 char *ptr;
1749 long from_addr, to_addr;
1750 fragS *frag;
1751 symbolS *to_symbol;
1752 {
1753 as_fatal("sparc_create_long_jump\n");
1754 } /* md_create_long_jump() */
1755
1756 /* should never be called for sparc */
1757 int md_estimate_size_before_relax(fragP, segtype)
1758 fragS *fragP;
1759 segT segtype;
1760 {
1761 as_fatal("sparc_estimate_size_before_relax\n");
1762 return(1);
1763 } /* md_estimate_size_before_relax() */
1764
1765 #if 0
1766 /* for debugging only */
1767 static void print_insn(insn)
1768 struct sparc_it *insn;
1769 {
1770 char *Reloc[] = {
1771 "RELOC_8",
1772 "RELOC_16",
1773 "RELOC_32",
1774 "RELOC_DISP8",
1775 "RELOC_DISP16",
1776 "RELOC_DISP32",
1777 "RELOC_WDISP30",
1778 "RELOC_WDISP22",
1779 "RELOC_HI22",
1780 "RELOC_22",
1781 "RELOC_13",
1782 "RELOC_LO10",
1783 "RELOC_SFA_BASE",
1784 "RELOC_SFA_OFF13",
1785 "RELOC_BASE10",
1786 "RELOC_BASE13",
1787 "RELOC_BASE22",
1788 "RELOC_PC10",
1789 "RELOC_PC22",
1790 "RELOC_JMP_TBL",
1791 "RELOC_SEGOFF16",
1792 "RELOC_GLOB_DAT",
1793 "RELOC_JMP_SLOT",
1794 "RELOC_RELATIVE",
1795 "NO_RELOC"
1796 };
1797
1798 if (insn->error) {
1799 fprintf(stderr, "ERROR: %s\n");
1800 }
1801 fprintf(stderr, "opcode=0x%08x\n", insn->opcode);
1802 fprintf(stderr, "reloc = %s\n", Reloc[insn->reloc]);
1803 fprintf(stderr, "exp = {
1804 \n");
1805 fprintf(stderr, "\t\tX_add_symbol = %s\n",
1806 ((insn->exp.X_add_symbol != NULL)
1807 ? ((S_GET_NAME(insn->exp.X_add_symbol) != NULL)
1808 ? S_GET_NAME(insn->exp.X_add_symbol)
1809 : "???")
1810 : "0"));
1811 fprintf(stderr, "\t\tX_sub_symbol = %s\n",
1812 ((insn->exp.X_subtract_symbol != NULL)
1813 ? (S_GET_NAME(insn->exp.X_subtract_symbol)
1814 ? S_GET_NAME(insn->exp.X_subtract_symbol)
1815 : "???")
1816 : "0"));
1817 fprintf(stderr, "\t\tX_add_number = %d\n",
1818 insn->exp.X_add_number);
1819 fprintf(stderr, "}\n");
1820 return;
1821 } /* print_insn() */
1822 #endif
1823
1824 /* Set the hook... */
1825
1826 /* void emit_sparc_reloc();
1827 void (*md_emit_relocations)() = emit_sparc_reloc; */
1828
1829 #ifdef comment
1830
1831 /*
1832 * Sparc/AM29K relocations are completely different, so it needs
1833 * this machine dependent routine to emit them.
1834 */
1835 #if defined(OBJ_AOUT) || defined(OBJ_BOUT)
1836 void emit_sparc_reloc(fixP, segment_address_in_file)
1837 register fixS *fixP;
1838 relax_addressT segment_address_in_file;
1839 {
1840 struct reloc_info_generic ri;
1841 register symbolS *symbolP;
1842 extern char *next_object_file_charP;
1843 /* long add_number; */
1844
1845 memset((char *) &ri, '\0', sizeof(ri));
1846 for (; fixP; fixP = fixP->fx_next) {
1847
1848 if (fixP->fx_r_type >= NO_RELOC) {
1849 as_fatal("fixP->fx_r_type = %d\n", fixP->fx_r_type);
1850 }
1851
1852 if ((symbolP = fixP->fx_addsy) != NULL) {
1853 ri.r_address = fixP->fx_frag->fr_address +
1854 fixP->fx_where - segment_address_in_file;
1855 if ((S_GET_TYPE(symbolP)) == N_UNDF) {
1856 ri.r_extern = 1;
1857 ri.r_index = symbolP->sy_number;
1858 } else {
1859 ri.r_extern = 0;
1860 ri.r_index = S_GET_TYPE(symbolP);
1861 }
1862 if (symbolP && symbolP->sy_frag) {
1863 ri.r_addend = symbolP->sy_frag->fr_address;
1864 }
1865 ri.r_type = fixP->fx_r_type;
1866 if (fixP->fx_pcrel) {
1867 /* ri.r_addend -= fixP->fx_where; */
1868 ri.r_addend -= ri.r_address;
1869 } else {
1870 ri.r_addend = fixP->fx_addnumber;
1871 }
1872
1873 md_ri_to_chars(next_object_file_charP, &ri);
1874 next_object_file_charP += md_reloc_size;
1875 }
1876 }
1877 return;
1878 } /* emit_sparc_reloc() */
1879 #endif /* aout or bout */
1880 #endif /* comment */
1881
1882 /*
1883 * md_parse_option
1884 * Invocation line includes a switch not recognized by the base assembler.
1885 * See if it's a processor-specific option. These are:
1886 *
1887 * -bump
1888 * Warn on architecture bumps. See also -A.
1889 *
1890 * -Av6, -Av7, -Av8, -Asparclite
1891 * Select the architecture. Instructions or features not
1892 * supported by the selected architecture cause fatal errors.
1893 *
1894 * The default is to start at v6, and bump the architecture up
1895 * whenever an instruction is seen at a higher level.
1896 *
1897 * If -bump is specified, a warning is printing when bumping to
1898 * higher levels.
1899 *
1900 * If an architecture is specified, all instructions must match
1901 * that architecture. Any higher level instructions are flagged
1902 * as errors.
1903 *
1904 * if both an architecture and -bump are specified, the
1905 * architecture starts at the specified level, but bumps are
1906 * warnings.
1907 *
1908 * start-sanitize-v9
1909 * Bumping between incompatible architectures is always an
1910 * error. For example, from sparclite to v9.
1911 * end-sanitize-v9
1912 */
1913 /* start-sanitize-v9 */
1914 /* There is also a -Av9 architecture option. xoxorich. */
1915 /* end-sanitize-v9 */
1916 int md_parse_option(argP, cntP, vecP)
1917 char **argP;
1918 int *cntP;
1919 char ***vecP;
1920 {
1921 char *p;
1922 const char **arch;
1923
1924 if (!strcmp(*argP,"bump")){
1925 warn_on_bump = 1;
1926
1927 } else if (**argP == 'A'){
1928 p = (*argP) + 1;
1929
1930 for (arch = architecture_pname; *arch != NULL; ++arch){
1931 if (strcmp(p, *arch) == 0){
1932 break;
1933 } /* found a match */
1934 } /* walk the pname table */
1935
1936 if (*arch == NULL){
1937 as_bad("unknown architecture: %s", p);
1938 } else {
1939 current_architecture = (enum sparc_architecture) (arch - architecture_pname);
1940 architecture_requested = 1;
1941 }
1942 } else {
1943 /* Unknown option */
1944 (*argP)++;
1945 return 0;
1946 }
1947 **argP = '\0'; /* Done parsing this switch */
1948 return 1;
1949 } /* md_parse_option() */
1950
1951 /* We have no need to default values of symbols. */
1952
1953 /* ARGSUSED */
1954 symbolS *md_undefined_symbol(name)
1955 char *name;
1956 {
1957 return 0;
1958 } /* md_undefined_symbol() */
1959
1960 /* Parse an operand that is machine-specific.
1961 We just return without modifying the expression if we have nothing
1962 to do. */
1963
1964 /* ARGSUSED */
1965 void md_operand(expressionP)
1966 expressionS *expressionP;
1967 {
1968 } /* md_operand() */
1969
1970 /* Round up a section size to the appropriate boundary. */
1971 long md_section_align (segment, size)
1972 segT segment;
1973 long size;
1974 {
1975 return (size + 7) & ~7; /* Round all sects to multiple of 8 */
1976 } /* md_section_align() */
1977
1978 /* Exactly what point is a PC-relative offset relative TO?
1979 On the sparc, they're relative to the address of the offset, plus
1980 its size. This gets us to the following instruction.
1981 (??? Is this right? FIXME-SOON) */
1982 long md_pcrel_from(fixP)
1983 fixS *fixP;
1984 {
1985 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
1986 } /* md_pcrel_from() */
1987
1988 void tc_aout_pre_write_hook(headers)
1989 object_headers *headers;
1990 {
1991 H_SET_VERSION(headers, 1);
1992 return;
1993 } /* tc_aout_pre_write_hook() */
1994
1995 /*
1996 * Local Variables:
1997 * comment-column: 0
1998 * fill-column: 131
1999 * End:
2000 */
2001
2002 /* end of tc-sparc.c */
This page took 0.100642 seconds and 5 git commands to generate.