mep-asm.c revision 302408
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
46static const char * parse_insn_normal
47  (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
48
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 *);
60static const char * parse_signed16   (CGEN_CPU_DESC, const char **, int, long *);
61static const char * parse_unsigned16 (CGEN_CPU_DESC, const char **, int, unsigned long *);
62static const char * parse_lo16       (CGEN_CPU_DESC, const char **, int, long *, long);
63static const char * parse_unsigned7  (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
64static const char * parse_zero       (CGEN_CPU_DESC, const char **, int, long *);
65
66const char *
67parse_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 */
85static const char *
86parse_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}
93static const char *
94parse_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
103const char *
104parse_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
117const char *
118parse_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
131const char *
132parse_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
194const char *
195parse_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
205static const char *
206parse_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
214static const char *
215parse_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
303static const char *
304parse_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
314static const char *
315parse_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
416static const char *
417parse_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
463typedef struct
464{
465  char *name;
466  char *expansion;
467}  macro;
468
469typedef struct
470{
471  const char *start;
472  int len;
473} arg;
474
475macro 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
487static char  * expand_string    (const char *, int);
488
489static const char *
490mep_cgen_expand_macros_and_parse_operand
491  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
492
493static char *
494str_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
508static macro *
509lookup_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
520static char *
521expand_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
562static char *
563expand_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
670const char * mep_cgen_parse_operand
671  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
672
673const char *
674mep_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
714const 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
730const char *
731mep_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
1007cgen_parse_fn * const mep_cgen_parse_handlers[] =
1008{
1009  parse_insn_normal,
1010};
1011
1012void
1013mep_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
1020CGEN_ASM_INIT_HOOK
1021#endif
1022}
1023
1024
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
1037char *
1038mep_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
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
1160static const char *
1161parse_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
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
1301const CGEN_INSN *
1302mep_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}
1399