xref: /netbsd-src/external/gpl3/binutils/dist/opcodes/mep-asm.c (revision 1b9578b8c2c1f848eeb16dabbfd7d1f0d9fdefbd)
1 /* Assembler interface for targets using CGEN. -*- C -*-
2    CGEN: Cpu tools GENerator
3 
4    THIS FILE IS MACHINE GENERATED WITH CGEN.
5    - the resultant file is machine generated, cgen-asm.in isn't
6 
7    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2007
8    Free Software Foundation, Inc.
9 
10    This file is part of libopcodes.
11 
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.
16 
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.
21 
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.  */
25 
26 
27 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
28    Keep that in mind.  */
29 
30 #include "sysdep.h"
31 #include <stdio.h>
32 #include "ansidecl.h"
33 #include "bfd.h"
34 #include "symcat.h"
35 #include "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"
41 
42 #undef  min
43 #define min(a,b) ((a) < (b) ? (a) : (b))
44 #undef  max
45 #define max(a,b) ((a) > (b) ? (a) : (b))
46 
47 static const char * parse_insn_normal
48   (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
49 
50 /* -- assembler routines inserted here.  */
51 
52 /* -- asm.c */
53 
54 #define CGEN_VALIDATE_INSN_SUPPORTED
55 
56        const char * parse_csrn       (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
57        const char * parse_tpreg      (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
58        const char * parse_spreg      (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
59        const char * parse_mep_align  (CGEN_CPU_DESC, const char **, enum cgen_operand_type, long *);
60        const char * parse_mep_alignu (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
61 static const char * parse_signed16   (CGEN_CPU_DESC, const char **, int, long *);
62 static const char * parse_unsigned16 (CGEN_CPU_DESC, const char **, int, unsigned long *);
63 static const char * parse_lo16       (CGEN_CPU_DESC, const char **, int, long *, long);
64 static const char * parse_unsigned7  (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
65 static const char * parse_zero       (CGEN_CPU_DESC, const char **, int, long *);
66 
67 const char *
68 parse_csrn (CGEN_CPU_DESC cd, const char **strp,
69 	    CGEN_KEYWORD *keyword_table, long *field)
70 {
71   const char *err;
72   unsigned long value;
73 
74   err = cgen_parse_keyword (cd, strp, keyword_table, field);
75   if (!err)
76     return NULL;
77 
78   err = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, & value);
79   if (err)
80     return err;
81   *field = value;
82   return NULL;
83 }
84 
85 /* begin-cop-ip-parse-handlers */
86 static const char *
87 parse_fmax_cr (CGEN_CPU_DESC cd,
88 	const char **strp,
89 	CGEN_KEYWORD *keyword_table  ATTRIBUTE_UNUSED,
90 	long *field)
91 {
92   return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr_fmax, field);
93 }
94 static const char *
95 parse_fmax_ccr (CGEN_CPU_DESC cd,
96 	const char **strp,
97 	CGEN_KEYWORD *keyword_table  ATTRIBUTE_UNUSED,
98 	long *field)
99 {
100   return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_fmax, field);
101 }
102 /* end-cop-ip-parse-handlers */
103 
104 const char *
105 parse_tpreg (CGEN_CPU_DESC cd, const char ** strp,
106 	     CGEN_KEYWORD *keyword_table, long *field)
107 {
108   const char *err;
109 
110   err = cgen_parse_keyword (cd, strp, keyword_table, field);
111   if (err)
112     return err;
113   if (*field != 13)
114     return _("Only $tp or $13 allowed for this opcode");
115   return NULL;
116 }
117 
118 const char *
119 parse_spreg (CGEN_CPU_DESC cd, const char ** strp,
120 	     CGEN_KEYWORD *keyword_table, long *field)
121 {
122   const char *err;
123 
124   err = cgen_parse_keyword (cd, strp, keyword_table, field);
125   if (err)
126     return err;
127   if (*field != 15)
128     return _("Only $sp or $15 allowed for this opcode");
129   return NULL;
130 }
131 
132 const char *
133 parse_mep_align (CGEN_CPU_DESC cd, const char ** strp,
134 		 enum cgen_operand_type type, long *field)
135 {
136   long lsbs = 0;
137   const char *err;
138 
139   switch (type)
140     {
141     case MEP_OPERAND_PCREL8A2:
142     case MEP_OPERAND_PCREL12A2:
143     case MEP_OPERAND_PCREL17A2:
144     case MEP_OPERAND_PCREL24A2:
145     case MEP_OPERAND_CDISP8A2:
146     case MEP_OPERAND_CDISP8A4:
147     case MEP_OPERAND_CDISP8A8:
148       err = cgen_parse_signed_integer   (cd, strp, type, field);
149       break;
150     case MEP_OPERAND_PCABS24A2:
151     case MEP_OPERAND_UDISP7:
152     case MEP_OPERAND_UDISP7A2:
153     case MEP_OPERAND_UDISP7A4:
154     case MEP_OPERAND_UIMM7A4:
155     case MEP_OPERAND_ADDR24A4:
156       err = cgen_parse_unsigned_integer (cd, strp, type, (unsigned long *) field);
157       break;
158     default:
159       abort();
160     }
161   if (err)
162     return err;
163   switch (type)
164     {
165     case MEP_OPERAND_UDISP7:
166       lsbs = 0;
167       break;
168     case MEP_OPERAND_PCREL8A2:
169     case MEP_OPERAND_PCREL12A2:
170     case MEP_OPERAND_PCREL17A2:
171     case MEP_OPERAND_PCREL24A2:
172     case MEP_OPERAND_PCABS24A2:
173     case MEP_OPERAND_UDISP7A2:
174     case MEP_OPERAND_CDISP8A2:
175       lsbs = *field & 1;
176       break;
177     case MEP_OPERAND_UDISP7A4:
178     case MEP_OPERAND_UIMM7A4:
179     case MEP_OPERAND_ADDR24A4:
180     case MEP_OPERAND_CDISP8A4:
181       lsbs = *field & 3;
182       break;
183     case MEP_OPERAND_CDISP8A8:
184       lsbs = *field & 7;
185       break;
186     default:
187       /* Safe assumption?  */
188       abort ();
189     }
190   if (lsbs)
191     return "Value is not aligned enough";
192   return NULL;
193 }
194 
195 const char *
196 parse_mep_alignu (CGEN_CPU_DESC cd, const char ** strp,
197 		 enum cgen_operand_type type, unsigned long *field)
198 {
199   return parse_mep_align (cd, strp, type, (long *) field);
200 }
201 
202 
203 /* Handle %lo(), %tpoff(), %sdaoff(), %hi(), and other signed
204    constants in a signed context.  */
205 
206 static const char *
207 parse_signed16 (CGEN_CPU_DESC cd,
208 		const char **strp,
209 		int opindex,
210 		long *valuep)
211 {
212   return parse_lo16 (cd, strp, opindex, valuep, 1);
213 }
214 
215 static const char *
216 parse_lo16 (CGEN_CPU_DESC cd,
217 	    const char **strp,
218 	    int opindex,
219 	    long *valuep,
220 	    long signedp)
221 {
222   const char *errmsg;
223   enum cgen_parse_operand_result result_type;
224   bfd_vma value;
225 
226   if (strncasecmp (*strp, "%lo(", 4) == 0)
227     {
228       *strp += 4;
229       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
230 				   & result_type, & value);
231       if (**strp != ')')
232 	return _("missing `)'");
233       ++*strp;
234       if (errmsg == NULL
235 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
236 	value &= 0xffff;
237       if (signedp)
238 	*valuep = (long)(short) value;
239       else
240 	*valuep = value;
241       return errmsg;
242     }
243 
244   if (strncasecmp (*strp, "%hi(", 4) == 0)
245     {
246       *strp += 4;
247       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
248 				   & result_type, & value);
249       if (**strp != ')')
250 	return _("missing `)'");
251       ++*strp;
252       if (errmsg == NULL
253 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
254 	value = (value + 0x8000) >> 16;
255       *valuep = value;
256       return errmsg;
257     }
258 
259   if (strncasecmp (*strp, "%uhi(", 5) == 0)
260     {
261       *strp += 5;
262       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
263 				   & result_type, & value);
264       if (**strp != ')')
265 	return _("missing `)'");
266       ++*strp;
267       if (errmsg == NULL
268 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
269 	value = value >> 16;
270       *valuep = value;
271       return errmsg;
272     }
273 
274   if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
275     {
276       *strp += 8;
277       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
278 				   NULL, & value);
279       if (**strp != ')')
280 	return _("missing `)'");
281       ++*strp;
282       *valuep = value;
283       return errmsg;
284     }
285 
286   if (strncasecmp (*strp, "%tpoff(", 7) == 0)
287     {
288       *strp += 7;
289       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
290 				   NULL, & value);
291       if (**strp != ')')
292 	return _("missing `)'");
293       ++*strp;
294       *valuep = value;
295       return errmsg;
296     }
297 
298   if (**strp == '%')
299     return _("invalid %function() here");
300 
301   return cgen_parse_signed_integer (cd, strp, opindex, valuep);
302 }
303 
304 static const char *
305 parse_unsigned16 (CGEN_CPU_DESC cd,
306 		  const char **strp,
307 		  int opindex,
308 		  unsigned long *valuep)
309 {
310   return parse_lo16 (cd, strp, opindex, (long *) valuep, 0);
311 }
312 
313 /* A special case of parse_signed16 which accepts only the value zero.  */
314 
315 static const char *
316 parse_zero (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
317 {
318   const char *errmsg;
319   enum cgen_parse_operand_result result_type;
320   bfd_vma value;
321 
322   /*fprintf(stderr, "dj: signed parse opindex `%s'\n", *strp);*/
323 
324   /* Prevent ($ry) from being attempted as an expression on 'sw $rx,($ry)'.
325      It will fail and cause ry to be listed as an undefined symbol in the
326      listing.  */
327   if (strncmp (*strp, "($", 2) == 0)
328     return "not zero"; /* any string will do -- will never be seen.  */
329 
330   if (strncasecmp (*strp, "%lo(", 4) == 0)
331     {
332       *strp += 4;
333       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
334 				   &result_type, &value);
335       if (**strp != ')')
336 	return "missing `)'";
337       ++*strp;
338       if (errmsg == NULL
339 	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
340 	return "not zero"; /* any string will do -- will never be seen.  */
341       *valuep = value;
342       return errmsg;
343     }
344 
345   if (strncasecmp (*strp, "%hi(", 4) == 0)
346     {
347       *strp += 4;
348       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
349 				   &result_type, &value);
350       if (**strp != ')')
351 	return "missing `)'";
352       ++*strp;
353       if (errmsg == NULL
354 	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
355 	return "not zero"; /* any string will do -- will never be seen.  */
356       *valuep = value;
357       return errmsg;
358     }
359 
360   if (strncasecmp (*strp, "%uhi(", 5) == 0)
361     {
362       *strp += 5;
363       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
364 				   &result_type, &value);
365       if (**strp != ')')
366 	return "missing `)'";
367       ++*strp;
368       if (errmsg == NULL
369 	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
370 	return "not zero"; /* any string will do -- will never be seen.  */
371       *valuep = value;
372       return errmsg;
373     }
374 
375   if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
376     {
377       *strp += 8;
378       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
379 				   &result_type, &value);
380       if (**strp != ')')
381 	return "missing `)'";
382       ++*strp;
383       if (errmsg == NULL
384 	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
385 	return "not zero"; /* any string will do -- will never be seen.  */
386       *valuep = value;
387       return errmsg;
388     }
389 
390   if (strncasecmp (*strp, "%tpoff(", 7) == 0)
391     {
392       *strp += 7;
393       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
394 				   &result_type, &value);
395       if (**strp != ')')
396 	return "missing `)'";
397       ++*strp;
398       if (errmsg == NULL
399 	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
400 	return "not zero"; /* any string will do -- will never be seen.  */
401       *valuep = value;
402       return errmsg;
403     }
404 
405   if (**strp == '%')
406     return "invalid %function() here";
407 
408   errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_NONE,
409 			       &result_type, &value);
410   if (errmsg == NULL
411       && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
412     return "not zero"; /* any string will do -- will never be seen.  */
413 
414   return errmsg;
415 }
416 
417 static const char *
418 parse_unsigned7 (CGEN_CPU_DESC cd, const char **strp,
419 		 enum cgen_operand_type opindex, unsigned long *valuep)
420 {
421   const char *errmsg;
422   bfd_vma value;
423 
424   /* fprintf(stderr, "dj: unsigned7 parse `%s'\n", *strp); */
425 
426   if (strncasecmp (*strp, "%tpoff(", 7) == 0)
427     {
428       int reloc;
429       *strp += 7;
430       switch (opindex)
431 	{
432 	case MEP_OPERAND_UDISP7:
433 	  reloc = BFD_RELOC_MEP_TPREL7;
434 	  break;
435 	case MEP_OPERAND_UDISP7A2:
436 	  reloc = BFD_RELOC_MEP_TPREL7A2;
437 	  break;
438 	case MEP_OPERAND_UDISP7A4:
439 	  reloc = BFD_RELOC_MEP_TPREL7A4;
440 	  break;
441 	default:
442 	  /* Safe assumption?  */
443 	  abort ();
444 	}
445       errmsg = cgen_parse_address (cd, strp, opindex, reloc,
446 				   NULL, &value);
447       if (**strp != ')')
448 	return "missing `)'";
449       ++*strp;
450       *valuep = value;
451       return errmsg;
452     }
453 
454   if (**strp == '%')
455     return _("invalid %function() here");
456 
457   return parse_mep_alignu (cd, strp, opindex, valuep);
458 }
459 
460 /* BEGIN LIGHTWEIGHT MACRO PROCESSOR.  */
461 
462 #define MAXARGS 9
463 
464 typedef struct
465 {
466   char *name;
467   char *expansion;
468 }  macro;
469 
470 typedef struct
471 {
472   const char *start;
473   int len;
474 } arg;
475 
476 macro macros[] =
477 {
478   { "sizeof", "(`1.end + (- `1))"},
479   { "startof", "(`1 | 0)" },
480   { "align4", "(`1&(~3))"},
481 /*{ "hi", "(((`1+0x8000)>>16) & 0xffff)" },  */
482 /*{ "lo", "(`1 & 0xffff)" },  */
483 /*{ "sdaoff", "((`1-__sdabase) & 0x7f)"},  */
484 /*{ "tpoff", "((`1-__tpbase) & 0x7f)"},  */
485   { 0,0 }
486 };
487 
488 static char  * expand_string    (const char *, int);
489 
490 static const char *
491 mep_cgen_expand_macros_and_parse_operand
492   (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
493 
494 static char *
495 str_append (char *dest, const char *input, int len)
496 {
497   char *new_dest;
498   int oldlen;
499 
500   if (len == 0)
501     return dest;
502   /* printf("str_append: <<%s>>, <<%s>>, %d\n", dest, input, len); */
503   oldlen = (dest ? strlen(dest) : 0);
504   new_dest = realloc (dest, oldlen + len + 1);
505   memset (new_dest + oldlen, 0, len + 1);
506   return strncat (new_dest, input, len);
507 }
508 
509 static macro *
510 lookup_macro (const char *name)
511 {
512   macro *m;
513 
514   for (m = macros; m->name; ++m)
515     if (strncmp (m->name, name, strlen(m->name)) == 0)
516       return m;
517 
518   return 0;
519 }
520 
521 static char *
522 expand_macro (arg *args, int narg, macro *mac)
523 {
524   char *result = 0, *rescanned_result = 0;
525   char *e = mac->expansion;
526   char *mark = e;
527   int arg = 0;
528 
529   /*  printf("expanding macro %s with %d args\n", mac->name, narg + 1); */
530   while (*e)
531     {
532       if (*e == '`' &&
533 	  (*e+1) &&
534 	  ((*(e + 1) - '1') <= MAXARGS) &&
535 	  ((*(e + 1) - '1') <= narg))
536 	{
537 	  result = str_append (result, mark, e - mark);
538 	  arg = (*(e + 1) - '1');
539 	  /* printf("replacing `%d with %s\n", arg+1, args[arg].start); */
540 	  result = str_append (result, args[arg].start, args[arg].len);
541 	  ++e;
542 	  mark = e+1;
543 	}
544       ++e;
545     }
546 
547   if (mark != e)
548     result = str_append (result, mark, e - mark);
549 
550   if (result)
551     {
552       rescanned_result = expand_string (result, 0);
553       free (result);
554       return rescanned_result;
555     }
556   else
557     return result;
558 }
559 
560 #define IN_TEXT 0
561 #define IN_ARGS 1
562 
563 static char *
564 expand_string (const char *in, int first_only)
565 {
566   int num_expansions = 0;
567   int depth = 0;
568   int narg = -1;
569   arg args[MAXARGS];
570   int state = IN_TEXT;
571   const char *mark = in;
572   macro *macro = 0;
573 
574   char *expansion = 0;
575   char *result = 0;
576 
577   while (*in)
578     {
579       switch (state)
580 	{
581 	case IN_TEXT:
582 	  if (*in == '%' && *(in + 1) && (!first_only || num_expansions == 0))
583 	    {
584 	      macro = lookup_macro (in + 1);
585 	      if (macro)
586 		{
587 		  /* printf("entering state %d at '%s'...\n", state, in); */
588 		  result = str_append (result, mark, in - mark);
589 		  mark = in;
590 		  in += 1 + strlen (macro->name);
591 		  while (*in == ' ') ++in;
592 		  if (*in != '(')
593 		    {
594 		      state = IN_TEXT;
595 		      macro = 0;
596 		    }
597 		  else
598 		    {
599 		      state = IN_ARGS;
600 		      narg = 0;
601 		      args[narg].start = in + 1;
602 		      args[narg].len = 0;
603 		      mark = in + 1;
604 		    }
605 		}
606 	    }
607 	  break;
608 	case IN_ARGS:
609 	  if (depth == 0)
610 	    {
611 	      switch (*in)
612 		{
613 		case ',':
614 		  narg++;
615 		  args[narg].start = (in + 1);
616 		  args[narg].len = 0;
617 		  break;
618 		case ')':
619 		  state = IN_TEXT;
620 		  /* printf("entering state %d at '%s'...\n", state, in); */
621 		  if (macro)
622 		    {
623 		      expansion = 0;
624 		      expansion = expand_macro (args, narg, macro);
625 		      num_expansions++;
626 		      if (expansion)
627 			{
628 			  result = str_append (result, expansion, strlen (expansion));
629 			  free (expansion);
630 			}
631 		    }
632 		  else
633 		    {
634 		      result = str_append (result, mark, in - mark);
635 		    }
636 		  macro = 0;
637 		  mark = in + 1;
638 		  break;
639 		case '(':
640 		  depth++;
641 		default:
642 		  args[narg].len++;
643 		  break;
644 		}
645 	    }
646 	  else
647 	    {
648 	      if (*in == ')')
649 		depth--;
650 	      if (narg > -1)
651 		args[narg].len++;
652 	    }
653 
654 	}
655       ++in;
656     }
657 
658   if (mark != in)
659     result = str_append (result, mark, in - mark);
660 
661   return result;
662 }
663 
664 #undef IN_ARGS
665 #undef IN_TEXT
666 #undef MAXARGS
667 
668 
669 /* END LIGHTWEIGHT MACRO PROCESSOR.  */
670 
671 const char * mep_cgen_parse_operand
672   (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
673 
674 const char *
675 mep_cgen_expand_macros_and_parse_operand (CGEN_CPU_DESC cd, int opindex,
676 					  const char ** strp_in, CGEN_FIELDS * fields)
677 {
678   const char * errmsg = NULL;
679   char *str = 0, *hold = 0;
680   const char **strp = 0;
681 
682   /* Set up a new pointer to macro-expanded string.  */
683   str = expand_string (*strp_in, 1);
684   /* fprintf (stderr, " expanded <<%s>> to <<%s>>\n", *strp_in, str); */
685 
686   hold = str;
687   strp = (const char **)(&str);
688 
689   errmsg = mep_cgen_parse_operand (cd, opindex, strp, fields);
690 
691   /* Now work out the advance.  */
692   if (strlen (str) == 0)
693     *strp_in += strlen (*strp_in);
694 
695   else
696     {
697       if (strstr (*strp_in, str))
698 	/* A macro-expansion was pulled off the front.  */
699 	*strp_in = strstr (*strp_in, str);
700       else
701 	/* A non-macro-expansion was pulled off the front.  */
702 	*strp_in += (str - hold);
703     }
704 
705   if (hold)
706     free (hold);
707 
708   return errmsg;
709 }
710 
711 #define CGEN_ASM_INIT_HOOK (cd->parse_operand = mep_cgen_expand_macros_and_parse_operand);
712 
713 /* -- dis.c */
714 
715 const char * mep_cgen_parse_operand
716   (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
717 
718 /* Main entry point for operand parsing.
719 
720    This function is basically just a big switch statement.  Earlier versions
721    used tables to look up the function to use, but
722    - if the table contains both assembler and disassembler functions then
723      the disassembler contains much of the assembler and vice-versa,
724    - there's a lot of inlining possibilities as things grow,
725    - using a switch statement avoids the function call overhead.
726 
727    This function could be moved into `parse_insn_normal', but keeping it
728    separate makes clear the interface between `parse_insn_normal' and each of
729    the handlers.  */
730 
731 const char *
732 mep_cgen_parse_operand (CGEN_CPU_DESC cd,
733 			   int opindex,
734 			   const char ** strp,
735 			   CGEN_FIELDS * fields)
736 {
737   const char * errmsg = NULL;
738   /* Used by scalar operands that still need to be parsed.  */
739   long junk ATTRIBUTE_UNUSED;
740 
741   switch (opindex)
742     {
743     case MEP_OPERAND_ADDR24A4 :
744       errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_ADDR24A4, (unsigned long *) (& fields->f_24u8a4n));
745       break;
746     case MEP_OPERAND_CALLNUM :
747       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CALLNUM, (unsigned long *) (& fields->f_callnum));
748       break;
749     case MEP_OPERAND_CCCC :
750       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CCCC, (unsigned long *) (& fields->f_rm));
751       break;
752     case MEP_OPERAND_CCRN :
753       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & fields->f_ccrn);
754       break;
755     case MEP_OPERAND_CDISP8 :
756       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_CDISP8, (long *) (& fields->f_8s24));
757       break;
758     case MEP_OPERAND_CDISP8A2 :
759       errmsg = parse_mep_align (cd, strp, MEP_OPERAND_CDISP8A2, (long *) (& fields->f_8s24a2));
760       break;
761     case MEP_OPERAND_CDISP8A4 :
762       errmsg = parse_mep_align (cd, strp, MEP_OPERAND_CDISP8A4, (long *) (& fields->f_8s24a4));
763       break;
764     case MEP_OPERAND_CDISP8A8 :
765       errmsg = parse_mep_align (cd, strp, MEP_OPERAND_CDISP8A8, (long *) (& fields->f_8s24a8));
766       break;
767     case MEP_OPERAND_CIMM4 :
768       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM4, (unsigned long *) (& fields->f_rn));
769       break;
770     case MEP_OPERAND_CIMM5 :
771       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM5, (unsigned long *) (& fields->f_5u24));
772       break;
773     case MEP_OPERAND_CODE16 :
774       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE16, (unsigned long *) (& fields->f_16u16));
775       break;
776     case MEP_OPERAND_CODE24 :
777       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE24, (unsigned long *) (& fields->f_24u4n));
778       break;
779     case MEP_OPERAND_CP_FLAG :
780       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & junk);
781       break;
782     case MEP_OPERAND_CRN :
783       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crn);
784       break;
785     case MEP_OPERAND_CRN64 :
786       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crn);
787       break;
788     case MEP_OPERAND_CRNX :
789       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crnx);
790       break;
791     case MEP_OPERAND_CRNX64 :
792       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crnx);
793       break;
794     case MEP_OPERAND_CSRN :
795       errmsg = parse_csrn (cd, strp, & mep_cgen_opval_h_csr, & fields->f_csrn);
796       break;
797     case MEP_OPERAND_CSRN_IDX :
798       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, (unsigned long *) (& fields->f_csrn));
799       break;
800     case MEP_OPERAND_DBG :
801       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
802       break;
803     case MEP_OPERAND_DEPC :
804       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
805       break;
806     case MEP_OPERAND_EPC :
807       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
808       break;
809     case MEP_OPERAND_EXC :
810       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
811       break;
812     case MEP_OPERAND_FMAX_CCRN :
813       errmsg = parse_fmax_ccr (cd, strp, & mep_cgen_opval_h_ccr, & fields->f_fmax_4_4);
814       break;
815     case MEP_OPERAND_FMAX_FRD :
816       errmsg = parse_fmax_cr (cd, strp, & mep_cgen_opval_h_cr, & fields->f_fmax_frd);
817       break;
818     case MEP_OPERAND_FMAX_FRD_INT :
819       errmsg = parse_fmax_cr (cd, strp, & mep_cgen_opval_h_cr, & fields->f_fmax_frd);
820       break;
821     case MEP_OPERAND_FMAX_FRM :
822       errmsg = parse_fmax_cr (cd, strp, & mep_cgen_opval_h_cr, & fields->f_fmax_frm);
823       break;
824     case MEP_OPERAND_FMAX_FRN :
825       errmsg = parse_fmax_cr (cd, strp, & mep_cgen_opval_h_cr, & fields->f_fmax_frn);
826       break;
827     case MEP_OPERAND_FMAX_FRN_INT :
828       errmsg = parse_fmax_cr (cd, strp, & mep_cgen_opval_h_cr, & fields->f_fmax_frn);
829       break;
830     case MEP_OPERAND_FMAX_RM :
831       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_fmax_rm);
832       break;
833     case MEP_OPERAND_HI :
834       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
835       break;
836     case MEP_OPERAND_LO :
837       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
838       break;
839     case MEP_OPERAND_LP :
840       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
841       break;
842     case MEP_OPERAND_MB0 :
843       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
844       break;
845     case MEP_OPERAND_MB1 :
846       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
847       break;
848     case MEP_OPERAND_ME0 :
849       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
850       break;
851     case MEP_OPERAND_ME1 :
852       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
853       break;
854     case MEP_OPERAND_NPC :
855       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
856       break;
857     case MEP_OPERAND_OPT :
858       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
859       break;
860     case MEP_OPERAND_PCABS24A2 :
861       errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_PCABS24A2, (unsigned long *) (& fields->f_24u5a2n));
862       break;
863     case MEP_OPERAND_PCREL12A2 :
864       errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL12A2, (long *) (& fields->f_12s4a2));
865       break;
866     case MEP_OPERAND_PCREL17A2 :
867       errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL17A2, (long *) (& fields->f_17s16a2));
868       break;
869     case MEP_OPERAND_PCREL24A2 :
870       errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL24A2, (long *) (& fields->f_24s5a2n));
871       break;
872     case MEP_OPERAND_PCREL8A2 :
873       errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL8A2, (long *) (& fields->f_8s8a2));
874       break;
875     case MEP_OPERAND_PSW :
876       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
877       break;
878     case MEP_OPERAND_R0 :
879       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
880       break;
881     case MEP_OPERAND_R1 :
882       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
883       break;
884     case MEP_OPERAND_RL :
885       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl);
886       break;
887     case MEP_OPERAND_RM :
888       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
889       break;
890     case MEP_OPERAND_RMA :
891       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
892       break;
893     case MEP_OPERAND_RN :
894       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
895       break;
896     case MEP_OPERAND_RN3 :
897       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
898       break;
899     case MEP_OPERAND_RN3C :
900       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
901       break;
902     case MEP_OPERAND_RN3L :
903       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
904       break;
905     case MEP_OPERAND_RN3S :
906       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
907       break;
908     case MEP_OPERAND_RN3UC :
909       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
910       break;
911     case MEP_OPERAND_RN3UL :
912       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
913       break;
914     case MEP_OPERAND_RN3US :
915       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
916       break;
917     case MEP_OPERAND_RNC :
918       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
919       break;
920     case MEP_OPERAND_RNL :
921       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
922       break;
923     case MEP_OPERAND_RNS :
924       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
925       break;
926     case MEP_OPERAND_RNUC :
927       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
928       break;
929     case MEP_OPERAND_RNUL :
930       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
931       break;
932     case MEP_OPERAND_RNUS :
933       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
934       break;
935     case MEP_OPERAND_SAR :
936       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
937       break;
938     case MEP_OPERAND_SDISP16 :
939       errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SDISP16, (long *) (& fields->f_16s16));
940       break;
941     case MEP_OPERAND_SIMM16 :
942       errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SIMM16, (long *) (& fields->f_16s16));
943       break;
944     case MEP_OPERAND_SIMM6 :
945       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM6, (long *) (& fields->f_6s8));
946       break;
947     case MEP_OPERAND_SIMM8 :
948       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8, (long *) (& fields->f_8s8));
949       break;
950     case MEP_OPERAND_SP :
951       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
952       break;
953     case MEP_OPERAND_SPR :
954       errmsg = parse_spreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
955       break;
956     case MEP_OPERAND_TP :
957       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
958       break;
959     case MEP_OPERAND_TPR :
960       errmsg = parse_tpreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
961       break;
962     case MEP_OPERAND_UDISP2 :
963       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_UDISP2, (long *) (& fields->f_2u6));
964       break;
965     case MEP_OPERAND_UDISP7 :
966       errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7, (unsigned long *) (& fields->f_7u9));
967       break;
968     case MEP_OPERAND_UDISP7A2 :
969       errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A2, (unsigned long *) (& fields->f_7u9a2));
970       break;
971     case MEP_OPERAND_UDISP7A4 :
972       errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A4, (unsigned long *) (& fields->f_7u9a4));
973       break;
974     case MEP_OPERAND_UIMM16 :
975       errmsg = parse_unsigned16 (cd, strp, MEP_OPERAND_UIMM16, (unsigned long *) (& fields->f_16u16));
976       break;
977     case MEP_OPERAND_UIMM2 :
978       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM2, (unsigned long *) (& fields->f_2u10));
979       break;
980     case MEP_OPERAND_UIMM24 :
981       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM24, (unsigned long *) (& fields->f_24u8n));
982       break;
983     case MEP_OPERAND_UIMM3 :
984       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM3, (unsigned long *) (& fields->f_3u5));
985       break;
986     case MEP_OPERAND_UIMM4 :
987       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM4, (unsigned long *) (& fields->f_4u8));
988       break;
989     case MEP_OPERAND_UIMM5 :
990       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM5, (unsigned long *) (& fields->f_5u8));
991       break;
992     case MEP_OPERAND_UIMM7A4 :
993       errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_UIMM7A4, (unsigned long *) (& fields->f_7u9a4));
994       break;
995     case MEP_OPERAND_ZERO :
996       errmsg = parse_zero (cd, strp, MEP_OPERAND_ZERO, (long *) (& junk));
997       break;
998 
999     default :
1000       /* xgettext:c-format */
1001       fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
1002       abort ();
1003   }
1004 
1005   return errmsg;
1006 }
1007 
1008 cgen_parse_fn * const mep_cgen_parse_handlers[] =
1009 {
1010   parse_insn_normal,
1011 };
1012 
1013 void
1014 mep_cgen_init_asm (CGEN_CPU_DESC cd)
1015 {
1016   mep_cgen_init_opcode_table (cd);
1017   mep_cgen_init_ibld_table (cd);
1018   cd->parse_handlers = & mep_cgen_parse_handlers[0];
1019   cd->parse_operand = mep_cgen_parse_operand;
1020 #ifdef CGEN_ASM_INIT_HOOK
1021 CGEN_ASM_INIT_HOOK
1022 #endif
1023 }
1024 
1025 
1026 
1027 /* Regex construction routine.
1028 
1029    This translates an opcode syntax string into a regex string,
1030    by replacing any non-character syntax element (such as an
1031    opcode) with the pattern '.*'
1032 
1033    It then compiles the regex and stores it in the opcode, for
1034    later use by mep_cgen_assemble_insn
1035 
1036    Returns NULL for success, an error message for failure.  */
1037 
1038 char *
1039 mep_cgen_build_insn_regex (CGEN_INSN *insn)
1040 {
1041   CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
1042   const char *mnem = CGEN_INSN_MNEMONIC (insn);
1043   char rxbuf[CGEN_MAX_RX_ELEMENTS];
1044   char *rx = rxbuf;
1045   const CGEN_SYNTAX_CHAR_TYPE *syn;
1046   int reg_err;
1047 
1048   syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
1049 
1050   /* Mnemonics come first in the syntax string.  */
1051   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1052     return _("missing mnemonic in syntax string");
1053   ++syn;
1054 
1055   /* Generate a case sensitive regular expression that emulates case
1056      insensitive matching in the "C" locale.  We cannot generate a case
1057      insensitive regular expression because in Turkish locales, 'i' and 'I'
1058      are not equal modulo case conversion.  */
1059 
1060   /* Copy the literal mnemonic out of the insn.  */
1061   for (; *mnem; mnem++)
1062     {
1063       char c = *mnem;
1064 
1065       if (ISALPHA (c))
1066 	{
1067 	  *rx++ = '[';
1068 	  *rx++ = TOLOWER (c);
1069 	  *rx++ = TOUPPER (c);
1070 	  *rx++ = ']';
1071 	}
1072       else
1073 	*rx++ = c;
1074     }
1075 
1076   /* Copy any remaining literals from the syntax string into the rx.  */
1077   for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
1078     {
1079       if (CGEN_SYNTAX_CHAR_P (* syn))
1080 	{
1081 	  char c = CGEN_SYNTAX_CHAR (* syn);
1082 
1083 	  switch (c)
1084 	    {
1085 	      /* Escape any regex metacharacters in the syntax.  */
1086 	    case '.': case '[': case '\\':
1087 	    case '*': case '^': case '$':
1088 
1089 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
1090 	    case '?': case '{': case '}':
1091 	    case '(': case ')': case '*':
1092 	    case '|': case '+': case ']':
1093 #endif
1094 	      *rx++ = '\\';
1095 	      *rx++ = c;
1096 	      break;
1097 
1098 	    default:
1099 	      if (ISALPHA (c))
1100 		{
1101 		  *rx++ = '[';
1102 		  *rx++ = TOLOWER (c);
1103 		  *rx++ = TOUPPER (c);
1104 		  *rx++ = ']';
1105 		}
1106 	      else
1107 		*rx++ = c;
1108 	      break;
1109 	    }
1110 	}
1111       else
1112 	{
1113 	  /* Replace non-syntax fields with globs.  */
1114 	  *rx++ = '.';
1115 	  *rx++ = '*';
1116 	}
1117     }
1118 
1119   /* Trailing whitespace ok.  */
1120   * rx++ = '[';
1121   * rx++ = ' ';
1122   * rx++ = '\t';
1123   * rx++ = ']';
1124   * rx++ = '*';
1125 
1126   /* But anchor it after that.  */
1127   * rx++ = '$';
1128   * rx = '\0';
1129 
1130   CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
1131   reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
1132 
1133   if (reg_err == 0)
1134     return NULL;
1135   else
1136     {
1137       static char msg[80];
1138 
1139       regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
1140       regfree ((regex_t *) CGEN_INSN_RX (insn));
1141       free (CGEN_INSN_RX (insn));
1142       (CGEN_INSN_RX (insn)) = NULL;
1143       return msg;
1144     }
1145 }
1146 
1147 
1148 /* Default insn parser.
1149 
1150    The syntax string is scanned and operands are parsed and stored in FIELDS.
1151    Relocs are queued as we go via other callbacks.
1152 
1153    ??? Note that this is currently an all-or-nothing parser.  If we fail to
1154    parse the instruction, we return 0 and the caller will start over from
1155    the beginning.  Backtracking will be necessary in parsing subexpressions,
1156    but that can be handled there.  Not handling backtracking here may get
1157    expensive in the case of the m68k.  Deal with later.
1158 
1159    Returns NULL for success, an error message for failure.  */
1160 
1161 static const char *
1162 parse_insn_normal (CGEN_CPU_DESC cd,
1163 		   const CGEN_INSN *insn,
1164 		   const char **strp,
1165 		   CGEN_FIELDS *fields)
1166 {
1167   /* ??? Runtime added insns not handled yet.  */
1168   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
1169   const char *str = *strp;
1170   const char *errmsg;
1171   const char *p;
1172   const CGEN_SYNTAX_CHAR_TYPE * syn;
1173 #ifdef CGEN_MNEMONIC_OPERANDS
1174   /* FIXME: wip */
1175   int past_opcode_p;
1176 #endif
1177 
1178   /* For now we assume the mnemonic is first (there are no leading operands).
1179      We can parse it without needing to set up operand parsing.
1180      GAS's input scrubber will ensure mnemonics are lowercase, but we may
1181      not be called from GAS.  */
1182   p = CGEN_INSN_MNEMONIC (insn);
1183   while (*p && TOLOWER (*p) == TOLOWER (*str))
1184     ++p, ++str;
1185 
1186   if (* p)
1187     return _("unrecognized instruction");
1188 
1189 #ifndef CGEN_MNEMONIC_OPERANDS
1190   if (* str && ! ISSPACE (* str))
1191     return _("unrecognized instruction");
1192 #endif
1193 
1194   CGEN_INIT_PARSE (cd);
1195   cgen_init_parse_operand (cd);
1196 #ifdef CGEN_MNEMONIC_OPERANDS
1197   past_opcode_p = 0;
1198 #endif
1199 
1200   /* We don't check for (*str != '\0') here because we want to parse
1201      any trailing fake arguments in the syntax string.  */
1202   syn = CGEN_SYNTAX_STRING (syntax);
1203 
1204   /* Mnemonics come first for now, ensure valid string.  */
1205   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1206     abort ();
1207 
1208   ++syn;
1209 
1210   while (* syn != 0)
1211     {
1212       /* Non operand chars must match exactly.  */
1213       if (CGEN_SYNTAX_CHAR_P (* syn))
1214 	{
1215 	  /* FIXME: While we allow for non-GAS callers above, we assume the
1216 	     first char after the mnemonic part is a space.  */
1217 	  /* FIXME: We also take inappropriate advantage of the fact that
1218 	     GAS's input scrubber will remove extraneous blanks.  */
1219 	  if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
1220 	    {
1221 #ifdef CGEN_MNEMONIC_OPERANDS
1222 	      if (CGEN_SYNTAX_CHAR(* syn) == ' ')
1223 		past_opcode_p = 1;
1224 #endif
1225 	      ++ syn;
1226 	      ++ str;
1227 	    }
1228 	  else if (*str)
1229 	    {
1230 	      /* Syntax char didn't match.  Can't be this insn.  */
1231 	      static char msg [80];
1232 
1233 	      /* xgettext:c-format */
1234 	      sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
1235 		       CGEN_SYNTAX_CHAR(*syn), *str);
1236 	      return msg;
1237 	    }
1238 	  else
1239 	    {
1240 	      /* Ran out of input.  */
1241 	      static char msg [80];
1242 
1243 	      /* xgettext:c-format */
1244 	      sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
1245 		       CGEN_SYNTAX_CHAR(*syn));
1246 	      return msg;
1247 	    }
1248 	  continue;
1249 	}
1250 
1251       /* We have an operand of some sort.  */
1252       errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
1253 					  &str, fields);
1254       if (errmsg)
1255 	return errmsg;
1256 
1257       /* Done with this operand, continue with next one.  */
1258       ++ syn;
1259     }
1260 
1261   /* If we're at the end of the syntax string, we're done.  */
1262   if (* syn == 0)
1263     {
1264       /* FIXME: For the moment we assume a valid `str' can only contain
1265 	 blanks now.  IE: We needn't try again with a longer version of
1266 	 the insn and it is assumed that longer versions of insns appear
1267 	 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
1268       while (ISSPACE (* str))
1269 	++ str;
1270 
1271       if (* str != '\0')
1272 	return _("junk at end of line"); /* FIXME: would like to include `str' */
1273 
1274       return NULL;
1275     }
1276 
1277   /* We couldn't parse it.  */
1278   return _("unrecognized instruction");
1279 }
1280 
1281 /* Main entry point.
1282    This routine is called for each instruction to be assembled.
1283    STR points to the insn to be assembled.
1284    We assume all necessary tables have been initialized.
1285    The assembled instruction, less any fixups, is stored in BUF.
1286    Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
1287    still needs to be converted to target byte order, otherwise BUF is an array
1288    of bytes in target byte order.
1289    The result is a pointer to the insn's entry in the opcode table,
1290    or NULL if an error occured (an error message will have already been
1291    printed).
1292 
1293    Note that when processing (non-alias) macro-insns,
1294    this function recurses.
1295 
1296    ??? It's possible to make this cpu-independent.
1297    One would have to deal with a few minor things.
1298    At this point in time doing so would be more of a curiosity than useful
1299    [for example this file isn't _that_ big], but keeping the possibility in
1300    mind helps keep the design clean.  */
1301 
1302 const CGEN_INSN *
1303 mep_cgen_assemble_insn (CGEN_CPU_DESC cd,
1304 			   const char *str,
1305 			   CGEN_FIELDS *fields,
1306 			   CGEN_INSN_BYTES_PTR buf,
1307 			   char **errmsg)
1308 {
1309   const char *start;
1310   CGEN_INSN_LIST *ilist;
1311   const char *parse_errmsg = NULL;
1312   const char *insert_errmsg = NULL;
1313   int recognized_mnemonic = 0;
1314 
1315   /* Skip leading white space.  */
1316   while (ISSPACE (* str))
1317     ++ str;
1318 
1319   /* The instructions are stored in hashed lists.
1320      Get the first in the list.  */
1321   ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
1322 
1323   /* Keep looking until we find a match.  */
1324   start = str;
1325   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
1326     {
1327       const CGEN_INSN *insn = ilist->insn;
1328       recognized_mnemonic = 1;
1329 
1330 #ifdef CGEN_VALIDATE_INSN_SUPPORTED
1331       /* Not usually needed as unsupported opcodes
1332 	 shouldn't be in the hash lists.  */
1333       /* Is this insn supported by the selected cpu?  */
1334       if (! mep_cgen_insn_supported (cd, insn))
1335 	continue;
1336 #endif
1337       /* If the RELAXED attribute is set, this is an insn that shouldn't be
1338 	 chosen immediately.  Instead, it is used during assembler/linker
1339 	 relaxation if possible.  */
1340       if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
1341 	continue;
1342 
1343       str = start;
1344 
1345       /* Skip this insn if str doesn't look right lexically.  */
1346       if (CGEN_INSN_RX (insn) != NULL &&
1347 	  regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
1348 	continue;
1349 
1350       /* Allow parse/insert handlers to obtain length of insn.  */
1351       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
1352 
1353       parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
1354       if (parse_errmsg != NULL)
1355 	continue;
1356 
1357       /* ??? 0 is passed for `pc'.  */
1358       insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
1359 						 (bfd_vma) 0);
1360       if (insert_errmsg != NULL)
1361         continue;
1362 
1363       /* It is up to the caller to actually output the insn and any
1364          queued relocs.  */
1365       return insn;
1366     }
1367 
1368   {
1369     static char errbuf[150];
1370 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
1371     const char *tmp_errmsg;
1372 
1373     /* If requesting verbose error messages, use insert_errmsg.
1374        Failing that, use parse_errmsg.  */
1375     tmp_errmsg = (insert_errmsg ? insert_errmsg :
1376 		  parse_errmsg ? parse_errmsg :
1377 		  recognized_mnemonic ?
1378 		  _("unrecognized form of instruction") :
1379 		  _("unrecognized instruction"));
1380 
1381     if (strlen (start) > 50)
1382       /* xgettext:c-format */
1383       sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
1384     else
1385       /* xgettext:c-format */
1386       sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
1387 #else
1388     if (strlen (start) > 50)
1389       /* xgettext:c-format */
1390       sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1391     else
1392       /* xgettext:c-format */
1393       sprintf (errbuf, _("bad instruction `%.50s'"), start);
1394 #endif
1395 
1396     *errmsg = errbuf;
1397     return NULL;
1398   }
1399 }
1400