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