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