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