|
|
1.1 root 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: /* relocation type for internal assembler use only */
21: #define SPARC_RELOC_13 (127)
22: #define SPARC_RELOC_22 (126)
23:
24: #define cypress 1234
25:
26: #undef DEBUGINSN
27:
28: #include <stdio.h>
29: #include <ctype.h>
30: #include "as.h"
31: #include "libc.h"
32: #include "md.h"
33: #include "messages.h"
34: #include "symbols.h"
35:
36: /* careful, this file includes data *declarations* */
37: #include "sparc-opcode.h"
38: #include <mach-o/sparc/reloc.h>
39:
40: /* From GNU ansidecl.h */
41: #define PARAMS(paramlist) paramlist
42:
43: typedef long offsetT;
44:
45: /*
46: * These are the default cputype and cpusubtype for the Sparc architecture.
47: */
48: const cpu_type_t md_cputype = CPU_TYPE_SPARC;
49: cpu_subtype_t md_cpusubtype = CPU_SUBTYPE_SPARC_ALL;
50:
51: /* This is the byte sex for the Sparc architecture */
52: const enum byte_sex md_target_byte_sex = BIG_ENDIAN_BYTE_SEX;
53:
54: /* These characters start a comment anywhere on the line */
55: const char md_comment_chars[] = ";!";
56:
57: /* These characters only start a comment at the beginning of a line */
58: const char md_line_comment_chars[] = "#";
59:
60: /*
61: * These characters can be used to separate mantissa decimal digits from
62: * exponent decimal digits in floating point numbers.
63: */
64: const char md_EXP_CHARS[] = "eE";
65:
66: /*
67: * The characters after a leading 0 that means this number is a floating point
68: * constant as in 0f123.456 or 0d1.234E-12 (see md_EXP_CHARS above).
69: */
70: const char md_FLT_CHARS[] = "dDfF";
71:
72: static void sparc_ip PARAMS ((char *));
73:
74: static enum sparc_architecture current_architecture = v6;
75: static int architecture_requested;
76: static int warn_on_bump;
77:
78: const relax_typeS md_relax_table[1];
79:
80: /* handle of the OPCODE hash table */
81: static struct hash_control *op_hash = NULL;
82:
83: #ifdef NeXT
84: static void s_proc PARAMS ((int));
85: static void s_ignore PARAMS ((int));
86: extern void s_seg PARAMS ((int));
87: #else NeXT
88: static void s_data1 PARAMS ((void));
89: static void s_seg PARAMS ((int));
90: static void s_proc PARAMS ((int));
91: static void s_reserve PARAMS ((int));
92: static void s_common PARAMS ((int));
93: #endif NeXT
94:
95: const pseudo_typeS md_pseudo_table[] =
96: {
97: #ifdef NeXT
98: {"global", s_globl, 0}, /* Maybe we should fix compiler to use globl */
99: {"proc", s_proc, 0}, /* nop??? */
100: /* This are to handle SUN assembler files and point to existing handlers */
101: {"empty", s_ignore, 0},
102: {"ident", s_ignore, 0},
103: {"optim", s_ignore, 0},
104: {"skip", s_space, 0},
105: {"type", s_ignore, 0},
106: {"word", cons, 4},
107: {"half", cons, 2},
108: /* these are custom handlers for SUN SPARC assembler only */
109:
110: #else NeXT
111: {"seg", s_seg, 0},
112: {"align", s_align_bytes, 0}, /* Defaulting is invalid (0) */
113: {"common", s_common, 0},
114: {"global", s_globl, 0},
115: {"half", cons, 2},
116: {"optim", s_ignore, 0},
117: {"proc", s_proc, 0},
118: {"reserve", s_reserve, 0},
119: {"seg", s_seg, 0},
120: {"skip", s_space, 0},
121: {"word", cons, 4},
122: #endif NeXT
123: {NULL, 0, 0},
124: };
125:
126: const int md_short_jump_size = 4;
127: const int md_long_jump_size = 4;
128: const int md_reloc_size = 12; /* Size of relocation record */
129:
130: /* This array holds the chars that always start a comment. If the
131: pre-processor is disabled, these aren't very useful */
132: const char comment_chars[] = "!"; /* JF removed '|' from comment_chars */
133:
134: /* This array holds the chars that only start a comment at the beginning of
135: a line. If the line seems to have the form '# 123 filename'
136: .line and .file directives will appear in the pre-processed output */
137: /* Note that input_file.c hand checks for '#' at the beginning of the
138: first line of the input file. This is because the compiler outputs
139: #NO_APP at the beginning of its output. */
140: /* Also note that comments started like this one will always
141: work if '/' isn't otherwise defined. */
142: const char line_comment_chars[] = "#";
143:
144: const char line_separator_chars[] = "";
145:
146: /* Chars that can be used to separate mant from exp in floating point nums */
147: const char EXP_CHARS[] = "eE";
148:
149: /* Chars that mean this number is a floating point constant */
150: /* As in 0f12.456 */
151: /* or 0d1.2345e12 */
152: const char FLT_CHARS[] = "rRsSfFdDxXpP";
153:
154: /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
155: changed in read.c. Ideally it shouldn't have to know about it at all,
156: but nothing is ideal around here. */
157:
158: static unsigned char octal[256];
159: #define isoctal(c) octal[(unsigned char) (c)]
160: static unsigned char toHex[256];
161:
162: struct sparc_it
163: {
164: char *error;
165: unsigned long opcode;
166: struct nlist *nlistp;
167: expressionS exp;
168: int pcrel;
169: char pcrel_reloc; /* do relocation? */
170: enum reloc_type_sparc reloc;
171: };
172:
173: struct sparc_it the_insn;
174:
175: #ifdef DEBUGINSN
176: static void print_insn PARAMS ((struct sparc_it *insn));
177: #endif
178: static int getExpression PARAMS ((char *str));
179:
180: static char *expr_end;
181:
182:
183: /*
184: * Indicates a 'set' instruction which may require a either
185: * of the following instructions depending on the size of the
186: * value argument:
187: *
188: * sethi %hi(value),reg
189: *
190: * or %g0,value,reg
191: *
192: * sethi %hi(value),reg
193: * or reg,%lo(value),reg
194: *
195: */
196: static int special_case_set = 0;
197:
198: /* s_proc and s_ignore are included for rudimentary
199: compatibility with the Sun assembler only */
200:
201: static void
202: s_proc (ignore)
203: int ignore;
204: {
205: totally_ignore_line();
206: }
207:
208: /* we simply ignore the rest of this statement */
209: static void
210: s_ignore (ignore)
211: int ignore;
212: {
213: totally_ignore_line();
214: }
215:
216: /* This function is called once, at assembler startup time. It should
217: set up all the tables, etc. that the MD part of the assembler will need. */
218: void
219: md_begin ()
220: {
221: register const char *retval = NULL;
222: int lose = 0;
223: register unsigned int i = 0;
224:
225: op_hash = hash_new ();
226:
227: while (i < NUMOPCODES)
228: {
229: const char *name = sparc_opcodes[i].name;
230: retval = hash_insert (op_hash, (char *)name, (char *)&sparc_opcodes[i]);
231:
232: if(retval != NULL && *retval != '\0') {
233: fprintf (stderr, "internal error: can't hash `%s': %s\n",
234: sparc_opcodes[i].name, retval);
235: lose = 1;
236: } do {
237: if (sparc_opcodes[i].match & sparc_opcodes[i].lose)
238: {
239: fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n",
240: sparc_opcodes[i].name, sparc_opcodes[i].args);
241: lose = 1;
242: }
243: ++i;
244: }
245: while (i < NUMOPCODES
246: && !strcmp (sparc_opcodes[i].name, name));
247: }
248:
249: if (lose)
250: as_fatal ("Broken assembler. No assembly attempted.");
251:
252: for (i = '0'; i < '8'; ++i)
253: octal[i] = 1;
254: for (i = '0'; i <= '9'; ++i)
255: toHex[i] = i - '0';
256: for (i = 'a'; i <= 'f'; ++i)
257: toHex[i] = i + 10 - 'a';
258: for (i = 'A'; i <= 'F'; ++i)
259: toHex[i] = i + 10 - 'A';
260: }
261:
262: void
263: md_end(
264: void)
265: {
266: return;
267: }
268:
269: void
270: md_assemble (str)
271: char *str;
272: {
273: char *toP;
274: int rsd;
275:
276: know (str);
277: sparc_ip (str);
278:
279: #ifdef DEBUGINSN
280: print_insn(&the_insn);
281: #endif
282:
283: /* See if "set" operand is absolute and small; skip sethi if so. */
284: if (special_case_set && the_insn.exp.X_seg == SEG_ABSOLUTE)
285: {
286: if (the_insn.exp.X_add_number >= -(1 << 12)
287: && the_insn.exp.X_add_number < (1 << 12))
288: {
289: the_insn.opcode = 0x80102000 /* or %g0,imm,... */
290: | (the_insn.opcode & 0x3E000000) /* dest reg */
291: | (the_insn.exp.X_add_number & 0x1FFF); /* imm */
292: special_case_set = 0; /* No longer special */
293: the_insn.reloc = SPARC_RELOC_NONE; /* No longer relocated */
294: }
295: }
296:
297: toP = frag_more (4);
298: /* put out the opcode */
299: md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
300:
301: /* put out the symbol-dependent stuff */
302: if (the_insn.reloc != SPARC_RELOC_NONE)
303: {
304: fix_new(frag_now,
305: (toP - frag_now->fr_literal),
306: 4,
307: the_insn.exp.X_add_symbol,
308: the_insn.exp.X_subtract_symbol,
309: the_insn.exp.X_add_number,
310: the_insn.pcrel,
311: the_insn.pcrel_reloc, /* 1 for local labels due to scatter loading */
312: the_insn.reloc);
313: }
314:
315: if (special_case_set) {
316: special_case_set = 0;
317: assert (the_insn.reloc == SPARC_RELOC_HI22);
318: /* See if "set" operand has no low-order bits; skip OR if so. */
319: if ((the_insn.exp.X_seg == SEG_ABSOLUTE) &&
320: ((the_insn.exp.X_add_number & 0x3FF) == 0))
321: return;
322:
323: toP = frag_more (4);
324: rsd = (the_insn.opcode >> 25) & 0x1f;
325: the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14);
326: md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
327: the_insn.pcrel_reloc = 0;
328:
329: fix_new(frag_now,
330: (toP - frag_now->fr_literal),
331: 4,
332: the_insn.exp.X_add_symbol,
333: the_insn.exp.X_subtract_symbol,
334: the_insn.exp.X_add_number,
335: the_insn.pcrel,
336: the_insn.pcrel_reloc,
337: SPARC_RELOC_LO10);
338: return;
339: }
340: }
341:
342: static void
343: sparc_ip (str)
344: char *str;
345: {
346: char *error_message = "";
347: char *s;
348: const char *args;
349: char c;
350: struct sparc_opcode *insn;
351: char *argsStart;
352: unsigned long opcode;
353: unsigned int mask = 0;
354: int match = 0;
355: int comma = 0;
356: long immediate_max = 0;
357:
358: for (s = str; islower (*s) || (*s >= '0' && *s <= '3'); ++s)
359: ;
360: switch (*s)
361: {
362:
363: case '\0':
364: break;
365:
366: case ',':
367: comma = 1;
368:
369: /*FALLTHROUGH */
370:
371: case ' ':
372: *s++ = '\0';
373: break;
374:
375: default:
376: as_bad ("Unknown opcode: `%s'", str);
377: exit (1);
378: }
379: if ((insn = (struct sparc_opcode *) hash_find (op_hash, str)) == NULL)
380: {
381: as_bad ("Unknown opcode: `%s'", str);
382: return;
383: }
384: if (comma)
385: {
386: *--s = ',';
387: }
388: argsStart = s;
389: for (;;)
390: {
391: opcode = insn->match;
392: memset (&the_insn, '\0', sizeof (the_insn));
393: the_insn.reloc = SPARC_RELOC_NONE;
394: the_insn.pcrel_reloc = 1; /* default, reloc, for scatter loading */
395:
396: /*
397: * Build the opcode, checking as we go to make
398: * sure that the operands match
399: */
400: for (args = insn->args;; ++args)
401: {
402: switch (*args)
403: {
404: case 'M':
405: case 'm':
406: if (strncmp (s, "%asr", 4) == 0)
407: {
408: s += 4;
409:
410: if (isdigit (*s))
411: {
412: long num = 0;
413:
414: while (isdigit (*s))
415: {
416: num = num * 10 + *s - '0';
417: ++s;
418: }
419:
420: if (num < 16 || 31 < num)
421: {
422: error_message = ": asr number must be between 15 and 31";
423: goto error;
424: } /* out of range */
425:
426: opcode |= (*args == 'M' ? RS1 (num) : RD (num));
427: continue;
428: }
429: else
430: {
431: error_message = ": expecting %asrN";
432: goto error;
433: } /* if %asr followed by a number. */
434:
435: } /* if %asr */
436: break;
437:
438:
439: case '\0': /* end of args */
440: if (*s == '\0')
441: {
442: match = 1;
443: }
444: break;
445:
446: case '+':
447: if (*s == '+')
448: {
449: ++s;
450: continue;
451: }
452: if (*s == '-')
453: {
454: continue;
455: }
456: break;
457:
458: case '[': /* these must match exactly */
459: case ']':
460: case ',':
461: case ' ':
462: if (*s++ == *args)
463: continue;
464: break;
465:
466: case '#': /* must be at least one digit */
467: if (isdigit (*s++))
468: {
469: while (isdigit (*s))
470: {
471: ++s;
472: }
473: continue;
474: }
475: break;
476:
477: case 'C': /* coprocessor state register */
478: if (strncmp (s, "%csr", 4) == 0)
479: {
480: s += 4;
481: continue;
482: }
483: break;
484:
485: case 'b': /* next operand is a coprocessor register */
486: case 'c':
487: case 'D':
488: if (*s++ == '%' && *s++ == 'c' && isdigit (*s))
489: {
490: mask = *s++;
491: if (isdigit (*s))
492: {
493: mask = 10 * (mask - '0') + (*s++ - '0');
494: if (mask >= 32)
495: {
496: break;
497: }
498: }
499: else
500: {
501: mask -= '0';
502: }
503: switch (*args)
504: {
505:
506: case 'b':
507: opcode |= mask << 14;
508: continue;
509:
510: case 'c':
511: opcode |= mask;
512: continue;
513:
514: case 'D':
515: opcode |= mask << 25;
516: continue;
517: }
518: }
519: break;
520:
521: case 'r': /* next operand must be a register */
522: case 'u':
523: case '1':
524: case '2':
525: case 'd':
526: if (*s++ == '%')
527: {
528: switch (c = *s++)
529: {
530:
531: case 'f': /* frame pointer */
532: if (*s++ == 'p')
533: {
534: mask = 0x1e;
535: break;
536: }
537: error_message = ": register not fp";
538: goto error;
539:
540: case 'g': /* global register */
541: if (isoctal (c = *s++))
542: {
543: mask = c - '0';
544: break;
545: }
546: error_message = ": invalid global register";
547: goto error;
548:
549: case 'i': /* in register */
550: if (isoctal (c = *s++))
551: {
552: mask = c - '0' + 24;
553: break;
554: }
555: error_message = ": invalid in register";
556: goto error;
557:
558: case 'l': /* local register */
559: if (isoctal (c = *s++))
560: {
561: mask = (c - '0' + 16);
562: break;
563: }
564: error_message = ": invalid local register";
565: goto error;
566:
567: case 'o': /* out register */
568: if (isoctal (c = *s++))
569: {
570: mask = (c - '0' + 8);
571: break;
572: }
573: error_message = ": invalid out register";
574: goto error;
575:
576: case 's': /* stack pointer */
577: if (*s++ == 'p')
578: {
579: mask = 0xe;
580: break;
581: }
582: error_message = ": register is not sp";
583: goto error;
584:
585: case 'r': /* any register */
586: if (!isdigit (c = *s++))
587: {
588: error_message = ": invalid register";
589: goto error;
590: }
591: /* FALLTHROUGH */
592: case '0':
593: case '1':
594: case '2':
595: case '3':
596: case '4':
597: case '5':
598: case '6':
599: case '7':
600: case '8':
601: case '9':
602: if (isdigit (*s))
603: {
604: if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
605: {
606: error_message = ": register # out of range";
607: goto error;
608: }
609: }
610: else
611: {
612: c -= '0';
613: }
614: mask = c;
615: break;
616:
617: default:
618: error_message = ": invalid resgiter #";
619: goto error;
620: }
621: /*
622: * Got the register, now figure out where
623: * it goes in the opcode.
624: */
625: switch (*args)
626: {
627:
628: case '1':
629: opcode |= mask << 14;
630: continue;
631:
632: case '2':
633: opcode |= mask;
634: continue;
635:
636: case 'd':
637: opcode |= mask << 25;
638: continue;
639:
640: case 'r':
641: opcode |= (mask << 25) | (mask << 14);
642: continue;
643:
644: case 'u':
645: opcode |= (mask << 25) | mask;
646: continue;
647: }
648: }
649: break;
650:
651: case 'e': /* next operand is a floating point register */
652: case 'v':
653: case 'V':
654:
655: case 'f':
656: case 'B':
657: case 'R':
658:
659: case 'g':
660: case 'H':
661: case 'J':
662: {
663: char format;
664:
665: if (*s++ == '%'
666: && ((format = *s) == 'f')
667: && isdigit (*++s))
668: {
669: for (mask = 0; isdigit (*s); ++s)
670: {
671: mask = 10 * mask + (*s - '0');
672: } /* read the number */
673:
674: if ((*args == 'v'
675: || *args == 'B'
676: || *args == 'H')
677: && (mask & 1))
678: {
679: break;
680: } /* register must be even numbered */
681:
682: if ((*args == 'V'
683: || *args == 'R'
684: || *args == 'J')
685: && (mask & 3))
686: {
687: break;
688: } /* register must be multiple of 4 */
689:
690: if (mask >= 32)
691: {
692: error_message = ": There are only 32 f registers; [0-31]";
693: goto error;
694: } /* on error */
695: }
696: else
697: {
698: break;
699: } /* if not an 'f' register. */
700:
701: switch (*args)
702: {
703:
704: case 'v':
705: case 'V':
706: case 'e':
707: opcode |= RS1 (mask);
708: continue;
709:
710:
711: case 'f':
712: case 'B':
713: case 'R':
714: opcode |= RS2 (mask);
715: continue;
716:
717: case 'g':
718: case 'H':
719: case 'J':
720: opcode |= RD (mask);
721: continue;
722: } /* pack it in. */
723:
724: know (0);
725: break;
726: } /* float arg */
727:
728: case 'F':
729: if (strncmp (s, "%fsr", 4) == 0)
730: {
731: s += 4;
732: continue;
733: }
734: break;
735:
736: case 'h': /* high 22 bits */
737: the_insn.reloc = SPARC_RELOC_HI22;
738: goto immediate;
739:
740: case 'l': /* 22 bit PC relative immediate */
741: the_insn.reloc = SPARC_RELOC_WDISP22;
742: the_insn.pcrel = 1;
743: goto immediate;
744:
745: case 'L': /* 30 bit immediate for call insn */
746: the_insn.reloc = SPARC_RELOC_WDISP30;
747: the_insn.pcrel = 1;
748: goto immediate;
749:
750: case 'n': /* 22 bit immediate */
751: the_insn.reloc = SPARC_RELOC_22;
752: goto immediate;
753:
754: case 'i': /* 13 bit immediate */
755: /* What's the difference between base13 and 13?
756: 13-bit immediate and 13-bit immediate+register */
757: the_insn.reloc = SPARC_RELOC_13;
758: immediate_max = 0x1FFF;
759:
760: /*FALLTHROUGH */
761:
762: immediate:
763: if (*s == ' ')
764: s++;
765: if (*s == '%')
766: {
767: if ((c = s[1]) == 'h' && s[2] == 'i')
768: {
769: the_insn.reloc = SPARC_RELOC_HI22;
770: s += 3;
771: }
772: else if (c == 'l' && s[2] == 'o')
773: {
774: the_insn.reloc = SPARC_RELOC_LO10;
775: s += 3;
776: }
777: else
778: break;
779: }
780: /* Note that if the getExpression() fails, we will still
781: have created U entries in the symbol table for the
782: 'symbols' in the input string. Try not to create U
783: symbols for registers, etc. */
784: {
785: /* This stuff checks to see if the expression ends in
786: +%reg. If it does, it removes the register from
787: the expression, and re-sets 's' to point to the
788: right place. */
789:
790: char *s1;
791:
792: for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++);
793:
794: if (s1 != s && isdigit (s1[-1]))
795: {
796: if (s1[-2] == '%' && s1[-3] == '+')
797: {
798: s1 -= 3;
799: *s1 = '\0';
800: (void) getExpression (s);
801: *s1 = '+';
802: s = s1;
803: continue;
804: }
805: else if (strchr ("goli0123456789",
806: s1[-2]) && s1[-3] == '%' && s1[-4] == '+')
807: {
808: s1 -= 4;
809: *s1 = '\0';
810: (void) getExpression (s);
811: *s1 = '+';
812: s = s1;
813: continue;
814: }
815: }
816: }
817: (void) getExpression (s);
818: s = expr_end;
819: /* The Next linker has the ability to scatter blocks of sections between
820: * labels. This requires that branches to labels that survive to the
821: * link phase be relocatable. These labels are those that are not L*
822: */
823: if (the_insn.exp.X_add_symbol != NULL && !flagseen['L']
824: && the_insn.exp.X_add_symbol->sy_nlist.n_un.n_name[0] == 'L') {
825: /* local symbol which will be thrown away. Don't bother
826: * to reloc it.
827: */
828: the_insn.pcrel_reloc = 0;
829: }
830:
831: if ((the_insn.exp.X_seg == SEG_ABSOLUTE ||
832: the_insn.exp.X_seg == SEG_BIG)
833: && the_insn.exp.X_add_symbol == 0)
834: {
835:
836: /* Check for invalid constant values. Don't warn if
837: constant was inside %hi or %lo, since these
838: truncate the constant to fit. */
839: if (immediate_max != 0
840: && the_insn.reloc != SPARC_RELOC_LO10
841: && the_insn.reloc != SPARC_RELOC_HI22
842: && (the_insn.exp.X_add_number > immediate_max
843: || the_insn.exp.X_add_number < ~immediate_max))
844: as_bad ("constant value must be between %ld and %ld",
845: ~immediate_max, immediate_max);
846:
847: if ((the_insn.reloc == SPARC_RELOC_WDISP22 ||
848: the_insn.reloc == SPARC_RELOC_WDISP30) &&
849: the_insn.exp.X_add_number & 3)
850: as_bad ("displacement is not long aligned");
851:
852: /* plug absolutes directly into opcode */
853:
854: switch(the_insn.reloc) {
855: case SPARC_RELOC_13:
856: if (the_insn.exp.X_seg == SEG_BIG)
857: opcode |= (*(int *) generic_bignum) & 0x1fff;
858: else
859: opcode |= the_insn.exp.X_add_number & 0x1fff;
860: the_insn.reloc = SPARC_RELOC_NONE;
861: break;
862: case SPARC_RELOC_22:
863: if (the_insn.exp.X_seg == SEG_BIG)
864: opcode |= (*(int *) generic_bignum) & 0x3fffff;
865: else
866: opcode |= the_insn.exp.X_add_number & 0x3fffff;
867: the_insn.reloc = SPARC_RELOC_NONE;
868: break;
869: case SPARC_RELOC_HI22:
870: /* extract upper 22 bits from constant */
871: opcode |= (the_insn.exp.X_add_number >> 10) & 0x3fffff;
872: the_insn.reloc = SPARC_RELOC_NONE;
873: break;
874: case SPARC_RELOC_LO10:
875: opcode |= the_insn.exp.X_add_number & 0x3ff;
876: break;
877:
878: /* the PC relative displacements are plugged in
879: if the argument is absolute, but retain
880: relocatability */
881: case SPARC_RELOC_WDISP22:
882: opcode |= (the_insn.exp.X_add_number >> 2) & 0x3fffff;
883: break;
884: case SPARC_RELOC_WDISP30:
885: opcode |= (the_insn.exp.X_add_number >> 2) & 0x3fffffff;
886: break;
887: default:
888: printf("Unknown reloc entry\n");
889: }
890: }
891:
892: /* Reset to prevent extraneous range check. */
893: immediate_max = 0;
894:
895: continue;
896:
897: case 'a':
898: if (*s++ == 'a')
899: {
900: opcode |= ANNUL;
901: continue;
902: }
903: break;
904:
905: case 'A':
906: {
907: char *push = input_line_pointer;
908: expressionS e;
909:
910: input_line_pointer = s;
911:
912: expression (&e);
913:
914: if (e.X_seg == SEG_ABSOLUTE)
915: {
916: opcode |= e.X_add_number << 5;
917: s = input_line_pointer;
918: input_line_pointer = push;
919: continue;
920: } /* if absolute */
921:
922: break;
923: } /* alternate space */
924:
925: case 'p':
926: if (strncmp (s, "%psr", 4) == 0)
927: {
928: s += 4;
929: continue;
930: }
931: break;
932:
933: case 'q': /* floating point queue */
934: if (strncmp (s, "%fq", 3) == 0)
935: {
936: s += 3;
937: continue;
938: }
939: break;
940:
941: case 'Q': /* coprocessor queue */
942: if (strncmp (s, "%cq", 3) == 0)
943: {
944: s += 3;
945: continue;
946: }
947: break;
948:
949: case 'S':
950: if (strcmp (str, "set") == 0)
951: {
952: special_case_set = 1;
953: continue;
954: }
955: break;
956:
957:
958: case 't':
959: if (strncmp (s, "%tbr", 4) != 0)
960: break;
961: s += 4;
962: continue;
963:
964: case 'w':
965: if (strncmp (s, "%wim", 4) != 0)
966: break;
967: s += 4;
968: continue;
969:
970: case 'y':
971: if (strncmp (s, "%y", 2) != 0)
972: break;
973: s += 2;
974: continue;
975:
976: default:
977: as_fatal ("failed sanity check.");
978: } /* switch on arg code */
979: break;
980: } /* for each arg that we expect */
981: error:
982: if (match == 0)
983: {
984: /* Args don't match. */
985: if (((unsigned) (&insn[1] - sparc_opcodes)) < NUMOPCODES
986: && !strcmp (insn->name, insn[1].name))
987: {
988: ++insn;
989: s = argsStart;
990: continue;
991: }
992: else
993: {
994: as_bad ("Illegal operands%s", error_message);
995: return;
996: }
997: }
998: else
999: {
1000: if (insn->architecture > current_architecture)
1001: {
1002: if ((!architecture_requested || warn_on_bump)
1003: &&
1004: 1
1005: )
1006: {
1007: if (warn_on_bump)
1008: {
1009: as_warn ("architecture bumped from \"%s\" to \"%s\" on \"%s\"",
1010: architecture_pname[current_architecture],
1011: architecture_pname[insn->architecture],
1012: str);
1013: } /* if warning */
1014:
1015: current_architecture = insn->architecture;
1016: }
1017: else
1018: {
1019: as_bad ("architecture mismatch on \"%s\" (\"%s\"). current architecture is \"%s\"",
1020: str,
1021: architecture_pname[insn->architecture],
1022: architecture_pname[current_architecture]);
1023: return;
1024: } /* if bump ok else error */
1025: } /* if architecture higher */
1026: } /* if no match */
1027:
1028: break;
1029: } /* forever looking for a match */
1030:
1031: the_insn.opcode = opcode;
1032: }
1033:
1034: static int
1035: getExpression (str)
1036: char *str;
1037: {
1038: char *save_in;
1039: segT seg;
1040:
1041: save_in = input_line_pointer;
1042: input_line_pointer = str;
1043: seg = expression (&the_insn.exp);
1044:
1045: if (seg != SEG_ABSOLUTE
1046: && seg != SEG_SECT
1047: && seg != SEG_DIFFSECT
1048: && seg != SEG_UNKNOWN
1049: && seg != SEG_NONE
1050: && seg != SEG_BIG) {
1051: the_insn.error = "bad segment";
1052: expr_end = input_line_pointer;
1053: input_line_pointer = save_in;
1054: return 1;
1055: }
1056: expr_end = input_line_pointer;
1057: input_line_pointer = save_in;
1058: return 0;
1059: } /* getExpression() */
1060:
1061:
1062: /*
1063: This is identical to the md_atof in m68k.c. I think this is right,
1064: but I'm not sure.
1065:
1066: Turn a string in input_line_pointer into a floating point constant of type
1067: type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1068: emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1069: */
1070:
1071: /* Equal to MAX_PRECISION in atof-ieee.c */
1072: #define MAX_LITTLENUMS 6
1073:
1074: char *
1075: md_atof (type, litP, sizeP)
1076: char type;
1077: char *litP;
1078: int *sizeP;
1079: {
1080: int prec;
1081: LITTLENUM_TYPE words[MAX_LITTLENUMS];
1082: LITTLENUM_TYPE *wordP;
1083: char *t;
1084: char *atof_ieee ();
1085:
1086: switch (type)
1087: {
1088: case 'f':
1089: case 'F':
1090: case 's':
1091: case 'S':
1092: prec = 2;
1093: break;
1094:
1095: case 'd':
1096: case 'D':
1097: case 'r':
1098: case 'R':
1099: prec = 4;
1100: break;
1101:
1102: case 'x':
1103: case 'X':
1104: prec = 6;
1105: break;
1106:
1107: case 'p':
1108: case 'P':
1109: prec = 6;
1110: break;
1111:
1112: default:
1113: *sizeP = 0;
1114: return "Bad call to MD_ATOF()";
1115: }
1116: t = atof_ieee (input_line_pointer, type, words);
1117: if (t)
1118: input_line_pointer = t;
1119: *sizeP = prec * sizeof (LITTLENUM_TYPE);
1120: for (wordP = words; prec--;)
1121: {
1122: md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
1123: litP += sizeof (LITTLENUM_TYPE);
1124: }
1125: return "";
1126: }
1127:
1128: /*
1129: * Write out big-endian.
1130: */
1131: void
1132: md_number_to_chars (buf, val, n)
1133: char *buf;
1134: long val;
1135: int n;
1136: {
1137: // sigh, all architectures do this..,
1138: switch(n) {
1139:
1140: case 4:
1141: *buf++ = val >> 24;
1142: *buf++ = val >> 16;
1143: case 2:
1144: *buf++ = val >> 8;
1145: case 1:
1146: *buf = val;
1147: break;
1148:
1149: default:
1150: abort();
1151: }
1152: }
1153:
1154: /* Apply a fixS to the frags, now that we know the value it ought to
1155: hold. */
1156:
1157:
1158: void
1159: md_number_to_imm(unsigned char *buf, long val, int size, fixS *fixP, int nsect)
1160: {
1161:
1162: /* handle the most common case quickly */
1163: if ((fixP->fx_r_type == NO_RELOC) ||
1164: (fixP->fx_r_type == SPARC_RELOC_NONE) ||
1165: (fixP->fx_r_type == SPARC_RELOC_VANILLA)) {
1166: switch(size){
1167: case 4:
1168: *buf++ = val >> 24;
1169: *buf++ = val >> 16;
1170: case 2:
1171: *buf++ = val >> 8;
1172: case 1:
1173: *buf = val;
1174: break;
1175: default:
1176: abort();
1177: }
1178: return;
1179: }
1180:
1181: switch (fixP->fx_r_type) {
1182: case SPARC_RELOC_WDISP30:
1183: val = (val >> 2) + 1; /* adjust for word displacement */
1184: buf[0] |= (val >> 24) & 0x3f;
1185: buf[1] = (val >> 16);
1186: buf[2] = val >> 8;
1187: buf[3] = val;
1188: break;
1189: case SPARC_RELOC_WDISP22:
1190: val = (val >>= 2) + 1;
1191: buf[1] |= (val >> 16) & 0x3f;
1192: buf[2] = val >> 8;
1193: buf[3] = val;
1194: break;
1195: case SPARC_RELOC_HI22:
1196: buf[1] |= (val >> 26) & 0x3f;
1197: buf[2] = val >> 18;
1198: buf[3] = val >> 10;
1199: break;
1200: case SPARC_RELOC_LO10:
1201: buf[2] |= (val >> 8) & 0x03;
1202: buf[3] = val;
1203: break;
1204:
1205: /* special cases that need to be handled internally by the as */
1206: case SPARC_RELOC_22:
1207: if (!fixP->fx_addsy) {
1208: if (val & ~0x003fffff) {
1209: as_bad ("relocation overflow");
1210: } /* on overflow */
1211: buf[1] |= (val >> 16) & 0x3f;
1212: buf[2] = val >> 8;
1213: buf[3] = val & 0xff;
1214: } else
1215: as_bad ("Undefined symbolic 22-bit immediate reference: %s",
1216: fixP->fx_addsy->sy_name);
1217: break;
1218: case SPARC_RELOC_13:
1219: if (!fixP->fx_addsy) {
1220: if (((val > 0) && (val & ~(offsetT)0x00001fff))
1221: || ((val < 0) && (~(val - 1) & ~(offsetT)0x00001fff))) {
1222: as_bad ("relocation overflow");
1223: }
1224: buf[2] |= (val >> 8) & 0x1f;
1225: buf[3] = val;
1226: } else
1227: as_bad ("Undefined symbolic 13-bit immediate reference: %s",
1228: fixP->fx_addsy->sy_name);
1229: break;
1230: case SPARC_RELOC_NONE:
1231: default:
1232: as_bad ("bad or unhandled relocation type: 0x%02x", fixP->fx_r_type);
1233: break;
1234: }
1235: }
1236:
1237:
1238: /*
1239: * md_parse_option
1240: * Invocation line includes a switch not recognized by the base assembler.
1241: * See if it's a processor-specific option. These are:
1242: *
1243: * -bump
1244: * Warn on architecture bumps. See also -A.
1245: *
1246: * -Av6, -Av7, -Av8, -Asparclite
1247: * Select the architecture. Instructions or features not
1248: * supported by the selected architecture cause fatal errors.
1249: *
1250: * The default is to start at v6, and bump the architecture up
1251: * whenever an instruction is seen at a higher level.
1252: *
1253: * If -bump is specified, a warning is printing when bumping to
1254: * higher levels.
1255: *
1256: * If an architecture is specified, all instructions must match
1257: * that architecture. Any higher level instructions are flagged
1258: * as errors.
1259: *
1260: * if both an architecture and -bump are specified, the
1261: * architecture starts at the specified level, but bumps are
1262: * warnings.
1263: *
1264: */
1265:
1266: int
1267: md_parse_option (argP, cntP, vecP)
1268: char **argP;
1269: int *cntP;
1270: char ***vecP;
1271: {
1272: char *p;
1273: const char **arch;
1274:
1275: if (!strcmp (*argP, "bump"))
1276: {
1277: warn_on_bump = 1;
1278: }
1279: else if (**argP == 'A')
1280: {
1281: p = (*argP) + 1;
1282:
1283: for (arch = architecture_pname; *arch != NULL; ++arch)
1284: {
1285: if (strcmp (p, *arch) == 0)
1286: {
1287: break;
1288: } /* found a match */
1289: } /* walk the pname table */
1290:
1291: if (*arch == NULL)
1292: {
1293: as_bad ("unknown architecture: %s", p);
1294: }
1295: else
1296: {
1297: current_architecture = (enum sparc_architecture) (arch - architecture_pname);
1298: architecture_requested = 1;
1299: }
1300: }
1301: #ifndef NeXT
1302: #ifdef OBJ_ELF
1303: else if (**argP == 'V')
1304: {
1305: print_version_id ();
1306: }
1307: else if (**argP == 'Q')
1308: {
1309: /* Qy - do emit .comment
1310: Qn - do not emit .comment */
1311: }
1312: else if (**argP == 's')
1313: {
1314: /* use .stab instead of .stab.excl */
1315: }
1316: #endif
1317: else if (strcmp (*argP, "sparc") == 0)
1318: {
1319: /* Ignore -sparc, used by SunOS make default .s.o rule. */
1320: }
1321: #endif /* NeXT */
1322: else
1323: {
1324: /* Unknown option */
1325: (*argP)++;
1326: return 0;
1327: }
1328: **argP = '\0'; /* Done parsing this switch */
1329: return 1;
1330: } /* md_parse_option() */
1331:
1332:
1333: int
1334: md_estimate_size_before_relax(
1335: fragS *fragP,
1336: int segment_type)
1337: {
1338: as_fatal("internal error: Relaxation should never occur");
1339: return(0);
1340: }
1341:
1342: void
1343: md_convert_frag(
1344: fragS *fragP)
1345: {
1346: as_fatal("internal error: Relaxation should never occur");
1347: }
1348:
1349:
1350: #ifdef DEBUGINSN
1351:
1352: char *
1353: S_GET_NAME(sym)
1354: symbolS *sym;
1355: {
1356: return (sym->sy_nlist.n_un.n_name);
1357: }
1358:
1359: /* for debugging only */
1360: static void
1361: print_insn (insn)
1362: struct sparc_it *insn;
1363: {
1364: const char *const Reloc[] = {
1365: "VANILLA",
1366: "PAIR",
1367: "HI22",
1368: "LO10",
1369: "DISP22",
1370: "PCREL",
1371: "22",
1372: "13",
1373: "SECTDIFF",
1374: "HI22_SECTDIFF",
1375: "LO10_SECTDIFF",
1376: "NONE",
1377: "UNUSED"
1378:
1379: };
1380:
1381: if (insn->error)
1382: fprintf (stderr, "ERROR: %s\n", insn->error);
1383: fprintf (stderr, "opcode=0x%08x\n", (unsigned int)insn->opcode);
1384: fprintf (stderr, "reloc = %s\n", Reloc[insn->reloc]);
1385: fprintf (stderr, "X_add_number = 0x%x\n",
1386: insn->exp.X_add_number);
1387:
1388: if (insn->exp.X_add_symbol != NULL)
1389: fprintf(stderr, "Add symbol: %s\n", S_GET_NAME(insn->exp.X_add_symbol));
1390: if (insn->exp.X_subtract_symbol != NULL)
1391: fprintf(stderr, "Subtract symbol: %s\n", S_GET_NAME(insn->exp.X_subtract_symbol));
1392: }
1393: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.