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