*** empty log message ***
[deliverable/binutils-gdb.git] / opcodes / mep-asm.c
1 /* Assembler interface for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
3
4 THIS FILE IS MACHINE GENERATED WITH CGEN.
5 - the resultant file is machine generated, cgen-asm.in isn't
6
7 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2007, 2008
8 Free Software Foundation, Inc.
9
10 This file is part of libopcodes.
11
12 This library is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 3, or (at your option)
15 any later version.
16
17 It is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
20 License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software Foundation, Inc.,
24 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
25
26
27 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
28 Keep that in mind. */
29
30 #include "sysdep.h"
31 #include <stdio.h>
32 #include "ansidecl.h"
33 #include "bfd.h"
34 #include "symcat.h"
35 #include "mep-desc.h"
36 #include "mep-opc.h"
37 #include "opintl.h"
38 #include "xregex.h"
39 #include "libiberty.h"
40 #include "safe-ctype.h"
41
42 #undef min
43 #define min(a,b) ((a) < (b) ? (a) : (b))
44 #undef max
45 #define max(a,b) ((a) > (b) ? (a) : (b))
46
47 static const char * parse_insn_normal
48 (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
49 \f
50 /* -- assembler routines inserted here. */
51
52 /* -- asm.c */
53
54 #include "elf/mep.h"
55
56 #define CGEN_VALIDATE_INSN_SUPPORTED
57
58 const char * parse_csrn (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
59 const char * parse_tpreg (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
60 const char * parse_spreg (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
61 const char * parse_mep_align (CGEN_CPU_DESC, const char **, enum cgen_operand_type, long *);
62 const char * parse_mep_alignu (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
63 static const char * parse_signed16 (CGEN_CPU_DESC, const char **, int, long *);
64 static const char * parse_unsigned16 (CGEN_CPU_DESC, const char **, int, unsigned long *);
65 static const char * parse_lo16 (CGEN_CPU_DESC, const char **, int, long *, long);
66 static const char * parse_unsigned7 (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
67 static const char * parse_zero (CGEN_CPU_DESC, const char **, int, long *);
68
69 const char *
70 parse_csrn (CGEN_CPU_DESC cd, const char **strp,
71 CGEN_KEYWORD *keyword_table, long *field)
72 {
73 const char *err;
74 unsigned long value;
75
76 err = cgen_parse_keyword (cd, strp, keyword_table, field);
77 if (!err)
78 return NULL;
79
80 err = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, & value);
81 if (err)
82 return err;
83 *field = value;
84 return NULL;
85 }
86
87 /* begin-cop-ip-parse-handlers */
88 static const char *
89 parse_ivc2_cr (CGEN_CPU_DESC,
90 const char **,
91 CGEN_KEYWORD *,
92 long *) ATTRIBUTE_UNUSED;
93 static const char *
94 parse_ivc2_cr (CGEN_CPU_DESC cd,
95 const char **strp,
96 CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
97 long *field)
98 {
99 return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr_ivc2, field);
100 }
101 static const char *
102 parse_ivc2_ccr (CGEN_CPU_DESC,
103 const char **,
104 CGEN_KEYWORD *,
105 long *) ATTRIBUTE_UNUSED;
106 static const char *
107 parse_ivc2_ccr (CGEN_CPU_DESC cd,
108 const char **strp,
109 CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
110 long *field)
111 {
112 return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, field);
113 }
114 /* end-cop-ip-parse-handlers */
115
116 const char *
117 parse_tpreg (CGEN_CPU_DESC cd, const char ** strp,
118 CGEN_KEYWORD *keyword_table, long *field)
119 {
120 const char *err;
121
122 err = cgen_parse_keyword (cd, strp, keyword_table, field);
123 if (err)
124 return err;
125 if (*field != 13)
126 return _("Only $tp or $13 allowed for this opcode");
127 return NULL;
128 }
129
130 const char *
131 parse_spreg (CGEN_CPU_DESC cd, const char ** strp,
132 CGEN_KEYWORD *keyword_table, long *field)
133 {
134 const char *err;
135
136 err = cgen_parse_keyword (cd, strp, keyword_table, field);
137 if (err)
138 return err;
139 if (*field != 15)
140 return _("Only $sp or $15 allowed for this opcode");
141 return NULL;
142 }
143
144 const char *
145 parse_mep_align (CGEN_CPU_DESC cd, const char ** strp,
146 enum cgen_operand_type type, long *field)
147 {
148 long lsbs = 0;
149 const char *err;
150
151 switch (type)
152 {
153 case MEP_OPERAND_PCREL8A2:
154 case MEP_OPERAND_PCREL12A2:
155 case MEP_OPERAND_PCREL17A2:
156 case MEP_OPERAND_PCREL24A2:
157 err = cgen_parse_signed_integer (cd, strp, type, field);
158 break;
159 case MEP_OPERAND_PCABS24A2:
160 case MEP_OPERAND_UDISP7:
161 case MEP_OPERAND_UDISP7A2:
162 case MEP_OPERAND_UDISP7A4:
163 case MEP_OPERAND_UIMM7A4:
164 case MEP_OPERAND_ADDR24A4:
165 err = cgen_parse_unsigned_integer (cd, strp, type, (unsigned long *) field);
166 break;
167 default:
168 abort();
169 }
170 if (err)
171 return err;
172 switch (type)
173 {
174 case MEP_OPERAND_UDISP7:
175 lsbs = 0;
176 break;
177 case MEP_OPERAND_PCREL8A2:
178 case MEP_OPERAND_PCREL12A2:
179 case MEP_OPERAND_PCREL17A2:
180 case MEP_OPERAND_PCREL24A2:
181 case MEP_OPERAND_PCABS24A2:
182 case MEP_OPERAND_UDISP7A2:
183 lsbs = *field & 1;
184 break;
185 case MEP_OPERAND_UDISP7A4:
186 case MEP_OPERAND_UIMM7A4:
187 case MEP_OPERAND_ADDR24A4:
188 lsbs = *field & 3;
189 break;
190 lsbs = *field & 7;
191 break;
192 default:
193 /* Safe assumption? */
194 abort ();
195 }
196 if (lsbs)
197 return "Value is not aligned enough";
198 return NULL;
199 }
200
201 const char *
202 parse_mep_alignu (CGEN_CPU_DESC cd, const char ** strp,
203 enum cgen_operand_type type, unsigned long *field)
204 {
205 return parse_mep_align (cd, strp, type, (long *) field);
206 }
207
208
209 /* Handle %lo(), %tpoff(), %sdaoff(), %hi(), and other signed
210 constants in a signed context. */
211
212 static const char *
213 parse_signed16 (CGEN_CPU_DESC cd,
214 const char **strp,
215 int opindex,
216 long *valuep)
217 {
218 return parse_lo16 (cd, strp, opindex, valuep, 1);
219 }
220
221 static const char *
222 parse_lo16 (CGEN_CPU_DESC cd,
223 const char **strp,
224 int opindex,
225 long *valuep,
226 long signedp)
227 {
228 const char *errmsg;
229 enum cgen_parse_operand_result result_type;
230 bfd_vma value;
231
232 if (strncasecmp (*strp, "%lo(", 4) == 0)
233 {
234 *strp += 4;
235 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
236 & result_type, & value);
237 if (**strp != ')')
238 return _("missing `)'");
239 ++*strp;
240 if (errmsg == NULL
241 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
242 value &= 0xffff;
243 if (signedp)
244 *valuep = (long)(short) value;
245 else
246 *valuep = value;
247 return errmsg;
248 }
249
250 if (strncasecmp (*strp, "%hi(", 4) == 0)
251 {
252 *strp += 4;
253 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
254 & result_type, & value);
255 if (**strp != ')')
256 return _("missing `)'");
257 ++*strp;
258 if (errmsg == NULL
259 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
260 value = (value + 0x8000) >> 16;
261 *valuep = value;
262 return errmsg;
263 }
264
265 if (strncasecmp (*strp, "%uhi(", 5) == 0)
266 {
267 *strp += 5;
268 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
269 & result_type, & value);
270 if (**strp != ')')
271 return _("missing `)'");
272 ++*strp;
273 if (errmsg == NULL
274 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
275 value = value >> 16;
276 *valuep = value;
277 return errmsg;
278 }
279
280 if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
281 {
282 *strp += 8;
283 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
284 NULL, & value);
285 if (**strp != ')')
286 return _("missing `)'");
287 ++*strp;
288 *valuep = value;
289 return errmsg;
290 }
291
292 if (strncasecmp (*strp, "%tpoff(", 7) == 0)
293 {
294 *strp += 7;
295 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
296 NULL, & value);
297 if (**strp != ')')
298 return _("missing `)'");
299 ++*strp;
300 *valuep = value;
301 return errmsg;
302 }
303
304 if (**strp == '%')
305 return _("invalid %function() here");
306
307 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
308 }
309
310 static const char *
311 parse_unsigned16 (CGEN_CPU_DESC cd,
312 const char **strp,
313 int opindex,
314 unsigned long *valuep)
315 {
316 return parse_lo16 (cd, strp, opindex, (long *) valuep, 0);
317 }
318
319 /* A special case of parse_signed16 which accepts only the value zero. */
320
321 static const char *
322 parse_zero (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
323 {
324 const char *errmsg;
325 enum cgen_parse_operand_result result_type;
326 bfd_vma value;
327
328 /*fprintf(stderr, "dj: signed parse opindex `%s'\n", *strp);*/
329
330 /* Prevent ($ry) from being attempted as an expression on 'sw $rx,($ry)'.
331 It will fail and cause ry to be listed as an undefined symbol in the
332 listing. */
333 if (strncmp (*strp, "($", 2) == 0)
334 return "not zero"; /* any string will do -- will never be seen. */
335
336 if (strncasecmp (*strp, "%lo(", 4) == 0)
337 {
338 *strp += 4;
339 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
340 &result_type, &value);
341 if (**strp != ')')
342 return "missing `)'";
343 ++*strp;
344 if (errmsg == NULL
345 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
346 return "not zero"; /* any string will do -- will never be seen. */
347 *valuep = value;
348 return errmsg;
349 }
350
351 if (strncasecmp (*strp, "%hi(", 4) == 0)
352 {
353 *strp += 4;
354 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
355 &result_type, &value);
356 if (**strp != ')')
357 return "missing `)'";
358 ++*strp;
359 if (errmsg == NULL
360 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
361 return "not zero"; /* any string will do -- will never be seen. */
362 *valuep = value;
363 return errmsg;
364 }
365
366 if (strncasecmp (*strp, "%uhi(", 5) == 0)
367 {
368 *strp += 5;
369 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
370 &result_type, &value);
371 if (**strp != ')')
372 return "missing `)'";
373 ++*strp;
374 if (errmsg == NULL
375 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
376 return "not zero"; /* any string will do -- will never be seen. */
377 *valuep = value;
378 return errmsg;
379 }
380
381 if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
382 {
383 *strp += 8;
384 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
385 &result_type, &value);
386 if (**strp != ')')
387 return "missing `)'";
388 ++*strp;
389 if (errmsg == NULL
390 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
391 return "not zero"; /* any string will do -- will never be seen. */
392 *valuep = value;
393 return errmsg;
394 }
395
396 if (strncasecmp (*strp, "%tpoff(", 7) == 0)
397 {
398 *strp += 7;
399 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
400 &result_type, &value);
401 if (**strp != ')')
402 return "missing `)'";
403 ++*strp;
404 if (errmsg == NULL
405 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
406 return "not zero"; /* any string will do -- will never be seen. */
407 *valuep = value;
408 return errmsg;
409 }
410
411 if (**strp == '%')
412 return "invalid %function() here";
413
414 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_NONE,
415 &result_type, &value);
416 if (errmsg == NULL
417 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
418 return "not zero"; /* any string will do -- will never be seen. */
419
420 return errmsg;
421 }
422
423 static const char *
424 parse_unsigned7 (CGEN_CPU_DESC cd, const char **strp,
425 enum cgen_operand_type opindex, unsigned long *valuep)
426 {
427 const char *errmsg;
428 bfd_vma value;
429
430 /* fprintf(stderr, "dj: unsigned7 parse `%s'\n", *strp); */
431
432 if (strncasecmp (*strp, "%tpoff(", 7) == 0)
433 {
434 int reloc;
435 *strp += 7;
436 switch (opindex)
437 {
438 case MEP_OPERAND_UDISP7:
439 reloc = BFD_RELOC_MEP_TPREL7;
440 break;
441 case MEP_OPERAND_UDISP7A2:
442 reloc = BFD_RELOC_MEP_TPREL7A2;
443 break;
444 case MEP_OPERAND_UDISP7A4:
445 reloc = BFD_RELOC_MEP_TPREL7A4;
446 break;
447 default:
448 /* Safe assumption? */
449 abort ();
450 }
451 errmsg = cgen_parse_address (cd, strp, opindex, reloc,
452 NULL, &value);
453 if (**strp != ')')
454 return "missing `)'";
455 ++*strp;
456 *valuep = value;
457 return errmsg;
458 }
459
460 if (**strp == '%')
461 return _("invalid %function() here");
462
463 return parse_mep_alignu (cd, strp, opindex, valuep);
464 }
465
466 static ATTRIBUTE_UNUSED const char *
467 parse_cdisp10 (CGEN_CPU_DESC cd,
468 const char **strp,
469 int opindex,
470 long *valuep)
471 {
472 const char *errmsg = 0;
473 signed long value;
474 long have_zero = 0;
475 int wide = 0;
476 int alignment;
477
478 switch (opindex)
479 {
480 case MEP_OPERAND_CDISP10A4:
481 alignment = 2;
482 break;
483 case MEP_OPERAND_CDISP10A2:
484 alignment = 1;
485 break;
486 case MEP_OPERAND_CDISP10:
487 default:
488 alignment = 0;
489 break;
490 }
491
492 if (MEP_CPU == EF_MEP_CPU_C5)
493 wide = 1;
494
495 if (strncmp (*strp, "0x0", 3) == 0
496 || (**strp == '0' && *(*strp + 1) != 'x'))
497 have_zero = 1;
498
499 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
500 if (errmsg)
501 return errmsg;
502
503 if (wide)
504 {
505 if (value < -512 || value > 511)
506 return _("Immediate is out of range -512 to 511");
507 }
508 else
509 {
510 if (value < -128 || value > 127)
511 return _("Immediate is out of range -128 to 127");
512 }
513
514 if (value & ((1<<alignment)-1))
515 return _("Value is not aligned enough");
516
517 /* If this field may require a relocation then use larger dsp16. */
518 if (! have_zero && value == 0)
519 return (wide ? _("Immediate is out of range -512 to 511")
520 : _("Immediate is out of range -128 to 127"));
521
522 *valuep = value;
523 return 0;
524 }
525
526 /* BEGIN LIGHTWEIGHT MACRO PROCESSOR. */
527
528 #define MAXARGS 9
529
530 typedef struct
531 {
532 char *name;
533 char *expansion;
534 } macro;
535
536 typedef struct
537 {
538 const char *start;
539 int len;
540 } arg;
541
542 macro macros[] =
543 {
544 { "sizeof", "(`1.end + (- `1))"},
545 { "startof", "(`1 | 0)" },
546 { "align4", "(`1&(~3))"},
547 /*{ "hi", "(((`1+0x8000)>>16) & 0xffff)" }, */
548 /*{ "lo", "(`1 & 0xffff)" }, */
549 /*{ "sdaoff", "((`1-__sdabase) & 0x7f)"}, */
550 /*{ "tpoff", "((`1-__tpbase) & 0x7f)"}, */
551 { 0,0 }
552 };
553
554 static char * expand_string (const char *, int);
555
556 static const char *
557 mep_cgen_expand_macros_and_parse_operand
558 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
559
560 static char *
561 str_append (char *dest, const char *input, int len)
562 {
563 char *new_dest;
564 int oldlen;
565
566 if (len == 0)
567 return dest;
568 /* printf("str_append: <<%s>>, <<%s>>, %d\n", dest, input, len); */
569 oldlen = (dest ? strlen(dest) : 0);
570 new_dest = realloc (dest, oldlen + len + 1);
571 memset (new_dest + oldlen, 0, len + 1);
572 return strncat (new_dest, input, len);
573 }
574
575 static macro *
576 lookup_macro (const char *name)
577 {
578 macro *m;
579
580 for (m = macros; m->name; ++m)
581 if (strncmp (m->name, name, strlen(m->name)) == 0)
582 return m;
583
584 return 0;
585 }
586
587 static char *
588 expand_macro (arg *args, int narg, macro *mac)
589 {
590 char *result = 0, *rescanned_result = 0;
591 char *e = mac->expansion;
592 char *mark = e;
593 int arg = 0;
594
595 /* printf("expanding macro %s with %d args\n", mac->name, narg + 1); */
596 while (*e)
597 {
598 if (*e == '`' &&
599 (*e+1) &&
600 ((*(e + 1) - '1') <= MAXARGS) &&
601 ((*(e + 1) - '1') <= narg))
602 {
603 result = str_append (result, mark, e - mark);
604 arg = (*(e + 1) - '1');
605 /* printf("replacing `%d with %s\n", arg+1, args[arg].start); */
606 result = str_append (result, args[arg].start, args[arg].len);
607 ++e;
608 mark = e+1;
609 }
610 ++e;
611 }
612
613 if (mark != e)
614 result = str_append (result, mark, e - mark);
615
616 if (result)
617 {
618 rescanned_result = expand_string (result, 0);
619 free (result);
620 return rescanned_result;
621 }
622 else
623 return result;
624 }
625
626 #define IN_TEXT 0
627 #define IN_ARGS 1
628
629 static char *
630 expand_string (const char *in, int first_only)
631 {
632 int num_expansions = 0;
633 int depth = 0;
634 int narg = -1;
635 arg args[MAXARGS];
636 int state = IN_TEXT;
637 const char *mark = in;
638 macro *macro = 0;
639
640 char *expansion = 0;
641 char *result = 0;
642
643 while (*in)
644 {
645 switch (state)
646 {
647 case IN_TEXT:
648 if (*in == '%' && *(in + 1) && (!first_only || num_expansions == 0))
649 {
650 macro = lookup_macro (in + 1);
651 if (macro)
652 {
653 /* printf("entering state %d at '%s'...\n", state, in); */
654 result = str_append (result, mark, in - mark);
655 mark = in;
656 in += 1 + strlen (macro->name);
657 while (*in == ' ') ++in;
658 if (*in != '(')
659 {
660 state = IN_TEXT;
661 macro = 0;
662 }
663 else
664 {
665 state = IN_ARGS;
666 narg = 0;
667 args[narg].start = in + 1;
668 args[narg].len = 0;
669 mark = in + 1;
670 }
671 }
672 }
673 break;
674 case IN_ARGS:
675 if (depth == 0)
676 {
677 switch (*in)
678 {
679 case ',':
680 narg++;
681 args[narg].start = (in + 1);
682 args[narg].len = 0;
683 break;
684 case ')':
685 state = IN_TEXT;
686 /* printf("entering state %d at '%s'...\n", state, in); */
687 if (macro)
688 {
689 expansion = 0;
690 expansion = expand_macro (args, narg, macro);
691 num_expansions++;
692 if (expansion)
693 {
694 result = str_append (result, expansion, strlen (expansion));
695 free (expansion);
696 }
697 }
698 else
699 {
700 result = str_append (result, mark, in - mark);
701 }
702 macro = 0;
703 mark = in + 1;
704 break;
705 case '(':
706 depth++;
707 default:
708 args[narg].len++;
709 break;
710 }
711 }
712 else
713 {
714 if (*in == ')')
715 depth--;
716 if (narg > -1)
717 args[narg].len++;
718 }
719
720 }
721 ++in;
722 }
723
724 if (mark != in)
725 result = str_append (result, mark, in - mark);
726
727 return result;
728 }
729
730 #undef IN_ARGS
731 #undef IN_TEXT
732 #undef MAXARGS
733
734
735 /* END LIGHTWEIGHT MACRO PROCESSOR. */
736
737 const char * mep_cgen_parse_operand
738 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
739
740 const char *
741 mep_cgen_expand_macros_and_parse_operand (CGEN_CPU_DESC cd, int opindex,
742 const char ** strp_in, CGEN_FIELDS * fields)
743 {
744 const char * errmsg = NULL;
745 char *str = 0, *hold = 0;
746 const char **strp = 0;
747
748 /* Set up a new pointer to macro-expanded string. */
749 str = expand_string (*strp_in, 1);
750 /* fprintf (stderr, " expanded <<%s>> to <<%s>>\n", *strp_in, str); */
751
752 hold = str;
753 strp = (const char **)(&str);
754
755 errmsg = mep_cgen_parse_operand (cd, opindex, strp, fields);
756
757 /* Now work out the advance. */
758 if (strlen (str) == 0)
759 *strp_in += strlen (*strp_in);
760
761 else
762 {
763 if (strstr (*strp_in, str))
764 /* A macro-expansion was pulled off the front. */
765 *strp_in = strstr (*strp_in, str);
766 else
767 /* A non-macro-expansion was pulled off the front. */
768 *strp_in += (str - hold);
769 }
770
771 if (hold)
772 free (hold);
773
774 return errmsg;
775 }
776
777 #define CGEN_ASM_INIT_HOOK (cd->parse_operand = mep_cgen_expand_macros_and_parse_operand);
778
779 /* -- dis.c */
780
781 const char * mep_cgen_parse_operand
782 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
783
784 /* Main entry point for operand parsing.
785
786 This function is basically just a big switch statement. Earlier versions
787 used tables to look up the function to use, but
788 - if the table contains both assembler and disassembler functions then
789 the disassembler contains much of the assembler and vice-versa,
790 - there's a lot of inlining possibilities as things grow,
791 - using a switch statement avoids the function call overhead.
792
793 This function could be moved into `parse_insn_normal', but keeping it
794 separate makes clear the interface between `parse_insn_normal' and each of
795 the handlers. */
796
797 const char *
798 mep_cgen_parse_operand (CGEN_CPU_DESC cd,
799 int opindex,
800 const char ** strp,
801 CGEN_FIELDS * fields)
802 {
803 const char * errmsg = NULL;
804 /* Used by scalar operands that still need to be parsed. */
805 long junk ATTRIBUTE_UNUSED;
806
807 switch (opindex)
808 {
809 case MEP_OPERAND_ADDR24A4 :
810 errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_ADDR24A4, (unsigned long *) (& fields->f_24u8a4n));
811 break;
812 case MEP_OPERAND_C5RMUIMM20 :
813 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_C5RMUIMM20, (unsigned long *) (& fields->f_c5_rmuimm20));
814 break;
815 case MEP_OPERAND_C5RNMUIMM24 :
816 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_C5RNMUIMM24, (unsigned long *) (& fields->f_c5_rnmuimm24));
817 break;
818 case MEP_OPERAND_CALLNUM :
819 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CALLNUM, (unsigned long *) (& fields->f_callnum));
820 break;
821 case MEP_OPERAND_CCCC :
822 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CCCC, (unsigned long *) (& fields->f_rm));
823 break;
824 case MEP_OPERAND_CCRN :
825 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & fields->f_ccrn);
826 break;
827 case MEP_OPERAND_CDISP10 :
828 errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10, (long *) (& fields->f_cdisp10));
829 break;
830 case MEP_OPERAND_CDISP10A2 :
831 errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A2, (long *) (& fields->f_cdisp10));
832 break;
833 case MEP_OPERAND_CDISP10A4 :
834 errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A4, (long *) (& fields->f_cdisp10));
835 break;
836 case MEP_OPERAND_CDISP10A8 :
837 errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A8, (long *) (& fields->f_cdisp10));
838 break;
839 case MEP_OPERAND_CDISP12 :
840 errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_CDISP12, (long *) (& fields->f_12s20));
841 break;
842 case MEP_OPERAND_CIMM4 :
843 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM4, (unsigned long *) (& fields->f_rn));
844 break;
845 case MEP_OPERAND_CIMM5 :
846 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM5, (unsigned long *) (& fields->f_5u24));
847 break;
848 case MEP_OPERAND_CODE16 :
849 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE16, (unsigned long *) (& fields->f_16u16));
850 break;
851 case MEP_OPERAND_CODE24 :
852 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE24, (unsigned long *) (& fields->f_24u4n));
853 break;
854 case MEP_OPERAND_CP_FLAG :
855 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & junk);
856 break;
857 case MEP_OPERAND_CRN :
858 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crn);
859 break;
860 case MEP_OPERAND_CRN64 :
861 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crn);
862 break;
863 case MEP_OPERAND_CRNX :
864 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crnx);
865 break;
866 case MEP_OPERAND_CRNX64 :
867 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crnx);
868 break;
869 case MEP_OPERAND_CROC :
870 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u7);
871 break;
872 case MEP_OPERAND_CROP :
873 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u23);
874 break;
875 case MEP_OPERAND_CRPC :
876 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u26);
877 break;
878 case MEP_OPERAND_CRPP :
879 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u18);
880 break;
881 case MEP_OPERAND_CRQC :
882 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u21);
883 break;
884 case MEP_OPERAND_CRQP :
885 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u13);
886 break;
887 case MEP_OPERAND_CSRN :
888 errmsg = parse_csrn (cd, strp, & mep_cgen_opval_h_csr, & fields->f_csrn);
889 break;
890 case MEP_OPERAND_CSRN_IDX :
891 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, (unsigned long *) (& fields->f_csrn));
892 break;
893 case MEP_OPERAND_DBG :
894 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
895 break;
896 case MEP_OPERAND_DEPC :
897 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
898 break;
899 case MEP_OPERAND_EPC :
900 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
901 break;
902 case MEP_OPERAND_EXC :
903 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
904 break;
905 case MEP_OPERAND_HI :
906 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
907 break;
908 case MEP_OPERAND_IMM16P0 :
909 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM16P0, (unsigned long *) (& fields->f_ivc2_imm16p0));
910 break;
911 case MEP_OPERAND_IMM3P12 :
912 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P12, (unsigned long *) (& fields->f_ivc2_3u12));
913 break;
914 case MEP_OPERAND_IMM3P25 :
915 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P25, (unsigned long *) (& fields->f_ivc2_3u25));
916 break;
917 case MEP_OPERAND_IMM3P4 :
918 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P4, (unsigned long *) (& fields->f_ivc2_3u4));
919 break;
920 case MEP_OPERAND_IMM3P5 :
921 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P5, (unsigned long *) (& fields->f_ivc2_3u5));
922 break;
923 case MEP_OPERAND_IMM3P9 :
924 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P9, (unsigned long *) (& fields->f_ivc2_3u9));
925 break;
926 case MEP_OPERAND_IMM4P10 :
927 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM4P10, (unsigned long *) (& fields->f_ivc2_4u10));
928 break;
929 case MEP_OPERAND_IMM4P4 :
930 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM4P4, (unsigned long *) (& fields->f_ivc2_4u4));
931 break;
932 case MEP_OPERAND_IMM4P8 :
933 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM4P8, (unsigned long *) (& fields->f_ivc2_4u8));
934 break;
935 case MEP_OPERAND_IMM5P23 :
936 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P23, (unsigned long *) (& fields->f_ivc2_5u23));
937 break;
938 case MEP_OPERAND_IMM5P3 :
939 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P3, (unsigned long *) (& fields->f_ivc2_5u3));
940 break;
941 case MEP_OPERAND_IMM5P7 :
942 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P7, (unsigned long *) (& fields->f_ivc2_5u7));
943 break;
944 case MEP_OPERAND_IMM5P8 :
945 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P8, (unsigned long *) (& fields->f_ivc2_5u8));
946 break;
947 case MEP_OPERAND_IMM6P2 :
948 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM6P2, (unsigned long *) (& fields->f_ivc2_6u2));
949 break;
950 case MEP_OPERAND_IMM6P6 :
951 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM6P6, (unsigned long *) (& fields->f_ivc2_6u6));
952 break;
953 case MEP_OPERAND_IMM8P0 :
954 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM8P0, (unsigned long *) (& fields->f_ivc2_8u0));
955 break;
956 case MEP_OPERAND_IMM8P20 :
957 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM8P20, (unsigned long *) (& fields->f_ivc2_8u20));
958 break;
959 case MEP_OPERAND_IMM8P4 :
960 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM8P4, (unsigned long *) (& fields->f_ivc2_8u4));
961 break;
962 case MEP_OPERAND_IVC_X_0_2 :
963 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_2, (unsigned long *) (& fields->f_ivc2_2u0));
964 break;
965 case MEP_OPERAND_IVC_X_0_3 :
966 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_3, (unsigned long *) (& fields->f_ivc2_3u0));
967 break;
968 case MEP_OPERAND_IVC_X_0_4 :
969 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_4, (unsigned long *) (& fields->f_ivc2_4u0));
970 break;
971 case MEP_OPERAND_IVC_X_0_5 :
972 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_5, (unsigned long *) (& fields->f_ivc2_5u0));
973 break;
974 case MEP_OPERAND_IVC_X_6_1 :
975 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_6_1, (unsigned long *) (& fields->f_ivc2_1u6));
976 break;
977 case MEP_OPERAND_IVC_X_6_2 :
978 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_6_2, (unsigned long *) (& fields->f_ivc2_2u6));
979 break;
980 case MEP_OPERAND_IVC_X_6_3 :
981 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_6_3, (unsigned long *) (& fields->f_ivc2_3u6));
982 break;
983 case MEP_OPERAND_IVC2CCRN :
984 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & fields->f_ivc2_ccrn);
985 break;
986 case MEP_OPERAND_IVC2CRN :
987 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_crnx);
988 break;
989 case MEP_OPERAND_IVC2RM :
990 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_ivc2_crm);
991 break;
992 case MEP_OPERAND_LO :
993 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
994 break;
995 case MEP_OPERAND_LP :
996 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
997 break;
998 case MEP_OPERAND_MB0 :
999 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1000 break;
1001 case MEP_OPERAND_MB1 :
1002 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1003 break;
1004 case MEP_OPERAND_ME0 :
1005 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1006 break;
1007 case MEP_OPERAND_ME1 :
1008 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1009 break;
1010 case MEP_OPERAND_NPC :
1011 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1012 break;
1013 case MEP_OPERAND_OPT :
1014 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1015 break;
1016 case MEP_OPERAND_PCABS24A2 :
1017 errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_PCABS24A2, (unsigned long *) (& fields->f_24u5a2n));
1018 break;
1019 case MEP_OPERAND_PCREL12A2 :
1020 errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL12A2, (long *) (& fields->f_12s4a2));
1021 break;
1022 case MEP_OPERAND_PCREL17A2 :
1023 errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL17A2, (long *) (& fields->f_17s16a2));
1024 break;
1025 case MEP_OPERAND_PCREL24A2 :
1026 errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL24A2, (long *) (& fields->f_24s5a2n));
1027 break;
1028 case MEP_OPERAND_PCREL8A2 :
1029 errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL8A2, (long *) (& fields->f_8s8a2));
1030 break;
1031 case MEP_OPERAND_PSW :
1032 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1033 break;
1034 case MEP_OPERAND_R0 :
1035 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1036 break;
1037 case MEP_OPERAND_R1 :
1038 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1039 break;
1040 case MEP_OPERAND_RL :
1041 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl);
1042 break;
1043 case MEP_OPERAND_RL5 :
1044 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl5);
1045 break;
1046 case MEP_OPERAND_RM :
1047 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
1048 break;
1049 case MEP_OPERAND_RMA :
1050 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
1051 break;
1052 case MEP_OPERAND_RN :
1053 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1054 break;
1055 case MEP_OPERAND_RN3 :
1056 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1057 break;
1058 case MEP_OPERAND_RN3C :
1059 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1060 break;
1061 case MEP_OPERAND_RN3L :
1062 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1063 break;
1064 case MEP_OPERAND_RN3S :
1065 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1066 break;
1067 case MEP_OPERAND_RN3UC :
1068 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1069 break;
1070 case MEP_OPERAND_RN3UL :
1071 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1072 break;
1073 case MEP_OPERAND_RN3US :
1074 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
1075 break;
1076 case MEP_OPERAND_RNC :
1077 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1078 break;
1079 case MEP_OPERAND_RNL :
1080 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1081 break;
1082 case MEP_OPERAND_RNS :
1083 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1084 break;
1085 case MEP_OPERAND_RNUC :
1086 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1087 break;
1088 case MEP_OPERAND_RNUL :
1089 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1090 break;
1091 case MEP_OPERAND_RNUS :
1092 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
1093 break;
1094 case MEP_OPERAND_SAR :
1095 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1096 break;
1097 case MEP_OPERAND_SDISP16 :
1098 errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SDISP16, (long *) (& fields->f_16s16));
1099 break;
1100 case MEP_OPERAND_SIMM16 :
1101 errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SIMM16, (long *) (& fields->f_16s16));
1102 break;
1103 case MEP_OPERAND_SIMM16P0 :
1104 errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM16P0, (long *) (& fields->f_ivc2_simm16p0));
1105 break;
1106 case MEP_OPERAND_SIMM6 :
1107 errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM6, (long *) (& fields->f_6s8));
1108 break;
1109 case MEP_OPERAND_SIMM8 :
1110 errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8, (long *) (& fields->f_8s8));
1111 break;
1112 case MEP_OPERAND_SIMM8P0 :
1113 errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8P0, (long *) (& fields->f_ivc2_8s0));
1114 break;
1115 case MEP_OPERAND_SIMM8P4 :
1116 errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8P4, (long *) (& fields->f_ivc2_8s4));
1117 break;
1118 case MEP_OPERAND_SP :
1119 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1120 break;
1121 case MEP_OPERAND_SPR :
1122 errmsg = parse_spreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1123 break;
1124 case MEP_OPERAND_TP :
1125 errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1126 break;
1127 case MEP_OPERAND_TPR :
1128 errmsg = parse_tpreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
1129 break;
1130 case MEP_OPERAND_UDISP2 :
1131 errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_UDISP2, (long *) (& fields->f_2u6));
1132 break;
1133 case MEP_OPERAND_UDISP7 :
1134 errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7, (unsigned long *) (& fields->f_7u9));
1135 break;
1136 case MEP_OPERAND_UDISP7A2 :
1137 errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A2, (unsigned long *) (& fields->f_7u9a2));
1138 break;
1139 case MEP_OPERAND_UDISP7A4 :
1140 errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A4, (unsigned long *) (& fields->f_7u9a4));
1141 break;
1142 case MEP_OPERAND_UIMM16 :
1143 errmsg = parse_unsigned16 (cd, strp, MEP_OPERAND_UIMM16, (unsigned long *) (& fields->f_16u16));
1144 break;
1145 case MEP_OPERAND_UIMM2 :
1146 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM2, (unsigned long *) (& fields->f_2u10));
1147 break;
1148 case MEP_OPERAND_UIMM24 :
1149 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM24, (unsigned long *) (& fields->f_24u8n));
1150 break;
1151 case MEP_OPERAND_UIMM3 :
1152 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM3, (unsigned long *) (& fields->f_3u5));
1153 break;
1154 case MEP_OPERAND_UIMM4 :
1155 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM4, (unsigned long *) (& fields->f_4u8));
1156 break;
1157 case MEP_OPERAND_UIMM5 :
1158 errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM5, (unsigned long *) (& fields->f_5u8));
1159 break;
1160 case MEP_OPERAND_UIMM7A4 :
1161 errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_UIMM7A4, (unsigned long *) (& fields->f_7u9a4));
1162 break;
1163 case MEP_OPERAND_ZERO :
1164 errmsg = parse_zero (cd, strp, MEP_OPERAND_ZERO, (long *) (& junk));
1165 break;
1166
1167 default :
1168 /* xgettext:c-format */
1169 fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
1170 abort ();
1171 }
1172
1173 return errmsg;
1174 }
1175
1176 cgen_parse_fn * const mep_cgen_parse_handlers[] =
1177 {
1178 parse_insn_normal,
1179 };
1180
1181 void
1182 mep_cgen_init_asm (CGEN_CPU_DESC cd)
1183 {
1184 mep_cgen_init_opcode_table (cd);
1185 mep_cgen_init_ibld_table (cd);
1186 cd->parse_handlers = & mep_cgen_parse_handlers[0];
1187 cd->parse_operand = mep_cgen_parse_operand;
1188 #ifdef CGEN_ASM_INIT_HOOK
1189 CGEN_ASM_INIT_HOOK
1190 #endif
1191 }
1192
1193 \f
1194
1195 /* Regex construction routine.
1196
1197 This translates an opcode syntax string into a regex string,
1198 by replacing any non-character syntax element (such as an
1199 opcode) with the pattern '.*'
1200
1201 It then compiles the regex and stores it in the opcode, for
1202 later use by mep_cgen_assemble_insn
1203
1204 Returns NULL for success, an error message for failure. */
1205
1206 char *
1207 mep_cgen_build_insn_regex (CGEN_INSN *insn)
1208 {
1209 CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
1210 const char *mnem = CGEN_INSN_MNEMONIC (insn);
1211 char rxbuf[CGEN_MAX_RX_ELEMENTS];
1212 char *rx = rxbuf;
1213 const CGEN_SYNTAX_CHAR_TYPE *syn;
1214 int reg_err;
1215
1216 syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
1217
1218 /* Mnemonics come first in the syntax string. */
1219 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1220 return _("missing mnemonic in syntax string");
1221 ++syn;
1222
1223 /* Generate a case sensitive regular expression that emulates case
1224 insensitive matching in the "C" locale. We cannot generate a case
1225 insensitive regular expression because in Turkish locales, 'i' and 'I'
1226 are not equal modulo case conversion. */
1227
1228 /* Copy the literal mnemonic out of the insn. */
1229 for (; *mnem; mnem++)
1230 {
1231 char c = *mnem;
1232
1233 if (ISALPHA (c))
1234 {
1235 *rx++ = '[';
1236 *rx++ = TOLOWER (c);
1237 *rx++ = TOUPPER (c);
1238 *rx++ = ']';
1239 }
1240 else
1241 *rx++ = c;
1242 }
1243
1244 /* Copy any remaining literals from the syntax string into the rx. */
1245 for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
1246 {
1247 if (CGEN_SYNTAX_CHAR_P (* syn))
1248 {
1249 char c = CGEN_SYNTAX_CHAR (* syn);
1250
1251 switch (c)
1252 {
1253 /* Escape any regex metacharacters in the syntax. */
1254 case '.': case '[': case '\\':
1255 case '*': case '^': case '$':
1256
1257 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
1258 case '?': case '{': case '}':
1259 case '(': case ')': case '*':
1260 case '|': case '+': case ']':
1261 #endif
1262 *rx++ = '\\';
1263 *rx++ = c;
1264 break;
1265
1266 default:
1267 if (ISALPHA (c))
1268 {
1269 *rx++ = '[';
1270 *rx++ = TOLOWER (c);
1271 *rx++ = TOUPPER (c);
1272 *rx++ = ']';
1273 }
1274 else
1275 *rx++ = c;
1276 break;
1277 }
1278 }
1279 else
1280 {
1281 /* Replace non-syntax fields with globs. */
1282 *rx++ = '.';
1283 *rx++ = '*';
1284 }
1285 }
1286
1287 /* Trailing whitespace ok. */
1288 * rx++ = '[';
1289 * rx++ = ' ';
1290 * rx++ = '\t';
1291 * rx++ = ']';
1292 * rx++ = '*';
1293
1294 /* But anchor it after that. */
1295 * rx++ = '$';
1296 * rx = '\0';
1297
1298 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
1299 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
1300
1301 if (reg_err == 0)
1302 return NULL;
1303 else
1304 {
1305 static char msg[80];
1306
1307 regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
1308 regfree ((regex_t *) CGEN_INSN_RX (insn));
1309 free (CGEN_INSN_RX (insn));
1310 (CGEN_INSN_RX (insn)) = NULL;
1311 return msg;
1312 }
1313 }
1314
1315 \f
1316 /* Default insn parser.
1317
1318 The syntax string is scanned and operands are parsed and stored in FIELDS.
1319 Relocs are queued as we go via other callbacks.
1320
1321 ??? Note that this is currently an all-or-nothing parser. If we fail to
1322 parse the instruction, we return 0 and the caller will start over from
1323 the beginning. Backtracking will be necessary in parsing subexpressions,
1324 but that can be handled there. Not handling backtracking here may get
1325 expensive in the case of the m68k. Deal with later.
1326
1327 Returns NULL for success, an error message for failure. */
1328
1329 static const char *
1330 parse_insn_normal (CGEN_CPU_DESC cd,
1331 const CGEN_INSN *insn,
1332 const char **strp,
1333 CGEN_FIELDS *fields)
1334 {
1335 /* ??? Runtime added insns not handled yet. */
1336 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
1337 const char *str = *strp;
1338 const char *errmsg;
1339 const char *p;
1340 const CGEN_SYNTAX_CHAR_TYPE * syn;
1341 #ifdef CGEN_MNEMONIC_OPERANDS
1342 /* FIXME: wip */
1343 int past_opcode_p;
1344 #endif
1345
1346 /* For now we assume the mnemonic is first (there are no leading operands).
1347 We can parse it without needing to set up operand parsing.
1348 GAS's input scrubber will ensure mnemonics are lowercase, but we may
1349 not be called from GAS. */
1350 p = CGEN_INSN_MNEMONIC (insn);
1351 while (*p && TOLOWER (*p) == TOLOWER (*str))
1352 ++p, ++str;
1353
1354 if (* p)
1355 return _("unrecognized instruction");
1356
1357 #ifndef CGEN_MNEMONIC_OPERANDS
1358 if (* str && ! ISSPACE (* str))
1359 return _("unrecognized instruction");
1360 #endif
1361
1362 CGEN_INIT_PARSE (cd);
1363 cgen_init_parse_operand (cd);
1364 #ifdef CGEN_MNEMONIC_OPERANDS
1365 past_opcode_p = 0;
1366 #endif
1367
1368 /* We don't check for (*str != '\0') here because we want to parse
1369 any trailing fake arguments in the syntax string. */
1370 syn = CGEN_SYNTAX_STRING (syntax);
1371
1372 /* Mnemonics come first for now, ensure valid string. */
1373 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
1374 abort ();
1375
1376 ++syn;
1377
1378 while (* syn != 0)
1379 {
1380 /* Non operand chars must match exactly. */
1381 if (CGEN_SYNTAX_CHAR_P (* syn))
1382 {
1383 /* FIXME: While we allow for non-GAS callers above, we assume the
1384 first char after the mnemonic part is a space. */
1385 /* FIXME: We also take inappropriate advantage of the fact that
1386 GAS's input scrubber will remove extraneous blanks. */
1387 if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
1388 {
1389 #ifdef CGEN_MNEMONIC_OPERANDS
1390 if (CGEN_SYNTAX_CHAR(* syn) == ' ')
1391 past_opcode_p = 1;
1392 #endif
1393 ++ syn;
1394 ++ str;
1395 }
1396 else if (*str)
1397 {
1398 /* Syntax char didn't match. Can't be this insn. */
1399 static char msg [80];
1400
1401 /* xgettext:c-format */
1402 sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
1403 CGEN_SYNTAX_CHAR(*syn), *str);
1404 return msg;
1405 }
1406 else
1407 {
1408 /* Ran out of input. */
1409 static char msg [80];
1410
1411 /* xgettext:c-format */
1412 sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
1413 CGEN_SYNTAX_CHAR(*syn));
1414 return msg;
1415 }
1416 continue;
1417 }
1418
1419 /* We have an operand of some sort. */
1420 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
1421 &str, fields);
1422 if (errmsg)
1423 return errmsg;
1424
1425 /* Done with this operand, continue with next one. */
1426 ++ syn;
1427 }
1428
1429 /* If we're at the end of the syntax string, we're done. */
1430 if (* syn == 0)
1431 {
1432 /* FIXME: For the moment we assume a valid `str' can only contain
1433 blanks now. IE: We needn't try again with a longer version of
1434 the insn and it is assumed that longer versions of insns appear
1435 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
1436 while (ISSPACE (* str))
1437 ++ str;
1438
1439 if (* str != '\0')
1440 return _("junk at end of line"); /* FIXME: would like to include `str' */
1441
1442 return NULL;
1443 }
1444
1445 /* We couldn't parse it. */
1446 return _("unrecognized instruction");
1447 }
1448 \f
1449 /* Main entry point.
1450 This routine is called for each instruction to be assembled.
1451 STR points to the insn to be assembled.
1452 We assume all necessary tables have been initialized.
1453 The assembled instruction, less any fixups, is stored in BUF.
1454 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
1455 still needs to be converted to target byte order, otherwise BUF is an array
1456 of bytes in target byte order.
1457 The result is a pointer to the insn's entry in the opcode table,
1458 or NULL if an error occured (an error message will have already been
1459 printed).
1460
1461 Note that when processing (non-alias) macro-insns,
1462 this function recurses.
1463
1464 ??? It's possible to make this cpu-independent.
1465 One would have to deal with a few minor things.
1466 At this point in time doing so would be more of a curiosity than useful
1467 [for example this file isn't _that_ big], but keeping the possibility in
1468 mind helps keep the design clean. */
1469
1470 const CGEN_INSN *
1471 mep_cgen_assemble_insn (CGEN_CPU_DESC cd,
1472 const char *str,
1473 CGEN_FIELDS *fields,
1474 CGEN_INSN_BYTES_PTR buf,
1475 char **errmsg)
1476 {
1477 const char *start;
1478 CGEN_INSN_LIST *ilist;
1479 const char *parse_errmsg = NULL;
1480 const char *insert_errmsg = NULL;
1481 int recognized_mnemonic = 0;
1482
1483 /* Skip leading white space. */
1484 while (ISSPACE (* str))
1485 ++ str;
1486
1487 /* The instructions are stored in hashed lists.
1488 Get the first in the list. */
1489 ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
1490
1491 /* Keep looking until we find a match. */
1492 start = str;
1493 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
1494 {
1495 const CGEN_INSN *insn = ilist->insn;
1496 recognized_mnemonic = 1;
1497
1498 #ifdef CGEN_VALIDATE_INSN_SUPPORTED
1499 /* Not usually needed as unsupported opcodes
1500 shouldn't be in the hash lists. */
1501 /* Is this insn supported by the selected cpu? */
1502 if (! mep_cgen_insn_supported (cd, insn))
1503 continue;
1504 #endif
1505 /* If the RELAXED attribute is set, this is an insn that shouldn't be
1506 chosen immediately. Instead, it is used during assembler/linker
1507 relaxation if possible. */
1508 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
1509 continue;
1510
1511 str = start;
1512
1513 /* Skip this insn if str doesn't look right lexically. */
1514 if (CGEN_INSN_RX (insn) != NULL &&
1515 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
1516 continue;
1517
1518 /* Allow parse/insert handlers to obtain length of insn. */
1519 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
1520
1521 parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
1522 if (parse_errmsg != NULL)
1523 continue;
1524
1525 /* ??? 0 is passed for `pc'. */
1526 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
1527 (bfd_vma) 0);
1528 if (insert_errmsg != NULL)
1529 continue;
1530
1531 /* It is up to the caller to actually output the insn and any
1532 queued relocs. */
1533 return insn;
1534 }
1535
1536 {
1537 static char errbuf[150];
1538 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
1539 const char *tmp_errmsg;
1540
1541 /* If requesting verbose error messages, use insert_errmsg.
1542 Failing that, use parse_errmsg. */
1543 tmp_errmsg = (insert_errmsg ? insert_errmsg :
1544 parse_errmsg ? parse_errmsg :
1545 recognized_mnemonic ?
1546 _("unrecognized form of instruction") :
1547 _("unrecognized instruction"));
1548
1549 if (strlen (start) > 50)
1550 /* xgettext:c-format */
1551 sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
1552 else
1553 /* xgettext:c-format */
1554 sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
1555 #else
1556 if (strlen (start) > 50)
1557 /* xgettext:c-format */
1558 sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1559 else
1560 /* xgettext:c-format */
1561 sprintf (errbuf, _("bad instruction `%.50s'"), start);
1562 #endif
1563
1564 *errmsg = errbuf;
1565 return NULL;
1566 }
1567 }
This page took 0.077941 seconds and 4 git commands to generate.