* mep.h (EF_MEP_COP_*): New.
[binutils.git] / opcodes / mep-asm.c
blob41a1f92fd092eef769f3c265c30c60e07264bb41
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)
15 any later version.
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.
28 Keep that in mind. */
30 #include "sysdep.h"
31 #include <stdio.h>
32 #include "ansidecl.h"
33 #include "bfd.h"
34 #include "symcat.h"
35 #include "mep-desc.h"
36 #include "mep-opc.h"
37 #include "opintl.h"
38 #include "xregex.h"
39 #include "libiberty.h"
40 #include "safe-ctype.h"
42 #undef min
43 #define min(a,b) ((a) < (b) ? (a) : (b))
44 #undef max
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. */
52 /* -- asm.c */
54 #include "elf/mep.h"
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 *);
69 const char *
70 parse_csrn (CGEN_CPU_DESC cd, const char **strp,
71 CGEN_KEYWORD *keyword_table, long *field)
73 const char *err;
74 unsigned long value;
76 err = cgen_parse_keyword (cd, strp, keyword_table, field);
77 if (!err)
78 return NULL;
80 err = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, & value);
81 if (err)
82 return err;
83 *field = value;
84 return NULL;
87 /* begin-cop-ip-parse-handlers */
88 /* end-cop-ip-parse-handlers */
90 const char *
91 parse_tpreg (CGEN_CPU_DESC cd, const char ** strp,
92 CGEN_KEYWORD *keyword_table, long *field)
94 const char *err;
96 err = cgen_parse_keyword (cd, strp, keyword_table, field);
97 if (err)
98 return err;
99 if (*field != 13)
100 return _("Only $tp or $13 allowed for this opcode");
101 return NULL;
104 const char *
105 parse_spreg (CGEN_CPU_DESC cd, const char ** strp,
106 CGEN_KEYWORD *keyword_table, long *field)
108 const char *err;
110 err = cgen_parse_keyword (cd, strp, keyword_table, field);
111 if (err)
112 return err;
113 if (*field != 15)
114 return _("Only $sp or $15 allowed for this opcode");
115 return NULL;
118 const char *
119 parse_mep_align (CGEN_CPU_DESC cd, const char ** strp,
120 enum cgen_operand_type type, long *field)
122 long lsbs = 0;
123 const char *err;
125 switch (type)
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);
132 break;
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);
140 break;
141 default:
142 abort();
144 if (err)
145 return err;
146 switch (type)
148 case MEP_OPERAND_UDISP7:
149 lsbs = 0;
150 break;
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:
157 lsbs = *field & 1;
158 break;
159 case MEP_OPERAND_UDISP7A4:
160 case MEP_OPERAND_UIMM7A4:
161 case MEP_OPERAND_ADDR24A4:
162 lsbs = *field & 3;
163 break;
164 lsbs = *field & 7;
165 break;
166 default:
167 /* Safe assumption? */
168 abort ();
170 if (lsbs)
171 return "Value is not aligned enough";
172 return NULL;
175 const char *
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. */
186 static const char *
187 parse_signed16 (CGEN_CPU_DESC cd,
188 const char **strp,
189 int opindex,
190 long *valuep)
192 return parse_lo16 (cd, strp, opindex, valuep, 1);
195 static const char *
196 parse_lo16 (CGEN_CPU_DESC cd,
197 const char **strp,
198 int opindex,
199 long *valuep,
200 long signedp)
202 const char *errmsg;
203 enum cgen_parse_operand_result result_type;
204 bfd_vma value;
206 if (strncasecmp (*strp, "%lo(", 4) == 0)
208 *strp += 4;
209 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
210 & result_type, & value);
211 if (**strp != ')')
212 return _("missing `)'");
213 ++*strp;
214 if (errmsg == NULL
215 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
216 value &= 0xffff;
217 if (signedp)
218 *valuep = (long)(short) value;
219 else
220 *valuep = value;
221 return errmsg;
224 if (strncasecmp (*strp, "%hi(", 4) == 0)
226 *strp += 4;
227 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
228 & result_type, & value);
229 if (**strp != ')')
230 return _("missing `)'");
231 ++*strp;
232 if (errmsg == NULL
233 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
234 value = (value + 0x8000) >> 16;
235 *valuep = value;
236 return errmsg;
239 if (strncasecmp (*strp, "%uhi(", 5) == 0)
241 *strp += 5;
242 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
243 & result_type, & value);
244 if (**strp != ')')
245 return _("missing `)'");
246 ++*strp;
247 if (errmsg == NULL
248 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
249 value = value >> 16;
250 *valuep = value;
251 return errmsg;
254 if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
256 *strp += 8;
257 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
258 NULL, & value);
259 if (**strp != ')')
260 return _("missing `)'");
261 ++*strp;
262 *valuep = value;
263 return errmsg;
266 if (strncasecmp (*strp, "%tpoff(", 7) == 0)
268 *strp += 7;
269 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
270 NULL, & value);
271 if (**strp != ')')
272 return _("missing `)'");
273 ++*strp;
274 *valuep = value;
275 return errmsg;
278 if (**strp == '%')
279 return _("invalid %function() here");
281 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
284 static const char *
285 parse_unsigned16 (CGEN_CPU_DESC cd,
286 const char **strp,
287 int opindex,
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. */
295 static const char *
296 parse_zero (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
298 const char *errmsg;
299 enum cgen_parse_operand_result result_type;
300 bfd_vma value;
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
306 listing. */
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)
312 *strp += 4;
313 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
314 &result_type, &value);
315 if (**strp != ')')
316 return "missing `)'";
317 ++*strp;
318 if (errmsg == NULL
319 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
320 return "not zero"; /* any string will do -- will never be seen. */
321 *valuep = value;
322 return errmsg;
325 if (strncasecmp (*strp, "%hi(", 4) == 0)
327 *strp += 4;
328 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
329 &result_type, &value);
330 if (**strp != ')')
331 return "missing `)'";
332 ++*strp;
333 if (errmsg == NULL
334 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
335 return "not zero"; /* any string will do -- will never be seen. */
336 *valuep = value;
337 return errmsg;
340 if (strncasecmp (*strp, "%uhi(", 5) == 0)
342 *strp += 5;
343 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
344 &result_type, &value);
345 if (**strp != ')')
346 return "missing `)'";
347 ++*strp;
348 if (errmsg == NULL
349 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
350 return "not zero"; /* any string will do -- will never be seen. */
351 *valuep = value;
352 return errmsg;
355 if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
357 *strp += 8;
358 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
359 &result_type, &value);
360 if (**strp != ')')
361 return "missing `)'";
362 ++*strp;
363 if (errmsg == NULL
364 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
365 return "not zero"; /* any string will do -- will never be seen. */
366 *valuep = value;
367 return errmsg;
370 if (strncasecmp (*strp, "%tpoff(", 7) == 0)
372 *strp += 7;
373 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
374 &result_type, &value);
375 if (**strp != ')')
376 return "missing `)'";
377 ++*strp;
378 if (errmsg == NULL
379 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
380 return "not zero"; /* any string will do -- will never be seen. */
381 *valuep = value;
382 return errmsg;
385 if (**strp == '%')
386 return "invalid %function() here";
388 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_NONE,
389 &result_type, &value);
390 if (errmsg == NULL
391 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
392 return "not zero"; /* any string will do -- will never be seen. */
394 return errmsg;
397 static const char *
398 parse_unsigned7 (CGEN_CPU_DESC cd, const char **strp,
399 enum cgen_operand_type opindex, unsigned long *valuep)
401 const char *errmsg;
402 bfd_vma value;
404 /* fprintf(stderr, "dj: unsigned7 parse `%s'\n", *strp); */
406 if (strncasecmp (*strp, "%tpoff(", 7) == 0)
408 int reloc;
409 *strp += 7;
410 switch (opindex)
412 case MEP_OPERAND_UDISP7:
413 reloc = BFD_RELOC_MEP_TPREL7;
414 break;
415 case MEP_OPERAND_UDISP7A2:
416 reloc = BFD_RELOC_MEP_TPREL7A2;
417 break;
418 case MEP_OPERAND_UDISP7A4:
419 reloc = BFD_RELOC_MEP_TPREL7A4;
420 break;
421 default:
422 /* Safe assumption? */
423 abort ();
425 errmsg = cgen_parse_address (cd, strp, opindex, reloc,
426 NULL, &value);
427 if (**strp != ')')
428 return "missing `)'";
429 ++*strp;
430 *valuep = value;
431 return errmsg;
434 if (**strp == '%')
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,
442 const char **strp,
443 int opindex,
444 long *valuep)
446 const char *errmsg = 0;
447 signed long value;
448 long have_zero = 0;
449 int wide = 0;
450 int alignment;
452 switch (opindex)
454 case MEP_OPERAND_CDISP10A4:
455 alignment = 2;
456 break;
457 case MEP_OPERAND_CDISP10A2:
458 alignment = 1;
459 break;
460 case MEP_OPERAND_CDISP10:
461 default:
462 alignment = 0;
463 break;
466 if (MEP_CPU == EF_MEP_CPU_C5)
467 wide = 1;
469 if (strncmp (*strp, "0x0", 3) == 0
470 || (**strp == '0' && *(*strp + 1) != 'x'))
471 have_zero = 1;
473 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
474 if (errmsg)
475 return errmsg;
477 if (wide)
479 if (value < -512 || value > 511)
480 return _("Immediate is out of range -512 to 511");
482 else
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"));
496 *valuep = value;
497 return 0;
500 /* BEGIN LIGHTWEIGHT MACRO PROCESSOR. */
502 #define MAXARGS 9
504 typedef struct
506 char *name;
507 char *expansion;
508 } macro;
510 typedef struct
512 const char *start;
513 int len;
514 } arg;
516 macro macros[] =
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)"}, */
525 { 0,0 }
528 static char * expand_string (const char *, int);
530 static const char *
531 mep_cgen_expand_macros_and_parse_operand
532 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
534 static char *
535 str_append (char *dest, const char *input, int len)
537 char *new_dest;
538 int oldlen;
540 if (len == 0)
541 return dest;
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);
549 static macro *
550 lookup_macro (const char *name)
552 macro *m;
554 for (m = macros; m->name; ++m)
555 if (strncmp (m->name, name, strlen(m->name)) == 0)
556 return m;
558 return 0;
561 static char *
562 expand_macro (arg *args, int narg, macro *mac)
564 char *result = 0, *rescanned_result = 0;
565 char *e = mac->expansion;
566 char *mark = e;
567 int arg = 0;
569 /* printf("expanding macro %s with %d args\n", mac->name, narg + 1); */
570 while (*e)
572 if (*e == '`' &&
573 (*e+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);
581 ++e;
582 mark = e+1;
584 ++e;
587 if (mark != e)
588 result = str_append (result, mark, e - mark);
590 if (result)
592 rescanned_result = expand_string (result, 0);
593 free (result);
594 return rescanned_result;
596 else
597 return result;
600 #define IN_TEXT 0
601 #define IN_ARGS 1
603 static char *
604 expand_string (const char *in, int first_only)
606 int num_expansions = 0;
607 int depth = 0;
608 int narg = -1;
609 arg args[MAXARGS];
610 int state = IN_TEXT;
611 const char *mark = in;
612 macro *macro = 0;
614 char *expansion = 0;
615 char *result = 0;
617 while (*in)
619 switch (state)
621 case IN_TEXT:
622 if (*in == '%' && *(in + 1) && (!first_only || num_expansions == 0))
624 macro = lookup_macro (in + 1);
625 if (macro)
627 /* printf("entering state %d at '%s'...\n", state, in); */
628 result = str_append (result, mark, in - mark);
629 mark = in;
630 in += 1 + strlen (macro->name);
631 while (*in == ' ') ++in;
632 if (*in != '(')
634 state = IN_TEXT;
635 macro = 0;
637 else
639 state = IN_ARGS;
640 narg = 0;
641 args[narg].start = in + 1;
642 args[narg].len = 0;
643 mark = in + 1;
647 break;
648 case IN_ARGS:
649 if (depth == 0)
651 switch (*in)
653 case ',':
654 narg++;
655 args[narg].start = (in + 1);
656 args[narg].len = 0;
657 break;
658 case ')':
659 state = IN_TEXT;
660 /* printf("entering state %d at '%s'...\n", state, in); */
661 if (macro)
663 expansion = 0;
664 expansion = expand_macro (args, narg, macro);
665 num_expansions++;
666 if (expansion)
668 result = str_append (result, expansion, strlen (expansion));
669 free (expansion);
672 else
674 result = str_append (result, mark, in - mark);
676 macro = 0;
677 mark = in + 1;
678 break;
679 case '(':
680 depth++;
681 default:
682 args[narg].len++;
683 break;
686 else
688 if (*in == ')')
689 depth--;
690 if (narg > -1)
691 args[narg].len++;
695 ++in;
698 if (mark != in)
699 result = str_append (result, mark, in - mark);
701 return result;
704 #undef IN_ARGS
705 #undef IN_TEXT
706 #undef MAXARGS
709 /* END LIGHTWEIGHT MACRO PROCESSOR. */
711 const char * mep_cgen_parse_operand
712 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
714 const char *
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); */
726 hold = 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);
735 else
737 if (strstr (*strp_in, str))
738 /* A macro-expansion was pulled off the front. */
739 *strp_in = strstr (*strp_in, str);
740 else
741 /* A non-macro-expansion was pulled off the front. */
742 *strp_in += (str - hold);
745 if (hold)
746 free (hold);
748 return errmsg;
751 #define CGEN_ASM_INIT_HOOK (cd->parse_operand = mep_cgen_expand_macros_and_parse_operand);
753 /* -- dis.c */
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
769 the handlers. */
771 const char *
772 mep_cgen_parse_operand (CGEN_CPU_DESC cd,
773 int opindex,
774 const char ** strp,
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;
781 switch (opindex)
783 case MEP_OPERAND_ADDR24A4 :
784 errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_ADDR24A4, (unsigned long *) (& fields->f_24u8a4n));
785 break;
786 case MEP_OPERAND_C5RMUIMM20 :
787 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_C5RMUIMM20, (unsigned long *) (& fields->f_c5_rmuimm20));
788 break;
789 case MEP_OPERAND_C5RNMUIMM24 :
790 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_C5RNMUIMM24, (unsigned long *) (& fields->f_c5_rnmuimm24));
791 break;
792 case MEP_OPERAND_CALLNUM :
793 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CALLNUM, (unsigned long *) (& fields->f_callnum));
794 break;
795 case MEP_OPERAND_CCCC :
796 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CCCC, (unsigned long *) (& fields->f_rm));
797 break;
798 case MEP_OPERAND_CCRN :
799 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & fields->f_ccrn);
800 break;
801 case MEP_OPERAND_CDISP10 :
802 errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10, (long *) (& fields->f_cdisp10));
803 break;
804 case MEP_OPERAND_CDISP10A2 :
805 errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A2, (long *) (& fields->f_cdisp10));
806 break;
807 case MEP_OPERAND_CDISP10A4 :
808 errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A4, (long *) (& fields->f_cdisp10));
809 break;
810 case MEP_OPERAND_CDISP10A8 :
811 errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A8, (long *) (& fields->f_cdisp10));
812 break;
813 case MEP_OPERAND_CDISP12 :
814 errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_CDISP12, (long *) (& fields->f_12s20));
815 break;
816 case MEP_OPERAND_CIMM4 :
817 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM4, (unsigned long *) (& fields->f_rn));
818 break;
819 case MEP_OPERAND_CIMM5 :
820 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM5, (unsigned long *) (& fields->f_5u24));
821 break;
822 case MEP_OPERAND_CODE16 :
823 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE16, (unsigned long *) (& fields->f_16u16));
824 break;
825 case MEP_OPERAND_CODE24 :
826 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE24, (unsigned long *) (& fields->f_24u4n));
827 break;
828 case MEP_OPERAND_CP_FLAG :
829 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & junk);
830 break;
831 case MEP_OPERAND_CRN :
832 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crn);
833 break;
834 case MEP_OPERAND_CRN64 :
835 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crn);
836 break;
837 case MEP_OPERAND_CRNX :
838 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crnx);
839 break;
840 case MEP_OPERAND_CRNX64 :
841 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crnx);
842 break;
843 case MEP_OPERAND_CSRN :
844 errmsg = parse_csrn (cd, strp, & mep_cgen_opval_h_csr, & fields->f_csrn);
845 break;
846 case MEP_OPERAND_CSRN_IDX :
847 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, (unsigned long *) (& fields->f_csrn));
848 break;
849 case MEP_OPERAND_DBG :
850 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
851 break;
852 case MEP_OPERAND_DEPC :
853 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
854 break;
855 case MEP_OPERAND_EPC :
856 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
857 break;
858 case MEP_OPERAND_EXC :
859 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
860 break;
861 case MEP_OPERAND_HI :
862 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
863 break;
864 case MEP_OPERAND_LO :
865 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
866 break;
867 case MEP_OPERAND_LP :
868 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
869 break;
870 case MEP_OPERAND_MB0 :
871 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
872 break;
873 case MEP_OPERAND_MB1 :
874 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
875 break;
876 case MEP_OPERAND_ME0 :
877 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
878 break;
879 case MEP_OPERAND_ME1 :
880 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
881 break;
882 case MEP_OPERAND_NPC :
883 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
884 break;
885 case MEP_OPERAND_OPT :
886 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
887 break;
888 case MEP_OPERAND_PCABS24A2 :
889 errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_PCABS24A2, (unsigned long *) (& fields->f_24u5a2n));
890 break;
891 case MEP_OPERAND_PCREL12A2 :
892 errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL12A2, (long *) (& fields->f_12s4a2));
893 break;
894 case MEP_OPERAND_PCREL17A2 :
895 errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL17A2, (long *) (& fields->f_17s16a2));
896 break;
897 case MEP_OPERAND_PCREL24A2 :
898 errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL24A2, (long *) (& fields->f_24s5a2n));
899 break;
900 case MEP_OPERAND_PCREL8A2 :
901 errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL8A2, (long *) (& fields->f_8s8a2));
902 break;
903 case MEP_OPERAND_PSW :
904 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
905 break;
906 case MEP_OPERAND_R0 :
907 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
908 break;
909 case MEP_OPERAND_R1 :
910 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
911 break;
912 case MEP_OPERAND_RL :
913 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl);
914 break;
915 case MEP_OPERAND_RL5 :
916 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl5);
917 break;
918 case MEP_OPERAND_RM :
919 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
920 break;
921 case MEP_OPERAND_RMA :
922 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
923 break;
924 case MEP_OPERAND_RN :
925 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
926 break;
927 case MEP_OPERAND_RN3 :
928 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
929 break;
930 case MEP_OPERAND_RN3C :
931 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
932 break;
933 case MEP_OPERAND_RN3L :
934 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
935 break;
936 case MEP_OPERAND_RN3S :
937 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
938 break;
939 case MEP_OPERAND_RN3UC :
940 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
941 break;
942 case MEP_OPERAND_RN3UL :
943 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
944 break;
945 case MEP_OPERAND_RN3US :
946 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
947 break;
948 case MEP_OPERAND_RNC :
949 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
950 break;
951 case MEP_OPERAND_RNL :
952 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
953 break;
954 case MEP_OPERAND_RNS :
955 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
956 break;
957 case MEP_OPERAND_RNUC :
958 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
959 break;
960 case MEP_OPERAND_RNUL :
961 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
962 break;
963 case MEP_OPERAND_RNUS :
964 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
965 break;
966 case MEP_OPERAND_SAR :
967 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
968 break;
969 case MEP_OPERAND_SDISP16 :
970 errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SDISP16, (long *) (& fields->f_16s16));
971 break;
972 case MEP_OPERAND_SIMM16 :
973 errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SIMM16, (long *) (& fields->f_16s16));
974 break;
975 case MEP_OPERAND_SIMM6 :
976 errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM6, (long *) (& fields->f_6s8));
977 break;
978 case MEP_OPERAND_SIMM8 :
979 errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8, (long *) (& fields->f_8s8));
980 break;
981 case MEP_OPERAND_SP :
982 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
983 break;
984 case MEP_OPERAND_SPR :
985 errmsg = parse_spreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
986 break;
987 case MEP_OPERAND_TP :
988 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
989 break;
990 case MEP_OPERAND_TPR :
991 errmsg = parse_tpreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
992 break;
993 case MEP_OPERAND_UDISP2 :
994 errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_UDISP2, (long *) (& fields->f_2u6));
995 break;
996 case MEP_OPERAND_UDISP7 :
997 errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7, (unsigned long *) (& fields->f_7u9));
998 break;
999 case MEP_OPERAND_UDISP7A2 :
1000 errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A2, (unsigned long *) (& fields->f_7u9a2));
1001 break;
1002 case MEP_OPERAND_UDISP7A4 :
1003 errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A4, (unsigned long *) (& fields->f_7u9a4));
1004 break;
1005 case MEP_OPERAND_UIMM16 :
1006 errmsg = parse_unsigned16 (cd, strp, MEP_OPERAND_UIMM16, (unsigned long *) (& fields->f_16u16));
1007 break;
1008 case MEP_OPERAND_UIMM2 :
1009 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM2, (unsigned long *) (& fields->f_2u10));
1010 break;
1011 case MEP_OPERAND_UIMM24 :
1012 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM24, (unsigned long *) (& fields->f_24u8n));
1013 break;
1014 case MEP_OPERAND_UIMM3 :
1015 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM3, (unsigned long *) (& fields->f_3u5));
1016 break;
1017 case MEP_OPERAND_UIMM4 :
1018 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM4, (unsigned long *) (& fields->f_4u8));
1019 break;
1020 case MEP_OPERAND_UIMM5 :
1021 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM5, (unsigned long *) (& fields->f_5u8));
1022 break;
1023 case MEP_OPERAND_UIMM7A4 :
1024 errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_UIMM7A4, (unsigned long *) (& fields->f_7u9a4));
1025 break;
1026 case MEP_OPERAND_ZERO :
1027 errmsg = parse_zero (cd, strp, MEP_OPERAND_ZERO, (long *) (& junk));
1028 break;
1030 default :
1031 /* xgettext:c-format */
1032 fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
1033 abort ();
1036 return errmsg;
1039 cgen_parse_fn * const mep_cgen_parse_handlers[] =
1041 parse_insn_normal,
1044 void
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
1052 CGEN_ASM_INIT_HOOK
1053 #endif
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. */
1069 char *
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];
1075 char *rx = rxbuf;
1076 const CGEN_SYNTAX_CHAR_TYPE *syn;
1077 int reg_err;
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");
1084 ++syn;
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++)
1094 char c = *mnem;
1096 if (ISALPHA (c))
1098 *rx++ = '[';
1099 *rx++ = TOLOWER (c);
1100 *rx++ = TOUPPER (c);
1101 *rx++ = ']';
1103 else
1104 *rx++ = 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);
1114 switch (c)
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 ']':
1124 #endif
1125 *rx++ = '\\';
1126 *rx++ = c;
1127 break;
1129 default:
1130 if (ISALPHA (c))
1132 *rx++ = '[';
1133 *rx++ = TOLOWER (c);
1134 *rx++ = TOUPPER (c);
1135 *rx++ = ']';
1137 else
1138 *rx++ = c;
1139 break;
1142 else
1144 /* Replace non-syntax fields with globs. */
1145 *rx++ = '.';
1146 *rx++ = '*';
1150 /* Trailing whitespace ok. */
1151 * rx++ = '[';
1152 * rx++ = ' ';
1153 * rx++ = '\t';
1154 * rx++ = ']';
1155 * rx++ = '*';
1157 /* But anchor it after that. */
1158 * rx++ = '$';
1159 * rx = '\0';
1161 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
1162 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
1164 if (reg_err == 0)
1165 return NULL;
1166 else
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;
1174 return msg;
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. */
1192 static const char *
1193 parse_insn_normal (CGEN_CPU_DESC cd,
1194 const CGEN_INSN *insn,
1195 const char **strp,
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;
1201 const char *errmsg;
1202 const char *p;
1203 const CGEN_SYNTAX_CHAR_TYPE * syn;
1204 #ifdef CGEN_MNEMONIC_OPERANDS
1205 /* FIXME: wip */
1206 int past_opcode_p;
1207 #endif
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))
1215 ++p, ++str;
1217 if (* p)
1218 return _("unrecognized instruction");
1220 #ifndef CGEN_MNEMONIC_OPERANDS
1221 if (* str && ! ISSPACE (* str))
1222 return _("unrecognized instruction");
1223 #endif
1225 CGEN_INIT_PARSE (cd);
1226 cgen_init_parse_operand (cd);
1227 #ifdef CGEN_MNEMONIC_OPERANDS
1228 past_opcode_p = 0;
1229 #endif
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))
1237 abort ();
1239 ++syn;
1241 while (* syn != 0)
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) == ' ')
1254 past_opcode_p = 1;
1255 #endif
1256 ++ syn;
1257 ++ str;
1259 else if (*str)
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);
1267 return msg;
1269 else
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));
1277 return msg;
1279 continue;
1282 /* We have an operand of some sort. */
1283 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
1284 &str, fields);
1285 if (errmsg)
1286 return errmsg;
1288 /* Done with this operand, continue with next one. */
1289 ++ syn;
1292 /* If we're at the end of the syntax string, we're done. */
1293 if (* syn == 0)
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))
1300 ++ str;
1302 if (* str != '\0')
1303 return _("junk at end of line"); /* FIXME: would like to include `str' */
1305 return NULL;
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
1322 printed).
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. */
1333 const CGEN_INSN *
1334 mep_cgen_assemble_insn (CGEN_CPU_DESC cd,
1335 const char *str,
1336 CGEN_FIELDS *fields,
1337 CGEN_INSN_BYTES_PTR buf,
1338 char **errmsg)
1340 const char *start;
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))
1348 ++ 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. */
1355 start = str;
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))
1366 continue;
1367 #endif
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)
1372 continue;
1374 str = start;
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)
1379 continue;
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)
1386 continue;
1388 /* ??? 0 is passed for `pc'. */
1389 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
1390 (bfd_vma) 0);
1391 if (insert_errmsg != NULL)
1392 continue;
1394 /* It is up to the caller to actually output the insn and any
1395 queued relocs. */
1396 return insn;
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);
1415 else
1416 /* xgettext:c-format */
1417 sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
1418 #else
1419 if (strlen (start) > 50)
1420 /* xgettext:c-format */
1421 sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1422 else
1423 /* xgettext:c-format */
1424 sprintf (errbuf, _("bad instruction `%.50s'"), start);
1425 #endif
1427 *errmsg = errbuf;
1428 return NULL;