Sync dlang demangling tests from upstream libiberty testsuite.
[deliverable/binutils-gdb.git] / opcodes / lm32-asm.c
CommitLineData
84e94c90
NC
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
2571583a 7 Copyright (C) 1996-2017 Free Software Foundation, Inc.
84e94c90
NC
8
9 This file is part of libopcodes.
10
11 This library is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3, or (at your option)
14 any later version.
15
16 It is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
19 License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
24
25
26/* ??? Eventually more and more of this stuff can go to cpu-independent files.
27 Keep that in mind. */
28
29#include "sysdep.h"
30#include <stdio.h>
31#include "ansidecl.h"
32#include "bfd.h"
33#include "symcat.h"
34#include "lm32-desc.h"
35#include "lm32-opc.h"
36#include "opintl.h"
37#include "xregex.h"
38#include "libiberty.h"
39#include "safe-ctype.h"
40
41#undef min
42#define min(a,b) ((a) < (b) ? (a) : (b))
43#undef max
44#define max(a,b) ((a) > (b) ? (a) : (b))
45
46static const char * parse_insn_normal
47 (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
48\f
49/* -- assembler routines inserted here. */
50
51/* -- asm.c */
52
53/* Handle signed/unsigned literal. */
54
55static const char *
56parse_imm (CGEN_CPU_DESC cd,
57 const char **strp,
58 int opindex,
59 unsigned long *valuep)
60{
61 const char *errmsg;
62 signed long value;
63
64 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
65 if (errmsg == NULL)
66 {
67 unsigned long x = value & 0xFFFF0000;
68 if (x != 0 && x != 0xFFFF0000)
69 errmsg = _("immediate value out of range");
70 else
71 *valuep = (value & 0xFFFF);
72 }
73 return errmsg;
74}
75
76/* Handle hi() */
77
78static const char *
79parse_hi16 (CGEN_CPU_DESC cd,
80 const char **strp,
81 int opindex,
82 unsigned long *valuep)
83{
84 if (strncasecmp (*strp, "hi(", 3) == 0)
85 {
86 enum cgen_parse_operand_result result_type;
87 bfd_vma value;
88 const char *errmsg;
89
90 *strp += 3;
91 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
92 &result_type, &value);
93 if (**strp != ')')
94 return _("missing `)'");
95
96 ++*strp;
97 if (errmsg == NULL
98 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
99 value = (value >> 16) & 0xffff;
100 *valuep = value;
101
102 return errmsg;
103 }
104
105 return parse_imm (cd, strp, opindex, valuep);
106}
107
108/* Handle lo() */
109
110static const char *
111parse_lo16 (CGEN_CPU_DESC cd,
112 const char **strp,
113 int opindex,
114 unsigned long *valuep)
115{
116 if (strncasecmp (*strp, "lo(", 3) == 0)
117 {
118 const char *errmsg;
119 enum cgen_parse_operand_result result_type;
120 bfd_vma value;
121
122 *strp += 3;
123 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
124 &result_type, &value);
125 if (**strp != ')')
126 return _("missing `)'");
127 ++*strp;
128 if (errmsg == NULL
129 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
130 value &= 0xffff;
131 *valuep = value;
132 return errmsg;
133 }
134
135 return parse_imm (cd, strp, opindex, valuep);
136}
137
138/* Handle gp() */
139
140static const char *
141parse_gp16 (CGEN_CPU_DESC cd,
142 const char **strp,
143 int opindex,
144 long *valuep)
145{
146 if (strncasecmp (*strp, "gp(", 3) == 0)
147 {
148 const char *errmsg;
149 enum cgen_parse_operand_result result_type;
150 bfd_vma value;
151
152 *strp += 3;
153 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_GPREL16,
154 & result_type, & value);
155 if (**strp != ')')
156 return _("missing `)'");
157 ++*strp;
158 if (errmsg == NULL
159 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
160 value &= 0xffff;
161 *valuep = value;
162 return errmsg;
163 }
164
165 return _("expecting gp relative address: gp(symbol)");
166}
167
168/* Handle got() */
169
170static const char *
171parse_got16 (CGEN_CPU_DESC cd,
172 const char **strp,
173 int opindex,
174 long *valuep)
175{
176 if (strncasecmp (*strp, "got(", 4) == 0)
177 {
178 const char *errmsg;
179 enum cgen_parse_operand_result result_type;
180 bfd_vma value;
181
182 *strp += 4;
183 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_16_GOT,
184 & result_type, & value);
185 if (**strp != ')')
186 return _("missing `)'");
187 ++*strp;
188 if (errmsg == NULL
189 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
190 value &= 0xffff;
191 *valuep = value;
192 return errmsg;
193 }
194
195 return _("expecting got relative address: got(symbol)");
196}
197
198/* Handle gotoffhi16() */
199
200static const char *
201parse_gotoff_hi16 (CGEN_CPU_DESC cd,
202 const char **strp,
203 int opindex,
204 long *valuep)
205{
206 if (strncasecmp (*strp, "gotoffhi16(", 11) == 0)
207 {
208 const char *errmsg;
209 enum cgen_parse_operand_result result_type;
210 bfd_vma value;
211
212 *strp += 11;
213 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_GOTOFF_HI16,
214 & result_type, & value);
215 if (**strp != ')')
216 return _("missing `)'");
217 ++*strp;
218 if (errmsg == NULL
219 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
220 value &= 0xffff;
221 *valuep = value;
222 return errmsg;
223 }
224
225 return _("expecting got relative address: gotoffhi16(symbol)");
226}
227
228/* Handle gotofflo16() */
229
230static const char *
231parse_gotoff_lo16 (CGEN_CPU_DESC cd,
232 const char **strp,
233 int opindex,
234 long *valuep)
235{
236 if (strncasecmp (*strp, "gotofflo16(", 11) == 0)
237 {
238 const char *errmsg;
239 enum cgen_parse_operand_result result_type;
240 bfd_vma value;
241
242 *strp += 11;
243 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LM32_GOTOFF_LO16,
244 &result_type, &value);
245 if (**strp != ')')
246 return _("missing `)'");
247 ++*strp;
248 if (errmsg == NULL
249 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
250 value &= 0xffff;
251 *valuep = value;
252 return errmsg;
253 }
254
255 return _("expecting got relative address: gotofflo16(symbol)");
256}
257
258const char * lm32_cgen_parse_operand
259 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
260
261/* Main entry point for operand parsing.
262
263 This function is basically just a big switch statement. Earlier versions
264 used tables to look up the function to use, but
265 - if the table contains both assembler and disassembler functions then
266 the disassembler contains much of the assembler and vice-versa,
267 - there's a lot of inlining possibilities as things grow,
268 - using a switch statement avoids the function call overhead.
269
270 This function could be moved into `parse_insn_normal', but keeping it
271 separate makes clear the interface between `parse_insn_normal' and each of
272 the handlers. */
273
274const char *
275lm32_cgen_parse_operand (CGEN_CPU_DESC cd,
276 int opindex,
277 const char ** strp,
278 CGEN_FIELDS * fields)
279{
280 const char * errmsg = NULL;
281 /* Used by scalar operands that still need to be parsed. */
282 long junk ATTRIBUTE_UNUSED;
283
284 switch (opindex)
285 {
286 case LM32_OPERAND_BRANCH :
287 {
288 bfd_vma value = 0;
289 errmsg = cgen_parse_address (cd, strp, LM32_OPERAND_BRANCH, 0, NULL, & value);
290 fields->f_branch = value;
291 }
292 break;
293 case LM32_OPERAND_CALL :
294 {
295 bfd_vma value = 0;
296 errmsg = cgen_parse_address (cd, strp, LM32_OPERAND_CALL, 0, NULL, & value);
297 fields->f_call = value;
298 }
299 break;
300 case LM32_OPERAND_CSR :
301 errmsg = cgen_parse_keyword (cd, strp, & lm32_cgen_opval_h_csr, & fields->f_csr);
302 break;
303 case LM32_OPERAND_EXCEPTION :
304 errmsg = cgen_parse_unsigned_integer (cd, strp, LM32_OPERAND_EXCEPTION, (unsigned long *) (& fields->f_exception));
305 break;
306 case LM32_OPERAND_GOT16 :
307 errmsg = parse_got16 (cd, strp, LM32_OPERAND_GOT16, (long *) (& fields->f_imm));
308 break;
309 case LM32_OPERAND_GOTOFFHI16 :
310 errmsg = parse_gotoff_hi16 (cd, strp, LM32_OPERAND_GOTOFFHI16, (long *) (& fields->f_imm));
311 break;
312 case LM32_OPERAND_GOTOFFLO16 :
313 errmsg = parse_gotoff_lo16 (cd, strp, LM32_OPERAND_GOTOFFLO16, (long *) (& fields->f_imm));
314 break;
315 case LM32_OPERAND_GP16 :
316 errmsg = parse_gp16 (cd, strp, LM32_OPERAND_GP16, (long *) (& fields->f_imm));
317 break;
318 case LM32_OPERAND_HI16 :
319 errmsg = parse_hi16 (cd, strp, LM32_OPERAND_HI16, (unsigned long *) (& fields->f_uimm));
320 break;
321 case LM32_OPERAND_IMM :
322 errmsg = cgen_parse_signed_integer (cd, strp, LM32_OPERAND_IMM, (long *) (& fields->f_imm));
323 break;
324 case LM32_OPERAND_LO16 :
325 errmsg = parse_lo16 (cd, strp, LM32_OPERAND_LO16, (unsigned long *) (& fields->f_uimm));
326 break;
327 case LM32_OPERAND_R0 :
328 errmsg = cgen_parse_keyword (cd, strp, & lm32_cgen_opval_h_gr, & fields->f_r0);
329 break;
330 case LM32_OPERAND_R1 :
331 errmsg = cgen_parse_keyword (cd, strp, & lm32_cgen_opval_h_gr, & fields->f_r1);
332 break;
333 case LM32_OPERAND_R2 :
334 errmsg = cgen_parse_keyword (cd, strp, & lm32_cgen_opval_h_gr, & fields->f_r2);
335 break;
336 case LM32_OPERAND_SHIFT :
337 errmsg = cgen_parse_unsigned_integer (cd, strp, LM32_OPERAND_SHIFT, (unsigned long *) (& fields->f_shift));
338 break;
339 case LM32_OPERAND_UIMM :
340 errmsg = cgen_parse_unsigned_integer (cd, strp, LM32_OPERAND_UIMM, (unsigned long *) (& fields->f_uimm));
341 break;
342 case LM32_OPERAND_USER :
343 errmsg = cgen_parse_unsigned_integer (cd, strp, LM32_OPERAND_USER, (unsigned long *) (& fields->f_user));
344 break;
345
346 default :
347 /* xgettext:c-format */
348 fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
349 abort ();
350 }
351
352 return errmsg;
353}
354
43e65147 355cgen_parse_fn * const lm32_cgen_parse_handlers[] =
84e94c90
NC
356{
357 parse_insn_normal,
358};
359
360void
361lm32_cgen_init_asm (CGEN_CPU_DESC cd)
362{
363 lm32_cgen_init_opcode_table (cd);
364 lm32_cgen_init_ibld_table (cd);
365 cd->parse_handlers = & lm32_cgen_parse_handlers[0];
366 cd->parse_operand = lm32_cgen_parse_operand;
367#ifdef CGEN_ASM_INIT_HOOK
368CGEN_ASM_INIT_HOOK
369#endif
370}
371
372\f
373
374/* Regex construction routine.
375
376 This translates an opcode syntax string into a regex string,
377 by replacing any non-character syntax element (such as an
378 opcode) with the pattern '.*'
379
380 It then compiles the regex and stores it in the opcode, for
381 later use by lm32_cgen_assemble_insn
382
383 Returns NULL for success, an error message for failure. */
384
43e65147 385char *
84e94c90 386lm32_cgen_build_insn_regex (CGEN_INSN *insn)
43e65147 387{
84e94c90
NC
388 CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
389 const char *mnem = CGEN_INSN_MNEMONIC (insn);
390 char rxbuf[CGEN_MAX_RX_ELEMENTS];
391 char *rx = rxbuf;
392 const CGEN_SYNTAX_CHAR_TYPE *syn;
393 int reg_err;
394
395 syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
396
397 /* Mnemonics come first in the syntax string. */
398 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
399 return _("missing mnemonic in syntax string");
400 ++syn;
401
402 /* Generate a case sensitive regular expression that emulates case
403 insensitive matching in the "C" locale. We cannot generate a case
404 insensitive regular expression because in Turkish locales, 'i' and 'I'
405 are not equal modulo case conversion. */
406
407 /* Copy the literal mnemonic out of the insn. */
408 for (; *mnem; mnem++)
409 {
410 char c = *mnem;
411
412 if (ISALPHA (c))
413 {
414 *rx++ = '[';
415 *rx++ = TOLOWER (c);
416 *rx++ = TOUPPER (c);
417 *rx++ = ']';
418 }
419 else
420 *rx++ = c;
421 }
422
423 /* Copy any remaining literals from the syntax string into the rx. */
424 for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
425 {
43e65147 426 if (CGEN_SYNTAX_CHAR_P (* syn))
84e94c90
NC
427 {
428 char c = CGEN_SYNTAX_CHAR (* syn);
429
43e65147 430 switch (c)
84e94c90
NC
431 {
432 /* Escape any regex metacharacters in the syntax. */
43e65147
L
433 case '.': case '[': case '\\':
434 case '*': case '^': case '$':
84e94c90
NC
435
436#ifdef CGEN_ESCAPE_EXTENDED_REGEX
43e65147 437 case '?': case '{': case '}':
84e94c90
NC
438 case '(': case ')': case '*':
439 case '|': case '+': case ']':
440#endif
441 *rx++ = '\\';
442 *rx++ = c;
443 break;
444
445 default:
446 if (ISALPHA (c))
447 {
448 *rx++ = '[';
449 *rx++ = TOLOWER (c);
450 *rx++ = TOUPPER (c);
451 *rx++ = ']';
452 }
453 else
454 *rx++ = c;
455 break;
456 }
457 }
458 else
459 {
460 /* Replace non-syntax fields with globs. */
461 *rx++ = '.';
462 *rx++ = '*';
463 }
464 }
465
466 /* Trailing whitespace ok. */
43e65147
L
467 * rx++ = '[';
468 * rx++ = ' ';
469 * rx++ = '\t';
470 * rx++ = ']';
471 * rx++ = '*';
84e94c90
NC
472
473 /* But anchor it after that. */
43e65147 474 * rx++ = '$';
84e94c90
NC
475 * rx = '\0';
476
477 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
478 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
479
43e65147 480 if (reg_err == 0)
84e94c90
NC
481 return NULL;
482 else
483 {
484 static char msg[80];
485
486 regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
487 regfree ((regex_t *) CGEN_INSN_RX (insn));
488 free (CGEN_INSN_RX (insn));
489 (CGEN_INSN_RX (insn)) = NULL;
490 return msg;
491 }
492}
493
494\f
495/* Default insn parser.
496
497 The syntax string is scanned and operands are parsed and stored in FIELDS.
498 Relocs are queued as we go via other callbacks.
499
500 ??? Note that this is currently an all-or-nothing parser. If we fail to
501 parse the instruction, we return 0 and the caller will start over from
502 the beginning. Backtracking will be necessary in parsing subexpressions,
503 but that can be handled there. Not handling backtracking here may get
504 expensive in the case of the m68k. Deal with later.
505
506 Returns NULL for success, an error message for failure. */
507
508static const char *
509parse_insn_normal (CGEN_CPU_DESC cd,
510 const CGEN_INSN *insn,
511 const char **strp,
512 CGEN_FIELDS *fields)
513{
514 /* ??? Runtime added insns not handled yet. */
515 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
516 const char *str = *strp;
517 const char *errmsg;
518 const char *p;
519 const CGEN_SYNTAX_CHAR_TYPE * syn;
520#ifdef CGEN_MNEMONIC_OPERANDS
521 /* FIXME: wip */
522 int past_opcode_p;
523#endif
524
525 /* For now we assume the mnemonic is first (there are no leading operands).
526 We can parse it without needing to set up operand parsing.
527 GAS's input scrubber will ensure mnemonics are lowercase, but we may
528 not be called from GAS. */
529 p = CGEN_INSN_MNEMONIC (insn);
530 while (*p && TOLOWER (*p) == TOLOWER (*str))
531 ++p, ++str;
532
533 if (* p)
534 return _("unrecognized instruction");
535
536#ifndef CGEN_MNEMONIC_OPERANDS
537 if (* str && ! ISSPACE (* str))
538 return _("unrecognized instruction");
539#endif
540
541 CGEN_INIT_PARSE (cd);
542 cgen_init_parse_operand (cd);
543#ifdef CGEN_MNEMONIC_OPERANDS
544 past_opcode_p = 0;
545#endif
546
547 /* We don't check for (*str != '\0') here because we want to parse
548 any trailing fake arguments in the syntax string. */
549 syn = CGEN_SYNTAX_STRING (syntax);
550
551 /* Mnemonics come first for now, ensure valid string. */
552 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
553 abort ();
554
555 ++syn;
556
557 while (* syn != 0)
558 {
559 /* Non operand chars must match exactly. */
560 if (CGEN_SYNTAX_CHAR_P (* syn))
561 {
562 /* FIXME: While we allow for non-GAS callers above, we assume the
563 first char after the mnemonic part is a space. */
564 /* FIXME: We also take inappropriate advantage of the fact that
565 GAS's input scrubber will remove extraneous blanks. */
566 if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
567 {
568#ifdef CGEN_MNEMONIC_OPERANDS
569 if (CGEN_SYNTAX_CHAR(* syn) == ' ')
570 past_opcode_p = 1;
571#endif
572 ++ syn;
573 ++ str;
574 }
575 else if (*str)
576 {
577 /* Syntax char didn't match. Can't be this insn. */
578 static char msg [80];
579
580 /* xgettext:c-format */
581 sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
582 CGEN_SYNTAX_CHAR(*syn), *str);
583 return msg;
584 }
585 else
586 {
587 /* Ran out of input. */
588 static char msg [80];
589
590 /* xgettext:c-format */
591 sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
592 CGEN_SYNTAX_CHAR(*syn));
593 return msg;
594 }
595 continue;
596 }
597
c7e2358a
AM
598#ifdef CGEN_MNEMONIC_OPERANDS
599 (void) past_opcode_p;
600#endif
84e94c90 601 /* We have an operand of some sort. */
c7e2358a 602 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
84e94c90
NC
603 if (errmsg)
604 return errmsg;
605
606 /* Done with this operand, continue with next one. */
607 ++ syn;
608 }
609
610 /* If we're at the end of the syntax string, we're done. */
611 if (* syn == 0)
612 {
613 /* FIXME: For the moment we assume a valid `str' can only contain
614 blanks now. IE: We needn't try again with a longer version of
615 the insn and it is assumed that longer versions of insns appear
616 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
617 while (ISSPACE (* str))
618 ++ str;
619
620 if (* str != '\0')
621 return _("junk at end of line"); /* FIXME: would like to include `str' */
622
623 return NULL;
624 }
625
626 /* We couldn't parse it. */
627 return _("unrecognized instruction");
628}
629\f
630/* Main entry point.
631 This routine is called for each instruction to be assembled.
632 STR points to the insn to be assembled.
633 We assume all necessary tables have been initialized.
634 The assembled instruction, less any fixups, is stored in BUF.
635 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
636 still needs to be converted to target byte order, otherwise BUF is an array
637 of bytes in target byte order.
638 The result is a pointer to the insn's entry in the opcode table,
639 or NULL if an error occured (an error message will have already been
640 printed).
641
642 Note that when processing (non-alias) macro-insns,
643 this function recurses.
644
645 ??? It's possible to make this cpu-independent.
646 One would have to deal with a few minor things.
647 At this point in time doing so would be more of a curiosity than useful
648 [for example this file isn't _that_ big], but keeping the possibility in
649 mind helps keep the design clean. */
650
651const CGEN_INSN *
652lm32_cgen_assemble_insn (CGEN_CPU_DESC cd,
653 const char *str,
654 CGEN_FIELDS *fields,
655 CGEN_INSN_BYTES_PTR buf,
656 char **errmsg)
657{
658 const char *start;
659 CGEN_INSN_LIST *ilist;
660 const char *parse_errmsg = NULL;
661 const char *insert_errmsg = NULL;
662 int recognized_mnemonic = 0;
663
664 /* Skip leading white space. */
665 while (ISSPACE (* str))
666 ++ str;
667
668 /* The instructions are stored in hashed lists.
669 Get the first in the list. */
670 ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
671
672 /* Keep looking until we find a match. */
673 start = str;
674 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
675 {
676 const CGEN_INSN *insn = ilist->insn;
677 recognized_mnemonic = 1;
678
43e65147 679#ifdef CGEN_VALIDATE_INSN_SUPPORTED
84e94c90
NC
680 /* Not usually needed as unsupported opcodes
681 shouldn't be in the hash lists. */
682 /* Is this insn supported by the selected cpu? */
683 if (! lm32_cgen_insn_supported (cd, insn))
684 continue;
685#endif
686 /* If the RELAXED attribute is set, this is an insn that shouldn't be
687 chosen immediately. Instead, it is used during assembler/linker
688 relaxation if possible. */
689 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
690 continue;
691
692 str = start;
693
694 /* Skip this insn if str doesn't look right lexically. */
695 if (CGEN_INSN_RX (insn) != NULL &&
696 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
697 continue;
698
699 /* Allow parse/insert handlers to obtain length of insn. */
700 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
701
702 parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
703 if (parse_errmsg != NULL)
704 continue;
705
706 /* ??? 0 is passed for `pc'. */
707 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
708 (bfd_vma) 0);
709 if (insert_errmsg != NULL)
710 continue;
711
712 /* It is up to the caller to actually output the insn and any
713 queued relocs. */
714 return insn;
715 }
716
717 {
718 static char errbuf[150];
84e94c90 719 const char *tmp_errmsg;
c7e2358a
AM
720#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
721#define be_verbose 1
84e94c90 722#else
c7e2358a 723#define be_verbose 0
84e94c90 724#endif
c7e2358a
AM
725
726 if (be_verbose)
727 {
728 /* If requesting verbose error messages, use insert_errmsg.
729 Failing that, use parse_errmsg. */
730 tmp_errmsg = (insert_errmsg ? insert_errmsg :
731 parse_errmsg ? parse_errmsg :
732 recognized_mnemonic ?
733 _("unrecognized form of instruction") :
734 _("unrecognized instruction"));
735
736 if (strlen (start) > 50)
737 /* xgettext:c-format */
738 sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
43e65147 739 else
c7e2358a
AM
740 /* xgettext:c-format */
741 sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
742 }
743 else
744 {
745 if (strlen (start) > 50)
746 /* xgettext:c-format */
747 sprintf (errbuf, _("bad instruction `%.50s...'"), start);
43e65147 748 else
c7e2358a
AM
749 /* xgettext:c-format */
750 sprintf (errbuf, _("bad instruction `%.50s'"), start);
751 }
43e65147 752
84e94c90
NC
753 *errmsg = errbuf;
754 return NULL;
755 }
756}
This page took 0.46032 seconds and 4 git commands to generate.