* fr30-asm.c,fr30-dis.c,fr30-opc.c,fr30-opc.h: Regenerate.
[binutils-gdb.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 */