2003-09-03 Dave Brolley <brolley@redhat.com>
[external/binutils.git] / opcodes / frv-asm.c
1 /* Assembler interface for targets using CGEN. -*- C -*-
2    CGEN: Cpu tools GENerator
3
4 THIS FILE IS MACHINE GENERATED WITH CGEN.
5 - the resultant file is machine generated, cgen-asm.in isn't
6
7 Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
8
9 This file is part of the GNU Binutils and GDB, the GNU debugger.
10
11 This program 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 2, or (at your option)
14 any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public 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 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
24
25 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
26    Keep that in mind.  */
27
28 #include "sysdep.h"
29 #include <stdio.h>
30 #include "ansidecl.h"
31 #include "bfd.h"
32 #include "symcat.h"
33 #include "frv-desc.h"
34 #include "frv-opc.h"
35 #include "opintl.h"
36 #include "xregex.h"
37 #include "libiberty.h"
38 #include "safe-ctype.h"
39
40 #undef  min
41 #define min(a,b) ((a) < (b) ? (a) : (b))
42 #undef  max
43 #define max(a,b) ((a) > (b) ? (a) : (b))
44
45 static const char * parse_insn_normal
46   (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
47 \f
48 /* -- assembler routines inserted here.  */
49
50 /* -- asm.c */
51 static const char * parse_ulo16
52   PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
53 static const char * parse_uslo16
54   PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
55 static const char * parse_uhi16
56   PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
57 static long parse_register_number
58   PARAMS ((const char **));
59 static const char * parse_spr
60   PARAMS ((CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *));
61 static const char * parse_d12
62   PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
63 static const char * parse_s12
64   PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
65 static const char * parse_u12
66   PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
67 static const char * parse_even_register
68   PARAMS ((CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *));
69 static const char * parse_A0
70   PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
71 static const char * parse_A1
72   PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
73 static const char * parse_A
74   PARAMS ((CGEN_CPU_DESC, const char **, int, long *, long));
75
76 static const char *
77 parse_ulo16 (cd, strp, opindex, valuep)
78      CGEN_CPU_DESC cd;
79      const char **strp;
80      int opindex;
81      unsigned long *valuep;
82 {
83   const char *errmsg;
84   enum cgen_parse_operand_result result_type;
85   bfd_vma value;
86  
87   if (**strp == '#' || **strp == '%')
88     {
89       if (strncasecmp (*strp + 1, "lo(", 3) == 0)
90         {
91           *strp += 4;
92           errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
93                                        &result_type, &value);
94           if (**strp != ')')
95             return "missing `)'";
96           ++*strp;
97           if (errmsg == NULL
98               && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
99             value &= 0xffff;
100           *valuep = value;
101           return errmsg;
102         }
103       if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
104         {
105           *strp += 9;
106           errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO,
107                                        &result_type, &value);
108           if (**strp != ')')
109             return "missing ')'";
110           ++*strp;
111           if (errmsg == NULL
112               && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
113             value >>= 16;
114           *valuep = value;
115           return errmsg;
116         }
117     }
118   return cgen_parse_signed_integer (cd, strp, opindex, valuep);
119 }
120
121 static const char *
122 parse_uslo16 (cd, strp, opindex, valuep)
123      CGEN_CPU_DESC cd;
124      const char **strp;
125      int opindex;
126      unsigned long *valuep;
127 {
128   const char *errmsg;
129   enum cgen_parse_operand_result result_type;
130   bfd_vma value;
131  
132   if (**strp == '#' || **strp == '%')
133     {
134       if (strncasecmp (*strp + 1, "lo(", 3) == 0)
135         {
136           *strp += 4;
137           errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
138                                        &result_type, &value);
139           if (**strp != ')')
140             return "missing `)'";
141           ++*strp;
142           if (errmsg == NULL
143               && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
144             value &= 0xffff;
145           *valuep = value;
146           return errmsg;
147         }
148       else if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
149         {
150           *strp += 9;
151           errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELLO,
152                                        &result_type, &value);
153           if (**strp != ')')
154             return "missing ')'";
155           ++*strp;
156           if (errmsg == NULL
157               && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
158             value &= 0xffff;
159           *valuep = value;
160           return errmsg;
161         }
162     }
163   return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
164 }
165
166 static const char *
167 parse_uhi16 (cd, strp, opindex, valuep)
168      CGEN_CPU_DESC cd;
169      const char **strp;
170      int opindex;
171      unsigned long *valuep;
172 {
173   const char *errmsg;
174   enum cgen_parse_operand_result result_type;
175   bfd_vma value;
176  
177   if (**strp == '#' || **strp == '%')
178     {
179       if (strncasecmp (*strp + 1, "hi(", 3) == 0)
180         {
181           *strp += 4;
182           errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16,
183                                        &result_type, &value);
184           if (**strp != ')')
185             return "missing `)'";
186           ++*strp;
187           if (errmsg == NULL
188               && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
189             value >>= 16;
190           *valuep = value;
191           return errmsg;
192         }
193       else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0)
194         {
195           *strp += 9;
196           errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELHI,
197                                        &result_type, &value);
198           if (**strp != ')')
199             return "missing ')'";
200           ++*strp;
201           if (errmsg == NULL
202               && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
203             value >>= 16;
204           *valuep = value;
205           return errmsg;
206         }
207     }
208   return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
209 }
210
211 static long
212 parse_register_number (strp)
213      const char **strp;
214 {
215   int regno;
216   if (**strp < '0' || **strp > '9')
217     return -1; /* error */
218
219   regno = **strp - '0';
220   for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp)
221     regno = regno * 10 + (**strp - '0');
222
223   return regno;
224 }
225
226 static const char *
227 parse_spr (cd, strp, table, valuep)
228      CGEN_CPU_DESC cd;
229      const char **strp;
230      CGEN_KEYWORD * table;
231      long *valuep;
232 {
233   const char *save_strp;
234   long regno;
235
236   /* Check for spr index notation.  */
237   if (strncasecmp (*strp, "spr[", 4) == 0)
238     {
239       *strp += 4;
240       regno = parse_register_number (strp);
241       if (**strp != ']')
242         return "missing `]'";
243       ++*strp;
244       if (! spr_valid (regno))
245         return "Special purpose register number is out of range";
246       *valuep = regno;
247       return NULL;
248     }
249
250   save_strp = *strp;
251   regno = parse_register_number (strp);
252   if (regno != -1)
253     {
254       if (! spr_valid (regno))
255         return "Special purpose register number is out of range";
256       *valuep = regno;
257       return NULL;
258     }
259
260   *strp = save_strp;
261   return cgen_parse_keyword (cd, strp, table, valuep);
262 }
263
264 static const char *
265 parse_d12 (cd, strp, opindex, valuep)
266      CGEN_CPU_DESC cd;
267      const char **strp;
268      int opindex;
269      long *valuep;
270 {
271   const char *errmsg;
272   enum cgen_parse_operand_result result_type;
273   bfd_vma value;
274  
275   /* Check for small data reference.  */
276   if (**strp == '#' || **strp == '%')
277     {
278       if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
279         {
280           *strp += 9;
281           errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12,
282                                        &result_type, &value);
283           if (**strp != ')')
284             return "missing `)'";
285           ++*strp;
286           *valuep = value;
287           return errmsg;
288         }
289     }
290   return cgen_parse_signed_integer (cd, strp, opindex, valuep);
291 }
292
293 static const char *
294 parse_s12 (cd, strp, opindex, valuep)
295      CGEN_CPU_DESC cd;
296      const char **strp;
297      int opindex;
298      long *valuep;
299 {
300   const char *errmsg;
301   enum cgen_parse_operand_result result_type;
302   bfd_vma value;
303  
304   /* Check for small data reference.  */
305   if ((**strp == '#' || **strp == '%')
306       && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
307     {
308       *strp += 9;
309       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPREL12,
310                                     &result_type, &value);
311       if (**strp != ')')
312         return "missing `)'";
313       ++*strp;
314       *valuep = value;
315       return errmsg;
316     }
317   else
318     {
319       if (**strp == '#')
320         ++*strp;
321       return cgen_parse_signed_integer (cd, strp, opindex, valuep);
322     }
323 }
324
325 static const char *
326 parse_u12 (cd, strp, opindex, valuep)
327      CGEN_CPU_DESC cd;
328      const char **strp;
329      int opindex;
330      long *valuep;
331 {
332   const char *errmsg;
333   enum cgen_parse_operand_result result_type;
334   bfd_vma value;
335  
336   /* Check for small data reference.  */
337   if ((**strp == '#' || **strp == '%')
338       && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
339     {
340       *strp += 9;
341       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_GPRELU12,
342                                     &result_type, &value);
343       if (**strp != ')')
344         return "missing `)'";
345       ++*strp;
346       *valuep = value;
347       return errmsg;
348     }
349   else
350     {
351       if (**strp == '#')
352         ++*strp;
353       return cgen_parse_signed_integer (cd, strp, opindex, valuep);
354     }
355 }
356
357 static const char *
358 parse_A (cd, strp, opindex, valuep, A)
359      CGEN_CPU_DESC cd;
360      const char **strp;
361      int opindex;
362      long *valuep;
363      long A;
364 {
365   const char *errmsg;
366  
367   if (**strp == '#')
368     ++*strp;
369
370   errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
371   if (errmsg)
372     return errmsg;
373
374   if (*valuep != A)
375     return "Value of A operand must be 0 or 1";
376
377   return NULL;
378 }
379
380 static const char *
381 parse_A0 (cd, strp, opindex, valuep)
382      CGEN_CPU_DESC cd;
383      const char **strp;
384      int opindex;
385      long *valuep;
386 {
387   return parse_A (cd, strp, opindex, valuep, 0);
388 }
389
390 static const char *
391 parse_A1 (cd, strp, opindex, valuep)
392      CGEN_CPU_DESC cd;
393      const char **strp;
394      int opindex;
395      long *valuep;
396 {
397   return parse_A (cd, strp, opindex, valuep, 1);
398 }
399
400 static const char *
401 parse_even_register (cd, strP, tableP, valueP)
402      CGEN_CPU_DESC  cd;
403      const char **  strP;
404      CGEN_KEYWORD * tableP;
405      long *         valueP;
406 {
407   const char * errmsg;
408   const char * saved_star_strP = * strP;
409
410   errmsg = cgen_parse_keyword (cd, strP, tableP, valueP);
411
412   if (errmsg == NULL && ((* valueP) & 1))
413     {
414       errmsg = _("register number must be even");
415       * strP = saved_star_strP;
416     }
417
418   return errmsg;
419 }
420 /* -- */
421
422 const char * frv_cgen_parse_operand
423   PARAMS ((CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *));
424
425 /* Main entry point for operand parsing.
426
427    This function is basically just a big switch statement.  Earlier versions
428    used tables to look up the function to use, but
429    - if the table contains both assembler and disassembler functions then
430      the disassembler contains much of the assembler and vice-versa,
431    - there's a lot of inlining possibilities as things grow,
432    - using a switch statement avoids the function call overhead.
433
434    This function could be moved into `parse_insn_normal', but keeping it
435    separate makes clear the interface between `parse_insn_normal' and each of
436    the handlers.  */
437
438 const char *
439 frv_cgen_parse_operand (cd, opindex, strp, fields)
440      CGEN_CPU_DESC cd;
441      int opindex;
442      const char ** strp;
443      CGEN_FIELDS * fields;
444 {
445   const char * errmsg = NULL;
446   /* Used by scalar operands that still need to be parsed.  */
447   long junk ATTRIBUTE_UNUSED;
448
449   switch (opindex)
450     {
451     case FRV_OPERAND_A0 :
452       errmsg = parse_A0 (cd, strp, FRV_OPERAND_A0, &fields->f_A);
453       break;
454     case FRV_OPERAND_A1 :
455       errmsg = parse_A1 (cd, strp, FRV_OPERAND_A1, &fields->f_A);
456       break;
457     case FRV_OPERAND_ACC40SI :
458       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Si);
459       break;
460     case FRV_OPERAND_ACC40SK :
461       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Sk);
462       break;
463     case FRV_OPERAND_ACC40UI :
464       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Ui);
465       break;
466     case FRV_OPERAND_ACC40UK :
467       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Uk);
468       break;
469     case FRV_OPERAND_ACCGI :
470       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGi);
471       break;
472     case FRV_OPERAND_ACCGK :
473       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGk);
474       break;
475     case FRV_OPERAND_CCI :
476       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CCi);
477       break;
478     case FRV_OPERAND_CPRDOUBLEK :
479       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
480       break;
481     case FRV_OPERAND_CPRI :
482       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRi);
483       break;
484     case FRV_OPERAND_CPRJ :
485       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRj);
486       break;
487     case FRV_OPERAND_CPRK :
488       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
489       break;
490     case FRV_OPERAND_CRI :
491       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRi);
492       break;
493     case FRV_OPERAND_CRJ :
494       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj);
495       break;
496     case FRV_OPERAND_CRJ_FLOAT :
497       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_float);
498       break;
499     case FRV_OPERAND_CRJ_INT :
500       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_int);
501       break;
502     case FRV_OPERAND_CRK :
503       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRk);
504       break;
505     case FRV_OPERAND_FCCI_1 :
506       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_1);
507       break;
508     case FRV_OPERAND_FCCI_2 :
509       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_2);
510       break;
511     case FRV_OPERAND_FCCI_3 :
512       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_3);
513       break;
514     case FRV_OPERAND_FCCK :
515       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCk);
516       break;
517     case FRV_OPERAND_FRDOUBLEI :
518       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
519       break;
520     case FRV_OPERAND_FRDOUBLEJ :
521       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
522       break;
523     case FRV_OPERAND_FRDOUBLEK :
524       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
525       break;
526     case FRV_OPERAND_FRI :
527       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
528       break;
529     case FRV_OPERAND_FRINTI :
530       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
531       break;
532     case FRV_OPERAND_FRINTIEVEN :
533       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
534       break;
535     case FRV_OPERAND_FRINTJ :
536       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
537       break;
538     case FRV_OPERAND_FRINTJEVEN :
539       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
540       break;
541     case FRV_OPERAND_FRINTK :
542       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
543       break;
544     case FRV_OPERAND_FRINTKEVEN :
545       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
546       break;
547     case FRV_OPERAND_FRJ :
548       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
549       break;
550     case FRV_OPERAND_FRK :
551       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
552       break;
553     case FRV_OPERAND_FRKHI :
554       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
555       break;
556     case FRV_OPERAND_FRKLO :
557       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
558       break;
559     case FRV_OPERAND_GRDOUBLEK :
560       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
561       break;
562     case FRV_OPERAND_GRI :
563       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRi);
564       break;
565     case FRV_OPERAND_GRJ :
566       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRj);
567       break;
568     case FRV_OPERAND_GRK :
569       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
570       break;
571     case FRV_OPERAND_GRKHI :
572       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
573       break;
574     case FRV_OPERAND_GRKLO :
575       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
576       break;
577     case FRV_OPERAND_ICCI_1 :
578       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_1);
579       break;
580     case FRV_OPERAND_ICCI_2 :
581       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_2);
582       break;
583     case FRV_OPERAND_ICCI_3 :
584       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_3);
585       break;
586     case FRV_OPERAND_LI :
587       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LI, &fields->f_LI);
588       break;
589     case FRV_OPERAND_AE :
590       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_AE, &fields->f_ae);
591       break;
592     case FRV_OPERAND_CCOND :
593       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_CCOND, &fields->f_ccond);
594       break;
595     case FRV_OPERAND_COND :
596       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_COND, &fields->f_cond);
597       break;
598     case FRV_OPERAND_D12 :
599       errmsg = parse_d12 (cd, strp, FRV_OPERAND_D12, &fields->f_d12);
600       break;
601     case FRV_OPERAND_DEBUG :
602       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_DEBUG, &fields->f_debug);
603       break;
604     case FRV_OPERAND_EIR :
605       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_EIR, &fields->f_eir);
606       break;
607     case FRV_OPERAND_HINT :
608       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_HINT, &fields->f_hint);
609       break;
610     case FRV_OPERAND_HINT_NOT_TAKEN :
611       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_not_taken, & fields->f_hint);
612       break;
613     case FRV_OPERAND_HINT_TAKEN :
614       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_taken, & fields->f_hint);
615       break;
616     case FRV_OPERAND_LABEL16 :
617       {
618         bfd_vma value;
619         errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL16, 0, NULL,  & value);
620         fields->f_label16 = value;
621       }
622       break;
623     case FRV_OPERAND_LABEL24 :
624       {
625         bfd_vma value;
626         errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL24, 0, NULL,  & value);
627         fields->f_label24 = value;
628       }
629       break;
630     case FRV_OPERAND_LOCK :
631       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LOCK, &fields->f_lock);
632       break;
633     case FRV_OPERAND_PACK :
634       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_pack, & fields->f_pack);
635       break;
636     case FRV_OPERAND_S10 :
637       errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S10, &fields->f_s10);
638       break;
639     case FRV_OPERAND_S12 :
640       errmsg = parse_s12 (cd, strp, FRV_OPERAND_S12, &fields->f_d12);
641       break;
642     case FRV_OPERAND_S16 :
643       errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S16, &fields->f_s16);
644       break;
645     case FRV_OPERAND_S5 :
646       errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S5, &fields->f_s5);
647       break;
648     case FRV_OPERAND_S6 :
649       errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6, &fields->f_s6);
650       break;
651     case FRV_OPERAND_S6_1 :
652       errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6_1, &fields->f_s6_1);
653       break;
654     case FRV_OPERAND_SLO16 :
655       errmsg = parse_uslo16 (cd, strp, FRV_OPERAND_SLO16, &fields->f_s16);
656       break;
657     case FRV_OPERAND_SPR :
658       errmsg = parse_spr (cd, strp, & frv_cgen_opval_spr_names, & fields->f_spr);
659       break;
660     case FRV_OPERAND_U12 :
661       errmsg = parse_u12 (cd, strp, FRV_OPERAND_U12, &fields->f_u12);
662       break;
663     case FRV_OPERAND_U16 :
664       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U16, &fields->f_u16);
665       break;
666     case FRV_OPERAND_U6 :
667       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U6, &fields->f_u6);
668       break;
669     case FRV_OPERAND_UHI16 :
670       errmsg = parse_uhi16 (cd, strp, FRV_OPERAND_UHI16, &fields->f_u16);
671       break;
672     case FRV_OPERAND_ULO16 :
673       errmsg = parse_ulo16 (cd, strp, FRV_OPERAND_ULO16, &fields->f_u16);
674       break;
675
676     default :
677       /* xgettext:c-format */
678       fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
679       abort ();
680   }
681
682   return errmsg;
683 }
684
685 cgen_parse_fn * const frv_cgen_parse_handlers[] = 
686 {
687   parse_insn_normal,
688 };
689
690 void
691 frv_cgen_init_asm (cd)
692      CGEN_CPU_DESC cd;
693 {
694   frv_cgen_init_opcode_table (cd);
695   frv_cgen_init_ibld_table (cd);
696   cd->parse_handlers = & frv_cgen_parse_handlers[0];
697   cd->parse_operand = frv_cgen_parse_operand;
698 }
699
700 \f
701
702 /* Regex construction routine.
703
704    This translates an opcode syntax string into a regex string,
705    by replacing any non-character syntax element (such as an
706    opcode) with the pattern '.*'
707
708    It then compiles the regex and stores it in the opcode, for
709    later use by frv_cgen_assemble_insn
710
711    Returns NULL for success, an error message for failure.  */
712
713 char * 
714 frv_cgen_build_insn_regex (CGEN_INSN *insn)
715 {  
716   CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
717   const char *mnem = CGEN_INSN_MNEMONIC (insn);
718   char rxbuf[CGEN_MAX_RX_ELEMENTS];
719   char *rx = rxbuf;
720   const CGEN_SYNTAX_CHAR_TYPE *syn;
721   int reg_err;
722
723   syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
724
725   /* Mnemonics come first in the syntax string.  */
726   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
727     return _("missing mnemonic in syntax string");
728   ++syn;
729
730   /* Generate a case sensitive regular expression that emulates case
731      insensitive matching in the "C" locale.  We cannot generate a case
732      insensitive regular expression because in Turkish locales, 'i' and 'I'
733      are not equal modulo case conversion.  */
734
735   /* Copy the literal mnemonic out of the insn.  */
736   for (; *mnem; mnem++)
737     {
738       char c = *mnem;
739
740       if (ISALPHA (c))
741         {
742           *rx++ = '[';
743           *rx++ = TOLOWER (c);
744           *rx++ = TOUPPER (c);
745           *rx++ = ']';
746         }
747       else
748         *rx++ = c;
749     }
750
751   /* Copy any remaining literals from the syntax string into the rx.  */
752   for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
753     {
754       if (CGEN_SYNTAX_CHAR_P (* syn)) 
755         {
756           char c = CGEN_SYNTAX_CHAR (* syn);
757
758           switch (c) 
759             {
760               /* Escape any regex metacharacters in the syntax.  */
761             case '.': case '[': case '\\': 
762             case '*': case '^': case '$': 
763
764 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
765             case '?': case '{': case '}': 
766             case '(': case ')': case '*':
767             case '|': case '+': case ']':
768 #endif
769               *rx++ = '\\';
770               *rx++ = c;
771               break;
772
773             default:
774               if (ISALPHA (c))
775                 {
776                   *rx++ = '[';
777                   *rx++ = TOLOWER (c);
778                   *rx++ = TOUPPER (c);
779                   *rx++ = ']';
780                 }
781               else
782                 *rx++ = c;
783               break;
784             }
785         }
786       else
787         {
788           /* Replace non-syntax fields with globs.  */
789           *rx++ = '.';
790           *rx++ = '*';
791         }
792     }
793
794   /* Trailing whitespace ok.  */
795   * rx++ = '['; 
796   * rx++ = ' '; 
797   * rx++ = '\t'; 
798   * rx++ = ']'; 
799   * rx++ = '*'; 
800
801   /* But anchor it after that.  */
802   * rx++ = '$'; 
803   * rx = '\0';
804
805   CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
806   reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
807
808   if (reg_err == 0) 
809     return NULL;
810   else
811     {
812       static char msg[80];
813
814       regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
815       regfree ((regex_t *) CGEN_INSN_RX (insn));
816       free (CGEN_INSN_RX (insn));
817       (CGEN_INSN_RX (insn)) = NULL;
818       return msg;
819     }
820 }
821
822 \f
823 /* Default insn parser.
824
825    The syntax string is scanned and operands are parsed and stored in FIELDS.
826    Relocs are queued as we go via other callbacks.
827
828    ??? Note that this is currently an all-or-nothing parser.  If we fail to
829    parse the instruction, we return 0 and the caller will start over from
830    the beginning.  Backtracking will be necessary in parsing subexpressions,
831    but that can be handled there.  Not handling backtracking here may get
832    expensive in the case of the m68k.  Deal with later.
833
834    Returns NULL for success, an error message for failure.  */
835
836 static const char *
837 parse_insn_normal (CGEN_CPU_DESC cd,
838                    const CGEN_INSN *insn,
839                    const char **strp,
840                    CGEN_FIELDS *fields)
841 {
842   /* ??? Runtime added insns not handled yet.  */
843   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
844   const char *str = *strp;
845   const char *errmsg;
846   const char *p;
847   const CGEN_SYNTAX_CHAR_TYPE * syn;
848 #ifdef CGEN_MNEMONIC_OPERANDS
849   /* FIXME: wip */
850   int past_opcode_p;
851 #endif
852
853   /* For now we assume the mnemonic is first (there are no leading operands).
854      We can parse it without needing to set up operand parsing.
855      GAS's input scrubber will ensure mnemonics are lowercase, but we may
856      not be called from GAS.  */
857   p = CGEN_INSN_MNEMONIC (insn);
858   while (*p && TOLOWER (*p) == TOLOWER (*str))
859     ++p, ++str;
860
861   if (* p)
862     return _("unrecognized instruction");
863
864 #ifndef CGEN_MNEMONIC_OPERANDS
865   if (* str && ! ISSPACE (* str))
866     return _("unrecognized instruction");
867 #endif
868
869   CGEN_INIT_PARSE (cd);
870   cgen_init_parse_operand (cd);
871 #ifdef CGEN_MNEMONIC_OPERANDS
872   past_opcode_p = 0;
873 #endif
874
875   /* We don't check for (*str != '\0') here because we want to parse
876      any trailing fake arguments in the syntax string.  */
877   syn = CGEN_SYNTAX_STRING (syntax);
878
879   /* Mnemonics come first for now, ensure valid string.  */
880   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
881     abort ();
882
883   ++syn;
884
885   while (* syn != 0)
886     {
887       /* Non operand chars must match exactly.  */
888       if (CGEN_SYNTAX_CHAR_P (* syn))
889         {
890           /* FIXME: While we allow for non-GAS callers above, we assume the
891              first char after the mnemonic part is a space.  */
892           /* FIXME: We also take inappropriate advantage of the fact that
893              GAS's input scrubber will remove extraneous blanks.  */
894           if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
895             {
896 #ifdef CGEN_MNEMONIC_OPERANDS
897               if (CGEN_SYNTAX_CHAR(* syn) == ' ')
898                 past_opcode_p = 1;
899 #endif
900               ++ syn;
901               ++ str;
902             }
903           else if (*str)
904             {
905               /* Syntax char didn't match.  Can't be this insn.  */
906               static char msg [80];
907
908               /* xgettext:c-format */
909               sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
910                        CGEN_SYNTAX_CHAR(*syn), *str);
911               return msg;
912             }
913           else
914             {
915               /* Ran out of input.  */
916               static char msg [80];
917
918               /* xgettext:c-format */
919               sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
920                        CGEN_SYNTAX_CHAR(*syn));
921               return msg;
922             }
923           continue;
924         }
925
926       /* We have an operand of some sort.  */
927       errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
928                                           &str, fields);
929       if (errmsg)
930         return errmsg;
931
932       /* Done with this operand, continue with next one.  */
933       ++ syn;
934     }
935
936   /* If we're at the end of the syntax string, we're done.  */
937   if (* syn == 0)
938     {
939       /* FIXME: For the moment we assume a valid `str' can only contain
940          blanks now.  IE: We needn't try again with a longer version of
941          the insn and it is assumed that longer versions of insns appear
942          before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
943       while (ISSPACE (* str))
944         ++ str;
945
946       if (* str != '\0')
947         return _("junk at end of line"); /* FIXME: would like to include `str' */
948
949       return NULL;
950     }
951
952   /* We couldn't parse it.  */
953   return _("unrecognized instruction");
954 }
955 \f
956 /* Main entry point.
957    This routine is called for each instruction to be assembled.
958    STR points to the insn to be assembled.
959    We assume all necessary tables have been initialized.
960    The assembled instruction, less any fixups, is stored in BUF.
961    Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
962    still needs to be converted to target byte order, otherwise BUF is an array
963    of bytes in target byte order.
964    The result is a pointer to the insn's entry in the opcode table,
965    or NULL if an error occured (an error message will have already been
966    printed).
967
968    Note that when processing (non-alias) macro-insns,
969    this function recurses.
970
971    ??? It's possible to make this cpu-independent.
972    One would have to deal with a few minor things.
973    At this point in time doing so would be more of a curiosity than useful
974    [for example this file isn't _that_ big], but keeping the possibility in
975    mind helps keep the design clean.  */
976
977 const CGEN_INSN *
978 frv_cgen_assemble_insn (CGEN_CPU_DESC cd,
979                            const char *str,
980                            CGEN_FIELDS *fields,
981                            CGEN_INSN_BYTES_PTR buf,
982                            char **errmsg)
983 {
984   const char *start;
985   CGEN_INSN_LIST *ilist;
986   const char *parse_errmsg = NULL;
987   const char *insert_errmsg = NULL;
988   int recognized_mnemonic = 0;
989
990   /* Skip leading white space.  */
991   while (ISSPACE (* str))
992     ++ str;
993
994   /* The instructions are stored in hashed lists.
995      Get the first in the list.  */
996   ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
997
998   /* Keep looking until we find a match.  */
999   start = str;
1000   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
1001     {
1002       const CGEN_INSN *insn = ilist->insn;
1003       recognized_mnemonic = 1;
1004
1005 #ifdef CGEN_VALIDATE_INSN_SUPPORTED 
1006       /* Not usually needed as unsupported opcodes
1007          shouldn't be in the hash lists.  */
1008       /* Is this insn supported by the selected cpu?  */
1009       if (! frv_cgen_insn_supported (cd, insn))
1010         continue;
1011 #endif
1012       /* If the RELAXED attribute is set, this is an insn that shouldn't be
1013          chosen immediately.  Instead, it is used during assembler/linker
1014          relaxation if possible.  */
1015       if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
1016         continue;
1017
1018       str = start;
1019
1020       /* Skip this insn if str doesn't look right lexically.  */
1021       if (CGEN_INSN_RX (insn) != NULL &&
1022           regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
1023         continue;
1024
1025       /* Allow parse/insert handlers to obtain length of insn.  */
1026       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
1027
1028       parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
1029       if (parse_errmsg != NULL)
1030         continue;
1031
1032       /* ??? 0 is passed for `pc'.  */
1033       insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
1034                                                  (bfd_vma) 0);
1035       if (insert_errmsg != NULL)
1036         continue;
1037
1038       /* It is up to the caller to actually output the insn and any
1039          queued relocs.  */
1040       return insn;
1041     }
1042
1043   {
1044     static char errbuf[150];
1045 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
1046     const char *tmp_errmsg;
1047
1048     /* If requesting verbose error messages, use insert_errmsg.
1049        Failing that, use parse_errmsg.  */
1050     tmp_errmsg = (insert_errmsg ? insert_errmsg :
1051                   parse_errmsg ? parse_errmsg :
1052                   recognized_mnemonic ?
1053                   _("unrecognized form of instruction") :
1054                   _("unrecognized instruction"));
1055
1056     if (strlen (start) > 50)
1057       /* xgettext:c-format */
1058       sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
1059     else 
1060       /* xgettext:c-format */
1061       sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
1062 #else
1063     if (strlen (start) > 50)
1064       /* xgettext:c-format */
1065       sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1066     else 
1067       /* xgettext:c-format */
1068       sprintf (errbuf, _("bad instruction `%.50s'"), start);
1069 #endif
1070       
1071     *errmsg = errbuf;
1072     return NULL;
1073   }
1074 }
1075 \f
1076 #if 0 /* This calls back to GAS which we can't do without care.  */
1077
1078 /* Record each member of OPVALS in the assembler's symbol table.
1079    This lets GAS parse registers for us.
1080    ??? Interesting idea but not currently used.  */
1081
1082 /* Record each member of OPVALS in the assembler's symbol table.
1083    FIXME: Not currently used.  */
1084
1085 void
1086 frv_cgen_asm_hash_keywords (CGEN_CPU_DESC cd, CGEN_KEYWORD *opvals)
1087 {
1088   CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
1089   const CGEN_KEYWORD_ENTRY * ke;
1090
1091   while ((ke = cgen_keyword_search_next (& search)) != NULL)
1092     {
1093 #if 0 /* Unnecessary, should be done in the search routine.  */
1094       if (! frv_cgen_opval_supported (ke))
1095         continue;
1096 #endif
1097       cgen_asm_record_register (cd, ke->name, ke->value);
1098     }
1099 }
1100
1101 #endif /* 0 */