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 "frv-desc.h"
35#include "frv-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 */
52inline static const char *
53parse_symbolic_address (CGEN_CPU_DESC cd,
54			const char **strp,
55			int opindex,
56			int opinfo,
57			enum cgen_parse_operand_result *resultp,
58			bfd_vma *valuep)
59{
60  enum cgen_parse_operand_result result_type;
61  const char *errmsg = (* cd->parse_operand_fn)
62    (cd, CGEN_PARSE_OPERAND_SYMBOLIC, strp, opindex, opinfo,
63     &result_type, valuep);
64
65  if (errmsg == NULL
66      && result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED)
67    return "symbolic expression required";
68
69  if (resultp)
70    *resultp = result_type;
71
72  return errmsg;
73}
74
75static const char *
76parse_ldd_annotation (CGEN_CPU_DESC cd,
77		      const char **strp,
78		      int opindex,
79		      unsigned long *valuep)
80{
81  const char *errmsg;
82  enum cgen_parse_operand_result result_type;
83  bfd_vma value;
84
85  if (**strp == '#' || **strp == '%')
86    {
87      if (strncasecmp (*strp + 1, "tlsdesc(", 8) == 0)
88	{
89	  *strp += 9;
90	  errmsg = parse_symbolic_address (cd, strp, opindex,
91					   BFD_RELOC_FRV_TLSDESC_RELAX,
92					   &result_type, &value);
93	  if (**strp != ')')
94	    return "missing ')'";
95	  if (valuep)
96	    *valuep = value;
97	  ++*strp;
98	  if (errmsg)
99	    return errmsg;
100	}
101    }
102
103  while (**strp == ' ' || **strp == '\t')
104    ++*strp;
105
106  if (**strp != '@')
107    return "missing `@'";
108
109  ++*strp;
110
111  return NULL;
112}
113
114static const char *
115parse_call_annotation (CGEN_CPU_DESC cd,
116		       const char **strp,
117		       int opindex,
118		       unsigned long *valuep)
119{
120  const char *errmsg;
121  enum cgen_parse_operand_result result_type;
122  bfd_vma value;
123
124  if (**strp == '#' || **strp == '%')
125    {
126      if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
127	{
128	  *strp += 11;
129	  errmsg = parse_symbolic_address (cd, strp, opindex,
130					   BFD_RELOC_FRV_GETTLSOFF_RELAX,
131					   &result_type, &value);
132	  if (**strp != ')')
133	    return "missing ')'";
134	  if (valuep)
135	    *valuep = value;
136	  ++*strp;
137	  if (errmsg)
138	    return errmsg;
139	}
140    }
141
142  while (**strp == ' ' || **strp == '\t')
143    ++*strp;
144
145  if (**strp != '@')
146    return "missing `@'";
147
148  ++*strp;
149
150  return NULL;
151}
152
153static const char *
154parse_ld_annotation (CGEN_CPU_DESC cd,
155		     const char **strp,
156		     int opindex,
157		     unsigned long *valuep)
158{
159  const char *errmsg;
160  enum cgen_parse_operand_result result_type;
161  bfd_vma value;
162
163  if (**strp == '#' || **strp == '%')
164    {
165      if (strncasecmp (*strp + 1, "tlsoff(", 7) == 0)
166	{
167	  *strp += 8;
168	  errmsg = parse_symbolic_address (cd, strp, opindex,
169					   BFD_RELOC_FRV_TLSOFF_RELAX,
170					   &result_type, &value);
171	  if (**strp != ')')
172	    return "missing ')'";
173	  if (valuep)
174	    *valuep = value;
175	  ++*strp;
176	  if (errmsg)
177	    return errmsg;
178	}
179    }
180
181  while (**strp == ' ' || **strp == '\t')
182    ++*strp;
183
184  if (**strp != '@')
185    return "missing `@'";
186
187  ++*strp;
188
189  return NULL;
190}
191
192static const char *
193parse_ulo16 (CGEN_CPU_DESC cd,
194	     const char **strp,
195	     int opindex,
196	     unsigned long *valuep)
197{
198  const char *errmsg;
199  enum cgen_parse_operand_result result_type;
200  bfd_vma value;
201
202  if (**strp == '#' || **strp == '%')
203    {
204      if (strncasecmp (*strp + 1, "lo(", 3) == 0)
205	{
206	  *strp += 4;
207	  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
208				       & result_type, & value);
209	  if (**strp != ')')
210	    return "missing `)'";
211	  ++*strp;
212	  if (errmsg == NULL
213	      && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
214	    value &= 0xffff;
215	  *valuep = value;
216	  return errmsg;
217	}
218      if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
219	{
220	  *strp += 9;
221	  errmsg = parse_symbolic_address (cd, strp, opindex,
222					   BFD_RELOC_FRV_GPRELLO,
223					   & result_type, & value);
224	  if (**strp != ')')
225	    return "missing ')'";
226	  ++*strp;
227	  *valuep = value;
228	  return errmsg;
229	}
230      else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
231	{
232	  *strp += 7;
233	  errmsg = parse_symbolic_address (cd, strp, opindex,
234					   BFD_RELOC_FRV_GOTLO,
235					   & result_type, & value);
236	  if (**strp != ')')
237	    return "missing ')'";
238	  ++*strp;
239	  *valuep = value;
240	  return errmsg;
241	}
242      else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
243	{
244	  *strp += 15;
245	  errmsg = parse_symbolic_address (cd, strp, opindex,
246					   BFD_RELOC_FRV_FUNCDESC_GOTLO,
247					   & result_type, & value);
248	  if (**strp != ')')
249	    return "missing ')'";
250	  ++*strp;
251	  *valuep = value;
252	  return errmsg;
253	}
254      else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
255	{
256	  *strp += 10;
257	  errmsg = parse_symbolic_address (cd, strp, opindex,
258					   BFD_RELOC_FRV_GOTOFFLO,
259					   & result_type, & value);
260	  if (**strp != ')')
261	    return "missing ')'";
262	  ++*strp;
263	  *valuep = value;
264	  return errmsg;
265	}
266      else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
267	{
268	  *strp += 18;
269	  errmsg = parse_symbolic_address (cd, strp, opindex,
270					   BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
271					   & result_type, & value);
272	  if (**strp != ')')
273	    return "missing ')'";
274	  ++*strp;
275	  *valuep = value;
276	  return errmsg;
277	}
278      else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
279	{
280	  *strp += 14;
281	  errmsg = parse_symbolic_address (cd, strp, opindex,
282					   BFD_RELOC_FRV_GOTTLSDESCLO,
283					   & result_type, & value);
284	  if (**strp != ')')
285	    return "missing ')'";
286	  ++*strp;
287	  *valuep = value;
288	  return errmsg;
289	}
290      else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
291	{
292	  *strp += 11;
293	  errmsg = parse_symbolic_address (cd, strp, opindex,
294					   BFD_RELOC_FRV_TLSMOFFLO,
295					   & result_type, & value);
296	  if (**strp != ')')
297	    return "missing ')'";
298	  ++*strp;
299	  *valuep = value;
300	  return errmsg;
301	}
302      else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
303	{
304	  *strp += 13;
305	  errmsg = parse_symbolic_address (cd, strp, opindex,
306					   BFD_RELOC_FRV_GOTTLSOFFLO,
307					   & result_type, & value);
308	  if (**strp != ')')
309	    return "missing ')'";
310	  ++*strp;
311	  *valuep = value;
312	  return errmsg;
313	}
314    }
315  return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
316}
317
318static const char *
319parse_uslo16 (CGEN_CPU_DESC cd,
320	      const char **strp,
321	      int opindex,
322	      signed long *valuep)
323{
324  const char *errmsg;
325  enum cgen_parse_operand_result result_type;
326  bfd_vma value;
327
328  if (**strp == '#' || **strp == '%')
329    {
330      if (strncasecmp (*strp + 1, "lo(", 3) == 0)
331	{
332	  *strp += 4;
333	  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
334				       & result_type, & value);
335	  if (**strp != ')')
336	    return "missing `)'";
337	  ++*strp;
338	  if (errmsg == NULL
339	      && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
340	    value &= 0xffff;
341	  *valuep = value;
342	  return errmsg;
343	}
344      else if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
345	{
346	  *strp += 9;
347	  errmsg = parse_symbolic_address (cd, strp, opindex,
348					   BFD_RELOC_FRV_GPRELLO,
349					   & result_type, & value);
350	  if (**strp != ')')
351	    return "missing ')'";
352	  ++*strp;
353	  *valuep = value;
354	  return errmsg;
355	}
356      else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
357	{
358	  *strp += 7;
359	  errmsg = parse_symbolic_address (cd, strp, opindex,
360					   BFD_RELOC_FRV_GOTLO,
361					   & result_type, & value);
362	  if (**strp != ')')
363	    return "missing ')'";
364	  ++*strp;
365	  *valuep = value;
366	  return errmsg;
367	}
368      else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
369	{
370	  *strp += 15;
371	  errmsg = parse_symbolic_address (cd, strp, opindex,
372					   BFD_RELOC_FRV_FUNCDESC_GOTLO,
373					   & result_type, & value);
374	  if (**strp != ')')
375	    return "missing ')'";
376	  ++*strp;
377	  *valuep = value;
378	  return errmsg;
379	}
380      else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
381	{
382	  *strp += 10;
383	  errmsg = parse_symbolic_address (cd, strp, opindex,
384					   BFD_RELOC_FRV_GOTOFFLO,
385					   & result_type, & value);
386	  if (**strp != ')')
387	    return "missing ')'";
388	  ++*strp;
389	  *valuep = value;
390	  return errmsg;
391	}
392      else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
393	{
394	  *strp += 18;
395	  errmsg = parse_symbolic_address (cd, strp, opindex,
396					   BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
397					   & result_type, & value);
398	  if (**strp != ')')
399	    return "missing ')'";
400	  ++*strp;
401	  *valuep = value;
402	  return errmsg;
403	}
404      else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
405	{
406	  *strp += 14;
407	  errmsg = parse_symbolic_address (cd, strp, opindex,
408					   BFD_RELOC_FRV_GOTTLSDESCLO,
409					   & result_type, & value);
410	  if (**strp != ')')
411	    return "missing ')'";
412	  ++*strp;
413	  *valuep = value;
414	  return errmsg;
415	}
416      else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
417	{
418	  *strp += 11;
419	  errmsg = parse_symbolic_address (cd, strp, opindex,
420					   BFD_RELOC_FRV_TLSMOFFLO,
421					   & result_type, & value);
422	  if (**strp != ')')
423	    return "missing ')'";
424	  ++*strp;
425	  *valuep = value;
426	  return errmsg;
427	}
428      else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
429	{
430	  *strp += 13;
431	  errmsg = parse_symbolic_address (cd, strp, opindex,
432					   BFD_RELOC_FRV_GOTTLSOFFLO,
433					   & result_type, & value);
434	  if (**strp != ')')
435	    return "missing ')'";
436	  ++*strp;
437	  *valuep = value;
438	  return errmsg;
439	}
440    }
441  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
442}
443
444static const char *
445parse_uhi16 (CGEN_CPU_DESC cd,
446	     const char **strp,
447	     int opindex,
448	     unsigned long *valuep)
449{
450  const char *errmsg;
451  enum cgen_parse_operand_result result_type;
452  bfd_vma value;
453
454  if (**strp == '#' || **strp == '%')
455    {
456      if (strncasecmp (*strp + 1, "hi(", 3) == 0)
457	{
458	  *strp += 4;
459	  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16,
460				       & result_type, & value);
461	  if (**strp != ')')
462	    return "missing `)'";
463	  ++*strp;
464	  if (errmsg == NULL
465	      && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
466	    {
467 	      /* If value is wider than 32 bits then be
468 		 careful about how we extract bits 16-31.  */
469 	      if (sizeof (value) > 4)
470 		value &= (((bfd_vma)1 << 16) << 16) - 1;
471
472	      value >>= 16;
473	    }
474	  *valuep = value;
475	  return errmsg;
476	}
477      else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0)
478	{
479	  *strp += 9;
480	  errmsg = parse_symbolic_address (cd, strp, opindex,
481					   BFD_RELOC_FRV_GPRELHI,
482					   & result_type, & value);
483	  if (**strp != ')')
484	    return "missing ')'";
485	  ++*strp;
486	  *valuep = value;
487	  return errmsg;
488	}
489      else if (strncasecmp (*strp + 1, "gothi(", 6) == 0)
490	{
491	  *strp += 7;
492	  errmsg = parse_symbolic_address (cd, strp, opindex,
493					   BFD_RELOC_FRV_GOTHI,
494					   & result_type, & value);
495	  if (**strp != ')')
496	    return "missing ')'";
497	  ++*strp;
498	  *valuep = value;
499	  return errmsg;
500	}
501      else if (strncasecmp (*strp + 1, "gotfuncdeschi(", 14) == 0)
502	{
503	  *strp += 15;
504	  errmsg = parse_symbolic_address (cd, strp, opindex,
505					   BFD_RELOC_FRV_FUNCDESC_GOTHI,
506					   & result_type, & value);
507	  if (**strp != ')')
508	    return "missing ')'";
509	  ++*strp;
510	  *valuep = value;
511	  return errmsg;
512	}
513      else if (strncasecmp (*strp + 1, "gotoffhi(", 9) == 0)
514	{
515	  *strp += 10;
516	  errmsg = parse_symbolic_address (cd, strp, opindex,
517					   BFD_RELOC_FRV_GOTOFFHI,
518					   & result_type, & value);
519	  if (**strp != ')')
520	    return "missing ')'";
521	  ++*strp;
522	  *valuep = value;
523	  return errmsg;
524	}
525      else if (strncasecmp (*strp + 1, "gotofffuncdeschi(", 17) == 0)
526	{
527	  *strp += 18;
528	  errmsg = parse_symbolic_address (cd, strp, opindex,
529					   BFD_RELOC_FRV_FUNCDESC_GOTOFFHI,
530					   & result_type, & value);
531	  if (**strp != ')')
532	    return "missing ')'";
533	  ++*strp;
534	  *valuep = value;
535	  return errmsg;
536	}
537      else if (strncasecmp (*strp + 1, "gottlsdeschi(", 13) == 0)
538	{
539	  *strp += 14;
540	  errmsg = parse_symbolic_address (cd, strp, opindex,
541					   BFD_RELOC_FRV_GOTTLSDESCHI,
542					   &result_type, &value);
543	  if (**strp != ')')
544	    return "missing ')'";
545	  ++*strp;
546	  *valuep = value;
547	  return errmsg;
548	}
549      else if (strncasecmp (*strp + 1, "tlsmoffhi(", 10) == 0)
550	{
551	  *strp += 11;
552	  errmsg = parse_symbolic_address (cd, strp, opindex,
553					   BFD_RELOC_FRV_TLSMOFFHI,
554					   & result_type, & value);
555	  if (**strp != ')')
556	    return "missing ')'";
557	  ++*strp;
558	  *valuep = value;
559	  return errmsg;
560	}
561      else if (strncasecmp (*strp + 1, "gottlsoffhi(", 12) == 0)
562	{
563	  *strp += 13;
564	  errmsg = parse_symbolic_address (cd, strp, opindex,
565					   BFD_RELOC_FRV_GOTTLSOFFHI,
566					   & result_type, & value);
567	  if (**strp != ')')
568	    return "missing ')'";
569	  ++*strp;
570	  *valuep = value;
571	  return errmsg;
572	}
573    }
574  return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
575}
576
577static long
578parse_register_number (const char **strp)
579{
580  int regno;
581
582  if (**strp < '0' || **strp > '9')
583    return -1; /* error */
584
585  regno = **strp - '0';
586  for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp)
587    regno = regno * 10 + (**strp - '0');
588
589  return regno;
590}
591
592static const char *
593parse_spr (CGEN_CPU_DESC cd,
594	   const char **strp,
595	   CGEN_KEYWORD * table,
596	   long *valuep)
597{
598  const char *save_strp;
599  long regno;
600
601  /* Check for spr index notation.  */
602  if (strncasecmp (*strp, "spr[", 4) == 0)
603    {
604      *strp += 4;
605      regno = parse_register_number (strp);
606      if (**strp != ']')
607        return _("missing `]'");
608      ++*strp;
609      if (! spr_valid (regno))
610	return _("Special purpose register number is out of range");
611      *valuep = regno;
612      return NULL;
613    }
614
615  save_strp = *strp;
616  regno = parse_register_number (strp);
617  if (regno != -1)
618    {
619      if (! spr_valid (regno))
620	return _("Special purpose register number is out of range");
621      *valuep = regno;
622      return NULL;
623    }
624
625  *strp = save_strp;
626  return cgen_parse_keyword (cd, strp, table, valuep);
627}
628
629static const char *
630parse_d12 (CGEN_CPU_DESC cd,
631	   const char **strp,
632	   int opindex,
633	   long *valuep)
634{
635  const char *errmsg;
636  enum cgen_parse_operand_result result_type;
637  bfd_vma value;
638
639  /* Check for small data reference.  */
640  if (**strp == '#' || **strp == '%')
641    {
642      if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
643        {
644          *strp += 9;
645          errmsg = parse_symbolic_address (cd, strp, opindex,
646					   BFD_RELOC_FRV_GPREL12,
647					   & result_type, & value);
648          if (**strp != ')')
649            return "missing `)'";
650          ++*strp;
651          *valuep = value;
652          return errmsg;
653        }
654      else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
655	{
656	  *strp += 7;
657	  errmsg = parse_symbolic_address (cd, strp, opindex,
658					   BFD_RELOC_FRV_GOT12,
659					   & result_type, & value);
660	  if (**strp != ')')
661	    return "missing ')'";
662	  ++*strp;
663	  *valuep = value;
664	  return errmsg;
665	}
666      else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
667	{
668	  *strp += 15;
669	  errmsg = parse_symbolic_address (cd, strp, opindex,
670					   BFD_RELOC_FRV_FUNCDESC_GOT12,
671					   & result_type, & value);
672	  if (**strp != ')')
673	    return "missing ')'";
674	  ++*strp;
675	  *valuep = value;
676	  return errmsg;
677	}
678      else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
679	{
680	  *strp += 10;
681	  errmsg = parse_symbolic_address (cd, strp, opindex,
682					   BFD_RELOC_FRV_GOTOFF12,
683					   & result_type, & value);
684	  if (**strp != ')')
685	    return "missing ')'";
686	  ++*strp;
687	  *valuep = value;
688	  return errmsg;
689	}
690      else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
691	{
692	  *strp += 18;
693	  errmsg = parse_symbolic_address (cd, strp, opindex,
694					   BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
695					   & result_type, & value);
696	  if (**strp != ')')
697	    return "missing ')'";
698	  ++*strp;
699	  *valuep = value;
700	  return errmsg;
701	}
702      else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
703	{
704	  *strp += 14;
705	  errmsg = parse_symbolic_address (cd, strp, opindex,
706					   BFD_RELOC_FRV_GOTTLSDESC12,
707					   & result_type, & value);
708	  if (**strp != ')')
709	    return "missing ')'";
710	  ++*strp;
711	  *valuep = value;
712	  return errmsg;
713	}
714      else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
715	{
716	  *strp += 11;
717	  errmsg = parse_symbolic_address (cd, strp, opindex,
718					   BFD_RELOC_FRV_TLSMOFF12,
719					   & result_type, & value);
720	  if (**strp != ')')
721	    return "missing ')'";
722	  ++*strp;
723	  *valuep = value;
724	  return errmsg;
725	}
726      else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
727	{
728	  *strp += 13;
729	  errmsg = parse_symbolic_address (cd, strp, opindex,
730					   BFD_RELOC_FRV_GOTTLSOFF12,
731					   & result_type, & value);
732	  if (**strp != ')')
733	    return "missing ')'";
734	  ++*strp;
735	  *valuep = value;
736	  return errmsg;
737	}
738    }
739  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
740}
741
742static const char *
743parse_s12 (CGEN_CPU_DESC cd,
744	   const char **strp,
745	   int opindex,
746	   long *valuep)
747{
748  const char *errmsg;
749  enum cgen_parse_operand_result result_type;
750  bfd_vma value;
751
752  /* Check for small data reference.  */
753  if (**strp == '#' || **strp == '%')
754    {
755      if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
756	{
757	  *strp += 9;
758	  errmsg = parse_symbolic_address (cd, strp, opindex,
759					   BFD_RELOC_FRV_GPREL12,
760					   & result_type, & value);
761	  if (**strp != ')')
762	    return "missing `)'";
763	  ++*strp;
764	  *valuep = value;
765	  return errmsg;
766	}
767      else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
768	{
769	  *strp += 7;
770	  errmsg = parse_symbolic_address (cd, strp, opindex,
771					   BFD_RELOC_FRV_GOT12,
772					   & result_type, & value);
773	  if (**strp != ')')
774	    return "missing ')'";
775	  ++*strp;
776	  *valuep = value;
777	  return errmsg;
778	}
779      else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
780	{
781	  *strp += 15;
782	  errmsg = parse_symbolic_address (cd, strp, opindex,
783					   BFD_RELOC_FRV_FUNCDESC_GOT12,
784					   & result_type, & value);
785	  if (**strp != ')')
786	    return "missing ')'";
787	  ++*strp;
788	  *valuep = value;
789	  return errmsg;
790	}
791      else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
792	{
793	  *strp += 10;
794	  errmsg = parse_symbolic_address (cd, strp, opindex,
795					   BFD_RELOC_FRV_GOTOFF12,
796					   & result_type, & value);
797	  if (**strp != ')')
798	    return "missing ')'";
799	  ++*strp;
800	  *valuep = value;
801	  return errmsg;
802	}
803      else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
804	{
805	  *strp += 18;
806	  errmsg = parse_symbolic_address (cd, strp, opindex,
807					   BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
808					   & result_type, & value);
809	  if (**strp != ')')
810	    return "missing ')'";
811	  ++*strp;
812	  *valuep = value;
813	  return errmsg;
814	}
815      else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
816	{
817	  *strp += 14;
818	  errmsg = parse_symbolic_address (cd, strp, opindex,
819					   BFD_RELOC_FRV_GOTTLSDESC12,
820					   & result_type, & value);
821	  if (**strp != ')')
822	    return "missing ')'";
823	  ++*strp;
824	  *valuep = value;
825	  return errmsg;
826	}
827      else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
828	{
829	  *strp += 11;
830	  errmsg = parse_symbolic_address (cd, strp, opindex,
831					   BFD_RELOC_FRV_TLSMOFF12,
832					   & result_type, & value);
833	  if (**strp != ')')
834	    return "missing ')'";
835	  ++*strp;
836	  *valuep = value;
837	  return errmsg;
838	}
839      else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
840	{
841	  *strp += 13;
842	  errmsg = parse_symbolic_address (cd, strp, opindex,
843					   BFD_RELOC_FRV_GOTTLSOFF12,
844					   & result_type, & value);
845	  if (**strp != ')')
846	    return "missing ')'";
847	  ++*strp;
848	  *valuep = value;
849	  return errmsg;
850	}
851    }
852
853  if (**strp == '#')
854    ++*strp;
855  return cgen_parse_signed_integer (cd, strp, opindex, valuep);
856}
857
858static const char *
859parse_u12 (CGEN_CPU_DESC cd,
860	   const char **strp,
861	   int opindex,
862	   long *valuep)
863{
864  const char *errmsg;
865  enum cgen_parse_operand_result result_type;
866  bfd_vma value;
867
868  /* Check for small data reference.  */
869  if ((**strp == '#' || **strp == '%')
870      && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
871    {
872      *strp += 9;
873      errmsg = parse_symbolic_address (cd, strp, opindex,
874				       BFD_RELOC_FRV_GPRELU12,
875				       & result_type, & value);
876      if (**strp != ')')
877        return "missing `)'";
878      ++*strp;
879      *valuep = value;
880      return errmsg;
881    }
882  else
883    {
884      if (**strp == '#')
885        ++*strp;
886      return cgen_parse_signed_integer (cd, strp, opindex, valuep);
887    }
888}
889
890static const char *
891parse_A (CGEN_CPU_DESC cd,
892	 const char **strp,
893	 int opindex,
894	 unsigned long *valuep,
895	 unsigned long A)
896{
897  const char *errmsg;
898
899  if (**strp == '#')
900    ++*strp;
901
902  errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
903  if (errmsg)
904    return errmsg;
905
906  if (*valuep != A)
907    return _("Value of A operand must be 0 or 1");
908
909  return NULL;
910}
911
912static const char *
913parse_A0 (CGEN_CPU_DESC cd,
914	  const char **strp,
915	  int opindex,
916	  unsigned long *valuep)
917{
918  return parse_A (cd, strp, opindex, valuep, 0);
919}
920
921static const char *
922parse_A1 (CGEN_CPU_DESC cd,
923	  const char **strp,
924	  int opindex,
925	  unsigned long *valuep)
926{
927  return parse_A (cd, strp, opindex, valuep, 1);
928}
929
930static const char *
931parse_even_register (CGEN_CPU_DESC  cd,
932		     const char **  strP,
933		     CGEN_KEYWORD * tableP,
934		     long *         valueP)
935{
936  const char * errmsg;
937  const char * saved_star_strP = * strP;
938
939  errmsg = cgen_parse_keyword (cd, strP, tableP, valueP);
940
941  if (errmsg == NULL && ((* valueP) & 1))
942    {
943      errmsg = _("register number must be even");
944      * strP = saved_star_strP;
945    }
946
947  return errmsg;
948}
949
950static const char *
951parse_call_label (CGEN_CPU_DESC cd,
952		  const char **strp,
953		  int opindex,
954		  int opinfo,
955		  enum cgen_parse_operand_result *resultp,
956		  bfd_vma *valuep)
957{
958  const char *errmsg;
959  bfd_vma value;
960
961  /* Check for small data reference.  */
962  if (opinfo == 0 && (**strp == '#' || **strp == '%'))
963    {
964      if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
965	{
966	  *strp += 11;
967	  errmsg = parse_symbolic_address (cd, strp, opindex,
968					   BFD_RELOC_FRV_GETTLSOFF,
969					   resultp, &value);
970	  if (**strp != ')')
971	    return _("missing `)'");
972	  ++*strp;
973	  *valuep = value;
974	  return errmsg;
975	}
976    }
977
978  return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
979}
980
981/* -- */
982
983const char * frv_cgen_parse_operand
984  (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
985
986/* Main entry point for operand parsing.
987
988   This function is basically just a big switch statement.  Earlier versions
989   used tables to look up the function to use, but
990   - if the table contains both assembler and disassembler functions then
991     the disassembler contains much of the assembler and vice-versa,
992   - there's a lot of inlining possibilities as things grow,
993   - using a switch statement avoids the function call overhead.
994
995   This function could be moved into `parse_insn_normal', but keeping it
996   separate makes clear the interface between `parse_insn_normal' and each of
997   the handlers.  */
998
999const char *
1000frv_cgen_parse_operand (CGEN_CPU_DESC cd,
1001			   int opindex,
1002			   const char ** strp,
1003			   CGEN_FIELDS * fields)
1004{
1005  const char * errmsg = NULL;
1006  /* Used by scalar operands that still need to be parsed.  */
1007  long junk ATTRIBUTE_UNUSED;
1008
1009  switch (opindex)
1010    {
1011    case FRV_OPERAND_A0 :
1012      errmsg = parse_A0 (cd, strp, FRV_OPERAND_A0, (unsigned long *) (& fields->f_A));
1013      break;
1014    case FRV_OPERAND_A1 :
1015      errmsg = parse_A1 (cd, strp, FRV_OPERAND_A1, (unsigned long *) (& fields->f_A));
1016      break;
1017    case FRV_OPERAND_ACC40SI :
1018      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Si);
1019      break;
1020    case FRV_OPERAND_ACC40SK :
1021      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Sk);
1022      break;
1023    case FRV_OPERAND_ACC40UI :
1024      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Ui);
1025      break;
1026    case FRV_OPERAND_ACC40UK :
1027      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Uk);
1028      break;
1029    case FRV_OPERAND_ACCGI :
1030      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGi);
1031      break;
1032    case FRV_OPERAND_ACCGK :
1033      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGk);
1034      break;
1035    case FRV_OPERAND_CCI :
1036      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CCi);
1037      break;
1038    case FRV_OPERAND_CPRDOUBLEK :
1039      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
1040      break;
1041    case FRV_OPERAND_CPRI :
1042      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRi);
1043      break;
1044    case FRV_OPERAND_CPRJ :
1045      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRj);
1046      break;
1047    case FRV_OPERAND_CPRK :
1048      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
1049      break;
1050    case FRV_OPERAND_CRI :
1051      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRi);
1052      break;
1053    case FRV_OPERAND_CRJ :
1054      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj);
1055      break;
1056    case FRV_OPERAND_CRJ_FLOAT :
1057      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_float);
1058      break;
1059    case FRV_OPERAND_CRJ_INT :
1060      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_int);
1061      break;
1062    case FRV_OPERAND_CRK :
1063      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRk);
1064      break;
1065    case FRV_OPERAND_FCCI_1 :
1066      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_1);
1067      break;
1068    case FRV_OPERAND_FCCI_2 :
1069      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_2);
1070      break;
1071    case FRV_OPERAND_FCCI_3 :
1072      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_3);
1073      break;
1074    case FRV_OPERAND_FCCK :
1075      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCk);
1076      break;
1077    case FRV_OPERAND_FRDOUBLEI :
1078      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
1079      break;
1080    case FRV_OPERAND_FRDOUBLEJ :
1081      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
1082      break;
1083    case FRV_OPERAND_FRDOUBLEK :
1084      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1085      break;
1086    case FRV_OPERAND_FRI :
1087      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
1088      break;
1089    case FRV_OPERAND_FRINTI :
1090      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
1091      break;
1092    case FRV_OPERAND_FRINTIEVEN :
1093      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
1094      break;
1095    case FRV_OPERAND_FRINTJ :
1096      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
1097      break;
1098    case FRV_OPERAND_FRINTJEVEN :
1099      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
1100      break;
1101    case FRV_OPERAND_FRINTK :
1102      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1103      break;
1104    case FRV_OPERAND_FRINTKEVEN :
1105      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1106      break;
1107    case FRV_OPERAND_FRJ :
1108      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
1109      break;
1110    case FRV_OPERAND_FRK :
1111      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1112      break;
1113    case FRV_OPERAND_FRKHI :
1114      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1115      break;
1116    case FRV_OPERAND_FRKLO :
1117      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
1118      break;
1119    case FRV_OPERAND_GRDOUBLEK :
1120      errmsg = parse_even_register (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
1121      break;
1122    case FRV_OPERAND_GRI :
1123      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRi);
1124      break;
1125    case FRV_OPERAND_GRJ :
1126      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRj);
1127      break;
1128    case FRV_OPERAND_GRK :
1129      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
1130      break;
1131    case FRV_OPERAND_GRKHI :
1132      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
1133      break;
1134    case FRV_OPERAND_GRKLO :
1135      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
1136      break;
1137    case FRV_OPERAND_ICCI_1 :
1138      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_1);
1139      break;
1140    case FRV_OPERAND_ICCI_2 :
1141      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_2);
1142      break;
1143    case FRV_OPERAND_ICCI_3 :
1144      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_3);
1145      break;
1146    case FRV_OPERAND_LI :
1147      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LI, (unsigned long *) (& fields->f_LI));
1148      break;
1149    case FRV_OPERAND_LRAD :
1150      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAD, (unsigned long *) (& fields->f_LRAD));
1151      break;
1152    case FRV_OPERAND_LRAE :
1153      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAE, (unsigned long *) (& fields->f_LRAE));
1154      break;
1155    case FRV_OPERAND_LRAS :
1156      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAS, (unsigned long *) (& fields->f_LRAS));
1157      break;
1158    case FRV_OPERAND_TLBPRL :
1159      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_TLBPRL, (unsigned long *) (& fields->f_TLBPRL));
1160      break;
1161    case FRV_OPERAND_TLBPROPX :
1162      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_TLBPROPX, (unsigned long *) (& fields->f_TLBPRopx));
1163      break;
1164    case FRV_OPERAND_AE :
1165      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_AE, (unsigned long *) (& fields->f_ae));
1166      break;
1167    case FRV_OPERAND_CALLANN :
1168      errmsg = parse_call_annotation (cd, strp, FRV_OPERAND_CALLANN, (unsigned long *) (& fields->f_reloc_ann));
1169      break;
1170    case FRV_OPERAND_CCOND :
1171      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_CCOND, (unsigned long *) (& fields->f_ccond));
1172      break;
1173    case FRV_OPERAND_COND :
1174      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_COND, (unsigned long *) (& fields->f_cond));
1175      break;
1176    case FRV_OPERAND_D12 :
1177      errmsg = parse_d12 (cd, strp, FRV_OPERAND_D12, (long *) (& fields->f_d12));
1178      break;
1179    case FRV_OPERAND_DEBUG :
1180      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_DEBUG, (unsigned long *) (& fields->f_debug));
1181      break;
1182    case FRV_OPERAND_EIR :
1183      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_EIR, (unsigned long *) (& fields->f_eir));
1184      break;
1185    case FRV_OPERAND_HINT :
1186      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_HINT, (unsigned long *) (& fields->f_hint));
1187      break;
1188    case FRV_OPERAND_HINT_NOT_TAKEN :
1189      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_not_taken, & fields->f_hint);
1190      break;
1191    case FRV_OPERAND_HINT_TAKEN :
1192      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_taken, & fields->f_hint);
1193      break;
1194    case FRV_OPERAND_LABEL16 :
1195      {
1196        bfd_vma value = 0;
1197        errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL16, 0, NULL,  & value);
1198        fields->f_label16 = value;
1199      }
1200      break;
1201    case FRV_OPERAND_LABEL24 :
1202      {
1203        bfd_vma value = 0;
1204        errmsg = parse_call_label (cd, strp, FRV_OPERAND_LABEL24, 0, NULL,  & value);
1205        fields->f_label24 = value;
1206      }
1207      break;
1208    case FRV_OPERAND_LDANN :
1209      errmsg = parse_ld_annotation (cd, strp, FRV_OPERAND_LDANN, (unsigned long *) (& fields->f_reloc_ann));
1210      break;
1211    case FRV_OPERAND_LDDANN :
1212      errmsg = parse_ldd_annotation (cd, strp, FRV_OPERAND_LDDANN, (unsigned long *) (& fields->f_reloc_ann));
1213      break;
1214    case FRV_OPERAND_LOCK :
1215      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LOCK, (unsigned long *) (& fields->f_lock));
1216      break;
1217    case FRV_OPERAND_PACK :
1218      errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_pack, & fields->f_pack);
1219      break;
1220    case FRV_OPERAND_S10 :
1221      errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S10, (long *) (& fields->f_s10));
1222      break;
1223    case FRV_OPERAND_S12 :
1224      errmsg = parse_s12 (cd, strp, FRV_OPERAND_S12, (long *) (& fields->f_d12));
1225      break;
1226    case FRV_OPERAND_S16 :
1227      errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S16, (long *) (& fields->f_s16));
1228      break;
1229    case FRV_OPERAND_S5 :
1230      errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S5, (long *) (& fields->f_s5));
1231      break;
1232    case FRV_OPERAND_S6 :
1233      errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6, (long *) (& fields->f_s6));
1234      break;
1235    case FRV_OPERAND_S6_1 :
1236      errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6_1, (long *) (& fields->f_s6_1));
1237      break;
1238    case FRV_OPERAND_SLO16 :
1239      errmsg = parse_uslo16 (cd, strp, FRV_OPERAND_SLO16, (long *) (& fields->f_s16));
1240      break;
1241    case FRV_OPERAND_SPR :
1242      errmsg = parse_spr (cd, strp, & frv_cgen_opval_spr_names, & fields->f_spr);
1243      break;
1244    case FRV_OPERAND_U12 :
1245      errmsg = parse_u12 (cd, strp, FRV_OPERAND_U12, (long *) (& fields->f_u12));
1246      break;
1247    case FRV_OPERAND_U16 :
1248      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U16, (unsigned long *) (& fields->f_u16));
1249      break;
1250    case FRV_OPERAND_U6 :
1251      errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U6, (unsigned long *) (& fields->f_u6));
1252      break;
1253    case FRV_OPERAND_UHI16 :
1254      errmsg = parse_uhi16 (cd, strp, FRV_OPERAND_UHI16, (unsigned long *) (& fields->f_u16));
1255      break;
1256    case FRV_OPERAND_ULO16 :
1257      errmsg = parse_ulo16 (cd, strp, FRV_OPERAND_ULO16, (unsigned long *) (& fields->f_u16));
1258      break;
1259
1260    default :
1261      /* xgettext:c-format */
1262      fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
1263      abort ();
1264  }
1265
1266  return errmsg;
1267}
1268
1269cgen_parse_fn * const frv_cgen_parse_handlers[] =
1270{
1271  parse_insn_normal,
1272};
1273
1274void
1275frv_cgen_init_asm (CGEN_CPU_DESC cd)
1276{
1277  frv_cgen_init_opcode_table (cd);
1278  frv_cgen_init_ibld_table (cd);
1279  cd->parse_handlers = & frv_cgen_parse_handlers[0];
1280  cd->parse_operand = frv_cgen_parse_operand;
1281#ifdef CGEN_ASM_INIT_HOOK
1282CGEN_ASM_INIT_HOOK
1283#endif
1284}
1285
1286
1287
1288/* Regex construction routine.
1289
1290   This translates an opcode syntax string into a regex string,
1291   by replacing any non-character syntax element (such as an
1292   opcode) with the pattern '.*'
1293
1294   It then compiles the regex and stores it in the opcode, for
1295   later use by frv_cgen_assemble_insn
1296
1297   Returns NULL for success, an error message for failure.  */
1298
1299char *
1300frv_cgen_build_insn_regex (CGEN_INSN *insn)
1301{
1302  CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
1303  const char *mnem = CGEN_INSN_MNEMONIC (insn);
1304  char rxbuf[CGEN_MAX_RX_ELEMENTS];
1305  char *rx = rxbuf;
1306  const CGEN_SYNTAX_CHAR_TYPE *syn;
1307  int reg_err;
1308
1309  syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
1310
1311  /* Mnemonics come first in the syntax string.  */
1312  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1313    return _("missing mnemonic in syntax string");
1314  ++syn;
1315
1316  /* Generate a case sensitive regular expression that emulates case
1317     insensitive matching in the "C" locale.  We cannot generate a case
1318     insensitive regular expression because in Turkish locales, 'i' and 'I'
1319     are not equal modulo case conversion.  */
1320
1321  /* Copy the literal mnemonic out of the insn.  */
1322  for (; *mnem; mnem++)
1323    {
1324      char c = *mnem;
1325
1326      if (ISALPHA (c))
1327	{
1328	  *rx++ = '[';
1329	  *rx++ = TOLOWER (c);
1330	  *rx++ = TOUPPER (c);
1331	  *rx++ = ']';
1332	}
1333      else
1334	*rx++ = c;
1335    }
1336
1337  /* Copy any remaining literals from the syntax string into the rx.  */
1338  for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
1339    {
1340      if (CGEN_SYNTAX_CHAR_P (* syn))
1341	{
1342	  char c = CGEN_SYNTAX_CHAR (* syn);
1343
1344	  switch (c)
1345	    {
1346	      /* Escape any regex metacharacters in the syntax.  */
1347	    case '.': case '[': case '\\':
1348	    case '*': case '^': case '$':
1349
1350#ifdef CGEN_ESCAPE_EXTENDED_REGEX
1351	    case '?': case '{': case '}':
1352	    case '(': case ')': case '*':
1353	    case '|': case '+': case ']':
1354#endif
1355	      *rx++ = '\\';
1356	      *rx++ = c;
1357	      break;
1358
1359	    default:
1360	      if (ISALPHA (c))
1361		{
1362		  *rx++ = '[';
1363		  *rx++ = TOLOWER (c);
1364		  *rx++ = TOUPPER (c);
1365		  *rx++ = ']';
1366		}
1367	      else
1368		*rx++ = c;
1369	      break;
1370	    }
1371	}
1372      else
1373	{
1374	  /* Replace non-syntax fields with globs.  */
1375	  *rx++ = '.';
1376	  *rx++ = '*';
1377	}
1378    }
1379
1380  /* Trailing whitespace ok.  */
1381  * rx++ = '[';
1382  * rx++ = ' ';
1383  * rx++ = '\t';
1384  * rx++ = ']';
1385  * rx++ = '*';
1386
1387  /* But anchor it after that.  */
1388  * rx++ = '$';
1389  * rx = '\0';
1390
1391  CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
1392  reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
1393
1394  if (reg_err == 0)
1395    return NULL;
1396  else
1397    {
1398      static char msg[80];
1399
1400      regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
1401      regfree ((regex_t *) CGEN_INSN_RX (insn));
1402      free (CGEN_INSN_RX (insn));
1403      (CGEN_INSN_RX (insn)) = NULL;
1404      return msg;
1405    }
1406}
1407
1408
1409/* Default insn parser.
1410
1411   The syntax string is scanned and operands are parsed and stored in FIELDS.
1412   Relocs are queued as we go via other callbacks.
1413
1414   ??? Note that this is currently an all-or-nothing parser.  If we fail to
1415   parse the instruction, we return 0 and the caller will start over from
1416   the beginning.  Backtracking will be necessary in parsing subexpressions,
1417   but that can be handled there.  Not handling backtracking here may get
1418   expensive in the case of the m68k.  Deal with later.
1419
1420   Returns NULL for success, an error message for failure.  */
1421
1422static const char *
1423parse_insn_normal (CGEN_CPU_DESC cd,
1424		   const CGEN_INSN *insn,
1425		   const char **strp,
1426		   CGEN_FIELDS *fields)
1427{
1428  /* ??? Runtime added insns not handled yet.  */
1429  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
1430  const char *str = *strp;
1431  const char *errmsg;
1432  const char *p;
1433  const CGEN_SYNTAX_CHAR_TYPE * syn;
1434#ifdef CGEN_MNEMONIC_OPERANDS
1435  /* FIXME: wip */
1436  int past_opcode_p;
1437#endif
1438
1439  /* For now we assume the mnemonic is first (there are no leading operands).
1440     We can parse it without needing to set up operand parsing.
1441     GAS's input scrubber will ensure mnemonics are lowercase, but we may
1442     not be called from GAS.  */
1443  p = CGEN_INSN_MNEMONIC (insn);
1444  while (*p && TOLOWER (*p) == TOLOWER (*str))
1445    ++p, ++str;
1446
1447  if (* p)
1448    return _("unrecognized instruction");
1449
1450#ifndef CGEN_MNEMONIC_OPERANDS
1451  if (* str && ! ISSPACE (* str))
1452    return _("unrecognized instruction");
1453#endif
1454
1455  CGEN_INIT_PARSE (cd);
1456  cgen_init_parse_operand (cd);
1457#ifdef CGEN_MNEMONIC_OPERANDS
1458  past_opcode_p = 0;
1459#endif
1460
1461  /* We don't check for (*str != '\0') here because we want to parse
1462     any trailing fake arguments in the syntax string.  */
1463  syn = CGEN_SYNTAX_STRING (syntax);
1464
1465  /* Mnemonics come first for now, ensure valid string.  */
1466  if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1467    abort ();
1468
1469  ++syn;
1470
1471  while (* syn != 0)
1472    {
1473      /* Non operand chars must match exactly.  */
1474      if (CGEN_SYNTAX_CHAR_P (* syn))
1475	{
1476	  /* FIXME: While we allow for non-GAS callers above, we assume the
1477	     first char after the mnemonic part is a space.  */
1478	  /* FIXME: We also take inappropriate advantage of the fact that
1479	     GAS's input scrubber will remove extraneous blanks.  */
1480	  if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
1481	    {
1482#ifdef CGEN_MNEMONIC_OPERANDS
1483	      if (CGEN_SYNTAX_CHAR(* syn) == ' ')
1484		past_opcode_p = 1;
1485#endif
1486	      ++ syn;
1487	      ++ str;
1488	    }
1489	  else if (*str)
1490	    {
1491	      /* Syntax char didn't match.  Can't be this insn.  */
1492	      static char msg [80];
1493
1494	      /* xgettext:c-format */
1495	      sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
1496		       CGEN_SYNTAX_CHAR(*syn), *str);
1497	      return msg;
1498	    }
1499	  else
1500	    {
1501	      /* Ran out of input.  */
1502	      static char msg [80];
1503
1504	      /* xgettext:c-format */
1505	      sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
1506		       CGEN_SYNTAX_CHAR(*syn));
1507	      return msg;
1508	    }
1509	  continue;
1510	}
1511
1512#ifdef CGEN_MNEMONIC_OPERANDS
1513      (void) past_opcode_p;
1514#endif
1515      /* We have an operand of some sort.  */
1516      errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
1517      if (errmsg)
1518	return errmsg;
1519
1520      /* Done with this operand, continue with next one.  */
1521      ++ syn;
1522    }
1523
1524  /* If we're at the end of the syntax string, we're done.  */
1525  if (* syn == 0)
1526    {
1527      /* FIXME: For the moment we assume a valid `str' can only contain
1528	 blanks now.  IE: We needn't try again with a longer version of
1529	 the insn and it is assumed that longer versions of insns appear
1530	 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
1531      while (ISSPACE (* str))
1532	++ str;
1533
1534      if (* str != '\0')
1535	return _("junk at end of line"); /* FIXME: would like to include `str' */
1536
1537      return NULL;
1538    }
1539
1540  /* We couldn't parse it.  */
1541  return _("unrecognized instruction");
1542}
1543
1544/* Main entry point.
1545   This routine is called for each instruction to be assembled.
1546   STR points to the insn to be assembled.
1547   We assume all necessary tables have been initialized.
1548   The assembled instruction, less any fixups, is stored in BUF.
1549   Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
1550   still needs to be converted to target byte order, otherwise BUF is an array
1551   of bytes in target byte order.
1552   The result is a pointer to the insn's entry in the opcode table,
1553   or NULL if an error occured (an error message will have already been
1554   printed).
1555
1556   Note that when processing (non-alias) macro-insns,
1557   this function recurses.
1558
1559   ??? It's possible to make this cpu-independent.
1560   One would have to deal with a few minor things.
1561   At this point in time doing so would be more of a curiosity than useful
1562   [for example this file isn't _that_ big], but keeping the possibility in
1563   mind helps keep the design clean.  */
1564
1565const CGEN_INSN *
1566frv_cgen_assemble_insn (CGEN_CPU_DESC cd,
1567			   const char *str,
1568			   CGEN_FIELDS *fields,
1569			   CGEN_INSN_BYTES_PTR buf,
1570			   char **errmsg)
1571{
1572  const char *start;
1573  CGEN_INSN_LIST *ilist;
1574  const char *parse_errmsg = NULL;
1575  const char *insert_errmsg = NULL;
1576  int recognized_mnemonic = 0;
1577
1578  /* Skip leading white space.  */
1579  while (ISSPACE (* str))
1580    ++ str;
1581
1582  /* The instructions are stored in hashed lists.
1583     Get the first in the list.  */
1584  ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
1585
1586  /* Keep looking until we find a match.  */
1587  start = str;
1588  for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
1589    {
1590      const CGEN_INSN *insn = ilist->insn;
1591      recognized_mnemonic = 1;
1592
1593#ifdef CGEN_VALIDATE_INSN_SUPPORTED
1594      /* Not usually needed as unsupported opcodes
1595	 shouldn't be in the hash lists.  */
1596      /* Is this insn supported by the selected cpu?  */
1597      if (! frv_cgen_insn_supported (cd, insn))
1598	continue;
1599#endif
1600      /* If the RELAXED attribute is set, this is an insn that shouldn't be
1601	 chosen immediately.  Instead, it is used during assembler/linker
1602	 relaxation if possible.  */
1603      if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
1604	continue;
1605
1606      str = start;
1607
1608      /* Skip this insn if str doesn't look right lexically.  */
1609      if (CGEN_INSN_RX (insn) != NULL &&
1610	  regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
1611	continue;
1612
1613      /* Allow parse/insert handlers to obtain length of insn.  */
1614      CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
1615
1616      parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
1617      if (parse_errmsg != NULL)
1618	continue;
1619
1620      /* ??? 0 is passed for `pc'.  */
1621      insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
1622						 (bfd_vma) 0);
1623      if (insert_errmsg != NULL)
1624        continue;
1625
1626      /* It is up to the caller to actually output the insn and any
1627         queued relocs.  */
1628      return insn;
1629    }
1630
1631  {
1632    static char errbuf[150];
1633    const char *tmp_errmsg;
1634#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
1635#define be_verbose 1
1636#else
1637#define be_verbose 0
1638#endif
1639
1640    if (be_verbose)
1641      {
1642	/* If requesting verbose error messages, use insert_errmsg.
1643	   Failing that, use parse_errmsg.  */
1644	tmp_errmsg = (insert_errmsg ? insert_errmsg :
1645		      parse_errmsg ? parse_errmsg :
1646		      recognized_mnemonic ?
1647		      _("unrecognized form of instruction") :
1648		      _("unrecognized instruction"));
1649
1650	if (strlen (start) > 50)
1651	  /* xgettext:c-format */
1652	  sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
1653	else
1654	  /* xgettext:c-format */
1655	  sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
1656      }
1657    else
1658      {
1659	if (strlen (start) > 50)
1660	  /* xgettext:c-format */
1661	  sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1662	else
1663	  /* xgettext:c-format */
1664	  sprintf (errbuf, _("bad instruction `%.50s'"), start);
1665      }
1666
1667    *errmsg = errbuf;
1668    return NULL;
1669  }
1670}
1671