1 /* DO NOT EDIT! -*- buffer-read-only: t -*- vi:set ro: */ 2 /* Assembler interface for targets using CGEN. -*- C -*- 3 CGEN: Cpu tools GENerator 4 5 THIS FILE IS MACHINE GENERATED WITH CGEN. 6 - the resultant file is machine generated, cgen-asm.in isn't 7 8 Copyright (C) 1996-2025 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 "fr30-desc.h" 36 #include "fr30-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 50 /* -- assembler routines inserted here. */ 52 53 /* -- asm.c */ 54 /* Handle register lists for LDMx and STMx. */ 55 56 static int 57 parse_register_number (const char **strp) 58 { 59 int regno; 60 61 if (**strp < '0' || **strp > '9') 62 return -1; /* Error. */ 63 regno = **strp - '0'; 64 ++*strp; 65 66 if (**strp >= '0' && **strp <= '9') 67 { 68 regno = regno * 10 + (**strp - '0'); 69 ++*strp; 70 } 71 72 return regno; 73 } 74 75 static const char * 76 parse_register_list (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, 77 const char **strp, 78 int opindex ATTRIBUTE_UNUSED, 79 unsigned long *valuep, 80 int high_low, /* 0 == high, 1 == low. */ 81 int load_store) /* 0 == load, 1 == store. */ 82 { 83 *valuep = 0; 84 while (**strp && **strp != ')') 85 { 86 int regno; 87 88 if (**strp != 'R' && **strp != 'r') 89 break; 90 ++*strp; 91 92 regno = parse_register_number (strp); 93 if (regno == -1) 94 return _("Register number is not valid"); 95 if (regno > 7 && !high_low) 96 return _("Register must be between r0 and r7"); 97 if (regno < 8 && high_low) 98 return _("Register must be between r8 and r15"); 99 100 if (high_low) 101 regno -= 8; 102 103 if (load_store) /* Mask is reversed for store. */ 104 *valuep |= 0x80 >> regno; 105 else 106 *valuep |= 1 << regno; 107 108 if (**strp == ',') 109 { 110 if (*(*strp + 1) == ')') 111 break; 112 ++*strp; 113 } 114 } 115 116 if (!*strp || **strp != ')') 117 return _("Register list is not valid"); 118 119 return NULL; 120 } 121 122 static const char * 123 parse_low_register_list_ld (CGEN_CPU_DESC cd, 124 const char **strp, 125 int opindex, 126 unsigned long *valuep) 127 { 128 return parse_register_list (cd, strp, opindex, valuep, 129 0 /* Low. */, 0 /* Load. */); 130 } 131 132 static const char * 133 parse_hi_register_list_ld (CGEN_CPU_DESC cd, 134 const char **strp, 135 int opindex, 136 unsigned long *valuep) 137 { 138 return parse_register_list (cd, strp, opindex, valuep, 139 1 /* High. */, 0 /* Load. */); 140 } 141 142 static const char * 143 parse_low_register_list_st (CGEN_CPU_DESC cd, 144 const char **strp, 145 int opindex, 146 unsigned long *valuep) 147 { 148 return parse_register_list (cd, strp, opindex, valuep, 149 0 /* Low. */, 1 /* Store. */); 150 } 151 152 static const char * 153 parse_hi_register_list_st (CGEN_CPU_DESC cd, 154 const char **strp, 155 int opindex, 156 unsigned long *valuep) 157 { 158 return parse_register_list (cd, strp, opindex, valuep, 159 1 /* High. */, 1 /* Store. */); 160 } 161 162 /* -- */ 163 164 const char * fr30_cgen_parse_operand 165 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *); 166 167 /* Main entry point for operand parsing. 168 169 This function is basically just a big switch statement. Earlier versions 170 used tables to look up the function to use, but 171 - if the table contains both assembler and disassembler functions then 172 the disassembler contains much of the assembler and vice-versa, 173 - there's a lot of inlining possibilities as things grow, 174 - using a switch statement avoids the function call overhead. 175 176 This function could be moved into `parse_insn_normal', but keeping it 177 separate makes clear the interface between `parse_insn_normal' and each of 178 the handlers. */ 179 180 const char * 181 fr30_cgen_parse_operand (CGEN_CPU_DESC cd, 182 int opindex, 183 const char ** strp, 184 CGEN_FIELDS * fields) 185 { 186 const char * errmsg = NULL; 187 /* Used by scalar operands that still need to be parsed. */ 188 long junk ATTRIBUTE_UNUSED; 189 190 switch (opindex) 191 { 192 case FR30_OPERAND_CRI : 193 errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_cr_names, & fields->f_CRi); 194 break; 195 case FR30_OPERAND_CRJ : 196 errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_cr_names, & fields->f_CRj); 197 break; 198 case FR30_OPERAND_R13 : 199 errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_h_r13, & junk); 200 break; 201 case FR30_OPERAND_R14 : 202 errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_h_r14, & junk); 203 break; 204 case FR30_OPERAND_R15 : 205 errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_h_r15, & junk); 206 break; 207 case FR30_OPERAND_RI : 208 errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_gr_names, & fields->f_Ri); 209 break; 210 case FR30_OPERAND_RIC : 211 errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_gr_names, & fields->f_Ric); 212 break; 213 case FR30_OPERAND_RJ : 214 errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_gr_names, & fields->f_Rj); 215 break; 216 case FR30_OPERAND_RJC : 217 errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_gr_names, & fields->f_Rjc); 218 break; 219 case FR30_OPERAND_RS1 : 220 errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_dr_names, & fields->f_Rs1); 221 break; 222 case FR30_OPERAND_RS2 : 223 errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_dr_names, & fields->f_Rs2); 224 break; 225 case FR30_OPERAND_CC : 226 errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_CC, (unsigned long *) (& fields->f_cc)); 227 break; 228 case FR30_OPERAND_CCC : 229 errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_CCC, (unsigned long *) (& fields->f_ccc)); 230 break; 231 case FR30_OPERAND_DIR10 : 232 errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_DIR10, (unsigned long *) (& fields->f_dir10)); 233 break; 234 case FR30_OPERAND_DIR8 : 235 errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_DIR8, (unsigned long *) (& fields->f_dir8)); 236 break; 237 case FR30_OPERAND_DIR9 : 238 errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_DIR9, (unsigned long *) (& fields->f_dir9)); 239 break; 240 case FR30_OPERAND_DISP10 : 241 errmsg = cgen_parse_signed_integer (cd, strp, FR30_OPERAND_DISP10, (long *) (& fields->f_disp10)); 242 break; 243 case FR30_OPERAND_DISP8 : 244 errmsg = cgen_parse_signed_integer (cd, strp, FR30_OPERAND_DISP8, (long *) (& fields->f_disp8)); 245 break; 246 case FR30_OPERAND_DISP9 : 247 errmsg = cgen_parse_signed_integer (cd, strp, FR30_OPERAND_DISP9, (long *) (& fields->f_disp9)); 248 break; 249 case FR30_OPERAND_I20 : 250 errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_I20, (unsigned long *) (& fields->f_i20)); 251 break; 252 case FR30_OPERAND_I32 : 253 errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_I32, (unsigned long *) (& fields->f_i32)); 254 break; 255 case FR30_OPERAND_I8 : 256 errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_I8, (unsigned long *) (& fields->f_i8)); 257 break; 258 case FR30_OPERAND_LABEL12 : 259 { 260 bfd_vma value = 0; 261 errmsg = cgen_parse_address (cd, strp, FR30_OPERAND_LABEL12, 0, NULL, & value); 262 fields->f_rel12 = value; 263 } 264 break; 265 case FR30_OPERAND_LABEL9 : 266 { 267 bfd_vma value = 0; 268 errmsg = cgen_parse_address (cd, strp, FR30_OPERAND_LABEL9, 0, NULL, & value); 269 fields->f_rel9 = value; 270 } 271 break; 272 case FR30_OPERAND_M4 : 273 errmsg = cgen_parse_signed_integer (cd, strp, FR30_OPERAND_M4, (long *) (& fields->f_m4)); 274 break; 275 case FR30_OPERAND_PS : 276 errmsg = cgen_parse_keyword (cd, strp, & fr30_cgen_opval_h_ps, & junk); 277 break; 278 case FR30_OPERAND_REGLIST_HI_LD : 279 errmsg = parse_hi_register_list_ld (cd, strp, FR30_OPERAND_REGLIST_HI_LD, (unsigned long *) (& fields->f_reglist_hi_ld)); 280 break; 281 case FR30_OPERAND_REGLIST_HI_ST : 282 errmsg = parse_hi_register_list_st (cd, strp, FR30_OPERAND_REGLIST_HI_ST, (unsigned long *) (& fields->f_reglist_hi_st)); 283 break; 284 case FR30_OPERAND_REGLIST_LOW_LD : 285 errmsg = parse_low_register_list_ld (cd, strp, FR30_OPERAND_REGLIST_LOW_LD, (unsigned long *) (& fields->f_reglist_low_ld)); 286 break; 287 case FR30_OPERAND_REGLIST_LOW_ST : 288 errmsg = parse_low_register_list_st (cd, strp, FR30_OPERAND_REGLIST_LOW_ST, (unsigned long *) (& fields->f_reglist_low_st)); 289 break; 290 case FR30_OPERAND_S10 : 291 errmsg = cgen_parse_signed_integer (cd, strp, FR30_OPERAND_S10, (long *) (& fields->f_s10)); 292 break; 293 case FR30_OPERAND_U10 : 294 errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_U10, (unsigned long *) (& fields->f_u10)); 295 break; 296 case FR30_OPERAND_U4 : 297 errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_U4, (unsigned long *) (& fields->f_u4)); 298 break; 299 case FR30_OPERAND_U4C : 300 errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_U4C, (unsigned long *) (& fields->f_u4c)); 301 break; 302 case FR30_OPERAND_U8 : 303 errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_U8, (unsigned long *) (& fields->f_u8)); 304 break; 305 case FR30_OPERAND_UDISP6 : 306 errmsg = cgen_parse_unsigned_integer (cd, strp, FR30_OPERAND_UDISP6, (unsigned long *) (& fields->f_udisp6)); 307 break; 308 309 default : 310 /* xgettext:c-format */ 311 opcodes_error_handler 312 (_("internal error: unrecognized field %d while parsing"), 313 opindex); 314 abort (); 315 } 316 317 return errmsg; 318 } 319 320 cgen_parse_fn * const fr30_cgen_parse_handlers[] = 321 { 322 parse_insn_normal, 323 }; 324 325 void 326 fr30_cgen_init_asm (CGEN_CPU_DESC cd) 327 { 328 fr30_cgen_init_opcode_table (cd); 329 fr30_cgen_init_ibld_table (cd); 330 cd->parse_handlers = & fr30_cgen_parse_handlers[0]; 331 cd->parse_operand = fr30_cgen_parse_operand; 332 #ifdef CGEN_ASM_INIT_HOOK 333 CGEN_ASM_INIT_HOOK 334 #endif 335 } 336 337 338 340 /* Regex construction routine. 341 342 This translates an opcode syntax string into a regex string, 343 by replacing any non-character syntax element (such as an 344 opcode) with the pattern '.*' 345 346 It then compiles the regex and stores it in the opcode, for 347 later use by fr30_cgen_assemble_insn 348 349 Returns NULL for success, an error message for failure. */ 350 351 char * 352 fr30_cgen_build_insn_regex (CGEN_INSN *insn) 353 { 354 CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn); 355 const char *mnem = CGEN_INSN_MNEMONIC (insn); 356 char rxbuf[CGEN_MAX_RX_ELEMENTS]; 357 char *rx = rxbuf; 358 const CGEN_SYNTAX_CHAR_TYPE *syn; 359 int reg_err; 360 361 syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc)); 362 363 /* Mnemonics come first in the syntax string. */ 364 if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) 365 return _("missing mnemonic in syntax string"); 366 ++syn; 367 368 /* Generate a case sensitive regular expression that emulates case 369 insensitive matching in the "C" locale. We cannot generate a case 370 insensitive regular expression because in Turkish locales, 'i' and 'I' 371 are not equal modulo case conversion. */ 372 373 /* Copy the literal mnemonic out of the insn. */ 374 for (; *mnem; mnem++) 375 { 376 char c = *mnem; 377 378 if (ISALPHA (c)) 379 { 380 *rx++ = '['; 381 *rx++ = TOLOWER (c); 382 *rx++ = TOUPPER (c); 383 *rx++ = ']'; 384 } 385 else 386 *rx++ = c; 387 } 388 389 /* Copy any remaining literals from the syntax string into the rx. */ 390 for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn) 391 { 392 if (CGEN_SYNTAX_CHAR_P (* syn)) 393 { 394 char c = CGEN_SYNTAX_CHAR (* syn); 395 396 switch (c) 397 { 398 /* Escape any regex metacharacters in the syntax. */ 399 case '.': case '[': case '\\': 400 case '*': case '^': case '$': 401 402 #ifdef CGEN_ESCAPE_EXTENDED_REGEX 403 case '?': case '{': case '}': 404 case '(': case ')': case '*': 405 case '|': case '+': case ']': 406 #endif 407 *rx++ = '\\'; 408 *rx++ = c; 409 break; 410 411 default: 412 if (ISALPHA (c)) 413 { 414 *rx++ = '['; 415 *rx++ = TOLOWER (c); 416 *rx++ = TOUPPER (c); 417 *rx++ = ']'; 418 } 419 else 420 *rx++ = c; 421 break; 422 } 423 } 424 else 425 { 426 /* Replace non-syntax fields with globs. */ 427 *rx++ = '.'; 428 *rx++ = '*'; 429 } 430 } 431 432 /* Trailing whitespace ok. */ 433 * rx++ = '['; 434 * rx++ = ' '; 435 * rx++ = '\t'; 436 * rx++ = ']'; 437 * rx++ = '*'; 438 439 /* But anchor it after that. */ 440 * rx++ = '$'; 441 * rx = '\0'; 442 443 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t)); 444 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB); 445 446 if (reg_err == 0) 447 return NULL; 448 else 449 { 450 static char msg[80]; 451 452 regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80); 453 regfree ((regex_t *) CGEN_INSN_RX (insn)); 454 free (CGEN_INSN_RX (insn)); 455 (CGEN_INSN_RX (insn)) = NULL; 456 return msg; 457 } 458 } 459 460 461 /* Default insn parser. 463 464 The syntax string is scanned and operands are parsed and stored in FIELDS. 465 Relocs are queued as we go via other callbacks. 466 467 ??? Note that this is currently an all-or-nothing parser. If we fail to 468 parse the instruction, we return 0 and the caller will start over from 469 the beginning. Backtracking will be necessary in parsing subexpressions, 470 but that can be handled there. Not handling backtracking here may get 471 expensive in the case of the m68k. Deal with later. 472 473 Returns NULL for success, an error message for failure. */ 474 475 static const char * 476 parse_insn_normal (CGEN_CPU_DESC cd, 477 const CGEN_INSN *insn, 478 const char **strp, 479 CGEN_FIELDS *fields) 480 { 481 /* ??? Runtime added insns not handled yet. */ 482 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); 483 const char *str = *strp; 484 const char *errmsg; 485 const char *p; 486 const CGEN_SYNTAX_CHAR_TYPE * syn; 487 #ifdef CGEN_MNEMONIC_OPERANDS 488 /* FIXME: wip */ 489 int past_opcode_p; 490 #endif 491 492 /* For now we assume the mnemonic is first (there are no leading operands). 493 We can parse it without needing to set up operand parsing. 494 GAS's input scrubber will ensure mnemonics are lowercase, but we may 495 not be called from GAS. */ 496 p = CGEN_INSN_MNEMONIC (insn); 497 while (*p && TOLOWER (*p) == TOLOWER (*str)) 498 ++p, ++str; 499 500 if (* p) 501 return _("unrecognized instruction"); 502 503 #ifndef CGEN_MNEMONIC_OPERANDS 504 if (* str && ! ISSPACE (* str)) 505 return _("unrecognized instruction"); 506 #endif 507 508 CGEN_INIT_PARSE (cd); 509 cgen_init_parse_operand (cd); 510 #ifdef CGEN_MNEMONIC_OPERANDS 511 past_opcode_p = 0; 512 #endif 513 514 /* We don't check for (*str != '\0') here because we want to parse 515 any trailing fake arguments in the syntax string. */ 516 syn = CGEN_SYNTAX_STRING (syntax); 517 518 /* Mnemonics come first for now, ensure valid string. */ 519 if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) 520 abort (); 521 522 ++syn; 523 524 while (* syn != 0) 525 { 526 /* Non operand chars must match exactly. */ 527 if (CGEN_SYNTAX_CHAR_P (* syn)) 528 { 529 /* FIXME: While we allow for non-GAS callers above, we assume the 530 first char after the mnemonic part is a space. */ 531 /* FIXME: We also take inappropriate advantage of the fact that 532 GAS's input scrubber will remove extraneous blanks. */ 533 if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn))) 534 { 535 #ifdef CGEN_MNEMONIC_OPERANDS 536 if (CGEN_SYNTAX_CHAR(* syn) == ' ') 537 past_opcode_p = 1; 538 #endif 539 ++ syn; 540 ++ str; 541 } 542 else if (*str) 543 { 544 /* Syntax char didn't match. Can't be this insn. */ 545 static char msg [80]; 546 547 /* xgettext:c-format */ 548 sprintf (msg, _("syntax error (expected char `%c', found `%c')"), 549 CGEN_SYNTAX_CHAR(*syn), *str); 550 return msg; 551 } 552 else 553 { 554 /* Ran out of input. */ 555 static char msg [80]; 556 557 /* xgettext:c-format */ 558 sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"), 559 CGEN_SYNTAX_CHAR(*syn)); 560 return msg; 561 } 562 continue; 563 } 564 565 #ifdef CGEN_MNEMONIC_OPERANDS 566 (void) past_opcode_p; 567 #endif 568 /* We have an operand of some sort. */ 569 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields); 570 if (errmsg) 571 return errmsg; 572 573 /* Done with this operand, continue with next one. */ 574 ++ syn; 575 } 576 577 /* If we're at the end of the syntax string, we're done. */ 578 if (* syn == 0) 579 { 580 /* FIXME: For the moment we assume a valid `str' can only contain 581 blanks now. IE: We needn't try again with a longer version of 582 the insn and it is assumed that longer versions of insns appear 583 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */ 584 while (ISSPACE (* str)) 585 ++ str; 586 587 if (* str != '\0') 588 return _("junk at end of line"); /* FIXME: would like to include `str' */ 589 590 return NULL; 591 } 592 593 /* We couldn't parse it. */ 594 return _("unrecognized instruction"); 595 } 596 597 /* Main entry point. 599 This routine is called for each instruction to be assembled. 600 STR points to the insn to be assembled. 601 We assume all necessary tables have been initialized. 602 The assembled instruction, less any fixups, is stored in BUF. 603 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value 604 still needs to be converted to target byte order, otherwise BUF is an array 605 of bytes in target byte order. 606 The result is a pointer to the insn's entry in the opcode table, 607 or NULL if an error occured (an error message will have already been 608 printed). 609 610 Note that when processing (non-alias) macro-insns, 611 this function recurses. 612 613 ??? It's possible to make this cpu-independent. 614 One would have to deal with a few minor things. 615 At this point in time doing so would be more of a curiosity than useful 616 [for example this file isn't _that_ big], but keeping the possibility in 617 mind helps keep the design clean. */ 618 619 const CGEN_INSN * 620 fr30_cgen_assemble_insn (CGEN_CPU_DESC cd, 621 const char *str, 622 CGEN_FIELDS *fields, 623 CGEN_INSN_BYTES_PTR buf, 624 char **errmsg) 625 { 626 const char *start; 627 CGEN_INSN_LIST *ilist; 628 const char *parse_errmsg = NULL; 629 const char *insert_errmsg = NULL; 630 int recognized_mnemonic = 0; 631 632 /* Skip leading white space. */ 633 while (ISSPACE (* str)) 634 ++ str; 635 636 /* The instructions are stored in hashed lists. 637 Get the first in the list. */ 638 ilist = CGEN_ASM_LOOKUP_INSN (cd, str); 639 640 /* Keep looking until we find a match. */ 641 start = str; 642 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist)) 643 { 644 const CGEN_INSN *insn = ilist->insn; 645 recognized_mnemonic = 1; 646 647 #ifdef CGEN_VALIDATE_INSN_SUPPORTED 648 /* Not usually needed as unsupported opcodes 649 shouldn't be in the hash lists. */ 650 /* Is this insn supported by the selected cpu? */ 651 if (! fr30_cgen_insn_supported (cd, insn)) 652 continue; 653 #endif 654 /* If the RELAXED attribute is set, this is an insn that shouldn't be 655 chosen immediately. Instead, it is used during assembler/linker 656 relaxation if possible. */ 657 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0) 658 continue; 659 660 str = start; 661 662 /* Skip this insn if str doesn't look right lexically. */ 663 if (CGEN_INSN_RX (insn) != NULL && 664 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH) 665 continue; 666 667 /* Allow parse/insert handlers to obtain length of insn. */ 668 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); 669 670 parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields); 671 if (parse_errmsg != NULL) 672 continue; 673 674 /* ??? 0 is passed for `pc'. */ 675 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf, 676 (bfd_vma) 0); 677 if (insert_errmsg != NULL) 678 continue; 679 680 /* It is up to the caller to actually output the insn and any 681 queued relocs. */ 682 return insn; 683 } 684 685 { 686 static char errbuf[150]; 687 const char *tmp_errmsg; 688 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS 689 #define be_verbose 1 690 #else 691 #define be_verbose 0 692 #endif 693 694 if (be_verbose) 695 { 696 /* If requesting verbose error messages, use insert_errmsg. 697 Failing that, use parse_errmsg. */ 698 tmp_errmsg = (insert_errmsg ? insert_errmsg : 699 parse_errmsg ? parse_errmsg : 700 recognized_mnemonic ? 701 _("unrecognized form of instruction") : 702 _("unrecognized instruction")); 703 704 if (strlen (start) > 50) 705 /* xgettext:c-format */ 706 sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start); 707 else 708 /* xgettext:c-format */ 709 sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start); 710 } 711 else 712 { 713 if (strlen (start) > 50) 714 /* xgettext:c-format */ 715 sprintf (errbuf, _("bad instruction `%.50s...'"), start); 716 else 717 /* xgettext:c-format */ 718 sprintf (errbuf, _("bad instruction `%.50s'"), start); 719 } 720 721 *errmsg = errbuf; 722 return NULL; 723 } 724 } 725