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