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 7 Copyright (C) 1996-2014 Free Software Foundation, Inc. 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 "frv-desc.h" 35 #include "frv-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 46 static const char * parse_insn_normal 47 (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *); 48 49 /* -- assembler routines inserted here. */ 51 52 /* -- asm.c */ 53 inline static const char * 54 parse_symbolic_address (CGEN_CPU_DESC cd, 55 const char **strp, 56 int opindex, 57 int opinfo, 58 enum cgen_parse_operand_result *resultp, 59 bfd_vma *valuep) 60 { 61 enum cgen_parse_operand_result result_type; 62 const char *errmsg = (* cd->parse_operand_fn) 63 (cd, CGEN_PARSE_OPERAND_SYMBOLIC, strp, opindex, opinfo, 64 &result_type, valuep); 65 66 if (errmsg == NULL 67 && result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED) 68 return "symbolic expression required"; 69 70 if (resultp) 71 *resultp = result_type; 72 73 return errmsg; 74 } 75 76 static const char * 77 parse_ldd_annotation (CGEN_CPU_DESC cd, 78 const char **strp, 79 int opindex, 80 unsigned long *valuep) 81 { 82 const char *errmsg; 83 enum cgen_parse_operand_result result_type; 84 bfd_vma value; 85 86 if (**strp == '#' || **strp == '%') 87 { 88 if (strncasecmp (*strp + 1, "tlsdesc(", 8) == 0) 89 { 90 *strp += 9; 91 errmsg = parse_symbolic_address (cd, strp, opindex, 92 BFD_RELOC_FRV_TLSDESC_RELAX, 93 &result_type, &value); 94 if (**strp != ')') 95 return "missing ')'"; 96 if (valuep) 97 *valuep = value; 98 ++*strp; 99 if (errmsg) 100 return errmsg; 101 } 102 } 103 104 while (**strp == ' ' || **strp == '\t') 105 ++*strp; 106 107 if (**strp != '@') 108 return "missing `@'"; 109 110 ++*strp; 111 112 return NULL; 113 } 114 115 static const char * 116 parse_call_annotation (CGEN_CPU_DESC cd, 117 const char **strp, 118 int opindex, 119 unsigned long *valuep) 120 { 121 const char *errmsg; 122 enum cgen_parse_operand_result result_type; 123 bfd_vma value; 124 125 if (**strp == '#' || **strp == '%') 126 { 127 if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0) 128 { 129 *strp += 11; 130 errmsg = parse_symbolic_address (cd, strp, opindex, 131 BFD_RELOC_FRV_GETTLSOFF_RELAX, 132 &result_type, &value); 133 if (**strp != ')') 134 return "missing ')'"; 135 if (valuep) 136 *valuep = value; 137 ++*strp; 138 if (errmsg) 139 return errmsg; 140 } 141 } 142 143 while (**strp == ' ' || **strp == '\t') 144 ++*strp; 145 146 if (**strp != '@') 147 return "missing `@'"; 148 149 ++*strp; 150 151 return NULL; 152 } 153 154 static const char * 155 parse_ld_annotation (CGEN_CPU_DESC cd, 156 const char **strp, 157 int opindex, 158 unsigned long *valuep) 159 { 160 const char *errmsg; 161 enum cgen_parse_operand_result result_type; 162 bfd_vma value; 163 164 if (**strp == '#' || **strp == '%') 165 { 166 if (strncasecmp (*strp + 1, "tlsoff(", 7) == 0) 167 { 168 *strp += 8; 169 errmsg = parse_symbolic_address (cd, strp, opindex, 170 BFD_RELOC_FRV_TLSOFF_RELAX, 171 &result_type, &value); 172 if (**strp != ')') 173 return "missing ')'"; 174 if (valuep) 175 *valuep = value; 176 ++*strp; 177 if (errmsg) 178 return errmsg; 179 } 180 } 181 182 while (**strp == ' ' || **strp == '\t') 183 ++*strp; 184 185 if (**strp != '@') 186 return "missing `@'"; 187 188 ++*strp; 189 190 return NULL; 191 } 192 193 static const char * 194 parse_ulo16 (CGEN_CPU_DESC cd, 195 const char **strp, 196 int opindex, 197 unsigned long *valuep) 198 { 199 const char *errmsg; 200 enum cgen_parse_operand_result result_type; 201 bfd_vma value; 202 203 if (**strp == '#' || **strp == '%') 204 { 205 if (strncasecmp (*strp + 1, "lo(", 3) == 0) 206 { 207 *strp += 4; 208 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16, 209 & result_type, & value); 210 if (**strp != ')') 211 return "missing `)'"; 212 ++*strp; 213 if (errmsg == NULL 214 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 215 value &= 0xffff; 216 *valuep = value; 217 return errmsg; 218 } 219 if (strncasecmp (*strp + 1, "gprello(", 8) == 0) 220 { 221 *strp += 9; 222 errmsg = parse_symbolic_address (cd, strp, opindex, 223 BFD_RELOC_FRV_GPRELLO, 224 & result_type, & value); 225 if (**strp != ')') 226 return "missing ')'"; 227 ++*strp; 228 *valuep = value; 229 return errmsg; 230 } 231 else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0) 232 { 233 *strp += 7; 234 errmsg = parse_symbolic_address (cd, strp, opindex, 235 BFD_RELOC_FRV_GOTLO, 236 & result_type, & value); 237 if (**strp != ')') 238 return "missing ')'"; 239 ++*strp; 240 *valuep = value; 241 return errmsg; 242 } 243 else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0) 244 { 245 *strp += 15; 246 errmsg = parse_symbolic_address (cd, strp, opindex, 247 BFD_RELOC_FRV_FUNCDESC_GOTLO, 248 & result_type, & value); 249 if (**strp != ')') 250 return "missing ')'"; 251 ++*strp; 252 *valuep = value; 253 return errmsg; 254 } 255 else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0) 256 { 257 *strp += 10; 258 errmsg = parse_symbolic_address (cd, strp, opindex, 259 BFD_RELOC_FRV_GOTOFFLO, 260 & result_type, & value); 261 if (**strp != ')') 262 return "missing ')'"; 263 ++*strp; 264 *valuep = value; 265 return errmsg; 266 } 267 else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0) 268 { 269 *strp += 18; 270 errmsg = parse_symbolic_address (cd, strp, opindex, 271 BFD_RELOC_FRV_FUNCDESC_GOTOFFLO, 272 & result_type, & value); 273 if (**strp != ')') 274 return "missing ')'"; 275 ++*strp; 276 *valuep = value; 277 return errmsg; 278 } 279 else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0) 280 { 281 *strp += 14; 282 errmsg = parse_symbolic_address (cd, strp, opindex, 283 BFD_RELOC_FRV_GOTTLSDESCLO, 284 & result_type, & value); 285 if (**strp != ')') 286 return "missing ')'"; 287 ++*strp; 288 *valuep = value; 289 return errmsg; 290 } 291 else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0) 292 { 293 *strp += 11; 294 errmsg = parse_symbolic_address (cd, strp, opindex, 295 BFD_RELOC_FRV_TLSMOFFLO, 296 & result_type, & value); 297 if (**strp != ')') 298 return "missing ')'"; 299 ++*strp; 300 *valuep = value; 301 return errmsg; 302 } 303 else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0) 304 { 305 *strp += 13; 306 errmsg = parse_symbolic_address (cd, strp, opindex, 307 BFD_RELOC_FRV_GOTTLSOFFLO, 308 & result_type, & value); 309 if (**strp != ')') 310 return "missing ')'"; 311 ++*strp; 312 *valuep = value; 313 return errmsg; 314 } 315 } 316 return cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 317 } 318 319 static const char * 320 parse_uslo16 (CGEN_CPU_DESC cd, 321 const char **strp, 322 int opindex, 323 signed long *valuep) 324 { 325 const char *errmsg; 326 enum cgen_parse_operand_result result_type; 327 bfd_vma value; 328 329 if (**strp == '#' || **strp == '%') 330 { 331 if (strncasecmp (*strp + 1, "lo(", 3) == 0) 332 { 333 *strp += 4; 334 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16, 335 & result_type, & value); 336 if (**strp != ')') 337 return "missing `)'"; 338 ++*strp; 339 if (errmsg == NULL 340 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 341 value &= 0xffff; 342 *valuep = value; 343 return errmsg; 344 } 345 else if (strncasecmp (*strp + 1, "gprello(", 8) == 0) 346 { 347 *strp += 9; 348 errmsg = parse_symbolic_address (cd, strp, opindex, 349 BFD_RELOC_FRV_GPRELLO, 350 & result_type, & value); 351 if (**strp != ')') 352 return "missing ')'"; 353 ++*strp; 354 *valuep = value; 355 return errmsg; 356 } 357 else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0) 358 { 359 *strp += 7; 360 errmsg = parse_symbolic_address (cd, strp, opindex, 361 BFD_RELOC_FRV_GOTLO, 362 & result_type, & value); 363 if (**strp != ')') 364 return "missing ')'"; 365 ++*strp; 366 *valuep = value; 367 return errmsg; 368 } 369 else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0) 370 { 371 *strp += 15; 372 errmsg = parse_symbolic_address (cd, strp, opindex, 373 BFD_RELOC_FRV_FUNCDESC_GOTLO, 374 & result_type, & value); 375 if (**strp != ')') 376 return "missing ')'"; 377 ++*strp; 378 *valuep = value; 379 return errmsg; 380 } 381 else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0) 382 { 383 *strp += 10; 384 errmsg = parse_symbolic_address (cd, strp, opindex, 385 BFD_RELOC_FRV_GOTOFFLO, 386 & result_type, & value); 387 if (**strp != ')') 388 return "missing ')'"; 389 ++*strp; 390 *valuep = value; 391 return errmsg; 392 } 393 else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0) 394 { 395 *strp += 18; 396 errmsg = parse_symbolic_address (cd, strp, opindex, 397 BFD_RELOC_FRV_FUNCDESC_GOTOFFLO, 398 & result_type, & value); 399 if (**strp != ')') 400 return "missing ')'"; 401 ++*strp; 402 *valuep = value; 403 return errmsg; 404 } 405 else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0) 406 { 407 *strp += 14; 408 errmsg = parse_symbolic_address (cd, strp, opindex, 409 BFD_RELOC_FRV_GOTTLSDESCLO, 410 & result_type, & value); 411 if (**strp != ')') 412 return "missing ')'"; 413 ++*strp; 414 *valuep = value; 415 return errmsg; 416 } 417 else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0) 418 { 419 *strp += 11; 420 errmsg = parse_symbolic_address (cd, strp, opindex, 421 BFD_RELOC_FRV_TLSMOFFLO, 422 & result_type, & value); 423 if (**strp != ')') 424 return "missing ')'"; 425 ++*strp; 426 *valuep = value; 427 return errmsg; 428 } 429 else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0) 430 { 431 *strp += 13; 432 errmsg = parse_symbolic_address (cd, strp, opindex, 433 BFD_RELOC_FRV_GOTTLSOFFLO, 434 & result_type, & value); 435 if (**strp != ')') 436 return "missing ')'"; 437 ++*strp; 438 *valuep = value; 439 return errmsg; 440 } 441 } 442 return cgen_parse_signed_integer (cd, strp, opindex, valuep); 443 } 444 445 static const char * 446 parse_uhi16 (CGEN_CPU_DESC cd, 447 const char **strp, 448 int opindex, 449 unsigned long *valuep) 450 { 451 const char *errmsg; 452 enum cgen_parse_operand_result result_type; 453 bfd_vma value; 454 455 if (**strp == '#' || **strp == '%') 456 { 457 if (strncasecmp (*strp + 1, "hi(", 3) == 0) 458 { 459 *strp += 4; 460 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16, 461 & result_type, & value); 462 if (**strp != ')') 463 return "missing `)'"; 464 ++*strp; 465 if (errmsg == NULL 466 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 467 { 468 /* If value is wider than 32 bits then be 469 careful about how we extract bits 16-31. */ 470 if (sizeof (value) > 4) 471 value &= (((bfd_vma)1 << 16) << 16) - 1; 472 473 value >>= 16; 474 } 475 *valuep = value; 476 return errmsg; 477 } 478 else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0) 479 { 480 *strp += 9; 481 errmsg = parse_symbolic_address (cd, strp, opindex, 482 BFD_RELOC_FRV_GPRELHI, 483 & result_type, & value); 484 if (**strp != ')') 485 return "missing ')'"; 486 ++*strp; 487 *valuep = value; 488 return errmsg; 489 } 490 else if (strncasecmp (*strp + 1, "gothi(", 6) == 0) 491 { 492 *strp += 7; 493 errmsg = parse_symbolic_address (cd, strp, opindex, 494 BFD_RELOC_FRV_GOTHI, 495 & result_type, & value); 496 if (**strp != ')') 497 return "missing ')'"; 498 ++*strp; 499 *valuep = value; 500 return errmsg; 501 } 502 else if (strncasecmp (*strp + 1, "gotfuncdeschi(", 14) == 0) 503 { 504 *strp += 15; 505 errmsg = parse_symbolic_address (cd, strp, opindex, 506 BFD_RELOC_FRV_FUNCDESC_GOTHI, 507 & result_type, & value); 508 if (**strp != ')') 509 return "missing ')'"; 510 ++*strp; 511 *valuep = value; 512 return errmsg; 513 } 514 else if (strncasecmp (*strp + 1, "gotoffhi(", 9) == 0) 515 { 516 *strp += 10; 517 errmsg = parse_symbolic_address (cd, strp, opindex, 518 BFD_RELOC_FRV_GOTOFFHI, 519 & result_type, & value); 520 if (**strp != ')') 521 return "missing ')'"; 522 ++*strp; 523 *valuep = value; 524 return errmsg; 525 } 526 else if (strncasecmp (*strp + 1, "gotofffuncdeschi(", 17) == 0) 527 { 528 *strp += 18; 529 errmsg = parse_symbolic_address (cd, strp, opindex, 530 BFD_RELOC_FRV_FUNCDESC_GOTOFFHI, 531 & result_type, & value); 532 if (**strp != ')') 533 return "missing ')'"; 534 ++*strp; 535 *valuep = value; 536 return errmsg; 537 } 538 else if (strncasecmp (*strp + 1, "gottlsdeschi(", 13) == 0) 539 { 540 *strp += 14; 541 errmsg = parse_symbolic_address (cd, strp, opindex, 542 BFD_RELOC_FRV_GOTTLSDESCHI, 543 &result_type, &value); 544 if (**strp != ')') 545 return "missing ')'"; 546 ++*strp; 547 *valuep = value; 548 return errmsg; 549 } 550 else if (strncasecmp (*strp + 1, "tlsmoffhi(", 10) == 0) 551 { 552 *strp += 11; 553 errmsg = parse_symbolic_address (cd, strp, opindex, 554 BFD_RELOC_FRV_TLSMOFFHI, 555 & result_type, & value); 556 if (**strp != ')') 557 return "missing ')'"; 558 ++*strp; 559 *valuep = value; 560 return errmsg; 561 } 562 else if (strncasecmp (*strp + 1, "gottlsoffhi(", 12) == 0) 563 { 564 *strp += 13; 565 errmsg = parse_symbolic_address (cd, strp, opindex, 566 BFD_RELOC_FRV_GOTTLSOFFHI, 567 & result_type, & value); 568 if (**strp != ')') 569 return "missing ')'"; 570 ++*strp; 571 *valuep = value; 572 return errmsg; 573 } 574 } 575 return cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 576 } 577 578 static long 579 parse_register_number (const char **strp) 580 { 581 int regno; 582 583 if (**strp < '0' || **strp > '9') 584 return -1; /* error */ 585 586 regno = **strp - '0'; 587 for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp) 588 regno = regno * 10 + (**strp - '0'); 589 590 return regno; 591 } 592 593 static const char * 594 parse_spr (CGEN_CPU_DESC cd, 595 const char **strp, 596 CGEN_KEYWORD * table, 597 long *valuep) 598 { 599 const char *save_strp; 600 long regno; 601 602 /* Check for spr index notation. */ 603 if (strncasecmp (*strp, "spr[", 4) == 0) 604 { 605 *strp += 4; 606 regno = parse_register_number (strp); 607 if (**strp != ']') 608 return _("missing `]'"); 609 ++*strp; 610 if (! spr_valid (regno)) 611 return _("Special purpose register number is out of range"); 612 *valuep = regno; 613 return NULL; 614 } 615 616 save_strp = *strp; 617 regno = parse_register_number (strp); 618 if (regno != -1) 619 { 620 if (! spr_valid (regno)) 621 return _("Special purpose register number is out of range"); 622 *valuep = regno; 623 return NULL; 624 } 625 626 *strp = save_strp; 627 return cgen_parse_keyword (cd, strp, table, valuep); 628 } 629 630 static const char * 631 parse_d12 (CGEN_CPU_DESC cd, 632 const char **strp, 633 int opindex, 634 long *valuep) 635 { 636 const char *errmsg; 637 enum cgen_parse_operand_result result_type; 638 bfd_vma value; 639 640 /* Check for small data reference. */ 641 if (**strp == '#' || **strp == '%') 642 { 643 if (strncasecmp (*strp + 1, "gprel12(", 8) == 0) 644 { 645 *strp += 9; 646 errmsg = parse_symbolic_address (cd, strp, opindex, 647 BFD_RELOC_FRV_GPREL12, 648 & result_type, & value); 649 if (**strp != ')') 650 return "missing `)'"; 651 ++*strp; 652 *valuep = value; 653 return errmsg; 654 } 655 else if (strncasecmp (*strp + 1, "got12(", 6) == 0) 656 { 657 *strp += 7; 658 errmsg = parse_symbolic_address (cd, strp, opindex, 659 BFD_RELOC_FRV_GOT12, 660 & result_type, & value); 661 if (**strp != ')') 662 return "missing ')'"; 663 ++*strp; 664 *valuep = value; 665 return errmsg; 666 } 667 else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0) 668 { 669 *strp += 15; 670 errmsg = parse_symbolic_address (cd, strp, opindex, 671 BFD_RELOC_FRV_FUNCDESC_GOT12, 672 & result_type, & value); 673 if (**strp != ')') 674 return "missing ')'"; 675 ++*strp; 676 *valuep = value; 677 return errmsg; 678 } 679 else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0) 680 { 681 *strp += 10; 682 errmsg = parse_symbolic_address (cd, strp, opindex, 683 BFD_RELOC_FRV_GOTOFF12, 684 & result_type, & value); 685 if (**strp != ')') 686 return "missing ')'"; 687 ++*strp; 688 *valuep = value; 689 return errmsg; 690 } 691 else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0) 692 { 693 *strp += 18; 694 errmsg = parse_symbolic_address (cd, strp, opindex, 695 BFD_RELOC_FRV_FUNCDESC_GOTOFF12, 696 & result_type, & value); 697 if (**strp != ')') 698 return "missing ')'"; 699 ++*strp; 700 *valuep = value; 701 return errmsg; 702 } 703 else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0) 704 { 705 *strp += 14; 706 errmsg = parse_symbolic_address (cd, strp, opindex, 707 BFD_RELOC_FRV_GOTTLSDESC12, 708 & result_type, & value); 709 if (**strp != ')') 710 return "missing ')'"; 711 ++*strp; 712 *valuep = value; 713 return errmsg; 714 } 715 else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0) 716 { 717 *strp += 11; 718 errmsg = parse_symbolic_address (cd, strp, opindex, 719 BFD_RELOC_FRV_TLSMOFF12, 720 & result_type, & value); 721 if (**strp != ')') 722 return "missing ')'"; 723 ++*strp; 724 *valuep = value; 725 return errmsg; 726 } 727 else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0) 728 { 729 *strp += 13; 730 errmsg = parse_symbolic_address (cd, strp, opindex, 731 BFD_RELOC_FRV_GOTTLSOFF12, 732 & result_type, & value); 733 if (**strp != ')') 734 return "missing ')'"; 735 ++*strp; 736 *valuep = value; 737 return errmsg; 738 } 739 } 740 return cgen_parse_signed_integer (cd, strp, opindex, valuep); 741 } 742 743 static const char * 744 parse_s12 (CGEN_CPU_DESC cd, 745 const char **strp, 746 int opindex, 747 long *valuep) 748 { 749 const char *errmsg; 750 enum cgen_parse_operand_result result_type; 751 bfd_vma value; 752 753 /* Check for small data reference. */ 754 if (**strp == '#' || **strp == '%') 755 { 756 if (strncasecmp (*strp + 1, "gprel12(", 8) == 0) 757 { 758 *strp += 9; 759 errmsg = parse_symbolic_address (cd, strp, opindex, 760 BFD_RELOC_FRV_GPREL12, 761 & result_type, & value); 762 if (**strp != ')') 763 return "missing `)'"; 764 ++*strp; 765 *valuep = value; 766 return errmsg; 767 } 768 else if (strncasecmp (*strp + 1, "got12(", 6) == 0) 769 { 770 *strp += 7; 771 errmsg = parse_symbolic_address (cd, strp, opindex, 772 BFD_RELOC_FRV_GOT12, 773 & result_type, & value); 774 if (**strp != ')') 775 return "missing ')'"; 776 ++*strp; 777 *valuep = value; 778 return errmsg; 779 } 780 else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0) 781 { 782 *strp += 15; 783 errmsg = parse_symbolic_address (cd, strp, opindex, 784 BFD_RELOC_FRV_FUNCDESC_GOT12, 785 & result_type, & value); 786 if (**strp != ')') 787 return "missing ')'"; 788 ++*strp; 789 *valuep = value; 790 return errmsg; 791 } 792 else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0) 793 { 794 *strp += 10; 795 errmsg = parse_symbolic_address (cd, strp, opindex, 796 BFD_RELOC_FRV_GOTOFF12, 797 & result_type, & value); 798 if (**strp != ')') 799 return "missing ')'"; 800 ++*strp; 801 *valuep = value; 802 return errmsg; 803 } 804 else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0) 805 { 806 *strp += 18; 807 errmsg = parse_symbolic_address (cd, strp, opindex, 808 BFD_RELOC_FRV_FUNCDESC_GOTOFF12, 809 & result_type, & value); 810 if (**strp != ')') 811 return "missing ')'"; 812 ++*strp; 813 *valuep = value; 814 return errmsg; 815 } 816 else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0) 817 { 818 *strp += 14; 819 errmsg = parse_symbolic_address (cd, strp, opindex, 820 BFD_RELOC_FRV_GOTTLSDESC12, 821 & result_type, & value); 822 if (**strp != ')') 823 return "missing ')'"; 824 ++*strp; 825 *valuep = value; 826 return errmsg; 827 } 828 else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0) 829 { 830 *strp += 11; 831 errmsg = parse_symbolic_address (cd, strp, opindex, 832 BFD_RELOC_FRV_TLSMOFF12, 833 & result_type, & value); 834 if (**strp != ')') 835 return "missing ')'"; 836 ++*strp; 837 *valuep = value; 838 return errmsg; 839 } 840 else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0) 841 { 842 *strp += 13; 843 errmsg = parse_symbolic_address (cd, strp, opindex, 844 BFD_RELOC_FRV_GOTTLSOFF12, 845 & result_type, & value); 846 if (**strp != ')') 847 return "missing ')'"; 848 ++*strp; 849 *valuep = value; 850 return errmsg; 851 } 852 } 853 854 if (**strp == '#') 855 ++*strp; 856 return cgen_parse_signed_integer (cd, strp, opindex, valuep); 857 } 858 859 static const char * 860 parse_u12 (CGEN_CPU_DESC cd, 861 const char **strp, 862 int opindex, 863 long *valuep) 864 { 865 const char *errmsg; 866 enum cgen_parse_operand_result result_type; 867 bfd_vma value; 868 869 /* Check for small data reference. */ 870 if ((**strp == '#' || **strp == '%') 871 && strncasecmp (*strp + 1, "gprel12(", 8) == 0) 872 { 873 *strp += 9; 874 errmsg = parse_symbolic_address (cd, strp, opindex, 875 BFD_RELOC_FRV_GPRELU12, 876 & result_type, & value); 877 if (**strp != ')') 878 return "missing `)'"; 879 ++*strp; 880 *valuep = value; 881 return errmsg; 882 } 883 else 884 { 885 if (**strp == '#') 886 ++*strp; 887 return cgen_parse_signed_integer (cd, strp, opindex, valuep); 888 } 889 } 890 891 static const char * 892 parse_A (CGEN_CPU_DESC cd, 893 const char **strp, 894 int opindex, 895 unsigned long *valuep, 896 unsigned long A) 897 { 898 const char *errmsg; 899 900 if (**strp == '#') 901 ++*strp; 902 903 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep); 904 if (errmsg) 905 return errmsg; 906 907 if (*valuep != A) 908 return _("Value of A operand must be 0 or 1"); 909 910 return NULL; 911 } 912 913 static const char * 914 parse_A0 (CGEN_CPU_DESC cd, 915 const char **strp, 916 int opindex, 917 unsigned long *valuep) 918 { 919 return parse_A (cd, strp, opindex, valuep, 0); 920 } 921 922 static const char * 923 parse_A1 (CGEN_CPU_DESC cd, 924 const char **strp, 925 int opindex, 926 unsigned long *valuep) 927 { 928 return parse_A (cd, strp, opindex, valuep, 1); 929 } 930 931 static const char * 932 parse_even_register (CGEN_CPU_DESC cd, 933 const char ** strP, 934 CGEN_KEYWORD * tableP, 935 long * valueP) 936 { 937 const char * errmsg; 938 const char * saved_star_strP = * strP; 939 940 errmsg = cgen_parse_keyword (cd, strP, tableP, valueP); 941 942 if (errmsg == NULL && ((* valueP) & 1)) 943 { 944 errmsg = _("register number must be even"); 945 * strP = saved_star_strP; 946 } 947 948 return errmsg; 949 } 950 951 static const char * 952 parse_call_label (CGEN_CPU_DESC cd, 953 const char **strp, 954 int opindex, 955 int opinfo, 956 enum cgen_parse_operand_result *resultp, 957 bfd_vma *valuep) 958 { 959 const char *errmsg; 960 bfd_vma value; 961 962 /* Check for small data reference. */ 963 if (opinfo == 0 && (**strp == '#' || **strp == '%')) 964 { 965 if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0) 966 { 967 *strp += 11; 968 errmsg = parse_symbolic_address (cd, strp, opindex, 969 BFD_RELOC_FRV_GETTLSOFF, 970 resultp, &value); 971 if (**strp != ')') 972 return _("missing `)'"); 973 ++*strp; 974 *valuep = value; 975 return errmsg; 976 } 977 } 978 979 return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep); 980 } 981 982 /* -- */ 983 984 const char * frv_cgen_parse_operand 985 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *); 986 987 /* Main entry point for operand parsing. 988 989 This function is basically just a big switch statement. Earlier versions 990 used tables to look up the function to use, but 991 - if the table contains both assembler and disassembler functions then 992 the disassembler contains much of the assembler and vice-versa, 993 - there's a lot of inlining possibilities as things grow, 994 - using a switch statement avoids the function call overhead. 995 996 This function could be moved into `parse_insn_normal', but keeping it 997 separate makes clear the interface between `parse_insn_normal' and each of 998 the handlers. */ 999 1000 const char * 1001 frv_cgen_parse_operand (CGEN_CPU_DESC cd, 1002 int opindex, 1003 const char ** strp, 1004 CGEN_FIELDS * fields) 1005 { 1006 const char * errmsg = NULL; 1007 /* Used by scalar operands that still need to be parsed. */ 1008 long junk ATTRIBUTE_UNUSED; 1009 1010 switch (opindex) 1011 { 1012 case FRV_OPERAND_A0 : 1013 errmsg = parse_A0 (cd, strp, FRV_OPERAND_A0, (unsigned long *) (& fields->f_A)); 1014 break; 1015 case FRV_OPERAND_A1 : 1016 errmsg = parse_A1 (cd, strp, FRV_OPERAND_A1, (unsigned long *) (& fields->f_A)); 1017 break; 1018 case FRV_OPERAND_ACC40SI : 1019 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Si); 1020 break; 1021 case FRV_OPERAND_ACC40SK : 1022 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Sk); 1023 break; 1024 case FRV_OPERAND_ACC40UI : 1025 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Ui); 1026 break; 1027 case FRV_OPERAND_ACC40UK : 1028 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Uk); 1029 break; 1030 case FRV_OPERAND_ACCGI : 1031 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGi); 1032 break; 1033 case FRV_OPERAND_ACCGK : 1034 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGk); 1035 break; 1036 case FRV_OPERAND_CCI : 1037 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CCi); 1038 break; 1039 case FRV_OPERAND_CPRDOUBLEK : 1040 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk); 1041 break; 1042 case FRV_OPERAND_CPRI : 1043 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRi); 1044 break; 1045 case FRV_OPERAND_CPRJ : 1046 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRj); 1047 break; 1048 case FRV_OPERAND_CPRK : 1049 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk); 1050 break; 1051 case FRV_OPERAND_CRI : 1052 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRi); 1053 break; 1054 case FRV_OPERAND_CRJ : 1055 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj); 1056 break; 1057 case FRV_OPERAND_CRJ_FLOAT : 1058 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_float); 1059 break; 1060 case FRV_OPERAND_CRJ_INT : 1061 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_int); 1062 break; 1063 case FRV_OPERAND_CRK : 1064 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRk); 1065 break; 1066 case FRV_OPERAND_FCCI_1 : 1067 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_1); 1068 break; 1069 case FRV_OPERAND_FCCI_2 : 1070 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_2); 1071 break; 1072 case FRV_OPERAND_FCCI_3 : 1073 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_3); 1074 break; 1075 case FRV_OPERAND_FCCK : 1076 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCk); 1077 break; 1078 case FRV_OPERAND_FRDOUBLEI : 1079 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi); 1080 break; 1081 case FRV_OPERAND_FRDOUBLEJ : 1082 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj); 1083 break; 1084 case FRV_OPERAND_FRDOUBLEK : 1085 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk); 1086 break; 1087 case FRV_OPERAND_FRI : 1088 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi); 1089 break; 1090 case FRV_OPERAND_FRINTI : 1091 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi); 1092 break; 1093 case FRV_OPERAND_FRINTIEVEN : 1094 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi); 1095 break; 1096 case FRV_OPERAND_FRINTJ : 1097 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj); 1098 break; 1099 case FRV_OPERAND_FRINTJEVEN : 1100 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj); 1101 break; 1102 case FRV_OPERAND_FRINTK : 1103 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk); 1104 break; 1105 case FRV_OPERAND_FRINTKEVEN : 1106 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk); 1107 break; 1108 case FRV_OPERAND_FRJ : 1109 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj); 1110 break; 1111 case FRV_OPERAND_FRK : 1112 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk); 1113 break; 1114 case FRV_OPERAND_FRKHI : 1115 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk); 1116 break; 1117 case FRV_OPERAND_FRKLO : 1118 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk); 1119 break; 1120 case FRV_OPERAND_GRDOUBLEK : 1121 errmsg = parse_even_register (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk); 1122 break; 1123 case FRV_OPERAND_GRI : 1124 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRi); 1125 break; 1126 case FRV_OPERAND_GRJ : 1127 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRj); 1128 break; 1129 case FRV_OPERAND_GRK : 1130 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk); 1131 break; 1132 case FRV_OPERAND_GRKHI : 1133 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk); 1134 break; 1135 case FRV_OPERAND_GRKLO : 1136 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk); 1137 break; 1138 case FRV_OPERAND_ICCI_1 : 1139 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_1); 1140 break; 1141 case FRV_OPERAND_ICCI_2 : 1142 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_2); 1143 break; 1144 case FRV_OPERAND_ICCI_3 : 1145 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_3); 1146 break; 1147 case FRV_OPERAND_LI : 1148 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LI, (unsigned long *) (& fields->f_LI)); 1149 break; 1150 case FRV_OPERAND_LRAD : 1151 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAD, (unsigned long *) (& fields->f_LRAD)); 1152 break; 1153 case FRV_OPERAND_LRAE : 1154 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAE, (unsigned long *) (& fields->f_LRAE)); 1155 break; 1156 case FRV_OPERAND_LRAS : 1157 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAS, (unsigned long *) (& fields->f_LRAS)); 1158 break; 1159 case FRV_OPERAND_TLBPRL : 1160 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_TLBPRL, (unsigned long *) (& fields->f_TLBPRL)); 1161 break; 1162 case FRV_OPERAND_TLBPROPX : 1163 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_TLBPROPX, (unsigned long *) (& fields->f_TLBPRopx)); 1164 break; 1165 case FRV_OPERAND_AE : 1166 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_AE, (unsigned long *) (& fields->f_ae)); 1167 break; 1168 case FRV_OPERAND_CALLANN : 1169 errmsg = parse_call_annotation (cd, strp, FRV_OPERAND_CALLANN, (unsigned long *) (& fields->f_reloc_ann)); 1170 break; 1171 case FRV_OPERAND_CCOND : 1172 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_CCOND, (unsigned long *) (& fields->f_ccond)); 1173 break; 1174 case FRV_OPERAND_COND : 1175 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_COND, (unsigned long *) (& fields->f_cond)); 1176 break; 1177 case FRV_OPERAND_D12 : 1178 errmsg = parse_d12 (cd, strp, FRV_OPERAND_D12, (long *) (& fields->f_d12)); 1179 break; 1180 case FRV_OPERAND_DEBUG : 1181 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_DEBUG, (unsigned long *) (& fields->f_debug)); 1182 break; 1183 case FRV_OPERAND_EIR : 1184 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_EIR, (unsigned long *) (& fields->f_eir)); 1185 break; 1186 case FRV_OPERAND_HINT : 1187 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_HINT, (unsigned long *) (& fields->f_hint)); 1188 break; 1189 case FRV_OPERAND_HINT_NOT_TAKEN : 1190 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_not_taken, & fields->f_hint); 1191 break; 1192 case FRV_OPERAND_HINT_TAKEN : 1193 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_taken, & fields->f_hint); 1194 break; 1195 case FRV_OPERAND_LABEL16 : 1196 { 1197 bfd_vma value = 0; 1198 errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL16, 0, NULL, & value); 1199 fields->f_label16 = value; 1200 } 1201 break; 1202 case FRV_OPERAND_LABEL24 : 1203 { 1204 bfd_vma value = 0; 1205 errmsg = parse_call_label (cd, strp, FRV_OPERAND_LABEL24, 0, NULL, & value); 1206 fields->f_label24 = value; 1207 } 1208 break; 1209 case FRV_OPERAND_LDANN : 1210 errmsg = parse_ld_annotation (cd, strp, FRV_OPERAND_LDANN, (unsigned long *) (& fields->f_reloc_ann)); 1211 break; 1212 case FRV_OPERAND_LDDANN : 1213 errmsg = parse_ldd_annotation (cd, strp, FRV_OPERAND_LDDANN, (unsigned long *) (& fields->f_reloc_ann)); 1214 break; 1215 case FRV_OPERAND_LOCK : 1216 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LOCK, (unsigned long *) (& fields->f_lock)); 1217 break; 1218 case FRV_OPERAND_PACK : 1219 errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_pack, & fields->f_pack); 1220 break; 1221 case FRV_OPERAND_S10 : 1222 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S10, (long *) (& fields->f_s10)); 1223 break; 1224 case FRV_OPERAND_S12 : 1225 errmsg = parse_s12 (cd, strp, FRV_OPERAND_S12, (long *) (& fields->f_d12)); 1226 break; 1227 case FRV_OPERAND_S16 : 1228 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S16, (long *) (& fields->f_s16)); 1229 break; 1230 case FRV_OPERAND_S5 : 1231 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S5, (long *) (& fields->f_s5)); 1232 break; 1233 case FRV_OPERAND_S6 : 1234 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6, (long *) (& fields->f_s6)); 1235 break; 1236 case FRV_OPERAND_S6_1 : 1237 errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6_1, (long *) (& fields->f_s6_1)); 1238 break; 1239 case FRV_OPERAND_SLO16 : 1240 errmsg = parse_uslo16 (cd, strp, FRV_OPERAND_SLO16, (long *) (& fields->f_s16)); 1241 break; 1242 case FRV_OPERAND_SPR : 1243 errmsg = parse_spr (cd, strp, & frv_cgen_opval_spr_names, & fields->f_spr); 1244 break; 1245 case FRV_OPERAND_U12 : 1246 errmsg = parse_u12 (cd, strp, FRV_OPERAND_U12, (long *) (& fields->f_u12)); 1247 break; 1248 case FRV_OPERAND_U16 : 1249 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U16, (unsigned long *) (& fields->f_u16)); 1250 break; 1251 case FRV_OPERAND_U6 : 1252 errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U6, (unsigned long *) (& fields->f_u6)); 1253 break; 1254 case FRV_OPERAND_UHI16 : 1255 errmsg = parse_uhi16 (cd, strp, FRV_OPERAND_UHI16, (unsigned long *) (& fields->f_u16)); 1256 break; 1257 case FRV_OPERAND_ULO16 : 1258 errmsg = parse_ulo16 (cd, strp, FRV_OPERAND_ULO16, (unsigned long *) (& fields->f_u16)); 1259 break; 1260 1261 default : 1262 /* xgettext:c-format */ 1263 fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex); 1264 abort (); 1265 } 1266 1267 return errmsg; 1268 } 1269 1270 cgen_parse_fn * const frv_cgen_parse_handlers[] = 1271 { 1272 parse_insn_normal, 1273 }; 1274 1275 void 1276 frv_cgen_init_asm (CGEN_CPU_DESC cd) 1277 { 1278 frv_cgen_init_opcode_table (cd); 1279 frv_cgen_init_ibld_table (cd); 1280 cd->parse_handlers = & frv_cgen_parse_handlers[0]; 1281 cd->parse_operand = frv_cgen_parse_operand; 1282 #ifdef CGEN_ASM_INIT_HOOK 1283 CGEN_ASM_INIT_HOOK 1284 #endif 1285 } 1286 1287 1288 1290 /* Regex construction routine. 1291 1292 This translates an opcode syntax string into a regex string, 1293 by replacing any non-character syntax element (such as an 1294 opcode) with the pattern '.*' 1295 1296 It then compiles the regex and stores it in the opcode, for 1297 later use by frv_cgen_assemble_insn 1298 1299 Returns NULL for success, an error message for failure. */ 1300 1301 char * 1302 frv_cgen_build_insn_regex (CGEN_INSN *insn) 1303 { 1304 CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn); 1305 const char *mnem = CGEN_INSN_MNEMONIC (insn); 1306 char rxbuf[CGEN_MAX_RX_ELEMENTS]; 1307 char *rx = rxbuf; 1308 const CGEN_SYNTAX_CHAR_TYPE *syn; 1309 int reg_err; 1310 1311 syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc)); 1312 1313 /* Mnemonics come first in the syntax string. */ 1314 if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) 1315 return _("missing mnemonic in syntax string"); 1316 ++syn; 1317 1318 /* Generate a case sensitive regular expression that emulates case 1319 insensitive matching in the "C" locale. We cannot generate a case 1320 insensitive regular expression because in Turkish locales, 'i' and 'I' 1321 are not equal modulo case conversion. */ 1322 1323 /* Copy the literal mnemonic out of the insn. */ 1324 for (; *mnem; mnem++) 1325 { 1326 char c = *mnem; 1327 1328 if (ISALPHA (c)) 1329 { 1330 *rx++ = '['; 1331 *rx++ = TOLOWER (c); 1332 *rx++ = TOUPPER (c); 1333 *rx++ = ']'; 1334 } 1335 else 1336 *rx++ = c; 1337 } 1338 1339 /* Copy any remaining literals from the syntax string into the rx. */ 1340 for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn) 1341 { 1342 if (CGEN_SYNTAX_CHAR_P (* syn)) 1343 { 1344 char c = CGEN_SYNTAX_CHAR (* syn); 1345 1346 switch (c) 1347 { 1348 /* Escape any regex metacharacters in the syntax. */ 1349 case '.': case '[': case '\\': 1350 case '*': case '^': case '$': 1351 1352 #ifdef CGEN_ESCAPE_EXTENDED_REGEX 1353 case '?': case '{': case '}': 1354 case '(': case ')': case '*': 1355 case '|': case '+': case ']': 1356 #endif 1357 *rx++ = '\\'; 1358 *rx++ = c; 1359 break; 1360 1361 default: 1362 if (ISALPHA (c)) 1363 { 1364 *rx++ = '['; 1365 *rx++ = TOLOWER (c); 1366 *rx++ = TOUPPER (c); 1367 *rx++ = ']'; 1368 } 1369 else 1370 *rx++ = c; 1371 break; 1372 } 1373 } 1374 else 1375 { 1376 /* Replace non-syntax fields with globs. */ 1377 *rx++ = '.'; 1378 *rx++ = '*'; 1379 } 1380 } 1381 1382 /* Trailing whitespace ok. */ 1383 * rx++ = '['; 1384 * rx++ = ' '; 1385 * rx++ = '\t'; 1386 * rx++ = ']'; 1387 * rx++ = '*'; 1388 1389 /* But anchor it after that. */ 1390 * rx++ = '$'; 1391 * rx = '\0'; 1392 1393 CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t)); 1394 reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB); 1395 1396 if (reg_err == 0) 1397 return NULL; 1398 else 1399 { 1400 static char msg[80]; 1401 1402 regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80); 1403 regfree ((regex_t *) CGEN_INSN_RX (insn)); 1404 free (CGEN_INSN_RX (insn)); 1405 (CGEN_INSN_RX (insn)) = NULL; 1406 return msg; 1407 } 1408 } 1409 1410 1411 /* Default insn parser. 1413 1414 The syntax string is scanned and operands are parsed and stored in FIELDS. 1415 Relocs are queued as we go via other callbacks. 1416 1417 ??? Note that this is currently an all-or-nothing parser. If we fail to 1418 parse the instruction, we return 0 and the caller will start over from 1419 the beginning. Backtracking will be necessary in parsing subexpressions, 1420 but that can be handled there. Not handling backtracking here may get 1421 expensive in the case of the m68k. Deal with later. 1422 1423 Returns NULL for success, an error message for failure. */ 1424 1425 static const char * 1426 parse_insn_normal (CGEN_CPU_DESC cd, 1427 const CGEN_INSN *insn, 1428 const char **strp, 1429 CGEN_FIELDS *fields) 1430 { 1431 /* ??? Runtime added insns not handled yet. */ 1432 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); 1433 const char *str = *strp; 1434 const char *errmsg; 1435 const char *p; 1436 const CGEN_SYNTAX_CHAR_TYPE * syn; 1437 #ifdef CGEN_MNEMONIC_OPERANDS 1438 /* FIXME: wip */ 1439 int past_opcode_p; 1440 #endif 1441 1442 /* For now we assume the mnemonic is first (there are no leading operands). 1443 We can parse it without needing to set up operand parsing. 1444 GAS's input scrubber will ensure mnemonics are lowercase, but we may 1445 not be called from GAS. */ 1446 p = CGEN_INSN_MNEMONIC (insn); 1447 while (*p && TOLOWER (*p) == TOLOWER (*str)) 1448 ++p, ++str; 1449 1450 if (* p) 1451 return _("unrecognized instruction"); 1452 1453 #ifndef CGEN_MNEMONIC_OPERANDS 1454 if (* str && ! ISSPACE (* str)) 1455 return _("unrecognized instruction"); 1456 #endif 1457 1458 CGEN_INIT_PARSE (cd); 1459 cgen_init_parse_operand (cd); 1460 #ifdef CGEN_MNEMONIC_OPERANDS 1461 past_opcode_p = 0; 1462 #endif 1463 1464 /* We don't check for (*str != '\0') here because we want to parse 1465 any trailing fake arguments in the syntax string. */ 1466 syn = CGEN_SYNTAX_STRING (syntax); 1467 1468 /* Mnemonics come first for now, ensure valid string. */ 1469 if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) 1470 abort (); 1471 1472 ++syn; 1473 1474 while (* syn != 0) 1475 { 1476 /* Non operand chars must match exactly. */ 1477 if (CGEN_SYNTAX_CHAR_P (* syn)) 1478 { 1479 /* FIXME: While we allow for non-GAS callers above, we assume the 1480 first char after the mnemonic part is a space. */ 1481 /* FIXME: We also take inappropriate advantage of the fact that 1482 GAS's input scrubber will remove extraneous blanks. */ 1483 if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn))) 1484 { 1485 #ifdef CGEN_MNEMONIC_OPERANDS 1486 if (CGEN_SYNTAX_CHAR(* syn) == ' ') 1487 past_opcode_p = 1; 1488 #endif 1489 ++ syn; 1490 ++ str; 1491 } 1492 else if (*str) 1493 { 1494 /* Syntax char didn't match. Can't be this insn. */ 1495 static char msg [80]; 1496 1497 /* xgettext:c-format */ 1498 sprintf (msg, _("syntax error (expected char `%c', found `%c')"), 1499 CGEN_SYNTAX_CHAR(*syn), *str); 1500 return msg; 1501 } 1502 else 1503 { 1504 /* Ran out of input. */ 1505 static char msg [80]; 1506 1507 /* xgettext:c-format */ 1508 sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"), 1509 CGEN_SYNTAX_CHAR(*syn)); 1510 return msg; 1511 } 1512 continue; 1513 } 1514 1515 #ifdef CGEN_MNEMONIC_OPERANDS 1516 (void) past_opcode_p; 1517 #endif 1518 /* We have an operand of some sort. */ 1519 errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields); 1520 if (errmsg) 1521 return errmsg; 1522 1523 /* Done with this operand, continue with next one. */ 1524 ++ syn; 1525 } 1526 1527 /* If we're at the end of the syntax string, we're done. */ 1528 if (* syn == 0) 1529 { 1530 /* FIXME: For the moment we assume a valid `str' can only contain 1531 blanks now. IE: We needn't try again with a longer version of 1532 the insn and it is assumed that longer versions of insns appear 1533 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */ 1534 while (ISSPACE (* str)) 1535 ++ str; 1536 1537 if (* str != '\0') 1538 return _("junk at end of line"); /* FIXME: would like to include `str' */ 1539 1540 return NULL; 1541 } 1542 1543 /* We couldn't parse it. */ 1544 return _("unrecognized instruction"); 1545 } 1546 1547 /* Main entry point. 1549 This routine is called for each instruction to be assembled. 1550 STR points to the insn to be assembled. 1551 We assume all necessary tables have been initialized. 1552 The assembled instruction, less any fixups, is stored in BUF. 1553 Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value 1554 still needs to be converted to target byte order, otherwise BUF is an array 1555 of bytes in target byte order. 1556 The result is a pointer to the insn's entry in the opcode table, 1557 or NULL if an error occured (an error message will have already been 1558 printed). 1559 1560 Note that when processing (non-alias) macro-insns, 1561 this function recurses. 1562 1563 ??? It's possible to make this cpu-independent. 1564 One would have to deal with a few minor things. 1565 At this point in time doing so would be more of a curiosity than useful 1566 [for example this file isn't _that_ big], but keeping the possibility in 1567 mind helps keep the design clean. */ 1568 1569 const CGEN_INSN * 1570 frv_cgen_assemble_insn (CGEN_CPU_DESC cd, 1571 const char *str, 1572 CGEN_FIELDS *fields, 1573 CGEN_INSN_BYTES_PTR buf, 1574 char **errmsg) 1575 { 1576 const char *start; 1577 CGEN_INSN_LIST *ilist; 1578 const char *parse_errmsg = NULL; 1579 const char *insert_errmsg = NULL; 1580 int recognized_mnemonic = 0; 1581 1582 /* Skip leading white space. */ 1583 while (ISSPACE (* str)) 1584 ++ str; 1585 1586 /* The instructions are stored in hashed lists. 1587 Get the first in the list. */ 1588 ilist = CGEN_ASM_LOOKUP_INSN (cd, str); 1589 1590 /* Keep looking until we find a match. */ 1591 start = str; 1592 for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist)) 1593 { 1594 const CGEN_INSN *insn = ilist->insn; 1595 recognized_mnemonic = 1; 1596 1597 #ifdef CGEN_VALIDATE_INSN_SUPPORTED 1598 /* Not usually needed as unsupported opcodes 1599 shouldn't be in the hash lists. */ 1600 /* Is this insn supported by the selected cpu? */ 1601 if (! frv_cgen_insn_supported (cd, insn)) 1602 continue; 1603 #endif 1604 /* If the RELAXED attribute is set, this is an insn that shouldn't be 1605 chosen immediately. Instead, it is used during assembler/linker 1606 relaxation if possible. */ 1607 if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0) 1608 continue; 1609 1610 str = start; 1611 1612 /* Skip this insn if str doesn't look right lexically. */ 1613 if (CGEN_INSN_RX (insn) != NULL && 1614 regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH) 1615 continue; 1616 1617 /* Allow parse/insert handlers to obtain length of insn. */ 1618 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); 1619 1620 parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields); 1621 if (parse_errmsg != NULL) 1622 continue; 1623 1624 /* ??? 0 is passed for `pc'. */ 1625 insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf, 1626 (bfd_vma) 0); 1627 if (insert_errmsg != NULL) 1628 continue; 1629 1630 /* It is up to the caller to actually output the insn and any 1631 queued relocs. */ 1632 return insn; 1633 } 1634 1635 { 1636 static char errbuf[150]; 1637 const char *tmp_errmsg; 1638 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS 1639 #define be_verbose 1 1640 #else 1641 #define be_verbose 0 1642 #endif 1643 1644 if (be_verbose) 1645 { 1646 /* If requesting verbose error messages, use insert_errmsg. 1647 Failing that, use parse_errmsg. */ 1648 tmp_errmsg = (insert_errmsg ? insert_errmsg : 1649 parse_errmsg ? parse_errmsg : 1650 recognized_mnemonic ? 1651 _("unrecognized form of instruction") : 1652 _("unrecognized instruction")); 1653 1654 if (strlen (start) > 50) 1655 /* xgettext:c-format */ 1656 sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start); 1657 else 1658 /* xgettext:c-format */ 1659 sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start); 1660 } 1661 else 1662 { 1663 if (strlen (start) > 50) 1664 /* xgettext:c-format */ 1665 sprintf (errbuf, _("bad instruction `%.50s...'"), start); 1666 else 1667 /* xgettext:c-format */ 1668 sprintf (errbuf, _("bad instruction `%.50s'"), start); 1669 } 1670 1671 *errmsg = errbuf; 1672 return NULL; 1673 } 1674 } 1675