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)
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.
37 #include "libiberty.h"
38 #include "safe-ctype.h"
41 #define min(a,b) ((a) < (b) ? (a) : (b))
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. */
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, unsigned 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 *));
71 parse_ulo16 (cd, strp, opindex, valuep)
75 unsigned long *valuep;
78 enum cgen_parse_operand_result result_type;
81 if (**strp == '#' || **strp == '%')
83 if (strncasecmp (*strp + 1, "lo(", 3) == 0)
86 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
87 &result_type, &value);
92 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
97 if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
100 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO,
101 &result_type, &value);
103 return "missing ')'";
106 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
112 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
116 parse_uslo16 (cd, strp, opindex, valuep)
120 unsigned long *valuep;
123 enum cgen_parse_operand_result result_type;
126 if (**strp == '#' || **strp == '%')
128 if (strncasecmp (*strp + 1, "lo(", 3) == 0)
131 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
132 &result_type, &value);
134 return "missing `)'";
137 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
142 else if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
145 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO,
146 &result_type, &value);
148 return "missing ')'";
151 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
157 return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
161 parse_uhi16 (cd, strp, opindex, valuep)
165 unsigned long *valuep;
168 enum cgen_parse_operand_result result_type;
171 if (**strp == '#' || **strp == '%')
173 if (strncasecmp (*strp + 1, "hi(", 3) == 0)
176 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16,
177 &result_type, &value);
179 return "missing `)'";
182 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
187 else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0)
190 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELHI,
191 &result_type, &value);
193 return "missing ')'";
196 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
202 return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
206 parse_register_number (strp)
210 if (**strp < '0' || **strp > '9')
211 return -1; /* error */
213 regno = **strp - '0';
214 for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp)
215 regno = regno * 10 + (**strp - '0');
221 parse_spr (cd, strp, table, valuep)
224 CGEN_KEYWORD * table;
227 const char *save_strp;
230 /* Check for spr index notation. */
231 if (strncasecmp (*strp, "spr[", 4) == 0)
234 regno = parse_register_number (strp);
236 return "missing `]'";
238 if (! spr_valid (regno))
239 return "Special purpose register number is out of range";
245 regno = parse_register_number (strp);
248 if (! spr_valid (regno))
249 return "Special purpose register number is out of range";
255 return cgen_parse_keyword (cd, strp, table, valuep);
259 parse_d12 (cd, strp, opindex, valuep)
266 enum cgen_parse_operand_result result_type;
269 /* Check for small data reference. */
270 if (**strp == '#' || **strp == '%')
272 if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
275 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12,
276 &result_type, &value);
278 return "missing `)'";
284 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
288 parse_s12 (cd, strp, opindex, valuep)
295 enum cgen_parse_operand_result result_type;
298 /* Check for small data reference. */
299 if ((**strp == '#' || **strp == '%')
300 && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
303 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12,
304 &result_type, &value);
306 return "missing `)'";
315 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
320 parse_u12 (cd, strp, opindex, valuep)
327 enum cgen_parse_operand_result result_type;
330 /* Check for small data reference. */
331 if ((**strp == '#' || **strp == '%')
332 && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
335 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELU12,
336 &result_type, &value);
338 return "missing `)'";
347 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
352 parse_even_register (cd, strP, tableP, valueP)
355 CGEN_KEYWORD * tableP;
359 const char * saved_star_strP = * strP;
361 errmsg = cgen_parse_keyword (cd, strP, tableP, valueP);
363 if (errmsg == NULL && ((* valueP) & 1))
365 errmsg = _("register number must be even");
366 * strP = saved_star_strP;
373 const char * frv_cgen_parse_operand
374 PARAMS ((CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *));
376 /* Main entry point for operand parsing.
378 This function is basically just a big switch statement. Earlier versions
379 used tables to look up the function to use, but
380 - if the table contains both assembler and disassembler functions then
381 the disassembler contains much of the assembler and vice-versa,
382 - there's a lot of inlining possibilities as things grow,
383 - using a switch statement avoids the function call overhead.
385 This function could be moved into `parse_insn_normal', but keeping it
386 separate makes clear the interface between `parse_insn_normal' and each of
390 frv_cgen_parse_operand (cd, opindex, strp, fields)
394 CGEN_FIELDS * fields;
396 const char * errmsg = NULL;
397 /* Used by scalar operands that still need to be parsed. */
398 long junk ATTRIBUTE_UNUSED;
403 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_A, &fields->f_A);
405 case FRV_OPERAND_ACC40SI :
406 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Si);
408 case FRV_OPERAND_ACC40SK :
409 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Sk);
411 case FRV_OPERAND_ACC40UI :
412 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Ui);
414 case FRV_OPERAND_ACC40UK :
415 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Uk);
417 case FRV_OPERAND_ACCGI :
418 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGi);
420 case FRV_OPERAND_ACCGK :
421 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGk);
423 case FRV_OPERAND_CCI :
424 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CCi);
426 case FRV_OPERAND_CPRDOUBLEK :
427 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
429 case FRV_OPERAND_CPRI :
430 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRi);
432 case FRV_OPERAND_CPRJ :
433 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRj);
435 case FRV_OPERAND_CPRK :
436 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
438 case FRV_OPERAND_CRI :
439 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRi);
441 case FRV_OPERAND_CRJ :
442 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj);
444 case FRV_OPERAND_CRJ_FLOAT :
445 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_float);
447 case FRV_OPERAND_CRJ_INT :
448 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_int);
450 case FRV_OPERAND_CRK :
451 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRk);
453 case FRV_OPERAND_FCCI_1 :
454 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_1);
456 case FRV_OPERAND_FCCI_2 :
457 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_2);
459 case FRV_OPERAND_FCCI_3 :
460 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_3);
462 case FRV_OPERAND_FCCK :
463 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCk);
465 case FRV_OPERAND_FRDOUBLEI :
466 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
468 case FRV_OPERAND_FRDOUBLEJ :
469 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
471 case FRV_OPERAND_FRDOUBLEK :
472 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
474 case FRV_OPERAND_FRI :
475 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
477 case FRV_OPERAND_FRINTI :
478 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
480 case FRV_OPERAND_FRINTIEVEN :
481 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
483 case FRV_OPERAND_FRINTJ :
484 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
486 case FRV_OPERAND_FRINTJEVEN :
487 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
489 case FRV_OPERAND_FRINTK :
490 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
492 case FRV_OPERAND_FRINTKEVEN :
493 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
495 case FRV_OPERAND_FRJ :
496 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
498 case FRV_OPERAND_FRK :
499 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
501 case FRV_OPERAND_FRKHI :
502 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
504 case FRV_OPERAND_FRKLO :
505 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
507 case FRV_OPERAND_GRDOUBLEK :
508 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
510 case FRV_OPERAND_GRI :
511 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRi);
513 case FRV_OPERAND_GRJ :
514 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRj);
516 case FRV_OPERAND_GRK :
517 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
519 case FRV_OPERAND_GRKHI :
520 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
522 case FRV_OPERAND_GRKLO :
523 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
525 case FRV_OPERAND_ICCI_1 :
526 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_1);
528 case FRV_OPERAND_ICCI_2 :
529 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_2);
531 case FRV_OPERAND_ICCI_3 :
532 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_3);
534 case FRV_OPERAND_LI :
535 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LI, &fields->f_LI);
537 case FRV_OPERAND_AE :
538 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_AE, &fields->f_ae);
540 case FRV_OPERAND_CCOND :
541 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_CCOND, &fields->f_ccond);
543 case FRV_OPERAND_COND :
544 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_COND, &fields->f_cond);
546 case FRV_OPERAND_D12 :
547 errmsg = parse_d12 (cd, strp, FRV_OPERAND_D12, &fields->f_d12);
549 case FRV_OPERAND_DEBUG :
550 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_DEBUG, &fields->f_debug);
552 case FRV_OPERAND_EIR :
553 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_EIR, &fields->f_eir);
555 case FRV_OPERAND_HINT :
556 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_HINT, &fields->f_hint);
558 case FRV_OPERAND_HINT_NOT_TAKEN :
559 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_not_taken, & fields->f_hint);
561 case FRV_OPERAND_HINT_TAKEN :
562 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_taken, & fields->f_hint);
564 case FRV_OPERAND_LABEL16 :
567 errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL16, 0, NULL, & value);
568 fields->f_label16 = value;
571 case FRV_OPERAND_LABEL24 :
574 errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL24, 0, NULL, & value);
575 fields->f_label24 = value;
578 case FRV_OPERAND_LOCK :
579 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LOCK, &fields->f_lock);
581 case FRV_OPERAND_PACK :
582 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_pack, & fields->f_pack);
584 case FRV_OPERAND_S10 :
585 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S10, &fields->f_s10);
587 case FRV_OPERAND_S12 :
588 errmsg = parse_s12 (cd, strp, FRV_OPERAND_S12, &fields->f_d12);
590 case FRV_OPERAND_S16 :
591 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S16, &fields->f_s16);
593 case FRV_OPERAND_S5 :
594 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S5, &fields->f_s5);
596 case FRV_OPERAND_S6 :
597 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6, &fields->f_s6);
599 case FRV_OPERAND_S6_1 :
600 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6_1, &fields->f_s6_1);
602 case FRV_OPERAND_SLO16 :
603 errmsg = parse_uslo16 (cd, strp, FRV_OPERAND_SLO16, &fields->f_s16);
605 case FRV_OPERAND_SPR :
606 errmsg = parse_spr (cd, strp, & frv_cgen_opval_spr_names, & fields->f_spr);
608 case FRV_OPERAND_U12 :
609 errmsg = parse_u12 (cd, strp, FRV_OPERAND_U12, &fields->f_u12);
611 case FRV_OPERAND_U16 :
612 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U16, &fields->f_u16);
614 case FRV_OPERAND_U6 :
615 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U6, &fields->f_u6);
617 case FRV_OPERAND_UHI16 :
618 errmsg = parse_uhi16 (cd, strp, FRV_OPERAND_UHI16, &fields->f_u16);
620 case FRV_OPERAND_ULO16 :
621 errmsg = parse_ulo16 (cd, strp, FRV_OPERAND_ULO16, &fields->f_u16);
625 /* xgettext:c-format */
626 fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
633 cgen_parse_fn * const frv_cgen_parse_handlers[] =
639 frv_cgen_init_asm (cd)
642 frv_cgen_init_opcode_table (cd);
643 frv_cgen_init_ibld_table (cd);
644 cd->parse_handlers = & frv_cgen_parse_handlers[0];
645 cd->parse_operand = frv_cgen_parse_operand;
650 /* Regex construction routine.
652 This translates an opcode syntax string into a regex string,
653 by replacing any non-character syntax element (such as an
654 opcode) with the pattern '.*'
656 It then compiles the regex and stores it in the opcode, for
657 later use by frv_cgen_assemble_insn
659 Returns NULL for success, an error message for failure. */
662 frv_cgen_build_insn_regex (CGEN_INSN *insn)
664 CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
665 const char *mnem = CGEN_INSN_MNEMONIC (insn);
666 char rxbuf[CGEN_MAX_RX_ELEMENTS];
668 const CGEN_SYNTAX_CHAR_TYPE *syn;
671 syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
673 /* Mnemonics come first in the syntax string. */
674 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
675 return _("missing mnemonic in syntax string");
678 /* Generate a case sensitive regular expression that emulates case
679 insensitive matching in the "C" locale. We cannot generate a case
680 insensitive regular expression because in Turkish locales, 'i' and 'I'
681 are not equal modulo case conversion. */
683 /* Copy the literal mnemonic out of the insn. */
684 for (; *mnem; mnem++)
699 /* Copy any remaining literals from the syntax string into the rx. */
700 for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
702 if (CGEN_SYNTAX_CHAR_P (* syn))
704 char c = CGEN_SYNTAX_CHAR (* syn);
708 /* Escape any regex metacharacters in the syntax. */
709 case '.': case '[': case '\\':
710 case '*': case '^': case '$':
712 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
713 case '?': case '{': case '}':
714 case '(': case ')': case '*':
715 case '|': case '+': case ']':
736 /* Replace non-syntax fields with globs. */
742 /* Trailing whitespace ok. */
749 /* But anchor it after that. */
753 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
754 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
762 regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
763 regfree ((regex_t *) CGEN_INSN_RX (insn));
764 free (CGEN_INSN_RX (insn));
765 (CGEN_INSN_RX (insn)) = NULL;
771 /* Default insn parser.
773 The syntax string is scanned and operands are parsed and stored in FIELDS.
774 Relocs are queued as we go via other callbacks.
776 ??? Note that this is currently an all-or-nothing parser. If we fail to
777 parse the instruction, we return 0 and the caller will start over from
778 the beginning. Backtracking will be necessary in parsing subexpressions,
779 but that can be handled there. Not handling backtracking here may get
780 expensive in the case of the m68k. Deal with later.
782 Returns NULL for success, an error message for failure. */
785 parse_insn_normal (CGEN_CPU_DESC cd,
786 const CGEN_INSN *insn,
790 /* ??? Runtime added insns not handled yet. */
791 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
792 const char *str = *strp;
795 const CGEN_SYNTAX_CHAR_TYPE * syn;
796 #ifdef CGEN_MNEMONIC_OPERANDS
801 /* For now we assume the mnemonic is first (there are no leading operands).
802 We can parse it without needing to set up operand parsing.
803 GAS's input scrubber will ensure mnemonics are lowercase, but we may
804 not be called from GAS. */
805 p = CGEN_INSN_MNEMONIC (insn);
806 while (*p && TOLOWER (*p) == TOLOWER (*str))
810 return _("unrecognized instruction");
812 #ifndef CGEN_MNEMONIC_OPERANDS
813 if (* str && ! ISSPACE (* str))
814 return _("unrecognized instruction");
817 CGEN_INIT_PARSE (cd);
818 cgen_init_parse_operand (cd);
819 #ifdef CGEN_MNEMONIC_OPERANDS
823 /* We don't check for (*str != '\0') here because we want to parse
824 any trailing fake arguments in the syntax string. */
825 syn = CGEN_SYNTAX_STRING (syntax);
827 /* Mnemonics come first for now, ensure valid string. */
828 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
835 /* Non operand chars must match exactly. */
836 if (CGEN_SYNTAX_CHAR_P (* syn))
838 /* FIXME: While we allow for non-GAS callers above, we assume the
839 first char after the mnemonic part is a space. */
840 /* FIXME: We also take inappropriate advantage of the fact that
841 GAS's input scrubber will remove extraneous blanks. */
842 if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
844 #ifdef CGEN_MNEMONIC_OPERANDS
845 if (CGEN_SYNTAX_CHAR(* syn) == ' ')
853 /* Syntax char didn't match. Can't be this insn. */
854 static char msg [80];
856 /* xgettext:c-format */
857 sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
858 CGEN_SYNTAX_CHAR(*syn), *str);
863 /* Ran out of input. */
864 static char msg [80];
866 /* xgettext:c-format */
867 sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
868 CGEN_SYNTAX_CHAR(*syn));
874 /* We have an operand of some sort. */
875 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
880 /* Done with this operand, continue with next one. */
884 /* If we're at the end of the syntax string, we're done. */
887 /* FIXME: For the moment we assume a valid `str' can only contain
888 blanks now. IE: We needn't try again with a longer version of
889 the insn and it is assumed that longer versions of insns appear
890 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
891 while (ISSPACE (* str))
895 return _("junk at end of line"); /* FIXME: would like to include `str' */
900 /* We couldn't parse it. */
901 return _("unrecognized instruction");
905 This routine is called for each instruction to be assembled.
906 STR points to the insn to be assembled.
907 We assume all necessary tables have been initialized.
908 The assembled instruction, less any fixups, is stored in BUF.
909 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
910 still needs to be converted to target byte order, otherwise BUF is an array
911 of bytes in target byte order.
912 The result is a pointer to the insn's entry in the opcode table,
913 or NULL if an error occured (an error message will have already been
916 Note that when processing (non-alias) macro-insns,
917 this function recurses.
919 ??? It's possible to make this cpu-independent.
920 One would have to deal with a few minor things.
921 At this point in time doing so would be more of a curiosity than useful
922 [for example this file isn't _that_ big], but keeping the possibility in
923 mind helps keep the design clean. */
926 frv_cgen_assemble_insn (CGEN_CPU_DESC cd,
929 CGEN_INSN_BYTES_PTR buf,
933 CGEN_INSN_LIST *ilist;
934 const char *parse_errmsg = NULL;
935 const char *insert_errmsg = NULL;
936 int recognized_mnemonic = 0;
938 /* Skip leading white space. */
939 while (ISSPACE (* str))
942 /* The instructions are stored in hashed lists.
943 Get the first in the list. */
944 ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
946 /* Keep looking until we find a match. */
948 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
950 const CGEN_INSN *insn = ilist->insn;
951 recognized_mnemonic = 1;
953 #ifdef CGEN_VALIDATE_INSN_SUPPORTED
954 /* Not usually needed as unsupported opcodes
955 shouldn't be in the hash lists. */
956 /* Is this insn supported by the selected cpu? */
957 if (! frv_cgen_insn_supported (cd, insn))
960 /* If the RELAXED attribute is set, this is an insn that shouldn't be
961 chosen immediately. Instead, it is used during assembler/linker
962 relaxation if possible. */
963 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
968 /* Skip this insn if str doesn't look right lexically. */
969 if (CGEN_INSN_RX (insn) != NULL &&
970 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
973 /* Allow parse/insert handlers to obtain length of insn. */
974 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
976 parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
977 if (parse_errmsg != NULL)
980 /* ??? 0 is passed for `pc'. */
981 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
983 if (insert_errmsg != NULL)
986 /* It is up to the caller to actually output the insn and any
992 static char errbuf[150];
993 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
994 const char *tmp_errmsg;
996 /* If requesting verbose error messages, use insert_errmsg.
997 Failing that, use parse_errmsg. */
998 tmp_errmsg = (insert_errmsg ? insert_errmsg :
999 parse_errmsg ? parse_errmsg :
1000 recognized_mnemonic ?
1001 _("unrecognized form of instruction") :
1002 _("unrecognized instruction"));
1004 if (strlen (start) > 50)
1005 /* xgettext:c-format */
1006 sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
1008 /* xgettext:c-format */
1009 sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
1011 if (strlen (start) > 50)
1012 /* xgettext:c-format */
1013 sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1015 /* xgettext:c-format */
1016 sprintf (errbuf, _("bad instruction `%.50s'"), start);
1024 #if 0 /* This calls back to GAS which we can't do without care. */
1026 /* Record each member of OPVALS in the assembler's symbol table.
1027 This lets GAS parse registers for us.
1028 ??? Interesting idea but not currently used. */
1030 /* Record each member of OPVALS in the assembler's symbol table.
1031 FIXME: Not currently used. */
1034 frv_cgen_asm_hash_keywords (CGEN_CPU_DESC cd, CGEN_KEYWORD *opvals)
1036 CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
1037 const CGEN_KEYWORD_ENTRY * ke;
1039 while ((ke = cgen_keyword_search_next (& search)) != NULL)
1041 #if 0 /* Unnecessary, should be done in the search routine. */
1042 if (! frv_cgen_opval_supported (ke))
1045 cgen_asm_record_register (cd, ke->name, ke->value);