tc-visium.c revision 1.1.1.8 1 /* This is the machine dependent code of the Visium Assembler.
2
3 Copyright (C) 2005-2026 Free Software Foundation, Inc.
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
21
22 #include "as.h"
23 #include "safe-ctype.h"
24 #include "subsegs.h"
25 #include "obstack.h"
26
27 #include "opcode/visium.h"
28 #include "elf/visium.h"
29 #include "dwarf2dbg.h"
30 #include "dw2gencfi.h"
31
32 /* Relocations and fixups:
33
34 There are two different cases where an instruction or data
35 directive operand requires relocation, or fixup.
36
37 1. Relative branch instructions, take an 16-bit signed word
38 offset. The formula for computing the offset is this:
39
40 offset = (destination - pc) / 4
41
42 Branch instructions never branch to a label not declared
43 locally, so the actual offset can always be computed by the assembler.
44 However, we provide a relocation type to support this.
45
46 2. Load literal instructions, such as MOVIU, which take a 16-bit
47 literal operand. The literal may be the top or bottom half of
48 a 32-bit value computed by the assembler, or by the linker. We provide
49 two relocation types here.
50
51 3. Data items (long, word and byte) preset with a value computed by
52 the linker. */
53
54
55 /* This string holds the chars that always start a comment. If the
56 pre-processor is disabled, these aren't very useful. */
57 const char comment_chars[] = "!;";
58
59 /* This array holds the chars that only start a comment at the beginning
60 of a line. If the line seems to have the form '# 123 filename' .line
61 and .file directives will appear in the pre-processed output. Note that
62 input_file.c hand checks for '#' at the beginning of the first line of
63 the input file. This is because the compiler outputs #NO_APP at the
64 beginning of its output. Also note that comments like this one will
65 always work. */
66 const char line_comment_chars[] = "#!;";
67 const char line_separator_chars[] = "";
68
69 /* Chars that can be used to separate mantissa from exponent in floating point
70 numbers. */
71 const char EXP_CHARS[] = "eE";
72
73 /* Chars that mean this number is a floating point constant, as in
74 "0f12.456" or "0d1.2345e12".
75
76 ...Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
77 changed in read.c. Ideally it shouldn't have to know about it at all,
78 but nothing is ideal around here. */
79 const char FLT_CHARS[] = "rRsSfFdDxXeE";
80
81 /* The size of a relocation record. */
82 const int md_reloc_size = 8;
83
84 /* The architecture for which we are assembling. */
85 enum visium_arch_val
86 {
87 VISIUM_ARCH_DEF,
88 VISIUM_ARCH_MCM24,
89 VISIUM_ARCH_MCM,
90 VISIUM_ARCH_GR6
91 };
92
93 static enum visium_arch_val visium_arch = VISIUM_ARCH_DEF;
94
95 /* The opcode architecture for which we are assembling. In contrast to the
96 previous one, this only determines which instructions are supported. */
97 static enum visium_opcode_arch_val visium_opcode_arch = VISIUM_OPCODE_ARCH_DEF;
98
99 /* Flags to set in the ELF header e_flags field. */
100 static flagword visium_flags = 0;
101
102 /* More than this number of nops in an alignment op gets a branch instead. */
103 static unsigned int nop_limit = 5;
104
105
106 /* Translate internal representation of relocation info to BFD target
107 format. */
108 arelent *
109 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
110 {
111 arelent *reloc;
112 bfd_reloc_code_real_type code;
113
114 reloc = notes_alloc (sizeof (arelent));
115 reloc->sym_ptr_ptr = notes_alloc (sizeof (asymbol *));
116 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
117 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
118
119 switch (fixp->fx_r_type)
120 {
121 case BFD_RELOC_8:
122 case BFD_RELOC_16:
123 case BFD_RELOC_32:
124 case BFD_RELOC_8_PCREL:
125 case BFD_RELOC_16_PCREL:
126 case BFD_RELOC_32_PCREL:
127 case BFD_RELOC_VISIUM_HI16:
128 case BFD_RELOC_VISIUM_LO16:
129 case BFD_RELOC_VISIUM_IM16:
130 case BFD_RELOC_VISIUM_REL16:
131 case BFD_RELOC_VISIUM_HI16_PCREL:
132 case BFD_RELOC_VISIUM_LO16_PCREL:
133 case BFD_RELOC_VISIUM_IM16_PCREL:
134 case BFD_RELOC_VTABLE_INHERIT:
135 case BFD_RELOC_VTABLE_ENTRY:
136 code = fixp->fx_r_type;
137 break;
138 default:
139 as_bad_where (fixp->fx_file, fixp->fx_line,
140 "internal error: unknown relocation type %d (`%s')",
141 fixp->fx_r_type,
142 bfd_get_reloc_code_name (fixp->fx_r_type));
143 return 0;
144 }
145
146 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
147 if (reloc->howto == 0)
148 {
149 as_bad_where (fixp->fx_file, fixp->fx_line,
150 "internal error: can't export reloc type %d (`%s')",
151 fixp->fx_r_type, bfd_get_reloc_code_name (code));
152 return 0;
153 }
154
155 /* Write the addend. */
156 if (reloc->howto->pc_relative == 0)
157 reloc->addend = fixp->fx_addnumber;
158 else
159 reloc->addend = fixp->fx_offset;
160
161 return reloc;
162 }
163
164 static void visium_rdata (int);
165
166 static void visium_update_parity_bit (char *);
167 static char *parse_exp (char *, expressionS *);
168
169 /* This table describes all the machine specific pseudo-ops the assembler
170 has to support, and that aren't handled elsewhere. The fields are:
171
172 1: Pseudo-op name without dot.
173 2: Function to call to execute this pseudo-op.
174 3: Integer arg to pass to the function. */
175 const pseudo_typeS md_pseudo_table[] =
176 {
177 {"align", s_align_bytes, 0},
178 {"noopt", s_ignore, 0},
179 {"optim", s_ignore, 0},
180 {"rdata", visium_rdata, 0},
181 {"rodata", visium_rdata, 0},
182 {0, 0, 0}
183 };
184
185
186 static void
187 visium_rdata (int xxx)
188 {
189 char *save_line = input_line_pointer;
190 static char section[] = ".rodata\n";
191
192 /* Just pretend this is .section .rodata */
193 input_line_pointer = section;
194 obj_elf_section (xxx);
195 input_line_pointer = save_line;
196 }
197
198 /* Align a section. */
199 valueT
200 md_section_align (asection *seg, valueT addr)
201 {
202 int align = bfd_section_alignment (seg);
203
204 return (addr + ((valueT) 1 << align) - 1) & -((valueT) 1 << align);
205 }
206
207 void
208 md_number_to_chars (char *buf, valueT val, int n)
209 {
210 number_to_chars_bigendian (buf, val, n);
211 }
212
213 symbolS *
214 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
215 {
216 return 0;
217 }
218
219 /* The parse options. */
220 const char md_shortopts[] = "m:";
221
222 const struct option md_longopts[] =
223 {
224 {NULL, no_argument, NULL, 0}
225 };
226
227 const size_t md_longopts_size = sizeof (md_longopts);
228
229 struct visium_option_table
230 {
231 char *option; /* Option name to match. */
232 char *help; /* Help information. */
233 int *var; /* Variable to change. */
234 int value; /* To what to change it. */
235 char *deprecated; /* If non-null, print this message. */
236 };
237
238 static struct visium_option_table visium_opts[] =
239 {
240 {NULL, NULL, NULL, 0, NULL}
241 };
242
243 struct visium_arch_option_table
244 {
245 const char *name;
246 enum visium_arch_val value;
247 };
248
249 static struct visium_arch_option_table visium_archs[] =
250 {
251 {"mcm24", VISIUM_ARCH_MCM24},
252 {"mcm", VISIUM_ARCH_MCM},
253 {"gr5", VISIUM_ARCH_MCM},
254 {"gr6", VISIUM_ARCH_GR6},
255 };
256
257 struct visium_long_option_table
258 {
259 const char *option; /* Substring to match. */
260 const char *help; /* Help information. */
261 int (*func) (const char *subopt); /* Function to decode sub-option. */
262 const char *deprecated; /* If non-null, print this message. */
263 };
264
265 static int
266 visium_parse_arch (const char *str)
267 {
268 unsigned int i;
269
270 if (strlen (str) == 0)
271 {
272 as_bad ("missing architecture name `%s'", str);
273 return 0;
274 }
275
276 for (i = 0; i < ARRAY_SIZE (visium_archs); i++)
277 if (strcmp (visium_archs[i].name, str) == 0)
278 {
279 visium_arch = visium_archs[i].value;
280 return 1;
281 }
282
283 as_bad ("unknown architecture `%s'\n", str);
284 return 0;
285 }
286
287 static struct visium_long_option_table visium_long_opts[] =
288 {
289 {"mtune=", "<arch_name>\t assemble for architecture <arch name>",
290 visium_parse_arch, NULL},
291 {NULL, NULL, NULL, NULL}
292 };
293
294 int
295 md_parse_option (int c, const char *arg)
296 {
297 struct visium_option_table *opt;
298 struct visium_long_option_table *lopt;
299
300 switch (c)
301 {
302 case 'a':
303 /* Listing option. Just ignore these, we don't support additional
304 ones. */
305 return 0;
306
307 default:
308 for (opt = visium_opts; opt->option != NULL; opt++)
309 {
310 if (c == opt->option[0]
311 && ((arg == NULL && opt->option[1] == 0)
312 || strcmp (arg, opt->option + 1) == 0))
313 {
314 /* If the option is deprecated, tell the user. */
315 if (opt->deprecated != NULL)
316 as_tsktsk ("option `-%c%s' is deprecated: %s", c,
317 arg ? arg : "", opt->deprecated);
318
319 if (opt->var != NULL)
320 *opt->var = opt->value;
321
322 return 1;
323 }
324 }
325
326 for (lopt = visium_long_opts; lopt->option != NULL; lopt++)
327 {
328 /* These options are expected to have an argument. */
329 if (c == lopt->option[0]
330 && arg != NULL
331 && strncmp (arg, lopt->option + 1,
332 strlen (lopt->option + 1)) == 0)
333 {
334 /* If the option is deprecated, tell the user. */
335 if (lopt->deprecated != NULL)
336 as_tsktsk ("option `-%c%s' is deprecated: %s", c, arg,
337 lopt->deprecated);
338
339 /* Call the sup-option parser. */
340 return lopt->func (arg + strlen (lopt->option) - 1);
341 }
342 }
343
344 return 0;
345 }
346
347 return 1;
348 }
349
350 void
351 md_show_usage (FILE * fp)
352 {
353 struct visium_option_table *opt;
354 struct visium_long_option_table *lopt;
355
356 fprintf (fp, " Visium-specific assembler options:\n");
357
358 for (opt = visium_opts; opt->option != NULL; opt++)
359 if (opt->help != NULL)
360 fprintf (fp, " -%-23s%s\n", opt->option, opt->help);
361
362 for (lopt = visium_long_opts; lopt->option != NULL; lopt++)
363 if (lopt->help != NULL)
364 fprintf (fp, " -%s%s\n", lopt->option, lopt->help);
365
366 }
367
368 /* Interface to relax_segment. */
369
370 /* Return the estimate of the size of a machine dependent frag
371 before any relaxing is done. It may also create any necessary
372 relocations. */
373 int
374 md_estimate_size_before_relax (fragS * fragP,
375 segT segment ATTRIBUTE_UNUSED)
376 {
377 fragP->fr_var = 4;
378 return 4;
379 }
380
381 /* Get the address of a symbol during relaxation. From tc-arm.c. */
382 static addressT
383 relaxed_symbol_addr (fragS *fragp, long stretch)
384 {
385 fragS *sym_frag;
386 addressT addr;
387 symbolS *sym;
388
389 sym = fragp->fr_symbol;
390 sym_frag = symbol_get_frag (sym);
391 know (S_GET_SEGMENT (sym) != absolute_section
392 || sym_frag == &zero_address_frag);
393 addr = S_GET_VALUE (sym) + fragp->fr_offset;
394
395 /* If frag has yet to be reached on this pass, assume it will
396 move by STRETCH just as we did. If this is not so, it will
397 be because some frag between grows, and that will force
398 another pass. */
399 if (stretch != 0
400 && sym_frag->relax_marker != fragp->relax_marker)
401 {
402 fragS *f;
403
404 /* Adjust stretch for any alignment frag. Note that if have
405 been expanding the earlier code, the symbol may be
406 defined in what appears to be an earlier frag. FIXME:
407 This doesn't handle the fr_subtype field, which specifies
408 a maximum number of bytes to skip when doing an
409 alignment. */
410 for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
411 {
412 if (f->fr_type == rs_align || f->fr_type == rs_align_code)
413 {
414 if (stretch < 0)
415 stretch = -(-stretch & ~((1ul << f->fr_offset) - 1));
416 else
417 stretch &= ~((1ul << f->fr_offset) - 1);
418 if (stretch == 0)
419 break;
420 }
421 }
422 if (f != NULL)
423 addr += stretch;
424 }
425
426 return addr;
427 }
428
429 /* Relax a machine dependent frag. This returns the amount by which
430 the current size of the frag should change. */
431 int
432 visium_relax_frag (asection *sec, fragS *fragP, long stretch)
433 {
434 int old_size, new_size;
435 addressT addr;
436
437 /* We only handle relaxation for the BRR instruction. */
438 gas_assert (fragP->fr_subtype == mode_ci);
439
440 if (!S_IS_DEFINED (fragP->fr_symbol)
441 || sec != S_GET_SEGMENT (fragP->fr_symbol)
442 || S_IS_WEAK (fragP->fr_symbol))
443 return 0;
444
445 old_size = fragP->fr_var;
446 addr = relaxed_symbol_addr (fragP, stretch);
447
448 /* If the target is the address of the instruction, we'll insert a NOP. */
449 if (addr == fragP->fr_address + fragP->fr_fix)
450 new_size = 8;
451 else
452 new_size = 4;
453
454 fragP->fr_var = new_size;
455 return new_size - old_size;
456 }
457
458 /* Convert a machine dependent frag. */
459 void
460 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED,
461 fragS * fragP)
462 {
463 char *buf = &fragP->fr_literal[0] + fragP->fr_fix;
464 expressionS exp;
465 fixS *fixP;
466
467 /* We only handle relaxation for the BRR instruction. */
468 gas_assert (fragP->fr_subtype == mode_ci);
469
470 /* Insert the NOP if requested. */
471 if (fragP->fr_var == 8)
472 {
473 memcpy (buf + 4, buf, 4);
474 memset (buf, 0, 4);
475 fragP->fr_fix += 4;
476 }
477
478 exp.X_op = O_symbol;
479 exp.X_add_symbol = fragP->fr_symbol;
480 exp.X_add_number = fragP->fr_offset;
481
482 /* Now we can create the relocation at the correct offset. */
483 fixP = fix_new_exp (fragP, fragP->fr_fix, 4, &exp, 1, BFD_RELOC_VISIUM_REL16);
484 fixP->fx_file = fragP->fr_file;
485 fixP->fx_line = fragP->fr_line;
486 fragP->fr_fix += 4;
487 fragP->fr_var = 0;
488 }
489
490 /* The location from which a PC relative jump should be calculated,
491 given a PC relative jump reloc. */
492 long
493 visium_pcrel_from_section (fixS *fixP, segT sec)
494 {
495 if (fixP->fx_addsy != NULL
496 && (!S_IS_DEFINED (fixP->fx_addsy)
497 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
498 {
499 /* The symbol is undefined (or is defined but not in this section).
500 Let the linker figure it out. */
501 return 0;
502 }
503
504 /* Return the address of the instruction. */
505 return fixP->fx_where + fixP->fx_frag->fr_address;
506 }
507
508 /* Indicate whether a fixup against a locally defined
509 symbol should be adjusted to be against the section
510 symbol. */
511 bool
512 visium_fix_adjustable (fixS *fix)
513 {
514 /* We need the symbol name for the VTABLE entries. */
515 return (fix->fx_r_type != BFD_RELOC_VTABLE_INHERIT
516 && fix->fx_r_type != BFD_RELOC_VTABLE_ENTRY);
517 }
518
519 /* Update the parity bit of the 4-byte instruction in BUF. */
520 static void
521 visium_update_parity_bit (char *buf)
522 {
523 int p1 = (buf[0] & 0x7f) ^ buf[1] ^ buf[2] ^ buf[3];
524 int p2 = 0;
525 int i;
526
527 for (i = 1; i <= 8; i++)
528 {
529 p2 ^= (p1 & 1);
530 p1 >>= 1;
531 }
532
533 buf[0] = (buf[0] & 0x7f) | ((p2 << 7) & 0x80);
534 }
535
536 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
537 of an rs_align_code fragment. */
538 void
539 visium_handle_align (fragS *fragP)
540 {
541 valueT count
542 = fragP->fr_next->fr_address - (fragP->fr_address + fragP->fr_fix);
543 valueT fix = count & 3;
544 char *p = fragP->fr_literal + fragP->fr_fix;
545
546 if (fix)
547 {
548 memset (p, 0, fix);
549 p += fix;
550 count -= fix;
551 fragP->fr_fix += fix;
552 }
553
554 if (count == 0)
555 return;
556
557 if (count > 4 * nop_limit && count <= 131068)
558 {
559 /* Make a branch, then follow with nops. */
560 md_number_to_chars (p, 0x78000000 + (count >> 2), 4);
561 visium_update_parity_bit (p);
562 p += 4;
563 fragP->fr_fix += 4;
564 }
565
566 *p = 0;
567 }
568
569 /* Apply a fixS to the frags, now that we know the value it ought to
570 hold. */
571 void
572 md_apply_fix (fixS * fixP, valueT * value, segT segment)
573 {
574 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
575 offsetT val;
576 long insn;
577
578 val = *value;
579
580 gas_assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
581
582 /* Remember value for tc_gen_reloc. */
583 fixP->fx_addnumber = val;
584
585 /* Since DIFF_EXPR_OK is defined, .-foo gets turned into PC
586 relative relocs. If this has happened, a non-PC relative
587 reloc must be reinstalled with its PC relative version here. */
588 if (fixP->fx_pcrel)
589 {
590 switch (fixP->fx_r_type)
591 {
592 case BFD_RELOC_8:
593 fixP->fx_r_type = BFD_RELOC_8_PCREL;
594 break;
595 case BFD_RELOC_16:
596 fixP->fx_r_type = BFD_RELOC_16_PCREL;
597 break;
598 case BFD_RELOC_32:
599 fixP->fx_r_type = BFD_RELOC_32_PCREL;
600 break;
601 case BFD_RELOC_VISIUM_HI16:
602 fixP->fx_r_type = BFD_RELOC_VISIUM_HI16_PCREL;
603 break;
604 case BFD_RELOC_VISIUM_LO16:
605 fixP->fx_r_type = BFD_RELOC_VISIUM_LO16_PCREL;
606 break;
607 case BFD_RELOC_VISIUM_IM16:
608 fixP->fx_r_type = BFD_RELOC_VISIUM_IM16_PCREL;
609 break;
610 default:
611 break;
612 }
613 }
614
615 /* If this is a data relocation, just output VAL. */
616 switch (fixP->fx_r_type)
617 {
618 case BFD_RELOC_8:
619 case BFD_RELOC_8_PCREL:
620 md_number_to_chars (buf, val, 1);
621 break;
622 case BFD_RELOC_16:
623 case BFD_RELOC_16_PCREL:
624 md_number_to_chars (buf, val, 2);
625 break;
626 case BFD_RELOC_32:
627 case BFD_RELOC_32_PCREL:
628 md_number_to_chars (buf, val, 4);
629 break;
630 case BFD_RELOC_VTABLE_INHERIT:
631 case BFD_RELOC_VTABLE_ENTRY:
632 fixP->fx_done = 0;
633 break;
634 default:
635 /* It's a relocation against an instruction. */
636 insn = bfd_getb32 (buf);
637
638 switch (fixP->fx_r_type)
639 {
640 case BFD_RELOC_VISIUM_REL16:
641 if (fixP->fx_addsy == NULL
642 || (S_IS_DEFINED (fixP->fx_addsy)
643 && S_GET_SEGMENT (fixP->fx_addsy) == segment))
644 {
645 if (val > 0x1fffc || val < -0x20000)
646 as_bad_where
647 (fixP->fx_file, fixP->fx_line,
648 "16-bit word displacement out of range: value = %d",
649 (int) val);
650 val = (val >> 2);
651
652 insn = (insn & 0xffff0000) | (val & 0x0000ffff);
653 }
654 break;
655
656 case BFD_RELOC_VISIUM_HI16:
657 case BFD_RELOC_VISIUM_HI16_PCREL:
658 if (fixP->fx_addsy == NULL)
659 insn = (insn & 0xffff0000) | ((val >> 16) & 0x0000ffff);
660 break;
661
662 case BFD_RELOC_VISIUM_LO16:
663 case BFD_RELOC_VISIUM_LO16_PCREL:
664 if (fixP->fx_addsy == NULL)
665 insn = (insn & 0xffff0000) | (val & 0x0000ffff);
666 break;
667
668 case BFD_RELOC_VISIUM_IM16:
669 case BFD_RELOC_VISIUM_IM16_PCREL:
670 if (fixP->fx_addsy == NULL)
671 {
672 if ((val & 0xffff0000) != 0)
673 as_bad_where (fixP->fx_file, fixP->fx_line,
674 "16-bit immediate out of range: value = %d",
675 (int) val);
676
677 insn = (insn & 0xffff0000) | val;
678 }
679 break;
680
681 case BFD_RELOC_NONE:
682 default:
683 as_bad_where (fixP->fx_file, fixP->fx_line,
684 "bad or unhandled relocation type: 0x%02x",
685 (unsigned int) fixP->fx_r_type);
686 break;
687 }
688
689 bfd_putb32 (insn, buf);
690 visium_update_parity_bit (buf);
691 break;
692 }
693
694 /* Are we finished with this relocation now? */
695 if (fixP->fx_addsy == NULL)
696 fixP->fx_done = 1;
697 }
698
699 char *
700 parse_exp (char *s, expressionS * op)
701 {
702 char *save = input_line_pointer;
703 char *new;
704
705 if (!s)
706 {
707 return s;
708 }
709
710 input_line_pointer = s;
711 expression (op);
712 new = input_line_pointer;
713 input_line_pointer = save;
714 return new;
715 }
716
717 /* If the given string is a Visium opcode mnemonic return the code
718 otherwise return -1. Use binary chop to find matching entry. */
719 static int
720 get_opcode (int *code, enum addressing_mode *mode, char *flags, char *mnem)
721 {
722 int l = 0;
723 int r = sizeof (opcode_table) / sizeof (struct opcode_entry) - 1;
724
725 do
726 {
727 int mid = (l + r) / 2;
728 int ans = strcmp (mnem, opcode_table[mid].mnem);
729
730 if (ans < 0)
731 r = mid - 1;
732 else if (ans > 0)
733 l = mid + 1;
734 else
735 {
736 *code = opcode_table[mid].code;
737 *mode = opcode_table[mid].mode;
738 *flags = opcode_table[mid].flags;
739
740 return 0;
741 }
742 }
743 while (l <= r);
744
745 return -1;
746 }
747
748 /* This function is called when the assembler starts up. It is called
749 after the options have been parsed and the output file has been
750 opened. */
751 void
752 md_begin (void)
753 {
754 switch (visium_arch)
755 {
756 case VISIUM_ARCH_DEF:
757 break;
758 case VISIUM_ARCH_MCM24:
759 visium_opcode_arch = VISIUM_OPCODE_ARCH_GR5;
760 visium_flags |= EF_VISIUM_ARCH_MCM24;
761 break;
762 case VISIUM_ARCH_MCM:
763 visium_opcode_arch = VISIUM_OPCODE_ARCH_GR5;
764 visium_flags |= EF_VISIUM_ARCH_MCM;
765 break;
766 case VISIUM_ARCH_GR6:
767 visium_opcode_arch = VISIUM_OPCODE_ARCH_GR6;
768 visium_flags |= EF_VISIUM_ARCH_MCM | EF_VISIUM_ARCH_GR6;
769 nop_limit = 2;
770 break;
771 default:
772 gas_assert (0);
773 }
774
775 bfd_set_private_flags (stdoutput, visium_flags);
776 }
777
778 /* This is identical to the md_atof in m68k.c. I think this is right,
779 but I'm not sure.
780
781 Turn a string in input_line_pointer into a floating point constant of type
782 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
783 emitted is stored in *sizeP . An error message is returned,
784 or NULL on OK. */
785
786 const char *
787 md_atof (int type, char *litP, int *sizeP)
788 {
789 int i, prec;
790 LITTLENUM_TYPE words[MAX_LITTLENUMS];
791 char *t;
792
793 switch (type)
794 {
795 case 'f':
796 case 'F':
797 case 's':
798 case 'S':
799 prec = 2;
800 break;
801
802 case 'd':
803 case 'D':
804 case 'r':
805 case 'R':
806 prec = 4;
807 break;
808
809 case 'x':
810 case 'X':
811 prec = 6;
812 break;
813
814 case 'p':
815 case 'P':
816 prec = 6;
817 break;
818
819 default:
820 *sizeP = 0;
821 return _("Bad call to MD_ATOF()");
822 }
823
824 t = atof_ieee (input_line_pointer, type, words);
825 if (t)
826 input_line_pointer = t;
827 *sizeP = prec * sizeof (LITTLENUM_TYPE);
828
829 if (target_big_endian)
830 {
831 for (i = 0; i < prec; i++)
832 {
833 md_number_to_chars (litP, words[i], sizeof (LITTLENUM_TYPE));
834 litP += sizeof (LITTLENUM_TYPE);
835 }
836 }
837 else
838 {
839 for (i = prec - 1; i >= 0; i--)
840 {
841 md_number_to_chars (litP, words[i], sizeof (LITTLENUM_TYPE));
842 litP += sizeof (LITTLENUM_TYPE);
843 }
844 }
845
846 return 0;
847 }
848
849 static inline char *
850 skip_space (char *s)
851 {
852 while (is_whitespace (*s))
853 ++s;
854
855 return s;
856 }
857
858 static int
859 parse_gen_reg (char **sptr, int *rptr)
860 {
861 char *s = skip_space (*sptr);
862 char buf[10];
863 int cnt;
864 int l, r;
865
866 cnt = 0;
867 memset (buf, '\0', 10);
868 while ((ISALNUM (*s)) && cnt < 10)
869 buf[cnt++] = TOLOWER (*s++);
870
871 l = 0;
872 r = sizeof (gen_reg_table) / sizeof (struct reg_entry) - 1;
873
874 do
875 {
876 int mid = (l + r) / 2;
877 int ans = strcmp (buf, gen_reg_table[mid].name);
878
879 if (ans < 0)
880 r = mid - 1;
881 else if (ans > 0)
882 l = mid + 1;
883 else
884 {
885 *rptr = gen_reg_table[mid].code;
886 *sptr = s;
887 return 0;
888 }
889 }
890 while (l <= r);
891
892 return -1;
893 }
894
895 static int
896 parse_fp_reg (char **sptr, int *rptr)
897 {
898 char *s = skip_space (*sptr);
899 char buf[10];
900 int cnt;
901 int l, r;
902
903 cnt = 0;
904 memset (buf, '\0', 10);
905 while ((ISALNUM (*s)) && cnt < 10)
906 buf[cnt++] = TOLOWER (*s++);
907
908 l = 0;
909 r = sizeof (fp_reg_table) / sizeof (struct reg_entry) - 1;
910
911 do
912 {
913 int mid = (l + r) / 2;
914 int ans = strcmp (buf, fp_reg_table[mid].name);
915
916 if (ans < 0)
917 r = mid - 1;
918 else if (ans > 0)
919 l = mid + 1;
920 else
921 {
922 *rptr = fp_reg_table[mid].code;
923 *sptr = s;
924 return 0;
925 }
926 }
927 while (l <= r);
928
929 return -1;
930 }
931
932 static int
933 parse_cc (char **sptr, int *rptr)
934 {
935 char *s = skip_space (*sptr);
936 char buf[10];
937 int cnt;
938 int l, r;
939
940 cnt = 0;
941 memset (buf, '\0', 10);
942 while ((ISALNUM (*s)) && cnt < 10)
943 buf[cnt++] = TOLOWER (*s++);
944
945 l = 0;
946 r = sizeof (cc_table) / sizeof (struct cc_entry) - 1;
947
948 do
949 {
950 int mid = (l + r) / 2;
951 int ans = strcmp (buf, cc_table[mid].name);
952
953 if (ans < 0)
954 r = mid - 1;
955 else if (ans > 0)
956 l = mid + 1;
957 else
958 {
959 *rptr = cc_table[mid].code;
960 *sptr = s;
961 return 0;
962 }
963 }
964 while (l <= r);
965
966 return -1;
967 }
968
969 /* Previous dest is the destination register number of the instruction
970 before the current one. */
971 static int previous_dest = 0;
972 static int previous_mode = 0;
973 static int condition_code = 0;
974 static int this_dest = 0;
975 static int this_mode = 0;
976
977
978 /* This is the main function in this file. It takes a line of assembly language
979 source code and assembles it. Note, labels and pseudo ops have already
980 been removed, so too has leading white space. */
981 void
982 md_assemble (char *str0)
983 {
984 char *str = str0;
985 int cnt;
986 char mnem[10];
987 int opcode;
988 enum addressing_mode amode;
989 char arch_flags;
990 int ans;
991
992 char *output;
993 int reloc = 0;
994 relax_substateT relax = 0;
995 expressionS e1;
996 int r1, r2, r3;
997 int cc;
998 int indx;
999
1000 /* Initialize the expression. */
1001 e1.X_op = O_absent;
1002
1003 /* Initialize destination register.
1004 If the instruction we just looked at is in the delay slot of an
1005 unconditional branch, then there is no index hazard. */
1006 if ((previous_mode == mode_cad || previous_mode == mode_ci)
1007 && condition_code == 15)
1008 this_dest = 0;
1009
1010 previous_dest = this_dest;
1011 previous_mode = this_mode;
1012 this_dest = 0;
1013
1014 /* Drop leading whitespace (probably not required). */
1015 while (is_whitespace (*str))
1016 str++;
1017
1018 /* Get opcode mnemonic and make sure it's in lower case. */
1019 cnt = 0;
1020 memset (mnem, '\0', 10);
1021 while ((ISALNUM (*str) || *str == '.' || *str == '_') && cnt < 10)
1022 mnem[cnt++] = TOLOWER (*str++);
1023
1024 /* Look up mnemonic in opcode table, and get the code,
1025 the instruction format, and the flags that indicate
1026 which family members support this mnemonic. */
1027 if (get_opcode (&opcode, &amode, &arch_flags, mnem) < 0)
1028 {
1029 as_bad ("Unknown instruction mnemonic `%s'", mnem);
1030 return;
1031 }
1032
1033 if ((VISIUM_OPCODE_ARCH_MASK (visium_opcode_arch) & arch_flags) == 0)
1034 {
1035 as_bad ("Architecture mismatch on `%s'", mnem);
1036 return;
1037 }
1038
1039 this_mode = amode;
1040
1041 switch (amode)
1042 {
1043 case mode_d:
1044 /* register :=
1045 Example:
1046 readmda r1 */
1047 ans = parse_gen_reg (&str, &r1);
1048 if (ans < 0)
1049 {
1050 as_bad ("Dest register required");
1051 return;
1052 }
1053 opcode |= (r1 << 10);
1054 this_dest = r1;
1055 break;
1056
1057 case mode_a:
1058 /* op= register
1059 Example: asld r1 */
1060 ans = parse_gen_reg (&str, &r1);
1061 if (ans < 0)
1062 {
1063 as_bad ("SourceA register required");
1064 return;
1065 }
1066 opcode |= (r1 << 16);
1067 break;
1068
1069 case mode_ab:
1070 /* register * register
1071 Example:
1072 mults r1,r2 */
1073 ans = parse_gen_reg (&str, &r1);
1074 if (ans < 0)
1075 {
1076 as_bad ("SourceA register required");
1077 return;
1078 }
1079 str = skip_space (str);
1080 if (*str == ',')
1081 {
1082 str++;
1083 ans = parse_gen_reg (&str, &r2);
1084 if (ans < 0)
1085 {
1086 as_bad ("SourceB register required");
1087 return;
1088 }
1089 opcode |= (r1 << 16) | (r2 << 4);
1090 }
1091 else
1092 {
1093 as_bad ("SourceB register required");
1094 return;
1095 }
1096 break;
1097
1098 case mode_da:
1099 /* register := register
1100 Example:
1101 extb.l r1,r2 */
1102 ans = parse_gen_reg (&str, &r1);
1103 if (ans < 0)
1104 {
1105 as_bad ("Dest register required");
1106 return;
1107 }
1108 str = skip_space (str);
1109 if (*str == ',')
1110 {
1111 str++;
1112 ans = parse_gen_reg (&str, &r2);
1113 if (ans < 0)
1114 {
1115 as_bad ("SourceA register required");
1116 return;
1117 }
1118 opcode |= (r1 << 10) | (r2 << 16);
1119 }
1120 else
1121 {
1122 as_bad ("SourceB register required");
1123 return;
1124 }
1125 this_dest = r1;
1126 break;
1127
1128 case mode_dab:
1129 /* register := register * register
1130 Example:
1131 add.l r1,r2,r3 */
1132 ans = parse_gen_reg (&str, &r1);
1133 if (ans < 0)
1134 {
1135 as_bad ("Dest register required");
1136 return;
1137 }
1138 str = skip_space (str);
1139 if (*str == ',')
1140 {
1141 str++;
1142 ans = parse_gen_reg (&str, &r2);
1143 if (ans < 0)
1144 {
1145 as_bad ("SourceA register required");
1146 return;
1147 }
1148 str = skip_space (str);
1149 if (*str == ',')
1150 {
1151 str++;
1152 ans = parse_gen_reg (&str, &r3);
1153 if (ans < 0)
1154 {
1155 as_bad ("SourceB register required");
1156 return;
1157 }
1158
1159 /* Got three regs, assemble instruction. */
1160 opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
1161 }
1162 else
1163 {
1164 as_bad ("SourceA register required");
1165 return;
1166 }
1167 }
1168 else
1169 {
1170 as_bad ("Dest register required");
1171 return;
1172 }
1173 this_dest = r1;
1174 break;
1175
1176 case mode_iab:
1177 /* 5-bit immediate * register * register
1178 Example:
1179 eamwrite 3,r1,r2 */
1180 str = parse_exp (str, &e1);
1181 str = skip_space (str);
1182 if (e1.X_op != O_absent && *str == ',')
1183 {
1184 int eam_op = e1.X_add_number;
1185
1186 str = skip_space (str + 1);
1187 ans = parse_gen_reg (&str, &r2);
1188 if (ans < 0)
1189 {
1190 as_bad ("SourceA register required");
1191 return;
1192 }
1193 str = skip_space (str);
1194 if (*str == ',')
1195 {
1196 str++;
1197 ans = parse_gen_reg (&str, &r3);
1198 if (ans < 0)
1199 {
1200 as_bad ("SourceB register required");
1201 return;
1202 }
1203
1204 /* Got three operands, assemble instruction. */
1205 if (eam_op < 0 || eam_op > 31)
1206 {
1207 as_bad ("eam_op out of range");
1208 }
1209 opcode |= ((eam_op & 0x1f) << 10) | (r2 << 16) | (r3 << 4);
1210 }
1211 }
1212 else
1213 {
1214 as_bad ("EAM_OP required");
1215 return;
1216 }
1217 break;
1218
1219 case mode_0ab:
1220 /* zero * register * register
1221 Example:
1222 cmp.l r1,r2 */
1223 ans = parse_gen_reg (&str, &r1);
1224 if (ans < 0)
1225 {
1226 as_bad ("SourceA register required");
1227 return;
1228 }
1229 str = skip_space (str);
1230 if (*str == ',')
1231 {
1232 str++;
1233 ans = parse_gen_reg (&str, &r2);
1234 if (ans < 0)
1235 {
1236 as_bad ("SourceB register required");
1237 return;
1238 }
1239 opcode |= (r1 << 16) | (r2 << 4);
1240 }
1241 else
1242 {
1243 as_bad ("SourceB register required");
1244 return;
1245 }
1246 break;
1247
1248 case mode_da0:
1249 /* register * register * zero
1250 Example:
1251 move.l r1,r2 */
1252 ans = parse_gen_reg (&str, &r1);
1253 if (ans < 0)
1254 {
1255 as_bad ("Dest register required");
1256 return;
1257 }
1258 str = skip_space (str);
1259 if (*str == ',')
1260 {
1261 str++;
1262 ans = parse_gen_reg (&str, &r2);
1263 if (ans < 0)
1264 {
1265 as_bad ("SourceA register required");
1266 return;
1267 }
1268 opcode |= (r1 << 10) | (r2 << 16);
1269 }
1270 else
1271 {
1272 as_bad ("SourceA register required");
1273 return;
1274 }
1275 this_dest = r1;
1276 break;
1277
1278 case mode_cad:
1279 /* condition * register * register
1280 Example:
1281 bra tr,r1,r2 */
1282 ans = parse_cc (&str, &cc);
1283 if (ans < 0)
1284 {
1285 as_bad ("condition code required");
1286 return;
1287 }
1288
1289 str = skip_space (str);
1290 if (*str == ',')
1291 {
1292 str = skip_space (str + 1);
1293 ans = parse_gen_reg (&str, &r2);
1294 if (ans < 0)
1295 {
1296 as_bad ("SourceA register required");
1297 return;
1298 }
1299 str = skip_space (str);
1300 if (*str == ',')
1301 {
1302 str++;
1303 ans = parse_gen_reg (&str, &r3);
1304 if (ans < 0)
1305 {
1306 as_bad ("Dest register required");
1307 return;
1308 }
1309
1310 /* Got three operands, assemble instruction. */
1311 opcode |= (cc << 27) | (r2 << 16) | (r3 << 10);
1312 }
1313 else
1314 {
1315 as_bad ("Dest register required");
1316 return;
1317 }
1318 }
1319 else
1320 {
1321 as_bad ("SourceA register required");
1322 return;
1323 }
1324
1325 if (previous_mode == mode_cad || previous_mode == mode_ci)
1326 as_bad ("branch instruction in delay slot");
1327
1328 /* For the GR6, BRA insns must be aligned on 64-bit boundaries. */
1329 if (visium_arch == VISIUM_ARCH_GR6)
1330 do_align (3, NULL, 0, 0);
1331
1332 this_dest = r3;
1333 condition_code = cc;
1334 break;
1335
1336 case mode_das:
1337 /* register := register * 5-bit immediate/register shift count
1338 Example:
1339 asl.l r1,r2,4 */
1340 ans = parse_gen_reg (&str, &r1);
1341 if (ans < 0)
1342 {
1343 as_bad ("Dest register required");
1344 return;
1345 }
1346 str = skip_space (str);
1347 if (*str == ',')
1348 {
1349 str++;
1350 ans = parse_gen_reg (&str, &r2);
1351 if (ans < 0)
1352 {
1353 as_bad ("SourceA register required");
1354 return;
1355 }
1356 str = skip_space (str);
1357 if (*str == ',')
1358 {
1359 str++;
1360 ans = parse_gen_reg (&str, &r3);
1361 if (ans == 0)
1362 {
1363 opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
1364 }
1365 else
1366 {
1367 str = parse_exp (str, &e1);
1368 if (e1.X_op == O_constant)
1369 {
1370 int imm = e1.X_add_number;
1371
1372 if (imm < 0 || imm > 31)
1373 as_bad ("immediate value out of range");
1374
1375 opcode |= ((r1 << 10) | (r2 << 16) | (1 << 9)
1376 | ((imm & 0x1f) << 4));
1377 }
1378 else
1379 {
1380 as_bad ("immediate operand required");
1381 return;
1382 }
1383 }
1384 }
1385 }
1386 else
1387 {
1388 as_bad ("SourceA register required");
1389 return;
1390 }
1391 this_dest = r1;
1392 break;
1393
1394 case mode_di:
1395 /* register := 5-bit immediate
1396 Example:
1397 eamread r1,3 */
1398 ans = parse_gen_reg (&str, &r1);
1399 if (ans < 0)
1400 {
1401 as_bad ("Dest register required");
1402 return;
1403 }
1404 str = skip_space (str);
1405 if (*str == ',')
1406 {
1407 str++;
1408 str = parse_exp (str, &e1);
1409 if (e1.X_op == O_constant)
1410 {
1411 int opnd2 = e1.X_add_number;
1412
1413 if (opnd2 < 0 || opnd2 > 31)
1414 {
1415 as_bad ("immediate operand out of range");
1416 return;
1417 }
1418 opcode |= (r1 << 10) | ((opnd2 & 0x1f) << 4);
1419 }
1420 else
1421 {
1422 as_bad ("immediate operand required");
1423 return;
1424 }
1425 }
1426 else
1427 {
1428 as_bad ("immediate operand required");
1429 return;
1430 }
1431 this_dest = r1;
1432 break;
1433
1434 case mode_ir:
1435 /* 5-bit immediate * register, e.g. trace 1,r1 */
1436 str = parse_exp (str, &e1);
1437 str = skip_space (str);
1438 if (e1.X_op == O_constant && *str == ',')
1439 {
1440 int opnd1 = e1.X_add_number;
1441
1442 str = skip_space (str + 1);
1443 ans = parse_gen_reg (&str, &r2);
1444 if (ans < 0)
1445 {
1446 as_bad ("SourceA register required");
1447 return;
1448 }
1449
1450 /* Got two operands, assemble instruction. */
1451 if (opnd1 < 0 || opnd1 > 31)
1452 {
1453 as_bad ("1st operand out of range");
1454 }
1455 opcode |= ((opnd1 & 0x1f) << 10) | (r2 << 16);
1456 }
1457 else
1458 {
1459 as_bad ("Immediate operand required");
1460 return;
1461 }
1462 break;
1463
1464 case mode_ai:
1465 /* register *= 16-bit unsigned immediate
1466 Example:
1467 addi r1,123 */
1468 ans = parse_gen_reg (&str, &r1);
1469 if (ans < 0)
1470 {
1471 as_bad ("Dest register required");
1472 return;
1473 }
1474 opcode |= (r1 << 16);
1475
1476 str = skip_space (str);
1477 if (*str != ',')
1478 {
1479 as_bad ("immediate value missing");
1480 return;
1481 }
1482 this_dest = r1;
1483 /* Fall through. */
1484
1485 case mode_i:
1486 /* MOVIL/WRTL traditionally get an implicit "%l" applied
1487 to their immediate value. For other opcodes, unless
1488 the immediate value is decorated with "%u" or "%l"
1489 it must be in the range 0 .. 65535. */
1490 if ((opcode & 0x7fe00000) == 0x04800000
1491 || (opcode & 0x7fe00000) == 0x05000000)
1492 reloc = BFD_RELOC_VISIUM_LO16;
1493 else
1494 reloc = BFD_RELOC_VISIUM_IM16;
1495
1496 str = skip_space (str + 1);
1497
1498 if (*str == '%')
1499 {
1500 if (str[1] == 'u')
1501 reloc = BFD_RELOC_VISIUM_HI16;
1502 else if (str[1] == 'l')
1503 reloc = BFD_RELOC_VISIUM_LO16;
1504 else
1505 {
1506 as_bad ("bad char after %%");
1507 return;
1508 }
1509
1510 str += 2;
1511 }
1512 str = parse_exp (str, &e1);
1513 if (e1.X_op != O_absent)
1514 {
1515 if (e1.X_op == O_constant)
1516 {
1517 int imm = e1.X_add_number;
1518
1519 if (reloc == BFD_RELOC_VISIUM_HI16)
1520 opcode |= ((imm >> 16) & 0xffff);
1521 else if (reloc == BFD_RELOC_VISIUM_LO16)
1522 opcode |= (imm & 0xffff);
1523 else
1524 {
1525 if (imm < 0 || imm > 0xffff)
1526 as_bad ("immediate value out of range");
1527
1528 opcode |= (imm & 0xffff);
1529 }
1530 /* No relocation is needed. */
1531 reloc = 0;
1532 }
1533 }
1534 else
1535 {
1536 as_bad ("immediate value missing");
1537 return;
1538 }
1539 break;
1540
1541 case mode_bax:
1542 /* register * register * 5-bit immediate,
1543 SourceB * SourceA * Index
1544 Examples
1545 write.l (r1),r2
1546 write.l 3(r1),r2 */
1547 str = skip_space (str);
1548
1549 indx = 0;
1550 if (*str != '(')
1551 {
1552 str = parse_exp (str, &e1);
1553 if (e1.X_op == O_constant)
1554 {
1555 indx = e1.X_add_number;
1556
1557 if (indx < 0 || indx > 31)
1558 {
1559 as_bad ("Index out of range");
1560 return;
1561 }
1562 }
1563 else
1564 {
1565 as_bad ("Index(SourceA) required");
1566 return;
1567 }
1568 }
1569
1570 str = skip_space (str);
1571
1572 if (*str != '(')
1573 {
1574 as_bad ("Index(SourceA) required");
1575 return;
1576 }
1577
1578 str = skip_space (str + 1);
1579
1580 ans = parse_gen_reg (&str, &r1);
1581 if (ans < 0)
1582 {
1583 as_bad ("SourceA register required");
1584 return;
1585 }
1586 str = skip_space (str);
1587 if (*str != ')')
1588 {
1589 as_bad ("(SourceA) required");
1590 return;
1591 }
1592 str = skip_space (str + 1);
1593
1594 if (*str == ',')
1595 {
1596 str = skip_space (str + 1);
1597 ans = parse_gen_reg (&str, &r2);
1598 if (ans < 0)
1599 {
1600 as_bad ("SourceB register required");
1601 return;
1602 }
1603 }
1604 else
1605 {
1606 as_bad ("SourceB register required");
1607 return;
1608 }
1609
1610 opcode |= (r1 << 16) | (r2 << 4) | ((indx & 0x1f) << 10);
1611
1612 if (indx != 0 && previous_mode == mode_cad)
1613 {
1614 /* We're in a delay slot.
1615 If the base reg is the destination of the branch, then issue
1616 an error message.
1617 Otherwise it is safe to use the base and index. */
1618 if (previous_dest != 0 && r1 == previous_dest)
1619 {
1620 as_bad ("base register not ready");
1621 return;
1622 }
1623 }
1624 else if (previous_dest != 0
1625 && r1 == previous_dest
1626 && (visium_arch == VISIUM_ARCH_MCM
1627 || visium_arch == VISIUM_ARCH_MCM24
1628 || (visium_arch == VISIUM_ARCH_DEF && indx != 0)))
1629 {
1630 as_warn ("base register not ready, NOP inserted.");
1631 /* Insert a NOP before the write instruction. */
1632 output = frag_more (4);
1633 memset (output, 0, 4);
1634 }
1635 break;
1636
1637 case mode_dax:
1638 /* register := register * 5-bit immediate
1639 Examples:
1640 read.b r1,(r2)
1641 read.w r1,3(r2) */
1642 ans = parse_gen_reg (&str, &r1);
1643 if (ans < 0)
1644 {
1645 as_bad ("Dest register required");
1646 return;
1647 }
1648 str = skip_space (str);
1649 if (*str != ',')
1650 {
1651 as_bad ("SourceA required");
1652 return;
1653 }
1654 str = skip_space (str + 1);
1655
1656 indx = 0;
1657 if (*str != '(')
1658 {
1659 str = parse_exp (str, &e1);
1660 if (e1.X_op == O_constant)
1661 {
1662 indx = e1.X_add_number;
1663
1664 if (indx < 0 || indx > 31)
1665 {
1666 as_bad ("Index out of range");
1667 return;
1668 }
1669 }
1670 else
1671 {
1672 as_bad ("Immediate 0 to 31 required");
1673 return;
1674 }
1675 }
1676 if (*str != '(')
1677 {
1678 as_bad ("(SourceA) required");
1679 return;
1680 }
1681 str++;
1682 ans = parse_gen_reg (&str, &r2);
1683 if (ans < 0)
1684 {
1685 as_bad ("SourceA register required");
1686 return;
1687 }
1688 str = skip_space (str);
1689 if (*str != ')')
1690 {
1691 as_bad ("(SourceA) required");
1692 return;
1693 }
1694 str++;
1695 opcode |= (r1 << 10) | (r2 << 16) | ((indx & 0x1f) << 4);
1696 this_dest = r1;
1697
1698 if (indx != 0 && previous_mode == mode_cad)
1699 {
1700 /* We're in a delay slot.
1701 If the base reg is the destination of the branch, then issue
1702 an error message.
1703 Otherwise it is safe to use the base and index. */
1704 if (previous_dest != 0 && r2 == previous_dest)
1705 {
1706 as_bad ("base register not ready");
1707 return;
1708 }
1709 }
1710 else if (previous_dest != 0
1711 && r2 == previous_dest
1712 && (visium_arch == VISIUM_ARCH_MCM
1713 || visium_arch == VISIUM_ARCH_MCM24
1714 || (visium_arch == VISIUM_ARCH_DEF && indx != 0)))
1715 {
1716 as_warn ("base register not ready, NOP inserted.");
1717 /* Insert a NOP before the read instruction. */
1718 output = frag_more (4);
1719 memset (output, 0, 4);
1720 }
1721 break;
1722
1723 case mode_s:
1724 /* special mode
1725 Example:
1726 nop */
1727 str = skip_space (str);
1728 break;
1729
1730 case mode_ci:
1731 /* condition * 16-bit signed word displacement
1732 Example:
1733 brr L1 */
1734 ans = parse_cc (&str, &cc);
1735 if (ans < 0)
1736 {
1737 as_bad ("condition code required");
1738 return;
1739 }
1740 opcode |= (cc << 27);
1741
1742 str = skip_space (str);
1743 if (*str == ',')
1744 {
1745 str = skip_space (str + 1);
1746 str = parse_exp (str, &e1);
1747 if (e1.X_op != O_absent)
1748 {
1749 if (e1.X_op == O_constant)
1750 {
1751 int imm = e1.X_add_number;
1752
1753 if (imm < -32768 || imm > 32767)
1754 as_bad ("immediate value out of range");
1755
1756 /* The GR6 doesn't correctly handle a 0 displacement
1757 so we insert a NOP and change it to -1. */
1758 if (imm == 0 && cc != 0 && visium_arch == VISIUM_ARCH_GR6)
1759 {
1760 output = frag_more (4);
1761 memset (output, 0, 4);
1762 imm = -1;
1763 }
1764
1765 opcode |= (imm & 0xffff);
1766 }
1767 else if (e1.X_op == O_symbol)
1768 {
1769 /* The GR6 doesn't correctly handle a 0 displacement
1770 so the instruction requires relaxation. */
1771 if (cc != 0 && visium_arch == VISIUM_ARCH_GR6)
1772 relax = amode;
1773 else
1774 reloc = BFD_RELOC_VISIUM_REL16;
1775 }
1776 else
1777 {
1778 as_bad ("immediate value missing");
1779 return;
1780 }
1781 }
1782 else
1783 {
1784 as_bad ("immediate value missing");
1785 return;
1786 }
1787 }
1788 else
1789 {
1790 as_bad ("immediate value missing");
1791 return;
1792 }
1793
1794 if (previous_mode == mode_cad || previous_mode == mode_ci)
1795 as_bad ("branch instruction in delay slot");
1796
1797 condition_code = cc;
1798 break;
1799
1800 case mode_fdab:
1801 /* float := float * float
1802 Example
1803 fadd f4,f3,f2 */
1804 ans = parse_fp_reg (&str, &r1);
1805 if (ans < 0)
1806 {
1807 as_bad ("floating point destination register required");
1808 return;
1809 }
1810 str = skip_space (str);
1811 if (*str == ',')
1812 {
1813 str++;
1814 ans = parse_fp_reg (&str, &r2);
1815 if (ans < 0)
1816 {
1817 as_bad ("floating point SourceA register required");
1818 return;
1819 }
1820 str = skip_space (str);
1821 if (*str == ',')
1822 {
1823 str++;
1824 ans = parse_fp_reg (&str, &r3);
1825 if (ans < 0)
1826 {
1827 as_bad ("floating point SourceB register required");
1828 return;
1829 }
1830
1831 /* Got 3 floating regs, assemble instruction. */
1832 opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
1833 }
1834 else
1835 {
1836 as_bad ("floating point SourceB register required");
1837 return;
1838 }
1839 }
1840 else
1841 {
1842 as_bad ("floating point SourceA register required");
1843 return;
1844 }
1845 break;
1846
1847 case mode_ifdab:
1848 /* 4-bit immediate * float * float * float
1849 Example
1850 fpinst 10,f1,f2,f3 */
1851 str = parse_exp (str, &e1);
1852 str = skip_space (str);
1853 if (e1.X_op != O_absent && *str == ',')
1854 {
1855 int finst = e1.X_add_number;
1856
1857 str = skip_space (str + 1);
1858 ans = parse_fp_reg (&str, &r1);
1859 if (ans < 0)
1860 {
1861 as_bad ("floating point destination register required");
1862 return;
1863 }
1864 str = skip_space (str);
1865 if (*str == ',')
1866 {
1867 str++;
1868 ans = parse_fp_reg (&str, &r2);
1869 if (ans < 0)
1870 {
1871 as_bad ("floating point SourceA register required");
1872 return;
1873 }
1874 str = skip_space (str);
1875 if (*str == ',')
1876 {
1877 str++;
1878 ans = parse_fp_reg (&str, &r3);
1879 if (ans < 0)
1880 {
1881 as_bad ("floating point SourceB register required");
1882 return;
1883 }
1884
1885 /* Got immediate and 3 floating regs,
1886 assemble instruction. */
1887 if (finst < 0 || finst > 15)
1888 as_bad ("finst out of range");
1889
1890 opcode |= (((finst & 0xf) << 27)
1891 | (r1 << 10) | (r2 << 16) | (r3 << 4));
1892 }
1893 else
1894 {
1895 as_bad ("floating point SourceB register required");
1896 return;
1897 }
1898 }
1899 else
1900 {
1901 as_bad ("floating point SourceA register required");
1902 return;
1903 }
1904 }
1905 else
1906 {
1907 as_bad ("finst missing");
1908 return;
1909 }
1910 break;
1911
1912 case mode_idfab:
1913 /* 4-bit immediate * register * float * float
1914 Example
1915 fpuread 4,r25,f2,f3 */
1916 str = parse_exp (str, &e1);
1917 str = skip_space (str);
1918 if (e1.X_op != O_absent && *str == ',')
1919 {
1920 int finst = e1.X_add_number;
1921
1922 str = skip_space (str + 1);
1923 ans = parse_gen_reg (&str, &r1);
1924 if (ans < 0)
1925 {
1926 as_bad ("destination general register required");
1927 return;
1928 }
1929 str = skip_space (str);
1930 if (*str == ',')
1931 {
1932 str++;
1933 ans = parse_fp_reg (&str, &r2);
1934 if (ans < 0)
1935 {
1936 as_bad ("floating point SourceA register required");
1937 return;
1938 }
1939 str = skip_space (str);
1940 if (*str == ',')
1941 {
1942 str++;
1943 ans = parse_fp_reg (&str, &r3);
1944 if (ans < 0)
1945 {
1946 as_bad ("floating point SourceB register required");
1947 return;
1948 }
1949
1950 /* Got immediate and 3 floating regs,
1951 assemble instruction. */
1952 if (finst < 0 || finst > 15)
1953 as_bad ("finst out of range");
1954
1955 opcode |= (((finst & 0xf) << 27)
1956 | (r1 << 10) | (r2 << 16) | (r3 << 4));
1957 }
1958 else
1959 {
1960 as_bad ("floating point SourceB register required");
1961 return;
1962 }
1963 }
1964 else
1965 {
1966 as_bad ("floating point SourceA register required");
1967 return;
1968 }
1969 }
1970 else
1971 {
1972 as_bad ("finst missing");
1973 return;
1974 }
1975 break;
1976
1977 case mode_fda:
1978 /* float := float
1979 Example
1980 fsqrt f4,f3 */
1981 ans = parse_fp_reg (&str, &r1);
1982 if (ans < 0)
1983 {
1984 as_bad ("floating point destination register required");
1985 return;
1986 }
1987 str = skip_space (str);
1988 if (*str == ',')
1989 {
1990 str++;
1991 ans = parse_fp_reg (&str, &r2);
1992 if (ans < 0)
1993 {
1994 as_bad ("floating point source register required");
1995 return;
1996 }
1997
1998 /* Got 2 floating regs, assemble instruction. */
1999 opcode |= (r1 << 10) | (r2 << 16);
2000 }
2001 else
2002 {
2003 as_bad ("floating point source register required");
2004 return;
2005 }
2006 break;
2007
2008 case mode_fdra:
2009 /* float := register
2010 Example
2011 fload f15,r6 */
2012 ans = parse_fp_reg (&str, &r1);
2013 if (ans < 0)
2014 {
2015 as_bad ("floating point destination register required");
2016 return;
2017 }
2018 str = skip_space (str);
2019 if (*str == ',')
2020 {
2021 str++;
2022 ans = parse_gen_reg (&str, &r2);
2023 if (ans < 0)
2024 {
2025 as_bad ("SourceA general register required");
2026 return;
2027 }
2028
2029 /* Got 2 regs, assemble instruction. */
2030 opcode |= (r1 << 10) | (r2 << 16);
2031 }
2032 else
2033 {
2034 as_bad ("SourceA general register required");
2035 return;
2036 }
2037 break;
2038
2039 case mode_rdfab:
2040 /* register := float * float
2041 Example
2042 fcmp r0,f4,f8
2043 For the GR6, register must be r0 and can be omitted. */
2044 ans = parse_gen_reg (&str, &r1);
2045 if (ans < 0)
2046 {
2047 if (visium_opcode_arch == VISIUM_OPCODE_ARCH_GR5)
2048 {
2049 as_bad ("Dest general register required");
2050 return;
2051 }
2052 r1 = 0;
2053 }
2054 else
2055 {
2056 if (r1 != 0 && visium_opcode_arch != VISIUM_OPCODE_ARCH_GR5)
2057 {
2058 as_bad ("FCMP/FCMPE can only use r0 as Dest register");
2059 return;
2060 }
2061
2062 str = skip_space (str);
2063 if (*str == ',')
2064 str++;
2065 else
2066 {
2067 as_bad ("floating point SourceA register required");
2068 return;
2069 }
2070 }
2071
2072 ans = parse_fp_reg (&str, &r2);
2073 if (ans < 0)
2074 {
2075 as_bad ("floating point SourceA register required");
2076 return;
2077 }
2078 str = skip_space (str);
2079 if (*str == ',')
2080 {
2081 str++;
2082 ans = parse_fp_reg (&str, &r3);
2083 if (ans < 0)
2084 {
2085 as_bad ("floating point SourceB register required");
2086 return;
2087 }
2088
2089 /* Got 3 regs, assemble instruction. */
2090 opcode |= (r1 << 10) | (r2 << 16) | (r3 << 4);
2091 }
2092
2093 this_dest = r1;
2094 break;
2095
2096 case mode_rdfa:
2097 /* register := float
2098 Example
2099 fstore r5,f12 */
2100 ans = parse_gen_reg (&str, &r1);
2101 if (ans < 0)
2102 {
2103 as_bad ("Dest general register required");
2104 return;
2105 }
2106 str = skip_space (str);
2107 if (*str == ',')
2108 {
2109 str++;
2110 ans = parse_fp_reg (&str, &r2);
2111 if (ans < 0)
2112 {
2113 as_bad ("floating point source register required");
2114 return;
2115 }
2116
2117 /* Got 2 regs, assemble instruction. */
2118 opcode |= (r1 << 10) | (r2 << 16);
2119 }
2120 else
2121 {
2122 as_bad ("floating point source register required");
2123 return;
2124 }
2125
2126 this_dest = r1;
2127 break;
2128
2129 case mode_rrr:
2130 /* register register register, all sources and destinations
2131 Example:
2132 bmd r1,r2,r3 */
2133
2134 ans = parse_gen_reg (&str, &r1);
2135 if (ans < 0)
2136 {
2137 as_bad ("destination address register required");
2138 return;
2139 }
2140 str = skip_space (str);
2141 if (*str == ',')
2142 {
2143 str++;
2144 ans = parse_gen_reg (&str, &r2);
2145 if (ans < 0)
2146 {
2147 as_bad ("source address register required");
2148 return;
2149 }
2150 str = skip_space (str);
2151 if (*str == ',')
2152 {
2153 str++;
2154 ans = parse_gen_reg (&str, &r3);
2155 if (ans < 0)
2156 {
2157 as_bad ("count register required");
2158 return;
2159 }
2160
2161 /* We insist on three registers but the opcode can only use
2162 r1,r2,r3. */
2163 if (r1 != 1 || r2 != 2 || r3 != 3)
2164 {
2165 as_bad ("BMI/BMD can only use format op r1,r2,r3");
2166 return;
2167 }
2168
2169 /* Opcode is unmodified by what comes out of the table. */
2170 }
2171 else
2172 {
2173 as_bad ("register required");
2174 return;
2175 }
2176 }
2177 else
2178 {
2179 as_bad ("register required");
2180 return;
2181 }
2182
2183 this_dest = r1;
2184 break;
2185
2186 default:
2187 break;
2188 }
2189
2190 if (relax)
2191 output = frag_var (rs_machine_dependent, 8, 4, relax, e1.X_add_symbol,
2192 e1.X_add_number, NULL);
2193 else
2194 output = frag_more (4);
2195
2196 /* Build the 32-bit instruction in a host-endian-neutral fashion. */
2197 output[0] = (opcode >> 24) & 0xff;
2198 output[1] = (opcode >> 16) & 0xff;
2199 output[2] = (opcode >> 8) & 0xff;
2200 output[3] = (opcode >> 0) & 0xff;
2201
2202 if (relax)
2203 /* The size of the instruction is unknown, so tie the debug info to the
2204 start of the instruction. */
2205 dwarf2_emit_insn (0);
2206 else
2207 {
2208 if (reloc)
2209 fix_new_exp (frag_now, output - frag_now->fr_literal, 4, &e1,
2210 reloc == BFD_RELOC_VISIUM_REL16, reloc);
2211 else
2212 visium_update_parity_bit (output);
2213
2214 dwarf2_emit_insn (4);
2215 }
2216
2217 if (*str != '\0')
2218 as_bad ("junk after instruction");
2219 }
2220
2221 void
2222 visium_cfi_frame_initial_instructions (void)
2223 {
2224 /* The CFA is in SP on function entry. */
2225 cfi_add_CFA_def_cfa (23, 0);
2226 }
2227
2228 int
2229 visium_regname_to_dw2regnum (char *regname)
2230 {
2231 if (!regname[0])
2232 return -1;
2233
2234 if (regname[0] == 'f' && regname[1] == 'p' && !regname[2])
2235 return 22;
2236
2237 if (regname[0] == 's' && regname[1] == 'p' && !regname[2])
2238 return 23;
2239
2240 if (regname[0] == 'm' && regname[1] == 'd' && !regname[3])
2241 switch (regname[2])
2242 {
2243 case 'b': return 32;
2244 case 'a': return 33;
2245 case 'c': return 34;
2246 default : return -1;
2247 }
2248
2249 if (regname[0] == 'f' || regname[0] == 'r')
2250 {
2251 char *p;
2252 unsigned int regnum = strtoul (regname + 1, &p, 10);
2253 if (*p)
2254 return -1;
2255 if (regnum >= (regname[0] == 'f' ? 16 : 32))
2256 return -1;
2257 if (regname[0] == 'f')
2258 regnum += 35;
2259 return regnum;
2260 }
2261
2262 return -1;
2263 }
2264