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