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