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