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