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, 2005, 2007, 2008
8 Free Software Foundation, Inc.
10 This file is part of libopcodes.
12 This library is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 3, or (at your option)
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.
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. */
27 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
39 #include "libiberty.h"
40 #include "safe-ctype.h"
43 #define min(a,b) ((a) < (b) ? (a) : (b))
45 #define max(a,b) ((a) > (b) ? (a) : (b))
47 static const char * parse_insn_normal
48 (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
50 /* -- assembler routines inserted here. */
56 #define CGEN_VALIDATE_INSN_SUPPORTED
58 const char * parse_csrn (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
59 const char * parse_tpreg (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
60 const char * parse_spreg (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
61 const char * parse_mep_align (CGEN_CPU_DESC, const char **, enum cgen_operand_type, long *);
62 const char * parse_mep_alignu (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
63 static const char * parse_signed16 (CGEN_CPU_DESC, const char **, int, long *);
64 static const char * parse_unsigned16 (CGEN_CPU_DESC, const char **, int, unsigned long *);
65 static const char * parse_lo16 (CGEN_CPU_DESC, const char **, int, long *, long);
66 static const char * parse_unsigned7 (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
67 static const char * parse_zero (CGEN_CPU_DESC, const char **, int, long *);
70 parse_csrn (CGEN_CPU_DESC cd, const char **strp,
71 CGEN_KEYWORD *keyword_table, long *field)
76 err = cgen_parse_keyword (cd, strp, keyword_table, field);
80 err = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, & value);
87 /* begin-cop-ip-parse-handlers */
88 /* end-cop-ip-parse-handlers */
91 parse_tpreg (CGEN_CPU_DESC cd, const char ** strp,
92 CGEN_KEYWORD *keyword_table, long *field)
96 err = cgen_parse_keyword (cd, strp, keyword_table, field);
100 return _("Only $tp or $13 allowed for this opcode");
105 parse_spreg (CGEN_CPU_DESC cd, const char ** strp,
106 CGEN_KEYWORD *keyword_table, long *field)
110 err = cgen_parse_keyword (cd, strp, keyword_table, field);
114 return _("Only $sp or $15 allowed for this opcode");
119 parse_mep_align (CGEN_CPU_DESC cd, const char ** strp,
120 enum cgen_operand_type type, long *field)
127 case MEP_OPERAND_PCREL8A2:
128 case MEP_OPERAND_PCREL12A2:
129 case MEP_OPERAND_PCREL17A2:
130 case MEP_OPERAND_PCREL24A2:
131 err = cgen_parse_signed_integer (cd, strp, type, field);
133 case MEP_OPERAND_PCABS24A2:
134 case MEP_OPERAND_UDISP7:
135 case MEP_OPERAND_UDISP7A2:
136 case MEP_OPERAND_UDISP7A4:
137 case MEP_OPERAND_UIMM7A4:
138 case MEP_OPERAND_ADDR24A4:
139 err = cgen_parse_unsigned_integer (cd, strp, type, (unsigned long *) field);
148 case MEP_OPERAND_UDISP7:
151 case MEP_OPERAND_PCREL8A2:
152 case MEP_OPERAND_PCREL12A2:
153 case MEP_OPERAND_PCREL17A2:
154 case MEP_OPERAND_PCREL24A2:
155 case MEP_OPERAND_PCABS24A2:
156 case MEP_OPERAND_UDISP7A2:
159 case MEP_OPERAND_UDISP7A4:
160 case MEP_OPERAND_UIMM7A4:
161 case MEP_OPERAND_ADDR24A4:
167 /* Safe assumption? */
171 return "Value is not aligned enough";
176 parse_mep_alignu (CGEN_CPU_DESC cd, const char ** strp,
177 enum cgen_operand_type type, unsigned long *field)
179 return parse_mep_align (cd, strp, type, (long *) field);
183 /* Handle %lo(), %tpoff(), %sdaoff(), %hi(), and other signed
184 constants in a signed context. */
187 parse_signed16 (CGEN_CPU_DESC cd,
192 return parse_lo16 (cd, strp, opindex, valuep, 1);
196 parse_lo16 (CGEN_CPU_DESC cd,
203 enum cgen_parse_operand_result result_type;
206 if (strncasecmp (*strp, "%lo(", 4) == 0)
209 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
210 & result_type, & value);
212 return _("missing `)'");
215 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
218 *valuep = (long)(short) value;
224 if (strncasecmp (*strp, "%hi(", 4) == 0)
227 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
228 & result_type, & value);
230 return _("missing `)'");
233 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
234 value = (value + 0x8000) >> 16;
239 if (strncasecmp (*strp, "%uhi(", 5) == 0)
242 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
243 & result_type, & value);
245 return _("missing `)'");
248 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
254 if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
257 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
260 return _("missing `)'");
266 if (strncasecmp (*strp, "%tpoff(", 7) == 0)
269 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
272 return _("missing `)'");
279 return _("invalid %function() here");
281 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
285 parse_unsigned16 (CGEN_CPU_DESC cd,
288 unsigned long *valuep)
290 return parse_lo16 (cd, strp, opindex, (long *) valuep, 0);
293 /* A special case of parse_signed16 which accepts only the value zero. */
296 parse_zero (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
299 enum cgen_parse_operand_result result_type;
302 /*fprintf(stderr, "dj: signed parse opindex `%s'\n", *strp);*/
304 /* Prevent ($ry) from being attempted as an expression on 'sw $rx,($ry)'.
305 It will fail and cause ry to be listed as an undefined symbol in the
307 if (strncmp (*strp, "($", 2) == 0)
308 return "not zero"; /* any string will do -- will never be seen. */
310 if (strncasecmp (*strp, "%lo(", 4) == 0)
313 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
314 &result_type, &value);
316 return "missing `)'";
319 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
320 return "not zero"; /* any string will do -- will never be seen. */
325 if (strncasecmp (*strp, "%hi(", 4) == 0)
328 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
329 &result_type, &value);
331 return "missing `)'";
334 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
335 return "not zero"; /* any string will do -- will never be seen. */
340 if (strncasecmp (*strp, "%uhi(", 5) == 0)
343 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
344 &result_type, &value);
346 return "missing `)'";
349 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
350 return "not zero"; /* any string will do -- will never be seen. */
355 if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
358 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
359 &result_type, &value);
361 return "missing `)'";
364 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
365 return "not zero"; /* any string will do -- will never be seen. */
370 if (strncasecmp (*strp, "%tpoff(", 7) == 0)
373 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
374 &result_type, &value);
376 return "missing `)'";
379 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
380 return "not zero"; /* any string will do -- will never be seen. */
386 return "invalid %function() here";
388 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_NONE,
389 &result_type, &value);
391 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
392 return "not zero"; /* any string will do -- will never be seen. */
398 parse_unsigned7 (CGEN_CPU_DESC cd, const char **strp,
399 enum cgen_operand_type opindex, unsigned long *valuep)
404 /* fprintf(stderr, "dj: unsigned7 parse `%s'\n", *strp); */
406 if (strncasecmp (*strp, "%tpoff(", 7) == 0)
412 case MEP_OPERAND_UDISP7:
413 reloc = BFD_RELOC_MEP_TPREL7;
415 case MEP_OPERAND_UDISP7A2:
416 reloc = BFD_RELOC_MEP_TPREL7A2;
418 case MEP_OPERAND_UDISP7A4:
419 reloc = BFD_RELOC_MEP_TPREL7A4;
422 /* Safe assumption? */
425 errmsg = cgen_parse_address (cd, strp, opindex, reloc,
428 return "missing `)'";
435 return _("invalid %function() here");
437 return parse_mep_alignu (cd, strp, opindex, valuep);
440 static ATTRIBUTE_UNUSED const char *
441 parse_cdisp10 (CGEN_CPU_DESC cd,
446 const char *errmsg = 0;
454 case MEP_OPERAND_CDISP10A4:
457 case MEP_OPERAND_CDISP10A2:
460 case MEP_OPERAND_CDISP10:
466 if (MEP_CPU == EF_MEP_CPU_C5)
469 if (strncmp (*strp, "0x0", 3) == 0
470 || (**strp == '0' && *(*strp + 1) != 'x'))
473 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
479 if (value < -512 || value > 511)
480 return _("Immediate is out of range -512 to 511");
484 if (value < -128 || value > 127)
485 return _("Immediate is out of range -128 to 127");
488 if (value & ((1<<alignment)-1))
489 return _("Value is not aligned enough");
491 /* If this field may require a relocation then use larger dsp16. */
492 if (! have_zero && value == 0)
493 return (wide ? _("Immediate is out of range -512 to 511")
494 : _("Immediate is out of range -128 to 127"));
500 /* BEGIN LIGHTWEIGHT MACRO PROCESSOR. */
518 { "sizeof", "(`1.end + (- `1))"},
519 { "startof", "(`1 | 0)" },
520 { "align4", "(`1&(~3))"},
521 /*{ "hi", "(((`1+0x8000)>>16) & 0xffff)" }, */
522 /*{ "lo", "(`1 & 0xffff)" }, */
523 /*{ "sdaoff", "((`1-__sdabase) & 0x7f)"}, */
524 /*{ "tpoff", "((`1-__tpbase) & 0x7f)"}, */
528 static char * expand_string (const char *, int);
531 mep_cgen_expand_macros_and_parse_operand
532 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
535 str_append (char *dest, const char *input, int len)
542 /* printf("str_append: <<%s>>, <<%s>>, %d\n", dest, input, len); */
543 oldlen = (dest ? strlen(dest) : 0);
544 new_dest = realloc (dest, oldlen + len + 1);
545 memset (new_dest + oldlen, 0, len + 1);
546 return strncat (new_dest, input, len);
550 lookup_macro (const char *name)
554 for (m = macros; m->name; ++m)
555 if (strncmp (m->name, name, strlen(m->name)) == 0)
562 expand_macro (arg *args, int narg, macro *mac)
564 char *result = 0, *rescanned_result = 0;
565 char *e = mac->expansion;
569 /* printf("expanding macro %s with %d args\n", mac->name, narg + 1); */
574 ((*(e + 1) - '1') <= MAXARGS) &&
575 ((*(e + 1) - '1') <= narg))
577 result = str_append (result, mark, e - mark);
578 arg = (*(e + 1) - '1');
579 /* printf("replacing `%d with %s\n", arg+1, args[arg].start); */
580 result = str_append (result, args[arg].start, args[arg].len);
588 result = str_append (result, mark, e - mark);
592 rescanned_result = expand_string (result, 0);
594 return rescanned_result;
604 expand_string (const char *in, int first_only)
606 int num_expansions = 0;
611 const char *mark = in;
622 if (*in == '%' && *(in + 1) && (!first_only || num_expansions == 0))
624 macro = lookup_macro (in + 1);
627 /* printf("entering state %d at '%s'...\n", state, in); */
628 result = str_append (result, mark, in - mark);
630 in += 1 + strlen (macro->name);
631 while (*in == ' ') ++in;
641 args[narg].start = in + 1;
655 args[narg].start = (in + 1);
660 /* printf("entering state %d at '%s'...\n", state, in); */
664 expansion = expand_macro (args, narg, macro);
668 result = str_append (result, expansion, strlen (expansion));
674 result = str_append (result, mark, in - mark);
699 result = str_append (result, mark, in - mark);
709 /* END LIGHTWEIGHT MACRO PROCESSOR. */
711 const char * mep_cgen_parse_operand
712 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
715 mep_cgen_expand_macros_and_parse_operand (CGEN_CPU_DESC cd, int opindex,
716 const char ** strp_in, CGEN_FIELDS * fields)
718 const char * errmsg = NULL;
719 char *str = 0, *hold = 0;
720 const char **strp = 0;
722 /* Set up a new pointer to macro-expanded string. */
723 str = expand_string (*strp_in, 1);
724 /* fprintf (stderr, " expanded <<%s>> to <<%s>>\n", *strp_in, str); */
727 strp = (const char **)(&str);
729 errmsg = mep_cgen_parse_operand (cd, opindex, strp, fields);
731 /* Now work out the advance. */
732 if (strlen (str) == 0)
733 *strp_in += strlen (*strp_in);
737 if (strstr (*strp_in, str))
738 /* A macro-expansion was pulled off the front. */
739 *strp_in = strstr (*strp_in, str);
741 /* A non-macro-expansion was pulled off the front. */
742 *strp_in += (str - hold);
751 #define CGEN_ASM_INIT_HOOK (cd->parse_operand = mep_cgen_expand_macros_and_parse_operand);
755 const char * mep_cgen_parse_operand
756 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
758 /* Main entry point for operand parsing.
760 This function is basically just a big switch statement. Earlier versions
761 used tables to look up the function to use, but
762 - if the table contains both assembler and disassembler functions then
763 the disassembler contains much of the assembler and vice-versa,
764 - there's a lot of inlining possibilities as things grow,
765 - using a switch statement avoids the function call overhead.
767 This function could be moved into `parse_insn_normal', but keeping it
768 separate makes clear the interface between `parse_insn_normal' and each of
772 mep_cgen_parse_operand (CGEN_CPU_DESC cd,
775 CGEN_FIELDS * fields)
777 const char * errmsg = NULL;
778 /* Used by scalar operands that still need to be parsed. */
779 long junk ATTRIBUTE_UNUSED;
783 case MEP_OPERAND_ADDR24A4 :
784 errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_ADDR24A4, (unsigned long *) (& fields->f_24u8a4n));
786 case MEP_OPERAND_C5RMUIMM20 :
787 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_C5RMUIMM20, (unsigned long *) (& fields->f_c5_rmuimm20));
789 case MEP_OPERAND_C5RNMUIMM24 :
790 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_C5RNMUIMM24, (unsigned long *) (& fields->f_c5_rnmuimm24));
792 case MEP_OPERAND_CALLNUM :
793 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CALLNUM, (unsigned long *) (& fields->f_callnum));
795 case MEP_OPERAND_CCCC :
796 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CCCC, (unsigned long *) (& fields->f_rm));
798 case MEP_OPERAND_CCRN :
799 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & fields->f_ccrn);
801 case MEP_OPERAND_CDISP10 :
802 errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10, (long *) (& fields->f_cdisp10));
804 case MEP_OPERAND_CDISP10A2 :
805 errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A2, (long *) (& fields->f_cdisp10));
807 case MEP_OPERAND_CDISP10A4 :
808 errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A4, (long *) (& fields->f_cdisp10));
810 case MEP_OPERAND_CDISP10A8 :
811 errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A8, (long *) (& fields->f_cdisp10));
813 case MEP_OPERAND_CDISP12 :
814 errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_CDISP12, (long *) (& fields->f_12s20));
816 case MEP_OPERAND_CIMM4 :
817 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM4, (unsigned long *) (& fields->f_rn));
819 case MEP_OPERAND_CIMM5 :
820 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM5, (unsigned long *) (& fields->f_5u24));
822 case MEP_OPERAND_CODE16 :
823 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE16, (unsigned long *) (& fields->f_16u16));
825 case MEP_OPERAND_CODE24 :
826 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE24, (unsigned long *) (& fields->f_24u4n));
828 case MEP_OPERAND_CP_FLAG :
829 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & junk);
831 case MEP_OPERAND_CRN :
832 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crn);
834 case MEP_OPERAND_CRN64 :
835 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crn);
837 case MEP_OPERAND_CRNX :
838 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crnx);
840 case MEP_OPERAND_CRNX64 :
841 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crnx);
843 case MEP_OPERAND_CSRN :
844 errmsg = parse_csrn (cd, strp, & mep_cgen_opval_h_csr, & fields->f_csrn);
846 case MEP_OPERAND_CSRN_IDX :
847 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, (unsigned long *) (& fields->f_csrn));
849 case MEP_OPERAND_DBG :
850 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
852 case MEP_OPERAND_DEPC :
853 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
855 case MEP_OPERAND_EPC :
856 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
858 case MEP_OPERAND_EXC :
859 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
861 case MEP_OPERAND_HI :
862 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
864 case MEP_OPERAND_LO :
865 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
867 case MEP_OPERAND_LP :
868 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
870 case MEP_OPERAND_MB0 :
871 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
873 case MEP_OPERAND_MB1 :
874 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
876 case MEP_OPERAND_ME0 :
877 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
879 case MEP_OPERAND_ME1 :
880 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
882 case MEP_OPERAND_NPC :
883 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
885 case MEP_OPERAND_OPT :
886 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
888 case MEP_OPERAND_PCABS24A2 :
889 errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_PCABS24A2, (unsigned long *) (& fields->f_24u5a2n));
891 case MEP_OPERAND_PCREL12A2 :
892 errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL12A2, (long *) (& fields->f_12s4a2));
894 case MEP_OPERAND_PCREL17A2 :
895 errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL17A2, (long *) (& fields->f_17s16a2));
897 case MEP_OPERAND_PCREL24A2 :
898 errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL24A2, (long *) (& fields->f_24s5a2n));
900 case MEP_OPERAND_PCREL8A2 :
901 errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL8A2, (long *) (& fields->f_8s8a2));
903 case MEP_OPERAND_PSW :
904 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
906 case MEP_OPERAND_R0 :
907 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
909 case MEP_OPERAND_R1 :
910 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
912 case MEP_OPERAND_RL :
913 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl);
915 case MEP_OPERAND_RL5 :
916 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl5);
918 case MEP_OPERAND_RM :
919 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
921 case MEP_OPERAND_RMA :
922 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
924 case MEP_OPERAND_RN :
925 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
927 case MEP_OPERAND_RN3 :
928 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
930 case MEP_OPERAND_RN3C :
931 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
933 case MEP_OPERAND_RN3L :
934 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
936 case MEP_OPERAND_RN3S :
937 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
939 case MEP_OPERAND_RN3UC :
940 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
942 case MEP_OPERAND_RN3UL :
943 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
945 case MEP_OPERAND_RN3US :
946 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
948 case MEP_OPERAND_RNC :
949 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
951 case MEP_OPERAND_RNL :
952 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
954 case MEP_OPERAND_RNS :
955 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
957 case MEP_OPERAND_RNUC :
958 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
960 case MEP_OPERAND_RNUL :
961 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
963 case MEP_OPERAND_RNUS :
964 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
966 case MEP_OPERAND_SAR :
967 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
969 case MEP_OPERAND_SDISP16 :
970 errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SDISP16, (long *) (& fields->f_16s16));
972 case MEP_OPERAND_SIMM16 :
973 errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SIMM16, (long *) (& fields->f_16s16));
975 case MEP_OPERAND_SIMM6 :
976 errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM6, (long *) (& fields->f_6s8));
978 case MEP_OPERAND_SIMM8 :
979 errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8, (long *) (& fields->f_8s8));
981 case MEP_OPERAND_SP :
982 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
984 case MEP_OPERAND_SPR :
985 errmsg = parse_spreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
987 case MEP_OPERAND_TP :
988 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
990 case MEP_OPERAND_TPR :
991 errmsg = parse_tpreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
993 case MEP_OPERAND_UDISP2 :
994 errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_UDISP2, (long *) (& fields->f_2u6));
996 case MEP_OPERAND_UDISP7 :
997 errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7, (unsigned long *) (& fields->f_7u9));
999 case MEP_OPERAND_UDISP7A2 :
1000 errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A2, (unsigned long *) (& fields->f_7u9a2));
1002 case MEP_OPERAND_UDISP7A4 :
1003 errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A4, (unsigned long *) (& fields->f_7u9a4));
1005 case MEP_OPERAND_UIMM16 :
1006 errmsg = parse_unsigned16 (cd, strp, MEP_OPERAND_UIMM16, (unsigned long *) (& fields->f_16u16));
1008 case MEP_OPERAND_UIMM2 :
1009 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM2, (unsigned long *) (& fields->f_2u10));
1011 case MEP_OPERAND_UIMM24 :
1012 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM24, (unsigned long *) (& fields->f_24u8n));
1014 case MEP_OPERAND_UIMM3 :
1015 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM3, (unsigned long *) (& fields->f_3u5));
1017 case MEP_OPERAND_UIMM4 :
1018 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM4, (unsigned long *) (& fields->f_4u8));
1020 case MEP_OPERAND_UIMM5 :
1021 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM5, (unsigned long *) (& fields->f_5u8));
1023 case MEP_OPERAND_UIMM7A4 :
1024 errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_UIMM7A4, (unsigned long *) (& fields->f_7u9a4));
1026 case MEP_OPERAND_ZERO :
1027 errmsg = parse_zero (cd, strp, MEP_OPERAND_ZERO, (long *) (& junk));
1031 /* xgettext:c-format */
1032 fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
1039 cgen_parse_fn * const mep_cgen_parse_handlers[] =
1045 mep_cgen_init_asm (CGEN_CPU_DESC cd)
1047 mep_cgen_init_opcode_table (cd);
1048 mep_cgen_init_ibld_table (cd);
1049 cd->parse_handlers = & mep_cgen_parse_handlers[0];
1050 cd->parse_operand = mep_cgen_parse_operand;
1051 #ifdef CGEN_ASM_INIT_HOOK
1058 /* Regex construction routine.
1060 This translates an opcode syntax string into a regex string,
1061 by replacing any non-character syntax element (such as an
1062 opcode) with the pattern '.*'
1064 It then compiles the regex and stores it in the opcode, for
1065 later use by mep_cgen_assemble_insn
1067 Returns NULL for success, an error message for failure. */
1070 mep_cgen_build_insn_regex (CGEN_INSN *insn)
1072 CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
1073 const char *mnem = CGEN_INSN_MNEMONIC (insn);
1074 char rxbuf[CGEN_MAX_RX_ELEMENTS];
1076 const CGEN_SYNTAX_CHAR_TYPE *syn;
1079 syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
1081 /* Mnemonics come first in the syntax string. */
1082 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1083 return _("missing mnemonic in syntax string");
1086 /* Generate a case sensitive regular expression that emulates case
1087 insensitive matching in the "C" locale. We cannot generate a case
1088 insensitive regular expression because in Turkish locales, 'i' and 'I'
1089 are not equal modulo case conversion. */
1091 /* Copy the literal mnemonic out of the insn. */
1092 for (; *mnem; mnem++)
1099 *rx++ = TOLOWER (c);
1100 *rx++ = TOUPPER (c);
1107 /* Copy any remaining literals from the syntax string into the rx. */
1108 for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
1110 if (CGEN_SYNTAX_CHAR_P (* syn))
1112 char c = CGEN_SYNTAX_CHAR (* syn);
1116 /* Escape any regex metacharacters in the syntax. */
1117 case '.': case '[': case '\\':
1118 case '*': case '^': case '$':
1120 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
1121 case '?': case '{': case '}':
1122 case '(': case ')': case '*':
1123 case '|': case '+': case ']':
1133 *rx++ = TOLOWER (c);
1134 *rx++ = TOUPPER (c);
1144 /* Replace non-syntax fields with globs. */
1150 /* Trailing whitespace ok. */
1157 /* But anchor it after that. */
1161 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
1162 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
1168 static char msg[80];
1170 regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
1171 regfree ((regex_t *) CGEN_INSN_RX (insn));
1172 free (CGEN_INSN_RX (insn));
1173 (CGEN_INSN_RX (insn)) = NULL;
1179 /* Default insn parser.
1181 The syntax string is scanned and operands are parsed and stored in FIELDS.
1182 Relocs are queued as we go via other callbacks.
1184 ??? Note that this is currently an all-or-nothing parser. If we fail to
1185 parse the instruction, we return 0 and the caller will start over from
1186 the beginning. Backtracking will be necessary in parsing subexpressions,
1187 but that can be handled there. Not handling backtracking here may get
1188 expensive in the case of the m68k. Deal with later.
1190 Returns NULL for success, an error message for failure. */
1193 parse_insn_normal (CGEN_CPU_DESC cd,
1194 const CGEN_INSN *insn,
1196 CGEN_FIELDS *fields)
1198 /* ??? Runtime added insns not handled yet. */
1199 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
1200 const char *str = *strp;
1203 const CGEN_SYNTAX_CHAR_TYPE * syn;
1204 #ifdef CGEN_MNEMONIC_OPERANDS
1209 /* For now we assume the mnemonic is first (there are no leading operands).
1210 We can parse it without needing to set up operand parsing.
1211 GAS's input scrubber will ensure mnemonics are lowercase, but we may
1212 not be called from GAS. */
1213 p = CGEN_INSN_MNEMONIC (insn);
1214 while (*p && TOLOWER (*p) == TOLOWER (*str))
1218 return _("unrecognized instruction");
1220 #ifndef CGEN_MNEMONIC_OPERANDS
1221 if (* str && ! ISSPACE (* str))
1222 return _("unrecognized instruction");
1225 CGEN_INIT_PARSE (cd);
1226 cgen_init_parse_operand (cd);
1227 #ifdef CGEN_MNEMONIC_OPERANDS
1231 /* We don't check for (*str != '\0') here because we want to parse
1232 any trailing fake arguments in the syntax string. */
1233 syn = CGEN_SYNTAX_STRING (syntax);
1235 /* Mnemonics come first for now, ensure valid string. */
1236 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1243 /* Non operand chars must match exactly. */
1244 if (CGEN_SYNTAX_CHAR_P (* syn))
1246 /* FIXME: While we allow for non-GAS callers above, we assume the
1247 first char after the mnemonic part is a space. */
1248 /* FIXME: We also take inappropriate advantage of the fact that
1249 GAS's input scrubber will remove extraneous blanks. */
1250 if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
1252 #ifdef CGEN_MNEMONIC_OPERANDS
1253 if (CGEN_SYNTAX_CHAR(* syn) == ' ')
1261 /* Syntax char didn't match. Can't be this insn. */
1262 static char msg [80];
1264 /* xgettext:c-format */
1265 sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
1266 CGEN_SYNTAX_CHAR(*syn), *str);
1271 /* Ran out of input. */
1272 static char msg [80];
1274 /* xgettext:c-format */
1275 sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
1276 CGEN_SYNTAX_CHAR(*syn));
1282 /* We have an operand of some sort. */
1283 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
1288 /* Done with this operand, continue with next one. */
1292 /* If we're at the end of the syntax string, we're done. */
1295 /* FIXME: For the moment we assume a valid `str' can only contain
1296 blanks now. IE: We needn't try again with a longer version of
1297 the insn and it is assumed that longer versions of insns appear
1298 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
1299 while (ISSPACE (* str))
1303 return _("junk at end of line"); /* FIXME: would like to include `str' */
1308 /* We couldn't parse it. */
1309 return _("unrecognized instruction");
1312 /* Main entry point.
1313 This routine is called for each instruction to be assembled.
1314 STR points to the insn to be assembled.
1315 We assume all necessary tables have been initialized.
1316 The assembled instruction, less any fixups, is stored in BUF.
1317 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
1318 still needs to be converted to target byte order, otherwise BUF is an array
1319 of bytes in target byte order.
1320 The result is a pointer to the insn's entry in the opcode table,
1321 or NULL if an error occured (an error message will have already been
1324 Note that when processing (non-alias) macro-insns,
1325 this function recurses.
1327 ??? It's possible to make this cpu-independent.
1328 One would have to deal with a few minor things.
1329 At this point in time doing so would be more of a curiosity than useful
1330 [for example this file isn't _that_ big], but keeping the possibility in
1331 mind helps keep the design clean. */
1334 mep_cgen_assemble_insn (CGEN_CPU_DESC cd,
1336 CGEN_FIELDS *fields,
1337 CGEN_INSN_BYTES_PTR buf,
1341 CGEN_INSN_LIST *ilist;
1342 const char *parse_errmsg = NULL;
1343 const char *insert_errmsg = NULL;
1344 int recognized_mnemonic = 0;
1346 /* Skip leading white space. */
1347 while (ISSPACE (* str))
1350 /* The instructions are stored in hashed lists.
1351 Get the first in the list. */
1352 ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
1354 /* Keep looking until we find a match. */
1356 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
1358 const CGEN_INSN *insn = ilist->insn;
1359 recognized_mnemonic = 1;
1361 #ifdef CGEN_VALIDATE_INSN_SUPPORTED
1362 /* Not usually needed as unsupported opcodes
1363 shouldn't be in the hash lists. */
1364 /* Is this insn supported by the selected cpu? */
1365 if (! mep_cgen_insn_supported (cd, insn))
1368 /* If the RELAXED attribute is set, this is an insn that shouldn't be
1369 chosen immediately. Instead, it is used during assembler/linker
1370 relaxation if possible. */
1371 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
1376 /* Skip this insn if str doesn't look right lexically. */
1377 if (CGEN_INSN_RX (insn) != NULL &&
1378 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
1381 /* Allow parse/insert handlers to obtain length of insn. */
1382 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
1384 parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
1385 if (parse_errmsg != NULL)
1388 /* ??? 0 is passed for `pc'. */
1389 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
1391 if (insert_errmsg != NULL)
1394 /* It is up to the caller to actually output the insn and any
1400 static char errbuf[150];
1401 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
1402 const char *tmp_errmsg;
1404 /* If requesting verbose error messages, use insert_errmsg.
1405 Failing that, use parse_errmsg. */
1406 tmp_errmsg = (insert_errmsg ? insert_errmsg :
1407 parse_errmsg ? parse_errmsg :
1408 recognized_mnemonic ?
1409 _("unrecognized form of instruction") :
1410 _("unrecognized instruction"));
1412 if (strlen (start) > 50)
1413 /* xgettext:c-format */
1414 sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
1416 /* xgettext:c-format */
1417 sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
1419 if (strlen (start) > 50)
1420 /* xgettext:c-format */
1421 sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1423 /* xgettext:c-format */
1424 sprintf (errbuf, _("bad instruction `%.50s'"), start);