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