Changeset 609 for branches/GNU/src/binutils/opcodes/fr30-asm.c
- Timestamp:
- Aug 16, 2003, 6:59:22 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/GNU/src/binutils/opcodes/fr30-asm.c
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.1.1.2
r608 r609 27 27 28 28 #include "sysdep.h" 29 #include <ctype.h>30 29 #include <stdio.h> 31 30 #include "ansidecl.h" … … 35 34 #include "fr30-opc.h" 36 35 #include "opintl.h" 37 38 #undef min 36 #include "xregex.h" 37 #include "libiberty.h" 38 #include "safe-ctype.h" 39 40 #undef min 39 41 #define min(a,b) ((a) < (b) ? (a) : (b)) 40 #undef max42 #undef max 41 43 #define max(a,b) ((a) > (b) ? (a) : (b)) 42 44 … … 45 47 46 48 47 /* -- assembler routines inserted here */49 /* -- assembler routines inserted here. */ 48 50 49 51 /* -- asm.c */ 50 /* Handle register lists for LDMx and STMx */ 52 /* Handle register lists for LDMx and STMx. */ 53 54 static int parse_register_number 55 PARAMS ((const char **)); 56 static const char * parse_register_list 57 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *, int, int)); 58 static const char * parse_low_register_list_ld 59 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *)); 60 static const char * parse_hi_register_list_ld 61 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *)); 62 static const char * parse_low_register_list_st 63 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *)); 64 static const char * parse_hi_register_list_st 65 PARAMS ((CGEN_CPU_DESC, const char **, int, unsigned long *)); 51 66 52 67 static int … … 56 71 int regno; 57 72 if (**strp < '0' || **strp > '9') 58 return -1; /* error */73 return -1; /* error. */ 59 74 regno = **strp - '0'; 60 75 ++*strp; … … 71 86 static const char * 72 87 parse_register_list (cd, strp, opindex, valuep, high_low, load_store) 73 CGEN_CPU_DESC cd ;88 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED; 74 89 const char **strp; 75 int opindex ;90 int opindex ATTRIBUTE_UNUSED; 76 91 unsigned long *valuep; 77 92 int high_low; /* 0 == high, 1 == low */ … … 79 94 { 80 95 int regno; 96 81 97 *valuep = 0; 82 98 while (**strp && **strp != ')') … … 97 113 regno -= 8; 98 114 99 if (load_store) /* mask is reversed for store*/115 if (load_store) /* Mask is reversed for store. */ 100 116 *valuep |= 0x80 >> regno; 101 117 else … … 158 174 /* -- */ 159 175 176 const char * fr30_cgen_parse_operand 177 PARAMS ((CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *)); 178 160 179 /* Main entry point for operand parsing. 161 180 … … 169 188 This function could be moved into `parse_insn_normal', but keeping it 170 189 separate makes clear the interface between `parse_insn_normal' and each of 171 the handlers. 172 */ 190 the handlers. */ 173 191 174 192 const char * … … 181 199 const char * errmsg = NULL; 182 200 /* Used by scalar operands that still need to be parsed. */ 183 long junk ;201 long junk ATTRIBUTE_UNUSED; 184 202 185 203 switch (opindex) … … 328 346 329 347 348 349 /* Regex construction routine. 350 351 This translates an opcode syntax string into a regex string, 352 by replacing any non-character syntax element (such as an 353 opcode) with the pattern '.*' 354 355 It then compiles the regex and stores it in the opcode, for 356 later use by fr30_cgen_assemble_insn 357 358 Returns NULL for success, an error message for failure. */ 359 360 char * 361 fr30_cgen_build_insn_regex (insn) 362 CGEN_INSN *insn; 363 { 364 CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn); 365 const char *mnem = CGEN_INSN_MNEMONIC (insn); 366 char rxbuf[CGEN_MAX_RX_ELEMENTS]; 367 char *rx = rxbuf; 368 const CGEN_SYNTAX_CHAR_TYPE *syn; 369 int reg_err; 370 371 syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc)); 372 373 /* Mnemonics come first in the syntax string. */ 374 if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) 375 return _("missing mnemonic in syntax string"); 376 ++syn; 377 378 /* Generate a case sensitive regular expression that emulates case 379 insensitive matching in the "C" locale. We cannot generate a case 380 insensitive regular expression because in Turkish locales, 'i' and 'I' 381 are not equal modulo case conversion. */ 382 383 /* Copy the literal mnemonic out of the insn. */ 384 for (; *mnem; mnem++) 385 { 386 char c = *mnem; 387 388 if (ISALPHA (c)) 389 { 390 *rx++ = '['; 391 *rx++ = TOLOWER (c); 392 *rx++ = TOUPPER (c); 393 *rx++ = ']'; 394 } 395 else 396 *rx++ = c; 397 } 398 399 /* Copy any remaining literals from the syntax string into the rx. */ 400 for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn) 401 { 402 if (CGEN_SYNTAX_CHAR_P (* syn)) 403 { 404 char c = CGEN_SYNTAX_CHAR (* syn); 405 406 switch (c) 407 { 408 /* Escape any regex metacharacters in the syntax. */ 409 case '.': case '[': case '\\': 410 case '*': case '^': case '$': 411 412 #ifdef CGEN_ESCAPE_EXTENDED_REGEX 413 case '?': case '{': case '}': 414 case '(': case ')': case '*': 415 case '|': case '+': case ']': 416 #endif 417 *rx++ = '\\'; 418 *rx++ = c; 419 break; 420 421 default: 422 if (ISALPHA (c)) 423 { 424 *rx++ = '['; 425 *rx++ = TOLOWER (c); 426 *rx++ = TOUPPER (c); 427 *rx++ = ']'; 428 } 429 else 430 *rx++ = c; 431 break; 432 } 433 } 434 else 435 { 436 /* Replace non-syntax fields with globs. */ 437 *rx++ = '.'; 438 *rx++ = '*'; 439 } 440 } 441 442 /* Trailing whitespace ok. */ 443 * rx++ = '['; 444 * rx++ = ' '; 445 * rx++ = '\t'; 446 * rx++ = ']'; 447 * rx++ = '*'; 448 449 /* But anchor it after that. */ 450 * rx++ = '$'; 451 * rx = '\0'; 452 453 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t)); 454 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB); 455 456 if (reg_err == 0) 457 return NULL; 458 else 459 { 460 static char msg[80]; 461 462 regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80); 463 regfree ((regex_t *) CGEN_INSN_RX (insn)); 464 free (CGEN_INSN_RX (insn)); 465 (CGEN_INSN_RX (insn)) = NULL; 466 return msg; 467 } 468 } 469 470 471 330 472 /* Default insn parser. 331 473 … … 339 481 expensive in the case of the m68k. Deal with later. 340 482 341 Returns NULL for success, an error message for failure. 342 */ 483 Returns NULL for success, an error message for failure. */ 343 484 344 485 static const char * … … 354 495 const char *errmsg; 355 496 const char *p; 356 const unsigned char* syn;497 const CGEN_SYNTAX_CHAR_TYPE * syn; 357 498 #ifdef CGEN_MNEMONIC_OPERANDS 358 499 /* FIXME: wip */ … … 365 506 not be called from GAS. */ 366 507 p = CGEN_INSN_MNEMONIC (insn); 367 while (*p && tolower (*p) == tolower(*str))508 while (*p && TOLOWER (*p) == TOLOWER (*str)) 368 509 ++p, ++str; 369 510 … … 372 513 373 514 #ifndef CGEN_MNEMONIC_OPERANDS 374 if (* str && ! isspace(* str))515 if (* str && ! ISSPACE (* str)) 375 516 return _("unrecognized instruction"); 376 517 #endif … … 401 542 /* FIXME: We also take inappropriate advantage of the fact that 402 543 GAS's input scrubber will remove extraneous blanks. */ 403 if ( tolower (*str) == tolower(CGEN_SYNTAX_CHAR (* syn)))544 if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn))) 404 545 { 405 546 #ifdef CGEN_MNEMONIC_OPERANDS 406 if ( * syn== ' ')547 if (CGEN_SYNTAX_CHAR(* syn) == ' ') 407 548 past_opcode_p = 1; 408 549 #endif … … 410 551 ++ str; 411 552 } 412 else 553 else if (*str) 413 554 { 414 555 /* Syntax char didn't match. Can't be this insn. */ 415 556 static char msg [80]; 557 416 558 /* xgettext:c-format */ 417 559 sprintf (msg, _("syntax error (expected char `%c', found `%c')"), 418 *syn, *str); 560 CGEN_SYNTAX_CHAR(*syn), *str); 561 return msg; 562 } 563 else 564 { 565 /* Ran out of input. */ 566 static char msg [80]; 567 568 /* xgettext:c-format */ 569 sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"), 570 CGEN_SYNTAX_CHAR(*syn)); 419 571 return msg; 420 572 } … … 423 575 424 576 /* We have an operand of some sort. */ 425 errmsg = fr30_cgen_parse_operand (cd, CGEN_SYNTAX_FIELD (*syn),577 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), 426 578 &str, fields); 427 579 if (errmsg) … … 433 585 434 586 /* If we're at the end of the syntax string, we're done. */ 435 if (* syn == '\0')587 if (* syn == 0) 436 588 { 437 589 /* FIXME: For the moment we assume a valid `str' can only contain … … 439 591 the insn and it is assumed that longer versions of insns appear 440 592 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */ 441 while ( isspace(* str))593 while (ISSPACE (* str)) 442 594 ++ str; 443 595 … … 484 636 const char *start; 485 637 CGEN_INSN_LIST *ilist; 486 const char *tmp_errmsg = NULL; 638 const char *parse_errmsg = NULL; 639 const char *insert_errmsg = NULL; 640 int recognized_mnemonic = 0; 487 641 488 642 /* Skip leading white space. */ 489 while ( isspace(* str))643 while (ISSPACE (* str)) 490 644 ++ str; 491 645 … … 495 649 496 650 /* Keep looking until we find a match. */ 497 498 651 start = str; 499 652 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist)) 500 653 { 501 654 const CGEN_INSN *insn = ilist->insn; 655 recognized_mnemonic = 1; 502 656 503 657 #ifdef CGEN_VALIDATE_INSN_SUPPORTED 504 /* not usually needed as unsupported opcodes shouldn't be in the hash lists */ 658 /* Not usually needed as unsupported opcodes 659 shouldn't be in the hash lists. */ 505 660 /* Is this insn supported by the selected cpu? */ 506 661 if (! fr30_cgen_insn_supported (cd, insn)) 507 662 continue; 508 663 #endif 509 510 664 /* If the RELAX attribute is set, this is an insn that shouldn't be 511 665 chosen immediately. Instead, it is used during assembler/linker … … 516 670 str = start; 517 671 672 /* Skip this insn if str doesn't look right lexically. */ 673 if (CGEN_INSN_RX (insn) != NULL && 674 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH) 675 continue; 676 518 677 /* Allow parse/insert handlers to obtain length of insn. */ 519 678 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); 520 679 521 tmp_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);522 if ( tmp_errmsg != NULL)680 parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields); 681 if (parse_errmsg != NULL) 523 682 continue; 524 683 525 /* ??? 0 is passed for `pc' */526 tmp_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,527 528 if ( tmp_errmsg != NULL)684 /* ??? 0 is passed for `pc'. */ 685 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf, 686 (bfd_vma) 0); 687 if (insert_errmsg != NULL) 529 688 continue; 530 689 … … 534 693 } 535 694 536 /* Make sure we leave this with something at this point. */537 if (tmp_errmsg == NULL)538 tmp_errmsg = "unknown mnemonic";539 540 695 { 541 696 static char errbuf[150]; 542 543 697 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS 544 /* if verbose error messages, use errmsg from CGEN_PARSE_FN */ 698 const char *tmp_errmsg; 699 700 /* If requesting verbose error messages, use insert_errmsg. 701 Failing that, use parse_errmsg. */ 702 tmp_errmsg = (insert_errmsg ? insert_errmsg : 703 parse_errmsg ? parse_errmsg : 704 recognized_mnemonic ? 705 _("unrecognized form of instruction") : 706 _("unrecognized instruction")); 707 545 708 if (strlen (start) > 50) 546 709 /* xgettext:c-format */ -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.