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