cpu,opcodes: add instruction semantics to bpf.cpu and minor fixes
[deliverable/binutils-gdb.git] / opcodes / frv-asm.c
CommitLineData
4162bb66 1/* DO NOT EDIT! -*- buffer-read-only: t -*- vi:set ro: */
fd3c93d5
DB
2/* Assembler interface for targets using CGEN. -*- C -*-
3 CGEN: Cpu tools GENerator
4
47b0e7ad
NC
5 THIS FILE IS MACHINE GENERATED WITH CGEN.
6 - the resultant file is machine generated, cgen-asm.in isn't
fd3c93d5 7
b3adc24a 8 Copyright (C) 1996-2020 Free Software Foundation, Inc.
fd3c93d5 9
9b201bb5 10 This file is part of libopcodes.
fd3c93d5 11
9b201bb5 12 This library is free software; you can redistribute it and/or modify
47b0e7ad 13 it under the terms of the GNU General Public License as published by
9b201bb5 14 the Free Software Foundation; either version 3, or (at your option)
47b0e7ad 15 any later version.
fd3c93d5 16
9b201bb5
NC
17 It is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
20 License for more details.
fd3c93d5 21
47b0e7ad
NC
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software Foundation, Inc.,
24 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
fd3c93d5 25
9b201bb5 26
fd3c93d5
DB
27/* ??? Eventually more and more of this stuff can go to cpu-independent files.
28 Keep that in mind. */
29
30#include "sysdep.h"
31#include <stdio.h>
32#include "ansidecl.h"
33#include "bfd.h"
34#include "symcat.h"
35#include "frv-desc.h"
36#include "frv-opc.h"
37#include "opintl.h"
38#include "xregex.h"
39#include "libiberty.h"
40#include "safe-ctype.h"
41
42#undef min
43#define min(a,b) ((a) < (b) ? (a) : (b))
44#undef max
45#define max(a,b) ((a) > (b) ? (a) : (b))
46
47static const char * parse_insn_normal
ffead7ae 48 (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
fd3c93d5
DB
49\f
50/* -- assembler routines inserted here. */
51
52/* -- asm.c */
90219bd0
AO
53inline static const char *
54parse_symbolic_address (CGEN_CPU_DESC cd,
55 const char **strp,
56 int opindex,
57 int opinfo,
58 enum cgen_parse_operand_result *resultp,
59 bfd_vma *valuep)
60{
61 enum cgen_parse_operand_result result_type;
62 const char *errmsg = (* cd->parse_operand_fn)
63 (cd, CGEN_PARSE_OPERAND_SYMBOLIC, strp, opindex, opinfo,
64 &result_type, valuep);
65
66 if (errmsg == NULL
67 && result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED)
68 return "symbolic expression required";
69
70 if (resultp)
71 *resultp = result_type;
72
73 return errmsg;
74}
75
76static const char *
77parse_ldd_annotation (CGEN_CPU_DESC cd,
78 const char **strp,
79 int opindex,
33b71eeb 80 unsigned long *valuep)
90219bd0
AO
81{
82 const char *errmsg;
83 enum cgen_parse_operand_result result_type;
84 bfd_vma value;
85
86 if (**strp == '#' || **strp == '%')
87 {
88 if (strncasecmp (*strp + 1, "tlsdesc(", 8) == 0)
89 {
90 *strp += 9;
91 errmsg = parse_symbolic_address (cd, strp, opindex,
92 BFD_RELOC_FRV_TLSDESC_RELAX,
93 &result_type, &value);
94 if (**strp != ')')
95 return "missing ')'";
96 if (valuep)
97 *valuep = value;
98 ++*strp;
99 if (errmsg)
100 return errmsg;
101 }
102 }
43e65147 103
90219bd0
AO
104 while (**strp == ' ' || **strp == '\t')
105 ++*strp;
43e65147 106
90219bd0
AO
107 if (**strp != '@')
108 return "missing `@'";
109
110 ++*strp;
111
112 return NULL;
113}
114
115static const char *
116parse_call_annotation (CGEN_CPU_DESC cd,
117 const char **strp,
118 int opindex,
33b71eeb 119 unsigned long *valuep)
90219bd0
AO
120{
121 const char *errmsg;
122 enum cgen_parse_operand_result result_type;
123 bfd_vma value;
124
125 if (**strp == '#' || **strp == '%')
126 {
127 if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
128 {
129 *strp += 11;
130 errmsg = parse_symbolic_address (cd, strp, opindex,
131 BFD_RELOC_FRV_GETTLSOFF_RELAX,
132 &result_type, &value);
133 if (**strp != ')')
134 return "missing ')'";
135 if (valuep)
136 *valuep = value;
137 ++*strp;
138 if (errmsg)
139 return errmsg;
140 }
141 }
43e65147 142
90219bd0
AO
143 while (**strp == ' ' || **strp == '\t')
144 ++*strp;
43e65147 145
90219bd0
AO
146 if (**strp != '@')
147 return "missing `@'";
148
149 ++*strp;
150
151 return NULL;
152}
153
154static const char *
155parse_ld_annotation (CGEN_CPU_DESC cd,
156 const char **strp,
157 int opindex,
33b71eeb 158 unsigned long *valuep)
90219bd0
AO
159{
160 const char *errmsg;
161 enum cgen_parse_operand_result result_type;
162 bfd_vma value;
163
164 if (**strp == '#' || **strp == '%')
165 {
166 if (strncasecmp (*strp + 1, "tlsoff(", 7) == 0)
167 {
168 *strp += 8;
169 errmsg = parse_symbolic_address (cd, strp, opindex,
170 BFD_RELOC_FRV_TLSOFF_RELAX,
171 &result_type, &value);
172 if (**strp != ')')
173 return "missing ')'";
174 if (valuep)
175 *valuep = value;
176 ++*strp;
177 if (errmsg)
178 return errmsg;
179 }
180 }
43e65147 181
90219bd0
AO
182 while (**strp == ' ' || **strp == '\t')
183 ++*strp;
43e65147 184
90219bd0
AO
185 if (**strp != '@')
186 return "missing `@'";
187
188 ++*strp;
189
190 return NULL;
191}
192
fd3c93d5 193static const char *
47b0e7ad
NC
194parse_ulo16 (CGEN_CPU_DESC cd,
195 const char **strp,
196 int opindex,
197 unsigned long *valuep)
fd3c93d5
DB
198{
199 const char *errmsg;
200 enum cgen_parse_operand_result result_type;
201 bfd_vma value;
43e65147 202
fd3c93d5
DB
203 if (**strp == '#' || **strp == '%')
204 {
205 if (strncasecmp (*strp + 1, "lo(", 3) == 0)
206 {
207 *strp += 4;
208 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
47b0e7ad 209 & result_type, & value);
fd3c93d5
DB
210 if (**strp != ')')
211 return "missing `)'";
212 ++*strp;
213 if (errmsg == NULL
214 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
215 value &= 0xffff;
216 *valuep = value;
217 return errmsg;
218 }
219 if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
220 {
221 *strp += 9;
90219bd0
AO
222 errmsg = parse_symbolic_address (cd, strp, opindex,
223 BFD_RELOC_FRV_GPRELLO,
47b0e7ad 224 & result_type, & value);
fd3c93d5
DB
225 if (**strp != ')')
226 return "missing ')'";
227 ++*strp;
ba2d3f07
AO
228 *valuep = value;
229 return errmsg;
230 }
231 else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
232 {
233 *strp += 7;
90219bd0
AO
234 errmsg = parse_symbolic_address (cd, strp, opindex,
235 BFD_RELOC_FRV_GOTLO,
47b0e7ad 236 & result_type, & value);
ba2d3f07
AO
237 if (**strp != ')')
238 return "missing ')'";
239 ++*strp;
ba2d3f07
AO
240 *valuep = value;
241 return errmsg;
242 }
243 else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
244 {
245 *strp += 15;
90219bd0
AO
246 errmsg = parse_symbolic_address (cd, strp, opindex,
247 BFD_RELOC_FRV_FUNCDESC_GOTLO,
47b0e7ad 248 & result_type, & value);
ba2d3f07
AO
249 if (**strp != ')')
250 return "missing ')'";
251 ++*strp;
ba2d3f07
AO
252 *valuep = value;
253 return errmsg;
254 }
255 else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
256 {
257 *strp += 10;
90219bd0
AO
258 errmsg = parse_symbolic_address (cd, strp, opindex,
259 BFD_RELOC_FRV_GOTOFFLO,
47b0e7ad 260 & result_type, & value);
ba2d3f07
AO
261 if (**strp != ')')
262 return "missing ')'";
263 ++*strp;
ba2d3f07
AO
264 *valuep = value;
265 return errmsg;
266 }
267 else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
268 {
269 *strp += 18;
90219bd0
AO
270 errmsg = parse_symbolic_address (cd, strp, opindex,
271 BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
47b0e7ad 272 & result_type, & value);
90219bd0
AO
273 if (**strp != ')')
274 return "missing ')'";
275 ++*strp;
276 *valuep = value;
277 return errmsg;
278 }
279 else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
280 {
281 *strp += 14;
282 errmsg = parse_symbolic_address (cd, strp, opindex,
283 BFD_RELOC_FRV_GOTTLSDESCLO,
47b0e7ad 284 & result_type, & value);
90219bd0
AO
285 if (**strp != ')')
286 return "missing ')'";
287 ++*strp;
288 *valuep = value;
289 return errmsg;
290 }
291 else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
292 {
293 *strp += 11;
294 errmsg = parse_symbolic_address (cd, strp, opindex,
295 BFD_RELOC_FRV_TLSMOFFLO,
47b0e7ad 296 & result_type, & value);
90219bd0
AO
297 if (**strp != ')')
298 return "missing ')'";
299 ++*strp;
300 *valuep = value;
301 return errmsg;
302 }
303 else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
304 {
305 *strp += 13;
306 errmsg = parse_symbolic_address (cd, strp, opindex,
307 BFD_RELOC_FRV_GOTTLSOFFLO,
47b0e7ad 308 & result_type, & value);
ba2d3f07
AO
309 if (**strp != ')')
310 return "missing ')'";
311 ++*strp;
fd3c93d5
DB
312 *valuep = value;
313 return errmsg;
314 }
315 }
33b71eeb 316 return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
fd3c93d5
DB
317}
318
319static const char *
47b0e7ad
NC
320parse_uslo16 (CGEN_CPU_DESC cd,
321 const char **strp,
322 int opindex,
323 signed long *valuep)
fd3c93d5
DB
324{
325 const char *errmsg;
326 enum cgen_parse_operand_result result_type;
327 bfd_vma value;
43e65147 328
fd3c93d5
DB
329 if (**strp == '#' || **strp == '%')
330 {
331 if (strncasecmp (*strp + 1, "lo(", 3) == 0)
332 {
333 *strp += 4;
334 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
47b0e7ad 335 & result_type, & value);
fd3c93d5
DB
336 if (**strp != ')')
337 return "missing `)'";
338 ++*strp;
339 if (errmsg == NULL
340 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
341 value &= 0xffff;
342 *valuep = value;
343 return errmsg;
344 }
345 else if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
346 {
347 *strp += 9;
90219bd0
AO
348 errmsg = parse_symbolic_address (cd, strp, opindex,
349 BFD_RELOC_FRV_GPRELLO,
47b0e7ad 350 & result_type, & value);
fd3c93d5
DB
351 if (**strp != ')')
352 return "missing ')'";
353 ++*strp;
fd3c93d5
DB
354 *valuep = value;
355 return errmsg;
356 }
ba2d3f07
AO
357 else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
358 {
359 *strp += 7;
90219bd0
AO
360 errmsg = parse_symbolic_address (cd, strp, opindex,
361 BFD_RELOC_FRV_GOTLO,
47b0e7ad 362 & result_type, & value);
ba2d3f07
AO
363 if (**strp != ')')
364 return "missing ')'";
365 ++*strp;
ba2d3f07
AO
366 *valuep = value;
367 return errmsg;
368 }
369 else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
370 {
371 *strp += 15;
90219bd0
AO
372 errmsg = parse_symbolic_address (cd, strp, opindex,
373 BFD_RELOC_FRV_FUNCDESC_GOTLO,
47b0e7ad 374 & result_type, & value);
ba2d3f07
AO
375 if (**strp != ')')
376 return "missing ')'";
377 ++*strp;
ba2d3f07
AO
378 *valuep = value;
379 return errmsg;
380 }
381 else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
382 {
383 *strp += 10;
90219bd0
AO
384 errmsg = parse_symbolic_address (cd, strp, opindex,
385 BFD_RELOC_FRV_GOTOFFLO,
47b0e7ad 386 & result_type, & value);
ba2d3f07
AO
387 if (**strp != ')')
388 return "missing ')'";
389 ++*strp;
ba2d3f07
AO
390 *valuep = value;
391 return errmsg;
392 }
393 else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
394 {
395 *strp += 18;
90219bd0
AO
396 errmsg = parse_symbolic_address (cd, strp, opindex,
397 BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
47b0e7ad 398 & result_type, & value);
90219bd0
AO
399 if (**strp != ')')
400 return "missing ')'";
401 ++*strp;
402 *valuep = value;
403 return errmsg;
404 }
405 else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
406 {
407 *strp += 14;
408 errmsg = parse_symbolic_address (cd, strp, opindex,
409 BFD_RELOC_FRV_GOTTLSDESCLO,
47b0e7ad 410 & result_type, & value);
90219bd0
AO
411 if (**strp != ')')
412 return "missing ')'";
413 ++*strp;
414 *valuep = value;
415 return errmsg;
416 }
417 else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
418 {
419 *strp += 11;
420 errmsg = parse_symbolic_address (cd, strp, opindex,
421 BFD_RELOC_FRV_TLSMOFFLO,
47b0e7ad 422 & result_type, & value);
90219bd0
AO
423 if (**strp != ')')
424 return "missing ')'";
425 ++*strp;
426 *valuep = value;
427 return errmsg;
428 }
429 else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
430 {
431 *strp += 13;
432 errmsg = parse_symbolic_address (cd, strp, opindex,
433 BFD_RELOC_FRV_GOTTLSOFFLO,
47b0e7ad 434 & result_type, & value);
ba2d3f07
AO
435 if (**strp != ')')
436 return "missing ')'";
437 ++*strp;
ba2d3f07
AO
438 *valuep = value;
439 return errmsg;
440 }
fd3c93d5 441 }
33b71eeb 442 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
fd3c93d5
DB
443}
444
445static const char *
47b0e7ad
NC
446parse_uhi16 (CGEN_CPU_DESC cd,
447 const char **strp,
448 int opindex,
449 unsigned long *valuep)
fd3c93d5
DB
450{
451 const char *errmsg;
452 enum cgen_parse_operand_result result_type;
453 bfd_vma value;
43e65147 454
fd3c93d5
DB
455 if (**strp == '#' || **strp == '%')
456 {
457 if (strncasecmp (*strp + 1, "hi(", 3) == 0)
458 {
459 *strp += 4;
460 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16,
47b0e7ad 461 & result_type, & value);
fd3c93d5
DB
462 if (**strp != ')')
463 return "missing `)'";
464 ++*strp;
465 if (errmsg == NULL
466 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
90219bd0 467 {
5011093d
NC
468 /* If value is wider than 32 bits then be
469 careful about how we extract bits 16-31. */
470 if (sizeof (value) > 4)
471 value &= (((bfd_vma)1 << 16) << 16) - 1;
472
90219bd0
AO
473 value >>= 16;
474 }
fd3c93d5
DB
475 *valuep = value;
476 return errmsg;
477 }
478 else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0)
479 {
480 *strp += 9;
90219bd0
AO
481 errmsg = parse_symbolic_address (cd, strp, opindex,
482 BFD_RELOC_FRV_GPRELHI,
47b0e7ad 483 & result_type, & value);
fd3c93d5
DB
484 if (**strp != ')')
485 return "missing ')'";
486 ++*strp;
fd3c93d5
DB
487 *valuep = value;
488 return errmsg;
489 }
ba2d3f07
AO
490 else if (strncasecmp (*strp + 1, "gothi(", 6) == 0)
491 {
492 *strp += 7;
90219bd0
AO
493 errmsg = parse_symbolic_address (cd, strp, opindex,
494 BFD_RELOC_FRV_GOTHI,
47b0e7ad 495 & result_type, & value);
ba2d3f07
AO
496 if (**strp != ')')
497 return "missing ')'";
498 ++*strp;
ba2d3f07
AO
499 *valuep = value;
500 return errmsg;
501 }
502 else if (strncasecmp (*strp + 1, "gotfuncdeschi(", 14) == 0)
503 {
504 *strp += 15;
90219bd0
AO
505 errmsg = parse_symbolic_address (cd, strp, opindex,
506 BFD_RELOC_FRV_FUNCDESC_GOTHI,
47b0e7ad 507 & result_type, & value);
ba2d3f07
AO
508 if (**strp != ')')
509 return "missing ')'";
510 ++*strp;
ba2d3f07
AO
511 *valuep = value;
512 return errmsg;
513 }
514 else if (strncasecmp (*strp + 1, "gotoffhi(", 9) == 0)
515 {
516 *strp += 10;
90219bd0
AO
517 errmsg = parse_symbolic_address (cd, strp, opindex,
518 BFD_RELOC_FRV_GOTOFFHI,
47b0e7ad 519 & result_type, & value);
ba2d3f07
AO
520 if (**strp != ')')
521 return "missing ')'";
522 ++*strp;
ba2d3f07
AO
523 *valuep = value;
524 return errmsg;
525 }
526 else if (strncasecmp (*strp + 1, "gotofffuncdeschi(", 17) == 0)
527 {
528 *strp += 18;
90219bd0
AO
529 errmsg = parse_symbolic_address (cd, strp, opindex,
530 BFD_RELOC_FRV_FUNCDESC_GOTOFFHI,
47b0e7ad 531 & result_type, & value);
90219bd0
AO
532 if (**strp != ')')
533 return "missing ')'";
534 ++*strp;
535 *valuep = value;
536 return errmsg;
537 }
538 else if (strncasecmp (*strp + 1, "gottlsdeschi(", 13) == 0)
539 {
540 *strp += 14;
541 errmsg = parse_symbolic_address (cd, strp, opindex,
542 BFD_RELOC_FRV_GOTTLSDESCHI,
543 &result_type, &value);
544 if (**strp != ')')
545 return "missing ')'";
546 ++*strp;
547 *valuep = value;
548 return errmsg;
549 }
550 else if (strncasecmp (*strp + 1, "tlsmoffhi(", 10) == 0)
551 {
552 *strp += 11;
553 errmsg = parse_symbolic_address (cd, strp, opindex,
554 BFD_RELOC_FRV_TLSMOFFHI,
47b0e7ad 555 & result_type, & value);
90219bd0
AO
556 if (**strp != ')')
557 return "missing ')'";
558 ++*strp;
559 *valuep = value;
560 return errmsg;
561 }
562 else if (strncasecmp (*strp + 1, "gottlsoffhi(", 12) == 0)
563 {
564 *strp += 13;
565 errmsg = parse_symbolic_address (cd, strp, opindex,
566 BFD_RELOC_FRV_GOTTLSOFFHI,
47b0e7ad 567 & result_type, & value);
ba2d3f07
AO
568 if (**strp != ')')
569 return "missing ')'";
570 ++*strp;
ba2d3f07
AO
571 *valuep = value;
572 return errmsg;
573 }
fd3c93d5
DB
574 }
575 return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
576}
577
578static long
47b0e7ad 579parse_register_number (const char **strp)
fd3c93d5
DB
580{
581 int regno;
47b0e7ad 582
fd3c93d5
DB
583 if (**strp < '0' || **strp > '9')
584 return -1; /* error */
585
586 regno = **strp - '0';
587 for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp)
588 regno = regno * 10 + (**strp - '0');
589
590 return regno;
591}
592
593static const char *
47b0e7ad
NC
594parse_spr (CGEN_CPU_DESC cd,
595 const char **strp,
596 CGEN_KEYWORD * table,
597 long *valuep)
fd3c93d5
DB
598{
599 const char *save_strp;
600 long regno;
601
602 /* Check for spr index notation. */
603 if (strncasecmp (*strp, "spr[", 4) == 0)
604 {
605 *strp += 4;
606 regno = parse_register_number (strp);
607 if (**strp != ']')
47b0e7ad 608 return _("missing `]'");
fd3c93d5
DB
609 ++*strp;
610 if (! spr_valid (regno))
47b0e7ad 611 return _("Special purpose register number is out of range");
fd3c93d5
DB
612 *valuep = regno;
613 return NULL;
614 }
615
616 save_strp = *strp;
617 regno = parse_register_number (strp);
618 if (regno != -1)
619 {
620 if (! spr_valid (regno))
47b0e7ad 621 return _("Special purpose register number is out of range");
fd3c93d5
DB
622 *valuep = regno;
623 return NULL;
624 }
625
626 *strp = save_strp;
627 return cgen_parse_keyword (cd, strp, table, valuep);
628}
629
630static const char *
47b0e7ad
NC
631parse_d12 (CGEN_CPU_DESC cd,
632 const char **strp,
633 int opindex,
634 long *valuep)
fd3c93d5
DB
635{
636 const char *errmsg;
637 enum cgen_parse_operand_result result_type;
638 bfd_vma value;
43e65147 639
fd3c93d5
DB
640 /* Check for small data reference. */
641 if (**strp == '#' || **strp == '%')
642 {
643 if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
644 {
645 *strp += 9;
90219bd0
AO
646 errmsg = parse_symbolic_address (cd, strp, opindex,
647 BFD_RELOC_FRV_GPREL12,
47b0e7ad 648 & result_type, & value);
fd3c93d5
DB
649 if (**strp != ')')
650 return "missing `)'";
651 ++*strp;
652 *valuep = value;
653 return errmsg;
654 }
ba2d3f07
AO
655 else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
656 {
657 *strp += 7;
90219bd0
AO
658 errmsg = parse_symbolic_address (cd, strp, opindex,
659 BFD_RELOC_FRV_GOT12,
47b0e7ad 660 & result_type, & value);
ba2d3f07
AO
661 if (**strp != ')')
662 return "missing ')'";
663 ++*strp;
664 *valuep = value;
665 return errmsg;
666 }
667 else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
668 {
669 *strp += 15;
90219bd0
AO
670 errmsg = parse_symbolic_address (cd, strp, opindex,
671 BFD_RELOC_FRV_FUNCDESC_GOT12,
47b0e7ad 672 & result_type, & value);
ba2d3f07
AO
673 if (**strp != ')')
674 return "missing ')'";
675 ++*strp;
676 *valuep = value;
677 return errmsg;
678 }
679 else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
680 {
681 *strp += 10;
90219bd0
AO
682 errmsg = parse_symbolic_address (cd, strp, opindex,
683 BFD_RELOC_FRV_GOTOFF12,
47b0e7ad 684 & result_type, & value);
ba2d3f07
AO
685 if (**strp != ')')
686 return "missing ')'";
687 ++*strp;
688 *valuep = value;
689 return errmsg;
690 }
691 else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
692 {
693 *strp += 18;
90219bd0
AO
694 errmsg = parse_symbolic_address (cd, strp, opindex,
695 BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
47b0e7ad 696 & result_type, & value);
90219bd0
AO
697 if (**strp != ')')
698 return "missing ')'";
699 ++*strp;
700 *valuep = value;
701 return errmsg;
702 }
703 else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
704 {
705 *strp += 14;
706 errmsg = parse_symbolic_address (cd, strp, opindex,
707 BFD_RELOC_FRV_GOTTLSDESC12,
47b0e7ad 708 & result_type, & value);
90219bd0
AO
709 if (**strp != ')')
710 return "missing ')'";
711 ++*strp;
712 *valuep = value;
713 return errmsg;
714 }
715 else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
716 {
717 *strp += 11;
718 errmsg = parse_symbolic_address (cd, strp, opindex,
719 BFD_RELOC_FRV_TLSMOFF12,
47b0e7ad 720 & result_type, & value);
90219bd0
AO
721 if (**strp != ')')
722 return "missing ')'";
723 ++*strp;
724 *valuep = value;
725 return errmsg;
726 }
727 else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
728 {
729 *strp += 13;
730 errmsg = parse_symbolic_address (cd, strp, opindex,
731 BFD_RELOC_FRV_GOTTLSOFF12,
47b0e7ad 732 & result_type, & value);
ba2d3f07
AO
733 if (**strp != ')')
734 return "missing ')'";
735 ++*strp;
736 *valuep = value;
737 return errmsg;
738 }
fd3c93d5
DB
739 }
740 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
741}
742
743static const char *
47b0e7ad
NC
744parse_s12 (CGEN_CPU_DESC cd,
745 const char **strp,
746 int opindex,
747 long *valuep)
fd3c93d5
DB
748{
749 const char *errmsg;
750 enum cgen_parse_operand_result result_type;
751 bfd_vma value;
43e65147 752
fd3c93d5 753 /* Check for small data reference. */
90219bd0 754 if (**strp == '#' || **strp == '%')
fd3c93d5 755 {
90219bd0
AO
756 if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
757 {
758 *strp += 9;
759 errmsg = parse_symbolic_address (cd, strp, opindex,
760 BFD_RELOC_FRV_GPREL12,
47b0e7ad 761 & result_type, & value);
90219bd0
AO
762 if (**strp != ')')
763 return "missing `)'";
764 ++*strp;
765 *valuep = value;
766 return errmsg;
767 }
768 else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
769 {
770 *strp += 7;
771 errmsg = parse_symbolic_address (cd, strp, opindex,
772 BFD_RELOC_FRV_GOT12,
47b0e7ad 773 & result_type, & value);
90219bd0
AO
774 if (**strp != ')')
775 return "missing ')'";
776 ++*strp;
777 *valuep = value;
778 return errmsg;
779 }
780 else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
781 {
782 *strp += 15;
783 errmsg = parse_symbolic_address (cd, strp, opindex,
784 BFD_RELOC_FRV_FUNCDESC_GOT12,
47b0e7ad 785 & result_type, & value);
90219bd0
AO
786 if (**strp != ')')
787 return "missing ')'";
788 ++*strp;
789 *valuep = value;
790 return errmsg;
791 }
792 else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
793 {
794 *strp += 10;
795 errmsg = parse_symbolic_address (cd, strp, opindex,
796 BFD_RELOC_FRV_GOTOFF12,
47b0e7ad 797 & result_type, & value);
90219bd0
AO
798 if (**strp != ')')
799 return "missing ')'";
800 ++*strp;
801 *valuep = value;
802 return errmsg;
803 }
804 else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
805 {
806 *strp += 18;
807 errmsg = parse_symbolic_address (cd, strp, opindex,
808 BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
47b0e7ad 809 & result_type, & value);
90219bd0
AO
810 if (**strp != ')')
811 return "missing ')'";
812 ++*strp;
813 *valuep = value;
814 return errmsg;
815 }
816 else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
817 {
818 *strp += 14;
819 errmsg = parse_symbolic_address (cd, strp, opindex,
820 BFD_RELOC_FRV_GOTTLSDESC12,
47b0e7ad 821 & result_type, & value);
90219bd0
AO
822 if (**strp != ')')
823 return "missing ')'";
824 ++*strp;
825 *valuep = value;
826 return errmsg;
827 }
828 else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
829 {
830 *strp += 11;
831 errmsg = parse_symbolic_address (cd, strp, opindex,
832 BFD_RELOC_FRV_TLSMOFF12,
47b0e7ad 833 & result_type, & value);
90219bd0
AO
834 if (**strp != ')')
835 return "missing ')'";
836 ++*strp;
837 *valuep = value;
838 return errmsg;
839 }
840 else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
841 {
842 *strp += 13;
843 errmsg = parse_symbolic_address (cd, strp, opindex,
844 BFD_RELOC_FRV_GOTTLSOFF12,
47b0e7ad 845 & result_type, & value);
90219bd0
AO
846 if (**strp != ')')
847 return "missing ')'";
848 ++*strp;
849 *valuep = value;
850 return errmsg;
851 }
fd3c93d5 852 }
90219bd0
AO
853
854 if (**strp == '#')
855 ++*strp;
856 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
fd3c93d5
DB
857}
858
859static const char *
47b0e7ad
NC
860parse_u12 (CGEN_CPU_DESC cd,
861 const char **strp,
862 int opindex,
863 long *valuep)
fd3c93d5
DB
864{
865 const char *errmsg;
866 enum cgen_parse_operand_result result_type;
867 bfd_vma value;
43e65147 868
fd3c93d5
DB
869 /* Check for small data reference. */
870 if ((**strp == '#' || **strp == '%')
871 && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
872 {
873 *strp += 9;
90219bd0
AO
874 errmsg = parse_symbolic_address (cd, strp, opindex,
875 BFD_RELOC_FRV_GPRELU12,
47b0e7ad 876 & result_type, & value);
fd3c93d5
DB
877 if (**strp != ')')
878 return "missing `)'";
879 ++*strp;
880 *valuep = value;
881 return errmsg;
882 }
883 else
884 {
885 if (**strp == '#')
886 ++*strp;
887 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
888 }
889}
890
ecd51ad3 891static const char *
47b0e7ad
NC
892parse_A (CGEN_CPU_DESC cd,
893 const char **strp,
894 int opindex,
895 unsigned long *valuep,
896 unsigned long A)
ecd51ad3
DB
897{
898 const char *errmsg;
43e65147 899
ecd51ad3
DB
900 if (**strp == '#')
901 ++*strp;
902
903 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
904 if (errmsg)
905 return errmsg;
906
907 if (*valuep != A)
47b0e7ad 908 return _("Value of A operand must be 0 or 1");
ecd51ad3
DB
909
910 return NULL;
911}
912
913static const char *
47b0e7ad
NC
914parse_A0 (CGEN_CPU_DESC cd,
915 const char **strp,
916 int opindex,
917 unsigned long *valuep)
ecd51ad3
DB
918{
919 return parse_A (cd, strp, opindex, valuep, 0);
920}
921
922static const char *
47b0e7ad
NC
923parse_A1 (CGEN_CPU_DESC cd,
924 const char **strp,
925 int opindex,
926 unsigned long *valuep)
ecd51ad3
DB
927{
928 return parse_A (cd, strp, opindex, valuep, 1);
929}
930
36c3ae24 931static const char *
47b0e7ad
NC
932parse_even_register (CGEN_CPU_DESC cd,
933 const char ** strP,
934 CGEN_KEYWORD * tableP,
935 long * valueP)
36c3ae24
NC
936{
937 const char * errmsg;
938 const char * saved_star_strP = * strP;
939
940 errmsg = cgen_parse_keyword (cd, strP, tableP, valueP);
941
942 if (errmsg == NULL && ((* valueP) & 1))
943 {
944 errmsg = _("register number must be even");
945 * strP = saved_star_strP;
946 }
947
948 return errmsg;
949}
90219bd0
AO
950
951static const char *
952parse_call_label (CGEN_CPU_DESC cd,
953 const char **strp,
954 int opindex,
955 int opinfo,
956 enum cgen_parse_operand_result *resultp,
957 bfd_vma *valuep)
958{
959 const char *errmsg;
960 bfd_vma value;
43e65147 961
90219bd0
AO
962 /* Check for small data reference. */
963 if (opinfo == 0 && (**strp == '#' || **strp == '%'))
964 {
965 if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
966 {
967 *strp += 11;
968 errmsg = parse_symbolic_address (cd, strp, opindex,
969 BFD_RELOC_FRV_GETTLSOFF,
970 resultp, &value);
971 if (**strp != ')')
47b0e7ad 972 return _("missing `)'");
90219bd0
AO
973 ++*strp;
974 *valuep = value;
975 return errmsg;
976 }
977 }
978
979 return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
980}
981
fd3c93d5
DB
982/* -- */
983
984const char * frv_cgen_parse_operand
47b0e7ad 985 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
fd3c93d5
DB
986
987/* Main entry point for operand parsing.
988
989 This function is basically just a big switch statement. Earlier versions
990 used tables to look up the function to use, but
991 - if the table contains both assembler and disassembler functions then
992 the disassembler contains much of the assembler and vice-versa,
993 - there's a lot of inlining possibilities as things grow,
994 - using a switch statement avoids the function call overhead.
995
996 This function could be moved into `parse_insn_normal', but keeping it
997 separate makes clear the interface between `parse_insn_normal' and each of
998 the handlers. */
999
1000const char *
47b0e7ad
NC
1001frv_cgen_parse_operand (CGEN_CPU_DESC cd,
1002 int opindex,
1003 const char ** strp,
1004 CGEN_FIELDS * fields)
fd3c93d5
DB
1005{
1006 const char * errmsg = NULL;
1007 /* Used by scalar operands that still need to be parsed. */
1008 long junk ATTRIBUTE_UNUSED;
1009
1010 switch (opindex)
1011 {
ecd51ad3 1012 case FRV_OPERAND_A0 :
33b71eeb 1013 errmsg = parse_A0 (cd, strp, FRV_OPERAND_A0, (unsigned long *) (& fields->f_A));
ecd51ad3
DB
1014 break;
1015 case FRV_OPERAND_A1 :
33b71eeb 1016 errmsg = parse_A1 (cd, strp, FRV_OPERAND_A1, (unsigned long *) (& fields->f_A));
fd3c93d5
DB
1017 break;
1018 case FRV_OPERAND_ACC40SI :
1019 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Si);
1020 break;
1021 case FRV_OPERAND_ACC40SK :
1022 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Sk);
1023 break;
1024 case FRV_OPERAND_ACC40UI :
1025 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Ui);
1026 break;
1027 case FRV_OPERAND_ACC40UK :
1028 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Uk);
1029 break;
1030 case FRV_OPERAND_ACCGI :
1031 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGi);
1032 break;
1033 case FRV_OPERAND_ACCGK :
1034 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGk);
1035 break;
1036 case FRV_OPERAND_CCI :
1037 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CCi);
1038 break;
1039 case FRV_OPERAND_CPRDOUBLEK :
f7c541f6 1040 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
fd3c93d5
DB
1041 break;
1042 case FRV_OPERAND_CPRI :
1043 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRi);
1044 break;
1045 case FRV_OPERAND_CPRJ :
1046 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRj);
1047 break;
1048 case FRV_OPERAND_CPRK :
1049 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
1050 break;
1051 case FRV_OPERAND_CRI :
1052 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRi);
1053 break;
1054 case FRV_OPERAND_CRJ :
1055 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj);
1056 break;
1057 case FRV_OPERAND_CRJ_FLOAT :
1058 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_float);
1059 break;
1060 case FRV_OPERAND_CRJ_INT :
1061 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_int);
1062 break;
1063 case FRV_OPERAND_CRK :
1064 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRk);
1065 break;
1066 case FRV_OPERAND_FCCI_1 :
1067 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_1);
1068 break;
1069 case FRV_OPERAND_FCCI_2 :
1070 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_2);
1071 break;
1072 case FRV_OPERAND_FCCI_3 :
1073 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_3);
1074 break;
1075 case FRV_OPERAND_FCCK :
1076 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCk);
1077 break;
1078 case FRV_OPERAND_FRDOUBLEI :
f7c541f6 1079 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
fd3c93d5
DB
1080 break;
1081 case FRV_OPERAND_FRDOUBLEJ :
f7c541f6 1082 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
fd3c93d5
DB
1083 break;
1084 case FRV_OPERAND_FRDOUBLEK :
f7c541f6 1085 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
fd3c93d5
DB
1086 break;
1087 case FRV_OPERAND_FRI :
1088 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
1089 break;
1090 case FRV_OPERAND_FRINTI :
1091 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
1092 break;
36c3ae24
NC
1093 case FRV_OPERAND_FRINTIEVEN :
1094 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
1095 break;
fd3c93d5
DB
1096 case FRV_OPERAND_FRINTJ :
1097 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
1098 break;
36c3ae24
NC
1099 case FRV_OPERAND_FRINTJEVEN :
1100 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
1101 break;
fd3c93d5
DB
1102 case FRV_OPERAND_FRINTK :
1103 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1104 break;
36c3ae24
NC
1105 case FRV_OPERAND_FRINTKEVEN :
1106 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1107 break;
fd3c93d5
DB
1108 case FRV_OPERAND_FRJ :
1109 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
1110 break;
1111 case FRV_OPERAND_FRK :
1112 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1113 break;
1114 case FRV_OPERAND_FRKHI :
1115 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1116 break;
1117 case FRV_OPERAND_FRKLO :
1118 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1119 break;
1120 case FRV_OPERAND_GRDOUBLEK :
f7c541f6 1121 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
fd3c93d5
DB
1122 break;
1123 case FRV_OPERAND_GRI :
1124 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRi);
1125 break;
1126 case FRV_OPERAND_GRJ :
1127 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRj);
1128 break;
1129 case FRV_OPERAND_GRK :
1130 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
1131 break;
1132 case FRV_OPERAND_GRKHI :
1133 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
1134 break;
1135 case FRV_OPERAND_GRKLO :
1136 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
1137 break;
1138 case FRV_OPERAND_ICCI_1 :
1139 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_1);
1140 break;
1141 case FRV_OPERAND_ICCI_2 :
1142 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_2);
1143 break;
1144 case FRV_OPERAND_ICCI_3 :
1145 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_3);
1146 break;
1147 case FRV_OPERAND_LI :
33b71eeb 1148 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LI, (unsigned long *) (& fields->f_LI));
fd3c93d5 1149 break;
676a64f4 1150 case FRV_OPERAND_LRAD :
33b71eeb 1151 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAD, (unsigned long *) (& fields->f_LRAD));
676a64f4
RS
1152 break;
1153 case FRV_OPERAND_LRAE :
33b71eeb 1154 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAE, (unsigned long *) (& fields->f_LRAE));
676a64f4
RS
1155 break;
1156 case FRV_OPERAND_LRAS :
33b71eeb 1157 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAS, (unsigned long *) (& fields->f_LRAS));
676a64f4
RS
1158 break;
1159 case FRV_OPERAND_TLBPRL :
33b71eeb 1160 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_TLBPRL, (unsigned long *) (& fields->f_TLBPRL));
676a64f4
RS
1161 break;
1162 case FRV_OPERAND_TLBPROPX :
33b71eeb 1163 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_TLBPROPX, (unsigned long *) (& fields->f_TLBPRopx));
676a64f4 1164 break;
fd3c93d5 1165 case FRV_OPERAND_AE :
33b71eeb 1166 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_AE, (unsigned long *) (& fields->f_ae));
fd3c93d5 1167 break;
90219bd0 1168 case FRV_OPERAND_CALLANN :
33b71eeb 1169 errmsg = parse_call_annotation (cd, strp, FRV_OPERAND_CALLANN, (unsigned long *) (& fields->f_reloc_ann));
90219bd0 1170 break;
fd3c93d5 1171 case FRV_OPERAND_CCOND :
33b71eeb 1172 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_CCOND, (unsigned long *) (& fields->f_ccond));
fd3c93d5
DB
1173 break;
1174 case FRV_OPERAND_COND :
33b71eeb 1175 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_COND, (unsigned long *) (& fields->f_cond));
fd3c93d5
DB
1176 break;
1177 case FRV_OPERAND_D12 :
33b71eeb 1178 errmsg = parse_d12 (cd, strp, FRV_OPERAND_D12, (long *) (& fields->f_d12));
fd3c93d5
DB
1179 break;
1180 case FRV_OPERAND_DEBUG :
33b71eeb 1181 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_DEBUG, (unsigned long *) (& fields->f_debug));
fd3c93d5
DB
1182 break;
1183 case FRV_OPERAND_EIR :
33b71eeb 1184 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_EIR, (unsigned long *) (& fields->f_eir));
fd3c93d5
DB
1185 break;
1186 case FRV_OPERAND_HINT :
33b71eeb 1187 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_HINT, (unsigned long *) (& fields->f_hint));
fd3c93d5
DB
1188 break;
1189 case FRV_OPERAND_HINT_NOT_TAKEN :
1190 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_not_taken, & fields->f_hint);
1191 break;
1192 case FRV_OPERAND_HINT_TAKEN :
1193 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_taken, & fields->f_hint);
1194 break;
1195 case FRV_OPERAND_LABEL16 :
1196 {
9494d739 1197 bfd_vma value = 0;
fd3c93d5
DB
1198 errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL16, 0, NULL, & value);
1199 fields->f_label16 = value;
1200 }
1201 break;
1202 case FRV_OPERAND_LABEL24 :
1203 {
9494d739 1204 bfd_vma value = 0;
90219bd0 1205 errmsg = parse_call_label (cd, strp, FRV_OPERAND_LABEL24, 0, NULL, & value);
fd3c93d5
DB
1206 fields->f_label24 = value;
1207 }
1208 break;
90219bd0 1209 case FRV_OPERAND_LDANN :
33b71eeb 1210 errmsg = parse_ld_annotation (cd, strp, FRV_OPERAND_LDANN, (unsigned long *) (& fields->f_reloc_ann));
90219bd0
AO
1211 break;
1212 case FRV_OPERAND_LDDANN :
33b71eeb 1213 errmsg = parse_ldd_annotation (cd, strp, FRV_OPERAND_LDDANN, (unsigned long *) (& fields->f_reloc_ann));
90219bd0 1214 break;
fd3c93d5 1215 case FRV_OPERAND_LOCK :
33b71eeb 1216 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LOCK, (unsigned long *) (& fields->f_lock));
fd3c93d5
DB
1217 break;
1218 case FRV_OPERAND_PACK :
1219 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_pack, & fields->f_pack);
1220 break;
1221 case FRV_OPERAND_S10 :
33b71eeb 1222 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S10, (long *) (& fields->f_s10));
fd3c93d5
DB
1223 break;
1224 case FRV_OPERAND_S12 :
33b71eeb 1225 errmsg = parse_s12 (cd, strp, FRV_OPERAND_S12, (long *) (& fields->f_d12));
fd3c93d5
DB
1226 break;
1227 case FRV_OPERAND_S16 :
33b71eeb 1228 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S16, (long *) (& fields->f_s16));
fd3c93d5
DB
1229 break;
1230 case FRV_OPERAND_S5 :
33b71eeb 1231 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S5, (long *) (& fields->f_s5));
fd3c93d5
DB
1232 break;
1233 case FRV_OPERAND_S6 :
33b71eeb 1234 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6, (long *) (& fields->f_s6));
fd3c93d5
DB
1235 break;
1236 case FRV_OPERAND_S6_1 :
33b71eeb 1237 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6_1, (long *) (& fields->f_s6_1));
fd3c93d5
DB
1238 break;
1239 case FRV_OPERAND_SLO16 :
33b71eeb 1240 errmsg = parse_uslo16 (cd, strp, FRV_OPERAND_SLO16, (long *) (& fields->f_s16));
fd3c93d5
DB
1241 break;
1242 case FRV_OPERAND_SPR :
1243 errmsg = parse_spr (cd, strp, & frv_cgen_opval_spr_names, & fields->f_spr);
1244 break;
1245 case FRV_OPERAND_U12 :
33b71eeb 1246 errmsg = parse_u12 (cd, strp, FRV_OPERAND_U12, (long *) (& fields->f_u12));
fd3c93d5
DB
1247 break;
1248 case FRV_OPERAND_U16 :
33b71eeb 1249 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U16, (unsigned long *) (& fields->f_u16));
fd3c93d5
DB
1250 break;
1251 case FRV_OPERAND_U6 :
33b71eeb 1252 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U6, (unsigned long *) (& fields->f_u6));
fd3c93d5
DB
1253 break;
1254 case FRV_OPERAND_UHI16 :
33b71eeb 1255 errmsg = parse_uhi16 (cd, strp, FRV_OPERAND_UHI16, (unsigned long *) (& fields->f_u16));
fd3c93d5
DB
1256 break;
1257 case FRV_OPERAND_ULO16 :
33b71eeb 1258 errmsg = parse_ulo16 (cd, strp, FRV_OPERAND_ULO16, (unsigned long *) (& fields->f_u16));
fd3c93d5
DB
1259 break;
1260
1261 default :
1262 /* xgettext:c-format */
a6743a54
AM
1263 opcodes_error_handler
1264 (_("internal error: unrecognized field %d while parsing"),
1265 opindex);
fd3c93d5
DB
1266 abort ();
1267 }
1268
1269 return errmsg;
1270}
1271
43e65147 1272cgen_parse_fn * const frv_cgen_parse_handlers[] =
fd3c93d5
DB
1273{
1274 parse_insn_normal,
1275};
1276
1277void
47b0e7ad 1278frv_cgen_init_asm (CGEN_CPU_DESC cd)
fd3c93d5
DB
1279{
1280 frv_cgen_init_opcode_table (cd);
1281 frv_cgen_init_ibld_table (cd);
1282 cd->parse_handlers = & frv_cgen_parse_handlers[0];
1283 cd->parse_operand = frv_cgen_parse_operand;
1620f33d
AM
1284#ifdef CGEN_ASM_INIT_HOOK
1285CGEN_ASM_INIT_HOOK
1286#endif
fd3c93d5
DB
1287}
1288
1289\f
1290
1291/* Regex construction routine.
1292
1293 This translates an opcode syntax string into a regex string,
1294 by replacing any non-character syntax element (such as an
1295 opcode) with the pattern '.*'
1296
1297 It then compiles the regex and stores it in the opcode, for
1298 later use by frv_cgen_assemble_insn
1299
1300 Returns NULL for success, an error message for failure. */
1301
43e65147 1302char *
ffead7ae 1303frv_cgen_build_insn_regex (CGEN_INSN *insn)
43e65147 1304{
fd3c93d5
DB
1305 CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
1306 const char *mnem = CGEN_INSN_MNEMONIC (insn);
1307 char rxbuf[CGEN_MAX_RX_ELEMENTS];
1308 char *rx = rxbuf;
1309 const CGEN_SYNTAX_CHAR_TYPE *syn;
1310 int reg_err;
1311
1312 syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
1313
1314 /* Mnemonics come first in the syntax string. */
1315 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1316 return _("missing mnemonic in syntax string");
1317 ++syn;
1318
1319 /* Generate a case sensitive regular expression that emulates case
1320 insensitive matching in the "C" locale. We cannot generate a case
1321 insensitive regular expression because in Turkish locales, 'i' and 'I'
1322 are not equal modulo case conversion. */
1323
1324 /* Copy the literal mnemonic out of the insn. */
1325 for (; *mnem; mnem++)
1326 {
1327 char c = *mnem;
1328
1329 if (ISALPHA (c))
1330 {
1331 *rx++ = '[';
1332 *rx++ = TOLOWER (c);
1333 *rx++ = TOUPPER (c);
1334 *rx++ = ']';
1335 }
1336 else
1337 *rx++ = c;
1338 }
1339
1340 /* Copy any remaining literals from the syntax string into the rx. */
1341 for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
1342 {
43e65147 1343 if (CGEN_SYNTAX_CHAR_P (* syn))
fd3c93d5
DB
1344 {
1345 char c = CGEN_SYNTAX_CHAR (* syn);
1346
43e65147 1347 switch (c)
fd3c93d5
DB
1348 {
1349 /* Escape any regex metacharacters in the syntax. */
43e65147
L
1350 case '.': case '[': case '\\':
1351 case '*': case '^': case '$':
fd3c93d5
DB
1352
1353#ifdef CGEN_ESCAPE_EXTENDED_REGEX
43e65147 1354 case '?': case '{': case '}':
fd3c93d5
DB
1355 case '(': case ')': case '*':
1356 case '|': case '+': case ']':
1357#endif
1358 *rx++ = '\\';
1359 *rx++ = c;
1360 break;
1361
1362 default:
1363 if (ISALPHA (c))
1364 {
1365 *rx++ = '[';
1366 *rx++ = TOLOWER (c);
1367 *rx++ = TOUPPER (c);
1368 *rx++ = ']';
1369 }
1370 else
1371 *rx++ = c;
1372 break;
1373 }
1374 }
1375 else
1376 {
1377 /* Replace non-syntax fields with globs. */
1378 *rx++ = '.';
1379 *rx++ = '*';
1380 }
1381 }
1382
1383 /* Trailing whitespace ok. */
43e65147
L
1384 * rx++ = '[';
1385 * rx++ = ' ';
1386 * rx++ = '\t';
1387 * rx++ = ']';
1388 * rx++ = '*';
fd3c93d5
DB
1389
1390 /* But anchor it after that. */
43e65147 1391 * rx++ = '$';
fd3c93d5
DB
1392 * rx = '\0';
1393
1394 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
1395 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
1396
43e65147 1397 if (reg_err == 0)
fd3c93d5
DB
1398 return NULL;
1399 else
1400 {
1401 static char msg[80];
1402
1403 regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
1404 regfree ((regex_t *) CGEN_INSN_RX (insn));
1405 free (CGEN_INSN_RX (insn));
1406 (CGEN_INSN_RX (insn)) = NULL;
1407 return msg;
1408 }
1409}
1410
1411\f
1412/* Default insn parser.
1413
1414 The syntax string is scanned and operands are parsed and stored in FIELDS.
1415 Relocs are queued as we go via other callbacks.
1416
1417 ??? Note that this is currently an all-or-nothing parser. If we fail to
1418 parse the instruction, we return 0 and the caller will start over from
1419 the beginning. Backtracking will be necessary in parsing subexpressions,
1420 but that can be handled there. Not handling backtracking here may get
1421 expensive in the case of the m68k. Deal with later.
1422
1423 Returns NULL for success, an error message for failure. */
1424
1425static const char *
ffead7ae
MM
1426parse_insn_normal (CGEN_CPU_DESC cd,
1427 const CGEN_INSN *insn,
1428 const char **strp,
1429 CGEN_FIELDS *fields)
fd3c93d5
DB
1430{
1431 /* ??? Runtime added insns not handled yet. */
1432 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
1433 const char *str = *strp;
1434 const char *errmsg;
1435 const char *p;
1436 const CGEN_SYNTAX_CHAR_TYPE * syn;
1437#ifdef CGEN_MNEMONIC_OPERANDS
1438 /* FIXME: wip */
1439 int past_opcode_p;
1440#endif
1441
1442 /* For now we assume the mnemonic is first (there are no leading operands).
1443 We can parse it without needing to set up operand parsing.
1444 GAS's input scrubber will ensure mnemonics are lowercase, but we may
1445 not be called from GAS. */
1446 p = CGEN_INSN_MNEMONIC (insn);
1447 while (*p && TOLOWER (*p) == TOLOWER (*str))
1448 ++p, ++str;
1449
1450 if (* p)
1451 return _("unrecognized instruction");
1452
1453#ifndef CGEN_MNEMONIC_OPERANDS
1454 if (* str && ! ISSPACE (* str))
1455 return _("unrecognized instruction");
1456#endif
1457
1458 CGEN_INIT_PARSE (cd);
1459 cgen_init_parse_operand (cd);
1460#ifdef CGEN_MNEMONIC_OPERANDS
1461 past_opcode_p = 0;
1462#endif
1463
1464 /* We don't check for (*str != '\0') here because we want to parse
1465 any trailing fake arguments in the syntax string. */
1466 syn = CGEN_SYNTAX_STRING (syntax);
1467
1468 /* Mnemonics come first for now, ensure valid string. */
1469 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1470 abort ();
1471
1472 ++syn;
1473
1474 while (* syn != 0)
1475 {
1476 /* Non operand chars must match exactly. */
1477 if (CGEN_SYNTAX_CHAR_P (* syn))
1478 {
1479 /* FIXME: While we allow for non-GAS callers above, we assume the
1480 first char after the mnemonic part is a space. */
1481 /* FIXME: We also take inappropriate advantage of the fact that
1482 GAS's input scrubber will remove extraneous blanks. */
1483 if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
1484 {
1485#ifdef CGEN_MNEMONIC_OPERANDS
1486 if (CGEN_SYNTAX_CHAR(* syn) == ' ')
1487 past_opcode_p = 1;
1488#endif
1489 ++ syn;
1490 ++ str;
1491 }
1492 else if (*str)
1493 {
1494 /* Syntax char didn't match. Can't be this insn. */
1495 static char msg [80];
1496
1497 /* xgettext:c-format */
1498 sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
1499 CGEN_SYNTAX_CHAR(*syn), *str);
1500 return msg;
1501 }
1502 else
1503 {
1504 /* Ran out of input. */
1505 static char msg [80];
1506
1507 /* xgettext:c-format */
1508 sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
1509 CGEN_SYNTAX_CHAR(*syn));
1510 return msg;
1511 }
1512 continue;
1513 }
1514
c7e2358a
AM
1515#ifdef CGEN_MNEMONIC_OPERANDS
1516 (void) past_opcode_p;
1517#endif
fd3c93d5 1518 /* We have an operand of some sort. */
c7e2358a 1519 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
fd3c93d5
DB
1520 if (errmsg)
1521 return errmsg;
1522
1523 /* Done with this operand, continue with next one. */
1524 ++ syn;
1525 }
1526
1527 /* If we're at the end of the syntax string, we're done. */
1528 if (* syn == 0)
1529 {
1530 /* FIXME: For the moment we assume a valid `str' can only contain
1531 blanks now. IE: We needn't try again with a longer version of
1532 the insn and it is assumed that longer versions of insns appear
1533 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
1534 while (ISSPACE (* str))
1535 ++ str;
1536
1537 if (* str != '\0')
1538 return _("junk at end of line"); /* FIXME: would like to include `str' */
1539
1540 return NULL;
1541 }
1542
1543 /* We couldn't parse it. */
1544 return _("unrecognized instruction");
1545}
1546\f
1547/* Main entry point.
1548 This routine is called for each instruction to be assembled.
1549 STR points to the insn to be assembled.
1550 We assume all necessary tables have been initialized.
1551 The assembled instruction, less any fixups, is stored in BUF.
1552 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
1553 still needs to be converted to target byte order, otherwise BUF is an array
1554 of bytes in target byte order.
1555 The result is a pointer to the insn's entry in the opcode table,
1556 or NULL if an error occured (an error message will have already been
1557 printed).
1558
1559 Note that when processing (non-alias) macro-insns,
1560 this function recurses.
1561
1562 ??? It's possible to make this cpu-independent.
1563 One would have to deal with a few minor things.
1564 At this point in time doing so would be more of a curiosity than useful
1565 [for example this file isn't _that_ big], but keeping the possibility in
1566 mind helps keep the design clean. */
1567
1568const CGEN_INSN *
ffead7ae
MM
1569frv_cgen_assemble_insn (CGEN_CPU_DESC cd,
1570 const char *str,
1571 CGEN_FIELDS *fields,
1572 CGEN_INSN_BYTES_PTR buf,
1573 char **errmsg)
fd3c93d5
DB
1574{
1575 const char *start;
1576 CGEN_INSN_LIST *ilist;
1577 const char *parse_errmsg = NULL;
1578 const char *insert_errmsg = NULL;
1579 int recognized_mnemonic = 0;
1580
1581 /* Skip leading white space. */
1582 while (ISSPACE (* str))
1583 ++ str;
1584
1585 /* The instructions are stored in hashed lists.
1586 Get the first in the list. */
1587 ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
1588
1589 /* Keep looking until we find a match. */
1590 start = str;
1591 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
1592 {
1593 const CGEN_INSN *insn = ilist->insn;
1594 recognized_mnemonic = 1;
1595
43e65147 1596#ifdef CGEN_VALIDATE_INSN_SUPPORTED
fd3c93d5
DB
1597 /* Not usually needed as unsupported opcodes
1598 shouldn't be in the hash lists. */
1599 /* Is this insn supported by the selected cpu? */
1600 if (! frv_cgen_insn_supported (cd, insn))
1601 continue;
1602#endif
b11dcf4e 1603 /* If the RELAXED attribute is set, this is an insn that shouldn't be
fd3c93d5
DB
1604 chosen immediately. Instead, it is used during assembler/linker
1605 relaxation if possible. */
b11dcf4e 1606 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
fd3c93d5
DB
1607 continue;
1608
1609 str = start;
1610
1611 /* Skip this insn if str doesn't look right lexically. */
1612 if (CGEN_INSN_RX (insn) != NULL &&
1613 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
1614 continue;
1615
1616 /* Allow parse/insert handlers to obtain length of insn. */
1617 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
1618
1619 parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
1620 if (parse_errmsg != NULL)
1621 continue;
1622
1623 /* ??? 0 is passed for `pc'. */
1624 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
1625 (bfd_vma) 0);
1626 if (insert_errmsg != NULL)
1627 continue;
1628
1629 /* It is up to the caller to actually output the insn and any
1630 queued relocs. */
1631 return insn;
1632 }
1633
1634 {
1635 static char errbuf[150];
fd3c93d5 1636 const char *tmp_errmsg;
c7e2358a
AM
1637#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
1638#define be_verbose 1
fd3c93d5 1639#else
c7e2358a 1640#define be_verbose 0
fd3c93d5 1641#endif
c7e2358a
AM
1642
1643 if (be_verbose)
1644 {
1645 /* If requesting verbose error messages, use insert_errmsg.
1646 Failing that, use parse_errmsg. */
1647 tmp_errmsg = (insert_errmsg ? insert_errmsg :
1648 parse_errmsg ? parse_errmsg :
1649 recognized_mnemonic ?
1650 _("unrecognized form of instruction") :
1651 _("unrecognized instruction"));
1652
1653 if (strlen (start) > 50)
1654 /* xgettext:c-format */
1655 sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
43e65147 1656 else
c7e2358a
AM
1657 /* xgettext:c-format */
1658 sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
1659 }
1660 else
1661 {
1662 if (strlen (start) > 50)
1663 /* xgettext:c-format */
1664 sprintf (errbuf, _("bad instruction `%.50s...'"), start);
43e65147 1665 else
c7e2358a
AM
1666 /* xgettext:c-format */
1667 sprintf (errbuf, _("bad instruction `%.50s'"), start);
1668 }
43e65147 1669
fd3c93d5
DB
1670 *errmsg = errbuf;
1671 return NULL;
1672 }
1673}
This page took 0.91644 seconds and 4 git commands to generate.