Change source files over to GPLv3.
[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
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 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 \f
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 \f
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 \f
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 }