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 (C) 1996-2017 Free Software Foundation, Inc.
8
9   This file is part of libopcodes.
10
11   This library is free software; you can redistribute it and/or modify
12   it under the terms of the GNU General Public License as published by
13   the Free Software Foundation; either version 3, or (at your option)
14   any later version.
15
16   It is distributed in the hope that it will be useful, but WITHOUT
17   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
19   License for more details.
20
21   You should have received a copy of the GNU General Public License
22   along with this program; if not, write to the Free Software Foundation, Inc.,
23   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
24
25
26/* ??? Eventually more and more of this stuff can go to cpu-independent files.
27   Keep that in mind.  */
28
29#include "sysdep.h"
30#include <stdio.h>
31#include "ansidecl.h"
32#include "bfd.h"
33#include "symcat.h"
34#include "mep-desc.h"
35#include "mep-opc.h"
36#include "opintl.h"
37#include "xregex.h"
38#include "libiberty.h"
39#include "safe-ctype.h"
40
41#undef  min
42#define min(a,b) ((a) < (b) ? (a) : (b))
43#undef  max
44#define max(a,b) ((a) > (b) ? (a) : (b))
45
46static const char * parse_insn_normal
47  (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
48
49/* -- assembler routines inserted here.  */
50
51/* -- asm.c */
52
53#include "elf/mep.h"
54
55#define CGEN_VALIDATE_INSN_SUPPORTED
56#define mep_cgen_insn_supported mep_cgen_insn_supported_asm
57
58       const char * parse_csrn       (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
59       const char * parse_tpreg      (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
60       const char * parse_spreg      (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
61       const char * parse_mep_align  (CGEN_CPU_DESC, const char **, enum cgen_operand_type, long *);
62       const char * parse_mep_alignu (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
63static const char * parse_signed16   (CGEN_CPU_DESC, const char **, int, long *);
64static const char * parse_signed16_range   (CGEN_CPU_DESC, const char **, int, long *) ATTRIBUTE_UNUSED;
65static const char * parse_unsigned16 (CGEN_CPU_DESC, const char **, int, unsigned long *);
66static const char * parse_unsigned16_range (CGEN_CPU_DESC, const char **, int, unsigned long *) ATTRIBUTE_UNUSED;
67static const char * parse_lo16       (CGEN_CPU_DESC, const char **, int, long *, long);
68static const char * parse_unsigned7  (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
69static const char * parse_zero       (CGEN_CPU_DESC, const char **, int, long *);
70
71const char *
72parse_csrn (CGEN_CPU_DESC cd, const char **strp,
73	    CGEN_KEYWORD *keyword_table, long *field)
74{
75  const char *err;
76  unsigned long value;
77
78  err = cgen_parse_keyword (cd, strp, keyword_table, field);
79  if (!err)
80    return NULL;
81
82  err = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, & value);
83  if (err)
84    return err;
85  *field = value;
86  return NULL;
87}
88
89/* begin-cop-ip-parse-handlers */
90static const char *
91parse_ivc2_cr (CGEN_CPU_DESC,
92	const char **,
93	CGEN_KEYWORD *,
94	long *) ATTRIBUTE_UNUSED;
95static const char *
96parse_ivc2_cr (CGEN_CPU_DESC cd,
97	const char **strp,
98	CGEN_KEYWORD *keyword_table  ATTRIBUTE_UNUSED,
99	long *field)
100{
101  return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr_ivc2, field);
102}
103static const char *
104parse_ivc2_ccr (CGEN_CPU_DESC,
105	const char **,
106	CGEN_KEYWORD *,
107	long *) ATTRIBUTE_UNUSED;
108static const char *
109parse_ivc2_ccr (CGEN_CPU_DESC cd,
110	const char **strp,
111	CGEN_KEYWORD *keyword_table  ATTRIBUTE_UNUSED,
112	long *field)
113{
114  return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, field);
115}
116/* end-cop-ip-parse-handlers */
117
118const char *
119parse_tpreg (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 != 13)
128    return _("Only $tp or $13 allowed for this opcode");
129  return NULL;
130}
131
132const char *
133parse_spreg (CGEN_CPU_DESC cd, const char ** strp,
134	     CGEN_KEYWORD *keyword_table, long *field)
135{
136  const char *err;
137
138  err = cgen_parse_keyword (cd, strp, keyword_table, field);
139  if (err)
140    return err;
141  if (*field != 15)
142    return _("Only $sp or $15 allowed for this opcode");
143  return NULL;
144}
145
146const char *
147parse_mep_align (CGEN_CPU_DESC cd, const char ** strp,
148		 enum cgen_operand_type type, long *field)
149{
150  long lsbs = 0;
151  const char *err;
152
153  switch (type)
154    {
155    case MEP_OPERAND_PCREL8A2:
156    case MEP_OPERAND_PCREL12A2:
157    case MEP_OPERAND_PCREL17A2:
158    case MEP_OPERAND_PCREL24A2:
159      err = cgen_parse_signed_integer   (cd, strp, type, field);
160      break;
161    case MEP_OPERAND_PCABS24A2:
162    case MEP_OPERAND_UDISP7:
163    case MEP_OPERAND_UDISP7A2:
164    case MEP_OPERAND_UDISP7A4:
165    case MEP_OPERAND_UIMM7A4:
166    case MEP_OPERAND_ADDR24A4:
167      err = cgen_parse_unsigned_integer (cd, strp, type, (unsigned long *) field);
168      break;
169    default:
170      abort();
171    }
172  if (err)
173    return err;
174  switch (type)
175    {
176    case MEP_OPERAND_UDISP7:
177      lsbs = 0;
178      break;
179    case MEP_OPERAND_PCREL8A2:
180    case MEP_OPERAND_PCREL12A2:
181    case MEP_OPERAND_PCREL17A2:
182    case MEP_OPERAND_PCREL24A2:
183    case MEP_OPERAND_PCABS24A2:
184    case MEP_OPERAND_UDISP7A2:
185      lsbs = *field & 1;
186      break;
187    case MEP_OPERAND_UDISP7A4:
188    case MEP_OPERAND_UIMM7A4:
189    case MEP_OPERAND_ADDR24A4:
190      lsbs = *field & 3;
191      break;
192      lsbs = *field & 7;
193      break;
194    default:
195      /* Safe assumption?  */
196      abort ();
197    }
198  if (lsbs)
199    return "Value is not aligned enough";
200  return NULL;
201}
202
203const char *
204parse_mep_alignu (CGEN_CPU_DESC cd, const char ** strp,
205		 enum cgen_operand_type type, unsigned long *field)
206{
207  return parse_mep_align (cd, strp, type, (long *) field);
208}
209
210
211/* Handle %lo(), %tpoff(), %sdaoff(), %hi(), and other signed
212   constants in a signed context.  */
213
214static const char *
215parse_signed16 (CGEN_CPU_DESC cd,
216		const char **strp,
217		int opindex,
218		long *valuep)
219{
220  return parse_lo16 (cd, strp, opindex, valuep, 1);
221}
222
223static const char *
224parse_lo16 (CGEN_CPU_DESC cd,
225	    const char **strp,
226	    int opindex,
227	    long *valuep,
228	    long signedp)
229{
230  const char *errmsg;
231  enum cgen_parse_operand_result result_type;
232  bfd_vma value;
233
234  if (strncasecmp (*strp, "%lo(", 4) == 0)
235    {
236      *strp += 4;
237      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
238				   & result_type, & value);
239      if (**strp != ')')
240	return _("missing `)'");
241      ++*strp;
242      if (errmsg == NULL
243	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
244	value &= 0xffff;
245      if (signedp)
246	*valuep = (long)(short) value;
247      else
248	*valuep = value;
249      return errmsg;
250    }
251
252  if (strncasecmp (*strp, "%hi(", 4) == 0)
253    {
254      *strp += 4;
255      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
256				   & result_type, & value);
257      if (**strp != ')')
258	return _("missing `)'");
259      ++*strp;
260      if (errmsg == NULL
261	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
262	value = (value + 0x8000) >> 16;
263      *valuep = value;
264      return errmsg;
265    }
266
267  if (strncasecmp (*strp, "%uhi(", 5) == 0)
268    {
269      *strp += 5;
270      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
271				   & result_type, & value);
272      if (**strp != ')')
273	return _("missing `)'");
274      ++*strp;
275      if (errmsg == NULL
276	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
277	value = value >> 16;
278      *valuep = value;
279      return errmsg;
280    }
281
282  if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
283    {
284      *strp += 8;
285      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
286				   NULL, & value);
287      if (**strp != ')')
288	return _("missing `)'");
289      ++*strp;
290      *valuep = value;
291      return errmsg;
292    }
293
294  if (strncasecmp (*strp, "%tpoff(", 7) == 0)
295    {
296      *strp += 7;
297      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
298				   NULL, & value);
299      if (**strp != ')')
300	return _("missing `)'");
301      ++*strp;
302      *valuep = value;
303      return errmsg;
304    }
305
306  if (**strp == '%')
307    return _("invalid %function() here");
308
309  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
310}
311
312static const char *
313parse_unsigned16 (CGEN_CPU_DESC cd,
314		  const char **strp,
315		  int opindex,
316		  unsigned long *valuep)
317{
318  return parse_lo16 (cd, strp, opindex, (long *) valuep, 0);
319}
320
321static const char *
322parse_signed16_range (CGEN_CPU_DESC cd,
323		      const char **strp,
324		      int opindex,
325		      signed long *valuep)
326{
327  const char *errmsg = 0;
328  signed long value;
329
330  errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
331  if (errmsg)
332    return errmsg;
333
334  if (value < -32768 || value > 32767)
335    return _("Immediate is out of range -32768 to 32767");
336
337  *valuep = value;
338  return 0;
339}
340
341static const char *
342parse_unsigned16_range (CGEN_CPU_DESC cd,
343			const char **strp,
344			int opindex,
345			unsigned long *valuep)
346{
347  const char *errmsg = 0;
348  unsigned long value;
349
350  errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
351  if (errmsg)
352    return errmsg;
353
354  if (value > 65535)
355    return _("Immediate is out of range 0 to 65535");
356
357  *valuep = value;
358  return 0;
359}
360
361/* A special case of parse_signed16 which accepts only the value zero.  */
362
363static const char *
364parse_zero (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
365{
366  const char *errmsg;
367  enum cgen_parse_operand_result result_type;
368  bfd_vma value;
369
370  /*fprintf(stderr, "dj: signed parse opindex `%s'\n", *strp);*/
371
372  /* Prevent ($ry) from being attempted as an expression on 'sw $rx,($ry)'.
373     It will fail and cause ry to be listed as an undefined symbol in the
374     listing.  */
375  if (strncmp (*strp, "($", 2) == 0)
376    return "not zero"; /* any string will do -- will never be seen.  */
377
378  if (strncasecmp (*strp, "%lo(", 4) == 0)
379    {
380      *strp += 4;
381      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
382				   &result_type, &value);
383      if (**strp != ')')
384	return "missing `)'";
385      ++*strp;
386      if (errmsg == NULL
387	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
388	return "not zero"; /* any string will do -- will never be seen.  */
389      *valuep = value;
390      return errmsg;
391    }
392
393  if (strncasecmp (*strp, "%hi(", 4) == 0)
394    {
395      *strp += 4;
396      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
397				   &result_type, &value);
398      if (**strp != ')')
399	return "missing `)'";
400      ++*strp;
401      if (errmsg == NULL
402	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
403	return "not zero"; /* any string will do -- will never be seen.  */
404      *valuep = value;
405      return errmsg;
406    }
407
408  if (strncasecmp (*strp, "%uhi(", 5) == 0)
409    {
410      *strp += 5;
411      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
412				   &result_type, &value);
413      if (**strp != ')')
414	return "missing `)'";
415      ++*strp;
416      if (errmsg == NULL
417	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
418	return "not zero"; /* any string will do -- will never be seen.  */
419      *valuep = value;
420      return errmsg;
421    }
422
423  if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
424    {
425      *strp += 8;
426      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
427				   &result_type, &value);
428      if (**strp != ')')
429	return "missing `)'";
430      ++*strp;
431      if (errmsg == NULL
432	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
433	return "not zero"; /* any string will do -- will never be seen.  */
434      *valuep = value;
435      return errmsg;
436    }
437
438  if (strncasecmp (*strp, "%tpoff(", 7) == 0)
439    {
440      *strp += 7;
441      errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
442				   &result_type, &value);
443      if (**strp != ')')
444	return "missing `)'";
445      ++*strp;
446      if (errmsg == NULL
447	  && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
448	return "not zero"; /* any string will do -- will never be seen.  */
449      *valuep = value;
450      return errmsg;
451    }
452
453  if (**strp == '%')
454    return "invalid %function() here";
455
456  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_NONE,
457			       &result_type, &value);
458  if (errmsg == NULL
459      && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
460    return "not zero"; /* any string will do -- will never be seen.  */
461
462  return errmsg;
463}
464
465static const char *
466parse_unsigned7 (CGEN_CPU_DESC cd, const char **strp,
467		 enum cgen_operand_type opindex, unsigned long *valuep)
468{
469  const char *errmsg;
470  bfd_vma value;
471
472  /* fprintf(stderr, "dj: unsigned7 parse `%s'\n", *strp); */
473
474  if (strncasecmp (*strp, "%tpoff(", 7) == 0)
475    {
476      int reloc;
477      *strp += 7;
478      switch (opindex)
479	{
480	case MEP_OPERAND_UDISP7:
481	  reloc = BFD_RELOC_MEP_TPREL7;
482	  break;
483	case MEP_OPERAND_UDISP7A2:
484	  reloc = BFD_RELOC_MEP_TPREL7A2;
485	  break;
486	case MEP_OPERAND_UDISP7A4:
487	  reloc = BFD_RELOC_MEP_TPREL7A4;
488	  break;
489	default:
490	  /* Safe assumption?  */
491	  abort ();
492	}
493      errmsg = cgen_parse_address (cd, strp, opindex, reloc,
494				   NULL, &value);
495      if (**strp != ')')
496	return "missing `)'";
497      ++*strp;
498      *valuep = value;
499      return errmsg;
500    }
501
502  if (**strp == '%')
503    return _("invalid %function() here");
504
505  return parse_mep_alignu (cd, strp, opindex, valuep);
506}
507
508static ATTRIBUTE_UNUSED const char *
509parse_cdisp10 (CGEN_CPU_DESC cd,
510	       const char **strp,
511	       int opindex,
512	       long *valuep)
513{
514  const char *errmsg = 0;
515  signed long value;
516  long have_zero = 0;
517  int wide = 0;
518  int alignment;
519
520  switch (opindex)
521    {
522    case MEP_OPERAND_CDISP10A4:
523      alignment = 2;
524      break;
525    case MEP_OPERAND_CDISP10A2:
526      alignment = 1;
527      break;
528    case MEP_OPERAND_CDISP10:
529    default:
530      alignment = 0;
531      break;
532    }
533
534  if ((MEP_CPU & EF_MEP_CPU_MASK) == EF_MEP_CPU_C5)
535    wide = 1;
536
537  if (strncmp (*strp, "0x0", 3) == 0
538      || (**strp == '0' && *(*strp + 1) != 'x'))
539    have_zero = 1;
540
541  errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
542  if (errmsg)
543    return errmsg;
544
545  if (wide)
546    {
547      if (value < -512 || value > 511)
548	return _("Immediate is out of range -512 to 511");
549    }
550  else
551    {
552      if (value < -128 || value > 127)
553	return _("Immediate is out of range -128 to 127");
554    }
555
556  if (value & ((1<<alignment)-1))
557    return _("Value is not aligned enough");
558
559  /* If this field may require a relocation then use larger dsp16.  */
560  if (! have_zero && value == 0)
561    return (wide ? _("Immediate is out of range -512 to 511")
562	    : _("Immediate is out of range -128 to 127"));
563
564  *valuep = value;
565  return 0;
566}
567
568/* BEGIN LIGHTWEIGHT MACRO PROCESSOR.  */
569
570#define MAXARGS 9
571
572typedef struct
573{
574  char *name;
575  char *expansion;
576}  macro;
577
578typedef struct
579{
580  const char *start;
581  int len;
582} arg;
583
584macro macros[] =
585{
586  { "sizeof", "(`1.end + (- `1))"},
587  { "startof", "(`1 | 0)" },
588  { "align4", "(`1&(~3))"},
589/*{ "hi", "(((`1+0x8000)>>16) & 0xffff)" },  */
590/*{ "lo", "(`1 & 0xffff)" },  */
591/*{ "sdaoff", "((`1-__sdabase) & 0x7f)"},  */
592/*{ "tpoff", "((`1-__tpbase) & 0x7f)"},  */
593  { 0,0 }
594};
595
596static char  * expand_string    (const char *, int);
597
598static const char *
599mep_cgen_expand_macros_and_parse_operand
600  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
601
602static char *
603str_append (char *dest, const char *input, int len)
604{
605  char *new_dest;
606  int oldlen;
607
608  if (len == 0)
609    return dest;
610  /* printf("str_append: <<%s>>, <<%s>>, %d\n", dest, input, len); */
611  oldlen = (dest ? strlen(dest) : 0);
612  new_dest = realloc (dest, oldlen + len + 1);
613  memset (new_dest + oldlen, 0, len + 1);
614  return strncat (new_dest, input, len);
615}
616
617static macro *
618lookup_macro (const char *name)
619{
620  macro *m;
621
622  for (m = macros; m->name; ++m)
623    if (strncmp (m->name, name, strlen(m->name)) == 0)
624      return m;
625
626  return 0;
627}
628
629static char *
630expand_macro (arg *args, int narg, macro *mac)
631{
632  char *result = 0, *rescanned_result = 0;
633  char *e = mac->expansion;
634  char *mark = e;
635  int mac_arg = 0;
636
637  /*  printf("expanding macro %s with %d args\n", mac->name, narg + 1); */
638  while (*e)
639    {
640      if (*e == '`' &&
641	  (*e+1) &&
642	  ((*(e + 1) - '1') <= MAXARGS) &&
643	  ((*(e + 1) - '1') <= narg))
644	{
645	  result = str_append (result, mark, e - mark);
646	  mac_arg = (*(e + 1) - '1');
647	  /* printf("replacing `%d with %s\n", mac_arg+1, args[mac_arg].start); */
648	  result = str_append (result, args[mac_arg].start, args[mac_arg].len);
649	  ++e;
650	  mark = e+1;
651	}
652      ++e;
653    }
654
655  if (mark != e)
656    result = str_append (result, mark, e - mark);
657
658  if (result)
659    {
660      rescanned_result = expand_string (result, 0);
661      free (result);
662      return rescanned_result;
663    }
664  else
665    return result;
666}
667
668#define IN_TEXT 0
669#define IN_ARGS 1
670
671static char *
672expand_string (const char *in, int first_only)
673{
674  int num_expansions = 0;
675  int depth = 0;
676  int narg = -1;
677  arg args[MAXARGS];
678  int state = IN_TEXT;
679  const char *mark = in;
680  macro *pmacro = NULL;
681  char *expansion = 0;
682  char *result = 0;
683
684  while (*in)
685    {
686      switch (state)
687	{
688	case IN_TEXT:
689	  if (*in == '%' && *(in + 1) && (!first_only || num_expansions == 0))
690	    {
691	      pmacro = lookup_macro (in + 1);
692	      if (pmacro)
693		{
694		  /* printf("entering state %d at '%s'...\n", state, in); */
695		  result = str_append (result, mark, in - mark);
696		  mark = in;
697		  in += 1 + strlen (pmacro->name);
698		  while (*in == ' ') ++in;
699		  if (*in != '(')
700		    {
701		      state = IN_TEXT;
702		      pmacro = NULL;
703		    }
704		  else
705		    {
706		      state = IN_ARGS;
707		      narg = 0;
708		      args[narg].start = in + 1;
709		      args[narg].len = 0;
710		      mark = in + 1;
711		    }
712		}
713	    }
714	  break;
715	case IN_ARGS:
716	  if (depth == 0)
717	    {
718	      switch (*in)
719		{
720		case ',':
721		  narg++;
722		  args[narg].start = (in + 1);
723		  args[narg].len = 0;
724		  break;
725		case ')':
726		  state = IN_TEXT;
727		  /* printf("entering state %d at '%s'...\n", state, in); */
728		  if (pmacro)
729		    {
730		      expansion = 0;
731		      expansion = expand_macro (args, narg, pmacro);
732		      num_expansions++;
733		      if (expansion)
734			{
735			  result = str_append (result, expansion, strlen (expansion));
736			  free (expansion);
737			}
738		    }
739		  else
740		    {
741		      result = str_append (result, mark, in - mark);
742		    }
743		  pmacro = NULL;
744		  mark = in + 1;
745		  break;
746		case '(':
747		  depth++;
748		  /* Fall through.  */
749		default:
750		  args[narg].len++;
751		  break;
752		}
753	    }
754	  else
755	    {
756	      if (*in == ')')
757		depth--;
758	      if (narg > -1)
759		args[narg].len++;
760	    }
761
762	}
763      ++in;
764    }
765
766  if (mark != in)
767    result = str_append (result, mark, in - mark);
768
769  return result;
770}
771
772#undef IN_ARGS
773#undef IN_TEXT
774#undef MAXARGS
775
776
777/* END LIGHTWEIGHT MACRO PROCESSOR.  */
778
779const char * mep_cgen_parse_operand
780  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
781
782const char *
783mep_cgen_expand_macros_and_parse_operand (CGEN_CPU_DESC cd, int opindex,
784					  const char ** strp_in, CGEN_FIELDS * fields)
785{
786  const char * errmsg = NULL;
787  char *str = 0, *hold = 0;
788  const char **strp = 0;
789
790  /* Set up a new pointer to macro-expanded string.  */
791  str = expand_string (*strp_in, 1);
792  /* fprintf (stderr, " expanded <<%s>> to <<%s>>\n", *strp_in, str); */
793
794  hold = str;
795  strp = (const char **)(&str);
796
797  errmsg = mep_cgen_parse_operand (cd, opindex, strp, fields);
798
799  /* Now work out the advance.  */
800  if (strlen (str) == 0)
801    *strp_in += strlen (*strp_in);
802
803  else
804    {
805      if (strstr (*strp_in, str))
806	/* A macro-expansion was pulled off the front.  */
807	*strp_in = strstr (*strp_in, str);
808      else
809	/* A non-macro-expansion was pulled off the front.  */
810	*strp_in += (str - hold);
811    }
812
813  if (hold)
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      fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
1287      abort ();
1288  }
1289
1290  return errmsg;
1291}
1292
1293cgen_parse_fn * const mep_cgen_parse_handlers[] =
1294{
1295  parse_insn_normal,
1296};
1297
1298void
1299mep_cgen_init_asm (CGEN_CPU_DESC cd)
1300{
1301  mep_cgen_init_opcode_table (cd);
1302  mep_cgen_init_ibld_table (cd);
1303  cd->parse_handlers = & mep_cgen_parse_handlers[0];
1304  cd->parse_operand = mep_cgen_parse_operand;
1305#ifdef CGEN_ASM_INIT_HOOK
1306CGEN_ASM_INIT_HOOK
1307#endif
1308}
1309
1310
1311
1312/* Regex construction routine.
1313
1314   This translates an opcode syntax string into a regex string,
1315   by replacing any non-character syntax element (such as an
1316   opcode) with the pattern '.*'
1317
1318   It then compiles the regex and stores it in the opcode, for
1319   later use by mep_cgen_assemble_insn
1320
1321   Returns NULL for success, an error message for failure.  */
1322
1323char *
1324mep_cgen_build_insn_regex (CGEN_INSN *insn)
1325{
1326  CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
1327  const char *mnem = CGEN_INSN_MNEMONIC (insn);
1328  char rxbuf[CGEN_MAX_RX_ELEMENTS];
1329  char *rx = rxbuf;
1330  const CGEN_SYNTAX_CHAR_TYPE *syn;
1331  int reg_err;
1332
1333  syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
1334
1335  /* Mnemonics come first in the syntax string.  */
1336  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1337    return _("missing mnemonic in syntax string");
1338  ++syn;
1339
1340  /* Generate a case sensitive regular expression that emulates case
1341     insensitive matching in the "C" locale.  We cannot generate a case
1342     insensitive regular expression because in Turkish locales, 'i' and 'I'
1343     are not equal modulo case conversion.  */
1344
1345  /* Copy the literal mnemonic out of the insn.  */
1346  for (; *mnem; mnem++)
1347    {
1348      char c = *mnem;
1349
1350      if (ISALPHA (c))
1351	{
1352	  *rx++ = '[';
1353	  *rx++ = TOLOWER (c);
1354	  *rx++ = TOUPPER (c);
1355	  *rx++ = ']';
1356	}
1357      else
1358	*rx++ = c;
1359    }
1360
1361  /* Copy any remaining literals from the syntax string into the rx.  */
1362  for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
1363    {
1364      if (CGEN_SYNTAX_CHAR_P (* syn))
1365	{
1366	  char c = CGEN_SYNTAX_CHAR (* syn);
1367
1368	  switch (c)
1369	    {
1370	      /* Escape any regex metacharacters in the syntax.  */
1371	    case '.': case '[': case '\\':
1372	    case '*': case '^': case '$':
1373
1374#ifdef CGEN_ESCAPE_EXTENDED_REGEX
1375	    case '?': case '{': case '}':
1376	    case '(': case ')': case '*':
1377	    case '|': case '+': case ']':
1378#endif
1379	      *rx++ = '\\';
1380	      *rx++ = c;
1381	      break;
1382
1383	    default:
1384	      if (ISALPHA (c))
1385		{
1386		  *rx++ = '[';
1387		  *rx++ = TOLOWER (c);
1388		  *rx++ = TOUPPER (c);
1389		  *rx++ = ']';
1390		}
1391	      else
1392		*rx++ = c;
1393	      break;
1394	    }
1395	}
1396      else
1397	{
1398	  /* Replace non-syntax fields with globs.  */
1399	  *rx++ = '.';
1400	  *rx++ = '*';
1401	}
1402    }
1403
1404  /* Trailing whitespace ok.  */
1405  * rx++ = '[';
1406  * rx++ = ' ';
1407  * rx++ = '\t';
1408  * rx++ = ']';
1409  * rx++ = '*';
1410
1411  /* But anchor it after that.  */
1412  * rx++ = '$';
1413  * rx = '\0';
1414
1415  CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
1416  reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
1417
1418  if (reg_err == 0)
1419    return NULL;
1420  else
1421    {
1422      static char msg[80];
1423
1424      regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
1425      regfree ((regex_t *) CGEN_INSN_RX (insn));
1426      free (CGEN_INSN_RX (insn));
1427      (CGEN_INSN_RX (insn)) = NULL;
1428      return msg;
1429    }
1430}
1431
1432
1433/* Default insn parser.
1434
1435   The syntax string is scanned and operands are parsed and stored in FIELDS.
1436   Relocs are queued as we go via other callbacks.
1437
1438   ??? Note that this is currently an all-or-nothing parser.  If we fail to
1439   parse the instruction, we return 0 and the caller will start over from
1440   the beginning.  Backtracking will be necessary in parsing subexpressions,
1441   but that can be handled there.  Not handling backtracking here may get
1442   expensive in the case of the m68k.  Deal with later.
1443
1444   Returns NULL for success, an error message for failure.  */
1445
1446static const char *
1447parse_insn_normal (CGEN_CPU_DESC cd,
1448		   const CGEN_INSN *insn,
1449		   const char **strp,
1450		   CGEN_FIELDS *fields)
1451{
1452  /* ??? Runtime added insns not handled yet.  */
1453  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
1454  const char *str = *strp;
1455  const char *errmsg;
1456  const char *p;
1457  const CGEN_SYNTAX_CHAR_TYPE * syn;
1458#ifdef CGEN_MNEMONIC_OPERANDS
1459  /* FIXME: wip */
1460  int past_opcode_p;
1461#endif
1462
1463  /* For now we assume the mnemonic is first (there are no leading operands).
1464     We can parse it without needing to set up operand parsing.
1465     GAS's input scrubber will ensure mnemonics are lowercase, but we may
1466     not be called from GAS.  */
1467  p = CGEN_INSN_MNEMONIC (insn);
1468  while (*p && TOLOWER (*p) == TOLOWER (*str))
1469    ++p, ++str;
1470
1471  if (* p)
1472    return _("unrecognized instruction");
1473
1474#ifndef CGEN_MNEMONIC_OPERANDS
1475  if (* str && ! ISSPACE (* str))
1476    return _("unrecognized instruction");
1477#endif
1478
1479  CGEN_INIT_PARSE (cd);
1480  cgen_init_parse_operand (cd);
1481#ifdef CGEN_MNEMONIC_OPERANDS
1482  past_opcode_p = 0;
1483#endif
1484
1485  /* We don't check for (*str != '\0') here because we want to parse
1486     any trailing fake arguments in the syntax string.  */
1487  syn = CGEN_SYNTAX_STRING (syntax);
1488
1489  /* Mnemonics come first for now, ensure valid string.  */
1490  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1491    abort ();
1492
1493  ++syn;
1494
1495  while (* syn != 0)
1496    {
1497      /* Non operand chars must match exactly.  */
1498      if (CGEN_SYNTAX_CHAR_P (* syn))
1499	{
1500	  /* FIXME: While we allow for non-GAS callers above, we assume the
1501	     first char after the mnemonic part is a space.  */
1502	  /* FIXME: We also take inappropriate advantage of the fact that
1503	     GAS's input scrubber will remove extraneous blanks.  */
1504	  if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
1505	    {
1506#ifdef CGEN_MNEMONIC_OPERANDS
1507	      if (CGEN_SYNTAX_CHAR(* syn) == ' ')
1508		past_opcode_p = 1;
1509#endif
1510	      ++ syn;
1511	      ++ str;
1512	    }
1513	  else if (*str)
1514	    {
1515	      /* Syntax char didn't match.  Can't be this insn.  */
1516	      static char msg [80];
1517
1518	      /* xgettext:c-format */
1519	      sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
1520		       CGEN_SYNTAX_CHAR(*syn), *str);
1521	      return msg;
1522	    }
1523	  else
1524	    {
1525	      /* Ran out of input.  */
1526	      static char msg [80];
1527
1528	      /* xgettext:c-format */
1529	      sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
1530		       CGEN_SYNTAX_CHAR(*syn));
1531	      return msg;
1532	    }
1533	  continue;
1534	}
1535
1536#ifdef CGEN_MNEMONIC_OPERANDS
1537      (void) past_opcode_p;
1538#endif
1539      /* We have an operand of some sort.  */
1540      errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
1541      if (errmsg)
1542	return errmsg;
1543
1544      /* Done with this operand, continue with next one.  */
1545      ++ syn;
1546    }
1547
1548  /* If we're at the end of the syntax string, we're done.  */
1549  if (* syn == 0)
1550    {
1551      /* FIXME: For the moment we assume a valid `str' can only contain
1552	 blanks now.  IE: We needn't try again with a longer version of
1553	 the insn and it is assumed that longer versions of insns appear
1554	 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
1555      while (ISSPACE (* str))
1556	++ str;
1557
1558      if (* str != '\0')
1559	return _("junk at end of line"); /* FIXME: would like to include `str' */
1560
1561      return NULL;
1562    }
1563
1564  /* We couldn't parse it.  */
1565  return _("unrecognized instruction");
1566}
1567
1568/* Main entry point.
1569   This routine is called for each instruction to be assembled.
1570   STR points to the insn to be assembled.
1571   We assume all necessary tables have been initialized.
1572   The assembled instruction, less any fixups, is stored in BUF.
1573   Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
1574   still needs to be converted to target byte order, otherwise BUF is an array
1575   of bytes in target byte order.
1576   The result is a pointer to the insn's entry in the opcode table,
1577   or NULL if an error occured (an error message will have already been
1578   printed).
1579
1580   Note that when processing (non-alias) macro-insns,
1581   this function recurses.
1582
1583   ??? It's possible to make this cpu-independent.
1584   One would have to deal with a few minor things.
1585   At this point in time doing so would be more of a curiosity than useful
1586   [for example this file isn't _that_ big], but keeping the possibility in
1587   mind helps keep the design clean.  */
1588
1589const CGEN_INSN *
1590mep_cgen_assemble_insn (CGEN_CPU_DESC cd,
1591			   const char *str,
1592			   CGEN_FIELDS *fields,
1593			   CGEN_INSN_BYTES_PTR buf,
1594			   char **errmsg)
1595{
1596  const char *start;
1597  CGEN_INSN_LIST *ilist;
1598  const char *parse_errmsg = NULL;
1599  const char *insert_errmsg = NULL;
1600  int recognized_mnemonic = 0;
1601
1602  /* Skip leading white space.  */
1603  while (ISSPACE (* str))
1604    ++ str;
1605
1606  /* The instructions are stored in hashed lists.
1607     Get the first in the list.  */
1608  ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
1609
1610  /* Keep looking until we find a match.  */
1611  start = str;
1612  for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
1613    {
1614      const CGEN_INSN *insn = ilist->insn;
1615      recognized_mnemonic = 1;
1616
1617#ifdef CGEN_VALIDATE_INSN_SUPPORTED
1618      /* Not usually needed as unsupported opcodes
1619	 shouldn't be in the hash lists.  */
1620      /* Is this insn supported by the selected cpu?  */
1621      if (! mep_cgen_insn_supported (cd, insn))
1622	continue;
1623#endif
1624      /* If the RELAXED attribute is set, this is an insn that shouldn't be
1625	 chosen immediately.  Instead, it is used during assembler/linker
1626	 relaxation if possible.  */
1627      if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
1628	continue;
1629
1630      str = start;
1631
1632      /* Skip this insn if str doesn't look right lexically.  */
1633      if (CGEN_INSN_RX (insn) != NULL &&
1634	  regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
1635	continue;
1636
1637      /* Allow parse/insert handlers to obtain length of insn.  */
1638      CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
1639
1640      parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
1641      if (parse_errmsg != NULL)
1642	continue;
1643
1644      /* ??? 0 is passed for `pc'.  */
1645      insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
1646						 (bfd_vma) 0);
1647      if (insert_errmsg != NULL)
1648        continue;
1649
1650      /* It is up to the caller to actually output the insn and any
1651         queued relocs.  */
1652      return insn;
1653    }
1654
1655  {
1656    static char errbuf[150];
1657    const char *tmp_errmsg;
1658#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
1659#define be_verbose 1
1660#else
1661#define be_verbose 0
1662#endif
1663
1664    if (be_verbose)
1665      {
1666	/* If requesting verbose error messages, use insert_errmsg.
1667	   Failing that, use parse_errmsg.  */
1668	tmp_errmsg = (insert_errmsg ? insert_errmsg :
1669		      parse_errmsg ? parse_errmsg :
1670		      recognized_mnemonic ?
1671		      _("unrecognized form of instruction") :
1672		      _("unrecognized instruction"));
1673
1674	if (strlen (start) > 50)
1675	  /* xgettext:c-format */
1676	  sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
1677	else
1678	  /* xgettext:c-format */
1679	  sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
1680      }
1681    else
1682      {
1683	if (strlen (start) > 50)
1684	  /* xgettext:c-format */
1685	  sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1686	else
1687	  /* xgettext:c-format */
1688	  sprintf (errbuf, _("bad instruction `%.50s'"), start);
1689      }
1690
1691    *errmsg = errbuf;
1692    return NULL;
1693  }
1694}
1695