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