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