2 /* tc-sparc.c -- Assemble for the SPARC
3 Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
26 /* careful, this file includes data *declarations* */
27 #include "opcode/sparc.h"
31 void md_number_to_chars();
34 void md_convert_frag();
35 void md_create_short_jump();
36 void md_create_long_jump();
37 int md_estimate_size_before_relax();
38 void md_ri_to_chars();
39 symbolS
*md_undefined_symbol();
40 static void sparc_ip();
42 static enum sparc_architecture current_architecture
= v6
;
43 static int architecture_requested
= 0;
44 static int warn_on_bump
= 0;
46 const relax_typeS md_relax_table
[] = {
49 /* handle of the OPCODE hash table */
50 static struct hash_control
*op_hash
= NULL
;
52 static void s_seg(), s_proc(), s_data1(), s_reserve(), s_common();
53 extern void s_globl(), s_long(), s_short(), s_space(), cons();
54 extern void s_align_bytes(), s_ignore();
56 const pseudo_typeS md_pseudo_table
[] = {
57 { "align", s_align_bytes
, 0 }, /* Defaulting is invalid (0) */
58 { "common", s_common
, 0 },
59 { "global", s_globl
, 0 },
61 { "optim", s_ignore
, 0 },
62 { "proc", s_proc
, 0 },
63 { "reserve", s_reserve
, 0 },
65 { "skip", s_space
, 0 },
70 const int md_short_jump_size
= 4;
71 const int md_long_jump_size
= 4;
72 const int md_reloc_size
= 12; /* Size of relocation record */
74 /* This array holds the chars that always start a comment. If the
75 pre-processor is disabled, these aren't very useful */
76 const char comment_chars
[] = "!"; /* JF removed '|' from comment_chars */
78 /* This array holds the chars that only start a comment at the beginning of
79 a line. If the line seems to have the form '# 123 filename'
80 .line and .file directives will appear in the pre-processed output */
81 /* Note that input_file.c hand checks for '#' at the beginning of the
82 first line of the input file. This is because the compiler outputs
83 #NO_APP at the beginning of its output. */
84 /* Also note that comments started like this one will always
85 work if '/' isn't otherwise defined. */
86 const char line_comment_chars
[] = "#";
88 /* Chars that can be used to separate mant from exp in floating point nums */
89 const char EXP_CHARS
[] = "eE";
91 /* Chars that mean this number is a floating point constant */
94 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
96 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
97 changed in read.c . Ideally it shouldn't have to know about it at all,
98 but nothing is ideal around here.
101 static unsigned char octal
[256];
102 #define isoctal(c) octal[c]
103 static unsigned char toHex
[256];
107 unsigned long opcode
;
108 struct nlist
*nlistp
;
111 enum reloc_type reloc
;
112 } the_insn
, set_insn
;
116 static void print_insn(struct sparc_it
*insn
);
118 static int getExpression(char *str
);
121 static void print_insn();
123 static int getExpression();
125 static char *expr_end
;
126 static int special_case
;
129 * Instructions that require wierd handling because they're longer than
132 #define SPECIAL_CASE_SET 1
133 #define SPECIAL_CASE_FDIV 2
136 * sort of like s_lcomm
139 static int max_alignment
= 15;
141 static void s_reserve() {
150 name
= input_line_pointer
;
151 c
= get_symbol_end();
152 p
= input_line_pointer
;
156 if (*input_line_pointer
!= ',') {
157 as_bad("Expected comma after name");
158 ignore_rest_of_line();
162 ++input_line_pointer
;
164 if ((size
= get_absolute_expression()) < 0) {
165 as_bad("BSS length (%d.) <0! Ignored.", size
);
166 ignore_rest_of_line();
171 symbolP
= symbol_find_or_make(name
);
174 if (strncmp(input_line_pointer
, ",\"bss\"", 6) != 0) {
175 as_bad("bad .reserve segment: `%s'", input_line_pointer
);
179 input_line_pointer
+= 6;
182 if (*input_line_pointer
== ',') {
183 ++input_line_pointer
;
186 if (*input_line_pointer
== '\n') {
187 as_bad("Missing alignment");
191 align
= get_absolute_expression();
192 if (align
> max_alignment
){
193 align
= max_alignment
;
194 as_warn("Alignment too large: %d. assumed.", align
);
195 } else if (align
< 0) {
197 as_warn("Alignment negative. 0 assumed.");
200 #define SEG_BSS SEG_E2
201 record_alignment(SEG_E2
, align
);
203 record_alignment(SEG_BSS
, align
);
206 /* convert to a power of 2 alignment */
207 for (temp
= 0; (align
& 1) == 0; align
>>= 1, ++temp
) ;;
210 as_bad("Alignment not a power of 2");
211 ignore_rest_of_line();
213 } /* not a power of two */
218 align
= ~((~0) << align
); /* Convert to a mask */
219 local_bss_counter
= (local_bss_counter
+ align
) & (~align
);
220 } /* if has optional alignment */
222 if (S_GET_OTHER(symbolP
) == 0
223 && S_GET_DESC(symbolP
) == 0
224 && ((S_GET_SEGMENT(symbolP
) == SEG_BSS
225 && S_GET_VALUE(symbolP
) == local_bss_counter
)
226 || !S_IS_DEFINED(symbolP
))) {
227 S_SET_VALUE(symbolP
, local_bss_counter
);
228 S_SET_SEGMENT(symbolP
, SEG_BSS
);
229 symbolP
->sy_frag
= &bss_address_frag
;
230 local_bss_counter
+= size
;
232 as_warn("Ignoring attempt to re-define symbol from %d. to %d.",
233 S_GET_VALUE(symbolP
), local_bss_counter
);
234 } /* if not redefining */
236 demand_empty_rest_of_line();
240 static void s_common() {
245 register symbolS
* symbolP
;
247 name
= input_line_pointer
;
248 c
= get_symbol_end();
249 /* just after name is now '\0' */
250 p
= input_line_pointer
;
253 if (* input_line_pointer
!= ',') {
254 as_bad("Expected comma after symbol-name");
255 ignore_rest_of_line();
258 input_line_pointer
++; /* skip ',' */
259 if ((temp
= get_absolute_expression ()) < 0) {
260 as_bad(".COMMon length (%d.) <0! Ignored.", temp
);
261 ignore_rest_of_line();
265 symbolP
= symbol_find_or_make(name
);
267 if (S_IS_DEFINED(symbolP
)) {
268 as_bad("Ignoring attempt to re-define symbol");
269 ignore_rest_of_line();
272 if (S_GET_VALUE(symbolP
) != 0) {
273 if (S_GET_VALUE(symbolP
) != temp
) {
274 as_warn("Length of .comm \"%s\" is already %d. Not changed to %d.",
275 S_GET_NAME(symbolP
), S_GET_VALUE(symbolP
), temp
);
278 S_SET_VALUE(symbolP
, temp
);
279 S_SET_EXTERNAL(symbolP
);
281 know(symbolP
->sy_frag
== &zero_address_frag
);
282 if (strncmp(input_line_pointer
, ",\"bss\"", 6) != 0
283 && strncmp(input_line_pointer
, ",\"data\"", 7) != 0) {
284 p
=input_line_pointer
;
285 while(*p
&& *p
!='\n')
289 as_bad("bad .common segment: `%s'", input_line_pointer
);
293 input_line_pointer
+= 6 + (input_line_pointer
[2] == 'd'); /* Skip either */
294 demand_empty_rest_of_line();
298 static void s_seg() {
300 if (strncmp(input_line_pointer
, "\"text\"", 6) == 0) {
301 input_line_pointer
+= 6;
305 if (strncmp(input_line_pointer
, "\"data\"", 6) == 0) {
306 input_line_pointer
+= 6;
310 if (strncmp(input_line_pointer
, "\"data1\"", 7) == 0) {
311 input_line_pointer
+= 7;
315 if (strncmp(input_line_pointer
, "\"bss\"", 5) == 0) {
316 input_line_pointer
+= 5;
317 /* We only support 2 segments -- text and data -- for now, so
318 things in the "bss segment" will have to go into data for now.
319 You can still allocate SEG_BSS stuff with .lcomm or .reserve. */
320 subseg_new(SEG_DATA
, 255); /* FIXME-SOMEDAY */
323 as_bad("Unknown segment type");
324 demand_empty_rest_of_line();
328 static void s_data1() {
329 subseg_new(SEG_DATA
, 1);
330 demand_empty_rest_of_line();
334 static void s_proc() {
335 extern char is_end_of_line
[];
337 while (!is_end_of_line
[*input_line_pointer
]) {
338 ++input_line_pointer
;
340 ++input_line_pointer
;
344 /* This function is called once, at assembler startup time. It should
345 set up all the tables, etc. that the MD part of the assembler will need. */
347 register char *retval
= NULL
;
349 register unsigned int i
= 0;
351 op_hash
= hash_new();
353 as_fatal("Virtual memory exhausted");
355 while (i
< NUMOPCODES
) {
356 const char *name
= sparc_opcodes
[i
].name
;
357 retval
= hash_insert(op_hash
, name
, &sparc_opcodes
[i
]);
358 if(retval
!= NULL
&& *retval
!= '\0') {
359 fprintf (stderr
, "internal error: can't hash `%s': %s\n",
360 sparc_opcodes
[i
].name
, retval
);
365 if (sparc_opcodes
[i
].match
& sparc_opcodes
[i
].lose
) {
366 fprintf (stderr
, "internal error: losing opcode: `%s' \"%s\"\n",
367 sparc_opcodes
[i
].name
, sparc_opcodes
[i
].args
);
371 } while (i
< NUMOPCODES
372 && !strcmp(sparc_opcodes
[i
].name
, name
));
376 as_fatal("Broken assembler. No assembly attempted.");
378 for (i
= '0'; i
< '8'; ++i
)
380 for (i
= '0'; i
<= '9'; ++i
)
382 for (i
= 'a'; i
<= 'f'; ++i
)
383 toHex
[i
] = i
+ 10 - 'a';
384 for (i
= 'A'; i
<= 'F'; ++i
)
385 toHex
[i
] = i
+ 10 - 'A';
392 void md_assemble(str
)
401 /* See if "set" operand is absolute and small; skip sethi if so. */
402 if (special_case
== SPECIAL_CASE_SET
&& the_insn
.exp
.X_seg
== SEG_ABSOLUTE
) {
403 if (the_insn
.exp
.X_add_number
>= -(1<<12)
404 && the_insn
.exp
.X_add_number
< (1<<12)) {
405 the_insn
.opcode
= 0x80102000 /* or %g0,imm,... */
406 | (the_insn
.opcode
& 0x3E000000) /* dest reg */
407 | (the_insn
.exp
.X_add_number
& 0x1FFF); /* imm */
408 special_case
= 0; /* No longer special */
409 the_insn
.reloc
= NO_RELOC
; /* No longer relocated */
414 /* put out the opcode */
415 md_number_to_chars(toP
, the_insn
.opcode
, 4);
417 /* put out the symbol-dependent stuff */
418 if (the_insn
.reloc
!= NO_RELOC
) {
419 fix_new(frag_now
, /* which frag */
420 (toP
- frag_now
->fr_literal
), /* where */
422 the_insn
.exp
.X_add_symbol
,
423 the_insn
.exp
.X_subtract_symbol
,
424 the_insn
.exp
.X_add_number
,
428 switch (special_case
) {
430 case SPECIAL_CASE_SET
:
432 assert(the_insn
.reloc
== RELOC_HI22
);
433 /* See if "set" operand has no low-order bits; skip OR if so. */
434 if (the_insn
.exp
.X_seg
== SEG_ABSOLUTE
435 && ((the_insn
.exp
.X_add_number
& 0x3FF) == 0))
438 rsd
= (the_insn
.opcode
>> 25) & 0x1f;
439 the_insn
.opcode
= 0x80102000 | (rsd
<< 25) | (rsd
<< 14);
440 md_number_to_chars(toP
, the_insn
.opcode
, 4);
441 fix_new(frag_now
, /* which frag */
442 (toP
- frag_now
->fr_literal
), /* where */
444 the_insn
.exp
.X_add_symbol
,
445 the_insn
.exp
.X_subtract_symbol
,
446 the_insn
.exp
.X_add_number
,
451 case SPECIAL_CASE_FDIV
:
452 /* According to information leaked from Sun, the "fdiv" instructions
453 on early SPARC machines would produce incorrect results sometimes.
454 The workaround is to add an fmovs of the destination register to
455 itself just after the instruction. This was true on machines
456 with Weitek 1165 float chips, such as the Sun-4/260 and /280. */
458 assert(the_insn
.reloc
== NO_RELOC
);
460 rsd
= (the_insn
.opcode
>> 25) & 0x1f;
461 the_insn
.opcode
= 0x81A00020 | (rsd
<< 25) | rsd
; /* fmovs dest,dest */
462 md_number_to_chars(toP
, the_insn
.opcode
, 4);
469 as_fatal("failed sanity check.");
471 } /* md_assemble() */
473 static void sparc_ip(str
)
476 char *error_message
= "";
480 struct sparc_opcode
*insn
;
482 unsigned long opcode
;
483 unsigned int mask
= 0;
487 for (s
= str
; islower(*s
) || (*s
>= '0' && *s
<= '3'); ++s
)
504 as_bad("Unknown opcode: `%s'", str
);
507 if ((insn
= (struct sparc_opcode
*) hash_find(op_hash
, str
)) == NULL
) {
508 as_bad("Unknown opcode: `%s'", str
);
516 opcode
= insn
->match
;
517 bzero(&the_insn
, sizeof(the_insn
));
518 the_insn
.reloc
= NO_RELOC
;
521 * Build the opcode, checking as we go to make
522 * sure that the operands match
524 for (args
= insn
->args
; ; ++args
) {
529 if (strncmp(s
, "%asr", 4) == 0) {
535 while (isdigit(*s
)) {
536 num
= num
*10 + *s
-'0';
540 if (num
< 16 || 31 < num
) {
541 error_message
= ": asr number must be between 15 and 31";
545 opcode
|= (*args
== 'M' ? RS1(num
) : RD(num
));
548 error_message
= ": expecting %asrN";
550 } /* if %asr followed by a number. */
555 /* start-sanitize-v9 */
558 the_insn
.reloc
= RELOC_11
;
562 the_insn
.reloc
= RELOC_WDISP2_14
;
567 the_insn
.reloc
= RELOC_WDISP19
;
572 if (*s
== 'p' && s
[1] == 'n') {
579 if (*s
== 'p' && s
[1] == 't') {
586 if (strncmp(s
, "%amr", 4) == 0) {
596 if (strncmp(s
, "icc", 3) == 0) {
606 if (strncmp(s
, "xcc", 3) == 0) {
616 if (strncmp(s
, "fcc0", 4) == 0) {
626 if (strncmp(s
, "fcc1", 4) == 0) {
636 if (strncmp(s
, "fcc2", 4) == 0) {
646 if (strncmp(s
, "fcc3", 4) == 0) {
653 if (strncmp(s
, "%pc", 3) == 0) {
660 if (strncmp(s
, "%modes", 6) == 0) {
667 if (strncmp(s
, "%tick", 5) == 0) {
673 /* end-sanitize-v9 */
675 case '\0': /* end of args */
691 case '[': /* these must match exactly */
699 case '#': /* must be at least one digit */
701 while (isdigit(*s
)) {
708 case 'C': /* coprocessor state register */
709 if (strncmp(s
, "%csr", 4) == 0) {
715 case 'b': /* next operand is a coprocessor register */
718 if (*s
++ == '%' && *s
++ == 'c' && isdigit(*s
)) {
721 mask
= 10 * (mask
- '0') + (*s
++ - '0');
731 opcode
|= mask
<< 14;
739 opcode
|= mask
<< 25;
745 case 'r': /* next operand must be a register */
752 case 'f': /* frame pointer */
759 case 'g': /* global register */
760 if (isoctal(c
= *s
++)) {
766 case 'i': /* in register */
767 if (isoctal(c
= *s
++)) {
773 case 'l': /* local register */
774 if (isoctal(c
= *s
++)) {
775 mask
= (c
- '0' + 16) ;
780 case 'o': /* out register */
781 if (isoctal(c
= *s
++)) {
782 mask
= (c
- '0' + 8) ;
787 case 's': /* stack pointer */
794 case 'r': /* any register */
795 if (!isdigit(c
= *s
++)) {
799 case '0': case '1': case '2': case '3': case '4':
800 case '5': case '6': case '7': case '8': case '9':
802 if ((c
= 10 * (c
- '0') + (*s
++ - '0')) >= 32) {
815 * Got the register, now figure out where
816 * it goes in the opcode.
821 opcode
|= mask
<< 14;
829 opcode
|= mask
<< 25;
833 opcode
|= (mask
<< 25) | (mask
<< 14);
839 /* start-sanitize-v9 */
845 /* end-sanitize-v9 */
846 case 'e': /* next operand is a floating point register */
861 /* start-sanitize-v9 */
863 && ((format
= *s
) == 'f'
867 /* end-sanitize-v9 */
868 && ((format
= *s
) == 'f')
870 /* start-sanitize-v9 */
872 /* end-sanitize-v9 */
877 for (mask
= 0; isdigit(*s
); ++s
) {
878 mask
= 10 * mask
+ (*s
- '0');
879 } /* read the number */
887 } /* register must be even numbered */
895 } /* register must be multiple of 4 */
899 error_message
= ": There are only 32 f registers; [0-31]";
902 /* start-sanitize-v9 */
907 error_message
= ": There are only 32 d registers [0, 2, ... 62].";
909 } else if (mask
& 1) {
910 error_message
= ": Only even numbered d registers exist.";
914 } else if (format
== 'q') {
917 ": There are only 16 q registers [0, 4, ... 60].";
919 } else if (mask
& 3) {
921 ": Only q registers evenly divisible by four exist.";
926 } /* depending on format */
930 } /* wrap high bit */
932 /* end-sanitize-v9 */
933 } /* if not an 'f' register. */
937 /* start-sanitize-v9 */
942 opcode
|= (mask
& 0x1f) << 9;
945 /* end-sanitize-v9 */
972 if (strncmp(s
, "%fsr", 4) == 0) {
978 case 'h': /* high 22 bits */
979 the_insn
.reloc
= RELOC_HI22
;
982 case 'l': /* 22 bit PC relative immediate */
983 the_insn
.reloc
= RELOC_WDISP22
;
987 case 'L': /* 30 bit immediate */
988 the_insn
.reloc
= RELOC_WDISP30
;
992 case 'n': /* 22 bit immediate */
993 the_insn
.reloc
= RELOC_22
;
996 case 'i': /* 13 bit immediate */
997 the_insn
.reloc
= RELOC_BASE13
;
1005 if ((c
= s
[1]) == 'h' && s
[2] == 'i') {
1006 the_insn
.reloc
= RELOC_HI22
;
1008 } else if (c
== 'l' && s
[2] == 'o') {
1009 the_insn
.reloc
= RELOC_LO10
;
1011 /* start-sanitize-v9 */
1016 the_insn
.reloc
= RELOC_HHI22
;
1022 the_insn
.reloc
= RELOC_HLO10
;
1025 /* end-sanitize-v9 */
1029 /* Note that if the getExpression() fails, we
1030 will still have created U entries in the
1031 symbol table for the 'symbols' in the input
1032 string. Try not to create U symbols for
1035 /* This stuff checks to see if the
1036 expression ends in +%reg If it does,
1037 it removes the register from the
1038 expression, and re-sets 's' to point
1039 to the right place */
1043 for (s1
= s
; *s1
&& *s1
!= ',' && *s1
!= ']'; s1
++) ;;
1045 if (s1
!= s
&& isdigit(s1
[-1])) {
1046 if(s1
[-2] == '%' && s1
[-3] == '+') {
1049 (void) getExpression(s
);
1053 } else if (strchr("goli0123456789", s1
[-2]) && s1
[-3] == '%' && s1
[-4] == '+') {
1056 (void) getExpression(s
);
1063 (void)getExpression(s
);
1075 char *push
= input_line_pointer
;
1078 input_line_pointer
= s
;
1080 if (expression(&e
) == SEG_ABSOLUTE
) {
1081 opcode
|= e
.X_add_number
<< 5;
1082 s
= input_line_pointer
;
1083 input_line_pointer
= push
;
1088 } /* alternate space */
1091 if (strncmp(s
, "%psr", 4) == 0) {
1097 case 'q': /* floating point queue */
1098 if (strncmp(s
, "%fq", 3) == 0) {
1104 case 'Q': /* coprocessor queue */
1105 if (strncmp(s
, "%cq", 3) == 0) {
1112 if (strcmp(str
, "set") == 0) {
1113 special_case
= SPECIAL_CASE_SET
;
1115 } else if (strncmp(str
, "fdiv", 4) == 0) {
1116 special_case
= SPECIAL_CASE_FDIV
;
1122 if (strncmp(s
, "%tbr", 4) != 0)
1128 if (strncmp(s
, "%wim", 4) != 0)
1134 if (strncmp(s
, "%y", 2) != 0)
1140 as_fatal("failed sanity check.");
1141 } /* switch on arg code */
1143 } /* for each arg that we expect */
1146 /* Args don't match. */
1147 if (((unsigned) (&insn
[1] - sparc_opcodes
)) < NUMOPCODES
1148 && !strcmp(insn
->name
, insn
[1].name
)) {
1153 as_bad("Illegal operands%s", error_message
);
1157 if (insn
->architecture
> current_architecture
) {
1158 if (!architecture_requested
|| warn_on_bump
) {
1161 as_warn("architecture bumped from \"%s\" to \"%s\" on \"%s\"",
1162 architecture_pname
[current_architecture
],
1163 architecture_pname
[insn
->architecture
],
1167 current_architecture
= insn
->architecture
;
1169 as_bad("architecture mismatch on \"%s\" (\"%s\"). current architecture is \"%s\"",
1171 architecture_pname
[insn
->architecture
],
1172 architecture_pname
[current_architecture
]);
1174 } /* if bump ok else error */
1175 } /* if architecture higher */
1179 } /* forever looking for a match */
1181 the_insn
.opcode
= opcode
;
1185 static int getExpression(str
)
1191 save_in
= input_line_pointer
;
1192 input_line_pointer
= str
;
1193 switch (seg
= expression(&the_insn
.exp
)) {
1200 case SEG_DIFFERENCE
:
1206 the_insn
.error
= "bad segment";
1207 expr_end
= input_line_pointer
;
1208 input_line_pointer
=save_in
;
1211 expr_end
= input_line_pointer
;
1212 input_line_pointer
= save_in
;
1214 } /* getExpression() */
1218 This is identical to the md_atof in m68k.c. I think this is right,
1221 Turn a string in input_line_pointer into a floating point constant of type
1222 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1223 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1226 /* Equal to MAX_PRECISION in atof-ieee.c */
1227 #define MAX_LITTLENUMS 6
1229 char *md_atof(type
,litP
,sizeP
)
1235 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1236 LITTLENUM_TYPE
*wordP
;
1268 return "Bad call to MD_ATOF()";
1270 t
=atof_ieee(input_line_pointer
,type
,words
);
1272 input_line_pointer
=t
;
1273 *sizeP
=prec
* sizeof(LITTLENUM_TYPE
);
1274 for(wordP
=words
;prec
--;) {
1275 md_number_to_chars(litP
,(long)(*wordP
++),sizeof(LITTLENUM_TYPE
));
1276 litP
+=sizeof(LITTLENUM_TYPE
);
1278 return ""; /* Someone should teach Dean about null pointers */
1282 * Write out big-endian.
1284 void md_number_to_chars(buf
,val
,n
)
1302 as_fatal("failed sanity check.");
1305 } /* md_number_to_chars() */
1307 /* Apply a fixS to the frags, now that we know the value it ought to
1310 void md_apply_fix(fixP
, val
)
1314 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
1316 assert(fixP
->fx_size
== 4);
1317 assert(fixP
->fx_r_type
< NO_RELOC
);
1319 fixP
->fx_addnumber
= val
; /* Remember value for emit_reloc */
1322 * This is a hack. There should be a better way to
1325 if (fixP
->fx_r_type
== RELOC_WDISP30
&& fixP
->fx_addsy
) {
1326 val
+= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1329 switch (fixP
->fx_r_type
) {
1332 buf
[0] = 0; /* val >> 24; */
1333 buf
[1] = 0; /* val >> 16; */
1334 buf
[2] = 0; /* val >> 8; */
1335 buf
[3] = 0; /* val; */
1339 case RELOC_8
: /* These don't seem to ever be needed. */
1346 val
= (val
>>= 2) + 1;
1347 buf
[0] |= (val
>> 24) & 0x3f;
1348 buf
[1]= (val
>> 16);
1353 /* start-sanitize-v9 */
1356 if (((val
> 0) && (val
& ~0x7ff))
1357 || ((val
< 0) && (~(val
- 1) & ~0x7ff))) {
1358 as_bad("relocation overflow.");
1361 buf
[2] = (val
>> 8) & 0x7;
1362 buf
[3] = val
& 0xff;
1365 case RELOC_WDISP2_14
:
1366 if (((val
> 0) && (val
& ~0x3fffc))
1367 || ((val
< 0) && (~(val
- 1) & ~0x3fffc))) {
1368 as_bad("relocation overflow.");
1371 val
= (val
>>= 2) + 1;
1372 buf
[1] |= ((val
>> 14) & 0x3) << 3;
1373 buf
[2] |= (val
>> 8) & 0x3f ;
1374 buf
[3] = val
& 0xff;
1378 if (((val
> 0) && (val
& ~0x1ffffc))
1379 || ((val
< 0) && (~(val
- 1) & ~0x1ffffc))) {
1380 as_bad("relocation overflow.");
1383 val
= (val
>>= 2) + 1;
1384 buf
[1] |= (val
>> 16) & 0x7;
1385 buf
[2] = (val
>> 8) & 0xff;
1386 buf
[3] = val
& 0xff;
1391 /* intentional fallthrough */
1393 /* end-sanitize-v9 */
1396 if(!fixP
->fx_addsy
) {
1397 buf
[1] |= (val
>> 26) & 0x3f;
1407 if (val
& ~0x003fffff) {
1408 as_bad("relocation overflow");
1410 buf
[1] |= (val
>> 16) & 0x3f;
1412 buf
[3] = val
& 0xff;
1416 if (val
& ~0x00001fff) {
1417 as_bad("relocation overflow");
1419 buf
[2] = (val
>> 8) & 0x1f;
1420 buf
[3] = val
& 0xff;
1423 /* start-sanitize-v9 */
1427 /* intentional fallthrough */
1429 /* end-sanitize-v9 */
1432 if(!fixP
->fx_addsy
) {
1433 buf
[2] |= (val
>> 8) & 0x03;
1439 case RELOC_SFA_BASE
:
1440 case RELOC_SFA_OFF13
:
1444 buf
[2] |= (val
>> 8) & 0x1f;
1449 val
= (val
>>= 2) + 1;
1452 buf
[1] |= (val
>> 16) & 0x3f;
1461 case RELOC_SEGOFF16
:
1462 case RELOC_GLOB_DAT
:
1463 case RELOC_JMP_SLOT
:
1464 case RELOC_RELATIVE
:
1469 as_bad("bad relocation type: 0x%02x", fixP
->fx_r_type
);
1472 } /* md_apply_fix() */
1474 /* should never be called for sparc */
1475 void md_create_short_jump(ptr
, from_addr
, to_addr
, frag
, to_symbol
)
1482 as_fatal("sparc_create_short_jmp\n");
1483 } /* md_create_short_jump() */
1485 /* Translate internal representation of relocation info to target format.
1487 On sparc: first 4 bytes are normal unsigned long address, next three
1488 bytes are index, most sig. byte first. Byte 7 is broken up with
1489 bit 7 as external, bits 6 & 5 unused, and the lower
1490 five bits as relocation type. Next 4 bytes are long addend. */
1491 /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
1492 void tc_aout_fix_to_chars(where
, fixP
, segment_address_in_file
)
1495 relax_addressT segment_address_in_file
;
1502 know(fixP
->fx_addsy
);
1504 if ((S_GET_TYPE(fixP
->fx_addsy
)) == N_UNDF
) {
1506 r_index
= fixP
->fx_addsy
->sy_number
;
1509 r_index
= S_GET_TYPE(fixP
->fx_addsy
);
1513 md_number_to_chars(where
,
1514 r_address
= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
- segment_address_in_file
,
1517 /* now the fun stuff */
1518 where
[4] = (r_index
>> 16) & 0x0ff;
1519 where
[5] = (r_index
>> 8) & 0x0ff;
1520 where
[6] = r_index
& 0x0ff;
1521 where
[7] = ((r_extern
<< 7) & 0x80) | (0 & 0x60) | (fixP
->fx_r_type
& 0x1F);
1524 if (fixP
->fx_addsy
->sy_frag
) {
1525 r_addend
= fixP
->fx_addsy
->sy_frag
->fr_address
;
1528 if (fixP
->fx_pcrel
) {
1529 r_addend
-= r_address
;
1531 r_addend
= fixP
->fx_addnumber
;
1534 md_number_to_chars(&where
[8], r_addend
, 4);
1537 } /* tc_aout_fix_to_chars() */
1539 /* should never be called for sparc */
1540 void md_convert_frag(headers
, fragP
)
1541 object_headers
*headers
;
1542 register fragS
*fragP
;
1544 as_fatal("sparc_convert_frag\n");
1545 } /* md_convert_frag() */
1547 /* should never be called for sparc */
1548 void md_create_long_jump(ptr
, from_addr
, to_addr
, frag
, to_symbol
)
1550 long from_addr
, to_addr
;
1554 as_fatal("sparc_create_long_jump\n");
1555 } /* md_create_long_jump() */
1557 /* should never be called for sparc */
1558 int md_estimate_size_before_relax(fragP
, segtype
)
1562 as_fatal("sparc_estimate_size_before_relax\n");
1564 } /* md_estimate_size_before_relax() */
1567 /* for debugging only */
1568 static void print_insn(insn
)
1569 struct sparc_it
*insn
;
1600 fprintf(stderr
, "ERROR: %s\n");
1602 fprintf(stderr
, "opcode=0x%08x\n", insn
->opcode
);
1603 fprintf(stderr
, "reloc = %s\n", Reloc
[insn
->reloc
]);
1604 fprintf(stderr
, "exp = {
1606 fprintf(stderr
, "\t\tX_add_symbol = %s\n",
1607 ((insn
->exp
.X_add_symbol
!= NULL
)
1608 ? ((S_GET_NAME(insn
->exp
.X_add_symbol
) != NULL
)
1609 ? S_GET_NAME(insn
->exp
.X_add_symbol
)
1612 fprintf(stderr
, "\t\tX_sub_symbol = %s\n",
1613 ((insn
->exp
.X_subtract_symbol
!= NULL
)
1614 ? (S_GET_NAME(insn
->exp
.X_subtract_symbol
)
1615 ? S_GET_NAME(insn
->exp
.X_subtract_symbol
)
1618 fprintf(stderr
, "\t\tX_add_number = %d\n",
1619 insn
->exp
.X_add_number
);
1620 fprintf(stderr
, "}\n");
1622 } /* print_insn() */
1625 /* Set the hook... */
1627 /* void emit_sparc_reloc();
1628 void (*md_emit_relocations)() = emit_sparc_reloc; */
1633 * Sparc/AM29K relocations are completely different, so it needs
1634 * this machine dependent routine to emit them.
1636 #if defined(OBJ_AOUT) || defined(OBJ_BOUT)
1637 void emit_sparc_reloc(fixP
, segment_address_in_file
)
1638 register fixS
*fixP
;
1639 relax_addressT segment_address_in_file
;
1641 struct reloc_info_generic ri
;
1642 register symbolS
*symbolP
;
1643 extern char *next_object_file_charP
;
1644 /* long add_number; */
1646 bzero((char *) &ri
, sizeof(ri
));
1647 for (; fixP
; fixP
= fixP
->fx_next
) {
1649 if (fixP
->fx_r_type
>= NO_RELOC
) {
1650 as_fatal("fixP->fx_r_type = %d\n", fixP
->fx_r_type
);
1653 if ((symbolP
= fixP
->fx_addsy
) != NULL
) {
1654 ri
.r_address
= fixP
->fx_frag
->fr_address
+
1655 fixP
->fx_where
- segment_address_in_file
;
1656 if ((S_GET_TYPE(symbolP
)) == N_UNDF
) {
1658 ri
.r_index
= symbolP
->sy_number
;
1661 ri
.r_index
= S_GET_TYPE(symbolP
);
1663 if (symbolP
&& symbolP
->sy_frag
) {
1664 ri
.r_addend
= symbolP
->sy_frag
->fr_address
;
1666 ri
.r_type
= fixP
->fx_r_type
;
1667 if (fixP
->fx_pcrel
) {
1668 /* ri.r_addend -= fixP->fx_where; */
1669 ri
.r_addend
-= ri
.r_address
;
1671 ri
.r_addend
= fixP
->fx_addnumber
;
1674 md_ri_to_chars(next_object_file_charP
, &ri
);
1675 next_object_file_charP
+= md_reloc_size
;
1679 } /* emit_sparc_reloc() */
1680 #endif /* aout or bout */
1681 #endif /* comment */
1685 * Invocation line includes a switch not recognized by the base assembler.
1686 * See if it's a processor-specific option. These are:
1689 * Warn on architecture bumps. See also -A.
1692 * Select the architecture. Instructions or features not
1693 * supported by the selected architecture cause fatal errors.
1695 * The default is to start at v6, and bump the architecture up
1696 * whenever an instruction is seen at a higher level.
1698 * If -bump is specified, a warning is printing when bumping to
1701 * If an architecture is specified, all instructions must match
1702 * that architecture. Any higher level instructions are flagged
1705 * if both an architecture and -bump are specified, the
1706 * architecture starts at the specified level, but bumps are
1710 /* start-sanitize-v9 */
1711 /* There is also a -Av9 architecture option. xoxorich. */
1712 /* end-sanitize-v9 */
1713 int md_parse_option(argP
, cntP
, vecP
)
1721 if (!strcmp(*argP
,"bump")){
1724 } else if (**argP
== 'A'){
1727 for (arch
= architecture_pname
; *arch
!= NULL
; ++arch
){
1728 if (strcmp(p
, *arch
) == 0){
1730 } /* found a match */
1731 } /* walk the pname table */
1734 as_bad("unknown architecture: %s", p
);
1736 current_architecture
= (enum sparc_architecture
) (arch
- architecture_pname
);
1737 architecture_requested
= 1;
1740 /* Unknown option */
1744 **argP
= '\0'; /* Done parsing this switch */
1746 } /* md_parse_option() */
1748 /* We have no need to default values of symbols. */
1751 symbolS
*md_undefined_symbol(name
)
1755 } /* md_undefined_symbol() */
1757 /* Parse an operand that is machine-specific.
1758 We just return without modifying the expression if we have nothing
1762 void md_operand(expressionP
)
1763 expressionS
*expressionP
;
1765 } /* md_operand() */
1767 /* Round up a section size to the appropriate boundary. */
1768 long md_section_align (segment
, size
)
1772 return (size
+ 7) & ~7; /* Round all sects to multiple of 8 */
1773 } /* md_section_align() */
1775 /* Exactly what point is a PC-relative offset relative TO?
1776 On the sparc, they're relative to the address of the offset, plus
1777 its size. This gets us to the following instruction.
1778 (??? Is this right? FIXME-SOON) */
1779 long md_pcrel_from(fixP
)
1782 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1783 } /* md_pcrel_from() */
1785 void tc_aout_pre_write_hook(headers
)
1786 object_headers
*headers
;
1788 H_SET_VERSION(headers
, 1);
1790 } /* tc_aout_pre_write_hook() */
1799 /* end of tc-sparc.c */