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