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