
1: /* m32c opcode support. -*- C -*- 2: 3: Copyright 2005, 2007 Free Software Foundation, Inc. 4: 5: Contributed by Red Hat Inc; developed under contract from Renesas 6: 7: This file is part of the GNU Binutils. 8: 9: This program is free software; you can redistribute it and/or modify 10: it under the terms of the GNU General Public License as published by 11: the Free Software Foundation; either version 3 of the License, or 12: (at your option) any later version. 13: 14: This program is distributed in the hope that it will be useful, 15: but WITHOUT ANY WARRANTY; without even the implied warranty of 16: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17: GNU General Public License for more details. 18: 19: You should have received a copy of the GNU General Public License 20: along with this program; if not, write to the Free Software 21: Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 22: MA 02110-1301, USA. */ 23: 24: 25: /* This file is an addendum to m32c.cpu. Heavy use of C code isn't 26: appropriate in .cpu files, so it resides here. This especially applies 27: to assembly/disassembly where parsing/printing can be quite involved. 28: Such things aren't really part of the specification of the cpu, per se, 29: so .cpu files provide the general framework and .opc files handle the 30: nitty-gritty details as necessary. 31: 32: Each section is delimited with start and end markers. 33: 34: <arch>-opc.h additions use: "-- opc.h" 35: <arch>-opc.c additions use: "-- opc.c" 36: <arch>-asm.c additions use: "-- asm.c" 37: <arch>-dis.c additions use: "-- dis.c" 38: <arch>-ibd.h additions use: "-- ibd.h". */ 39: ^L 40: /* -- opc.h */ 41: 42: /* Needed for RTL's 'ext' and 'trunc' operators. */ 43: #include "cgen-types.h" 44: #include "cgen-ops.h" 45: 46: /* We can't use the default hash size because many bits are used by 47: operands. */ 48: #define CGEN_DIS_HASH_SIZE 1 49: #define CGEN_DIS_HASH(buf, value) 0 50: #define CGEN_VERBOSE_ASSEMBLER_ERRORS 51: #define CGEN_VALIDATE_INSN_SUPPORTED 52: 53: extern int m32c_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *); 54: 55: #define CGEN_ASM_HASH_SIZE 0xffff 56: #define CGEN_ASM_HASH(mnem) m32c_asm_hash ((mnem)) 57: 58: /* -- */ 59: ^L 60: /* -- opc.c */ 61: static unsigned int 62: m32c_asm_hash (const char *mnem) 63: { 64: unsigned int h; 65: 66: /* The length of the mnemonic for the Jcnd insns is 1. Hash jsri. */ 67: if (mnem[0] == 'j' && mnem[1] != 's') 68: return 'j'; 69: 70: /* Don't hash scCND */ 71: if (mnem[0] == 's' && mnem[1] == 'c') 72: return 's'; 73: 74: /* Don't hash bmCND */ 75: if (mnem[0] == 'b' && mnem[1] == 'm') 76: return 'b'; 77: 78: for (h = 0; *mnem && *mnem != ' ' && *mnem != ':'; ++mnem) 79: h += *mnem; 80: return h % CGEN_ASM_HASH_SIZE; 81: } 82: ^L 83: /* -- asm.c */ 84: #include "safe-ctype.h" 85: 86: #define MACH_M32C 5 /* Must match md_begin. */ 87: 88: static int 89: m32c_cgen_isa_register (const char **strp) 90: { 91: int u; 92: const char *s = *strp; 93: static char * m32c_register_names [] = 94: { 95: "r0", "r1", "r2", "r3", "r0l", "r0h", "r1l", "r1h", 96: "a0", "a1", "r2r0", "r3r1", "sp", "fb", "dct0", "dct1", "flg", "svf", 97: "drc0", "drc1", "dmd0", "dmd1", "intb", "svp", "vct", "isp", "dma0", 98: "dma1", "dra0", "dra1", "dsa0", "dsa1", 0 99: }; 100: 101: for (u = 0; m32c_register_names[u]; u++) 102: { 103: int len = strlen (m32c_register_names[u]); 104: 105: if (memcmp (m32c_register_names[u], s, len) == 0 106: && (s[len] == 0 || ! ISALNUM (s[len]))) 107: return 1; 108: } 109: return 0; 110: } 111: 112: #define PARSE_UNSIGNED \ 113: do \ 114: { \ 115: /* Don't successfully parse literals beginning with '['. */ \ 116: if (**strp == '[') \ 117: return "Invalid literal"; /* Anything -- will not be seen. */ \ 118: \ 119: errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);\ 120: if (errmsg) \ 121: return errmsg; \ 122: } \ 123: while (0) 124: 125: #define PARSE_SIGNED \ 126: do \ 127: { \ 128: /* Don't successfully parse literals beginning with '['. */ \ 129: if (**strp == '[') \ 130: return "Invalid literal"; /* Anything -- will not be seen. */ \ 131: \ 132: errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); \ 133: if (errmsg) \ 134: return errmsg; \ 135: } \ 136: while (0) 137: 138: static const char * 139: parse_unsigned6 (CGEN_CPU_DESC cd, const char **strp, 140: int opindex, unsigned long *valuep) 141: { 142: const char *errmsg = 0; 143: unsigned long value; 144: 145: PARSE_UNSIGNED; 146: 147: if (value > 0x3f) 148: return _("imm:6 immediate is out of range"); 149: 150: *valuep = value; 151: return 0; 152: } 153: 154: static const char * 155: parse_unsigned8 (CGEN_CPU_DESC cd, const char **strp, 156: int opindex, unsigned long *valuep) 157: { 158: const char *errmsg = 0; 159: unsigned long value; 160: long have_zero = 0; 161: 162: if (strncasecmp (*strp, "%dsp8(", 6) == 0) 163: { 164: enum cgen_parse_operand_result result_type; 165: bfd_vma value; 166: const char *errmsg; 167: 168: *strp += 6; 169: errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_8, 170: & result_type, & value); 171: if (**strp != ')') 172: return _("missing `)'"); 173: (*strp) ++; 174: 175: if (errmsg == NULL 176: && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 177: { 178: return _("%dsp8() takes a symbolic address, not a number"); 179: } 180: *valuep = value; 181: return errmsg; 182: } 183: 184: if (strncmp (*strp, "0x0", 3) == 0 185: || (**strp == '0' && *(*strp + 1) != 'x')) 186: have_zero = 1; 187: 188: PARSE_UNSIGNED; 189: 190: if (value > 0xff) 191: return _("dsp:8 immediate is out of range"); 192: 193: /* If this field may require a relocation then use larger dsp16. */ 194: if (! have_zero && value == 0) 195: return _("dsp:8 immediate is out of range"); 196: 197: *valuep = value; 198: return 0; 199: } 200: 201: static const char * 202: parse_signed4 (CGEN_CPU_DESC cd, const char **strp, 203: int opindex, signed long *valuep) 204: { 205: const char *errmsg = 0; 206: signed long value; 207: long have_zero = 0; 208: 209: if (strncmp (*strp, "0x0", 3) == 0 210: || (**strp == '0' && *(*strp + 1) != 'x')) 211: have_zero = 1; 212: 213: PARSE_SIGNED; 214: 215: if (value < -8 || value > 7) 216: return _("Immediate is out of range -8 to 7"); 217: 218: /* If this field may require a relocation then use larger dsp16. */ 219: if (! have_zero && value == 0) 220: return _("Immediate is out of range -8 to 7"); 221: 222: *valuep = value; 223: return 0; 224: } 225: 226: static const char * 227: parse_signed4n (CGEN_CPU_DESC cd, const char **strp, 228: int opindex, signed long *valuep) 229: { 230: const char *errmsg = 0; 231: signed long value; 232: long have_zero = 0; 233: 234: if (strncmp (*strp, "0x0", 3) == 0 235: || (**strp == '0' && *(*strp + 1) != 'x')) 236: have_zero = 1; 237: 238: PARSE_SIGNED; 239: 240: if (value < -7 || value > 8) 241: return _("Immediate is out of range -7 to 8"); 242: 243: /* If this field may require a relocation then use larger dsp16. */ 244: if (! have_zero && value == 0) 245: return _("Immediate is out of range -7 to 8"); 246: 247: *valuep = -value; 248: return 0; 249: } 250: 251: static const char * 252: parse_signed8 (CGEN_CPU_DESC cd, const char **strp, 253: int opindex, signed long *valuep) 254: { 255: const char *errmsg = 0; 256: signed long value; 257: 258: if (strncasecmp (*strp, "%hi8(", 5) == 0) 259: { 260: enum cgen_parse_operand_result result_type; 261: bfd_vma value; 262: const char *errmsg; 263: 264: *strp += 5; 265: errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_M32C_HI8, 266: & result_type, & value); 267: if (**strp != ')') 268: return _("missing `)'"); 269: (*strp) ++; 270: 271: if (errmsg == NULL 272: && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 273: { 274: value >>= 16; 275: } 276: *valuep = value; 277: return errmsg; 278: } 279: 280: PARSE_SIGNED; 281: 282: if (value <= 255 && value > 127) 283: value -= 0x100; 284: 285: if (value < -128 || value > 127) 286: return _("dsp:8 immediate is out of range"); 287: 288: *valuep = value; 289: return 0; 290: } 291: 292: static const char * 293: parse_unsigned16 (CGEN_CPU_DESC cd, const char **strp, 294: int opindex, unsigned long *valuep) 295: { 296: const char *errmsg = 0; 297: unsigned long value; 298: long have_zero = 0; 299: 300: if (strncasecmp (*strp, "%dsp16(", 7) == 0) 301: { 302: enum cgen_parse_operand_result result_type; 303: bfd_vma value; 304: const char *errmsg; 305: 306: *strp += 7; 307: errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_16, 308: & result_type, & value); 309: if (**strp != ')') 310: return _("missing `)'"); 311: (*strp) ++; 312: 313: if (errmsg == NULL 314: && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 315: { 316: return _("%dsp16() takes a symbolic address, not a number"); 317: } 318: *valuep = value; 319: return errmsg; 320: } 321: 322: /* Don't successfully parse literals beginning with '['. */ 323: if (**strp == '[') 324: return "Invalid literal"; /* Anything -- will not be seen. */ 325: 326: /* Don't successfully parse register names. */ 327: if (m32c_cgen_isa_register (strp)) 328: return "Invalid literal"; /* Anything -- will not be seen. */ 329: 330: if (strncmp (*strp, "0x0", 3) == 0 331: || (**strp == '0' && *(*strp + 1) != 'x')) 332: have_zero = 1; 333: 334: errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value); 335: if (errmsg) 336: return errmsg; 337: 338: if (value > 0xffff) 339: return _("dsp:16 immediate is out of range"); 340: 341: /* If this field may require a relocation then use larger dsp24. */ 342: if (cd->machs == MACH_M32C && ! have_zero && value == 0 343: && (strncmp (*strp, "[a", 2) == 0 344: || **strp == ',' 345: || **strp == 0)) 346: return _("dsp:16 immediate is out of range"); 347: 348: *valuep = value; 349: return 0; 350: } 351: 352: static const char * 353: parse_signed16 (CGEN_CPU_DESC cd, const char **strp, 354: int opindex, signed long *valuep) 355: { 356: const char *errmsg = 0; 357: signed long value; 358: 359: if (strncasecmp (*strp, "%lo16(", 6) == 0) 360: { 361: enum cgen_parse_operand_result result_type; 362: bfd_vma value; 363: const char *errmsg; 364: 365: *strp += 6; 366: errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16, 367: & result_type, & value); 368: if (**strp != ')') 369: return _("missing `)'"); 370: (*strp) ++; 371: 372: if (errmsg == NULL 373: && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 374: { 375: value &= 0xffff; 376: } 377: *valuep = value; 378: return errmsg; 379: } 380: 381: if (strncasecmp (*strp, "%hi16(", 6) == 0) 382: { 383: enum cgen_parse_operand_result result_type; 384: bfd_vma value; 385: const char *errmsg; 386: 387: *strp += 6; 388: errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16, 389: & result_type, & value); 390: if (**strp != ')') 391: return _("missing `)'"); 392: (*strp) ++; 393: 394: if (errmsg == NULL 395: && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) 396: { 397: value >>= 16; 398: } 399: *valuep = value; 400: return errmsg; 401: } 402: 403: PARSE_SIGNED; 404: 405: if (value <= 65535 && value > 32767) 406: value -= 0x10000; 407: 408: if (value < -32768 || value > 32767) 409: return _("dsp:16 immediate is out of range"); 410: 411: *valuep = value; 412: return 0; 413: } 414: 415: static const char * 416: parse_unsigned20 (CGEN_CPU_DESC cd, const char **strp, 417: int opindex, unsigned long *valuep) 418: { 419: const char *errmsg = 0; 420: unsigned long value; 421: 422: /* Don't successfully parse literals beginning with '['. */ 423: if (**strp == '[') 424: return "Invalid literal"; /* Anything -- will not be seen. */ 425: 426: /* Don't successfully parse register names. */ 427: if (m32c_cgen_isa_register (strp)) 428: return "Invalid literal"; /* Anything -- will not be seen. */ 429: 430: errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value); 431: if (errmsg) 432: return errmsg; 433: 434: if (value > 0xfffff) 435: return _("dsp:20 immediate is out of range"); 436: 437: *valuep = value; 438: return 0; 439: } 440: 441: static const char * 442: parse_unsigned24 (CGEN_CPU_DESC cd, const char **strp, 443: int opindex, unsigned long *valuep) 444: { 445: const char *errmsg = 0; 446: unsigned long value; 447: 448: /* Don't successfully parse literals beginning with '['. */ 449: if (**strp == '[') 450: return "Invalid literal"; /* Anything -- will not be seen. */ 451: 452: /* Don't successfully parse register names. */ 453: if (m32c_cgen_isa_register (strp)) 454: return "Invalid literal"; /* Anything -- will not be seen. */ 455: 456: errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value); 457: if (errmsg) 458: return errmsg; 459: 460: if (value > 0xffffff) 461: return _("dsp:24 immediate is out of range"); 462: 463: *valuep = value; 464: return 0; 465: } 466: 467: /* This should only be used for #imm->reg. */ 468: static const char * 469: parse_signed24 (CGEN_CPU_DESC cd, const char **strp, 470: int opindex, signed long *valuep) 471: { 472: const char *errmsg = 0; 473: signed long value; 474: 475: PARSE_SIGNED; 476: 477: if (value <= 0xffffff && value > 0x7fffff) 478: value -= 0x1000000; 479: 480: if (value > 0xffffff) 481: return _("dsp:24 immediate is out of range"); 482: 483: *valuep = value; 484: return 0; 485: } 486: 487: static const char * 488: parse_signed32 (CGEN_CPU_DESC cd, const char **strp, 489: int opindex, signed long *valuep) 490: { 491: const char *errmsg = 0; 492: signed long value; 493: 494: errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); 495: if (errmsg) 496: return errmsg; 497: 498: *valuep = value; 499: return 0; 500: } 501: 502: static const char * 503: parse_imm1_S (CGEN_CPU_DESC cd, const char **strp, 504: int opindex, signed long *valuep) 505: { 506: const char *errmsg = 0; 507: signed long value; 508: 509: errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); 510: if (errmsg) 511: return errmsg; 512: 513: if (value < 1 || value > 2) 514: return _("immediate is out of range 1-2"); 515: 516: *valuep = value; 517: return 0; 518: } 519: 520: static const char * 521: parse_imm3_S (CGEN_CPU_DESC cd, const char **strp, 522: int opindex, signed long *valuep) 523: { 524: const char *errmsg = 0; 525: signed long value; 526: 527: errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); 528: if (errmsg) 529: return errmsg; 530: 531: if (value < 1 || value > 8) 532: return _("immediate is out of range 1-8"); 533: 534: *valuep = value; 535: return 0; 536: } 537: 538: static const char * 539: parse_bit3_S (CGEN_CPU_DESC cd, const char **strp, 540: int opindex, signed long *valuep) 541: { 542: const char *errmsg = 0; 543: signed long value; 544: 545: errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value); 546: if (errmsg) 547: return errmsg; 548: 549: if (value < 0 || value > 7) 550: return _("immediate is out of range 0-7"); 551: 552: *valuep = value; 553: return 0; 554: } 555: 556: static const char * 557: parse_lab_5_3 (CGEN_CPU_DESC cd, 558: const char **strp, 559: int opindex ATTRIBUTE_UNUSED, 560: int opinfo, 561: enum cgen_parse_operand_result *type_addr, 562: bfd_vma *valuep) 563: { 564: const char *errmsg = 0; 565: bfd_vma value; 566: enum cgen_parse_operand_result op_res; 567: 568: errmsg = cgen_parse_address (cd, strp, M32C_OPERAND_LAB_5_3, 569: opinfo, & op_res, & value); 570: 571: if (type_addr) 572: *type_addr = op_res; 573: 574: if (op_res == CGEN_PARSE_OPERAND_ADDRESS) 575: { 576: /* This is a hack; the field cannot handle near-zero signed 577: offsets that CGEN wants to put in to indicate an "empty" 578: operand at first. */ 579: *valuep = 2; 580: return 0; 581: } 582: if (errmsg) 583: return errmsg; 584: 585: if (value < 2 || value > 9) 586: return _("immediate is out of range 2-9"); 587: 588: *valuep = value; 589: return 0; 590: } 591: 592: static const char * 593: parse_Bitno16R (CGEN_CPU_DESC cd, const char **strp, 594: int opindex, unsigned long *valuep) 595: { 596: const char *errmsg = 0; 597: unsigned long value; 598: 599: errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value); 600: if (errmsg) 601: return errmsg; 602: 603: if (value > 15) 604: return _("Bit number for indexing general register is out of range 0-15"); 605: 606: *valuep = value; 607: return 0; 608: } 609: 610: static const char * 611: parse_unsigned_bitbase (CGEN_CPU_DESC cd, const char **strp, 612: int opindex, unsigned long *valuep, 613: unsigned bits, int allow_syms) 614: { 615: const char *errmsg = 0; 616: unsigned long bit; 617: unsigned long base; 618: const char *newp = *strp; 619: unsigned long long bitbase; 620: long have_zero = 0; 621: 622: errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & bit); 623: if (errmsg) 624: return errmsg; 625: 626: if (*newp != ',') 627: return "Missing base for bit,base:8"; 628: 629: ++newp; 630: 631: if (strncmp (newp, "0x0", 3) == 0 632: || (newp[0] == '0' && newp[1] != 'x')) 633: have_zero = 1; 634: 635: errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & base); 636: if (errmsg) 637: return errmsg; 638: 639: bitbase = (unsigned long long) bit + ((unsigned long long) base * 8); 640: 641: if (bitbase >= (1ull << bits)) 642: return _("bit,base is out of range"); 643: 644: /* If this field may require a relocation then use larger displacement. */ 645: if (! have_zero && base == 0) 646: { 647: switch (allow_syms) { 648: case 0: 649: return _("bit,base out of range for symbol"); 650: case 1: 651: break; 652: case 2: 653: if (strncmp (newp, "[sb]", 4) != 0) 654: return _("bit,base out of range for symbol"); 655: break; 656: } 657: } 658: 659: *valuep = bitbase; 660: *strp = newp; 661: return 0; 662: } 663: 664: static const char * 665: parse_signed_bitbase (CGEN_CPU_DESC cd, const char **strp, 666: int opindex, signed long *valuep, 667: unsigned bits, int allow_syms) 668: { 669: const char *errmsg = 0; 670: unsigned long bit; 671: signed long base; 672: const char *newp = *strp; 673: long long bitbase; 674: long long limit; 675: long have_zero = 0; 676: 677: errmsg = cgen_parse_unsigned_integer (cd, & newp, opindex, & bit); 678: if (errmsg) 679: return errmsg; 680: 681: if (*newp != ',') 682: return "Missing base for bit,base:8"; 683: 684: ++newp; 685: 686: if (strncmp (newp, "0x0", 3) == 0 687: || (newp[0] == '0' && newp[1] != 'x')) 688: have_zero = 1; 689: 690: errmsg = cgen_parse_signed_integer (cd, & newp, opindex, & base); 691: if (errmsg) 692: return errmsg; 693: 694: bitbase = (long long)bit + ((long long)base * 8); 695: 696: limit = 1ll << (bits - 1); 697: if (bitbase < -limit || bitbase >= limit) 698: return _("bit,base is out of range"); 699: 700: /* If this field may require a relocation then use larger displacement. */ 701: if (! have_zero && base == 0 && ! allow_syms) 702: return _("bit,base out of range for symbol"); 703: 704: *valuep = bitbase; 705: *strp = newp; 706: return 0; 707: } 708: 709: static const char * 710: parse_unsigned_bitbase8 (CGEN_CPU_DESC cd, const char **strp, 711: int opindex, unsigned long *valuep) 712: { 713: return parse_unsigned_bitbase (cd, strp, opindex, valuep, 8, 0); 714: } 715: 716: static const char * 717: parse_unsigned_bitbase11 (CGEN_CPU_DESC cd, const char **strp, 718: int opindex, unsigned long *valuep) 719: { 720: return parse_unsigned_bitbase (cd, strp, opindex, valuep, 11, 0); 721: } 722: 723: static const char * 724: parse_unsigned_bitbase16 (CGEN_CPU_DESC cd, const char **strp, 725: int opindex, unsigned long *valuep) 726: { 727: return parse_unsigned_bitbase (cd, strp, opindex, valuep, 16, 1); 728: } 729: 730: static const char * 731: parse_unsigned_bitbase19 (CGEN_CPU_DESC cd, const char **strp, 732: int opindex, unsigned long *valuep) 733: { 734: return parse_unsigned_bitbase (cd, strp, opindex, valuep, 19, 2); 735: } 736: 737: static const char * 738: parse_unsigned_bitbase27 (CGEN_CPU_DESC cd, const char **strp, 739: int opindex, unsigned long *valuep) 740: { 741: return parse_unsigned_bitbase (cd, strp, opindex, valuep, 27, 1); 742: } 743: 744: static const char * 745: parse_signed_bitbase8 (CGEN_CPU_DESC cd, const char **strp, 746: int opindex, signed long *valuep) 747: { 748: return parse_signed_bitbase (cd, strp, opindex, valuep, 8, 1); 749: } 750: 751: static const char * 752: parse_signed_bitbase11 (CGEN_CPU_DESC cd, const char **strp, 753: int opindex, signed long *valuep) 754: { 755: return parse_signed_bitbase (cd, strp, opindex, valuep, 11, 0); 756: } 757: 758: static const char * 759: parse_signed_bitbase19 (CGEN_CPU_DESC cd, const char **strp, 760: int opindex, signed long *valuep) 761: { 762: return parse_signed_bitbase (cd, strp, opindex, valuep, 19, 1); 763: } 764: 765: /* Parse the suffix as :<char> or as nothing followed by a whitespace. */ 766: 767: static const char * 768: parse_suffix (const char **strp, char suffix) 769: { 770: const char *newp = *strp; 771: 772: if (**strp == ':' && TOLOWER (*(*strp + 1)) == suffix) 773: newp = *strp + 2; 774: 775: if (ISSPACE (*newp)) 776: { 777: *strp = newp; 778: return 0; 779: } 780: 781: return "Invalid suffix"; /* Anything -- will not be seen. */ 782: } 783: 784: static const char * 785: parse_S (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp, 786: int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED) 787: { 788: return parse_suffix (strp, 's'); 789: } 790: 791: static const char * 792: parse_G (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp, 793: int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED) 794: { 795: return parse_suffix (strp, 'g'); 796: } 797: 798: static const char * 799: parse_Q (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp, 800: int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED) 801: { 802: return parse_suffix (strp, 'q'); 803: } 804: 805: static const char * 806: parse_Z (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp, 807: int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED) 808: { 809: return parse_suffix (strp, 'z'); 810: } 811: 812: /* Parse an empty suffix. Fail if the next char is ':'. */ 813: 814: static const char * 815: parse_X (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, const char **strp, 816: int opindex ATTRIBUTE_UNUSED, signed long *valuep ATTRIBUTE_UNUSED) 817: { 818: if (**strp == ':') 819: return "Unexpected suffix"; 820: