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