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