* cgen-asm.in (insert_normal): Use CGEN_BOOL_ATTR.
[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 Foundation, Inc.,
22 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 #undef min
34 #define min(a,b) ((a) < (b) ? (a) : (b))
35 #undef max
36 #define max(a,b) ((a) > (b) ? (a) : (b))
37
38 #undef INLINE
39 #ifdef __GNUC__
40 #define INLINE __inline__
41 #else
42 #define INLINE
43 #endif
44
45 /* Used by the ifield rtx function.  */
46 #define FLD(f) (fields->f)
47
48 static const char * insert_normal
49      PARAMS ((CGEN_OPCODE_DESC, long, unsigned int, unsigned int, unsigned int,
50               unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR));
51 static const char * parse_insn_normal
52      PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *,
53               const char **, CGEN_FIELDS *));
54 static const char * insert_insn_normal
55      PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *,
56               CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
57 \f
58 /* -- assembler routines inserted here */
59 /* -- asm.c */
60
61 /* Handle '#' prefixes (i.e. skip over them).  */
62
63 static const char *
64 parse_hash (od, strp, opindex, valuep)
65      CGEN_OPCODE_DESC od;
66      const char **strp;
67      int opindex;
68      unsigned long *valuep;
69 {
70   if (**strp == '#')
71     ++*strp;
72   return NULL;
73 }
74
75 /* Handle shigh(), high().  */
76
77 static const char *
78 parse_hi16 (od, strp, opindex, valuep)
79      CGEN_OPCODE_DESC od;
80      const char **strp;
81      int opindex;
82      unsigned long *valuep;
83 {
84   const char *errmsg;
85   enum cgen_parse_operand_result result_type;
86   bfd_vma value;
87
88   if (**strp == '#')
89     ++*strp;
90
91   if (strncasecmp (*strp, "high(", 5) == 0)
92     {
93       *strp += 5;
94       errmsg = cgen_parse_address (od, strp, opindex, BFD_RELOC_M32R_HI16_ULO,
95                                    &result_type, &value);
96       if (**strp != ')')
97         return "missing `)'";
98       ++*strp;
99       if (errmsg == NULL
100           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
101         value >>= 16;
102       *valuep = value;
103       return errmsg;
104     }
105   else if (strncasecmp (*strp, "shigh(", 6) == 0)
106     {
107       *strp += 6;
108       errmsg = cgen_parse_address (od, strp, opindex, BFD_RELOC_M32R_HI16_SLO,
109                                    &result_type, &value);
110       if (**strp != ')')
111         return "missing `)'";
112       ++*strp;
113       if (errmsg == NULL
114           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
115         value = (value >> 16) + (value & 0x8000 ? 1 : 0);
116       *valuep = value;
117       return errmsg;
118     }
119
120   return cgen_parse_unsigned_integer (od, strp, opindex, valuep);
121 }
122
123 /* Handle low() in a signed context.  Also handle sda().
124    The signedness of the value doesn't matter to low(), but this also
125    handles the case where low() isn't present.  */
126
127 static const char *
128 parse_slo16 (od, strp, opindex, valuep)
129      CGEN_OPCODE_DESC od;
130      const char **strp;
131      int opindex;
132      long *valuep;
133 {
134   const char *errmsg;
135   enum cgen_parse_operand_result result_type;
136   bfd_vma value;
137
138   if (**strp == '#')
139     ++*strp;
140
141   if (strncasecmp (*strp, "low(", 4) == 0)
142     {
143       *strp += 4;
144       errmsg = cgen_parse_address (od, strp, opindex, BFD_RELOC_M32R_LO16,
145                                    &result_type, &value);
146       if (**strp != ')')
147         return "missing `)'";
148       ++*strp;
149       if (errmsg == NULL
150           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
151         value &= 0xffff;
152       *valuep = value;
153       return errmsg;
154     }
155
156   if (strncasecmp (*strp, "sda(", 4) == 0)
157     {
158       *strp += 4;
159       errmsg = cgen_parse_address (od, strp, opindex, BFD_RELOC_M32R_SDA16,
160                                    NULL, &value);
161       if (**strp != ')')
162         return "missing `)'";
163       ++*strp;
164       *valuep = value;
165       return errmsg;
166     }
167
168   return cgen_parse_signed_integer (od, strp, opindex, valuep);
169 }
170
171 /* Handle low() in an unsigned context.
172    The signedness of the value doesn't matter to low(), but this also
173    handles the case where low() isn't present.  */
174
175 static const char *
176 parse_ulo16 (od, strp, opindex, valuep)
177      CGEN_OPCODE_DESC od;
178      const char **strp;
179      int opindex;
180      unsigned long *valuep;
181 {
182   const char *errmsg;
183   enum cgen_parse_operand_result result_type;
184   bfd_vma value;
185
186   if (**strp == '#')
187     ++*strp;
188
189   if (strncasecmp (*strp, "low(", 4) == 0)
190     {
191       *strp += 4;
192       errmsg = cgen_parse_address (od, strp, opindex, BFD_RELOC_M32R_LO16,
193                                    &result_type, &value);
194       if (**strp != ')')
195         return "missing `)'";
196       ++*strp;
197       if (errmsg == NULL
198           && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
199         value &= 0xffff;
200       *valuep = value;
201       return errmsg;
202     }
203
204   return cgen_parse_unsigned_integer (od, strp, opindex, valuep);
205 }
206
207 /* -- */
208
209 /* Main entry point for operand parsing.
210
211    This function is basically just a big switch statement.  Earlier versions
212    used tables to look up the function to use, but
213    - if the table contains both assembler and disassembler functions then
214      the disassembler contains much of the assembler and vice-versa,
215    - there's a lot of inlining possibilities as things grow,
216    - using a switch statement avoids the function call overhead.
217
218    This function could be moved into `parse_insn_normal', but keeping it
219    separate makes clear the interface between `parse_insn_normal' and each of
220    the handlers.
221 */
222
223 const char *
224 m32r_cgen_parse_operand (od, opindex, strp, fields)
225      CGEN_OPCODE_DESC od;
226      int opindex;
227      const char ** strp;
228      CGEN_FIELDS * fields;
229 {
230   const char * errmsg;
231
232   switch (opindex)
233     {
234     case M32R_OPERAND_SR :
235       errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_gr, & fields->f_r2);
236       break;
237     case M32R_OPERAND_DR :
238       errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_gr, & fields->f_r1);
239       break;
240     case M32R_OPERAND_SRC1 :
241       errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_gr, & fields->f_r1);
242       break;
243     case M32R_OPERAND_SRC2 :
244       errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_gr, & fields->f_r2);
245       break;
246     case M32R_OPERAND_SCR :
247       errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_cr, & fields->f_r2);
248       break;
249     case M32R_OPERAND_DCR :
250       errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_cr, & fields->f_r1);
251       break;
252     case M32R_OPERAND_SIMM8 :
253       errmsg = cgen_parse_signed_integer (od, strp, M32R_OPERAND_SIMM8, &fields->f_simm8);
254       break;
255     case M32R_OPERAND_SIMM16 :
256       errmsg = cgen_parse_signed_integer (od, strp, M32R_OPERAND_SIMM16, &fields->f_simm16);
257       break;
258     case M32R_OPERAND_UIMM4 :
259       errmsg = cgen_parse_unsigned_integer (od, strp, M32R_OPERAND_UIMM4, &fields->f_uimm4);
260       break;
261     case M32R_OPERAND_UIMM5 :
262       errmsg = cgen_parse_unsigned_integer (od, strp, M32R_OPERAND_UIMM5, &fields->f_uimm5);
263       break;
264     case M32R_OPERAND_UIMM16 :
265       errmsg = cgen_parse_unsigned_integer (od, strp, M32R_OPERAND_UIMM16, &fields->f_uimm16);
266       break;
267 /* start-sanitize-m32rx */
268     case M32R_OPERAND_IMM1 :
269       errmsg = cgen_parse_unsigned_integer (od, strp, M32R_OPERAND_IMM1, &fields->f_imm1);
270       break;
271 /* end-sanitize-m32rx */
272 /* start-sanitize-m32rx */
273     case M32R_OPERAND_ACCD :
274       errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_accums, & fields->f_accd);
275       break;
276 /* end-sanitize-m32rx */
277 /* start-sanitize-m32rx */
278     case M32R_OPERAND_ACCS :
279       errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_accums, & fields->f_accs);
280       break;
281 /* end-sanitize-m32rx */
282 /* start-sanitize-m32rx */
283     case M32R_OPERAND_ACC :
284       errmsg = cgen_parse_keyword (od, strp, & m32r_cgen_opval_h_accums, & fields->f_acc);
285       break;
286 /* end-sanitize-m32rx */
287     case M32R_OPERAND_HASH :
288       errmsg = parse_hash (od, strp, M32R_OPERAND_HASH, &fields->f_nil);
289       break;
290     case M32R_OPERAND_HI16 :
291       errmsg = parse_hi16 (od, strp, M32R_OPERAND_HI16, &fields->f_hi16);
292       break;
293     case M32R_OPERAND_SLO16 :
294       errmsg = parse_slo16 (od, strp, M32R_OPERAND_SLO16, &fields->f_simm16);
295       break;
296     case M32R_OPERAND_ULO16 :
297       errmsg = parse_ulo16 (od, strp, M32R_OPERAND_ULO16, &fields->f_uimm16);
298       break;
299     case M32R_OPERAND_UIMM24 :
300       {
301         bfd_vma value;
302         errmsg = cgen_parse_address (od, strp, M32R_OPERAND_UIMM24, 0, NULL,  & value);
303         fields->f_uimm24 = value;
304       }
305       break;
306     case M32R_OPERAND_DISP8 :
307       {
308         bfd_vma value;
309         errmsg = cgen_parse_address (od, strp, M32R_OPERAND_DISP8, 0, NULL,  & value);
310         fields->f_disp8 = value;
311       }
312       break;
313     case M32R_OPERAND_DISP16 :
314       {
315         bfd_vma value;
316         errmsg = cgen_parse_address (od, strp, M32R_OPERAND_DISP16, 0, NULL,  & value);
317         fields->f_disp16 = value;
318       }
319       break;
320     case M32R_OPERAND_DISP24 :
321       {
322         bfd_vma value;
323         errmsg = cgen_parse_address (od, strp, M32R_OPERAND_DISP24, 0, NULL,  & value);
324         fields->f_disp24 = value;
325       }
326       break;
327
328     default :
329       /* xgettext:c-format */
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 const char *
353 m32r_cgen_insert_operand (od, opindex, fields, buffer, pc)
354      CGEN_OPCODE_DESC od;
355      int opindex;
356      CGEN_FIELDS * fields;
357      CGEN_INSN_BYTES_PTR buffer;
358      bfd_vma pc;
359 {
360   const char * errmsg;
361   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
362
363   switch (opindex)
364     {
365     case M32R_OPERAND_SR :
366       errmsg = insert_normal (od, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, buffer);
367       break;
368     case M32R_OPERAND_DR :
369       errmsg = insert_normal (od, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 32, total_length, buffer);
370       break;
371     case M32R_OPERAND_SRC1 :
372       errmsg = insert_normal (od, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 32, total_length, buffer);
373       break;
374     case M32R_OPERAND_SRC2 :
375       errmsg = insert_normal (od, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, buffer);
376       break;
377     case M32R_OPERAND_SCR :
378       errmsg = insert_normal (od, fields->f_r2, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, buffer);
379       break;
380     case M32R_OPERAND_DCR :
381       errmsg = insert_normal (od, fields->f_r1, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 4, 32, total_length, buffer);
382       break;
383     case M32R_OPERAND_SIMM8 :
384       errmsg = insert_normal (od, fields->f_simm8, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 8, 8, 32, total_length, buffer);
385       break;
386     case M32R_OPERAND_SIMM16 :
387       errmsg = insert_normal (od, fields->f_simm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX), 0, 16, 16, 32, total_length, buffer);
388       break;
389     case M32R_OPERAND_UIMM4 :
390       errmsg = insert_normal (od, fields->f_uimm4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 4, 32, total_length, buffer);
391       break;
392     case M32R_OPERAND_UIMM5 :
393       errmsg = insert_normal (od, fields->f_uimm5, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 11, 5, 32, total_length, buffer);
394       break;
395     case M32R_OPERAND_UIMM16 :
396       errmsg = insert_normal (od, fields->f_uimm16, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 16, 16, 32, total_length, buffer);
397       break;
398 /* start-sanitize-m32rx */
399     case M32R_OPERAND_IMM1 :
400       {
401         long value = fields->f_imm1;
402         value = ((value) - (1));
403         errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 0, 15, 1, 32, total_length, buffer);
404       }
405       break;
406 /* end-sanitize-m32rx */
407 /* start-sanitize-m32rx */
408     case M32R_OPERAND_ACCD :
409       errmsg = insert_normal (od, fields->f_accd, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 4, 2, 32, total_length, buffer);
410       break;
411 /* end-sanitize-m32rx */
412 /* start-sanitize-m32rx */
413     case M32R_OPERAND_ACCS :
414       errmsg = insert_normal (od, fields->f_accs, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 12, 2, 32, total_length, buffer);
415       break;
416 /* end-sanitize-m32rx */
417 /* start-sanitize-m32rx */
418     case M32R_OPERAND_ACC :
419       errmsg = insert_normal (od, fields->f_acc, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 1, 32, total_length, buffer);
420       break;
421 /* end-sanitize-m32rx */
422     case M32R_OPERAND_HASH :
423       errmsg = insert_normal (od, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer);
424       break;
425     case M32R_OPERAND_HI16 :
426       errmsg = insert_normal (od, fields->f_hi16, 0|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 0, 16, 16, 32, total_length, buffer);
427       break;
428     case M32R_OPERAND_SLO16 :
429       errmsg = insert_normal (od, fields->f_simm16, 0, 0, 16, 16, 32, total_length, buffer);
430       break;
431     case M32R_OPERAND_ULO16 :
432       errmsg = insert_normal (od, fields->f_uimm16, 0|(1<<CGEN_OPERAND_UNSIGNED), 0, 16, 16, 32, total_length, buffer);
433       break;
434     case M32R_OPERAND_UIMM24 :
435       errmsg = insert_normal (od, fields->f_uimm24, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_UNSIGNED), 0, 8, 24, 32, total_length, buffer);
436       break;
437     case M32R_OPERAND_DISP8 :
438       {
439         long value = fields->f_disp8;
440         value = ((int) (((value) - (((pc) & (-4))))) >> (2));
441         errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 8, 32, total_length, buffer);
442       }
443       break;
444     case M32R_OPERAND_DISP16 :
445       {
446         long value = fields->f_disp16;
447         value = ((int) (((value) - (pc))) >> (2));
448         errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 16, 16, 32, total_length, buffer);
449       }
450       break;
451     case M32R_OPERAND_DISP24 :
452       {
453         long value = fields->f_disp24;
454         value = ((int) (((value) - (pc))) >> (2));
455         errmsg = insert_normal (od, value, 0|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR), 0, 8, 24, 32, total_length, buffer);
456       }
457       break;
458
459     default :
460       /* xgettext:c-format */
461       fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
462                opindex);
463       abort ();
464   }
465
466   return errmsg;
467 }
468
469 cgen_parse_fn * const m32r_cgen_parse_handlers[] = 
470 {
471   0, /* default */
472   parse_insn_normal,
473 };
474
475 cgen_insert_fn * const m32r_cgen_insert_handlers[] = 
476 {
477   0, /* default */
478   insert_insn_normal,
479 };
480
481 void
482 m32r_cgen_init_asm (od)
483      CGEN_OPCODE_DESC od;
484 {
485 }
486
487 \f
488 #if ! CGEN_INT_INSN_P
489
490 /* Subroutine of insert_normal.  */
491
492 static INLINE void
493 insert_1 (od, value, start, length, word_length, bufp)
494      CGEN_OPCODE_DESC od;
495      unsigned long value;
496      int start,length,word_length;
497      unsigned char *bufp;
498 {
499   unsigned long x,mask;
500   int shift;
501   int big_p = CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG;
502
503   switch (word_length)
504     {
505     case 8:
506       x = *bufp;
507       break;
508     case 16:
509       if (big_p)
510         x = bfd_getb16 (bufp);
511       else
512         x = bfd_getl16 (bufp);
513       break;
514     case 24:
515       /* ??? This may need reworking as these cases don't necessarily
516          want the first byte and the last two bytes handled like this.  */
517       if (big_p)
518         x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
519       else
520         x = bfd_getl16 (bufp) | (bufp[2] << 16);
521       break;
522     case 32:
523       if (big_p)
524         x = bfd_getb32 (bufp);
525       else
526         x = bfd_getl32 (bufp);
527       break;
528     default :
529       abort ();
530     }
531
532   /* Written this way to avoid undefined behaviour.  */
533   mask = (((1L << (length - 1)) - 1) << 1) | 1;
534   if (CGEN_INSN_LSB0_P)
535     shift = (start + 1) - length;
536   else
537     shift = (word_length - (start + length));
538   x = (x & ~(mask << shift)) | ((value & mask) << shift);
539
540   switch (word_length)
541     {
542     case 8:
543       *bufp = x;
544       break;
545     case 16:
546       if (big_p)
547         bfd_putb16 (x, bufp);
548       else
549         bfd_putl16 (x, bufp);
550       break;
551     case 24:
552       /* ??? This may need reworking as these cases don't necessarily
553          want the first byte and the last two bytes handled like this.  */
554       if (big_p)
555         {
556           bufp[0] = x >> 16;
557           bfd_putb16 (x, bufp + 1);
558         }
559       else
560         {
561           bfd_putl16 (x, bufp);
562           bufp[2] = x >> 16;
563         }
564       break;
565     case 32:
566       if (big_p)
567         bfd_putb32 (x, bufp);
568       else
569         bfd_putl32 (x, bufp);
570       break;
571     default :
572       abort ();
573     }
574 }
575
576 #endif /* ! CGEN_INT_INSN_P */
577
578 /* Default insertion routine.
579
580    ATTRS is a mask of the boolean attributes.
581    WORD_OFFSET is the offset in bits from the start of the insn of the value.
582    WORD_LENGTH is the length of the word in bits in which the value resides.
583    START is the starting bit number in the word, architecture origin.
584    LENGTH is the length of VALUE in bits.
585    TOTAL_LENGTH is the total length of the insn in bits.
586
587    The result is an error message or NULL if success.  */
588
589 /* ??? This duplicates functionality with bfd's howto table and
590    bfd_install_relocation.  */
591 /* ??? This doesn't handle bfd_vma's.  Create another function when
592    necessary.  */
593
594 static const char *
595 insert_normal (od, value, attrs, word_offset, start, length, word_length,
596                total_length, buffer)
597      CGEN_OPCODE_DESC od;
598      long value;
599      unsigned int attrs;
600      unsigned int word_offset, start, length, word_length, total_length;
601      CGEN_INSN_BYTES_PTR buffer;
602 {
603   static char errbuf[100];
604   /* Written this way to avoid undefined behaviour.  */
605   unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
606
607   /* If LENGTH is zero, this operand doesn't contribute to the value.  */
608   if (length == 0)
609     return NULL;
610
611   if (CGEN_INT_INSN_P
612       && word_offset != 0)
613     abort ();
614
615   if (word_length > 32)
616     abort ();
617
618   /* For architectures with insns smaller than the insn-base-bitsize,
619      word_length may be too big.  */
620 #if CGEN_MIN_INSN_BITSIZE < CGEN_BASE_INSN_BITSIZE
621   if (word_offset == 0
622       && word_length > total_length)
623     word_length = total_length;
624 #endif
625
626   /* Ensure VALUE will fit.  */
627   if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED))
628     {
629       unsigned long maxval = mask;
630       if ((unsigned long) value > maxval)
631         {
632           /* xgettext:c-format */
633           sprintf (errbuf,
634                    _("operand out of range (%lu not between 0 and %lu)"),
635                    value, maxval);
636           return errbuf;
637         }
638     }
639   else
640     {
641       long minval = - (1L << (length - 1));
642       long maxval = (1L << (length - 1)) - 1;
643       if (value < minval || value > maxval)
644         {
645           sprintf
646             /* xgettext:c-format */
647             (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
648              value, minval, maxval);
649           return errbuf;
650         }
651     }
652
653 #if CGEN_INT_INSN_P
654
655   {
656     int shift;
657
658     if (CGEN_INSN_LSB0_P)
659       shift = (start + 1) - length;
660     else
661       shift = word_length - (start + length);
662     *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
663   }
664
665 #else /* ! CGEN_INT_INSN_P */
666
667   {
668     unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
669
670     insert_1 (od, value, start, length, word_length, bufp);
671   }
672
673 #endif /* ! CGEN_INT_INSN_P */
674
675   return NULL;
676 }
677 \f
678 /* Default insn parser.
679
680    The syntax string is scanned and operands are parsed and stored in FIELDS.
681    Relocs are queued as we go via other callbacks.
682
683    ??? Note that this is currently an all-or-nothing parser.  If we fail to
684    parse the instruction, we return 0 and the caller will start over from
685    the beginning.  Backtracking will be necessary in parsing subexpressions,
686    but that can be handled there.  Not handling backtracking here may get
687    expensive in the case of the m68k.  Deal with later.
688
689    Returns NULL for success, an error message for failure.
690 */
691
692 static const char *
693 parse_insn_normal (od, insn, strp, fields)
694      CGEN_OPCODE_DESC od;
695      const CGEN_INSN * insn;
696      const char ** strp;
697      CGEN_FIELDS * fields;
698 {
699   const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
700   const char * str = *strp;
701   const char * errmsg;
702   const char * p;
703   const unsigned char * syn;
704 #ifdef CGEN_MNEMONIC_OPERANDS
705   /* FIXME: wip */
706   int past_opcode_p;
707 #endif
708
709   /* For now we assume the mnemonic is first (there are no leading operands).
710      We can parse it without needing to set up operand parsing.
711      GAS's input scrubber will ensure mnemonics are lowercase, but we may
712      not be called from GAS.  */
713   p = CGEN_INSN_MNEMONIC (insn);
714   while (*p && tolower (*p) == tolower (*str))
715     ++p, ++str;
716   
717   if (* p || (* str && !isspace (* str)))
718     return _("unrecognized instruction");
719
720   CGEN_INIT_PARSE (od);
721   cgen_init_parse_operand (od);
722 #ifdef CGEN_MNEMONIC_OPERANDS
723   past_opcode_p = 0;
724 #endif
725
726   /* We don't check for (*str != '\0') here because we want to parse
727      any trailing fake arguments in the syntax string.  */
728   syn = CGEN_SYNTAX_STRING (syntax);
729
730   /* Mnemonics come first for now, ensure valid string.  */
731   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
732     abort ();
733
734   ++syn;
735
736   while (* syn != 0)
737     {
738       /* Non operand chars must match exactly.  */
739       if (CGEN_SYNTAX_CHAR_P (* syn))
740         {
741           if (*str == CGEN_SYNTAX_CHAR (* syn))
742             {
743 #ifdef CGEN_MNEMONIC_OPERANDS
744               if (* syn == ' ')
745                 past_opcode_p = 1;
746 #endif
747               ++ syn;
748               ++ str;
749             }
750           else
751             {
752               /* Syntax char didn't match.  Can't be this insn.  */
753               /* FIXME: would like to return something like
754                  "expected char `c'" */
755               return _("syntax error");
756             }
757           continue;
758         }
759
760       /* We have an operand of some sort.  */
761       errmsg = m32r_cgen_parse_operand (od, CGEN_SYNTAX_FIELD (*syn),
762                                           &str, fields);
763       if (errmsg)
764         return errmsg;
765
766       /* Done with this operand, continue with next one.  */
767       ++ syn;
768     }
769
770   /* If we're at the end of the syntax string, we're done.  */
771   if (* syn == '\0')
772     {
773       /* FIXME: For the moment we assume a valid `str' can only contain
774          blanks now.  IE: We needn't try again with a longer version of
775          the insn and it is assumed that longer versions of insns appear
776          before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
777       while (isspace (* str))
778         ++ str;
779
780       if (* str != '\0')
781         return _("junk at end of line"); /* FIXME: would like to include `str' */
782
783       return NULL;
784     }
785
786   /* We couldn't parse it.  */
787   return _("unrecognized instruction");
788 }
789
790 /* Default insn builder (insert handler).
791    The instruction is recorded in CGEN_INT_INSN_P byte order
792    (meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
793    recorded in host byte order, otherwise BUFFER is an array of bytes and the
794    value is recorded in target byte order).
795    The result is an error message or NULL if success.  */
796
797 static const char *
798 insert_insn_normal (od, insn, fields, buffer, pc)
799      CGEN_OPCODE_DESC od;
800      const CGEN_INSN * insn;
801      CGEN_FIELDS * fields;
802      CGEN_INSN_BYTES_PTR buffer;
803      bfd_vma pc;
804 {
805   const CGEN_SYNTAX * syntax = CGEN_INSN_SYNTAX (insn);
806   unsigned long value;
807   const unsigned char * syn;
808
809   CGEN_INIT_INSERT (od);
810   value = CGEN_INSN_BASE_VALUE (insn);
811
812   /* If we're recording insns as numbers (rather than a string of bytes),
813      target byte order handling is deferred until later.  */
814
815 #if CGEN_INT_INSN_P
816
817   *buffer = value;
818
819 #else
820
821   cgen_put_insn_value (od, buffer, min (CGEN_BASE_INSN_BITSIZE,
822                                         CGEN_FIELDS_BITSIZE (fields)),
823                        value);
824
825 #endif /* ! CGEN_INT_INSN_P */
826
827   /* ??? It would be better to scan the format's fields.
828      Still need to be able to insert a value based on the operand though;
829      e.g. storing a branch displacement that got resolved later.
830      Needs more thought first.  */
831
832   for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
833     {
834       const char *errmsg;
835
836       if (CGEN_SYNTAX_CHAR_P (* syn))
837         continue;
838
839       errmsg = m32r_cgen_insert_operand (od, CGEN_SYNTAX_FIELD (*syn),
840                                            fields, buffer, pc);
841       if (errmsg)
842         return errmsg;
843     }
844
845   return NULL;
846 }
847 \f
848 /* Main entry point.
849    This routine is called for each instruction to be assembled.
850    STR points to the insn to be assembled.
851    We assume all necessary tables have been initialized.
852    The assembled instruction, less any fixups, is stored in BUF.
853    Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
854    still needs to be converted to target byte order, otherwise BUF is an array
855    of bytes in target byte order.
856    The result is a pointer to the insn's entry in the opcode table,
857    or NULL if an error occured (an error message will have already been
858    printed).
859
860    Note that when processing (non-alias) macro-insns,
861    this function recurses.  */
862
863 const CGEN_INSN *
864 m32r_cgen_assemble_insn (od, str, fields, buf, errmsg)
865      CGEN_OPCODE_DESC od;
866      const char * str;
867      CGEN_FIELDS * fields;
868      CGEN_INSN_BYTES_PTR buf;
869      char ** errmsg;
870 {
871   const char * start;
872   CGEN_INSN_LIST * ilist;
873
874   /* Skip leading white space.  */
875   while (isspace (* str))
876     ++ str;
877
878   /* The instructions are stored in hashed lists.
879      Get the first in the list.  */
880   ilist = CGEN_ASM_LOOKUP_INSN (od, str);
881
882   /* Keep looking until we find a match.  */
883
884   start = str;
885   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
886     {
887       const CGEN_INSN *insn = ilist->insn;
888
889 #if 0 /* not needed as unsupported opcodes shouldn't be in the hash lists */
890       /* Is this insn supported by the selected cpu?  */
891       if (! m32r_cgen_insn_supported (od, insn))
892         continue;
893 #endif
894
895       /* If the RELAX attribute is set, this is an insn that shouldn't be
896          chosen immediately.  Instead, it is used during assembler/linker
897          relaxation if possible.  */
898       if (CGEN_INSN_ATTR (insn, CGEN_INSN_RELAX) != 0)
899         continue;
900
901       str = start;
902
903       /* Allow parse/insert handlers to obtain length of insn.  */
904       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
905
906       if (! CGEN_PARSE_FN (insn) (od, insn, & str, fields))
907         {
908           /* ??? 0 is passed for `pc' */
909           if (CGEN_INSERT_FN (insn) (od, insn, fields, buf, (bfd_vma) 0) != NULL)
910             continue;
911           /* It is up to the caller to actually output the insn and any
912              queued relocs.  */
913           return insn;
914         }
915
916       /* Try the next entry.  */
917     }
918
919   /* FIXME: We can return a better error message than this.
920      Need to track why it failed and pick the right one.  */
921   {
922     static char errbuf[100];
923     if (strlen (start) > 50)
924       /* xgettext:c-format */
925       sprintf (errbuf, _("bad instruction `%.50s...'"), start);
926     else 
927       /* xgettext:c-format */
928       sprintf (errbuf, _("bad instruction `%.50s'"), start);
929       
930     *errmsg = errbuf;
931     return NULL;
932   }
933 }
934 \f
935 #if 0 /* This calls back to GAS which we can't do without care.  */
936
937 /* Record each member of OPVALS in the assembler's symbol table.
938    This lets GAS parse registers for us.
939    ??? Interesting idea but not currently used.  */
940
941 /* Record each member of OPVALS in the assembler's symbol table.
942    FIXME: Not currently used.  */
943
944 void
945 m32r_cgen_asm_hash_keywords (od, opvals)
946      CGEN_OPCODE_DESC od;
947      CGEN_KEYWORD * opvals;
948 {
949   CGEN_KEYWORD_SEARCH search = cgen_keyword_search_init (opvals, NULL);
950   const CGEN_KEYWORD_ENTRY * ke;
951
952   while ((ke = cgen_keyword_search_next (& search)) != NULL)
953     {
954 #if 0 /* Unnecessary, should be done in the search routine.  */
955       if (! m32r_cgen_opval_supported (ke))
956         continue;
957 #endif
958       cgen_asm_record_register (od, ke->name, ke->value);
959     }
960 }
961
962 #endif /* 0 */