(linenum→info "unix/slp.c:2238")

binutils/2.18/cpu/m32c.opc

    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: