Change source files over to GPLv3.
[deliverable/binutils-gdb.git] / opcodes / openrisc-asm.c
CommitLineData
87e6d782
NC
1/* Assembler interface for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
3
47b0e7ad
NC
4 THIS FILE IS MACHINE GENERATED WITH CGEN.
5 - the resultant file is machine generated, cgen-asm.in isn't
87e6d782 6
9b201bb5 7 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2007
47b0e7ad 8 Free Software Foundation, Inc.
87e6d782 9
9b201bb5 10 This file is part of libopcodes.
87e6d782 11
9b201bb5 12 This library is free software; you can redistribute it and/or modify
47b0e7ad 13 it under the terms of the GNU General Public License as published by
9b201bb5 14 the Free Software Foundation; either version 3, or (at your option)
47b0e7ad 15 any later version.
87e6d782 16
9b201bb5
NC
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.
87e6d782 21
47b0e7ad
NC
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. */
87e6d782 25
9b201bb5 26
87e6d782
NC
27/* ??? Eventually more and more of this stuff can go to cpu-independent files.
28 Keep that in mind. */
29
30#include "sysdep.h"
87e6d782
NC
31#include <stdio.h>
32#include "ansidecl.h"
33#include "bfd.h"
34#include "symcat.h"
35#include "openrisc-desc.h"
36#include "openrisc-opc.h"
37#include "opintl.h"
fc7bc883 38#include "xregex.h"
fc05c67f 39#include "libiberty.h"
37111cc7 40#include "safe-ctype.h"
87e6d782 41
37111cc7 42#undef min
87e6d782 43#define min(a,b) ((a) < (b) ? (a) : (b))
37111cc7 44#undef max
87e6d782
NC
45#define max(a,b) ((a) > (b) ? (a) : (b))
46
47static const char * parse_insn_normal
ffead7ae 48 (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
87e6d782 49\f
37111cc7 50/* -- assembler routines inserted here. */
87e6d782
NC
51
52/* -- asm.c */
53
47b0e7ad 54static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");
87e6d782 55
47b0e7ad 56#define CGEN_VERBOSE_ASSEMBLER_ERRORS
0e2ee3ca 57
87e6d782 58long
47b0e7ad 59openrisc_sign_extend_16bit (long value)
87e6d782 60{
8f807746 61 return ((value & 0xffff) ^ 0x8000) - 0x8000;
87e6d782
NC
62}
63
87e6d782
NC
64/* Handle hi(). */
65
66static const char *
47b0e7ad 67parse_hi16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep)
87e6d782
NC
68{
69 const char *errmsg;
70 enum cgen_parse_operand_result result_type;
8f807746 71 unsigned long ret;
87e6d782
NC
72
73 if (**strp == '#')
74 ++*strp;
75
76 if (strncasecmp (*strp, "hi(", 3) == 0)
77 {
8f807746 78 bfd_vma value;
87e6d782 79
8f807746 80 *strp += 3;
33b71eeb 81 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
47b0e7ad 82 & result_type, & value);
87e6d782 83 if (**strp != ')')
47b0e7ad 84 return MISSING_CLOSING_PARENTHESIS;
8f807746 85
87e6d782
NC
86 ++*strp;
87 if (errmsg == NULL
88 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
89 value >>= 16;
8f807746 90 ret = value;
87e6d782
NC
91 }
92 else
93 {
94 if (**strp == '-')
8f807746
AM
95 {
96 long value;
33b71eeb 97
8f807746
AM
98 errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value);
99 ret = value;
100 }
87e6d782 101 else
8f807746
AM
102 {
103 unsigned long value;
33b71eeb 104
8f807746
AM
105 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, &value);
106 ret = value;
107 }
87e6d782 108 }
8f807746
AM
109
110 *valuep = ((ret & 0xffff) ^ 0x8000) - 0x8000;
87e6d782
NC
111 return errmsg;
112}
113
0e2ee3ca 114/* Handle lo(). */
87e6d782
NC
115
116static const char *
47b0e7ad 117parse_lo16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep)
87e6d782
NC
118{
119 const char *errmsg;
120 enum cgen_parse_operand_result result_type;
8f807746 121 unsigned long ret;
87e6d782
NC
122
123 if (**strp == '#')
124 ++*strp;
125
126 if (strncasecmp (*strp, "lo(", 3) == 0)
127 {
8f807746 128 bfd_vma value;
87e6d782 129
8f807746 130 *strp += 3;
33b71eeb 131 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
47b0e7ad 132 & result_type, & value);
87e6d782 133 if (**strp != ')')
47b0e7ad 134 return MISSING_CLOSING_PARENTHESIS;
87e6d782 135
8f807746
AM
136 ++*strp;
137 ret = value;
87e6d782 138 }
87e6d782 139 else
8f807746
AM
140 {
141 if (**strp == '-')
142 {
143 long value;
33b71eeb 144
8f807746
AM
145 errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value);
146 ret = value;
147 }
148 else
149 {
150 unsigned long value;
33b71eeb 151
8f807746
AM
152 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, &value);
153 ret = value;
154 }
155 }
156
157 *valuep = ((ret & 0xffff) ^ 0x8000) - 0x8000;
87e6d782
NC
158 return errmsg;
159}
160
161/* -- */
162
0e2ee3ca 163const char * openrisc_cgen_parse_operand
47b0e7ad 164 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
0e2ee3ca 165
87e6d782
NC
166/* Main entry point for operand parsing.
167
168 This function is basically just a big switch statement. Earlier versions
169 used tables to look up the function to use, but
170 - if the table contains both assembler and disassembler functions then
171 the disassembler contains much of the assembler and vice-versa,
172 - there's a lot of inlining possibilities as things grow,
173 - using a switch statement avoids the function call overhead.
174
175 This function could be moved into `parse_insn_normal', but keeping it
176 separate makes clear the interface between `parse_insn_normal' and each of
9a2e995d 177 the handlers. */
87e6d782
NC
178
179const char *
47b0e7ad
NC
180openrisc_cgen_parse_operand (CGEN_CPU_DESC cd,
181 int opindex,
182 const char ** strp,
183 CGEN_FIELDS * fields)
87e6d782
NC
184{
185 const char * errmsg = NULL;
186 /* Used by scalar operands that still need to be parsed. */
fc05c67f 187 long junk ATTRIBUTE_UNUSED;
87e6d782
NC
188
189 switch (opindex)
190 {
191 case OPENRISC_OPERAND_ABS_26 :
192 {
9494d739 193 bfd_vma value = 0;
87e6d782
NC
194 errmsg = cgen_parse_address (cd, strp, OPENRISC_OPERAND_ABS_26, 0, NULL, & value);
195 fields->f_abs26 = value;
196 }
197 break;
198 case OPENRISC_OPERAND_DISP_26 :
199 {
9494d739 200 bfd_vma value = 0;
87e6d782
NC
201 errmsg = cgen_parse_address (cd, strp, OPENRISC_OPERAND_DISP_26, 0, NULL, & value);
202 fields->f_disp26 = value;
203 }
204 break;
205 case OPENRISC_OPERAND_HI16 :
33b71eeb 206 errmsg = parse_hi16 (cd, strp, OPENRISC_OPERAND_HI16, (long *) (& fields->f_simm16));
87e6d782
NC
207 break;
208 case OPENRISC_OPERAND_LO16 :
33b71eeb 209 errmsg = parse_lo16 (cd, strp, OPENRISC_OPERAND_LO16, (long *) (& fields->f_lo16));
87e6d782
NC
210 break;
211 case OPENRISC_OPERAND_OP_F_23 :
33b71eeb 212 errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_OP_F_23, (unsigned long *) (& fields->f_op4));
87e6d782
NC
213 break;
214 case OPENRISC_OPERAND_OP_F_3 :
33b71eeb 215 errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_OP_F_3, (unsigned long *) (& fields->f_op5));
87e6d782
NC
216 break;
217 case OPENRISC_OPERAND_RA :
218 errmsg = cgen_parse_keyword (cd, strp, & openrisc_cgen_opval_h_gr, & fields->f_r2);
219 break;
220 case OPENRISC_OPERAND_RB :
221 errmsg = cgen_parse_keyword (cd, strp, & openrisc_cgen_opval_h_gr, & fields->f_r3);
222 break;
223 case OPENRISC_OPERAND_RD :
224 errmsg = cgen_parse_keyword (cd, strp, & openrisc_cgen_opval_h_gr, & fields->f_r1);
225 break;
226 case OPENRISC_OPERAND_SIMM_16 :
33b71eeb 227 errmsg = cgen_parse_signed_integer (cd, strp, OPENRISC_OPERAND_SIMM_16, (long *) (& fields->f_simm16));
87e6d782
NC
228 break;
229 case OPENRISC_OPERAND_UI16NC :
33b71eeb 230 errmsg = parse_lo16 (cd, strp, OPENRISC_OPERAND_UI16NC, (long *) (& fields->f_i16nc));
87e6d782
NC
231 break;
232 case OPENRISC_OPERAND_UIMM_16 :
33b71eeb 233 errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_UIMM_16, (unsigned long *) (& fields->f_uimm16));
87e6d782
NC
234 break;
235 case OPENRISC_OPERAND_UIMM_5 :
33b71eeb 236 errmsg = cgen_parse_unsigned_integer (cd, strp, OPENRISC_OPERAND_UIMM_5, (unsigned long *) (& fields->f_uimm5));
87e6d782
NC
237 break;
238
239 default :
240 /* xgettext:c-format */
241 fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
242 abort ();
243 }
244
245 return errmsg;
246}
247
248cgen_parse_fn * const openrisc_cgen_parse_handlers[] =
249{
250 parse_insn_normal,
251};
252
253void
47b0e7ad 254openrisc_cgen_init_asm (CGEN_CPU_DESC cd)
87e6d782
NC
255{
256 openrisc_cgen_init_opcode_table (cd);
257 openrisc_cgen_init_ibld_table (cd);
258 cd->parse_handlers = & openrisc_cgen_parse_handlers[0];
259 cd->parse_operand = openrisc_cgen_parse_operand;
1620f33d
AM
260#ifdef CGEN_ASM_INIT_HOOK
261CGEN_ASM_INIT_HOOK
262#endif
87e6d782
NC
263}
264
fc7bc883
RH
265\f
266
37111cc7 267/* Regex construction routine.
fc7bc883 268
37111cc7
NC
269 This translates an opcode syntax string into a regex string,
270 by replacing any non-character syntax element (such as an
271 opcode) with the pattern '.*'
fc7bc883 272
37111cc7
NC
273 It then compiles the regex and stores it in the opcode, for
274 later use by openrisc_cgen_assemble_insn
fc7bc883 275
37111cc7 276 Returns NULL for success, an error message for failure. */
fc7bc883
RH
277
278char *
ffead7ae 279openrisc_cgen_build_insn_regex (CGEN_INSN *insn)
fc7bc883 280{
fc05c67f 281 CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
fc7bc883 282 const char *mnem = CGEN_INSN_MNEMONIC (insn);
fc7bc883
RH
283 char rxbuf[CGEN_MAX_RX_ELEMENTS];
284 char *rx = rxbuf;
285 const CGEN_SYNTAX_CHAR_TYPE *syn;
286 int reg_err;
287
288 syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
289
f3a55c17
NC
290 /* Mnemonics come first in the syntax string. */
291 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
292 return _("missing mnemonic in syntax string");
fc7bc883
RH
293 ++syn;
294
f3a55c17
NC
295 /* Generate a case sensitive regular expression that emulates case
296 insensitive matching in the "C" locale. We cannot generate a case
297 insensitive regular expression because in Turkish locales, 'i' and 'I'
298 are not equal modulo case conversion. */
fc7bc883 299
f3a55c17
NC
300 /* Copy the literal mnemonic out of the insn. */
301 for (; *mnem; mnem++)
302 {
303 char c = *mnem;
304
305 if (ISALPHA (c))
306 {
307 *rx++ = '[';
308 *rx++ = TOLOWER (c);
309 *rx++ = TOUPPER (c);
310 *rx++ = ']';
311 }
312 else
313 *rx++ = c;
314 }
315
316 /* Copy any remaining literals from the syntax string into the rx. */
317 for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
fc7bc883
RH
318 {
319 if (CGEN_SYNTAX_CHAR_P (* syn))
320 {
f3a55c17
NC
321 char c = CGEN_SYNTAX_CHAR (* syn);
322
323 switch (c)
324 {
325 /* Escape any regex metacharacters in the syntax. */
326 case '.': case '[': case '\\':
327 case '*': case '^': case '$':
fc7bc883
RH
328
329#ifdef CGEN_ESCAPE_EXTENDED_REGEX
f3a55c17
NC
330 case '?': case '{': case '}':
331 case '(': case ')': case '*':
332 case '|': case '+': case ']':
fc7bc883 333#endif
f3a55c17
NC
334 *rx++ = '\\';
335 *rx++ = c;
336 break;
337
338 default:
339 if (ISALPHA (c))
340 {
341 *rx++ = '[';
342 *rx++ = TOLOWER (c);
343 *rx++ = TOUPPER (c);
344 *rx++ = ']';
345 }
346 else
347 *rx++ = c;
348 break;
349 }
fc7bc883
RH
350 }
351 else
352 {
f3a55c17
NC
353 /* Replace non-syntax fields with globs. */
354 *rx++ = '.';
355 *rx++ = '*';
fc7bc883
RH
356 }
357 }
358
f3a55c17 359 /* Trailing whitespace ok. */
fc7bc883
RH
360 * rx++ = '[';
361 * rx++ = ' ';
362 * rx++ = '\t';
363 * rx++ = ']';
364 * rx++ = '*';
365
f3a55c17 366 /* But anchor it after that. */
fc7bc883
RH
367 * rx++ = '$';
368 * rx = '\0';
369
370 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
f3a55c17 371 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
fc7bc883
RH
372
373 if (reg_err == 0)
374 return NULL;
375 else
376 {
377 static char msg[80];
f3a55c17 378
fc7bc883
RH
379 regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
380 regfree ((regex_t *) CGEN_INSN_RX (insn));
381 free (CGEN_INSN_RX (insn));
382 (CGEN_INSN_RX (insn)) = NULL;
37111cc7 383 return msg;
fc7bc883
RH
384 }
385}
386
87e6d782
NC
387\f
388/* Default insn parser.
389
390 The syntax string is scanned and operands are parsed and stored in FIELDS.
391 Relocs are queued as we go via other callbacks.
392
393 ??? Note that this is currently an all-or-nothing parser. If we fail to
394 parse the instruction, we return 0 and the caller will start over from
395 the beginning. Backtracking will be necessary in parsing subexpressions,
396 but that can be handled there. Not handling backtracking here may get
397 expensive in the case of the m68k. Deal with later.
398
f3a55c17 399 Returns NULL for success, an error message for failure. */
87e6d782
NC
400
401static const char *
ffead7ae
MM
402parse_insn_normal (CGEN_CPU_DESC cd,
403 const CGEN_INSN *insn,
404 const char **strp,
405 CGEN_FIELDS *fields)
87e6d782
NC
406{
407 /* ??? Runtime added insns not handled yet. */
408 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
409 const char *str = *strp;
410 const char *errmsg;
411 const char *p;
412 const CGEN_SYNTAX_CHAR_TYPE * syn;
413#ifdef CGEN_MNEMONIC_OPERANDS
414 /* FIXME: wip */
415 int past_opcode_p;
416#endif
417
418 /* For now we assume the mnemonic is first (there are no leading operands).
419 We can parse it without needing to set up operand parsing.
420 GAS's input scrubber will ensure mnemonics are lowercase, but we may
421 not be called from GAS. */
422 p = CGEN_INSN_MNEMONIC (insn);
37111cc7 423 while (*p && TOLOWER (*p) == TOLOWER (*str))
87e6d782
NC
424 ++p, ++str;
425
426 if (* p)
427 return _("unrecognized instruction");
428
429#ifndef CGEN_MNEMONIC_OPERANDS
37111cc7 430 if (* str && ! ISSPACE (* str))
87e6d782
NC
431 return _("unrecognized instruction");
432#endif
433
434 CGEN_INIT_PARSE (cd);
435 cgen_init_parse_operand (cd);
436#ifdef CGEN_MNEMONIC_OPERANDS
437 past_opcode_p = 0;
438#endif
439
440 /* We don't check for (*str != '\0') here because we want to parse
441 any trailing fake arguments in the syntax string. */
442 syn = CGEN_SYNTAX_STRING (syntax);
443
444 /* Mnemonics come first for now, ensure valid string. */
445 if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
446 abort ();
447
448 ++syn;
449
450 while (* syn != 0)
451 {
452 /* Non operand chars must match exactly. */
453 if (CGEN_SYNTAX_CHAR_P (* syn))
454 {
455 /* FIXME: While we allow for non-GAS callers above, we assume the
456 first char after the mnemonic part is a space. */
457 /* FIXME: We also take inappropriate advantage of the fact that
458 GAS's input scrubber will remove extraneous blanks. */
37111cc7 459 if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
87e6d782
NC
460 {
461#ifdef CGEN_MNEMONIC_OPERANDS
462 if (CGEN_SYNTAX_CHAR(* syn) == ' ')
463 past_opcode_p = 1;
464#endif
465 ++ syn;
466 ++ str;
467 }
468 else if (*str)
469 {
470 /* Syntax char didn't match. Can't be this insn. */
471 static char msg [80];
f3a55c17 472
87e6d782
NC
473 /* xgettext:c-format */
474 sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
475 CGEN_SYNTAX_CHAR(*syn), *str);
476 return msg;
477 }
478 else
479 {
480 /* Ran out of input. */
481 static char msg [80];
f3a55c17 482
87e6d782
NC
483 /* xgettext:c-format */
484 sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
485 CGEN_SYNTAX_CHAR(*syn));
486 return msg;
487 }
488 continue;
489 }
490
491 /* We have an operand of some sort. */
a978a3e5 492 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),
87e6d782
NC
493 &str, fields);
494 if (errmsg)
495 return errmsg;
496
497 /* Done with this operand, continue with next one. */
498 ++ syn;
499 }
500
501 /* If we're at the end of the syntax string, we're done. */
502 if (* syn == 0)
503 {
504 /* FIXME: For the moment we assume a valid `str' can only contain
505 blanks now. IE: We needn't try again with a longer version of
506 the insn and it is assumed that longer versions of insns appear
507 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
37111cc7 508 while (ISSPACE (* str))
87e6d782
NC
509 ++ str;
510
511 if (* str != '\0')
512 return _("junk at end of line"); /* FIXME: would like to include `str' */
513
514 return NULL;
515 }
516
517 /* We couldn't parse it. */
518 return _("unrecognized instruction");
519}
520\f
521/* Main entry point.
522 This routine is called for each instruction to be assembled.
523 STR points to the insn to be assembled.
524 We assume all necessary tables have been initialized.
525 The assembled instruction, less any fixups, is stored in BUF.
526 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
527 still needs to be converted to target byte order, otherwise BUF is an array
528 of bytes in target byte order.
529 The result is a pointer to the insn's entry in the opcode table,
530 or NULL if an error occured (an error message will have already been
531 printed).
532
533 Note that when processing (non-alias) macro-insns,
534 this function recurses.
535
536 ??? It's possible to make this cpu-independent.
537 One would have to deal with a few minor things.
538 At this point in time doing so would be more of a curiosity than useful
539 [for example this file isn't _that_ big], but keeping the possibility in
540 mind helps keep the design clean. */
541
542const CGEN_INSN *
ffead7ae
MM
543openrisc_cgen_assemble_insn (CGEN_CPU_DESC cd,
544 const char *str,
545 CGEN_FIELDS *fields,
546 CGEN_INSN_BYTES_PTR buf,
547 char **errmsg)
87e6d782
NC
548{
549 const char *start;
550 CGEN_INSN_LIST *ilist;
551 const char *parse_errmsg = NULL;
552 const char *insert_errmsg = NULL;
fc7bc883 553 int recognized_mnemonic = 0;
87e6d782
NC
554
555 /* Skip leading white space. */
37111cc7 556 while (ISSPACE (* str))
87e6d782
NC
557 ++ str;
558
559 /* The instructions are stored in hashed lists.
560 Get the first in the list. */
561 ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
562
563 /* Keep looking until we find a match. */
87e6d782
NC
564 start = str;
565 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
566 {
567 const CGEN_INSN *insn = ilist->insn;
fc7bc883 568 recognized_mnemonic = 1;
87e6d782
NC
569
570#ifdef CGEN_VALIDATE_INSN_SUPPORTED
f3a55c17
NC
571 /* Not usually needed as unsupported opcodes
572 shouldn't be in the hash lists. */
87e6d782
NC
573 /* Is this insn supported by the selected cpu? */
574 if (! openrisc_cgen_insn_supported (cd, insn))
575 continue;
576#endif
b11dcf4e 577 /* If the RELAXED attribute is set, this is an insn that shouldn't be
87e6d782
NC
578 chosen immediately. Instead, it is used during assembler/linker
579 relaxation if possible. */
b11dcf4e 580 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
87e6d782
NC
581 continue;
582
583 str = start;
584
f3a55c17 585 /* Skip this insn if str doesn't look right lexically. */
fc7bc883
RH
586 if (CGEN_INSN_RX (insn) != NULL &&
587 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
588 continue;
589
87e6d782
NC
590 /* Allow parse/insert handlers to obtain length of insn. */
591 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
592
593 parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
594 if (parse_errmsg != NULL)
595 continue;
596
f3a55c17 597 /* ??? 0 is passed for `pc'. */
87e6d782
NC
598 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
599 (bfd_vma) 0);
600 if (insert_errmsg != NULL)
601 continue;
602
603 /* It is up to the caller to actually output the insn and any
604 queued relocs. */
605 return insn;
606 }
607
608 {
609 static char errbuf[150];
610#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
611 const char *tmp_errmsg;
612
613 /* If requesting verbose error messages, use insert_errmsg.
f3a55c17 614 Failing that, use parse_errmsg. */
87e6d782
NC
615 tmp_errmsg = (insert_errmsg ? insert_errmsg :
616 parse_errmsg ? parse_errmsg :
f3a55c17
NC
617 recognized_mnemonic ?
618 _("unrecognized form of instruction") :
87e6d782
NC
619 _("unrecognized instruction"));
620
621 if (strlen (start) > 50)
622 /* xgettext:c-format */
623 sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
624 else
625 /* xgettext:c-format */
626 sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
627#else
628 if (strlen (start) > 50)
629 /* xgettext:c-format */
630 sprintf (errbuf, _("bad instruction `%.50s...'"), start);
631 else
632 /* xgettext:c-format */
633 sprintf (errbuf, _("bad instruction `%.50s'"), start);
634#endif
635
636 *errmsg = errbuf;
637 return NULL;
638 }
639}
This page took 0.520788 seconds and 4 git commands to generate.