OSDN Git Service

Use safe-ctype.h not ctype.h
[pf3gnuchains/pf3gnuchains3x.git] / opcodes / m32r-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 "m32r-desc.h"
34 #include "m32r-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_hash
52   PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
53 static const char * parse_hi16
54   PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
55 static const char * parse_slo16
56   PARAMS ((CGEN_CPU_DESC, const char **, int, long *));
57 static const char * parse_ulo16
58   PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *));
59
60 /* Handle '#' prefixes (i.e. skip over them).  */
61
62 static const char *
63 parse_hash (cd, strp, opindex, valuep)
64      CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
65      const char **strp;
66      int opindex ATTRIBUTE_UNUSED;
67      unsigned long *valuep ATTRIBUTE_UNUSED;
68 {
69   if (**strp == '#')
70     ++*strp;
71   return NULL;
72 }
73
74 /* Handle shigh(), high().  */
75
76 static const char *
77 parse_hi16 (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 == '#')
88     ++*strp;
89
90   if (strncasecmp (*strp, "high(", 5) == 0)
91     {
92       *strp += 5;
93       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_HI16_ULO,
94                                    &result_type, &value);
95       if (**strp != ')')
96         return "missing `)'";
97       ++*strp;
98       if (errmsg == NULL
99           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
100         value >>= 16;
101       *valuep = value;
102       return errmsg;
103     }
104   else if (strncasecmp (*strp, "shigh(", 6) == 0)
105     {
106       *strp += 6;
107       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_HI16_SLO,
108                                    &result_type, &value);
109       if (**strp != ')')
110         return "missing `)'";
111       ++*strp;
112       if (errmsg == NULL
113           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
114         value = (value >> 16) + (value & 0x8000 ? 1 : 0);
115       *valuep = value;
116       return errmsg;
117     }
118
119   return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
120 }
121
122 /* Handle low() in a signed context.  Also handle sda().
123    The signedness of the value doesn't matter to low(), but this also
124    handles the case where low() isn't present.  */
125
126 static const char *
127 parse_slo16 (cd, strp, opindex, valuep)
128      CGEN_CPU_DESC cd;
129      const char **strp;
130      int opindex;
131      long *valuep;
132 {
133   const char *errmsg;
134   enum cgen_parse_operand_result result_type;
135   bfd_vma value;
136
137   if (**strp == '#')
138     ++*strp;
139
140   if (strncasecmp (*strp, "low(", 4) == 0)
141     {
142       *strp += 4;
143       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_LO16,
144                                    &result_type, &value);
145       if (**strp != ')')
146         return "missing `)'";
147       ++*strp;
148       if (errmsg == NULL
149           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
150         value &= 0xffff;
151       *valuep = value;
152       return errmsg;
153     }
154
155   if (strncasecmp (*strp, "sda(", 4) == 0)
156     {
157       *strp += 4;
158       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_SDA16,
159                                    NULL, &value);
160       if (**strp != ')')
161         return "missing `)'";
162       ++*strp;
163       *valuep = value;
164       return errmsg;
165     }
166
167   return cgen_parse_signed_integer (cd, strp, opindex, valuep);
168 }
169
170 /* Handle low() in an unsigned context.
171    The signedness of the value doesn't matter to low(), but this also
172    handles the case where low() isn't present.  */
173
174 static const char *
175 parse_ulo16 (cd, strp, opindex, valuep)
176      CGEN_CPU_DESC cd;
177      const char **strp;
178      int opindex;
179      unsigned long *valuep;
180 {
181   const char *errmsg;
182   enum cgen_parse_operand_result result_type;
183   bfd_vma value;
184
185   if (**strp == '#')
186     ++*strp;
187
188   if (strncasecmp (*strp, "low(", 4) == 0)
189     {
190       *strp += 4;
191       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32R_LO16,
192                                    &result_type, &value);
193       if (**strp != ')')
194         return "missing `)'";
195       ++*strp;
196       if (errmsg == NULL
197           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
198         value &= 0xffff;
199       *valuep = value;
200       return errmsg;
201     }
202
203   return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
204 }
205
206 /* -- */
207
208 const char * m32r_cgen_parse_operand
209   PARAMS ((CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *));
210
211 /* Main entry point for operand parsing.
212
213    This function is basically just a big switch statement.  Earlier versions
214    used tables to look up the function to use, but
215    - if the table contains both assembler and disassembler functions then
216      the disassembler contains much of the assembler and vice-versa,
217    - there's a lot of inlining possibilities as things grow,
218    - using a switch statement avoids the function call overhead.
219
220    This function could be moved into `parse_insn_normal', but keeping it
221    separate makes clear the interface between `parse_insn_normal' and each of
222    the handlers.
223 */
224
225 const char *
226 m32r_cgen_parse_operand (cd, opindex, strp, fields)
227      CGEN_CPU_DESC cd;
228      int opindex;
229      const char ** strp;
230      CGEN_FIELDS * fields;
231 {
232   const char * errmsg = NULL;
233   /* Used by scalar operands that still need to be parsed.  */
234   long junk ATTRIBUTE_UNUSED;
235
236   switch (opindex)
237     {
238     case M32R_OPERAND_ACC :
239       errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_h_accums, & fields->f_acc);
240       break;
241     case M32R_OPERAND_ACCD :
242       errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_h_accums, & fields->f_accd);
243       break;
244     case M32R_OPERAND_ACCS :
245       errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_h_accums, & fields->f_accs);
246       break;
247     case M32R_OPERAND_DCR :
248       errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_cr_names, & fields->f_r1);
249       break;
250     case M32R_OPERAND_DISP16 :
251       {
252         bfd_vma value;
253         errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_DISP16, 0, NULL,  & value);
254         fields->f_disp16 = value;
255       }
256       break;
257     case M32R_OPERAND_DISP24 :
258       {
259         bfd_vma value;
260         errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_DISP24, 0, NULL,  & value);
261         fields->f_disp24 = value;
262       }
263       break;
264     case M32R_OPERAND_DISP8 :
265       {
266         bfd_vma value;
267         errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_DISP8, 0, NULL,  & value);
268         fields->f_disp8 = value;
269       }
270       break;
271     case M32R_OPERAND_DR :
272       errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r1);
273       break;
274     case M32R_OPERAND_HASH :
275       errmsg = parse_hash (cd, strp, M32R_OPERAND_HASH, &junk);
276       break;
277     case M32R_OPERAND_HI16 :
278       errmsg = parse_hi16 (cd, strp, M32R_OPERAND_HI16, &fields->f_hi16);
279       break;
280     case M32R_OPERAND_IMM1 :
281       errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_IMM1, &fields->f_imm1);
282       break;
283     case M32R_OPERAND_SCR :
284       errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_cr_names, & fields->f_r2);
285       break;
286     case M32R_OPERAND_SIMM16 :
287       errmsg = cgen_parse_signed_integer (cd, strp, M32R_OPERAND_SIMM16, &fields->f_simm16);
288       break;
289     case M32R_OPERAND_SIMM8 :
290       errmsg = cgen_parse_signed_integer (cd, strp, M32R_OPERAND_SIMM8, &fields->f_simm8);
291       break;
292     case M32R_OPERAND_SLO16 :
293       errmsg = parse_slo16 (cd, strp, M32R_OPERAND_SLO16, &fields->f_simm16);
294       break;
295     case M32R_OPERAND_SR :
296       errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r2);
297       break;
298     case M32R_OPERAND_SRC1 :
299       errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r1);
300       break;
301     case M32R_OPERAND_SRC2 :
302       errmsg = cgen_parse_keyword (cd, strp, & m32r_cgen_opval_gr_names, & fields->f_r2);
303       break;
304     case M32R_OPERAND_UIMM16 :
305       errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_UIMM16, &fields->f_uimm16);
306       break;
307     case M32R_OPERAND_UIMM24 :
308       {
309         bfd_vma value;
310         errmsg = cgen_parse_address (cd, strp, M32R_OPERAND_UIMM24, 0, NULL,  & value);
311         fields->f_uimm24 = value;
312       }
313       break;
314     case M32R_OPERAND_UIMM4 :
315       errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_UIMM4, &fields->f_uimm4);
316       break;
317     case M32R_OPERAND_UIMM5 :
318       errmsg = cgen_parse_unsigned_integer (cd, strp, M32R_OPERAND_UIMM5, &fields->f_uimm5);
319       break;
320     case M32R_OPERAND_ULO16 :
321       errmsg = parse_ulo16 (cd, strp, M32R_OPERAND_ULO16, &fields->f_uimm16);
322       break;
323
324     default :
325       /* xgettext:c-format */
326       fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
327       abort ();
328   }
329
330   return errmsg;
331 }
332
333 cgen_parse_fn * const m32r_cgen_parse_handlers[] = 
334 {
335   parse_insn_normal,
336 };
337
338 void
339 m32r_cgen_init_asm (cd)
340      CGEN_CPU_DESC cd;
341 {
342   m32r_cgen_init_opcode_table (cd);
343   m32r_cgen_init_ibld_table (cd);
344   cd->parse_handlers = & m32r_cgen_parse_handlers[0];
345   cd->parse_operand = m32r_cgen_parse_operand;
346 }
347
348 \f
349
350 /* Regex construction routine.
351
352    This translates an opcode syntax string into a regex string,
353    by replacing any non-character syntax element (such as an
354    opcode) with the pattern '.*'
355
356    It then compiles the regex and stores it in the opcode, for
357    later use by m32r_cgen_assemble_insn
358
359    Returns NULL for success, an error message for failure.  */
360
361 char * 
362 m32r_cgen_build_insn_regex (insn)
363      CGEN_INSN *insn;
364 {  
365   CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
366   const char *mnem = CGEN_INSN_MNEMONIC (insn);
367   char rxbuf[CGEN_MAX_RX_ELEMENTS];
368   char *rx = rxbuf;
369   const CGEN_SYNTAX_CHAR_TYPE *syn;
370   int reg_err;
371
372   syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
373
374   /* Mnemonics come first in the syntax string.  */
375   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
376     return _("missing mnemonic in syntax string");
377   ++syn;
378
379   /* Generate a case sensitive regular expression that emulates case
380      insensitive matching in the "C" locale.  We cannot generate a case
381      insensitive regular expression because in Turkish locales, 'i' and 'I'
382      are not equal modulo case conversion.  */
383
384   /* Copy the literal mnemonic out of the insn.  */
385   for (; *mnem; mnem++)
386     {
387       char c = *mnem;
388
389       if (ISALPHA (c))
390         {
391           *rx++ = '[';
392           *rx++ = TOLOWER (c);
393           *rx++ = TOUPPER (c);
394           *rx++ = ']';
395         }
396       else
397         *rx++ = c;
398     }
399
400   /* Copy any remaining literals from the syntax string into the rx.  */
401   for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
402     {
403       if (CGEN_SYNTAX_CHAR_P (* syn)) 
404         {
405           char c = CGEN_SYNTAX_CHAR (* syn);
406
407           switch (c) 
408             {
409               /* Escape any regex metacharacters in the syntax.  */
410             case '.': case '[': case '\\': 
411             case '*': case '^': case '$': 
412
413 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
414             case '?': case '{': case '}': 
415             case '(': case ')': case '*':
416             case '|': case '+': case ']':
417 #endif
418               *rx++ = '\\';
419               *rx++ = c;
420               break;
421
422             default:
423               if (ISALPHA (c))
424                 {
425                   *rx++ = '[';
426                   *rx++ = TOLOWER (c);
427                   *rx++ = TOUPPER (c);
428                   *rx++ = ']';
429                 }
430               else
431                 *rx++ = c;
432               break;
433             }
434         }
435       else
436         {
437           /* Replace non-syntax fields with globs.  */
438           *rx++ = '.';
439           *rx++ = '*';
440         }
441     }
442
443   /* Trailing whitespace ok.  */
444   * rx++ = '['; 
445   * rx++ = ' '; 
446   * rx++ = '\t'; 
447   * rx++ = ']'; 
448   * rx++ = '*'; 
449
450   /* But anchor it after that.  */
451   * rx++ = '$'; 
452   * rx = '\0';
453
454   CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
455   reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
456
457   if (reg_err == 0) 
458     return NULL;
459   else
460     {
461       static char msg[80];
462
463       regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
464       regfree ((regex_t *) CGEN_INSN_RX (insn));
465       free (CGEN_INSN_RX (insn));
466       (CGEN_INSN_RX (insn)) = NULL;
467       return msg;
468     }
469 }
470
471 \f
472 /* Default insn parser.
473
474    The syntax string is scanned and operands are parsed and stored in FIELDS.
475    Relocs are queued as we go via other callbacks.
476
477    ??? Note that this is currently an all-or-nothing parser.  If we fail to
478    parse the instruction, we return 0 and the caller will start over from
479    the beginning.  Backtracking will be necessary in parsing subexpressions,
480    but that can be handled there.  Not handling backtracking here may get
481    expensive in the case of the m68k.  Deal with later.
482
483    Returns NULL for success, an error message for failure.  */
484
485 static const char *
486 parse_insn_normal (cd, insn, strp, fields)
487      CGEN_CPU_DESC cd;
488      const CGEN_INSN *insn;
489      const char **strp;
490      CGEN_FIELDS *fields;
491 {
492   /* ??? Runtime added insns not handled yet.  */
493   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
494   const char *str = *strp;
495   const char *errmsg;
496   const char *p;
497   const CGEN_SYNTAX_CHAR_TYPE * syn;
498 #ifdef CGEN_MNEMONIC_OPERANDS
499   /* FIXME: wip */
500   int past_opcode_p;
501 #endif
502
503   /* For now we assume the mnemonic is first (there are no leading operands).
504      We can parse it without needing to set up operand parsing.
505      GAS's input scrubber will ensure mnemonics are lowercase, but we may
506      not be called from GAS.  */
507   p = CGEN_INSN_MNEMONIC (insn);
508   while (*p && TOLOWER (*p) == TOLOWER (*str))
509     ++p, ++str;
510
511   if (* p)
512     return _("unrecognized instruction");
513
514 #ifndef CGEN_MNEMONIC_OPERANDS
515   if (* str && ! ISSPACE (* str))
516     return _("unrecognized instruction");
517 #endif
518
519   CGEN_INIT_PARSE (cd);
520   cgen_init_parse_operand (cd);
521 #ifdef CGEN_MNEMONIC_OPERANDS
522   past_opcode_p = 0;
523 #endif
524
525   /* We don't check for (*str != '\0') here because we want to parse
526      any trailing fake arguments in the syntax string.  */
527   syn = CGEN_SYNTAX_STRING (syntax);
528
529   /* Mnemonics come first for now, ensure valid string.  */
530   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
531     abort ();
532
533   ++syn;
534
535   while (* syn != 0)
536     {
537       /* Non operand chars must match exactly.  */
538       if (CGEN_SYNTAX_CHAR_P (* syn))
539         {
540           /* FIXME: While we allow for non-GAS callers above, we assume the
541              first char after the mnemonic part is a space.  */
542           /* FIXME: We also take inappropriate advantage of the fact that
543              GAS's input scrubber will remove extraneous blanks.  */
544           if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
545             {
546 #ifdef CGEN_MNEMONIC_OPERANDS
547               if (CGEN_SYNTAX_CHAR(* syn) == ' ')
548                 past_opcode_p = 1;
549 #endif
550               ++ syn;
551               ++ str;
552             }
553           else if (*str)
554             {
555               /* Syntax char didn't match.  Can't be this insn.  */
556               static char msg [80];
557
558               /* xgettext:c-format */
559               sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
560                        CGEN_SYNTAX_CHAR(*syn), *str);
561               return msg;
562             }
563           else
564             {
565               /* Ran out of input.  */
566               static char msg [80];
567
568               /* xgettext:c-format */
569               sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
570                        CGEN_SYNTAX_CHAR(*syn));
571               return msg;
572             }
573           continue;
574         }
575
576       /* We have an operand of some sort.  */
577       errmsg = m32r_cgen_parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
578                                           &str, fields);
579       if (errmsg)
580         return errmsg;
581
582       /* Done with this operand, continue with next one.  */
583       ++ syn;
584     }
585
586   /* If we're at the end of the syntax string, we're done.  */
587   if (* syn == 0)
588     {
589       /* FIXME: For the moment we assume a valid `str' can only contain
590          blanks now.  IE: We needn't try again with a longer version of
591          the insn and it is assumed that longer versions of insns appear
592          before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
593       while (ISSPACE (* str))
594         ++ str;
595
596       if (* str != '\0')
597         return _("junk at end of line"); /* FIXME: would like to include `str' */
598
599       return NULL;
600     }
601
602   /* We couldn't parse it.  */
603   return _("unrecognized instruction");
604 }
605 \f
606 /* Main entry point.
607    This routine is called for each instruction to be assembled.
608    STR points to the insn to be assembled.
609    We assume all necessary tables have been initialized.
610    The assembled instruction, less any fixups, is stored in BUF.
611    Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
612    still needs to be converted to target byte order, otherwise BUF is an array
613    of bytes in target byte order.
614    The result is a pointer to the insn's entry in the opcode table,
615    or NULL if an error occured (an error message will have already been
616    printed).
617
618    Note that when processing (non-alias) macro-insns,
619    this function recurses.
620
621    ??? It's possible to make this cpu-independent.
622    One would have to deal with a few minor things.
623    At this point in time doing so would be more of a curiosity than useful
624    [for example this file isn't _that_ big], but keeping the possibility in
625    mind helps keep the design clean.  */
626
627 const CGEN_INSN *
628 m32r_cgen_assemble_insn (cd, str, fields, buf, errmsg)
629      CGEN_CPU_DESC cd;
630      const char *str;
631      CGEN_FIELDS *fields;
632      CGEN_INSN_BYTES_PTR buf;
633      char **errmsg;
634 {
635   const char *start;
636   CGEN_INSN_LIST *ilist;
637   const char *parse_errmsg = NULL;
638   const char *insert_errmsg = NULL;
639   int recognized_mnemonic = 0;
640
641   /* Skip leading white space.  */
642   while (ISSPACE (* str))
643     ++ str;
644
645   /* The instructions are stored in hashed lists.
646      Get the first in the list.  */
647   ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
648
649   /* Keep looking until we find a match.  */
650   start = str;
651   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
652     {
653       const CGEN_INSN *insn = ilist->insn;
654       recognized_mnemonic = 1;
655
656 #ifdef CGEN_VALIDATE_INSN_SUPPORTED 
657       /* Not usually needed as unsupported opcodes
658          shouldn't be in the hash lists.  */
659       /* Is this insn supported by the selected cpu?  */
660       if (! m32r_cgen_insn_supported (cd, insn))
661         continue;
662 #endif
663       /* If the RELAX attribute is set, this is an insn that shouldn't be
664          chosen immediately.  Instead, it is used during assembler/linker
665          relaxation if possible.  */
666       if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAX) != 0)
667         continue;
668
669       str = start;
670
671       /* Skip this insn if str doesn't look right lexically.  */
672       if (CGEN_INSN_RX (insn) != NULL &&
673           regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
674         continue;
675
676       /* Allow parse/insert handlers to obtain length of insn.  */
677       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
678
679       parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
680       if (parse_errmsg != NULL)
681         continue;
682
683       /* ??? 0 is passed for `pc'.  */
684       insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
685                                                  (bfd_vma) 0);
686       if (insert_errmsg != NULL)
687         continue;
688
689       /* It is up to the caller to actually output the insn and any
690          queued relocs.  */
691       return insn;
692     }
693
694   {
695     static char errbuf[150];
696 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
697     const char *tmp_errmsg;
698
699     /* If requesting verbose error messages, use insert_errmsg.
700        Failing that, use parse_errmsg.  */
701     tmp_errmsg = (insert_errmsg ? insert_errmsg :
702                   parse_errmsg ? parse_errmsg :
703                   recognized_mnemonic ?
704                   _("unrecognized form of instruction") :
705                   _("unrecognized instruction"));
706
707     if (strlen (start) > 50)
708       /* xgettext:c-format */
709       sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
710     else 
711       /* xgettext:c-format */
712       sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
713 #else
714     if (strlen (start) > 50)
715       /* xgettext:c-format */
716       sprintf (errbuf, _("bad instruction `%.50s...'"), start);
717     else 
718       /* xgettext:c-format */
719       sprintf (errbuf, _("bad instruction `%.50s'"), start);
720 #endif
721       
722     *errmsg = errbuf;
723     return NULL;
724   }
725 }
726 \f
727 #if 0 /* This calls back to GAS which we can't do without care.  */
728
729 /* Record each member of OPVALS in the assembler's symbol table.
730    This lets GAS parse registers for us.
731    ??? Interesting idea but not currently used.  */
732
733 /* Record each member of OPVALS in the assembler's symbol table.
734    FIXME: Not currently used.  */
735
736 void
737 m32r_cgen_asm_hash_keywords (cd, opvals)
738      CGEN_CPU_DESC cd;
739      CGEN_KEYWORD *opvals;
740 {
741   CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
742   const CGEN_KEYWORD_ENTRY * ke;
743
744   while ((ke = cgen_keyword_search_next (& search)) != NULL)
745     {
746 #if 0 /* Unnecessary, should be done in the search routine.  */
747       if (! m32r_cgen_opval_supported (ke))
748         continue;
749 #endif
750       cgen_asm_record_register (cd, ke->name, ke->value);
751     }
752 }
753
754 #endif /* 0 */