* cgen-asm.in (insert_normal): Handle empty fields and 64 bit hosts.
[platform/upstream/binutils.git] / opcodes / m32r-asm.c
1 /* Assembler interface for targets using CGEN. -*- C -*-
2    CGEN: Cpu tools GENerator
3
4 This file is used to generate m32r-asm.c.
5
6 Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
7
8 This file is part of the GNU Binutils and GDB, the GNU debugger.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
23
24 #include "sysdep.h"
25 #include <ctype.h>
26 #include <stdio.h>
27 #include "ansidecl.h"
28 #include "bfd.h"
29 #include "symcat.h"
30 #include "m32r-opc.h"
31 #include "opintl.h"
32
33 /* ??? The layout of this stuff is still work in progress.
34    For speed in assembly/disassembly, we use inline functions.  That of course
35    will only work for GCC.  When this stuff is finished, we can decide whether
36    to keep the inline functions (and only get the performance increase when
37    compiled with GCC), or switch to macros, or use something else.
38 */
39
40 static const char * insert_normal
41      PARAMS ((long, unsigned int, int, int, int, char *));
42 static const char * parse_insn_normal
43      PARAMS ((const CGEN_INSN *, const char **, CGEN_FIELDS *));
44 static const char * insert_insn_normal
45      PARAMS ((const CGEN_INSN *, CGEN_FIELDS *, cgen_insn_t *));
46 \f
47 /* -- assembler routines inserted here */
48 /* -- asm.c */
49
50 /* Handle '#' prefixes (i.e. skip over them).  */
51
52 static const char *
53 parse_hash (strp, opindex, valuep)
54      const char **strp;
55      int opindex;
56      unsigned long *valuep;
57 {
58   if (**strp == '#')
59     ++*strp;
60   return NULL;
61 }
62
63 /* Handle shigh(), high().  */
64
65 static const char *
66 parse_hi16 (strp, opindex, valuep)
67      const char **strp;
68      int opindex;
69      unsigned long *valuep;
70 {
71   const char *errmsg;
72   enum cgen_parse_operand_result result_type;
73
74   if (**strp == '#')
75     ++*strp;
76
77   if (strncasecmp (*strp, "high(", 5) == 0)
78     {
79       *strp += 5;
80       errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_HI16_ULO,
81                                    &result_type, valuep);
82       if (**strp != ')')
83         return "missing `)'";
84       ++*strp;
85       if (errmsg == NULL
86           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
87         *valuep >>= 16;
88       return errmsg;
89     }
90   else if (strncasecmp (*strp, "shigh(", 6) == 0)
91     {
92       *strp += 6;
93       errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_HI16_SLO,
94                                    &result_type, valuep);
95       if (**strp != ')')
96         return "missing `)'";
97       ++*strp;
98       if (errmsg == NULL
99           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
100         *valuep = (*valuep >> 16) + ((*valuep) & 0x8000 ? 1 : 0);
101       return errmsg;
102     }
103
104   return cgen_parse_unsigned_integer (strp, opindex, valuep);
105 }
106
107 /* Handle low() in a signed context.  Also handle sda().
108    The signedness of the value doesn't matter to low(), but this also
109    handles the case where low() isn't present.  */
110
111 static const char *
112 parse_slo16 (strp, opindex, valuep)
113      const char **strp;
114      int opindex;
115      long *valuep;
116 {
117   const char *errmsg;
118   enum cgen_parse_operand_result result_type;
119
120   if (**strp == '#')
121     ++*strp;
122
123   if (strncasecmp (*strp, "low(", 4) == 0)
124     {
125       *strp += 4;
126       errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_LO16,
127                                    &result_type, valuep);
128       if (**strp != ')')
129         return "missing `)'";
130       ++*strp;
131       if (errmsg == NULL
132           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
133         *valuep &= 0xffff;
134       return errmsg;
135     }
136
137   if (strncasecmp (*strp, "sda(", 4) == 0)
138     {
139       *strp += 4;
140       errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_SDA16, NULL, valuep);
141       if (**strp != ')')
142         return "missing `)'";
143       ++*strp;
144       return errmsg;
145     }
146
147   return cgen_parse_signed_integer (strp, opindex, valuep);
148 }
149
150 /* Handle low() in an unsigned context.
151    The signedness of the value doesn't matter to low(), but this also
152    handles the case where low() isn't present.  */
153
154 static const char *
155 parse_ulo16 (strp, opindex, valuep)
156      const char **strp;
157      int opindex;
158      unsigned long *valuep;
159 {
160   const char *errmsg;
161   enum cgen_parse_operand_result result_type;
162
163   if (**strp == '#')
164     ++*strp;
165
166   if (strncasecmp (*strp, "low(", 4) == 0)
167     {
168       *strp += 4;
169       errmsg = cgen_parse_address (strp, opindex, BFD_RELOC_M32R_LO16,
170                                    &result_type, valuep);
171       if (**strp != ')')
172         return "missing `)'";
173       ++*strp;
174       if (errmsg == NULL
175           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
176         *valuep &= 0xffff;
177       return errmsg;
178     }
179
180   return cgen_parse_unsigned_integer (strp, opindex, valuep);
181 }
182
183 /* -- */
184
185 /* Main entry point for operand parsing.
186
187    This function is basically just a big switch statement.  Earlier versions
188    used tables to look up the function to use, but
189    - if the table contains both assembler and disassembler functions then
190      the disassembler contains much of the assembler and vice-versa,
191    - there's a lot of inlining possibilities as things grow,
192    - using a switch statement avoids the function call overhead.
193
194    This function could be moved into `parse_insn_normal', but keeping it
195    separate makes clear the interface between `parse_insn_normal' and each of
196    the handlers.
197 */
198
199 const char *
200 m32r_cgen_parse_operand (opindex, strp, fields)
201      int opindex;
202      const char ** strp;
203      CGEN_FIELDS * fields;
204 {
205   const char * errmsg;
206
207   switch (opindex)
208     {
209     case M32R_OPERAND_SR :
210       errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r2);
211       break;
212     case M32R_OPERAND_DR :
213       errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r1);
214       break;
215     case M32R_OPERAND_SRC1 :
216       errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r1);
217       break;
218     case M32R_OPERAND_SRC2 :
219       errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_gr, & fields->f_r2);
220       break;
221     case M32R_OPERAND_SCR :
222       errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_cr, & fields->f_r2);
223       break;
224     case M32R_OPERAND_DCR :
225       errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_cr, & fields->f_r1);
226       break;
227     case M32R_OPERAND_SIMM8 :
228       errmsg = cgen_parse_signed_integer (strp, M32R_OPERAND_SIMM8, &fields->f_simm8);
229       break;
230     case M32R_OPERAND_SIMM16 :
231       errmsg = cgen_parse_signed_integer (strp, M32R_OPERAND_SIMM16, &fields->f_simm16);
232       break;
233     case M32R_OPERAND_UIMM4 :
234       errmsg = cgen_parse_unsigned_integer (strp, M32R_OPERAND_UIMM4, &fields->f_uimm4);
235       break;
236     case M32R_OPERAND_UIMM5 :
237       errmsg = cgen_parse_unsigned_integer (strp, M32R_OPERAND_UIMM5, &fields->f_uimm5);
238       break;
239     case M32R_OPERAND_UIMM16 :
240       errmsg = cgen_parse_unsigned_integer (strp, M32R_OPERAND_UIMM16, &fields->f_uimm16);
241       break;
242 /* start-sanitize-m32rx */
243     case M32R_OPERAND_IMM1 :
244       errmsg = cgen_parse_unsigned_integer (strp, M32R_OPERAND_IMM1, &fields->f_imm1);
245       break;
246 /* end-sanitize-m32rx */
247 /* start-sanitize-m32rx */
248     case M32R_OPERAND_ACCD :
249       errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_accums, & fields->f_accd);
250       break;
251 /* end-sanitize-m32rx */
252 /* start-sanitize-m32rx */
253     case M32R_OPERAND_ACCS :
254       errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_accums, & fields->f_accs);
255       break;
256 /* end-sanitize-m32rx */
257 /* start-sanitize-m32rx */
258     case M32R_OPERAND_ACC :
259       errmsg = cgen_parse_keyword (strp, & m32r_cgen_opval_h_accums, & fields->f_acc);
260       break;
261 /* end-sanitize-m32rx */
262     case M32R_OPERAND_HASH :
263       errmsg = parse_hash (strp, M32R_OPERAND_HASH, &fields->f_nil);
264       break;
265     case M32R_OPERAND_HI16 :
266       errmsg = parse_hi16 (strp, M32R_OPERAND_HI16, &fields->f_hi16);
267       break;
268     case M32R_OPERAND_SLO16 :
269       errmsg = parse_slo16 (strp, M32R_OPERAND_SLO16, &fields->f_simm16);
270       break;
271     case M32R_OPERAND_ULO16 :
272       errmsg = parse_ulo16 (strp, M32R_OPERAND_ULO16, &fields->f_uimm16);
273       break;
274     case M32R_OPERAND_UIMM24 :
275       errmsg = cgen_parse_address (strp, M32R_OPERAND_UIMM24, 0, NULL, & fields->f_uimm24);
276       break;
277     case M32R_OPERAND_DISP8 :
278       errmsg = cgen_parse_address (strp, M32R_OPERAND_DISP8, 0, NULL, & fields->f_disp8);
279       break;
280     case M32R_OPERAND_DISP16 :
281       errmsg = cgen_parse_address (strp, M32R_OPERAND_DISP16, 0, NULL, & fields->f_disp16);
282       break;
283     case M32R_OPERAND_DISP24 :
284       errmsg = cgen_parse_address (strp, M32R_OPERAND_DISP24, 0, NULL, & fields->f_disp24);
285       break;
286
287     default :
288       /* xgettext:c-format */
289       fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
290       abort ();
291   }
292
293   return errmsg;
294 }
295
296 /* Main entry point for operand insertion.
297
298    This function is basically just a big switch statement.  Earlier versions
299    used tables to look up the function to use, but
300    - if the table contains both assembler and disassembler functions then
301      the disassembler contains much of the assembler and vice-versa,
302    - there's a lot of inlining possibilities as things grow,
303    - using a switch statement avoids the function call overhead.
304
305    This function could be moved into `parse_insn_normal', but keeping it
306    separate makes clear the interface between `parse_insn_normal' and each of
307    the handlers.  It's also needed by GAS to insert operands that couldn't be
308    resolved during parsing.
309 */
310
311 const char *
312 m32r_cgen_insert_operand (opindex, fields, buffer)
313      int opindex;
314      CGEN_FIELDS * fields;
315      char * buffer;
316 {
317   const char * errmsg;
318
319   switch (opindex)
320     {
321     case M32R_OPERAND_SR :
322       errmsg = insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
323       break;
324     case M32R_OPERAND_DR :
325       errmsg = insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
326       break;
327     case M32R_OPERAND_SRC1 :
328       errmsg = insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
329       break;
330     case M32R_OPERAND_SRC2 :
331       errmsg = insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
332       break;
333     case M32R_OPERAND_SCR :
334       errmsg = insert_normal (fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
335       break;
336     case M32R_OPERAND_DCR :
337       errmsg = insert_normal (fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
338       break;
339     case M32R_OPERAND_SIMM8 :
340       errmsg = insert_normal (fields->f_simm8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
341       break;
342     case M32R_OPERAND_SIMM16 :
343       errmsg = insert_normal (fields->f_simm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
344       break;
345     case M32R_OPERAND_UIMM4 :
346       errmsg = insert_normal (fields->f_uimm4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), buffer);
347       break;
348     case M32R_OPERAND_UIMM5 :
349       errmsg = insert_normal (fields->f_uimm5, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 11, 5, CGEN_FIELDS_BITSIZE (fields), buffer);
350       break;
351     case M32R_OPERAND_UIMM16 :
352       errmsg = insert_normal (fields->f_uimm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
353       break;
354 /* start-sanitize-m32rx */
355     case M32R_OPERAND_IMM1 :
356       {
357         long value = ((fields->f_imm1) - (1));
358         errmsg = insert_normal (value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 15, 1, CGEN_FIELDS_BITSIZE (fields), buffer);
359       }
360       break;
361 /* end-sanitize-m32rx */
362 /* start-sanitize-m32rx */
363     case M32R_OPERAND_ACCD :
364       errmsg = insert_normal (fields->f_accd, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 2, CGEN_FIELDS_BITSIZE (fields), buffer);
365       break;
366 /* end-sanitize-m32rx */
367 /* start-sanitize-m32rx */
368     case M32R_OPERAND_ACCS :
369       errmsg = insert_normal (fields->f_accs, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 2, CGEN_FIELDS_BITSIZE (fields), buffer);
370       break;
371 /* end-sanitize-m32rx */
372 /* start-sanitize-m32rx */
373     case M32R_OPERAND_ACC :
374       errmsg = insert_normal (fields->f_acc, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 1, CGEN_FIELDS_BITSIZE (fields), buffer);
375       break;
376 /* end-sanitize-m32rx */
377     case M32R_OPERAND_HASH :
378       errmsg = insert_normal (fields->f_nil, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), buffer);
379       break;
380     case M32R_OPERAND_HI16 :
381       errmsg = insert_normal (fields->f_hi16, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
382       break;
383     case M32R_OPERAND_SLO16 :
384       errmsg = insert_normal (fields->f_simm16, 0, 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
385       break;
386     case M32R_OPERAND_ULO16 :
387       errmsg = insert_normal (fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
388       break;
389     case M32R_OPERAND_UIMM24 :
390       errmsg = insert_normal (fields->f_uimm24, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), 8, 24, CGEN_FIELDS_BITSIZE (fields), buffer);
391       break;
392     case M32R_OPERAND_DISP8 :
393       {
394         long value = ((fields->f_disp8) >> (2));
395         errmsg = insert_normal (value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 8, CGEN_FIELDS_BITSIZE (fields), buffer);
396       }
397       break;
398     case M32R_OPERAND_DISP16 :
399       {
400         long value = ((fields->f_disp16) >> (2));
401         errmsg = insert_normal (value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 16, 16, CGEN_FIELDS_BITSIZE (fields), buffer);
402       }
403       break;
404     case M32R_OPERAND_DISP24 :
405       {
406         long value = ((fields->f_disp24) >> (2));
407         errmsg = insert_normal (value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 8, 24, CGEN_FIELDS_BITSIZE (fields), buffer);
408       }
409       break;
410
411     default :
412       /* xgettext:c-format */
413       fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
414                opindex);
415       abort ();
416   }
417
418   return errmsg;
419 }
420
421 cgen_parse_fn * m32r_cgen_parse_handlers[] = 
422 {
423   0, /* default */
424   parse_insn_normal,
425 };
426
427 cgen_insert_fn * m32r_cgen_insert_handlers[] = 
428 {
429   0, /* default */
430   insert_insn_normal,
431 };
432
433 void
434 m32r_cgen_init_asm (mach, endian)
435      int mach;
436      enum cgen_endian endian;
437 {
438   m32r_cgen_init_tables (mach);
439   cgen_set_cpu (& m32r_cgen_opcode_table, mach, endian);
440   cgen_asm_init ();
441 }
442
443 \f
444 /* Default insertion routine.
445
446    ATTRS is a mask of the boolean attributes.
447    LENGTH is the length of VALUE in bits.
448    TOTAL_LENGTH is the total length of the insn (currently 8,16,32).
449
450    The result is an error message or NULL if success.  */
451
452 /* ??? This duplicates functionality with bfd's howto table and
453    bfd_install_relocation.  */
454 /* ??? For architectures where insns can be representable as ints,
455    store insn in `field' struct and add registers, etc. while parsing?  */
456
457 static const char *
458 insert_normal (value, attrs, start, length, total_length, buffer)
459      long value;
460      unsigned int attrs;
461      int start;
462      int length;
463      int total_length;
464      char * buffer;
465 {
466   bfd_vma x;
467   static char buf[100];
468   /* Written this way to avoid undefined behaviour.
469      Yes, `long' will be bfd_vma but not yet.  */
470   long mask = (((1L << (length - 1)) - 1) << 1) | 1;
471
472   /* If LENGTH is zero, this operand doesn't contribute to the value.  */
473   if (length == 0)
474     return NULL;
475
476   /* Ensure VALUE will fit.  */
477   if ((attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED)) != 0)
478     {
479       unsigned long max = mask;
480       if ((unsigned long) value > max)
481         {
482           /* xgettext:c-format */
483           sprintf (buf, _("operand out of range (%lu not between 0 and %lu)"),
484                    value, max);
485           return buf;
486         }
487     }
488   else
489     {
490       long min = - (1L << (length - 1));
491       long max = (1L << (length - 1)) - 1;
492       if (value < min || value > max)
493         {
494           sprintf
495             /* xgettext:c-format */
496             (buf, _("operand out of range (%ld not between %ld and %ld)"),
497              value, min, max);
498           return buf;
499         }
500     }
501
502 #if 0 /*def CGEN_INT_INSN*/
503   *buffer |= (value & mask) << (total_length - (start + length));
504 #else
505   switch (total_length)
506     {
507     case 8:
508       x = * (unsigned char *) buffer;
509       break;
510     case 16:
511       if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
512         x = bfd_getb16 (buffer);
513       else
514         x = bfd_getl16 (buffer);
515       break;
516     case 32:
517       if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
518         x = bfd_getb32 (buffer);
519       else
520         x = bfd_getl32 (buffer);
521       break;
522     default :
523       abort ();
524     }
525
526   x |= (value & mask) << (total_length - (start + length));
527
528   switch (total_length)
529     {
530     case 8:
531       * buffer = value;
532       break;
533     case 16:
534       if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
535         bfd_putb16 (x, buffer);
536       else
537         bfd_putl16 (x, buffer);
538       break;
539     case 32:
540       if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
541         bfd_putb32 (x, buffer);
542       else
543         bfd_putl32 (x, buffer);
544       break;
545     default :
546       abort ();
547     }
548 #endif
549
550   return NULL;
551 }
552 \f
553 /* Default insn parser.
554
555    The syntax string is scanned and operands are parsed and stored in FIELDS.
556    Relocs are queued as we go via other callbacks.
557
558    ??? Note that this is currently an all-or-nothing parser.  If we fail to
559    parse the instruction, we return 0 and the caller will start over from
560    the beginning.  Backtracking will be necessary in parsing subexpressions,
561    but that can be handled there.  Not handling backtracking here may get
562    expensive in the case of the m68k.  Deal with later.
563
564    Returns NULL for success, an error message for failure.
565 */
566
567 static const char *
568 parse_insn_normal (insn, strp, fields)
569      const CGEN_INSN * insn;
570      const char ** strp;
571      CGEN_FIELDS * fields;
572 {
573   const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
574   const char * str = *strp;
575   const char * errmsg;
576   const char * p;
577   const unsigned char * syn;
578 #ifdef CGEN_MNEMONIC_OPERANDS
579   int past_opcode_p;
580 #endif
581
582   /* For now we assume the mnemonic is first (there are no leading operands).
583      We can parse it without needing to set up operand parsing.  */
584   p = CGEN_INSN_MNEMONIC (insn);
585   while (* p && * p == * str)
586     ++ p, ++ str;
587   
588   if (* p || (* str && !isspace (* str)))
589     return _("unrecognized instruction");
590
591   CGEN_INIT_PARSE ();
592   cgen_init_parse_operand ();
593 #ifdef CGEN_MNEMONIC_OPERANDS
594   past_opcode_p = 0;
595 #endif
596
597   /* We don't check for (*str != '\0') here because we want to parse
598      any trailing fake arguments in the syntax string.  */
599   syn = CGEN_SYNTAX_STRING (CGEN_INSN_SYNTAX (insn));
600
601   /* Mnemonics come first for now, ensure valid string.  */
602   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
603     abort ();
604
605   ++syn;
606
607   while (* syn != 0)
608     {
609       /* Non operand chars must match exactly.  */
610       /* FIXME: Need to better handle whitespace.  */
611       if (CGEN_SYNTAX_CHAR_P (* syn))
612         {
613           if (*str == CGEN_SYNTAX_CHAR (* syn))
614             {
615 #ifdef CGEN_MNEMONIC_OPERANDS
616               if (* syn == ' ')
617                 past_opcode_p = 1;
618 #endif
619               ++ syn;
620               ++ str;
621             }
622           else
623             {
624               /* Syntax char didn't match.  Can't be this insn.  */
625               /* FIXME: would like to return something like
626                  "expected char `c'" */
627               return _("syntax error");
628             }
629           continue;
630         }
631
632       /* We have an operand of some sort.  */
633       errmsg = m32r_cgen_parse_operand (CGEN_SYNTAX_FIELD (*syn),
634                                          &str, fields);
635       if (errmsg)
636         return errmsg;
637
638       /* Done with this operand, continue with next one.  */
639       ++ syn;
640     }
641
642   /* If we're at the end of the syntax string, we're done.  */
643   if (* syn == '\0')
644     {
645       /* FIXME: For the moment we assume a valid `str' can only contain
646          blanks now.  IE: We needn't try again with a longer version of
647          the insn and it is assumed that longer versions of insns appear
648          before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
649       while (isspace (* str))
650         ++ str;
651
652       if (* str != '\0')
653         return _("junk at end of line"); /* FIXME: would like to include `str' */
654
655       return NULL;
656     }
657
658   /* We couldn't parse it.  */
659   return "unrecognized instruction";
660 }
661
662 /* Default insn builder (insert handler).
663    The instruction is recorded in target byte order.
664    The result is an error message or NULL if success.  */
665 /* FIXME: change buffer to char *?  */
666
667 static const char *
668 insert_insn_normal (insn, fields, buffer)
669      const CGEN_INSN * insn;
670      CGEN_FIELDS * fields;
671      cgen_insn_t * buffer;
672 {
673   const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
674   bfd_vma value;
675   const unsigned char * syn;
676
677   CGEN_INIT_INSERT ();
678   value = CGEN_INSN_VALUE (insn);
679
680   /* If we're recording insns as numbers (rather than a string of bytes),
681      target byte order handling is deferred until later.  */
682 #undef min
683 #define min(a,b) ((a) < (b) ? (a) : (b))
684 #if 0 /*def CGEN_INT_INSN*/
685   *buffer = value;
686 #else
687   switch (min (CGEN_BASE_INSN_BITSIZE, CGEN_FIELDS_BITSIZE (fields)))
688     {
689     case 8:
690       * buffer = value;
691       break;
692     case 16:
693       if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
694         bfd_putb16 (value, (char *) buffer);
695       else
696         bfd_putl16 (value, (char *) buffer);
697       break;
698     case 32:
699       if (CGEN_CURRENT_ENDIAN == CGEN_ENDIAN_BIG)
700         bfd_putb32 (value, (char *) buffer);
701       else
702         bfd_putl32 (value, (char *) buffer);
703       break;
704     default:
705       abort ();
706     }
707 #endif
708
709   /* ??? Rather than scanning the syntax string again, we could store
710      in `fields' a null terminated list of the fields that are present.  */
711
712   for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
713     {
714       const char *errmsg;
715
716       if (CGEN_SYNTAX_CHAR_P (* syn))
717         continue;
718
719       errmsg = m32r_cgen_insert_operand (CGEN_SYNTAX_FIELD (*syn), fields,
720                                            (char *) buffer);
721       if (errmsg)
722         return errmsg;
723     }
724
725   return NULL;
726 }
727 \f
728 /* Main entry point.
729    This routine is called for each instruction to be assembled.
730    STR points to the insn to be assembled.
731    We assume all necessary tables have been initialized.
732    The assembled instruction, less any fixups, is stored in buf.
733    [??? What byte order?]
734    The result is a pointer to the insn's entry in the opcode table,
735    or NULL if an error occured (an error message will have already been
736    printed).
737
738    Note that when processing (non-alias) macro-insns,
739    this function recurses.  */
740
741 const CGEN_INSN *
742 m32r_cgen_assemble_insn (str, fields, buf, errmsg)
743      const char * str;
744      CGEN_FIELDS * fields;
745      cgen_insn_t * buf;
746      char ** errmsg;
747 {
748   const char * start;
749   CGEN_INSN_LIST * ilist;
750
751   /* Skip leading white space.  */
752   while (isspace (* str))
753     ++ str;
754
755   /* The instructions are stored in hashed lists.
756      Get the first in the list.  */
757   ilist = CGEN_ASM_LOOKUP_INSN (str);
758
759   /* Keep looking until we find a match.  */
760
761   start = str;
762   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
763     {
764       const CGEN_INSN *insn = ilist->insn;
765
766 #if 0 /* not needed as unsupported opcodes shouldn't be in the hash lists */
767       /* Is this insn supported by the selected cpu?  */
768       if (! m32r_cgen_insn_supported (insn))
769         continue;
770 #endif
771
772 #if 1 /* FIXME: wip */
773       /* If the RELAX attribute is set, this is an insn that shouldn't be
774          chosen immediately.  Instead, it is used during assembler/linker
775          relaxation if possible.  */
776       if (CGEN_INSN_ATTR (insn, CGEN_INSN_RELAX) != 0)
777         continue;
778 #endif
779
780       str = start;
781
782       /* Record a default length for the insn.  This will get set to the
783          correct value while parsing.  */
784       /* FIXME: wip */
785       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
786
787       if (! CGEN_PARSE_FN (insn) (insn, & str, fields))
788         {
789           if (CGEN_INSERT_FN (insn) (insn, fields, buf) != NULL)
790             continue;
791           /* It is up to the caller to actually output the insn and any
792              queued relocs.  */
793           return insn;
794         }
795
796       /* Try the next entry.  */
797     }
798
799   /* FIXME: We can return a better error message than this.
800      Need to track why it failed and pick the right one.  */
801   {
802     static char errbuf[100];
803     if (strlen (start) > 50)
804       /* xgettext:c-format */
805       sprintf (errbuf, _("bad instruction `%.50s...'"), start);
806     else 
807       /* xgettext:c-format */
808       sprintf (errbuf, _("bad instruction `%.50s'"), start);
809       
810     *errmsg = errbuf;
811     return NULL;
812   }
813 }
814 \f
815 #if 0 /* This calls back to GAS which we can't do without care.  */
816
817 /* Record each member of OPVALS in the assembler's symbol table.
818    This lets GAS parse registers for us.
819    ??? Interesting idea but not currently used.  */
820
821 /* Record each member of OPVALS in the assembler's symbol table.
822    FIXME: Not currently used.  */
823
824 void
825 m32r_cgen_asm_hash_keywords (opvals)
826      CGEN_KEYWORD * opvals;
827 {
828   CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
829   const CGEN_KEYWORD_ENTRY * ke;
830
831   while ((ke = cgen_keyword_search_next (& search)) != NULL)
832     {
833 #if 0 /* Unnecessary, should be done in the search routine.  */
834       if (! m32r_cgen_opval_supported (ke))
835         continue;
836 #endif
837       cgen_asm_record_register (ke->name, ke->value);
838     }
839 }
840
841 #endif /* 0 */