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