1
/* Assembler interface for targets using CGEN. -*- C -*-
2
CGEN: Cpu tools GENerator
4
THIS FILE IS MACHINE GENERATED WITH CGEN.
5
- the resultant file is machine generated, cgen-asm.in isn't
7
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2007, 2008, 2010
8
Free Software Foundation, Inc.
10
This file is part of libopcodes.
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)
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.
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. */
27
/* ??? Eventually more and more of this stuff can go to cpu-independent files.
35
#include "xc16x-desc.h"
36
#include "xc16x-opc.h"
39
#include "libiberty.h"
40
#include "safe-ctype.h"
43
#define min(a,b) ((a) < (b) ? (a) : (b))
45
#define max(a,b) ((a) > (b) ? (a) : (b))
47
static const char * parse_insn_normal
48
(CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
50
/* -- assembler routines inserted here. */
53
/* Handle '#' prefixes (i.e. skip over them). */
56
parse_hash (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
58
int opindex ATTRIBUTE_UNUSED,
59
long *valuep ATTRIBUTE_UNUSED)
66
return _("Missing '#' prefix");
69
/* Handle '.' prefixes (i.e. skip over them). */
72
parse_dot (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
74
int opindex ATTRIBUTE_UNUSED,
75
long *valuep ATTRIBUTE_UNUSED)
82
return _("Missing '.' prefix");
85
/* Handle 'pof:' prefixes (i.e. skip over them). */
88
parse_pof (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
90
int opindex ATTRIBUTE_UNUSED,
91
long *valuep ATTRIBUTE_UNUSED)
93
if (strncasecmp (*strp, "pof:", 4) == 0)
98
return _("Missing 'pof:' prefix");
101
/* Handle 'pag:' prefixes (i.e. skip over them). */
104
parse_pag (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
106
int opindex ATTRIBUTE_UNUSED,
107
long *valuep ATTRIBUTE_UNUSED)
109
if (strncasecmp (*strp, "pag:", 4) == 0)
114
return _("Missing 'pag:' prefix");
117
/* Handle 'sof' prefixes (i.e. skip over them). */
120
parse_sof (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
122
int opindex ATTRIBUTE_UNUSED,
123
long *valuep ATTRIBUTE_UNUSED)
125
if (strncasecmp (*strp, "sof:", 4) == 0)
130
return _("Missing 'sof:' prefix");
133
/* Handle 'seg' prefixes (i.e. skip over them). */
136
parse_seg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
138
int opindex ATTRIBUTE_UNUSED,
139
long *valuep ATTRIBUTE_UNUSED)
141
if (strncasecmp (*strp, "seg:", 4) == 0)
146
return _("Missing 'seg:' prefix");
150
const char * xc16x_cgen_parse_operand
151
(CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
153
/* Main entry point for operand parsing.
155
This function is basically just a big switch statement. Earlier versions
156
used tables to look up the function to use, but
157
- if the table contains both assembler and disassembler functions then
158
the disassembler contains much of the assembler and vice-versa,
159
- there's a lot of inlining possibilities as things grow,
160
- using a switch statement avoids the function call overhead.
162
This function could be moved into `parse_insn_normal', but keeping it
163
separate makes clear the interface between `parse_insn_normal' and each of
167
xc16x_cgen_parse_operand (CGEN_CPU_DESC cd,
170
CGEN_FIELDS * fields)
172
const char * errmsg = NULL;
173
/* Used by scalar operands that still need to be parsed. */
174
long junk ATTRIBUTE_UNUSED;
178
case XC16X_OPERAND_REGNAM :
179
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_psw_names, & fields->f_reg8);
181
case XC16X_OPERAND_BIT01 :
182
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_BIT01, (unsigned long *) (& fields->f_op_1bit));
184
case XC16X_OPERAND_BIT1 :
185
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_BIT1, (unsigned long *) (& fields->f_op_bit1));
187
case XC16X_OPERAND_BIT2 :
188
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_BIT2, (unsigned long *) (& fields->f_op_bit2));
190
case XC16X_OPERAND_BIT4 :
191
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_BIT4, (unsigned long *) (& fields->f_op_bit4));
193
case XC16X_OPERAND_BIT8 :
194
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_BIT8, (unsigned long *) (& fields->f_op_bit8));
196
case XC16X_OPERAND_BITONE :
197
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_BITONE, (unsigned long *) (& fields->f_op_onebit));
199
case XC16X_OPERAND_CADDR :
202
errmsg = cgen_parse_address (cd, strp, XC16X_OPERAND_CADDR, 0, NULL, & value);
203
fields->f_offset16 = value;
206
case XC16X_OPERAND_COND :
207
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_conditioncode_names, & fields->f_condcode);
209
case XC16X_OPERAND_DATA8 :
210
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_DATA8, (unsigned long *) (& fields->f_data8));
212
case XC16X_OPERAND_DATAHI8 :
213
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_DATAHI8, (unsigned long *) (& fields->f_datahi8));
215
case XC16X_OPERAND_DOT :
216
errmsg = parse_dot (cd, strp, XC16X_OPERAND_DOT, (long *) (& junk));
218
case XC16X_OPERAND_DR :
219
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_gr_names, & fields->f_r1);
221
case XC16X_OPERAND_DRB :
222
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_grb_names, & fields->f_r1);
224
case XC16X_OPERAND_DRI :
225
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_gr_names, & fields->f_r4);
227
case XC16X_OPERAND_EXTCOND :
228
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_extconditioncode_names, & fields->f_extccode);
230
case XC16X_OPERAND_GENREG :
231
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_r8_names, & fields->f_regb8);
233
case XC16X_OPERAND_HASH :
234
errmsg = parse_hash (cd, strp, XC16X_OPERAND_HASH, (long *) (& junk));
236
case XC16X_OPERAND_ICOND :
237
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_conditioncode_names, & fields->f_icondcode);
239
case XC16X_OPERAND_LBIT2 :
240
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_LBIT2, (unsigned long *) (& fields->f_op_lbit2));
242
case XC16X_OPERAND_LBIT4 :
243
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_LBIT4, (unsigned long *) (& fields->f_op_lbit4));
245
case XC16X_OPERAND_MASK8 :
246
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_MASK8, (unsigned long *) (& fields->f_mask8));
248
case XC16X_OPERAND_MASKLO8 :
249
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_MASKLO8, (unsigned long *) (& fields->f_datahi8));
251
case XC16X_OPERAND_MEMGR8 :
252
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_memgr8_names, & fields->f_memgr8);
254
case XC16X_OPERAND_MEMORY :
257
errmsg = cgen_parse_address (cd, strp, XC16X_OPERAND_MEMORY, 0, NULL, & value);
258
fields->f_memory = value;
261
case XC16X_OPERAND_PAG :
262
errmsg = parse_pag (cd, strp, XC16X_OPERAND_PAG, (long *) (& junk));
264
case XC16X_OPERAND_PAGENUM :
265
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_PAGENUM, (unsigned long *) (& fields->f_pagenum));
267
case XC16X_OPERAND_POF :
268
errmsg = parse_pof (cd, strp, XC16X_OPERAND_POF, (long *) (& junk));
270
case XC16X_OPERAND_QBIT :
271
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_QBIT, (unsigned long *) (& fields->f_qbit));
273
case XC16X_OPERAND_QHIBIT :
274
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_QHIBIT, (unsigned long *) (& fields->f_qhibit));
276
case XC16X_OPERAND_QLOBIT :
277
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_QLOBIT, (unsigned long *) (& fields->f_qlobit));
279
case XC16X_OPERAND_REG8 :
280
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_r8_names, & fields->f_reg8);
282
case XC16X_OPERAND_REGB8 :
283
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_grb8_names, & fields->f_regb8);
285
case XC16X_OPERAND_REGBMEM8 :
286
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_regbmem8_names, & fields->f_regmem8);
288
case XC16X_OPERAND_REGHI8 :
289
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_r8_names, & fields->f_reghi8);
291
case XC16X_OPERAND_REGMEM8 :
292
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_regmem8_names, & fields->f_regmem8);
294
case XC16X_OPERAND_REGOFF8 :
295
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_r8_names, & fields->f_regoff8);
297
case XC16X_OPERAND_REL :
298
errmsg = cgen_parse_signed_integer (cd, strp, XC16X_OPERAND_REL, (long *) (& fields->f_rel8));
300
case XC16X_OPERAND_RELHI :
301
errmsg = cgen_parse_signed_integer (cd, strp, XC16X_OPERAND_RELHI, (long *) (& fields->f_relhi8));
303
case XC16X_OPERAND_SEG :
304
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_SEG, (unsigned long *) (& fields->f_seg8));
306
case XC16X_OPERAND_SEGHI8 :
307
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_SEGHI8, (unsigned long *) (& fields->f_segnum8));
309
case XC16X_OPERAND_SEGM :
310
errmsg = parse_seg (cd, strp, XC16X_OPERAND_SEGM, (long *) (& junk));
312
case XC16X_OPERAND_SOF :
313
errmsg = parse_sof (cd, strp, XC16X_OPERAND_SOF, (long *) (& junk));
315
case XC16X_OPERAND_SR :
316
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_gr_names, & fields->f_r2);
318
case XC16X_OPERAND_SR2 :
319
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_gr_names, & fields->f_r0);
321
case XC16X_OPERAND_SRB :
322
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_grb_names, & fields->f_r2);
324
case XC16X_OPERAND_SRC1 :
325
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_gr_names, & fields->f_r1);
327
case XC16X_OPERAND_SRC2 :
328
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_gr_names, & fields->f_r2);
330
case XC16X_OPERAND_SRDIV :
331
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_regdiv8_names, & fields->f_reg8);
333
case XC16X_OPERAND_U4 :
334
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_reg0_name, & fields->f_uimm4);
336
case XC16X_OPERAND_UIMM16 :
337
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_UIMM16, (unsigned long *) (& fields->f_uimm16));
339
case XC16X_OPERAND_UIMM2 :
340
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_ext_names, & fields->f_uimm2);
342
case XC16X_OPERAND_UIMM3 :
343
errmsg = cgen_parse_keyword (cd, strp, & xc16x_cgen_opval_reg0_name1, & fields->f_uimm3);
345
case XC16X_OPERAND_UIMM4 :
346
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_UIMM4, (unsigned long *) (& fields->f_uimm4));
348
case XC16X_OPERAND_UIMM7 :
349
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_UIMM7, (unsigned long *) (& fields->f_uimm7));
351
case XC16X_OPERAND_UIMM8 :
352
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_UIMM8, (unsigned long *) (& fields->f_uimm8));
354
case XC16X_OPERAND_UPAG16 :
355
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_UPAG16, (unsigned long *) (& fields->f_uimm16));
357
case XC16X_OPERAND_UPOF16 :
360
errmsg = cgen_parse_address (cd, strp, XC16X_OPERAND_UPOF16, 0, NULL, & value);
361
fields->f_memory = value;
364
case XC16X_OPERAND_USEG16 :
365
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_USEG16, (unsigned long *) (& fields->f_offset16));
367
case XC16X_OPERAND_USEG8 :
368
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_USEG8, (unsigned long *) (& fields->f_seg8));
370
case XC16X_OPERAND_USOF16 :
371
errmsg = cgen_parse_unsigned_integer (cd, strp, XC16X_OPERAND_USOF16, (unsigned long *) (& fields->f_offset16));
375
/* xgettext:c-format */
376
fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
383
cgen_parse_fn * const xc16x_cgen_parse_handlers[] =
389
xc16x_cgen_init_asm (CGEN_CPU_DESC cd)
391
xc16x_cgen_init_opcode_table (cd);
392
xc16x_cgen_init_ibld_table (cd);
393
cd->parse_handlers = & xc16x_cgen_parse_handlers[0];
394
cd->parse_operand = xc16x_cgen_parse_operand;
395
#ifdef CGEN_ASM_INIT_HOOK
402
/* Regex construction routine.
404
This translates an opcode syntax string into a regex string,
405
by replacing any non-character syntax element (such as an
406
opcode) with the pattern '.*'
408
It then compiles the regex and stores it in the opcode, for
409
later use by xc16x_cgen_assemble_insn
411
Returns NULL for success, an error message for failure. */
414
xc16x_cgen_build_insn_regex (CGEN_INSN *insn)
416
CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
417
const char *mnem = CGEN_INSN_MNEMONIC (insn);
418
char rxbuf[CGEN_MAX_RX_ELEMENTS];
420
const CGEN_SYNTAX_CHAR_TYPE *syn;
423
syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
425
/* Mnemonics come first in the syntax string. */
426
if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
427
return _("missing mnemonic in syntax string");
430
/* Generate a case sensitive regular expression that emulates case
431
insensitive matching in the "C" locale. We cannot generate a case
432
insensitive regular expression because in Turkish locales, 'i' and 'I'
433
are not equal modulo case conversion. */
435
/* Copy the literal mnemonic out of the insn. */
436
for (; *mnem; mnem++)
451
/* Copy any remaining literals from the syntax string into the rx. */
452
for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
454
if (CGEN_SYNTAX_CHAR_P (* syn))
456
char c = CGEN_SYNTAX_CHAR (* syn);
460
/* Escape any regex metacharacters in the syntax. */
461
case '.': case '[': case '\\':
462
case '*': case '^': case '$':
464
#ifdef CGEN_ESCAPE_EXTENDED_REGEX
465
case '?': case '{': case '}':
466
case '(': case ')': case '*':
467
case '|': case '+': case ']':
488
/* Replace non-syntax fields with globs. */
494
/* Trailing whitespace ok. */
501
/* But anchor it after that. */
505
CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
506
reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
514
regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
515
regfree ((regex_t *) CGEN_INSN_RX (insn));
516
free (CGEN_INSN_RX (insn));
517
(CGEN_INSN_RX (insn)) = NULL;
523
/* Default insn parser.
525
The syntax string is scanned and operands are parsed and stored in FIELDS.
526
Relocs are queued as we go via other callbacks.
528
??? Note that this is currently an all-or-nothing parser. If we fail to
529
parse the instruction, we return 0 and the caller will start over from
530
the beginning. Backtracking will be necessary in parsing subexpressions,
531
but that can be handled there. Not handling backtracking here may get
532
expensive in the case of the m68k. Deal with later.
534
Returns NULL for success, an error message for failure. */
537
parse_insn_normal (CGEN_CPU_DESC cd,
538
const CGEN_INSN *insn,
542
/* ??? Runtime added insns not handled yet. */
543
const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
544
const char *str = *strp;
547
const CGEN_SYNTAX_CHAR_TYPE * syn;
548
#ifdef CGEN_MNEMONIC_OPERANDS
553
/* For now we assume the mnemonic is first (there are no leading operands).
554
We can parse it without needing to set up operand parsing.
555
GAS's input scrubber will ensure mnemonics are lowercase, but we may
556
not be called from GAS. */
557
p = CGEN_INSN_MNEMONIC (insn);
558
while (*p && TOLOWER (*p) == TOLOWER (*str))
562
return _("unrecognized instruction");
564
#ifndef CGEN_MNEMONIC_OPERANDS
565
if (* str && ! ISSPACE (* str))
566
return _("unrecognized instruction");
569
CGEN_INIT_PARSE (cd);
570
cgen_init_parse_operand (cd);
571
#ifdef CGEN_MNEMONIC_OPERANDS
575
/* We don't check for (*str != '\0') here because we want to parse
576
any trailing fake arguments in the syntax string. */
577
syn = CGEN_SYNTAX_STRING (syntax);
579
/* Mnemonics come first for now, ensure valid string. */
580
if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
587
/* Non operand chars must match exactly. */
588
if (CGEN_SYNTAX_CHAR_P (* syn))
590
/* FIXME: While we allow for non-GAS callers above, we assume the
591
first char after the mnemonic part is a space. */
592
/* FIXME: We also take inappropriate advantage of the fact that
593
GAS's input scrubber will remove extraneous blanks. */
594
if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
596
#ifdef CGEN_MNEMONIC_OPERANDS
597
if (CGEN_SYNTAX_CHAR(* syn) == ' ')
605
/* Syntax char didn't match. Can't be this insn. */
606
static char msg [80];
608
/* xgettext:c-format */
609
sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
610
CGEN_SYNTAX_CHAR(*syn), *str);
615
/* Ran out of input. */
616
static char msg [80];
618
/* xgettext:c-format */
619
sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
620
CGEN_SYNTAX_CHAR(*syn));
626
#ifdef CGEN_MNEMONIC_OPERANDS
627
(void) past_opcode_p;
629
/* We have an operand of some sort. */
630
errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
634
/* Done with this operand, continue with next one. */
638
/* If we're at the end of the syntax string, we're done. */
641
/* FIXME: For the moment we assume a valid `str' can only contain
642
blanks now. IE: We needn't try again with a longer version of
643
the insn and it is assumed that longer versions of insns appear
644
before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */
645
while (ISSPACE (* str))
649
return _("junk at end of line"); /* FIXME: would like to include `str' */
654
/* We couldn't parse it. */
655
return _("unrecognized instruction");
659
This routine is called for each instruction to be assembled.
660
STR points to the insn to be assembled.
661
We assume all necessary tables have been initialized.
662
The assembled instruction, less any fixups, is stored in BUF.
663
Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
664
still needs to be converted to target byte order, otherwise BUF is an array
665
of bytes in target byte order.
666
The result is a pointer to the insn's entry in the opcode table,
667
or NULL if an error occured (an error message will have already been
670
Note that when processing (non-alias) macro-insns,
671
this function recurses.
673
??? It's possible to make this cpu-independent.
674
One would have to deal with a few minor things.
675
At this point in time doing so would be more of a curiosity than useful
676
[for example this file isn't _that_ big], but keeping the possibility in
677
mind helps keep the design clean. */
680
xc16x_cgen_assemble_insn (CGEN_CPU_DESC cd,
683
CGEN_INSN_BYTES_PTR buf,
687
CGEN_INSN_LIST *ilist;
688
const char *parse_errmsg = NULL;
689
const char *insert_errmsg = NULL;
690
int recognized_mnemonic = 0;
692
/* Skip leading white space. */
693
while (ISSPACE (* str))
696
/* The instructions are stored in hashed lists.
697
Get the first in the list. */
698
ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
700
/* Keep looking until we find a match. */
702
for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
704
const CGEN_INSN *insn = ilist->insn;
705
recognized_mnemonic = 1;
707
#ifdef CGEN_VALIDATE_INSN_SUPPORTED
708
/* Not usually needed as unsupported opcodes
709
shouldn't be in the hash lists. */
710
/* Is this insn supported by the selected cpu? */
711
if (! xc16x_cgen_insn_supported (cd, insn))
714
/* If the RELAXED attribute is set, this is an insn that shouldn't be
715
chosen immediately. Instead, it is used during assembler/linker
716
relaxation if possible. */
717
if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
722
/* Skip this insn if str doesn't look right lexically. */
723
if (CGEN_INSN_RX (insn) != NULL &&
724
regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
727
/* Allow parse/insert handlers to obtain length of insn. */
728
CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
730
parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
731
if (parse_errmsg != NULL)
734
/* ??? 0 is passed for `pc'. */
735
insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
737
if (insert_errmsg != NULL)
740
/* It is up to the caller to actually output the insn and any
746
static char errbuf[150];
747
const char *tmp_errmsg;
748
#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
756
/* If requesting verbose error messages, use insert_errmsg.
757
Failing that, use parse_errmsg. */
758
tmp_errmsg = (insert_errmsg ? insert_errmsg :
759
parse_errmsg ? parse_errmsg :
760
recognized_mnemonic ?
761
_("unrecognized form of instruction") :
762
_("unrecognized instruction"));
764
if (strlen (start) > 50)
765
/* xgettext:c-format */
766
sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
768
/* xgettext:c-format */
769
sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
773
if (strlen (start) > 50)
774
/* xgettext:c-format */
775
sprintf (errbuf, _("bad instruction `%.50s...'"), start);
777
/* xgettext:c-format */
778
sprintf (errbuf, _("bad instruction `%.50s'"), start);