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