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