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