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