1 /* tc-sparc.c -- Assemble for the SPARC
2 Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
27 /* careful, this file includes data *declarations* */
28 #include "opcode/sparc.h"
32 void md_number_to_chars();
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();
43 static enum sparc_architecture current_architecture
= v6
;
44 static int architecture_requested
= 0;
45 static int warn_on_bump
= 0;
47 const relax_typeS md_relax_table
[] = {
50 /* handle of the OPCODE hash table */
51 static struct hash_control
*op_hash
= NULL
;
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();
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 },
62 { "optim", s_ignore
, 0 },
63 { "proc", s_proc
, 0 },
64 { "reserve", s_reserve
, 0 },
66 { "skip", s_space
, 0 },
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 */
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 */
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
[] = "#";
89 /* Chars that can be used to separate mant from exp in floating point nums */
90 const char EXP_CHARS
[] = "eE";
92 /* Chars that mean this number is a floating point constant */
95 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
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.
102 static unsigned char octal
[256];
103 #define isoctal(c) octal[c]
104 static unsigned char toHex
[256];
108 unsigned long opcode
;
109 struct nlist
*nlistp
;
112 enum reloc_type reloc
;
113 } the_insn
, set_insn
;
117 static void print_insn(struct sparc_it
*insn
);
119 static int getExpression(char *str
);
120 #else /* not __STDC__ */
122 static void print_insn();
124 static int getExpression();
125 #endif /* not __STDC__ */
127 static char *expr_end
;
128 static int special_case
;
131 * Instructions that require wierd handling because they're longer than
134 #define SPECIAL_CASE_SET 1
135 #define SPECIAL_CASE_FDIV 2
138 * sort of like s_lcomm
141 static int max_alignment
= 15;
143 static void s_reserve() {
152 name
= input_line_pointer
;
153 c
= get_symbol_end();
154 p
= input_line_pointer
;
158 if (*input_line_pointer
!= ',') {
159 as_bad("Expected comma after name");
160 ignore_rest_of_line();
164 ++input_line_pointer
;
166 if ((size
= get_absolute_expression()) < 0) {
167 as_bad("BSS length (%d.) <0! Ignored.", size
);
168 ignore_rest_of_line();
173 symbolP
= symbol_find_or_make(name
);
176 if (strncmp(input_line_pointer
, ",\"bss\"", 6) != 0) {
177 as_bad("bad .reserve segment: `%s'", input_line_pointer
);
181 input_line_pointer
+= 6;
184 if (*input_line_pointer
== ',') {
185 ++input_line_pointer
;
188 if (*input_line_pointer
== '\n') {
189 as_bad("Missing alignment");
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) {
199 as_warn("Alignment negative. 0 assumed.");
202 #define SEG_BSS SEG_E2
203 record_alignment(SEG_E2
, align
);
205 record_alignment(SEG_BSS
, align
);
208 /* convert to a power of 2 alignment */
209 for (temp
= 0; (align
& 1) == 0; align
>>= 1, ++temp
) ;;
212 as_bad("Alignment not a power of 2");
213 ignore_rest_of_line();
215 } /* not a power of two */
220 align
= ~((~0) << align
); /* Convert to a mask */
221 local_bss_counter
= (local_bss_counter
+ align
) & (~align
);
222 } /* if has optional alignment */
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
;
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 */
238 demand_empty_rest_of_line();
242 static void s_common() {
247 register symbolS
* symbolP
;
249 name
= input_line_pointer
;
250 c
= get_symbol_end();
251 /* just after name is now '\0' */
252 p
= input_line_pointer
;
255 if (* input_line_pointer
!= ',') {
256 as_bad("Expected comma after symbol-name");
257 ignore_rest_of_line();
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();
267 symbolP
= symbol_find_or_make(name
);
269 if (S_IS_DEFINED(symbolP
)) {
270 as_bad("Ignoring attempt to re-define symbol");
271 ignore_rest_of_line();
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
);
280 S_SET_VALUE(symbolP
, temp
);
281 S_SET_EXTERNAL(symbolP
);
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')
291 as_bad("bad .common segment: `%s'", input_line_pointer
);
295 input_line_pointer
+= 6 + (input_line_pointer
[2] == 'd'); /* Skip either */
296 demand_empty_rest_of_line();
300 static void s_seg() {
302 if (strncmp(input_line_pointer
, "\"text\"", 6) == 0) {
303 input_line_pointer
+= 6;
307 if (strncmp(input_line_pointer
, "\"data\"", 6) == 0) {
308 input_line_pointer
+= 6;
312 if (strncmp(input_line_pointer
, "\"data1\"", 7) == 0) {
313 input_line_pointer
+= 7;
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 */
325 as_bad("Unknown segment type");
326 demand_empty_rest_of_line();
330 static void s_data1() {
331 subseg_new(SEG_DATA
, 1);
332 demand_empty_rest_of_line();
336 static void s_proc() {
337 extern char is_end_of_line
[];
339 while (!is_end_of_line
[*input_line_pointer
]) {
340 ++input_line_pointer
;
342 ++input_line_pointer
;
346 /* start-sanitize-v9 */
348 struct priv_reg_entry
{ char *name
; int regnum
; };
349 struct priv_reg_entry priv_reg_table
[] =
362 { "canrestore", 11 },
368 { "", -1 }, /* end marker */
371 static int cmp_reg_entry (p
, q
)
372 struct priv_reg_entry
*p
, *q
;
374 return strcmp (q
->name
, p
->name
);
377 /* end-sanitize-v9 */
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. */
382 register char *retval
= NULL
;
384 register unsigned int i
= 0;
386 op_hash
= hash_new();
388 as_fatal("Virtual memory exhausted");
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
);
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
);
406 } while (i
< NUMOPCODES
407 && !strcmp(sparc_opcodes
[i
].name
, name
));
411 as_fatal("Broken assembler. No assembly attempted.");
413 for (i
= '0'; i
< '8'; ++i
)
415 for (i
= '0'; i
<= '9'; ++i
)
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';
422 /* start-sanitize-v9 */
424 qsort (priv_reg_table
, sizeof (priv_reg_table
) / sizeof (priv_reg_table
[0]),
425 sizeof (priv_reg_table
[0]), cmp_reg_entry
);
427 /* end-sanitize-v9 */
434 void md_assemble(str
)
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 */
456 /* put out the opcode */
457 md_number_to_chars(toP
, the_insn
.opcode
, 4);
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 */
464 the_insn
.exp
.X_add_symbol
,
465 the_insn
.exp
.X_subtract_symbol
,
466 the_insn
.exp
.X_add_number
,
470 switch (special_case
) {
472 case SPECIAL_CASE_SET
:
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))
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 */
486 the_insn
.exp
.X_add_symbol
,
487 the_insn
.exp
.X_subtract_symbol
,
488 the_insn
.exp
.X_add_number
,
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. */
500 assert(the_insn
.reloc
== NO_RELOC
);
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);
511 as_fatal("failed sanity check.");
513 } /* md_assemble() */
515 static void sparc_ip(str
)
518 char *error_message
= "";
522 struct sparc_opcode
*insn
;
524 unsigned long opcode
;
525 unsigned int mask
= 0;
528 long immediate_max
= 0;
530 for (s
= str
; islower(*s
) || (*s
>= '0' && *s
<= '3'); ++s
)
547 as_bad("Unknown opcode: `%s'", str
);
550 if ((insn
= (struct sparc_opcode
*) hash_find(op_hash
, str
)) == NULL
) {
551 as_bad("Unknown opcode: `%s'", str
);
559 opcode
= insn
->match
;
560 memset(&the_insn
, '\0', sizeof(the_insn
));
561 the_insn
.reloc
= NO_RELOC
;
564 * Build the opcode, checking as we go to make
565 * sure that the operands match
567 for (args
= insn
->args
; ; ++args
) {
570 /* start-sanitize-v9 */
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. */
586 if (! (lo
= (s
[0] == 'S')))
588 if (! (hi
= (s
[1] == 'S')))
590 mask
|= (1 << ((hi
<<1) | lo
));
595 /* Parse a number, somehow. */
603 error_message
= "unrecognizable mmask";
606 opcode
|= SIMM13(mask
);
611 /* Parse a prefetch function. */
614 int prefetch_fcn
= 0;
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;
629 error_message
= "unrecognizable prefetch fucntion";
635 /* Parse a number, somehow. */
636 error_message
= "unrecognizable prefetch fucntion";
643 /* Parse a privileged register. */
646 struct priv_reg_entry
*p
= priv_reg_table
;
650 while (p
->name
[0] > s
[0])
652 while (p
->name
[0] == s
[0])
654 len
= strlen (p
->name
);
655 if (strncmp (p
->name
, s
, len
) == 0)
659 if (p
->name
[0] != s
[0])
661 error_message
= "unrecognizable privileged register";
665 opcode
|= (p
->regnum
<< 14);
667 opcode
|= (p
->regnum
<< 25);
673 error_message
= "unrecognizable privileged register";
677 /* end-sanitize-v9 */
681 if (strncmp(s
, "%asr", 4) == 0) {
687 while (isdigit(*s
)) {
688 num
= num
*10 + *s
-'0';
692 if (num
< 16 || 31 < num
) {
693 error_message
= ": asr number must be between 15 and 31";
697 opcode
|= (*args
== 'M' ? RS1(num
) : RD(num
));
700 error_message
= ": expecting %asrN";
702 } /* if %asr followed by a number. */
707 /* start-sanitize-v9 */
710 the_insn
.reloc
= RELOC_11
;
711 immediate_max
= 0x03FF;
715 the_insn
.reloc
= RELOC_10
;
716 immediate_max
= 0x01FF;
720 the_insn
.reloc
= RELOC_WDISP2_14
;
725 the_insn
.reloc
= RELOC_WDISP19
;
730 if (*s
== 'p' && s
[1] == 'n') {
737 if (*s
== 'p' && s
[1] == 't') {
747 if (strncmp(s
, "icc", 3) == 0) {
757 if (strncmp(s
, "xcc", 3) == 0) {
767 if (strncmp(s
, "fcc0", 4) == 0) {
777 if (strncmp(s
, "fcc1", 4) == 0) {
787 if (strncmp(s
, "fcc2", 4) == 0) {
797 if (strncmp(s
, "fcc3", 4) == 0) {
804 if (strncmp(s
, "%pc", 3) == 0) {
811 if (strncmp(s
, "%tick", 5) == 0) {
817 /* end-sanitize-v9 */
819 case '\0': /* end of args */
835 case '[': /* these must match exactly */
843 case '#': /* must be at least one digit */
845 while (isdigit(*s
)) {
852 case 'C': /* coprocessor state register */
853 if (strncmp(s
, "%csr", 4) == 0) {
859 case 'b': /* next operand is a coprocessor register */
862 if (*s
++ == '%' && *s
++ == 'c' && isdigit(*s
)) {
865 mask
= 10 * (mask
- '0') + (*s
++ - '0');
875 opcode
|= mask
<< 14;
883 opcode
|= mask
<< 25;
889 case 'r': /* next operand must be a register */
896 case 'f': /* frame pointer */
903 case 'g': /* global register */
904 if (isoctal(c
= *s
++)) {
910 case 'i': /* in register */
911 if (isoctal(c
= *s
++)) {
917 case 'l': /* local register */
918 if (isoctal(c
= *s
++)) {
919 mask
= (c
- '0' + 16) ;
924 case 'o': /* out register */
925 if (isoctal(c
= *s
++)) {
926 mask
= (c
- '0' + 8) ;
931 case 's': /* stack pointer */
938 case 'r': /* any register */
939 if (!isdigit(c
= *s
++)) {
943 case '0': case '1': case '2': case '3': case '4':
944 case '5': case '6': case '7': case '8': case '9':
946 if ((c
= 10 * (c
- '0') + (*s
++ - '0')) >= 32) {
959 * Got the register, now figure out where
960 * it goes in the opcode.
965 opcode
|= mask
<< 14;
973 opcode
|= mask
<< 25;
977 opcode
|= (mask
<< 25) | (mask
<< 14);
983 case 'e': /* next operand is a floating point register */
998 /* start-sanitize-v9 */
1000 && ((format
= *s
) == 'f'
1004 /* end-sanitize-v9 */
1005 && ((format
= *s
) == 'f')
1007 /* start-sanitize-v9 */
1009 /* end-sanitize-v9 */
1014 for (mask
= 0; isdigit(*s
); ++s
) {
1015 mask
= 10 * mask
+ (*s
- '0');
1016 } /* read the number */
1023 } /* register must be even numbered */
1030 } /* register must be multiple of 4 */
1032 if (format
== 'f') {
1034 error_message
= ": There are only 32 f registers; [0-31]";
1037 /* start-sanitize-v9 */
1040 if (format
== 'd') {
1042 error_message
= ": There are only 32 d registers [0, 2, ... 62].";
1044 } else if (mask
& 1) {
1045 error_message
= ": Only even numbered d registers exist.";
1049 } else if (format
== 'q') {
1052 ": There are only 16 q registers [0, 4, ... 60].";
1054 } else if (mask
& 3) {
1056 ": Only q registers evenly divisible by four exist.";
1061 } /* depending on format */
1065 } /* wrap high bit */
1067 /* end-sanitize-v9 */
1068 } /* if not an 'f' register. */
1076 opcode
|= RS1(mask
);
1083 opcode
|= RS2(mask
);
1098 if (strncmp(s
, "%fsr", 4) == 0) {
1104 case 'h': /* high 22 bits */
1105 the_insn
.reloc
= RELOC_HI22
;
1108 case 'l': /* 22 bit PC relative immediate */
1109 the_insn
.reloc
= RELOC_WDISP22
;
1113 case 'L': /* 30 bit immediate */
1114 the_insn
.reloc
= RELOC_WDISP30
;
1118 case 'n': /* 22 bit immediate */
1119 the_insn
.reloc
= RELOC_22
;
1122 case 'i': /* 13 bit immediate */
1123 the_insn
.reloc
= RELOC_BASE13
;
1124 immediate_max
= 0x0FFF;
1132 if ((c
= s
[1]) == 'h' && s
[2] == 'i') {
1133 the_insn
.reloc
= RELOC_HI22
;
1135 } else if (c
== 'l' && s
[2] == 'o') {
1136 the_insn
.reloc
= RELOC_LO10
;
1138 /* start-sanitize-v9 */
1143 the_insn
.reloc
= RELOC_HHI22
;
1149 the_insn
.reloc
= RELOC_HLO10
;
1152 /* end-sanitize-v9 */
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
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 */
1170 for (s1
= s
; *s1
&& *s1
!= ',' && *s1
!= ']'; s1
++) ;;
1172 if (s1
!= s
&& isdigit(s1
[-1])) {
1173 if(s1
[-2] == '%' && s1
[-3] == '+') {
1176 (void) getExpression(s
);
1180 } else if (strchr("goli0123456789", s1
[-2]) && s1
[-3] == '%' && s1
[-4] == '+') {
1183 (void) getExpression(s
);
1190 (void)getExpression(s
);
1193 /* Check for invalid constant values. Don't
1194 warn if constant was inside %hi or %lo,
1195 since these truncate the constant to
1197 if (immediate_max
!= 0
1198 && the_insn
.reloc
!= RELOC_LO10
1199 && the_insn
.reloc
!= RELOC_HI22
1200 /* start-sanitize-v9 */
1202 && the_insn
.reloc
!= RELOC_HLO10
1203 && the_insn
.reloc
!= RELOC_HHI22
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. */
1226 char *push
= input_line_pointer
;
1229 input_line_pointer
= s
;
1231 if (expression(&e
) == SEG_ABSOLUTE
) {
1232 opcode
|= e
.X_add_number
<< 5;
1233 s
= input_line_pointer
;
1234 input_line_pointer
= push
;
1239 } /* alternate space */
1242 if (strncmp(s
, "%psr", 4) == 0) {
1248 case 'q': /* floating point queue */
1249 if (strncmp(s
, "%fq", 3) == 0) {
1255 case 'Q': /* coprocessor queue */
1256 if (strncmp(s
, "%cq", 3) == 0) {
1263 if (strcmp(str
, "set") == 0) {
1264 special_case
= SPECIAL_CASE_SET
;
1266 } else if (strncmp(str
, "fdiv", 4) == 0) {
1267 special_case
= SPECIAL_CASE_FDIV
;
1272 /* start-sanitize-v9 */
1275 if (strncmp (s
, "%asi", 4) != 0)
1281 if (strncmp (s
, "%fprs", 5) != 0)
1287 if (strncmp (s
, "%ccr", 4) != 0)
1292 /* end-sanitize-v9 */
1295 if (strncmp(s
, "%tbr", 4) != 0)
1301 if (strncmp(s
, "%wim", 4) != 0)
1307 if (strncmp(s
, "%y", 2) != 0)
1313 as_fatal("failed sanity check.");
1314 } /* switch on arg code */
1316 } /* for each arg that we expect */
1319 /* Args don't match. */
1320 if (((unsigned) (&insn
[1] - sparc_opcodes
)) < NUMOPCODES
1321 && !strcmp(insn
->name
, insn
[1].name
)) {
1326 as_bad("Illegal operands%s", error_message
);
1330 if (insn
->architecture
> current_architecture
) {
1331 if ((!architecture_requested
|| warn_on_bump
)
1333 /* start-sanitize-v9 */
1335 ! ARCHITECTURES_CONFLICT_P (current_architecture
,
1338 /* end-sanitize-v9 */
1340 /* start-sanitize-v9 */
1342 /* end-sanitize-v9 */
1345 as_warn("architecture bumped from \"%s\" to \"%s\" on \"%s\"",
1346 architecture_pname
[current_architecture
],
1347 architecture_pname
[insn
->architecture
],
1351 current_architecture
= insn
->architecture
;
1353 as_bad("architecture mismatch on \"%s\" (\"%s\"). current architecture is \"%s\"",
1355 architecture_pname
[insn
->architecture
],
1356 architecture_pname
[current_architecture
]);
1358 } /* if bump ok else error */
1359 } /* if architecture higher */
1363 } /* forever looking for a match */
1365 the_insn
.opcode
= opcode
;
1369 static int getExpression(str
)
1375 save_in
= input_line_pointer
;
1376 input_line_pointer
= str
;
1377 switch (seg
= expression(&the_insn
.exp
)) {
1384 case SEG_DIFFERENCE
:
1390 the_insn
.error
= "bad segment";
1391 expr_end
= input_line_pointer
;
1392 input_line_pointer
=save_in
;
1395 expr_end
= input_line_pointer
;
1396 input_line_pointer
= save_in
;
1398 } /* getExpression() */
1402 This is identical to the md_atof in m68k.c. I think this is right,
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.
1410 /* Equal to MAX_PRECISION in atof-ieee.c */
1411 #define MAX_LITTLENUMS 6
1413 char *md_atof(type
,litP
,sizeP
)
1419 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1420 LITTLENUM_TYPE
*wordP
;
1452 return "Bad call to MD_ATOF()";
1454 t
=atof_ieee(input_line_pointer
,type
,words
);
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
);
1462 return ""; /* Someone should teach Dean about null pointers */
1466 * Write out big-endian.
1468 void md_number_to_chars(buf
,val
,n
)
1486 as_fatal("failed sanity check.");
1489 } /* md_number_to_chars() */
1491 /* Apply a fixS to the frags, now that we know the value it ought to
1494 void md_apply_fix(fixP
, val
)
1498 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
1500 assert(fixP
->fx_size
== 4);
1501 assert(fixP
->fx_r_type
< NO_RELOC
);
1503 fixP
->fx_addnumber
= val
; /* Remember value for emit_reloc */
1506 * This is a hack. There should be a better way to
1509 if (fixP
->fx_r_type
== RELOC_WDISP30
&& fixP
->fx_addsy
) {
1510 val
+= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1513 switch (fixP
->fx_r_type
) {
1516 buf
[0] = 0; /* val >> 24; */
1517 buf
[1] = 0; /* val >> 16; */
1518 buf
[2] = 0; /* val >> 8; */
1519 buf
[3] = 0; /* val; */
1523 case RELOC_8
: /* These don't seem to ever be needed. */
1530 val
= (val
>>= 2) + 1;
1531 buf
[0] |= (val
>> 24) & 0x3f;
1532 buf
[1]= (val
>> 16);
1537 /* start-sanitize-v9 */
1540 if (((val
> 0) && (val
& ~0x7ff))
1541 || ((val
< 0) && (~(val
- 1) & ~0x7ff))) {
1542 as_bad("relocation overflow.");
1545 buf
[2] |= (val
>> 8) & 0x7;
1546 buf
[3] = val
& 0xff;
1550 if (((val
> 0) && (val
& ~0x3ff))
1551 || ((val
< 0) && (~(val
- 1) & ~0x3ff))) {
1552 as_bad("relocation overflow.");
1555 buf
[2] |= (val
>> 8) & 0x3;
1556 buf
[3] = val
& 0xff;
1559 case RELOC_WDISP2_14
:
1560 if (((val
> 0) && (val
& ~0x3fffc))
1561 || ((val
< 0) && (~(val
- 1) & ~0x3fffc))) {
1562 as_bad("relocation overflow.");
1565 val
= (val
>>= 2) + 1;
1566 buf
[1] |= ((val
>> 14) & 0x3) << 3;
1567 buf
[2] |= (val
>> 8) & 0x3f ;
1568 buf
[3] = val
& 0xff;
1572 if (((val
> 0) && (val
& ~0x1ffffc))
1573 || ((val
< 0) && (~(val
- 1) & ~0x1ffffc))) {
1574 as_bad("relocation overflow.");
1577 val
= (val
>>= 2) + 1;
1578 buf
[1] |= (val
>> 16) & 0x7;
1579 buf
[2] = (val
>> 8) & 0xff;
1580 buf
[3] = val
& 0xff;
1585 /* intentional fallthrough */
1587 /* end-sanitize-v9 */
1590 if(!fixP
->fx_addsy
) {
1591 buf
[1] |= (val
>> 26) & 0x3f;
1601 if (val
& ~0x003fffff) {
1602 as_bad("relocation overflow");
1604 buf
[1] |= (val
>> 16) & 0x3f;
1606 buf
[3] = val
& 0xff;
1610 if (val
& ~0x00001fff) {
1611 as_bad("relocation overflow");
1613 buf
[2] |= (val
>> 8) & 0x1f;
1614 buf
[3] = val
& 0xff;
1617 /* start-sanitize-v9 */
1621 /* intentional fallthrough */
1623 /* end-sanitize-v9 */
1626 if(!fixP
->fx_addsy
) {
1627 buf
[2] |= (val
>> 8) & 0x03;
1633 case RELOC_SFA_BASE
:
1634 case RELOC_SFA_OFF13
:
1638 if (((val
> 0) && (val
& ~0x00001fff))
1639 || ((val
< 0) && (~(val
- 1) & ~0x00001fff))) {
1640 as_bad("relocation overflow");
1642 buf
[2] |= (val
>> 8) & 0x1f;
1647 val
= (val
>>= 2) + 1;
1650 buf
[1] |= (val
>> 16) & 0x3f;
1659 case RELOC_SEGOFF16
:
1660 case RELOC_GLOB_DAT
:
1661 case RELOC_JMP_SLOT
:
1662 case RELOC_RELATIVE
:
1667 as_bad("bad relocation type: 0x%02x", fixP
->fx_r_type
);
1670 } /* md_apply_fix() */
1672 /* should never be called for sparc */
1673 void md_create_short_jump(ptr
, from_addr
, to_addr
, frag
, to_symbol
)
1680 as_fatal("sparc_create_short_jmp\n");
1681 } /* md_create_short_jump() */
1683 /* Translate internal representation of relocation info to target format.
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 */
1691 tc_aout_fix_to_chars(where
, fixP
, segment_address_in_file
)
1694 relax_addressT segment_address_in_file
;
1701 know(fixP
->fx_addsy
);
1703 if (!S_IS_DEFINED(fixP
->fx_addsy
)) {
1705 r_index
= fixP
->fx_addsy
->sy_number
;
1708 r_index
= S_GET_TYPE(fixP
->fx_addsy
);
1712 md_number_to_chars(where
,
1713 r_address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
- segment_address_in_file
,
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);
1723 if (fixP
->fx_addsy
->sy_frag
) {
1724 r_addend
= fixP
->fx_addsy
->sy_frag
->fr_address
;
1727 if (fixP
->fx_pcrel
) {
1728 r_addend
+= fixP
->fx_offset
- r_address
;
1730 r_addend
= fixP
->fx_addnumber
;
1733 md_number_to_chars(&where
[8], r_addend
, 4);
1736 } /* tc_aout_fix_to_chars() */
1738 /* should never be called for sparc */
1739 void md_convert_frag(headers
, fragP
)
1740 object_headers
*headers
;
1741 register fragS
*fragP
;
1743 as_fatal("sparc_convert_frag\n");
1744 } /* md_convert_frag() */
1746 /* should never be called for sparc */
1747 void md_create_long_jump(ptr
, from_addr
, to_addr
, frag
, to_symbol
)
1749 long from_addr
, to_addr
;
1753 as_fatal("sparc_create_long_jump\n");
1754 } /* md_create_long_jump() */
1756 /* should never be called for sparc */
1757 int md_estimate_size_before_relax(fragP
, segtype
)
1761 as_fatal("sparc_estimate_size_before_relax\n");
1763 } /* md_estimate_size_before_relax() */
1766 /* for debugging only */
1767 static void print_insn(insn
)
1768 struct sparc_it
*insn
;
1799 fprintf(stderr
, "ERROR: %s\n");
1801 fprintf(stderr
, "opcode=0x%08x\n", insn
->opcode
);
1802 fprintf(stderr
, "reloc = %s\n", Reloc
[insn
->reloc
]);
1803 fprintf(stderr
, "exp = {
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
)
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
)
1817 fprintf(stderr
, "\t\tX_add_number = %d\n",
1818 insn
->exp
.X_add_number
);
1819 fprintf(stderr
, "}\n");
1821 } /* print_insn() */
1824 /* Set the hook... */
1826 /* void emit_sparc_reloc();
1827 void (*md_emit_relocations)() = emit_sparc_reloc; */
1832 * Sparc/AM29K relocations are completely different, so it needs
1833 * this machine dependent routine to emit them.
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
;
1840 struct reloc_info_generic ri
;
1841 register symbolS
*symbolP
;
1842 extern char *next_object_file_charP
;
1843 /* long add_number; */
1845 memset((char *) &ri
, '\0', sizeof(ri
));
1846 for (; fixP
; fixP
= fixP
->fx_next
) {
1848 if (fixP
->fx_r_type
>= NO_RELOC
) {
1849 as_fatal("fixP->fx_r_type = %d\n", fixP
->fx_r_type
);
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
) {
1857 ri
.r_index
= symbolP
->sy_number
;
1860 ri
.r_index
= S_GET_TYPE(symbolP
);
1862 if (symbolP
&& symbolP
->sy_frag
) {
1863 ri
.r_addend
= symbolP
->sy_frag
->fr_address
;
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
;
1870 ri
.r_addend
= fixP
->fx_addnumber
;
1873 md_ri_to_chars(next_object_file_charP
, &ri
);
1874 next_object_file_charP
+= md_reloc_size
;
1878 } /* emit_sparc_reloc() */
1879 #endif /* aout or bout */
1880 #endif /* comment */
1884 * Invocation line includes a switch not recognized by the base assembler.
1885 * See if it's a processor-specific option. These are:
1888 * Warn on architecture bumps. See also -A.
1890 * -Av6, -Av7, -Av8, -Asparclite
1891 * Select the architecture. Instructions or features not
1892 * supported by the selected architecture cause fatal errors.
1894 * The default is to start at v6, and bump the architecture up
1895 * whenever an instruction is seen at a higher level.
1897 * If -bump is specified, a warning is printing when bumping to
1900 * If an architecture is specified, all instructions must match
1901 * that architecture. Any higher level instructions are flagged
1904 * if both an architecture and -bump are specified, the
1905 * architecture starts at the specified level, but bumps are
1909 * Bumping between incompatible architectures is always an
1910 * error. For example, from sparclite to v9.
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
)
1924 if (!strcmp(*argP
,"bump")){
1927 } else if (**argP
== 'A'){
1930 for (arch
= architecture_pname
; *arch
!= NULL
; ++arch
){
1931 if (strcmp(p
, *arch
) == 0){
1933 } /* found a match */
1934 } /* walk the pname table */
1937 as_bad("unknown architecture: %s", p
);
1939 current_architecture
= (enum sparc_architecture
) (arch
- architecture_pname
);
1940 architecture_requested
= 1;
1943 /* Unknown option */
1947 **argP
= '\0'; /* Done parsing this switch */
1949 } /* md_parse_option() */
1951 /* We have no need to default values of symbols. */
1954 symbolS
*md_undefined_symbol(name
)
1958 } /* md_undefined_symbol() */
1960 /* Parse an operand that is machine-specific.
1961 We just return without modifying the expression if we have nothing
1965 void md_operand(expressionP
)
1966 expressionS
*expressionP
;
1968 } /* md_operand() */
1970 /* Round up a section size to the appropriate boundary. */
1971 long md_section_align (segment
, size
)
1975 return (size
+ 7) & ~7; /* Round all sects to multiple of 8 */
1976 } /* md_section_align() */
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
)
1985 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1986 } /* md_pcrel_from() */
1988 void tc_aout_pre_write_hook(headers
)
1989 object_headers
*headers
;
1991 H_SET_VERSION(headers
, 1);
1993 } /* tc_aout_pre_write_hook() */
2002 /* end of tc-sparc.c */