[BACK]Return to mep-asm.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils / dist / opcodes

Annotation of src/external/gpl3/binutils/dist/opcodes/mep-asm.c, Revision 1.1.1.4.12.2

1.1.1.4.12.1  pgoyette    1: /* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
1.1       skrll       2: /* Assembler interface for targets using CGEN. -*- C -*-
                      3:    CGEN: Cpu tools GENerator
                      4:
                      5:    THIS FILE IS MACHINE GENERATED WITH CGEN.
                      6:    - the resultant file is machine generated, cgen-asm.in isn't
                      7:
1.1.1.4.12.1  pgoyette    8:    Copyright (C) 1996-2018 Free Software Foundation, Inc.
1.1       skrll       9:
                     10:    This file is part of libopcodes.
                     11:
                     12:    This library is free software; you can redistribute it and/or modify
                     13:    it under the terms of the GNU General Public License as published by
                     14:    the Free Software Foundation; either version 3, or (at your option)
                     15:    any later version.
                     16:
                     17:    It is distributed in the hope that it will be useful, but WITHOUT
                     18:    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     19:    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
                     20:    License for more details.
                     21:
                     22:    You should have received a copy of the GNU General Public License
                     23:    along with this program; if not, write to the Free Software Foundation, Inc.,
                     24:    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
                     25:
                     26:
                     27: /* ??? Eventually more and more of this stuff can go to cpu-independent files.
                     28:    Keep that in mind.  */
                     29:
                     30: #include "sysdep.h"
                     31: #include <stdio.h>
                     32: #include "ansidecl.h"
                     33: #include "bfd.h"
                     34: #include "symcat.h"
                     35: #include "mep-desc.h"
                     36: #include "mep-opc.h"
                     37: #include "opintl.h"
                     38: #include "xregex.h"
                     39: #include "libiberty.h"
                     40: #include "safe-ctype.h"
                     41:
                     42: #undef  min
                     43: #define min(a,b) ((a) < (b) ? (a) : (b))
                     44: #undef  max
                     45: #define max(a,b) ((a) > (b) ? (a) : (b))
                     46:
                     47: static const char * parse_insn_normal
                     48:   (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
                     49: 
                     50: /* -- assembler routines inserted here.  */
                     51:
                     52: /* -- asm.c */
                     53:
1.1.1.2   christos   54: #include "elf/mep.h"
                     55:
1.1       skrll      56: #define CGEN_VALIDATE_INSN_SUPPORTED
1.1.1.2   christos   57: #define mep_cgen_insn_supported mep_cgen_insn_supported_asm
1.1       skrll      58:
                     59:        const char * parse_csrn       (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
                     60:        const char * parse_tpreg      (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
                     61:        const char * parse_spreg      (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
                     62:        const char * parse_mep_align  (CGEN_CPU_DESC, const char **, enum cgen_operand_type, long *);
                     63:        const char * parse_mep_alignu (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
                     64: static const char * parse_signed16   (CGEN_CPU_DESC, const char **, int, long *);
1.1.1.2   christos   65: static const char * parse_signed16_range   (CGEN_CPU_DESC, const char **, int, long *) ATTRIBUTE_UNUSED;
1.1       skrll      66: static const char * parse_unsigned16 (CGEN_CPU_DESC, const char **, int, unsigned long *);
1.1.1.2   christos   67: static const char * parse_unsigned16_range (CGEN_CPU_DESC, const char **, int, unsigned long *) ATTRIBUTE_UNUSED;
1.1       skrll      68: static const char * parse_lo16       (CGEN_CPU_DESC, const char **, int, long *, long);
                     69: static const char * parse_unsigned7  (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
                     70: static const char * parse_zero       (CGEN_CPU_DESC, const char **, int, long *);
                     71:
                     72: const char *
                     73: parse_csrn (CGEN_CPU_DESC cd, const char **strp,
                     74:            CGEN_KEYWORD *keyword_table, long *field)
                     75: {
                     76:   const char *err;
                     77:   unsigned long value;
                     78:
                     79:   err = cgen_parse_keyword (cd, strp, keyword_table, field);
                     80:   if (!err)
                     81:     return NULL;
                     82:
                     83:   err = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, & value);
                     84:   if (err)
                     85:     return err;
                     86:   *field = value;
                     87:   return NULL;
                     88: }
                     89:
                     90: /* begin-cop-ip-parse-handlers */
                     91: static const char *
1.1.1.2   christos   92: parse_ivc2_cr (CGEN_CPU_DESC,
                     93:        const char **,
                     94:        CGEN_KEYWORD *,
                     95:        long *) ATTRIBUTE_UNUSED;
                     96: static const char *
                     97: parse_ivc2_cr (CGEN_CPU_DESC cd,
1.1       skrll      98:        const char **strp,
                     99:        CGEN_KEYWORD *keyword_table  ATTRIBUTE_UNUSED,
                    100:        long *field)
                    101: {
1.1.1.2   christos  102:   return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr_ivc2, field);
1.1       skrll     103: }
                    104: static const char *
1.1.1.2   christos  105: parse_ivc2_ccr (CGEN_CPU_DESC,
                    106:        const char **,
                    107:        CGEN_KEYWORD *,
                    108:        long *) ATTRIBUTE_UNUSED;
                    109: static const char *
                    110: parse_ivc2_ccr (CGEN_CPU_DESC cd,
1.1       skrll     111:        const char **strp,
                    112:        CGEN_KEYWORD *keyword_table  ATTRIBUTE_UNUSED,
                    113:        long *field)
                    114: {
1.1.1.2   christos  115:   return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, field);
1.1       skrll     116: }
                    117: /* end-cop-ip-parse-handlers */
                    118:
                    119: const char *
                    120: parse_tpreg (CGEN_CPU_DESC cd, const char ** strp,
                    121:             CGEN_KEYWORD *keyword_table, long *field)
                    122: {
                    123:   const char *err;
                    124:
                    125:   err = cgen_parse_keyword (cd, strp, keyword_table, field);
                    126:   if (err)
                    127:     return err;
                    128:   if (*field != 13)
                    129:     return _("Only $tp or $13 allowed for this opcode");
                    130:   return NULL;
                    131: }
                    132:
                    133: const char *
                    134: parse_spreg (CGEN_CPU_DESC cd, const char ** strp,
                    135:             CGEN_KEYWORD *keyword_table, long *field)
                    136: {
                    137:   const char *err;
                    138:
                    139:   err = cgen_parse_keyword (cd, strp, keyword_table, field);
                    140:   if (err)
                    141:     return err;
                    142:   if (*field != 15)
                    143:     return _("Only $sp or $15 allowed for this opcode");
                    144:   return NULL;
                    145: }
                    146:
                    147: const char *
                    148: parse_mep_align (CGEN_CPU_DESC cd, const char ** strp,
                    149:                 enum cgen_operand_type type, long *field)
                    150: {
                    151:   long lsbs = 0;
                    152:   const char *err;
                    153:
                    154:   switch (type)
                    155:     {
                    156:     case MEP_OPERAND_PCREL8A2:
                    157:     case MEP_OPERAND_PCREL12A2:
                    158:     case MEP_OPERAND_PCREL17A2:
                    159:     case MEP_OPERAND_PCREL24A2:
                    160:       err = cgen_parse_signed_integer   (cd, strp, type, field);
                    161:       break;
                    162:     case MEP_OPERAND_PCABS24A2:
                    163:     case MEP_OPERAND_UDISP7:
                    164:     case MEP_OPERAND_UDISP7A2:
                    165:     case MEP_OPERAND_UDISP7A4:
                    166:     case MEP_OPERAND_UIMM7A4:
                    167:     case MEP_OPERAND_ADDR24A4:
                    168:       err = cgen_parse_unsigned_integer (cd, strp, type, (unsigned long *) field);
                    169:       break;
                    170:     default:
                    171:       abort();
                    172:     }
                    173:   if (err)
                    174:     return err;
                    175:   switch (type)
                    176:     {
                    177:     case MEP_OPERAND_UDISP7:
                    178:       lsbs = 0;
                    179:       break;
                    180:     case MEP_OPERAND_PCREL8A2:
                    181:     case MEP_OPERAND_PCREL12A2:
                    182:     case MEP_OPERAND_PCREL17A2:
                    183:     case MEP_OPERAND_PCREL24A2:
                    184:     case MEP_OPERAND_PCABS24A2:
                    185:     case MEP_OPERAND_UDISP7A2:
                    186:       lsbs = *field & 1;
                    187:       break;
                    188:     case MEP_OPERAND_UDISP7A4:
                    189:     case MEP_OPERAND_UIMM7A4:
                    190:     case MEP_OPERAND_ADDR24A4:
                    191:       lsbs = *field & 3;
                    192:       break;
                    193:       lsbs = *field & 7;
                    194:       break;
                    195:     default:
                    196:       /* Safe assumption?  */
                    197:       abort ();
                    198:     }
                    199:   if (lsbs)
                    200:     return "Value is not aligned enough";
                    201:   return NULL;
                    202: }
                    203:
                    204: const char *
                    205: parse_mep_alignu (CGEN_CPU_DESC cd, const char ** strp,
                    206:                 enum cgen_operand_type type, unsigned long *field)
                    207: {
                    208:   return parse_mep_align (cd, strp, type, (long *) field);
                    209: }
                    210:
                    211:
                    212: /* Handle %lo(), %tpoff(), %sdaoff(), %hi(), and other signed
                    213:    constants in a signed context.  */
                    214:
                    215: static const char *
                    216: parse_signed16 (CGEN_CPU_DESC cd,
                    217:                const char **strp,
                    218:                int opindex,
                    219:                long *valuep)
                    220: {
                    221:   return parse_lo16 (cd, strp, opindex, valuep, 1);
                    222: }
                    223:
                    224: static const char *
                    225: parse_lo16 (CGEN_CPU_DESC cd,
                    226:            const char **strp,
                    227:            int opindex,
                    228:            long *valuep,
                    229:            long signedp)
                    230: {
                    231:   const char *errmsg;
                    232:   enum cgen_parse_operand_result result_type;
                    233:   bfd_vma value;
                    234:
                    235:   if (strncasecmp (*strp, "%lo(", 4) == 0)
                    236:     {
                    237:       *strp += 4;
                    238:       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
                    239:                                   & result_type, & value);
                    240:       if (**strp != ')')
                    241:        return _("missing `)'");
                    242:       ++*strp;
                    243:       if (errmsg == NULL
                    244:          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
                    245:        value &= 0xffff;
                    246:       if (signedp)
                    247:        *valuep = (long)(short) value;
                    248:       else
                    249:        *valuep = value;
                    250:       return errmsg;
                    251:     }
                    252:
                    253:   if (strncasecmp (*strp, "%hi(", 4) == 0)
                    254:     {
                    255:       *strp += 4;
                    256:       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
                    257:                                   & result_type, & value);
                    258:       if (**strp != ')')
                    259:        return _("missing `)'");
                    260:       ++*strp;
                    261:       if (errmsg == NULL
                    262:          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
                    263:        value = (value + 0x8000) >> 16;
                    264:       *valuep = value;
                    265:       return errmsg;
                    266:     }
                    267:
                    268:   if (strncasecmp (*strp, "%uhi(", 5) == 0)
                    269:     {
                    270:       *strp += 5;
                    271:       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
                    272:                                   & result_type, & value);
                    273:       if (**strp != ')')
                    274:        return _("missing `)'");
                    275:       ++*strp;
                    276:       if (errmsg == NULL
                    277:          && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
                    278:        value = value >> 16;
                    279:       *valuep = value;
                    280:       return errmsg;
                    281:     }
                    282:
                    283:   if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
                    284:     {
                    285:       *strp += 8;
                    286:       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
                    287:                                   NULL, & value);
                    288:       if (**strp != ')')
                    289:        return _("missing `)'");
                    290:       ++*strp;
                    291:       *valuep = value;
                    292:       return errmsg;
                    293:     }
                    294:
                    295:   if (strncasecmp (*strp, "%tpoff(", 7) == 0)
                    296:     {
                    297:       *strp += 7;
                    298:       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
                    299:                                   NULL, & value);
                    300:       if (**strp != ')')
                    301:        return _("missing `)'");
                    302:       ++*strp;
                    303:       *valuep = value;
                    304:       return errmsg;
                    305:     }
                    306:
                    307:   if (**strp == '%')
                    308:     return _("invalid %function() here");
                    309:
                    310:   return cgen_parse_signed_integer (cd, strp, opindex, valuep);
                    311: }
                    312:
                    313: static const char *
                    314: parse_unsigned16 (CGEN_CPU_DESC cd,
                    315:                  const char **strp,
                    316:                  int opindex,
                    317:                  unsigned long *valuep)
                    318: {
                    319:   return parse_lo16 (cd, strp, opindex, (long *) valuep, 0);
                    320: }
                    321:
1.1.1.2   christos  322: static const char *
                    323: parse_signed16_range (CGEN_CPU_DESC cd,
                    324:                      const char **strp,
                    325:                      int opindex,
                    326:                      signed long *valuep)
                    327: {
                    328:   const char *errmsg = 0;
                    329:   signed long value;
                    330:
                    331:   errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
                    332:   if (errmsg)
                    333:     return errmsg;
                    334:
                    335:   if (value < -32768 || value > 32767)
                    336:     return _("Immediate is out of range -32768 to 32767");
                    337:
                    338:   *valuep = value;
                    339:   return 0;
                    340: }
                    341:
                    342: static const char *
                    343: parse_unsigned16_range (CGEN_CPU_DESC cd,
                    344:                        const char **strp,
                    345:                        int opindex,
                    346:                        unsigned long *valuep)
                    347: {
                    348:   const char *errmsg = 0;
                    349:   unsigned long value;
                    350:
                    351:   errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
                    352:   if (errmsg)
                    353:     return errmsg;
                    354:
                    355:   if (value > 65535)
                    356:     return _("Immediate is out of range 0 to 65535");
                    357:
                    358:   *valuep = value;
                    359:   return 0;
                    360: }
                    361:
1.1       skrll     362: /* A special case of parse_signed16 which accepts only the value zero.  */
                    363:
                    364: static const char *
                    365: parse_zero (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
                    366: {
                    367:   const char *errmsg;
                    368:   enum cgen_parse_operand_result result_type;
                    369:   bfd_vma value;
                    370:
                    371:   /*fprintf(stderr, "dj: signed parse opindex `%s'\n", *strp);*/
                    372:
                    373:   /* Prevent ($ry) from being attempted as an expression on 'sw $rx,($ry)'.
                    374:      It will fail and cause ry to be listed as an undefined symbol in the
                    375:      listing.  */
                    376:   if (strncmp (*strp, "($", 2) == 0)
                    377:     return "not zero"; /* any string will do -- will never be seen.  */
                    378:
                    379:   if (strncasecmp (*strp, "%lo(", 4) == 0)
                    380:     {
                    381:       *strp += 4;
                    382:       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
                    383:                                   &result_type, &value);
                    384:       if (**strp != ')')
                    385:        return "missing `)'";
                    386:       ++*strp;
                    387:       if (errmsg == NULL
                    388:          && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
                    389:        return "not zero"; /* any string will do -- will never be seen.  */
                    390:       *valuep = value;
                    391:       return errmsg;
                    392:     }
                    393:
                    394:   if (strncasecmp (*strp, "%hi(", 4) == 0)
                    395:     {
                    396:       *strp += 4;
                    397:       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
                    398:                                   &result_type, &value);
                    399:       if (**strp != ')')
                    400:        return "missing `)'";
                    401:       ++*strp;
                    402:       if (errmsg == NULL
                    403:          && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
                    404:        return "not zero"; /* any string will do -- will never be seen.  */
                    405:       *valuep = value;
                    406:       return errmsg;
                    407:     }
                    408:
                    409:   if (strncasecmp (*strp, "%uhi(", 5) == 0)
                    410:     {
                    411:       *strp += 5;
                    412:       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
                    413:                                   &result_type, &value);
                    414:       if (**strp != ')')
                    415:        return "missing `)'";
                    416:       ++*strp;
                    417:       if (errmsg == NULL
                    418:          && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
                    419:        return "not zero"; /* any string will do -- will never be seen.  */
                    420:       *valuep = value;
                    421:       return errmsg;
                    422:     }
                    423:
                    424:   if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
                    425:     {
                    426:       *strp += 8;
                    427:       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
                    428:                                   &result_type, &value);
                    429:       if (**strp != ')')
                    430:        return "missing `)'";
                    431:       ++*strp;
                    432:       if (errmsg == NULL
                    433:          && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
                    434:        return "not zero"; /* any string will do -- will never be seen.  */
                    435:       *valuep = value;
                    436:       return errmsg;
                    437:     }
                    438:
                    439:   if (strncasecmp (*strp, "%tpoff(", 7) == 0)
                    440:     {
                    441:       *strp += 7;
                    442:       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
                    443:                                   &result_type, &value);
                    444:       if (**strp != ')')
                    445:        return "missing `)'";
                    446:       ++*strp;
                    447:       if (errmsg == NULL
                    448:          && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
                    449:        return "not zero"; /* any string will do -- will never be seen.  */
                    450:       *valuep = value;
                    451:       return errmsg;
                    452:     }
                    453:
                    454:   if (**strp == '%')
                    455:     return "invalid %function() here";
                    456:
                    457:   errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_NONE,
                    458:                               &result_type, &value);
                    459:   if (errmsg == NULL
                    460:       && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
                    461:     return "not zero"; /* any string will do -- will never be seen.  */
                    462:
                    463:   return errmsg;
                    464: }
                    465:
                    466: static const char *
                    467: parse_unsigned7 (CGEN_CPU_DESC cd, const char **strp,
                    468:                 enum cgen_operand_type opindex, unsigned long *valuep)
                    469: {
                    470:   const char *errmsg;
                    471:   bfd_vma value;
                    472:
                    473:   /* fprintf(stderr, "dj: unsigned7 parse `%s'\n", *strp); */
                    474:
                    475:   if (strncasecmp (*strp, "%tpoff(", 7) == 0)
                    476:     {
                    477:       int reloc;
                    478:       *strp += 7;
                    479:       switch (opindex)
                    480:        {
                    481:        case MEP_OPERAND_UDISP7:
                    482:          reloc = BFD_RELOC_MEP_TPREL7;
                    483:          break;
                    484:        case MEP_OPERAND_UDISP7A2:
                    485:          reloc = BFD_RELOC_MEP_TPREL7A2;
                    486:          break;
                    487:        case MEP_OPERAND_UDISP7A4:
                    488:          reloc = BFD_RELOC_MEP_TPREL7A4;
                    489:          break;
                    490:        default:
                    491:          /* Safe assumption?  */
1.1.1.3   christos  492:          abort ();
1.1       skrll     493:        }
                    494:       errmsg = cgen_parse_address (cd, strp, opindex, reloc,
                    495:                                   NULL, &value);
                    496:       if (**strp != ')')
                    497:        return "missing `)'";
                    498:       ++*strp;
                    499:       *valuep = value;
                    500:       return errmsg;
                    501:     }
                    502:
                    503:   if (**strp == '%')
                    504:     return _("invalid %function() here");
                    505:
                    506:   return parse_mep_alignu (cd, strp, opindex, valuep);
                    507: }
                    508:
1.1.1.2   christos  509: static ATTRIBUTE_UNUSED const char *
                    510: parse_cdisp10 (CGEN_CPU_DESC cd,
                    511:               const char **strp,
                    512:               int opindex,
                    513:               long *valuep)
                    514: {
                    515:   const char *errmsg = 0;
                    516:   signed long value;
                    517:   long have_zero = 0;
                    518:   int wide = 0;
                    519:   int alignment;
                    520:
                    521:   switch (opindex)
                    522:     {
                    523:     case MEP_OPERAND_CDISP10A4:
                    524:       alignment = 2;
                    525:       break;
                    526:     case MEP_OPERAND_CDISP10A2:
                    527:       alignment = 1;
                    528:       break;
                    529:     case MEP_OPERAND_CDISP10:
                    530:     default:
                    531:       alignment = 0;
                    532:       break;
                    533:     }
                    534:
                    535:   if ((MEP_CPU & EF_MEP_CPU_MASK) == EF_MEP_CPU_C5)
                    536:     wide = 1;
                    537:
1.1.1.3   christos  538:   if (strncmp (*strp, "0x0", 3) == 0
1.1.1.2   christos  539:       || (**strp == '0' && *(*strp + 1) != 'x'))
                    540:     have_zero = 1;
                    541:
                    542:   errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
                    543:   if (errmsg)
                    544:     return errmsg;
                    545:
                    546:   if (wide)
                    547:     {
                    548:       if (value < -512 || value > 511)
                    549:        return _("Immediate is out of range -512 to 511");
                    550:     }
                    551:   else
                    552:     {
                    553:       if (value < -128 || value > 127)
                    554:        return _("Immediate is out of range -128 to 127");
                    555:     }
                    556:
                    557:   if (value & ((1<<alignment)-1))
                    558:     return _("Value is not aligned enough");
                    559:
                    560:   /* If this field may require a relocation then use larger dsp16.  */
                    561:   if (! have_zero && value == 0)
                    562:     return (wide ? _("Immediate is out of range -512 to 511")
                    563:            : _("Immediate is out of range -128 to 127"));
                    564:
                    565:   *valuep = value;
                    566:   return 0;
                    567: }
                    568:
1.1       skrll     569: /* BEGIN LIGHTWEIGHT MACRO PROCESSOR.  */
                    570:
                    571: #define MAXARGS 9
                    572:
                    573: typedef struct
                    574: {
                    575:   char *name;
                    576:   char *expansion;
                    577: }  macro;
                    578:
                    579: typedef struct
                    580: {
                    581:   const char *start;
                    582:   int len;
                    583: } arg;
                    584:
                    585: macro macros[] =
                    586: {
                    587:   { "sizeof", "(`1.end + (- `1))"},
                    588:   { "startof", "(`1 | 0)" },
                    589:   { "align4", "(`1&(~3))"},
                    590: /*{ "hi", "(((`1+0x8000)>>16) & 0xffff)" },  */
                    591: /*{ "lo", "(`1 & 0xffff)" },  */
                    592: /*{ "sdaoff", "((`1-__sdabase) & 0x7f)"},  */
                    593: /*{ "tpoff", "((`1-__tpbase) & 0x7f)"},  */
                    594:   { 0,0 }
                    595: };
                    596:
                    597: static char  * expand_string    (const char *, int);
                    598:
                    599: static const char *
                    600: mep_cgen_expand_macros_and_parse_operand
                    601:   (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
                    602:
                    603: static char *
                    604: str_append (char *dest, const char *input, int len)
1.1.1.3   christos  605: {
1.1       skrll     606:   char *new_dest;
                    607:   int oldlen;
                    608:
                    609:   if (len == 0)
                    610:     return dest;
                    611:   /* printf("str_append: <<%s>>, <<%s>>, %d\n", dest, input, len); */
                    612:   oldlen = (dest ? strlen(dest) : 0);
                    613:   new_dest = realloc (dest, oldlen + len + 1);
                    614:   memset (new_dest + oldlen, 0, len + 1);
                    615:   return strncat (new_dest, input, len);
                    616: }
                    617:
                    618: static macro *
                    619: lookup_macro (const char *name)
                    620: {
                    621:   macro *m;
                    622:
                    623:   for (m = macros; m->name; ++m)
                    624:     if (strncmp (m->name, name, strlen(m->name)) == 0)
                    625:       return m;
                    626:
                    627:   return 0;
                    628: }
                    629:
                    630: static char *
                    631: expand_macro (arg *args, int narg, macro *mac)
                    632: {
                    633:   char *result = 0, *rescanned_result = 0;
                    634:   char *e = mac->expansion;
                    635:   char *mark = e;
1.1.1.2   christos  636:   int mac_arg = 0;
1.1       skrll     637:
                    638:   /*  printf("expanding macro %s with %d args\n", mac->name, narg + 1); */
                    639:   while (*e)
                    640:     {
1.1.1.3   christos  641:       if (*e == '`' &&
                    642:          (*e+1) &&
1.1       skrll     643:          ((*(e + 1) - '1') <= MAXARGS) &&
                    644:          ((*(e + 1) - '1') <= narg))
                    645:        {
                    646:          result = str_append (result, mark, e - mark);
1.1.1.2   christos  647:          mac_arg = (*(e + 1) - '1');
                    648:          /* printf("replacing `%d with %s\n", mac_arg+1, args[mac_arg].start); */
                    649:          result = str_append (result, args[mac_arg].start, args[mac_arg].len);
1.1       skrll     650:          ++e;
                    651:          mark = e+1;
                    652:        }
                    653:       ++e;
                    654:     }
                    655:
                    656:   if (mark != e)
                    657:     result = str_append (result, mark, e - mark);
                    658:
                    659:   if (result)
                    660:     {
                    661:       rescanned_result = expand_string (result, 0);
                    662:       free (result);
                    663:       return rescanned_result;
                    664:     }
1.1.1.3   christos  665:   else
1.1       skrll     666:     return result;
                    667: }
                    668:
                    669: #define IN_TEXT 0
                    670: #define IN_ARGS 1
                    671:
                    672: static char *
                    673: expand_string (const char *in, int first_only)
                    674: {
                    675:   int num_expansions = 0;
                    676:   int depth = 0;
                    677:   int narg = -1;
                    678:   arg args[MAXARGS];
                    679:   int state = IN_TEXT;
                    680:   const char *mark = in;
1.1.1.2   christos  681:   macro *pmacro = NULL;
1.1       skrll     682:   char *expansion = 0;
                    683:   char *result = 0;
                    684:
                    685:   while (*in)
                    686:     {
                    687:       switch (state)
                    688:        {
                    689:        case IN_TEXT:
1.1.1.3   christos  690:          if (*in == '%' && *(in + 1) && (!first_only || num_expansions == 0))
                    691:            {
1.1.1.2   christos  692:              pmacro = lookup_macro (in + 1);
                    693:              if (pmacro)
1.1       skrll     694:                {
                    695:                  /* printf("entering state %d at '%s'...\n", state, in); */
                    696:                  result = str_append (result, mark, in - mark);
                    697:                  mark = in;
1.1.1.2   christos  698:                  in += 1 + strlen (pmacro->name);
1.1       skrll     699:                  while (*in == ' ') ++in;
                    700:                  if (*in != '(')
                    701:                    {
1.1.1.3   christos  702:                      state = IN_TEXT;
1.1.1.2   christos  703:                      pmacro = NULL;
1.1       skrll     704:                    }
                    705:                  else
                    706:                    {
                    707:                      state = IN_ARGS;
                    708:                      narg = 0;
                    709:                      args[narg].start = in + 1;
                    710:                      args[narg].len = 0;
1.1.1.3   christos  711:                      mark = in + 1;
1.1       skrll     712:                    }
                    713:                }
                    714:            }
                    715:          break;
                    716:        case IN_ARGS:
                    717:          if (depth == 0)
                    718:            {
                    719:              switch (*in)
                    720:                {
                    721:                case ',':
                    722:                  narg++;
                    723:                  args[narg].start = (in + 1);
                    724:                  args[narg].len = 0;
                    725:                  break;
                    726:                case ')':
                    727:                  state = IN_TEXT;
                    728:                  /* printf("entering state %d at '%s'...\n", state, in); */
1.1.1.2   christos  729:                  if (pmacro)
1.1       skrll     730:                    {
                    731:                      expansion = 0;
1.1.1.2   christos  732:                      expansion = expand_macro (args, narg, pmacro);
1.1       skrll     733:                      num_expansions++;
                    734:                      if (expansion)
                    735:                        {
                    736:                          result = str_append (result, expansion, strlen (expansion));
                    737:                          free (expansion);
                    738:                        }
                    739:                    }
                    740:                  else
                    741:                    {
                    742:                      result = str_append (result, mark, in - mark);
                    743:                    }
1.1.1.2   christos  744:                  pmacro = NULL;
1.1       skrll     745:                  mark = in + 1;
                    746:                  break;
                    747:                case '(':
                    748:                  depth++;
1.1.1.4.12.1  pgoyette  749:                  /* Fall through.  */
1.1       skrll     750:                default:
                    751:                  args[narg].len++;
1.1.1.3   christos  752:                  break;
1.1       skrll     753:                }
1.1.1.3   christos  754:            }
1.1       skrll     755:          else
                    756:            {
                    757:              if (*in == ')')
                    758:                depth--;
                    759:              if (narg > -1)
                    760:                args[narg].len++;
                    761:            }
1.1.1.3   christos  762:
1.1       skrll     763:        }
                    764:       ++in;
                    765:     }
1.1.1.3   christos  766:
1.1       skrll     767:   if (mark != in)
                    768:     result = str_append (result, mark, in - mark);
1.1.1.3   christos  769:
1.1       skrll     770:   return result;
                    771: }
                    772:
                    773: #undef IN_ARGS
                    774: #undef IN_TEXT
                    775: #undef MAXARGS
                    776:
                    777:
                    778: /* END LIGHTWEIGHT MACRO PROCESSOR.  */
                    779:
                    780: const char * mep_cgen_parse_operand
                    781:   (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
                    782:
                    783: const char *
                    784: mep_cgen_expand_macros_and_parse_operand (CGEN_CPU_DESC cd, int opindex,
                    785:                                          const char ** strp_in, CGEN_FIELDS * fields)
                    786: {
                    787:   const char * errmsg = NULL;
                    788:   char *str = 0, *hold = 0;
                    789:   const char **strp = 0;
                    790:
                    791:   /* Set up a new pointer to macro-expanded string.  */
                    792:   str = expand_string (*strp_in, 1);
                    793:   /* fprintf (stderr, " expanded <<%s>> to <<%s>>\n", *strp_in, str); */
                    794:
                    795:   hold = str;
                    796:   strp = (const char **)(&str);
                    797:
                    798:   errmsg = mep_cgen_parse_operand (cd, opindex, strp, fields);
                    799:
                    800:   /* Now work out the advance.  */
                    801:   if (strlen (str) == 0)
                    802:     *strp_in += strlen (*strp_in);
                    803:
                    804:   else
                    805:     {
                    806:       if (strstr (*strp_in, str))
                    807:        /* A macro-expansion was pulled off the front.  */
1.1.1.3   christos  808:        *strp_in = strstr (*strp_in, str);
1.1       skrll     809:       else
                    810:        /* A non-macro-expansion was pulled off the front.  */
1.1.1.3   christos  811:        *strp_in += (str - hold);
1.1       skrll     812:     }
                    813:
                    814:   if (hold)
                    815:     free (hold);
                    816:
                    817:   return errmsg;
                    818: }
                    819:
1.1.1.3   christos  820: #define CGEN_ASM_INIT_HOOK (cd->parse_operand = mep_cgen_expand_macros_and_parse_operand);
1.1       skrll     821:
                    822: /* -- dis.c */
                    823:
                    824: const char * mep_cgen_parse_operand
                    825:   (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
                    826:
                    827: /* Main entry point for operand parsing.
                    828:
                    829:    This function is basically just a big switch statement.  Earlier versions
                    830:    used tables to look up the function to use, but
                    831:    - if the table contains both assembler and disassembler functions then
                    832:      the disassembler contains much of the assembler and vice-versa,
                    833:    - there's a lot of inlining possibilities as things grow,
                    834:    - using a switch statement avoids the function call overhead.
                    835:
                    836:    This function could be moved into `parse_insn_normal', but keeping it
                    837:    separate makes clear the interface between `parse_insn_normal' and each of
                    838:    the handlers.  */
                    839:
                    840: const char *
                    841: mep_cgen_parse_operand (CGEN_CPU_DESC cd,
                    842:                           int opindex,
                    843:                           const char ** strp,
                    844:                           CGEN_FIELDS * fields)
                    845: {
                    846:   const char * errmsg = NULL;
                    847:   /* Used by scalar operands that still need to be parsed.  */
                    848:   long junk ATTRIBUTE_UNUSED;
                    849:
                    850:   switch (opindex)
                    851:     {
                    852:     case MEP_OPERAND_ADDR24A4 :
                    853:       errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_ADDR24A4, (unsigned long *) (& fields->f_24u8a4n));
                    854:       break;
1.1.1.2   christos  855:     case MEP_OPERAND_C5RMUIMM20 :
                    856:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_C5RMUIMM20, (unsigned long *) (& fields->f_c5_rmuimm20));
                    857:       break;
                    858:     case MEP_OPERAND_C5RNMUIMM24 :
                    859:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_C5RNMUIMM24, (unsigned long *) (& fields->f_c5_rnmuimm24));
                    860:       break;
1.1       skrll     861:     case MEP_OPERAND_CALLNUM :
                    862:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CALLNUM, (unsigned long *) (& fields->f_callnum));
                    863:       break;
                    864:     case MEP_OPERAND_CCCC :
                    865:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CCCC, (unsigned long *) (& fields->f_rm));
                    866:       break;
                    867:     case MEP_OPERAND_CCRN :
                    868:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & fields->f_ccrn);
                    869:       break;
1.1.1.2   christos  870:     case MEP_OPERAND_CDISP10 :
                    871:       errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10, (long *) (& fields->f_cdisp10));
1.1       skrll     872:       break;
1.1.1.2   christos  873:     case MEP_OPERAND_CDISP10A2 :
                    874:       errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A2, (long *) (& fields->f_cdisp10));
1.1       skrll     875:       break;
1.1.1.2   christos  876:     case MEP_OPERAND_CDISP10A4 :
                    877:       errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A4, (long *) (& fields->f_cdisp10));
1.1       skrll     878:       break;
1.1.1.2   christos  879:     case MEP_OPERAND_CDISP10A8 :
                    880:       errmsg = parse_cdisp10 (cd, strp, MEP_OPERAND_CDISP10A8, (long *) (& fields->f_cdisp10));
                    881:       break;
                    882:     case MEP_OPERAND_CDISP12 :
                    883:       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_CDISP12, (long *) (& fields->f_12s20));
1.1       skrll     884:       break;
                    885:     case MEP_OPERAND_CIMM4 :
                    886:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM4, (unsigned long *) (& fields->f_rn));
                    887:       break;
                    888:     case MEP_OPERAND_CIMM5 :
                    889:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM5, (unsigned long *) (& fields->f_5u24));
                    890:       break;
                    891:     case MEP_OPERAND_CODE16 :
                    892:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE16, (unsigned long *) (& fields->f_16u16));
                    893:       break;
                    894:     case MEP_OPERAND_CODE24 :
                    895:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE24, (unsigned long *) (& fields->f_24u4n));
                    896:       break;
                    897:     case MEP_OPERAND_CP_FLAG :
                    898:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & junk);
                    899:       break;
                    900:     case MEP_OPERAND_CRN :
                    901:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crn);
                    902:       break;
                    903:     case MEP_OPERAND_CRN64 :
                    904:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crn);
                    905:       break;
                    906:     case MEP_OPERAND_CRNX :
                    907:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crnx);
                    908:       break;
                    909:     case MEP_OPERAND_CRNX64 :
                    910:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crnx);
                    911:       break;
1.1.1.2   christos  912:     case MEP_OPERAND_CROC :
                    913:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u7);
                    914:       break;
                    915:     case MEP_OPERAND_CROP :
                    916:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u23);
                    917:       break;
                    918:     case MEP_OPERAND_CRPC :
                    919:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u26);
                    920:       break;
                    921:     case MEP_OPERAND_CRPP :
                    922:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u18);
                    923:       break;
                    924:     case MEP_OPERAND_CRQC :
                    925:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u21);
                    926:       break;
                    927:     case MEP_OPERAND_CRQP :
                    928:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_5u13);
                    929:       break;
1.1       skrll     930:     case MEP_OPERAND_CSRN :
                    931:       errmsg = parse_csrn (cd, strp, & mep_cgen_opval_h_csr, & fields->f_csrn);
                    932:       break;
                    933:     case MEP_OPERAND_CSRN_IDX :
                    934:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, (unsigned long *) (& fields->f_csrn));
                    935:       break;
                    936:     case MEP_OPERAND_DBG :
                    937:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
                    938:       break;
                    939:     case MEP_OPERAND_DEPC :
                    940:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
                    941:       break;
                    942:     case MEP_OPERAND_EPC :
                    943:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
                    944:       break;
                    945:     case MEP_OPERAND_EXC :
                    946:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
                    947:       break;
1.1.1.2   christos  948:     case MEP_OPERAND_HI :
                    949:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
1.1       skrll     950:       break;
1.1.1.2   christos  951:     case MEP_OPERAND_IMM16P0 :
                    952:       errmsg = parse_unsigned16_range (cd, strp, MEP_OPERAND_IMM16P0, (unsigned long *) (& fields->f_ivc2_imm16p0));
1.1       skrll     953:       break;
1.1.1.2   christos  954:     case MEP_OPERAND_IMM3P12 :
                    955:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P12, (unsigned long *) (& fields->f_ivc2_3u12));
1.1       skrll     956:       break;
1.1.1.2   christos  957:     case MEP_OPERAND_IMM3P25 :
                    958:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P25, (unsigned long *) (& fields->f_ivc2_3u25));
1.1       skrll     959:       break;
1.1.1.2   christos  960:     case MEP_OPERAND_IMM3P4 :
                    961:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P4, (unsigned long *) (& fields->f_ivc2_3u4));
1.1       skrll     962:       break;
1.1.1.2   christos  963:     case MEP_OPERAND_IMM3P5 :
                    964:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P5, (unsigned long *) (& fields->f_ivc2_3u5));
1.1       skrll     965:       break;
1.1.1.2   christos  966:     case MEP_OPERAND_IMM3P9 :
                    967:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM3P9, (unsigned long *) (& fields->f_ivc2_3u9));
1.1       skrll     968:       break;
1.1.1.2   christos  969:     case MEP_OPERAND_IMM4P10 :
                    970:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM4P10, (unsigned long *) (& fields->f_ivc2_4u10));
                    971:       break;
                    972:     case MEP_OPERAND_IMM4P4 :
                    973:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM4P4, (unsigned long *) (& fields->f_ivc2_4u4));
                    974:       break;
                    975:     case MEP_OPERAND_IMM4P8 :
                    976:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM4P8, (unsigned long *) (& fields->f_ivc2_4u8));
                    977:       break;
                    978:     case MEP_OPERAND_IMM5P23 :
                    979:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P23, (unsigned long *) (& fields->f_ivc2_5u23));
                    980:       break;
                    981:     case MEP_OPERAND_IMM5P3 :
                    982:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P3, (unsigned long *) (& fields->f_ivc2_5u3));
                    983:       break;
                    984:     case MEP_OPERAND_IMM5P7 :
                    985:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P7, (unsigned long *) (& fields->f_ivc2_5u7));
                    986:       break;
                    987:     case MEP_OPERAND_IMM5P8 :
                    988:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM5P8, (unsigned long *) (& fields->f_ivc2_5u8));
                    989:       break;
                    990:     case MEP_OPERAND_IMM6P2 :
                    991:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM6P2, (unsigned long *) (& fields->f_ivc2_6u2));
                    992:       break;
                    993:     case MEP_OPERAND_IMM6P6 :
                    994:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM6P6, (unsigned long *) (& fields->f_ivc2_6u6));
                    995:       break;
                    996:     case MEP_OPERAND_IMM8P0 :
                    997:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM8P0, (unsigned long *) (& fields->f_ivc2_8u0));
                    998:       break;
                    999:     case MEP_OPERAND_IMM8P20 :
                   1000:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM8P20, (unsigned long *) (& fields->f_ivc2_8u20));
                   1001:       break;
                   1002:     case MEP_OPERAND_IMM8P4 :
                   1003:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IMM8P4, (unsigned long *) (& fields->f_ivc2_8u4));
                   1004:       break;
                   1005:     case MEP_OPERAND_IVC_X_0_2 :
                   1006:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_2, (unsigned long *) (& fields->f_ivc2_2u0));
                   1007:       break;
                   1008:     case MEP_OPERAND_IVC_X_0_3 :
                   1009:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_3, (unsigned long *) (& fields->f_ivc2_3u0));
                   1010:       break;
                   1011:     case MEP_OPERAND_IVC_X_0_4 :
                   1012:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_4, (unsigned long *) (& fields->f_ivc2_4u0));
                   1013:       break;
                   1014:     case MEP_OPERAND_IVC_X_0_5 :
                   1015:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_0_5, (unsigned long *) (& fields->f_ivc2_5u0));
                   1016:       break;
                   1017:     case MEP_OPERAND_IVC_X_6_1 :
                   1018:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_6_1, (unsigned long *) (& fields->f_ivc2_1u6));
                   1019:       break;
                   1020:     case MEP_OPERAND_IVC_X_6_2 :
                   1021:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_6_2, (unsigned long *) (& fields->f_ivc2_2u6));
                   1022:       break;
                   1023:     case MEP_OPERAND_IVC_X_6_3 :
                   1024:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_IVC_X_6_3, (unsigned long *) (& fields->f_ivc2_3u6));
                   1025:       break;
                   1026:     case MEP_OPERAND_IVC2_ACC0_0 :
                   1027:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1028:       break;
                   1029:     case MEP_OPERAND_IVC2_ACC0_1 :
                   1030:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1031:       break;
                   1032:     case MEP_OPERAND_IVC2_ACC0_2 :
                   1033:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1034:       break;
                   1035:     case MEP_OPERAND_IVC2_ACC0_3 :
                   1036:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1037:       break;
                   1038:     case MEP_OPERAND_IVC2_ACC0_4 :
                   1039:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1040:       break;
                   1041:     case MEP_OPERAND_IVC2_ACC0_5 :
                   1042:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1043:       break;
                   1044:     case MEP_OPERAND_IVC2_ACC0_6 :
                   1045:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1046:       break;
                   1047:     case MEP_OPERAND_IVC2_ACC0_7 :
                   1048:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1049:       break;
                   1050:     case MEP_OPERAND_IVC2_ACC1_0 :
                   1051:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1052:       break;
                   1053:     case MEP_OPERAND_IVC2_ACC1_1 :
                   1054:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1055:       break;
                   1056:     case MEP_OPERAND_IVC2_ACC1_2 :
                   1057:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1058:       break;
                   1059:     case MEP_OPERAND_IVC2_ACC1_3 :
                   1060:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1061:       break;
                   1062:     case MEP_OPERAND_IVC2_ACC1_4 :
                   1063:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1064:       break;
                   1065:     case MEP_OPERAND_IVC2_ACC1_5 :
                   1066:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1067:       break;
                   1068:     case MEP_OPERAND_IVC2_ACC1_6 :
                   1069:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1070:       break;
                   1071:     case MEP_OPERAND_IVC2_ACC1_7 :
                   1072:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1073:       break;
                   1074:     case MEP_OPERAND_IVC2_CC :
                   1075:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1076:       break;
                   1077:     case MEP_OPERAND_IVC2_COFA0 :
                   1078:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1079:       break;
                   1080:     case MEP_OPERAND_IVC2_COFA1 :
                   1081:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1082:       break;
                   1083:     case MEP_OPERAND_IVC2_COFR0 :
                   1084:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1085:       break;
                   1086:     case MEP_OPERAND_IVC2_COFR1 :
                   1087:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1088:       break;
                   1089:     case MEP_OPERAND_IVC2_CSAR0 :
                   1090:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1091:       break;
                   1092:     case MEP_OPERAND_IVC2_CSAR1 :
                   1093:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & junk);
                   1094:       break;
                   1095:     case MEP_OPERAND_IVC2C3CCRN :
                   1096:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & fields->f_ivc2_ccrn_c3);
                   1097:       break;
                   1098:     case MEP_OPERAND_IVC2CCRN :
                   1099:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, & fields->f_ivc2_ccrn);
                   1100:       break;
                   1101:     case MEP_OPERAND_IVC2CRN :
                   1102:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_ivc2_crnx);
                   1103:       break;
                   1104:     case MEP_OPERAND_IVC2RM :
                   1105:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_ivc2_crm);
1.1       skrll    1106:       break;
                   1107:     case MEP_OPERAND_LO :
                   1108:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
                   1109:       break;
                   1110:     case MEP_OPERAND_LP :
                   1111:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
                   1112:       break;
                   1113:     case MEP_OPERAND_MB0 :
                   1114:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
                   1115:       break;
                   1116:     case MEP_OPERAND_MB1 :
                   1117:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
                   1118:       break;
                   1119:     case MEP_OPERAND_ME0 :
                   1120:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
                   1121:       break;
                   1122:     case MEP_OPERAND_ME1 :
                   1123:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
                   1124:       break;
                   1125:     case MEP_OPERAND_NPC :
                   1126:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
                   1127:       break;
                   1128:     case MEP_OPERAND_OPT :
                   1129:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
                   1130:       break;
                   1131:     case MEP_OPERAND_PCABS24A2 :
                   1132:       errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_PCABS24A2, (unsigned long *) (& fields->f_24u5a2n));
                   1133:       break;
                   1134:     case MEP_OPERAND_PCREL12A2 :
                   1135:       errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL12A2, (long *) (& fields->f_12s4a2));
                   1136:       break;
                   1137:     case MEP_OPERAND_PCREL17A2 :
                   1138:       errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL17A2, (long *) (& fields->f_17s16a2));
                   1139:       break;
                   1140:     case MEP_OPERAND_PCREL24A2 :
                   1141:       errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL24A2, (long *) (& fields->f_24s5a2n));
                   1142:       break;
                   1143:     case MEP_OPERAND_PCREL8A2 :
                   1144:       errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL8A2, (long *) (& fields->f_8s8a2));
                   1145:       break;
                   1146:     case MEP_OPERAND_PSW :
                   1147:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
                   1148:       break;
                   1149:     case MEP_OPERAND_R0 :
                   1150:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
                   1151:       break;
                   1152:     case MEP_OPERAND_R1 :
                   1153:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
                   1154:       break;
                   1155:     case MEP_OPERAND_RL :
                   1156:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl);
                   1157:       break;
1.1.1.2   christos 1158:     case MEP_OPERAND_RL5 :
                   1159:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl5);
                   1160:       break;
1.1       skrll    1161:     case MEP_OPERAND_RM :
                   1162:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
                   1163:       break;
                   1164:     case MEP_OPERAND_RMA :
                   1165:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm);
                   1166:       break;
                   1167:     case MEP_OPERAND_RN :
                   1168:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
                   1169:       break;
                   1170:     case MEP_OPERAND_RN3 :
                   1171:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
                   1172:       break;
                   1173:     case MEP_OPERAND_RN3C :
                   1174:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
                   1175:       break;
                   1176:     case MEP_OPERAND_RN3L :
                   1177:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
                   1178:       break;
                   1179:     case MEP_OPERAND_RN3S :
                   1180:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
                   1181:       break;
                   1182:     case MEP_OPERAND_RN3UC :
                   1183:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
                   1184:       break;
                   1185:     case MEP_OPERAND_RN3UL :
                   1186:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
                   1187:       break;
                   1188:     case MEP_OPERAND_RN3US :
                   1189:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3);
                   1190:       break;
                   1191:     case MEP_OPERAND_RNC :
                   1192:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
                   1193:       break;
                   1194:     case MEP_OPERAND_RNL :
                   1195:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
                   1196:       break;
                   1197:     case MEP_OPERAND_RNS :
                   1198:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
                   1199:       break;
                   1200:     case MEP_OPERAND_RNUC :
                   1201:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
                   1202:       break;
                   1203:     case MEP_OPERAND_RNUL :
                   1204:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
                   1205:       break;
                   1206:     case MEP_OPERAND_RNUS :
                   1207:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn);
                   1208:       break;
                   1209:     case MEP_OPERAND_SAR :
                   1210:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk);
                   1211:       break;
                   1212:     case MEP_OPERAND_SDISP16 :
                   1213:       errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SDISP16, (long *) (& fields->f_16s16));
                   1214:       break;
                   1215:     case MEP_OPERAND_SIMM16 :
                   1216:       errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SIMM16, (long *) (& fields->f_16s16));
                   1217:       break;
1.1.1.2   christos 1218:     case MEP_OPERAND_SIMM16P0 :
                   1219:       errmsg = parse_signed16_range (cd, strp, MEP_OPERAND_SIMM16P0, (long *) (& fields->f_ivc2_simm16p0));
                   1220:       break;
1.1       skrll    1221:     case MEP_OPERAND_SIMM6 :
                   1222:       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM6, (long *) (& fields->f_6s8));
                   1223:       break;
                   1224:     case MEP_OPERAND_SIMM8 :
                   1225:       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8, (long *) (& fields->f_8s8));
                   1226:       break;
1.1.1.2   christos 1227:     case MEP_OPERAND_SIMM8P0 :
                   1228:       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8P0, (long *) (& fields->f_ivc2_8s0));
                   1229:       break;
                   1230:     case MEP_OPERAND_SIMM8P20 :
                   1231:       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8P20, (long *) (& fields->f_ivc2_8s20));
                   1232:       break;
                   1233:     case MEP_OPERAND_SIMM8P4 :
                   1234:       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8P4, (long *) (& fields->f_ivc2_8s4));
                   1235:       break;
1.1       skrll    1236:     case MEP_OPERAND_SP :
                   1237:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
                   1238:       break;
                   1239:     case MEP_OPERAND_SPR :
                   1240:       errmsg = parse_spreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
                   1241:       break;
                   1242:     case MEP_OPERAND_TP :
                   1243:       errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk);
                   1244:       break;
                   1245:     case MEP_OPERAND_TPR :
                   1246:       errmsg = parse_tpreg (cd, strp, & mep_cgen_opval_h_gpr, & junk);
                   1247:       break;
                   1248:     case MEP_OPERAND_UDISP2 :
                   1249:       errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_UDISP2, (long *) (& fields->f_2u6));
                   1250:       break;
                   1251:     case MEP_OPERAND_UDISP7 :
                   1252:       errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7, (unsigned long *) (& fields->f_7u9));
                   1253:       break;
                   1254:     case MEP_OPERAND_UDISP7A2 :
                   1255:       errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A2, (unsigned long *) (& fields->f_7u9a2));
                   1256:       break;
                   1257:     case MEP_OPERAND_UDISP7A4 :
                   1258:       errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A4, (unsigned long *) (& fields->f_7u9a4));
                   1259:       break;
                   1260:     case MEP_OPERAND_UIMM16 :
                   1261:       errmsg = parse_unsigned16 (cd, strp, MEP_OPERAND_UIMM16, (unsigned long *) (& fields->f_16u16));
                   1262:       break;
                   1263:     case MEP_OPERAND_UIMM2 :
                   1264:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM2, (unsigned long *) (& fields->f_2u10));
                   1265:       break;
                   1266:     case MEP_OPERAND_UIMM24 :
                   1267:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM24, (unsigned long *) (& fields->f_24u8n));
                   1268:       break;
                   1269:     case MEP_OPERAND_UIMM3 :
                   1270:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM3, (unsigned long *) (& fields->f_3u5));
                   1271:       break;
                   1272:     case MEP_OPERAND_UIMM4 :
                   1273:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM4, (unsigned long *) (& fields->f_4u8));
                   1274:       break;
                   1275:     case MEP_OPERAND_UIMM5 :
                   1276:       errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM5, (unsigned long *) (& fields->f_5u8));
                   1277:       break;
                   1278:     case MEP_OPERAND_UIMM7A4 :
                   1279:       errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_UIMM7A4, (unsigned long *) (& fields->f_7u9a4));
                   1280:       break;
                   1281:     case MEP_OPERAND_ZERO :
                   1282:       errmsg = parse_zero (cd, strp, MEP_OPERAND_ZERO, (long *) (& junk));
                   1283:       break;
                   1284:
                   1285:     default :
                   1286:       /* xgettext:c-format */
1.1.1.4.12.2! pgoyette 1287:       opcodes_error_handler
        !          1288:        (_("internal error: unrecognized field %d while parsing"),
        !          1289:         opindex);
1.1       skrll    1290:       abort ();
                   1291:   }
                   1292:
                   1293:   return errmsg;
                   1294: }
                   1295:
1.1.1.3   christos 1296: cgen_parse_fn * const mep_cgen_parse_handlers[] =
1.1       skrll    1297: {
                   1298:   parse_insn_normal,
                   1299: };
                   1300:
                   1301: void
                   1302: mep_cgen_init_asm (CGEN_CPU_DESC cd)
                   1303: {
                   1304:   mep_cgen_init_opcode_table (cd);
                   1305:   mep_cgen_init_ibld_table (cd);
                   1306:   cd->parse_handlers = & mep_cgen_parse_handlers[0];
                   1307:   cd->parse_operand = mep_cgen_parse_operand;
                   1308: #ifdef CGEN_ASM_INIT_HOOK
                   1309: CGEN_ASM_INIT_HOOK
                   1310: #endif
                   1311: }
                   1312:
                   1313: 
                   1314:
                   1315: /* Regex construction routine.
                   1316:
                   1317:    This translates an opcode syntax string into a regex string,
                   1318:    by replacing any non-character syntax element (such as an
                   1319:    opcode) with the pattern '.*'
                   1320:
                   1321:    It then compiles the regex and stores it in the opcode, for
                   1322:    later use by mep_cgen_assemble_insn
                   1323:
                   1324:    Returns NULL for success, an error message for failure.  */
                   1325:
1.1.1.3   christos 1326: char *
1.1       skrll    1327: mep_cgen_build_insn_regex (CGEN_INSN *insn)
1.1.1.3   christos 1328: {
1.1       skrll    1329:   CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
                   1330:   const char *mnem = CGEN_INSN_MNEMONIC (insn);
                   1331:   char rxbuf[CGEN_MAX_RX_ELEMENTS];
                   1332:   char *rx = rxbuf;
                   1333:   const CGEN_SYNTAX_CHAR_TYPE *syn;
                   1334:   int reg_err;
                   1335:
                   1336:   syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
                   1337:
                   1338:   /* Mnemonics come first in the syntax string.  */
                   1339:   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
                   1340:     return _("missing mnemonic in syntax string");
                   1341:   ++syn;
                   1342:
                   1343:   /* Generate a case sensitive regular expression that emulates case
                   1344:      insensitive matching in the "C" locale.  We cannot generate a case
                   1345:      insensitive regular expression because in Turkish locales, 'i' and 'I'
                   1346:      are not equal modulo case conversion.  */
                   1347:
                   1348:   /* Copy the literal mnemonic out of the insn.  */
                   1349:   for (; *mnem; mnem++)
                   1350:     {
                   1351:       char c = *mnem;
                   1352:
                   1353:       if (ISALPHA (c))
                   1354:        {
                   1355:          *rx++ = '[';
                   1356:          *rx++ = TOLOWER (c);
                   1357:          *rx++ = TOUPPER (c);
                   1358:          *rx++ = ']';
                   1359:        }
                   1360:       else
                   1361:        *rx++ = c;
                   1362:     }
                   1363:
                   1364:   /* Copy any remaining literals from the syntax string into the rx.  */
                   1365:   for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
                   1366:     {
1.1.1.3   christos 1367:       if (CGEN_SYNTAX_CHAR_P (* syn))
1.1       skrll    1368:        {
                   1369:          char c = CGEN_SYNTAX_CHAR (* syn);
                   1370:
1.1.1.3   christos 1371:          switch (c)
1.1       skrll    1372:            {
                   1373:              /* Escape any regex metacharacters in the syntax.  */
1.1.1.3   christos 1374:            case '.': case '[': case '\\':
                   1375:            case '*': case '^': case '$':
1.1       skrll    1376:
                   1377: #ifdef CGEN_ESCAPE_EXTENDED_REGEX
1.1.1.3   christos 1378:            case '?': case '{': case '}':
1.1       skrll    1379:            case '(': case ')': case '*':
                   1380:            case '|': case '+': case ']':
                   1381: #endif
                   1382:              *rx++ = '\\';
                   1383:              *rx++ = c;
                   1384:              break;
                   1385:
                   1386:            default:
                   1387:              if (ISALPHA (c))
                   1388:                {
                   1389:                  *rx++ = '[';
                   1390:                  *rx++ = TOLOWER (c);
                   1391:                  *rx++ = TOUPPER (c);
                   1392:                  *rx++ = ']';
                   1393:                }
                   1394:              else
                   1395:                *rx++ = c;
                   1396:              break;
                   1397:            }
                   1398:        }
                   1399:       else
                   1400:        {
                   1401:          /* Replace non-syntax fields with globs.  */
                   1402:          *rx++ = '.';
                   1403:          *rx++ = '*';
                   1404:        }
                   1405:     }
                   1406:
                   1407:   /* Trailing whitespace ok.  */
1.1.1.3   christos 1408:   * rx++ = '[';
                   1409:   * rx++ = ' ';
                   1410:   * rx++ = '\t';
                   1411:   * rx++ = ']';
                   1412:   * rx++ = '*';
1.1       skrll    1413:
                   1414:   /* But anchor it after that.  */
1.1.1.3   christos 1415:   * rx++ = '$';
1.1       skrll    1416:   * rx = '\0';
                   1417:
                   1418:   CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
                   1419:   reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
                   1420:
1.1.1.3   christos 1421:   if (reg_err == 0)
1.1       skrll    1422:     return NULL;
                   1423:   else
                   1424:     {
                   1425:       static char msg[80];
                   1426:
                   1427:       regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
                   1428:       regfree ((regex_t *) CGEN_INSN_RX (insn));
                   1429:       free (CGEN_INSN_RX (insn));
                   1430:       (CGEN_INSN_RX (insn)) = NULL;
                   1431:       return msg;
                   1432:     }
                   1433: }
                   1434:
                   1435: 
                   1436: /* Default insn parser.
                   1437:
                   1438:    The syntax string is scanned and operands are parsed and stored in FIELDS.
                   1439:    Relocs are queued as we go via other callbacks.
                   1440:
                   1441:    ??? Note that this is currently an all-or-nothing parser.  If we fail to
                   1442:    parse the instruction, we return 0 and the caller will start over from
                   1443:    the beginning.  Backtracking will be necessary in parsing subexpressions,
                   1444:    but that can be handled there.  Not handling backtracking here may get
                   1445:    expensive in the case of the m68k.  Deal with later.
                   1446:
                   1447:    Returns NULL for success, an error message for failure.  */
                   1448:
                   1449: static const char *
                   1450: parse_insn_normal (CGEN_CPU_DESC cd,
                   1451:                   const CGEN_INSN *insn,
                   1452:                   const char **strp,
                   1453:                   CGEN_FIELDS *fields)
                   1454: {
                   1455:   /* ??? Runtime added insns not handled yet.  */
                   1456:   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
                   1457:   const char *str = *strp;
                   1458:   const char *errmsg;
                   1459:   const char *p;
                   1460:   const CGEN_SYNTAX_CHAR_TYPE * syn;
                   1461: #ifdef CGEN_MNEMONIC_OPERANDS
                   1462:   /* FIXME: wip */
                   1463:   int past_opcode_p;
                   1464: #endif
                   1465:
                   1466:   /* For now we assume the mnemonic is first (there are no leading operands).
                   1467:      We can parse it without needing to set up operand parsing.
                   1468:      GAS's input scrubber will ensure mnemonics are lowercase, but we may
                   1469:      not be called from GAS.  */
                   1470:   p = CGEN_INSN_MNEMONIC (insn);
                   1471:   while (*p && TOLOWER (*p) == TOLOWER (*str))
                   1472:     ++p, ++str;
                   1473:
                   1474:   if (* p)
                   1475:     return _("unrecognized instruction");
                   1476:
                   1477: #ifndef CGEN_MNEMONIC_OPERANDS
                   1478:   if (* str && ! ISSPACE (* str))
                   1479:     return _("unrecognized instruction");
                   1480: #endif
                   1481:
                   1482:   CGEN_INIT_PARSE (cd);
                   1483:   cgen_init_parse_operand (cd);
                   1484: #ifdef CGEN_MNEMONIC_OPERANDS
                   1485:   past_opcode_p = 0;
                   1486: #endif
                   1487:
                   1488:   /* We don't check for (*str != '\0') here because we want to parse
                   1489:      any trailing fake arguments in the syntax string.  */
                   1490:   syn = CGEN_SYNTAX_STRING (syntax);
                   1491:
                   1492:   /* Mnemonics come first for now, ensure valid string.  */
                   1493:   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
                   1494:     abort ();
                   1495:
                   1496:   ++syn;
                   1497:
                   1498:   while (* syn != 0)
                   1499:     {
                   1500:       /* Non operand chars must match exactly.  */
                   1501:       if (CGEN_SYNTAX_CHAR_P (* syn))
                   1502:        {
                   1503:          /* FIXME: While we allow for non-GAS callers above, we assume the
                   1504:             first char after the mnemonic part is a space.  */
                   1505:          /* FIXME: We also take inappropriate advantage of the fact that
                   1506:             GAS's input scrubber will remove extraneous blanks.  */
                   1507:          if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
                   1508:            {
                   1509: #ifdef CGEN_MNEMONIC_OPERANDS
                   1510:              if (CGEN_SYNTAX_CHAR(* syn) == ' ')
                   1511:                past_opcode_p = 1;
                   1512: #endif
                   1513:              ++ syn;
                   1514:              ++ str;
                   1515:            }
                   1516:          else if (*str)
                   1517:            {
                   1518:              /* Syntax char didn't match.  Can't be this insn.  */
                   1519:              static char msg [80];
                   1520:
                   1521:              /* xgettext:c-format */
                   1522:              sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
                   1523:                       CGEN_SYNTAX_CHAR(*syn), *str);
                   1524:              return msg;
                   1525:            }
                   1526:          else
                   1527:            {
                   1528:              /* Ran out of input.  */
                   1529:              static char msg [80];
                   1530:
                   1531:              /* xgettext:c-format */
                   1532:              sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
                   1533:                       CGEN_SYNTAX_CHAR(*syn));
                   1534:              return msg;
                   1535:            }
                   1536:          continue;
                   1537:        }
                   1538:
1.1.1.2   christos 1539: #ifdef CGEN_MNEMONIC_OPERANDS
                   1540:       (void) past_opcode_p;
                   1541: #endif
1.1       skrll    1542:       /* We have an operand of some sort.  */
1.1.1.2   christos 1543:       errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
1.1       skrll    1544:       if (errmsg)
                   1545:        return errmsg;
                   1546:
                   1547:       /* Done with this operand, continue with next one.  */
                   1548:       ++ syn;
                   1549:     }
                   1550:
                   1551:   /* If we're at the end of the syntax string, we're done.  */
                   1552:   if (* syn == 0)
                   1553:     {
                   1554:       /* FIXME: For the moment we assume a valid `str' can only contain
                   1555:         blanks now.  IE: We needn't try again with a longer version of
                   1556:         the insn and it is assumed that longer versions of insns appear
                   1557:         before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
                   1558:       while (ISSPACE (* str))
                   1559:        ++ str;
                   1560:
                   1561:       if (* str != '\0')
                   1562:        return _("junk at end of line"); /* FIXME: would like to include `str' */
                   1563:
                   1564:       return NULL;
                   1565:     }
                   1566:
                   1567:   /* We couldn't parse it.  */
                   1568:   return _("unrecognized instruction");
                   1569: }
                   1570: 
                   1571: /* Main entry point.
                   1572:    This routine is called for each instruction to be assembled.
                   1573:    STR points to the insn to be assembled.
                   1574:    We assume all necessary tables have been initialized.
                   1575:    The assembled instruction, less any fixups, is stored in BUF.
                   1576:    Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
                   1577:    still needs to be converted to target byte order, otherwise BUF is an array
                   1578:    of bytes in target byte order.
                   1579:    The result is a pointer to the insn's entry in the opcode table,
                   1580:    or NULL if an error occured (an error message will have already been
                   1581:    printed).
                   1582:
                   1583:    Note that when processing (non-alias) macro-insns,
                   1584:    this function recurses.
                   1585:
                   1586:    ??? It's possible to make this cpu-independent.
                   1587:    One would have to deal with a few minor things.
                   1588:    At this point in time doing so would be more of a curiosity than useful
                   1589:    [for example this file isn't _that_ big], but keeping the possibility in
                   1590:    mind helps keep the design clean.  */
                   1591:
                   1592: const CGEN_INSN *
                   1593: mep_cgen_assemble_insn (CGEN_CPU_DESC cd,
                   1594:                           const char *str,
                   1595:                           CGEN_FIELDS *fields,
                   1596:                           CGEN_INSN_BYTES_PTR buf,
                   1597:                           char **errmsg)
                   1598: {
                   1599:   const char *start;
                   1600:   CGEN_INSN_LIST *ilist;
                   1601:   const char *parse_errmsg = NULL;
                   1602:   const char *insert_errmsg = NULL;
                   1603:   int recognized_mnemonic = 0;
                   1604:
                   1605:   /* Skip leading white space.  */
                   1606:   while (ISSPACE (* str))
                   1607:     ++ str;
                   1608:
                   1609:   /* The instructions are stored in hashed lists.
                   1610:      Get the first in the list.  */
                   1611:   ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
                   1612:
                   1613:   /* Keep looking until we find a match.  */
                   1614:   start = str;
                   1615:   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
                   1616:     {
                   1617:       const CGEN_INSN *insn = ilist->insn;
                   1618:       recognized_mnemonic = 1;
                   1619:
1.1.1.3   christos 1620: #ifdef CGEN_VALIDATE_INSN_SUPPORTED
1.1       skrll    1621:       /* Not usually needed as unsupported opcodes
                   1622:         shouldn't be in the hash lists.  */
                   1623:       /* Is this insn supported by the selected cpu?  */
                   1624:       if (! mep_cgen_insn_supported (cd, insn))
                   1625:        continue;
                   1626: #endif
                   1627:       /* If the RELAXED attribute is set, this is an insn that shouldn't be
                   1628:         chosen immediately.  Instead, it is used during assembler/linker
                   1629:         relaxation if possible.  */
                   1630:       if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
                   1631:        continue;
                   1632:
                   1633:       str = start;
                   1634:
                   1635:       /* Skip this insn if str doesn't look right lexically.  */
                   1636:       if (CGEN_INSN_RX (insn) != NULL &&
                   1637:          regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
                   1638:        continue;
                   1639:
                   1640:       /* Allow parse/insert handlers to obtain length of insn.  */
                   1641:       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
                   1642:
                   1643:       parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
                   1644:       if (parse_errmsg != NULL)
                   1645:        continue;
                   1646:
                   1647:       /* ??? 0 is passed for `pc'.  */
                   1648:       insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
                   1649:                                                 (bfd_vma) 0);
                   1650:       if (insert_errmsg != NULL)
                   1651:         continue;
                   1652:
                   1653:       /* It is up to the caller to actually output the insn and any
                   1654:          queued relocs.  */
                   1655:       return insn;
                   1656:     }
                   1657:
                   1658:   {
                   1659:     static char errbuf[150];
                   1660:     const char *tmp_errmsg;
1.1.1.2   christos 1661: #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
                   1662: #define be_verbose 1
1.1       skrll    1663: #else
1.1.1.2   christos 1664: #define be_verbose 0
1.1       skrll    1665: #endif
1.1.1.2   christos 1666:
                   1667:     if (be_verbose)
                   1668:       {
                   1669:        /* If requesting verbose error messages, use insert_errmsg.
                   1670:           Failing that, use parse_errmsg.  */
                   1671:        tmp_errmsg = (insert_errmsg ? insert_errmsg :
                   1672:                      parse_errmsg ? parse_errmsg :
                   1673:                      recognized_mnemonic ?
                   1674:                      _("unrecognized form of instruction") :
                   1675:                      _("unrecognized instruction"));
                   1676:
                   1677:        if (strlen (start) > 50)
                   1678:          /* xgettext:c-format */
                   1679:          sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
1.1.1.3   christos 1680:        else
1.1.1.2   christos 1681:          /* xgettext:c-format */
                   1682:          sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
                   1683:       }
                   1684:     else
                   1685:       {
                   1686:        if (strlen (start) > 50)
                   1687:          /* xgettext:c-format */
                   1688:          sprintf (errbuf, _("bad instruction `%.50s...'"), start);
1.1.1.3   christos 1689:        else
1.1.1.2   christos 1690:          /* xgettext:c-format */
                   1691:          sprintf (errbuf, _("bad instruction `%.50s'"), start);
                   1692:       }
1.1.1.3   christos 1693:
1.1       skrll    1694:     *errmsg = errbuf;
                   1695:     return NULL;
                   1696:   }
                   1697: }

CVSweb <webmaster@jp.NetBSD.org>