* config/obj-ecoff.c (get_tag): Save tag name in permanent memory
[deliverable/binutils-gdb.git] / gas / config / tc-sparc.c
CommitLineData
fecd2382 1/* tc-sparc.c -- Assemble for the SPARC
a87b3269 2 Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
355afbcd 3
fecd2382 4 This file is part of GAS, the GNU Assembler.
355afbcd 5
fecd2382
RP
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
6321e9ea 8 the Free Software Foundation; either version 2, or (at your option)
fecd2382 9 any later version.
355afbcd 10
fecd2382
RP
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.
355afbcd 15
fecd2382
RP
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
a87b3269
RP
20#define cypress 1234
21
fecd2382
RP
22#include <stdio.h>
23#include <ctype.h>
24
25#include "as.h"
26
27/* careful, this file includes data *declarations* */
584a0f78 28#include "opcode/sparc.h"
fecd2382 29
355afbcd
KR
30void md_begin ();
31void md_end ();
32void md_number_to_chars ();
33void md_assemble ();
34char *md_atof ();
355afbcd
KR
35void md_create_short_jump ();
36void md_create_long_jump ();
37int md_estimate_size_before_relax ();
38void md_ri_to_chars ();
39symbolS *md_undefined_symbol ();
40static void sparc_ip ();
fecd2382 41
839df5c3 42static enum sparc_architecture current_architecture = v6;
428d312b
KR
43static int architecture_requested;
44static int warn_on_bump;
839df5c3 45
ed9638af
KR
46extern int target_big_endian;
47
428d312b 48const relax_typeS md_relax_table[1];
fecd2382
RP
49
50/* handle of the OPCODE hash table */
51static struct hash_control *op_hash = NULL;
52
355afbcd
KR
53static void s_seg (), s_proc (), s_data1 (), s_reserve (), s_common ();
54extern void s_globl (), s_long (), s_short (), s_space (), cons ();
ed9638af 55extern void s_align_bytes (), s_ignore (), s_local();
428d312b
KR
56/* start-sanitize-v9 */
57#ifndef NO_V9
58static void s_xword ();
59#endif
60/* end-sanitize-v9 */
61
62/* Ugly hack to keep non-BFD version working. */
63#ifndef BFD_ASSEMBLER
64#define BFD_RELOC_NONE NO_RELOC
65#define BFD_RELOC_32 RELOC_32
66#define BFD_RELOC_HI22 RELOC_HI22
67#define BFD_RELOC_LO10 RELOC_LO10
68#define BFD_RELOC_SPARC_WDISP22 RELOC_WDISP22
69#define BFD_RELOC_32_PCREL_S2 RELOC_WDISP30
70#define BFD_RELOC_SPARC22 RELOC_22
71#define BFD_RELOC_SPARC_BASE13 RELOC_BASE13
72#define BFD_RELOC_SPARC13 RELOC_13
73#define BFD_RELOC_SPARC_BASE22 RELOC_BASE22
74#define subseg_set subseg_new
75#endif
355afbcd
KR
76
77const pseudo_typeS md_pseudo_table[] =
78{
79 {"align", s_align_bytes, 0}, /* Defaulting is invalid (0) */
80 {"common", s_common, 0},
81 {"global", s_globl, 0},
82 {"half", cons, 2},
ed9638af
KR
83#ifdef OBJ_ELF
84 {"local", s_local, 0},
85#endif
355afbcd
KR
86 {"optim", s_ignore, 0},
87 {"proc", s_proc, 0},
88 {"reserve", s_reserve, 0},
89 {"seg", s_seg, 0},
90 {"skip", s_space, 0},
91 {"word", cons, 4},
428d312b
KR
92/* start-sanitize-v9 */
93#ifndef NO_V9
94 {"xword", s_xword, 0},
95#endif
96/* end-sanitize-v9 */
355afbcd 97 {NULL, 0, 0},
fecd2382
RP
98};
99
839df5c3
RP
100const int md_short_jump_size = 4;
101const int md_long_jump_size = 4;
355afbcd 102const int md_reloc_size = 12; /* Size of relocation record */
fecd2382
RP
103
104/* This array holds the chars that always start a comment. If the
105 pre-processor is disabled, these aren't very useful */
839df5c3 106const char comment_chars[] = "!"; /* JF removed '|' from comment_chars */
fecd2382
RP
107
108/* This array holds the chars that only start a comment at the beginning of
109 a line. If the line seems to have the form '# 123 filename'
110 .line and .file directives will appear in the pre-processed output */
111/* Note that input_file.c hand checks for '#' at the beginning of the
112 first line of the input file. This is because the compiler outputs
113 #NO_APP at the beginning of its output. */
839df5c3
RP
114/* Also note that comments started like this one will always
115 work if '/' isn't otherwise defined. */
116const char line_comment_chars[] = "#";
fecd2382 117
355afbcd
KR
118const char line_separator_chars[] = "";
119
fecd2382 120/* Chars that can be used to separate mant from exp in floating point nums */
839df5c3 121const char EXP_CHARS[] = "eE";
fecd2382
RP
122
123/* Chars that mean this number is a floating point constant */
124/* As in 0f12.456 */
125/* or 0d1.2345e12 */
839df5c3 126const char FLT_CHARS[] = "rRsSfFdDxXpP";
fecd2382
RP
127
128/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
129 changed in read.c . Ideally it shouldn't have to know about it at all,
130 but nothing is ideal around here.
131 */
132
133static unsigned char octal[256];
134#define isoctal(c) octal[c]
355afbcd
KR
135static unsigned char toHex[256];
136
137struct sparc_it
138 {
139 char *error;
140 unsigned long opcode;
141 struct nlist *nlistp;
142 expressionS exp;
143 int pcrel;
428d312b
KR
144#ifdef BFD_ASSEMBLER
145 bfd_reloc_code_real_type reloc;
146#else
355afbcd 147 enum reloc_type reloc;
fecd2382 148#endif
428d312b
KR
149 };
150
151struct sparc_it the_insn, set_insn;
152
fecd2382 153#if 0
428d312b 154static void print_insn PARAMS ((struct sparc_it *insn));
fecd2382 155#endif
428d312b 156static int getExpression PARAMS ((char *str));
a87b3269 157
fecd2382
RP
158static char *expr_end;
159static int special_case;
160
161/*
162 * Instructions that require wierd handling because they're longer than
163 * 4 bytes.
164 */
165#define SPECIAL_CASE_SET 1
166#define SPECIAL_CASE_FDIV 2
167
168/*
169 * sort of like s_lcomm
170 *
171 */
584a0f78
RP
172static int max_alignment = 15;
173
355afbcd
KR
174static void
175s_reserve ()
176{
177 char *name;
178 char *p;
179 char c;
180 int align;
181 int size;
182 int temp;
183 symbolS *symbolP;
184
185 name = input_line_pointer;
186 c = get_symbol_end ();
187 p = input_line_pointer;
188 *p = c;
189 SKIP_WHITESPACE ();
190
191 if (*input_line_pointer != ',')
192 {
193 as_bad ("Expected comma after name");
194 ignore_rest_of_line ();
195 return;
196 }
197
198 ++input_line_pointer;
199
200 if ((size = get_absolute_expression ()) < 0)
201 {
202 as_bad ("BSS length (%d.) <0! Ignored.", size);
203 ignore_rest_of_line ();
204 return;
205 } /* bad length */
206
207 *p = 0;
208 symbolP = symbol_find_or_make (name);
209 *p = c;
210
125f0b0d
KR
211 if (strncmp (input_line_pointer, ",\"bss\"", 6) != 0
212 && strncmp (input_line_pointer, ",\".bss\"", 7) != 0)
355afbcd
KR
213 {
214 as_bad ("bad .reserve segment: `%s'", input_line_pointer);
215 return;
216 } /* if not bss */
217
125f0b0d
KR
218 if (input_line_pointer[2] == '.')
219 input_line_pointer += 7;
220 else
221 input_line_pointer += 6;
355afbcd
KR
222 SKIP_WHITESPACE ();
223
224 if (*input_line_pointer == ',')
225 {
226 ++input_line_pointer;
227
228 SKIP_WHITESPACE ();
229 if (*input_line_pointer == '\n')
230 {
231 as_bad ("Missing alignment");
232 return;
233 }
234
235 align = get_absolute_expression ();
236 if (align > max_alignment)
237 {
238 align = max_alignment;
239 as_warn ("Alignment too large: %d. assumed.", align);
240 }
241 else if (align < 0)
242 {
243 align = 0;
244 as_warn ("Alignment negative. 0 assumed.");
fecd2382 245 }
428d312b
KR
246
247 record_alignment (bss_section, align);
355afbcd
KR
248
249 /* convert to a power of 2 alignment */
250 for (temp = 0; (align & 1) == 0; align >>= 1, ++temp);;
251
252 if (align != 1)
253 {
254 as_bad ("Alignment not a power of 2");
255 ignore_rest_of_line ();
256 return;
257 } /* not a power of two */
258
259 align = temp;
355afbcd 260 } /* if has optional alignment */
428d312b
KR
261 else
262 align = 0;
355afbcd 263
125f0b0d
KR
264 if ((S_GET_SEGMENT (symbolP) == bss_section
265 || !S_IS_DEFINED (symbolP))
266#ifdef OBJ_AOUT
267 && S_GET_OTHER (symbolP) == 0
355afbcd 268 && S_GET_DESC (symbolP) == 0
125f0b0d
KR
269#endif
270 )
355afbcd 271 {
428d312b
KR
272 if (! need_pass_2)
273 {
274 char *p;
275 segT current_seg = now_seg;
276 subsegT current_subseg = now_subseg;
277
278 subseg_set (bss_section, 1); /* switch to bss */
279
280 if (align)
281 frag_align (align, 0); /* do alignment */
282
283 /* detach from old frag */
284 if (S_GET_SEGMENT(symbolP) == bss_section)
285 symbolP->sy_frag->fr_symbol = NULL;
286
287 symbolP->sy_frag = frag_now;
288 p = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
289 size, (char *)0);
290 *p = 0;
291
292 S_SET_SEGMENT (symbolP, bss_section);
293
294 subseg_set (current_seg, current_subseg);
295 }
355afbcd
KR
296 }
297 else
298 {
428d312b 299 as_warn("Ignoring attempt to re-define symbol %s.", name);
355afbcd
KR
300 } /* if not redefining */
301
302 demand_empty_rest_of_line ();
428d312b 303}
355afbcd 304
ed9638af
KR
305#ifdef OBJ_ELF
306/* Currently used only by Solaris 2. */
307void
308s_local ()
309{
310 char *name;
311 int c;
312 symbolS *symbolP;
313
314 do
315 {
316 name = input_line_pointer;
317 c = get_symbol_end ();
318 symbolP = symbol_find_or_make (name);
319 *input_line_pointer = c;
320 SKIP_WHITESPACE ();
321 S_CLEAR_EXTERNAL (symbolP);
322 symbolP->local = 1;
323 if (c == ',')
324 {
325 input_line_pointer++;
326 SKIP_WHITESPACE ();
327 if (*input_line_pointer == '\n')
328 c = '\n';
329 }
330 }
331 while (c == ',');
332 demand_empty_rest_of_line ();
333}
334#endif
335
355afbcd
KR
336static void
337s_common ()
338{
ed9638af
KR
339 char *name;
340 char c;
341 char *p;
342 int temp, size;
343 symbolS *symbolP;
355afbcd
KR
344
345 name = input_line_pointer;
346 c = get_symbol_end ();
347 /* just after name is now '\0' */
348 p = input_line_pointer;
349 *p = c;
350 SKIP_WHITESPACE ();
351 if (*input_line_pointer != ',')
352 {
353 as_bad ("Expected comma after symbol-name");
354 ignore_rest_of_line ();
355 return;
356 }
357 input_line_pointer++; /* skip ',' */
358 if ((temp = get_absolute_expression ()) < 0)
359 {
360 as_bad (".COMMon length (%d.) <0! Ignored.", temp);
361 ignore_rest_of_line ();
362 return;
363 }
ed9638af 364 size = temp;
355afbcd
KR
365 *p = 0;
366 symbolP = symbol_find_or_make (name);
367 *p = c;
368 if (S_IS_DEFINED (symbolP))
369 {
370 as_bad ("Ignoring attempt to re-define symbol");
371 ignore_rest_of_line ();
372 return;
373 }
374 if (S_GET_VALUE (symbolP) != 0)
375 {
ed9638af 376 if (S_GET_VALUE (symbolP) != size)
355afbcd 377 {
125f0b0d
KR
378 as_warn ("Length of .comm \"%s\" is already %ld. Not changed to %d.",
379 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
680227f3 380 }
355afbcd
KR
381 }
382 else
383 {
ed9638af
KR
384#ifndef OBJ_ELF
385 S_SET_VALUE (symbolP, size);
355afbcd 386 S_SET_EXTERNAL (symbolP);
428d312b 387#endif
355afbcd
KR
388 }
389 know (symbolP->sy_frag == &zero_address_frag);
428d312b
KR
390 if (*input_line_pointer != ',')
391 {
125f0b0d 392 as_bad ("Expected comma after common length");
428d312b
KR
393 ignore_rest_of_line ();
394 return;
395 }
396 input_line_pointer++;
125f0b0d
KR
397 SKIP_WHITESPACE ();
398 if (*input_line_pointer != '"')
ed9638af 399 {
125f0b0d
KR
400 temp = get_absolute_expression ();
401 if (temp > max_alignment)
402 {
403 temp = max_alignment;
404 as_warn ("Common alignment too large: %d. assumed", temp);
405 }
406 else if (temp < 0)
407 {
408 temp = 0;
409 as_warn ("Common alignment negative; 0 assumed");
410 }
b2565433 411#ifdef OBJ_ELF
125f0b0d
KR
412 if (symbolP->local)
413 {
ff4cac38
KR
414 segT old_sec;
415 int old_subsec;
125f0b0d 416 char *p;
ff4cac38 417 int align;
ed9638af 418
ff4cac38
KR
419 allocate_bss:
420 old_sec = now_seg;
421 old_subsec = now_subseg;
422 align = temp;
125f0b0d
KR
423 record_alignment (bss_section, align);
424 subseg_set (bss_section, 0);
425 if (align)
426 frag_align (align, 0);
427 if (S_GET_SEGMENT (symbolP) == bss_section)
428 symbolP->sy_frag->fr_symbol = 0;
429 symbolP->sy_frag = frag_now;
430 p = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
431 (char *) 0);
432 *p = 0;
433 S_SET_SEGMENT (symbolP, bss_section);
434 S_CLEAR_EXTERNAL (symbolP);
435 subseg_set (old_sec, old_subsec);
436 }
437 else
b2565433 438#endif
125f0b0d 439 {
ff4cac38 440 allocate_common:
125f0b0d
KR
441 S_SET_VALUE (symbolP, size);
442 S_SET_EXTERNAL (symbolP);
443 /* should be common, but this is how gas does it for now */
444 S_SET_SEGMENT (symbolP, &bfd_und_section);
445 }
ed9638af
KR
446 }
447 else
448 {
125f0b0d 449 input_line_pointer++;
ff4cac38
KR
450 /* @@ Some use the dot, some don't. Can we get some consistency?? */
451 if (*input_line_pointer == '.')
452 input_line_pointer++;
453 /* @@ Some say data, some say bss. */
125f0b0d 454 if (strncmp (input_line_pointer, "bss\"", 4)
ff4cac38 455 && strncmp (input_line_pointer, "data\"", 5))
125f0b0d 456 {
ff4cac38
KR
457 while (*--input_line_pointer != '"')
458 ;
459 input_line_pointer--;
125f0b0d
KR
460 goto bad_common_segment;
461 }
462 while (*input_line_pointer++ != '"')
463 ;
ff4cac38 464 goto allocate_common;
355afbcd 465 }
355afbcd
KR
466 demand_empty_rest_of_line ();
467 return;
ff4cac38
KR
468
469 {
470 bad_common_segment:
471 p = input_line_pointer;
472 while (*p && *p != '\n')
473 p++;
474 c = *p;
475 *p = '\0';
476 as_bad ("bad .common segment %s", input_line_pointer + 1);
477 *p = c;
478 input_line_pointer = p;
479 ignore_rest_of_line ();
480 return;
481 }
482}
355afbcd
KR
483
484static void
485s_seg ()
486{
487
488 if (strncmp (input_line_pointer, "\"text\"", 6) == 0)
489 {
490 input_line_pointer += 6;
491 s_text ();
492 return;
493 }
494 if (strncmp (input_line_pointer, "\"data\"", 6) == 0)
495 {
496 input_line_pointer += 6;
497 s_data ();
498 return;
499 }
500 if (strncmp (input_line_pointer, "\"data1\"", 7) == 0)
501 {
502 input_line_pointer += 7;
503 s_data1 ();
504 return;
505 }
506 if (strncmp (input_line_pointer, "\"bss\"", 5) == 0)
507 {
508 input_line_pointer += 5;
509 /* We only support 2 segments -- text and data -- for now, so
428d312b
KR
510 things in the "bss segment" will have to go into data for now.
511 You can still allocate SEG_BSS stuff with .lcomm or .reserve. */
512 subseg_set (data_section, 255); /* FIXME-SOMEDAY */
355afbcd
KR
513 return;
514 }
515 as_bad ("Unknown segment type");
516 demand_empty_rest_of_line ();
517 return;
518} /* s_seg() */
519
520static void
521s_data1 ()
522{
428d312b 523 subseg_set (data_section, 1);
355afbcd
KR
524 demand_empty_rest_of_line ();
525 return;
526} /* s_data1() */
fecd2382 527
355afbcd
KR
528static void
529s_proc ()
530{
531 extern char is_end_of_line[];
fecd2382 532
355afbcd
KR
533 while (!is_end_of_line[*input_line_pointer])
534 {
535 ++input_line_pointer;
536 }
537 ++input_line_pointer;
538 return;
539} /* s_proc() */
fecd2382 540
680227f3
KR
541/* start-sanitize-v9 */
542#ifndef NO_V9
428d312b
KR
543static void
544s_xword ()
545{
125f0b0d
KR
546 SKIP_WHITESPACE ();
547 if (isdigit (*input_line_pointer))
548 big_cons (8);
549 else
550 cons (8);
428d312b
KR
551}
552
355afbcd
KR
553struct priv_reg_entry
554 {
555 char *name;
556 int regnum;
557 };
428d312b 558
680227f3
KR
559struct priv_reg_entry priv_reg_table[] =
560{
355afbcd
KR
561 {"tpc", 0},
562 {"tnpc", 1},
563 {"tstate", 2},
564 {"tt", 3},
565 {"tick", 4},
566 {"tba", 5},
567 {"pstate", 6},
568 {"tl", 7},
569 {"pil", 8},
570 {"cwp", 9},
571 {"cansave", 10},
572 {"canrestore", 11},
573 {"cleanwin", 12},
574 {"otherwin", 13},
575 {"wstate", 14},
125f0b0d 576 {"fq", 15},
355afbcd
KR
577 {"ver", 31},
578 {"", -1}, /* end marker */
680227f3
KR
579};
580
ed9638af
KR
581struct membar_masks
582{
583 char *name;
584 int len;
585 int mask;
586};
587
588#define MEMBAR_MASKS_SIZE 7
589
590struct membar_masks membar_masks[MEMBAR_MASKS_SIZE] =
591{
592 {"Sync", 4, 0x40},
593 {"MemIssue", 8, 0x20},
594 {"Lookaside", 9, 0x10},
595 {"StoreStore", 10, 0x08},
596 {"LoadStore", 9, 0x04},
597 {"StoreLoad", 9, 0x02},
598 {"LoadLoad", 8, 0x01},
599};
600
355afbcd
KR
601static int
602cmp_reg_entry (p, q)
680227f3
KR
603 struct priv_reg_entry *p, *q;
604{
605 return strcmp (q->name, p->name);
606}
355afbcd 607
680227f3
KR
608#endif
609/* end-sanitize-v9 */
610
fecd2382
RP
611/* This function is called once, at assembler startup time. It should
612 set up all the tables, etc. that the MD part of the assembler will need. */
355afbcd
KR
613void
614md_begin ()
615{
616 register char *retval = NULL;
617 int lose = 0;
618 register unsigned int i = 0;
619
620 op_hash = hash_new ();
621 if (op_hash == NULL)
622 as_fatal ("Virtual memory exhausted");
623
624 while (i < NUMOPCODES)
625 {
626 const char *name = sparc_opcodes[i].name;
627 retval = hash_insert (op_hash, name, &sparc_opcodes[i]);
628 if (retval != NULL && *retval != '\0')
629 {
630 fprintf (stderr, "internal error: can't hash `%s': %s\n",
631 sparc_opcodes[i].name, retval);
632 lose = 1;
fecd2382 633 }
355afbcd
KR
634 do
635 {
636 if (sparc_opcodes[i].match & sparc_opcodes[i].lose)
637 {
638 fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n",
639 sparc_opcodes[i].name, sparc_opcodes[i].args);
640 lose = 1;
641 }
642 ++i;
643 }
644 while (i < NUMOPCODES
645 && !strcmp (sparc_opcodes[i].name, name));
646 }
647
648 if (lose)
649 as_fatal ("Broken assembler. No assembly attempted.");
650
651 for (i = '0'; i < '8'; ++i)
652 octal[i] = 1;
653 for (i = '0'; i <= '9'; ++i)
654 toHex[i] = i - '0';
655 for (i = 'a'; i <= 'f'; ++i)
656 toHex[i] = i + 10 - 'a';
657 for (i = 'A'; i <= 'F'; ++i)
658 toHex[i] = i + 10 - 'A';
659
660 /* start-sanitize-v9 */
680227f3 661#ifndef NO_V9
125f0b0d
KR
662#ifdef sparcv9
663 current_architecture = v9;
664#endif
665
355afbcd
KR
666 qsort (priv_reg_table, sizeof (priv_reg_table) / sizeof (priv_reg_table[0]),
667 sizeof (priv_reg_table[0]), cmp_reg_entry);
680227f3 668#endif
355afbcd 669 /* end-sanitize-v9 */
ed9638af
KR
670
671 target_big_endian = 1;
355afbcd 672} /* md_begin() */
fecd2382 673
355afbcd
KR
674void
675md_end ()
676{
677 return;
678} /* md_end() */
fecd2382 679
355afbcd
KR
680void
681md_assemble (str)
682 char *str;
fecd2382 683{
355afbcd
KR
684 char *toP;
685 int rsd;
686
687 know (str);
688 sparc_ip (str);
689
690 /* See if "set" operand is absolute and small; skip sethi if so. */
428d312b 691 if (special_case == SPECIAL_CASE_SET
5ac34ac3 692 && the_insn.exp.X_op == O_constant)
355afbcd
KR
693 {
694 if (the_insn.exp.X_add_number >= -(1 << 12)
695 && the_insn.exp.X_add_number < (1 << 12))
696 {
697 the_insn.opcode = 0x80102000 /* or %g0,imm,... */
698 | (the_insn.opcode & 0x3E000000) /* dest reg */
699 | (the_insn.exp.X_add_number & 0x1FFF); /* imm */
700 special_case = 0; /* No longer special */
428d312b 701 the_insn.reloc = BFD_RELOC_NONE; /* No longer relocated */
680227f3 702 }
355afbcd
KR
703 }
704
705 toP = frag_more (4);
706 /* put out the opcode */
125f0b0d 707 md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
355afbcd
KR
708
709 /* put out the symbol-dependent stuff */
428d312b 710 if (the_insn.reloc != BFD_RELOC_NONE)
355afbcd 711 {
5ac34ac3
ILT
712 fix_new_exp (frag_now, /* which frag */
713 (toP - frag_now->fr_literal), /* where */
714 4, /* size */
715 &the_insn.exp,
716 the_insn.pcrel,
717 the_insn.reloc);
355afbcd 718 }
428d312b 719
355afbcd
KR
720 switch (special_case)
721 {
355afbcd
KR
722 case SPECIAL_CASE_SET:
723 special_case = 0;
428d312b 724 assert (the_insn.reloc == BFD_RELOC_HI22);
355afbcd 725 /* See if "set" operand has no low-order bits; skip OR if so. */
5ac34ac3 726 if (the_insn.exp.X_op == O_constant
355afbcd
KR
727 && ((the_insn.exp.X_add_number & 0x3FF) == 0))
728 return;
729 toP = frag_more (4);
730 rsd = (the_insn.opcode >> 25) & 0x1f;
731 the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14);
125f0b0d 732 md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
5ac34ac3
ILT
733 fix_new_exp (frag_now, /* which frag */
734 (toP - frag_now->fr_literal), /* where */
735 4, /* size */
736 &the_insn.exp,
737 the_insn.pcrel,
738 BFD_RELOC_LO10);
355afbcd
KR
739 return;
740
741 case SPECIAL_CASE_FDIV:
742 /* According to information leaked from Sun, the "fdiv" instructions
8fc0776d
JW
743 on early SPARC machines would produce incorrect results sometimes.
744 The workaround is to add an fmovs of the destination register to
745 itself just after the instruction. This was true on machines
746 with Weitek 1165 float chips, such as the Sun-4/260 and /280. */
355afbcd 747 special_case = 0;
428d312b 748 assert (the_insn.reloc == BFD_RELOC_NONE);
355afbcd
KR
749 toP = frag_more (4);
750 rsd = (the_insn.opcode >> 25) & 0x1f;
751 the_insn.opcode = 0x81A00020 | (rsd << 25) | rsd; /* fmovs dest,dest */
125f0b0d 752 md_number_to_chars (toP, (valueT) the_insn.opcode, 4);
355afbcd
KR
753 return;
754
755 case 0:
756 return;
757
758 default:
759 as_fatal ("failed sanity check.");
760 }
761} /* md_assemble() */
762
763static void
764sparc_ip (str)
765 char *str;
fecd2382 766{
355afbcd
KR
767 char *error_message = "";
768 char *s;
769 const char *args;
770 char c;
771 struct sparc_opcode *insn;
772 char *argsStart;
773 unsigned long opcode;
774 unsigned int mask = 0;
775 int match = 0;
776 int comma = 0;
777 long immediate_max = 0;
778
779 for (s = str; islower (*s) || (*s >= '0' && *s <= '3'); ++s)
780 ;
781 switch (*s)
782 {
783
784 case '\0':
785 break;
786
787 case ',':
788 comma = 1;
789
790 /*FALLTHROUGH */
791
792 case ' ':
793 *s++ = '\0';
794 break;
795
796 default:
797 as_bad ("Unknown opcode: `%s'", str);
798 exit (1);
799 }
800 if ((insn = (struct sparc_opcode *) hash_find (op_hash, str)) == NULL)
801 {
802 as_bad ("Unknown opcode: `%s'", str);
803 return;
804 }
805 if (comma)
806 {
807 *--s = ',';
808 }
809 argsStart = s;
810 for (;;)
811 {
812 opcode = insn->match;
813 memset (&the_insn, '\0', sizeof (the_insn));
428d312b 814 the_insn.reloc = BFD_RELOC_NONE;
355afbcd
KR
815
816 /*
8fc0776d
JW
817 * Build the opcode, checking as we go to make
818 * sure that the operands match
819 */
355afbcd
KR
820 for (args = insn->args;; ++args)
821 {
822 switch (*args)
823 {
824
825 /* start-sanitize-v9 */
680227f3 826#ifndef NO_V9
355afbcd
KR
827 case 'K':
828 {
355afbcd 829 int mask = 0;
ed9638af
KR
830 int i;
831
832 /* Parse a series of masks. */
833 if (*s == '#')
355afbcd 834 {
ed9638af 835 while (*s == '#')
355afbcd 836 {
ed9638af
KR
837 ++s;
838 for (i = 0; i < MEMBAR_MASKS_SIZE; i++)
839 if (!strncmp (s, membar_masks[i].name,
840 membar_masks[i].len))
841 break;
842 if (i < MEMBAR_MASKS_SIZE)
843 {
844 mask |= membar_masks[i].mask;
845 s += membar_masks[i].len;
846 }
847 else
848 {
849 error_message = ": invalid membar mask name";
850 goto error;
851 }
852 if (*s == '|')
853 ++s;
355afbcd 854 }
ed9638af
KR
855 }
856 else if (isdigit (*s))
857 {
858 while (isdigit (*s))
355afbcd 859 {
ed9638af
KR
860 mask = mask * 10 + *s - '0';
861 ++s;
862 }
863
864 if (mask < 0 || mask > 127)
865 {
866 error_message = ": invalid membar mask number";
867 goto error;
355afbcd 868 }
355afbcd 869 }
ed9638af 870 else
355afbcd 871 {
ed9638af 872 error_message = ": unrecognizable membar mask";
355afbcd
KR
873 goto error;
874 }
875 opcode |= SIMM13 (mask);
876 continue;
877 }
878
879 case '*':
ed9638af
KR
880 {
881 int prefetch_fcn = 0;
355afbcd 882
ed9638af
KR
883 /* Parse a prefetch function. */
884 if (*s == '#')
885 {
886 s += 1;
887 if (!strncmp (s, "n_reads", 7))
888 prefetch_fcn = 0, s += 7;
889 else if (!strncmp (s, "one_read", 8))
890 prefetch_fcn = 1, s += 8;
891 else if (!strncmp (s, "n_writes", 8))
892 prefetch_fcn = 2, s += 8;
893 else if (!strncmp (s, "one_write", 9))
894 prefetch_fcn = 3, s += 9;
895 else if (!strncmp (s, "page", 4))
896 prefetch_fcn = 4, s += 4;
897 else
898 {
899 error_message = ": invalid prefetch function name";
900 goto error;
901 }
902 }
903 else if (isdigit (*s))
904 {
905 while (isdigit (*s))
906 {
907 prefetch_fcn = prefetch_fcn * 10 + *s - '0';
908 ++s;
909 }
910
911 if (prefetch_fcn < 0 || prefetch_fcn > 31)
912 {
913 error_message = ": invalid prefetch function number";
914 goto error;
915 }
916 }
917 else
918 {
919 error_message = ": unrecognizable prefetch function";
920 goto error;
921 }
922 opcode |= RD (prefetch_fcn);
923 continue;
924 }
355afbcd
KR
925
926 case '!':
927 case '?':
928 /* Parse a privileged register. */
929 if (*s == '%')
930 {
931 struct priv_reg_entry *p = priv_reg_table;
125f0b0d 932 int len = 9999999; /* init to make gcc happy */
355afbcd
KR
933
934 s += 1;
935 while (p->name[0] > s[0])
936 p++;
937 while (p->name[0] == s[0])
938 {
939 len = strlen (p->name);
940 if (strncmp (p->name, s, len) == 0)
941 break;
942 p++;
943 }
944 if (p->name[0] != s[0])
945 {
ed9638af 946 error_message = ": unrecognizable privileged register";
355afbcd
KR
947 goto error;
948 }
949 if (*args == '?')
950 opcode |= (p->regnum << 14);
951 else
952 opcode |= (p->regnum << 25);
953 s += len;
954 continue;
955 }
956 else
957 {
ed9638af 958 error_message = ": unrecognizable privileged register";
355afbcd
KR
959 goto error;
960 }
961#endif
962 /* end-sanitize-v9 */
680227f3 963
355afbcd
KR
964 case 'M':
965 case 'm':
966 if (strncmp (s, "%asr", 4) == 0)
967 {
968 s += 4;
680227f3 969
355afbcd
KR
970 if (isdigit (*s))
971 {
972 long num = 0;
973
974 while (isdigit (*s))
975 {
976 num = num * 10 + *s - '0';
977 ++s;
978 }
979
980 if (num < 16 || 31 < num)
981 {
982 error_message = ": asr number must be between 15 and 31";
983 goto error;
984 } /* out of range */
985
986 opcode |= (*args == 'M' ? RS1 (num) : RD (num));
987 continue;
988 }
989 else
990 {
991 error_message = ": expecting %asrN";
992 goto error;
993 } /* if %asr followed by a number. */
994
995 } /* if %asr */
996 break;
997
998 /* start-sanitize-v9 */
999#ifndef NO_V9
1000 case 'I':
125f0b0d 1001 the_insn.reloc = BFD_RELOC_SPARC_11;
355afbcd
KR
1002 immediate_max = 0x03FF;
1003 goto immediate;
1004
1005 case 'j':
125f0b0d 1006 the_insn.reloc = BFD_RELOC_SPARC_10;
355afbcd
KR
1007 immediate_max = 0x01FF;
1008 goto immediate;
1009
1010 case 'k':
125f0b0d 1011 the_insn.reloc = /* RELOC_WDISP2_14 */ BFD_RELOC_SPARC_WDISP16;
355afbcd
KR
1012 the_insn.pcrel = 1;
1013 goto immediate;
1014
1015 case 'G':
125f0b0d 1016 the_insn.reloc = BFD_RELOC_SPARC_WDISP19;
355afbcd
KR
1017 the_insn.pcrel = 1;
1018 goto immediate;
1019
1020 case 'N':
1021 if (*s == 'p' && s[1] == 'n')
1022 {
1023 s += 2;
1024 continue;
1025 }
1026 break;
1027
1028 case 'T':
1029 if (*s == 'p' && s[1] == 't')
1030 {
1031 s += 2;
1032 continue;
1033 }
1034 break;
1035
1036 case 'z':
1037 if (*s == ' ')
1038 {
1039 ++s;
1040 }
0d44b3d1 1041 if (strncmp (s, "%icc", 4) == 0)
355afbcd 1042 {
0d44b3d1 1043 s += 4;
355afbcd
KR
1044 continue;
1045 }
1046 break;
1047
1048 case 'Z':
1049 if (*s == ' ')
1050 {
1051 ++s;
1052 }
0d44b3d1 1053 if (strncmp (s, "%xcc", 4) == 0)
355afbcd 1054 {
0d44b3d1 1055 s += 4;
355afbcd
KR
1056 continue;
1057 }
1058 break;
1059
1060 case '6':
1061 if (*s == ' ')
1062 {
1063 ++s;
1064 }
0d44b3d1 1065 if (strncmp (s, "%fcc0", 5) == 0)
355afbcd 1066 {
0d44b3d1 1067 s += 5;
355afbcd
KR
1068 continue;
1069 }
1070 break;
1071
1072 case '7':
1073 if (*s == ' ')
1074 {
1075 ++s;
1076 }
0d44b3d1 1077 if (strncmp (s, "%fcc1", 5) == 0)
355afbcd 1078 {
0d44b3d1 1079 s += 5;
355afbcd
KR
1080 continue;
1081 }
1082 break;
1083
1084 case '8':
1085 if (*s == ' ')
1086 {
1087 ++s;
1088 }
0d44b3d1 1089 if (strncmp (s, "%fcc2", 5) == 0)
355afbcd 1090 {
0d44b3d1 1091 s += 5;
355afbcd
KR
1092 continue;
1093 }
1094 break;
1095
1096 case '9':
1097 if (*s == ' ')
1098 {
1099 ++s;
1100 }
0d44b3d1 1101 if (strncmp (s, "%fcc3", 5) == 0)
355afbcd 1102 {
0d44b3d1 1103 s += 5;
355afbcd
KR
1104 continue;
1105 }
1106 break;
1107
1108 case 'P':
1109 if (strncmp (s, "%pc", 3) == 0)
1110 {
1111 s += 3;
1112 continue;
1113 }
1114 break;
1115
1116 case 'W':
1117 if (strncmp (s, "%tick", 5) == 0)
1118 {
1119 s += 5;
1120 continue;
1121 }
1122 break;
1123#endif /* NO_V9 */
1124 /* end-sanitize-v9 */
1125
1126 case '\0': /* end of args */
1127 if (*s == '\0')
1128 {
1129 match = 1;
1130 }
1131 break;
1132
1133 case '+':
1134 if (*s == '+')
1135 {
1136 ++s;
1137 continue;
1138 }
1139 if (*s == '-')
1140 {
1141 continue;
1142 }
1143 break;
1144
1145 case '[': /* these must match exactly */
1146 case ']':
1147 case ',':
1148 case ' ':
1149 if (*s++ == *args)
1150 continue;
1151 break;
1152
1153 case '#': /* must be at least one digit */
1154 if (isdigit (*s++))
1155 {
1156 while (isdigit (*s))
1157 {
1158 ++s;
1159 }
1160 continue;
1161 }
1162 break;
1163
1164 case 'C': /* coprocessor state register */
1165 if (strncmp (s, "%csr", 4) == 0)
1166 {
1167 s += 4;
1168 continue;
1169 }
1170 break;
1171
1172 case 'b': /* next operand is a coprocessor register */
1173 case 'c':
1174 case 'D':
1175 if (*s++ == '%' && *s++ == 'c' && isdigit (*s))
1176 {
1177 mask = *s++;
1178 if (isdigit (*s))
1179 {
1180 mask = 10 * (mask - '0') + (*s++ - '0');
1181 if (mask >= 32)
1182 {
1183 break;
1184 }
1185 }
1186 else
1187 {
1188 mask -= '0';
1189 }
1190 switch (*args)
1191 {
1192
1193 case 'b':
1194 opcode |= mask << 14;
1195 continue;
1196
1197 case 'c':
1198 opcode |= mask;
1199 continue;
1200
1201 case 'D':
1202 opcode |= mask << 25;
1203 continue;
1204 }
1205 }
1206 break;
1207
1208 case 'r': /* next operand must be a register */
1209 case '1':
1210 case '2':
1211 case 'd':
1212 if (*s++ == '%')
1213 {
1214 switch (c = *s++)
1215 {
1216
1217 case 'f': /* frame pointer */
1218 if (*s++ == 'p')
1219 {
1220 mask = 0x1e;
1221 break;
1222 }
1223 goto error;
1224
1225 case 'g': /* global register */
1226 if (isoctal (c = *s++))
1227 {
1228 mask = c - '0';
1229 break;
1230 }
1231 goto error;
1232
1233 case 'i': /* in register */
1234 if (isoctal (c = *s++))
1235 {
1236 mask = c - '0' + 24;
1237 break;
1238 }
1239 goto error;
1240
1241 case 'l': /* local register */
1242 if (isoctal (c = *s++))
1243 {
1244 mask = (c - '0' + 16);
1245 break;
1246 }
1247 goto error;
1248
1249 case 'o': /* out register */
1250 if (isoctal (c = *s++))
1251 {
1252 mask = (c - '0' + 8);
1253 break;
1254 }
1255 goto error;
1256
1257 case 's': /* stack pointer */
1258 if (*s++ == 'p')
1259 {
1260 mask = 0xe;
1261 break;
1262 }
1263 goto error;
1264
1265 case 'r': /* any register */
1266 if (!isdigit (c = *s++))
1267 {
1268 goto error;
1269 }
1270 /* FALLTHROUGH */
1271 case '0':
1272 case '1':
1273 case '2':
1274 case '3':
1275 case '4':
1276 case '5':
1277 case '6':
1278 case '7':
1279 case '8':
1280 case '9':
1281 if (isdigit (*s))
1282 {
1283 if ((c = 10 * (c - '0') + (*s++ - '0')) >= 32)
680227f3 1284 {
680227f3
KR
1285 goto error;
1286 }
355afbcd
KR
1287 }
1288 else
1289 {
1290 c -= '0';
1291 }
1292 mask = c;
1293 break;
1294
1295 default:
1296 goto error;
1297 }
1298 /*
680227f3
KR
1299 * Got the register, now figure out where
1300 * it goes in the opcode.
1301 */
355afbcd
KR
1302 switch (*args)
1303 {
1304
1305 case '1':
1306 opcode |= mask << 14;
1307 continue;
1308
1309 case '2':
1310 opcode |= mask;
1311 continue;
1312
1313 case 'd':
1314 opcode |= mask << 25;
1315 continue;
1316
1317 case 'r':
1318 opcode |= (mask << 25) | (mask << 14);
1319 continue;
1320 }
1321 }
1322 break;
1323
1324 case 'e': /* next operand is a floating point register */
1325 case 'v':
1326 case 'V':
1327
1328 case 'f':
1329 case 'B':
1330 case 'R':
1331
1332 case 'g':
1333 case 'H':
1334 case 'J':
1335 {
1336 char format;
1337
1338 if (*s++ == '%'
355afbcd 1339 && ((format = *s) == 'f')
355afbcd
KR
1340 && isdigit (*++s))
1341 {
355afbcd
KR
1342 for (mask = 0; isdigit (*s); ++s)
1343 {
1344 mask = 10 * mask + (*s - '0');
1345 } /* read the number */
1346
1347 if ((*args == 'v'
1348 || *args == 'B'
1349 || *args == 'H')
1350 && (mask & 1))
1351 {
1352 break;
1353 } /* register must be even numbered */
1354
1355 if ((*args == 'V'
1356 || *args == 'R'
1357 || *args == 'J')
1358 && (mask & 3))
1359 {
1360 break;
1361 } /* register must be multiple of 4 */
1362
125f0b0d 1363/* start-sanitize-v9 */
a79c6033 1364#ifndef NO_V9
125f0b0d 1365 if (mask >= 64)
355afbcd 1366 {
125f0b0d
KR
1367 error_message = ": There are only 64 f registers; [0-63]";
1368 goto error;
1369 } /* on error */
1370 if (mask >= 32)
1371 {
1372 mask -= 31;
1373 } /* wrap high bit */
1374#else
1375/* end-sanitize-v9 */
1376 if (mask >= 32)
1377 {
1378 error_message = ": There are only 32 f registers; [0-31]";
1379 goto error;
1380 } /* on error */
1381/* start-sanitize-v9 */
1382#endif
1383/* end-sanitize-v9 */
1384 }
1385 else
1386 {
1387 break;
1388 } /* if not an 'f' register. */
355afbcd
KR
1389
1390 switch (*args)
1391 {
1392
1393 case 'v':
1394 case 'V':
1395 case 'e':
1396 opcode |= RS1 (mask);
1397 continue;
1398
1399
1400 case 'f':
1401 case 'B':
1402 case 'R':
1403 opcode |= RS2 (mask);
1404 continue;
1405
1406 case 'g':
1407 case 'H':
1408 case 'J':
1409 opcode |= RD (mask);
1410 continue;
1411 } /* pack it in. */
1412
1413 know (0);
1414 break;
1415 } /* float arg */
1416
1417 case 'F':
1418 if (strncmp (s, "%fsr", 4) == 0)
1419 {
1420 s += 4;
1421 continue;
1422 }
1423 break;
1424
1425 case 'h': /* high 22 bits */
428d312b 1426 the_insn.reloc = BFD_RELOC_HI22;
355afbcd
KR
1427 goto immediate;
1428
1429 case 'l': /* 22 bit PC relative immediate */
428d312b 1430 the_insn.reloc = BFD_RELOC_SPARC_WDISP22;
355afbcd
KR
1431 the_insn.pcrel = 1;
1432 goto immediate;
1433
1434 case 'L': /* 30 bit immediate */
428d312b 1435 the_insn.reloc = BFD_RELOC_32_PCREL_S2;
355afbcd
KR
1436 the_insn.pcrel = 1;
1437 goto immediate;
1438
1439 case 'n': /* 22 bit immediate */
428d312b 1440 the_insn.reloc = BFD_RELOC_SPARC22;
355afbcd
KR
1441 goto immediate;
1442
1443 case 'i': /* 13 bit immediate */
428d312b
KR
1444 /* What's the difference between base13 and 13? */
1445 the_insn.reloc = BFD_RELOC_SPARC_BASE13;
355afbcd
KR
1446 immediate_max = 0x0FFF;
1447
1448 /*FALLTHROUGH */
1449
1450 immediate:
1451 if (*s == ' ')
1452 s++;
1453 if (*s == '%')
1454 {
1455 if ((c = s[1]) == 'h' && s[2] == 'i')
1456 {
428d312b 1457 the_insn.reloc = BFD_RELOC_HI22;
355afbcd
KR
1458 s += 3;
1459 }
1460 else if (c == 'l' && s[2] == 'o')
1461 {
428d312b 1462 the_insn.reloc = BFD_RELOC_LO10;
355afbcd
KR
1463 s += 3;
1464 /* start-sanitize-v9 */
9b856b4f 1465#ifndef NO_V9
355afbcd
KR
1466 }
1467 else if (c == 'u'
1468 && s[2] == 'h'
1469 && s[3] == 'i')
1470 {
125f0b0d 1471 the_insn.reloc = BFD_RELOC_SPARC_HH22;
355afbcd 1472 s += 4;
355afbcd
KR
1473 }
1474 else if (c == 'u'
1475 && s[2] == 'l'
1476 && s[3] == 'o')
1477 {
125f0b0d 1478 the_insn.reloc = BFD_RELOC_SPARC_HM10;
355afbcd 1479 s += 4;
9b856b4f 1480#endif /* NO_V9 */
355afbcd
KR
1481 /* end-sanitize-v9 */
1482 }
1483 else
1484 break;
1485 }
1486 /* Note that if the getExpression() fails, we
8fc0776d
JW
1487 will still have created U entries in the
1488 symbol table for the 'symbols' in the input
1489 string. Try not to create U symbols for
1490 registers, etc. */
355afbcd
KR
1491 {
1492 /* This stuff checks to see if the
8fc0776d
JW
1493 expression ends in +%reg If it does,
1494 it removes the register from the
1495 expression, and re-sets 's' to point
1496 to the right place */
355afbcd
KR
1497
1498 char *s1;
1499
1500 for (s1 = s; *s1 && *s1 != ',' && *s1 != ']'; s1++);;
1501
1502 if (s1 != s && isdigit (s1[-1]))
1503 {
1504 if (s1[-2] == '%' && s1[-3] == '+')
1505 {
1506 s1 -= 3;
1507 *s1 = '\0';
1508 (void) getExpression (s);
1509 *s1 = '+';
1510 s = s1;
1511 continue;
1512 }
1513 else if (strchr ("goli0123456789", s1[-2]) && s1[-3] == '%' && s1[-4] == '+')
1514 {
1515 s1 -= 4;
1516 *s1 = '\0';
1517 (void) getExpression (s);
1518 *s1 = '+';
1519 s = s1;
1520 continue;
1521 }
1522 }
1523 }
1524 (void) getExpression (s);
1525 s = expr_end;
1526
1527 /* Check for invalid constant values. Don't
8fc0776d
JW
1528 warn if constant was inside %hi or %lo,
1529 since these truncate the constant to
1530 fit. */
355afbcd 1531 if (immediate_max != 0
428d312b
KR
1532 && the_insn.reloc != BFD_RELOC_LO10
1533 && the_insn.reloc != BFD_RELOC_HI22
355afbcd 1534 /* start-sanitize-v9 */
0cef0e20 1535#ifndef NO_V9
428d312b 1536#ifndef BFD_ASSEMBLER /* the bfd backend doesn't support these relocs yet */
355afbcd
KR
1537 && the_insn.reloc != RELOC_HLO10
1538 && the_insn.reloc != RELOC_HHI22
428d312b 1539#endif
0cef0e20 1540#endif
355afbcd
KR
1541 /* end-sanitize-v9 */
1542 && the_insn.exp.X_add_symbol == 0
5ac34ac3
ILT
1543 && the_insn.exp.X_op_symbol == 0
1544 && the_insn.exp.X_op == O_constant
355afbcd
KR
1545 && (the_insn.exp.X_add_number > immediate_max
1546 || the_insn.exp.X_add_number < ~immediate_max))
1547 as_bad ("constant value must be between %ld and %ld",
1548 ~immediate_max, immediate_max);
1549 /* Reset to prevent extraneous range check. */
1550 immediate_max = 0;
1551
1552 continue;
1553
1554 case 'a':
1555 if (*s++ == 'a')
1556 {
1557 opcode |= ANNUL;
1558 continue;
1559 }
1560 break;
1561
1562 case 'A':
1563 {
ed9638af
KR
1564/* start-sanitize-v9 */
1565#ifdef NO_V9
1566/* end-sanitize-v9 */
355afbcd
KR
1567 char *push = input_line_pointer;
1568 expressionS e;
1569
1570 input_line_pointer = s;
1571
5ac34ac3
ILT
1572 expression (&e);
1573 if (e.X_op == O_constant)
355afbcd
KR
1574 {
1575 opcode |= e.X_add_number << 5;
1576 s = input_line_pointer;
1577 input_line_pointer = push;
1578 continue;
1579 } /* if absolute */
1580
1581 break;
ed9638af
KR
1582/* start-sanitize-v9 */
1583#else
1584 int asi = 0;
1585
1586 /* Parse an asi. */
1587 if (*s == '#')
1588 {
1589 s += 1;
1590 if (!strncmp (s, "ASI_AIUP", 8))
1591 asi = 0x10, s += 8;
1592 else if (!strncmp (s, "ASI_AIUS", 8))
1593 asi = 0x11, s += 8;
1594 else if (!strncmp (s, "ASI_PNF", 7))
1595 asi = 0x82, s += 7;
1596 else if (!strncmp (s, "ASI_SNF", 7))
1597 asi = 0x83, s += 7;
1598 else if (!strncmp (s, "ASI_P", 5))
1599 asi = 0x80, s += 5;
1600 else if (!strncmp (s, "ASI_S", 5))
1601 asi = 0x81, s += 5;
1602 else
1603 {
1604 error_message = ": invalid asi name";
1605 goto error;
1606 }
1607 }
1608 else if (isdigit (*s))
1609 {
1610 char *push = input_line_pointer;
1611 input_line_pointer = s;
1612 asi = get_absolute_expression ();
1613 s = input_line_pointer;
1614 input_line_pointer = push;
1615
1616 if (asi < 0 || asi > 255)
1617 {
1618 error_message = ": invalid asi number";
1619 goto error;
1620 }
1621 }
1622 else
1623 {
1624 error_message = ": unrecognizable asi";
1625 goto error;
1626 }
1627 opcode |= ASI (asi);
1628 continue;
1629#endif
1630/* end-sanitize-v9 */
355afbcd
KR
1631 } /* alternate space */
1632
1633 case 'p':
1634 if (strncmp (s, "%psr", 4) == 0)
1635 {
1636 s += 4;
1637 continue;
1638 }
1639 break;
1640
1641 case 'q': /* floating point queue */
1642 if (strncmp (s, "%fq", 3) == 0)
1643 {
1644 s += 3;
1645 continue;
1646 }
1647 break;
1648
1649 case 'Q': /* coprocessor queue */
1650 if (strncmp (s, "%cq", 3) == 0)
1651 {
1652 s += 3;
1653 continue;
1654 }
1655 break;
1656
1657 case 'S':
1658 if (strcmp (str, "set") == 0)
1659 {
1660 special_case = SPECIAL_CASE_SET;
1661 continue;
1662 }
1663 else if (strncmp (str, "fdiv", 4) == 0)
1664 {
1665 special_case = SPECIAL_CASE_FDIV;
1666 continue;
1667 }
1668 break;
1669
1670 /* start-sanitize-v9 */
680227f3 1671#ifndef NO_V9
355afbcd
KR
1672 case 'o':
1673 if (strncmp (s, "%asi", 4) != 0)
1674 break;
1675 s += 4;
1676 continue;
1677
1678 case 's':
1679 if (strncmp (s, "%fprs", 5) != 0)
1680 break;
1681 s += 5;
1682 continue;
1683
1684 case 'E':
1685 if (strncmp (s, "%ccr", 4) != 0)
1686 break;
1687 s += 4;
1688 continue;
680227f3 1689#endif /* NO_V9 */
355afbcd 1690 /* end-sanitize-v9 */
680227f3 1691
355afbcd
KR
1692 case 't':
1693 if (strncmp (s, "%tbr", 4) != 0)
1694 break;
1695 s += 4;
1696 continue;
1697
1698 case 'w':
1699 if (strncmp (s, "%wim", 4) != 0)
1700 break;
1701 s += 4;
1702 continue;
1703
1704 case 'y':
1705 if (strncmp (s, "%y", 2) != 0)
1706 break;
1707 s += 2;
1708 continue;
1709
1710 default:
1711 as_fatal ("failed sanity check.");
1712 } /* switch on arg code */
1713 break;
1714 } /* for each arg that we expect */
1715 error:
1716 if (match == 0)
1717 {
1718 /* Args don't match. */
1719 if (((unsigned) (&insn[1] - sparc_opcodes)) < NUMOPCODES
1720 && !strcmp (insn->name, insn[1].name))
1721 {
1722 ++insn;
1723 s = argsStart;
1724 continue;
1725 }
1726 else
1727 {
1728 as_bad ("Illegal operands%s", error_message);
1729 return;
1730 }
1731 }
1732 else
1733 {
1734 if (insn->architecture > current_architecture)
1735 {
1736 if ((!architecture_requested || warn_on_bump)
1737 &&
1738 /* start-sanitize-v9 */
680227f3 1739#ifndef NO_V9
355afbcd
KR
1740 !ARCHITECTURES_CONFLICT_P (current_architecture,
1741 insn->architecture)
680227f3 1742#else
355afbcd
KR
1743 /* end-sanitize-v9 */
1744 1
1745 /* start-sanitize-v9 */
680227f3 1746#endif
355afbcd
KR
1747 /* end-sanitize-v9 */
1748 )
1749 {
1750 if (warn_on_bump)
1751 {
1752 as_warn ("architecture bumped from \"%s\" to \"%s\" on \"%s\"",
1753 architecture_pname[current_architecture],
1754 architecture_pname[insn->architecture],
1755 str);
1756 } /* if warning */
fecd2382 1757
355afbcd
KR
1758 current_architecture = insn->architecture;
1759 }
1760 else
1761 {
1762 as_bad ("architecture mismatch on \"%s\" (\"%s\"). current architecture is \"%s\"",
1763 str,
1764 architecture_pname[insn->architecture],
1765 architecture_pname[current_architecture]);
1766 return;
1767 } /* if bump ok else error */
1768 } /* if architecture higher */
1769 } /* if no match */
1770
1771 break;
1772 } /* forever looking for a match */
1773
1774 the_insn.opcode = opcode;
1775 return;
1776} /* sparc_ip() */
1777
1778static int
1779getExpression (str)
1780 char *str;
fecd2382 1781{
355afbcd
KR
1782 char *save_in;
1783 segT seg;
1784
1785 save_in = input_line_pointer;
1786 input_line_pointer = str;
428d312b
KR
1787 seg = expression (&the_insn.exp);
1788 if (seg == absolute_section
1789 || seg == text_section
1790 || seg == data_section
1791 || seg == bss_section
5ac34ac3 1792 || seg == undefined_section)
428d312b
KR
1793 /* ok */;
1794 else
355afbcd 1795 {
355afbcd
KR
1796 the_insn.error = "bad segment";
1797 expr_end = input_line_pointer;
1798 input_line_pointer = save_in;
1799 return 1;
1800 }
1801 expr_end = input_line_pointer;
1802 input_line_pointer = save_in;
1803 return 0;
1804} /* getExpression() */
fecd2382
RP
1805
1806
1807/*
1808 This is identical to the md_atof in m68k.c. I think this is right,
1809 but I'm not sure.
355afbcd 1810
fecd2382
RP
1811 Turn a string in input_line_pointer into a floating point constant of type
1812 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1813 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
1814 */
1815
1816/* Equal to MAX_PRECISION in atof-ieee.c */
1817#define MAX_LITTLENUMS 6
1818
355afbcd
KR
1819char *
1820md_atof (type, litP, sizeP)
1821 char type;
1822 char *litP;
1823 int *sizeP;
fecd2382 1824{
355afbcd
KR
1825 int prec;
1826 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1827 LITTLENUM_TYPE *wordP;
1828 char *t;
1829 char *atof_ieee ();
1830
1831 switch (type)
1832 {
1833
1834 case 'f':
1835 case 'F':
1836 case 's':
1837 case 'S':
1838 prec = 2;
1839 break;
1840
1841 case 'd':
1842 case 'D':
1843 case 'r':
1844 case 'R':
1845 prec = 4;
1846 break;
1847
1848 case 'x':
1849 case 'X':
1850 prec = 6;
1851 break;
1852
1853 case 'p':
1854 case 'P':
1855 prec = 6;
1856 break;
1857
1858 default:
1859 *sizeP = 0;
1860 return "Bad call to MD_ATOF()";
1861 }
1862 t = atof_ieee (input_line_pointer, type, words);
1863 if (t)
1864 input_line_pointer = t;
1865 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1866 for (wordP = words; prec--;)
1867 {
125f0b0d 1868 md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
355afbcd
KR
1869 litP += sizeof (LITTLENUM_TYPE);
1870 }
ed9638af
KR
1871 return 0;
1872}
fecd2382
RP
1873
1874/*
1875 * Write out big-endian.
1876 */
355afbcd
KR
1877void
1878md_number_to_chars (buf, val, n)
1879 char *buf;
125f0b0d 1880 valueT val;
355afbcd 1881 int n;
fecd2382 1882{
355afbcd
KR
1883
1884 switch (n)
1885 {
125f0b0d
KR
1886 /* start-sanitize-v9 */
1887 case 8:
1888 *buf++ = val >> 56;
1889 *buf++ = val >> 48;
1890 *buf++ = val >> 40;
1891 *buf++ = val >> 32;
1892 /* end-sanitize-v9 */
355afbcd
KR
1893 case 4:
1894 *buf++ = val >> 24;
1895 *buf++ = val >> 16;
1896 case 2:
1897 *buf++ = val >> 8;
1898 case 1:
1899 *buf = val;
1900 break;
1901
1902 default:
1903 as_fatal ("failed sanity check.");
1904 }
1905 return;
1906} /* md_number_to_chars() */
fecd2382
RP
1907
1908/* Apply a fixS to the frags, now that we know the value it ought to
1909 hold. */
1910
428d312b
KR
1911#ifdef BFD_ASSEMBLER
1912int
1913#else
355afbcd 1914void
428d312b
KR
1915#endif
1916md_apply_fix (fixP, value)
355afbcd 1917 fixS *fixP;
428d312b 1918#ifdef BFD_ASSEMBLER
125f0b0d 1919 valueT *value;
428d312b
KR
1920#else
1921 long value;
1922#endif
fecd2382 1923{
355afbcd 1924 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
125f0b0d 1925 offsetT val;
428d312b
KR
1926
1927#ifdef BFD_ASSEMBLER
1928 val = *value;
1929#else
1930 val = value;
1931#endif
355afbcd 1932
428d312b
KR
1933#ifdef BFD_ASSEMBLER
1934 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
1935#else
355afbcd 1936 assert (fixP->fx_r_type < NO_RELOC);
428d312b 1937#endif
355afbcd
KR
1938
1939 fixP->fx_addnumber = val; /* Remember value for emit_reloc */
1940
1941 /*
428d312b
KR
1942 * This is a hack. There should be a better way to
1943 * handle this.
1944 */
1945 if (fixP->fx_r_type == BFD_RELOC_32_PCREL_S2 && fixP->fx_addsy)
355afbcd
KR
1946 {
1947 val += fixP->fx_where + fixP->fx_frag->fr_address;
1948 }
1949
1950 switch (fixP->fx_r_type)
1951 {
1952
428d312b 1953 case BFD_RELOC_32:
355afbcd
KR
1954 buf[0] = 0; /* val >> 24; */
1955 buf[1] = 0; /* val >> 16; */
1956 buf[2] = 0; /* val >> 8; */
1957 buf[3] = 0; /* val; */
1958 break;
1959
428d312b 1960 case BFD_RELOC_32_PCREL_S2:
355afbcd
KR
1961 val = (val >>= 2) + 1;
1962 buf[0] |= (val >> 24) & 0x3f;
1963 buf[1] = (val >> 16);
1964 buf[2] = val >> 8;
1965 buf[3] = val;
1966 break;
1967
1968 /* start-sanitize-v9 */
839df5c3 1969#ifndef NO_V9
125f0b0d 1970 case BFD_RELOC_SPARC_11:
355afbcd
KR
1971 if (((val > 0) && (val & ~0x7ff))
1972 || ((val < 0) && (~(val - 1) & ~0x7ff)))
1973 {
1974 as_bad ("relocation overflow.");
1975 } /* on overflow */
1976
1977 buf[2] |= (val >> 8) & 0x7;
1978 buf[3] = val & 0xff;
1979 break;
1980
125f0b0d 1981 case BFD_RELOC_SPARC_10:
355afbcd
KR
1982 if (((val > 0) && (val & ~0x3ff))
1983 || ((val < 0) && (~(val - 1) & ~0x3ff)))
1984 {
1985 as_bad ("relocation overflow.");
1986 } /* on overflow */
1987
1988 buf[2] |= (val >> 8) & 0x3;
1989 buf[3] = val & 0xff;
1990 break;
1991
125f0b0d 1992 case BFD_RELOC_SPARC_WDISP16:
355afbcd
KR
1993 if (((val > 0) && (val & ~0x3fffc))
1994 || ((val < 0) && (~(val - 1) & ~0x3fffc)))
1995 {
1996 as_bad ("relocation overflow.");
1997 } /* on overflow */
1998
1999 val = (val >>= 2) + 1;
8fc0776d 2000 buf[1] |= ((val >> 14) & 0x3) << 4;
355afbcd
KR
2001 buf[2] |= (val >> 8) & 0x3f;
2002 buf[3] = val & 0xff;
2003 break;
2004
125f0b0d 2005 case BFD_RELOC_SPARC_WDISP19:
355afbcd
KR
2006 if (((val > 0) && (val & ~0x1ffffc))
2007 || ((val < 0) && (~(val - 1) & ~0x1ffffc)))
2008 {
2009 as_bad ("relocation overflow.");
2010 } /* on overflow */
2011
2012 val = (val >>= 2) + 1;
2013 buf[1] |= (val >> 16) & 0x7;
2014 buf[2] = (val >> 8) & 0xff;
2015 buf[3] = val & 0xff;
2016 break;
2017
125f0b0d 2018 case BFD_RELOC_SPARC_HH22:
355afbcd
KR
2019 val >>= 32;
2020 /* intentional fallthrough */
839df5c3 2021#endif /* NO_V9 */
355afbcd
KR
2022 /* end-sanitize-v9 */
2023
125f0b0d
KR
2024 /* start-sanitize-v9 */
2025#ifndef NO_V9
2026 case BFD_RELOC_SPARC_LM22:
2027#endif
2028 /* end-sanitize-v9 */
428d312b 2029 case BFD_RELOC_HI22:
355afbcd
KR
2030 if (!fixP->fx_addsy)
2031 {
2032 buf[1] |= (val >> 26) & 0x3f;
2033 buf[2] = val >> 18;
2034 buf[3] = val >> 10;
2035 }
2036 else
2037 {
2038 buf[2] = 0;
2039 buf[3] = 0;
2040 }
2041 break;
2042
428d312b 2043 case BFD_RELOC_SPARC22:
355afbcd
KR
2044 if (val & ~0x003fffff)
2045 {
2046 as_bad ("relocation overflow");
2047 } /* on overflow */
2048 buf[1] |= (val >> 16) & 0x3f;
2049 buf[2] = val >> 8;
2050 buf[3] = val & 0xff;
2051 break;
2052
428d312b 2053 case BFD_RELOC_SPARC13:
355afbcd
KR
2054 if (val & ~0x00001fff)
2055 {
2056 as_bad ("relocation overflow");
2057 } /* on overflow */
2058 buf[2] |= (val >> 8) & 0x1f;
2059 buf[3] = val & 0xff;
2060 break;
2061
2062 /* start-sanitize-v9 */
9b856b4f 2063#ifndef NO_V9
125f0b0d 2064 case BFD_RELOC_SPARC_HM10:
355afbcd
KR
2065 val >>= 32;
2066 /* intentional fallthrough */
9b856b4f 2067#endif /* NO_V9 */
355afbcd
KR
2068 /* end-sanitize-v9 */
2069
428d312b 2070 case BFD_RELOC_LO10:
355afbcd
KR
2071 if (!fixP->fx_addsy)
2072 {
2073 buf[2] |= (val >> 8) & 0x03;
2074 buf[3] = val;
2075 }
2076 else
2077 buf[3] = 0;
2078 break;
428d312b 2079 case BFD_RELOC_SPARC_BASE13:
125f0b0d
KR
2080 if (((val > 0) && (val & ~(offsetT)0x00001fff))
2081 || ((val < 0) && (~(val - 1) & ~(offsetT)0x00001fff)))
355afbcd
KR
2082 {
2083 as_bad ("relocation overflow");
125f0b0d 2084 }
355afbcd
KR
2085 buf[2] |= (val >> 8) & 0x1f;
2086 buf[3] = val;
2087 break;
2088
428d312b 2089 case BFD_RELOC_SPARC_WDISP22:
355afbcd
KR
2090 val = (val >>= 2) + 1;
2091 /* FALLTHROUGH */
428d312b 2092 case BFD_RELOC_SPARC_BASE22:
355afbcd
KR
2093 buf[1] |= (val >> 16) & 0x3f;
2094 buf[2] = val >> 8;
2095 buf[3] = val;
2096 break;
2097
428d312b 2098 case BFD_RELOC_NONE:
355afbcd 2099 default:
428d312b 2100 as_bad ("bad or unhandled relocation type: 0x%02x", fixP->fx_r_type);
355afbcd
KR
2101 break;
2102 }
428d312b
KR
2103
2104#ifdef BFD_ASSEMBLER
2105 return 1;
2106#endif
2107}
fecd2382
RP
2108
2109/* should never be called for sparc */
355afbcd
KR
2110void
2111md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
2112 char *ptr;
125f0b0d
KR
2113 addressT from_addr;
2114 addressT to_addr;
355afbcd
KR
2115 fragS *frag;
2116 symbolS *to_symbol;
fecd2382 2117{
355afbcd 2118 as_fatal ("sparc_create_short_jmp\n");
428d312b
KR
2119}
2120
2121#ifdef BFD_ASSEMBLER
2122
2123/* Translate internal representation of relocation info to BFD target
2124 format. */
2125arelent *
2126tc_gen_reloc (section, fixp)
2127 asection *section;
2128 fixS *fixp;
2129{
2130 arelent *reloc;
2131 bfd_reloc_code_real_type code;
2132
2133 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
2134 assert (reloc != 0);
2135
2136 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
2137 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2138 if (fixp->fx_pcrel == 0)
2139 reloc->addend = fixp->fx_addnumber;
2140 else
ed9638af
KR
2141 switch (OUTPUT_FLAVOR)
2142 {
2143 case bfd_target_elf_flavour:
2144 reloc->addend = 0;
2145 break;
2146 case bfd_target_aout_flavour:
2147 reloc->addend = - reloc->address;
2148 break;
2149 default:
2150 /* What's a good default here? Is there any?? */
2151 abort ();
2152 }
428d312b 2153
428d312b
KR
2154 switch (fixp->fx_r_type)
2155 {
2156 case BFD_RELOC_32:
2157 case BFD_RELOC_HI22:
2158 case BFD_RELOC_LO10:
2159 case BFD_RELOC_32_PCREL_S2:
2160 case BFD_RELOC_SPARC_BASE13:
ed9638af 2161 case BFD_RELOC_SPARC_WDISP22:
125f0b0d
KR
2162 /* start-sanitize-v9 */
2163 case BFD_RELOC_SPARC_10:
2164 case BFD_RELOC_SPARC_11:
2165 case BFD_RELOC_SPARC_HH22:
2166 case BFD_RELOC_SPARC_HM10:
2167 case BFD_RELOC_SPARC_LM22:
2168 case BFD_RELOC_SPARC_PC_HH22:
2169 case BFD_RELOC_SPARC_PC_HM10:
2170 case BFD_RELOC_SPARC_PC_LM22:
2171 /* end-sanitize-v9 */
428d312b
KR
2172 code = fixp->fx_r_type;
2173 break;
2174 default:
2175 abort ();
2176 }
2177 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
2178 assert (reloc->howto != 0);
2179
2180 return reloc;
2181}
2182
2183#else
fecd2382
RP
2184
2185/* Translate internal representation of relocation info to target format.
355afbcd 2186
fecd2382
RP
2187 On sparc: first 4 bytes are normal unsigned long address, next three
2188 bytes are index, most sig. byte first. Byte 7 is broken up with
2189 bit 7 as external, bits 6 & 5 unused, and the lower
2190 five bits as relocation type. Next 4 bytes are long addend. */
2191/* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
680227f3 2192void
355afbcd 2193tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
680227f3
KR
2194 char *where;
2195 fixS *fixP;
2196 relax_addressT segment_address_in_file;
fecd2382 2197{
355afbcd
KR
2198 long r_index;
2199 long r_extern;
2200 long r_addend = 0;
2201 long r_address;
2202
2203 know (fixP->fx_addsy);
2204
2205 if (!S_IS_DEFINED (fixP->fx_addsy))
2206 {
2207 r_extern = 1;
2208 r_index = fixP->fx_addsy->sy_number;
2209 }
2210 else
2211 {
2212 r_extern = 0;
2213 r_index = S_GET_TYPE (fixP->fx_addsy);
2214 }
2215
2216 /* this is easy */
2217 md_number_to_chars (where,
2218 r_address = fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
2219 4);
2220
2221 /* now the fun stuff */
2222 where[4] = (r_index >> 16) & 0x0ff;
2223 where[5] = (r_index >> 8) & 0x0ff;
2224 where[6] = r_index & 0x0ff;
2225 where[7] = ((r_extern << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F);
2226
2227 /* Also easy */
2228 if (fixP->fx_addsy->sy_frag)
2229 {
2230 r_addend = fixP->fx_addsy->sy_frag->fr_address;
2231 }
2232
2233 if (fixP->fx_pcrel)
2234 {
2235 r_addend += fixP->fx_offset - r_address;
2236 }
2237 else
2238 {
2239 r_addend = fixP->fx_addnumber;
2240 }
2241
2242 md_number_to_chars (&where[8], r_addend, 4);
2243
2244 return;
2245} /* tc_aout_fix_to_chars() */
428d312b 2246#endif
fecd2382
RP
2247
2248/* should never be called for sparc */
355afbcd
KR
2249void
2250md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
2251 char *ptr;
125f0b0d 2252 addressT from_addr, to_addr;
355afbcd
KR
2253 fragS *frag;
2254 symbolS *to_symbol;
fecd2382 2255{
355afbcd
KR
2256 as_fatal ("sparc_create_long_jump\n");
2257} /* md_create_long_jump() */
fecd2382
RP
2258
2259/* should never be called for sparc */
355afbcd
KR
2260int
2261md_estimate_size_before_relax (fragP, segtype)
2262 fragS *fragP;
2263 segT segtype;
fecd2382 2264{
355afbcd
KR
2265 as_fatal ("sparc_estimate_size_before_relax\n");
2266 return (1);
2267} /* md_estimate_size_before_relax() */
fecd2382
RP
2268
2269#if 0
2270/* for debugging only */
355afbcd
KR
2271static void
2272print_insn (insn)
2273 struct sparc_it *insn;
fecd2382 2274{
355afbcd
KR
2275 char *Reloc[] =
2276 {
2277 "RELOC_8",
2278 "RELOC_16",
2279 "RELOC_32",
2280 "RELOC_DISP8",
2281 "RELOC_DISP16",
2282 "RELOC_DISP32",
2283 "RELOC_WDISP30",
2284 "RELOC_WDISP22",
2285 "RELOC_HI22",
2286 "RELOC_22",
2287 "RELOC_13",
2288 "RELOC_LO10",
2289 "RELOC_SFA_BASE",
2290 "RELOC_SFA_OFF13",
2291 "RELOC_BASE10",
2292 "RELOC_BASE13",
2293 "RELOC_BASE22",
2294 "RELOC_PC10",
2295 "RELOC_PC22",
2296 "RELOC_JMP_TBL",
2297 "RELOC_SEGOFF16",
2298 "RELOC_GLOB_DAT",
2299 "RELOC_JMP_SLOT",
2300 "RELOC_RELATIVE",
2301 "NO_RELOC"
2302 };
2303
2304 if (insn->error)
2305 {
2306 fprintf (stderr, "ERROR: %s\n");
2307 }
2308 fprintf (stderr, "opcode=0x%08x\n", insn->opcode);
2309 fprintf (stderr, "reloc = %s\n", Reloc[insn->reloc]);
2310 fprintf (stderr, "exp = {\n");
2311 fprintf (stderr, "\t\tX_add_symbol = %s\n",
2312 ((insn->exp.X_add_symbol != NULL)
2313 ? ((S_GET_NAME (insn->exp.X_add_symbol) != NULL)
2314 ? S_GET_NAME (insn->exp.X_add_symbol)
2315 : "???")
2316 : "0"));
2317 fprintf (stderr, "\t\tX_sub_symbol = %s\n",
5ac34ac3
ILT
2318 ((insn->exp.X_op_symbol != NULL)
2319 ? (S_GET_NAME (insn->exp.X_op_symbol)
2320 ? S_GET_NAME (insn->exp.X_op_symbol)
355afbcd
KR
2321 : "???")
2322 : "0"));
2323 fprintf (stderr, "\t\tX_add_number = %d\n",
2324 insn->exp.X_add_number);
2325 fprintf (stderr, "}\n");
2326 return;
2327} /* print_insn() */
2328
fecd2382
RP
2329#endif
2330
839df5c3
RP
2331/*
2332 * md_parse_option
2333 * Invocation line includes a switch not recognized by the base assembler.
2334 * See if it's a processor-specific option. These are:
2335 *
2336 * -bump
2337 * Warn on architecture bumps. See also -A.
2338 *
680227f3 2339 * -Av6, -Av7, -Av8, -Asparclite
839df5c3
RP
2340 * Select the architecture. Instructions or features not
2341 * supported by the selected architecture cause fatal errors.
2342 *
2343 * The default is to start at v6, and bump the architecture up
2344 * whenever an instruction is seen at a higher level.
2345 *
2346 * If -bump is specified, a warning is printing when bumping to
2347 * higher levels.
2348 *
2349 * If an architecture is specified, all instructions must match
2350 * that architecture. Any higher level instructions are flagged
355afbcd 2351 * as errors.
839df5c3
RP
2352 *
2353 * if both an architecture and -bump are specified, the
2354 * architecture starts at the specified level, but bumps are
2355 * warnings.
2356 *
680227f3 2357 * start-sanitize-v9
162e3485
KR
2358 * -Av9
2359 * Another architecture switch.
2360 *
2361 * Note:
680227f3
KR
2362 * Bumping between incompatible architectures is always an
2363 * error. For example, from sparclite to v9.
2364 * end-sanitize-v9
839df5c3 2365 */
162e3485 2366
355afbcd
KR
2367int
2368md_parse_option (argP, cntP, vecP)
2369 char **argP;
2370 int *cntP;
2371 char ***vecP;
fecd2382 2372{
355afbcd
KR
2373 char *p;
2374 const char **arch;
2375
2376 if (!strcmp (*argP, "bump"))
2377 {
2378 warn_on_bump = 1;
2379
2380 }
2381 else if (**argP == 'A')
2382 {
2383 p = (*argP) + 1;
2384
2385 for (arch = architecture_pname; *arch != NULL; ++arch)
2386 {
2387 if (strcmp (p, *arch) == 0)
2388 {
2389 break;
2390 } /* found a match */
2391 } /* walk the pname table */
2392
2393 if (*arch == NULL)
2394 {
2395 as_bad ("unknown architecture: %s", p);
2396 }
2397 else
2398 {
2399 current_architecture = (enum sparc_architecture) (arch - architecture_pname);
2400 architecture_requested = 1;
839df5c3 2401 }
355afbcd 2402 }
ed9638af
KR
2403#ifdef OBJ_ELF
2404 else if (**argP == 'V')
2405 {
2406 extern void print_version_id ();
2407 print_version_id ();
2408 }
2409 else if (**argP == 'Q')
2410 {
2411 /* Qy - do emit .comment
2412 Qn - do not emit .comment */
2413 }
2414 else if (**argP == 's')
2415 {
2416 /* use .stab instead of .stab.excl */
2417 }
2418#endif
355afbcd
KR
2419 else
2420 {
2421 /* Unknown option */
2422 (*argP)++;
2423 return 0;
2424 }
2425 **argP = '\0'; /* Done parsing this switch */
2426 return 1;
2427} /* md_parse_option() */
fecd2382
RP
2428
2429/* We have no need to default values of symbols. */
2430
2431/* ARGSUSED */
355afbcd
KR
2432symbolS *
2433md_undefined_symbol (name)
2434 char *name;
fecd2382 2435{
355afbcd
KR
2436 return 0;
2437} /* md_undefined_symbol() */
fecd2382
RP
2438
2439/* Parse an operand that is machine-specific.
2440 We just return without modifying the expression if we have nothing
2441 to do. */
2442
2443/* ARGSUSED */
355afbcd
KR
2444void
2445md_operand (expressionP)
2446 expressionS *expressionP;
fecd2382 2447{
428d312b 2448}
fecd2382
RP
2449
2450/* Round up a section size to the appropriate boundary. */
125f0b0d 2451valueT
355afbcd
KR
2452md_section_align (segment, size)
2453 segT segment;
125f0b0d 2454 valueT size;
fecd2382 2455{
428d312b
KR
2456 /* Round all sects to multiple of 8 */
2457 return (size + 7) & ~7;
2458}
fecd2382
RP
2459
2460/* Exactly what point is a PC-relative offset relative TO?
2461 On the sparc, they're relative to the address of the offset, plus
2462 its size. This gets us to the following instruction.
2463 (??? Is this right? FIXME-SOON) */
355afbcd
KR
2464long
2465md_pcrel_from (fixP)
2466 fixS *fixP;
fecd2382 2467{
355afbcd 2468 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
428d312b 2469}
fecd2382 2470
428d312b 2471#ifndef BFD_ASSEMBLER
355afbcd
KR
2472void
2473tc_aout_pre_write_hook (headers)
2474 object_headers *headers;
584a0f78 2475{
355afbcd 2476 H_SET_VERSION (headers, 1);
428d312b
KR
2477}
2478#endif
584a0f78 2479
8b228fe9 2480/* end of tc-sparc.c */
This page took 0.190178 seconds and 4 git commands to generate.