Home | History | Annotate | Line # | Download | only in opcodes
      1 /* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
      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 
      8    Copyright (C) 1996-2026 Free Software Foundation, Inc.
      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 "mt-desc.h"
     36 #include "mt-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.  */
     52 
     53 /* -- asm.c */
     54 /* Range checking for signed numbers.  Returns 0 if acceptable
     55    and 1 if the value is out of bounds for a signed quantity.  */
     56 
     57 static int
     58 signed_out_of_bounds (long val)
     59 {
     60   if ((val < -32768) || (val > 32767))
     61     return 1;
     62   return 0;
     63 }
     64 
     65 static const char *
     66 parse_loopsize (CGEN_CPU_DESC cd,
     67 		const char **strp,
     68 		int opindex,
     69 		void *arg)
     70 {
     71   signed long * valuep = (signed long *) arg;
     72   const char *errmsg;
     73   bfd_reloc_code_real_type code = BFD_RELOC_NONE;
     74   enum cgen_parse_operand_result result_type;
     75   bfd_vma value;
     76 
     77   /* Is it a control transfer instructions?  */
     78   if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_LOOPSIZE)
     79     {
     80       code = BFD_RELOC_MT_PCINSN8;
     81       errmsg = cgen_parse_address (cd, strp, opindex, code,
     82                                    & result_type, & value);
     83       *valuep = value;
     84       return errmsg;
     85     }
     86 
     87   abort ();
     88 }
     89 
     90 static const char *
     91 parse_imm16 (CGEN_CPU_DESC cd,
     92 	     const char **strp,
     93 	     int opindex,
     94 	     void *arg)
     95 {
     96   signed long * valuep = (signed long *) arg;
     97   const char *errmsg;
     98   enum cgen_parse_operand_result result_type;
     99   bfd_reloc_code_real_type code = BFD_RELOC_NONE;
    100   bfd_vma value;
    101 
    102   /* Is it a control transfer instructions?  */
    103   if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16O)
    104     {
    105       code = BFD_RELOC_16_PCREL;
    106       errmsg = cgen_parse_address (cd, strp, opindex, code,
    107                                    & result_type, & value);
    108       if (errmsg == NULL)
    109 	{
    110 	  if (signed_out_of_bounds (value))
    111 	    errmsg = _("Operand out of range. Must be between -32768 and 32767.");
    112 	}
    113       *valuep = value;
    114       return errmsg;
    115     }
    116 
    117   /* If it's not a control transfer instruction, then
    118      we have to check for %OP relocating operators.  */
    119   if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16L)
    120     ;
    121   else if (strncmp (*strp, "%hi16", 5) == 0)
    122     {
    123       *strp += 5;
    124       code = BFD_RELOC_HI16;
    125     }
    126   else if (strncmp (*strp, "%lo16", 5) == 0)
    127     {
    128       *strp += 5;
    129       code = BFD_RELOC_LO16;
    130     }
    131 
    132   /* If we found a %OP relocating operator, then parse it as an address.
    133      If not, we need to parse it as an integer, either signed or unsigned
    134      depending on which operand type we have.  */
    135   if (code != BFD_RELOC_NONE)
    136     {
    137        /* %OP relocating operator found.  */
    138        errmsg = cgen_parse_address (cd, strp, opindex, code,
    139                                    & result_type, & value);
    140        if (errmsg == NULL)
    141 	 {
    142            switch (result_type)
    143 	     {
    144 	     case (CGEN_PARSE_OPERAND_RESULT_NUMBER):
    145 	       if (code == BFD_RELOC_HI16)
    146 		 value = (value >> 16) & 0xFFFF;
    147 	       else if (code == BFD_RELOC_LO16)
    148 		 value = value  & 0xFFFF;
    149 	       else
    150 		 errmsg = _("Biiiig Trouble in parse_imm16!");
    151 	       break;
    152 
    153 	     case (CGEN_PARSE_OPERAND_RESULT_QUEUED):
    154 	       /* No special processing for this case.  */
    155 	       break;
    156 
    157 	     default:
    158 	       errmsg = _("The percent-operator's operand is not a symbol");
    159 	       break;
    160              }
    161 	 }
    162        *valuep = value;
    163     }
    164   else
    165     {
    166       /* Parse hex values like 0xffff as unsigned, and sign extend
    167 	 them manually.  */
    168       int parse_signed = (opindex == (CGEN_OPERAND_TYPE)MT_OPERAND_IMM16);
    169 
    170       if ((*strp)[0] == '0'
    171 	  && ((*strp)[1] == 'x' || (*strp)[1] == 'X'))
    172 	parse_signed = 0;
    173 
    174       /* No relocating operator.  Parse as an number.  */
    175       if (parse_signed)
    176 	{
    177           /* Parse as as signed integer.  */
    178 
    179           errmsg = cgen_parse_signed_integer (cd, strp, opindex, valuep);
    180 
    181           if (errmsg == NULL)
    182 	    {
    183 #if 0
    184 	      /* Manual range checking is needed for the signed case.  */
    185 	      if (*valuep & 0x8000)
    186                 value = 0xffff0000 | *valuep;
    187 	      else
    188                 value = *valuep;
    189 
    190 	      if (signed_out_of_bounds (value))
    191 	        errmsg = _("Operand out of range. Must be between -32768 and 32767.");
    192 	      /* Truncate to 16 bits. This is necessary
    193 		 because cgen will have sign extended *valuep.  */
    194 	      *valuep &= 0xFFFF;
    195 #endif
    196 	    }
    197 	}
    198       else
    199 	{
    200           /* MT_OPERAND_IMM16Z.  Parse as an unsigned integer.  */
    201           errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, (unsigned long *) valuep);
    202 
    203 	  if (opindex == (CGEN_OPERAND_TYPE) MT_OPERAND_IMM16
    204 	      && *valuep >= 0x8000
    205 	      && *valuep <= 0xffff)
    206 	    *valuep -= 0x10000;
    207 	}
    208     }
    209 
    210   return errmsg;
    211 }
    212 
    213 
    214 static const char *
    215 parse_dup (CGEN_CPU_DESC cd,
    216 	   const char **strp,
    217 	   int opindex,
    218 	   unsigned long *valuep)
    219 {
    220   const char *errmsg = NULL;
    221 
    222   if (strncmp (*strp, "dup", 3) == 0 || strncmp (*strp, "DUP", 3) == 0)
    223     {
    224       *strp += 3;
    225       *valuep = 1;
    226     }
    227   else if (strncmp (*strp, "xx", 2) == 0 || strncmp (*strp, "XX", 2) == 0)
    228     {
    229       *strp += 2;
    230       *valuep = 0;
    231     }
    232   else
    233     errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
    234 
    235   return errmsg;
    236 }
    237 
    238 
    239 static const char *
    240 parse_ball (CGEN_CPU_DESC cd,
    241 	    const char **strp,
    242 	    int opindex,
    243 	    unsigned long *valuep)
    244 {
    245   const char *errmsg = NULL;
    246 
    247   if (strncmp (*strp, "all", 3) == 0 || strncmp (*strp, "ALL", 3) == 0)
    248     {
    249       *strp += 3;
    250       *valuep = 1;
    251     }
    252   else if (strncmp (*strp, "one", 3) == 0 || strncmp (*strp, "ONE", 3) == 0)
    253     {
    254       *strp += 3;
    255       *valuep = 0;
    256     }
    257   else
    258     errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
    259 
    260   return errmsg;
    261 }
    262 
    263 static const char *
    264 parse_xmode (CGEN_CPU_DESC cd,
    265 	     const char **strp,
    266 	     int opindex,
    267 	     unsigned long *valuep)
    268 {
    269   const char *errmsg = NULL;
    270 
    271   if (strncmp (*strp, "pm", 2) == 0 || strncmp (*strp, "PM", 2) == 0)
    272     {
    273       *strp += 2;
    274       *valuep = 1;
    275     }
    276   else if (strncmp (*strp, "xm", 2) == 0 || strncmp (*strp, "XM", 2) == 0)
    277     {
    278       *strp += 2;
    279       *valuep = 0;
    280     }
    281   else
    282     errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
    283 
    284   return errmsg;
    285 }
    286 
    287 static const char *
    288 parse_rc (CGEN_CPU_DESC cd,
    289 	  const char **strp,
    290 	  int opindex,
    291 	  unsigned long *valuep)
    292 {
    293   const char *errmsg = NULL;
    294 
    295   if (strncmp (*strp, "r", 1) == 0 || strncmp (*strp, "R", 1) == 0)
    296     {
    297       *strp += 1;
    298       *valuep = 1;
    299     }
    300   else if (strncmp (*strp, "c", 1) == 0 || strncmp (*strp, "C", 1) == 0)
    301     {
    302       *strp += 1;
    303       *valuep = 0;
    304     }
    305   else
    306     errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
    307 
    308   return errmsg;
    309 }
    310 
    311 static const char *
    312 parse_cbrb (CGEN_CPU_DESC cd,
    313 	    const char **strp,
    314 	    int opindex,
    315 	    unsigned long *valuep)
    316 {
    317   const char *errmsg = NULL;
    318 
    319   if (strncmp (*strp, "rb", 2) == 0 || strncmp (*strp, "RB", 2) == 0)
    320     {
    321       *strp += 2;
    322       *valuep = 1;
    323     }
    324   else if (strncmp (*strp, "cb", 2) == 0 || strncmp (*strp, "CB", 2) == 0)
    325     {
    326       *strp += 2;
    327       *valuep = 0;
    328     }
    329   else
    330     errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
    331 
    332   return errmsg;
    333 }
    334 
    335 static const char *
    336 parse_rbbc (CGEN_CPU_DESC cd,
    337 	    const char **strp,
    338 	    int opindex,
    339 	    unsigned long *valuep)
    340 {
    341   const char *errmsg = NULL;
    342 
    343   if (strncmp (*strp, "rt", 2) == 0 || strncmp (*strp, "RT", 2) == 0)
    344     {
    345       *strp += 2;
    346       *valuep = 0;
    347     }
    348   else if (strncmp (*strp, "br1", 3) == 0 || strncmp (*strp, "BR1", 3) == 0)
    349     {
    350       *strp += 3;
    351       *valuep = 1;
    352     }
    353   else if (strncmp (*strp, "br2", 3) == 0 || strncmp (*strp, "BR2", 3) == 0)
    354     {
    355       *strp += 3;
    356       *valuep = 2;
    357     }
    358   else if (strncmp (*strp, "cs", 2) == 0 || strncmp (*strp, "CS", 2) == 0)
    359     {
    360       *strp += 2;
    361       *valuep = 3;
    362     }
    363   else
    364     errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
    365 
    366   return errmsg;
    367 }
    368 
    369 static const char *
    370 parse_type (CGEN_CPU_DESC cd,
    371 	    const char **strp,
    372 	    int opindex,
    373 	    unsigned long *valuep)
    374 {
    375   const char *errmsg = NULL;
    376 
    377   if (strncmp (*strp, "odd", 3) == 0 || strncmp (*strp, "ODD", 3) == 0)
    378     {
    379       *strp += 3;
    380       *valuep = 0;
    381     }
    382   else if (strncmp (*strp, "even", 4) == 0 || strncmp (*strp, "EVEN", 4) == 0)
    383     {
    384       *strp += 4;
    385       *valuep = 1;
    386     }
    387   else if (strncmp (*strp, "oe", 2) == 0 || strncmp (*strp, "OE", 2) == 0)
    388     {
    389       *strp += 2;
    390       *valuep = 2;
    391     }
    392   else
    393     errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
    394 
    395  if ((errmsg == NULL) && (*valuep == 3))
    396     errmsg = _("invalid operand.  type may have values 0,1,2 only.");
    397 
    398   return errmsg;
    399 }
    400 
    401 /* -- dis.c */
    402 
    403 const char * mt_cgen_parse_operand
    404   (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
    405 
    406 /* Main entry point for operand parsing.
    407 
    408    This function is basically just a big switch statement.  Earlier versions
    409    used tables to look up the function to use, but
    410    - if the table contains both assembler and disassembler functions then
    411      the disassembler contains much of the assembler and vice-versa,
    412    - there's a lot of inlining possibilities as things grow,
    413    - using a switch statement avoids the function call overhead.
    414 
    415    This function could be moved into `parse_insn_normal', but keeping it
    416    separate makes clear the interface between `parse_insn_normal' and each of
    417    the handlers.  */
    418 
    419 const char *
    420 mt_cgen_parse_operand (CGEN_CPU_DESC cd,
    421 			   int opindex,
    422 			   const char ** strp,
    423 			   CGEN_FIELDS * fields)
    424 {
    425   const char * errmsg = NULL;
    426   /* Used by scalar operands that still need to be parsed.  */
    427   long junk ATTRIBUTE_UNUSED;
    428 
    429   switch (opindex)
    430     {
    431     case MT_OPERAND_A23 :
    432       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_A23, (unsigned long *) (& fields->f_a23));
    433       break;
    434     case MT_OPERAND_BALL :
    435       errmsg = parse_ball (cd, strp, MT_OPERAND_BALL, (unsigned long *) (& fields->f_ball));
    436       break;
    437     case MT_OPERAND_BALL2 :
    438       errmsg = parse_ball (cd, strp, MT_OPERAND_BALL2, (unsigned long *) (& fields->f_ball2));
    439       break;
    440     case MT_OPERAND_BANKADDR :
    441       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_BANKADDR, (unsigned long *) (& fields->f_bankaddr));
    442       break;
    443     case MT_OPERAND_BRC :
    444       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_BRC, (unsigned long *) (& fields->f_brc));
    445       break;
    446     case MT_OPERAND_BRC2 :
    447       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_BRC2, (unsigned long *) (& fields->f_brc2));
    448       break;
    449     case MT_OPERAND_CB1INCR :
    450       errmsg = cgen_parse_signed_integer (cd, strp, MT_OPERAND_CB1INCR, (long *) (& fields->f_cb1incr));
    451       break;
    452     case MT_OPERAND_CB1SEL :
    453       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CB1SEL, (unsigned long *) (& fields->f_cb1sel));
    454       break;
    455     case MT_OPERAND_CB2INCR :
    456       errmsg = cgen_parse_signed_integer (cd, strp, MT_OPERAND_CB2INCR, (long *) (& fields->f_cb2incr));
    457       break;
    458     case MT_OPERAND_CB2SEL :
    459       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CB2SEL, (unsigned long *) (& fields->f_cb2sel));
    460       break;
    461     case MT_OPERAND_CBRB :
    462       errmsg = parse_cbrb (cd, strp, MT_OPERAND_CBRB, (unsigned long *) (& fields->f_cbrb));
    463       break;
    464     case MT_OPERAND_CBS :
    465       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CBS, (unsigned long *) (& fields->f_cbs));
    466       break;
    467     case MT_OPERAND_CBX :
    468       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CBX, (unsigned long *) (& fields->f_cbx));
    469       break;
    470     case MT_OPERAND_CCB :
    471       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CCB, (unsigned long *) (& fields->f_ccb));
    472       break;
    473     case MT_OPERAND_CDB :
    474       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CDB, (unsigned long *) (& fields->f_cdb));
    475       break;
    476     case MT_OPERAND_CELL :
    477       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CELL, (unsigned long *) (& fields->f_cell));
    478       break;
    479     case MT_OPERAND_COLNUM :
    480       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_COLNUM, (unsigned long *) (& fields->f_colnum));
    481       break;
    482     case MT_OPERAND_CONTNUM :
    483       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CONTNUM, (unsigned long *) (& fields->f_contnum));
    484       break;
    485     case MT_OPERAND_CR :
    486       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CR, (unsigned long *) (& fields->f_cr));
    487       break;
    488     case MT_OPERAND_CTXDISP :
    489       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_CTXDISP, (unsigned long *) (& fields->f_ctxdisp));
    490       break;
    491     case MT_OPERAND_DUP :
    492       errmsg = parse_dup (cd, strp, MT_OPERAND_DUP, (unsigned long *) (& fields->f_dup));
    493       break;
    494     case MT_OPERAND_FBDISP :
    495       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_FBDISP, (unsigned long *) (& fields->f_fbdisp));
    496       break;
    497     case MT_OPERAND_FBINCR :
    498       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_FBINCR, (unsigned long *) (& fields->f_fbincr));
    499       break;
    500     case MT_OPERAND_FRDR :
    501       errmsg = cgen_parse_keyword (cd, strp, & mt_cgen_opval_h_spr, & fields->f_dr);
    502       break;
    503     case MT_OPERAND_FRDRRR :
    504       errmsg = cgen_parse_keyword (cd, strp, & mt_cgen_opval_h_spr, & fields->f_drrr);
    505       break;
    506     case MT_OPERAND_FRSR1 :
    507       errmsg = cgen_parse_keyword (cd, strp, & mt_cgen_opval_h_spr, & fields->f_sr1);
    508       break;
    509     case MT_OPERAND_FRSR2 :
    510       errmsg = cgen_parse_keyword (cd, strp, & mt_cgen_opval_h_spr, & fields->f_sr2);
    511       break;
    512     case MT_OPERAND_ID :
    513       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_ID, (unsigned long *) (& fields->f_id));
    514       break;
    515     case MT_OPERAND_IMM16 :
    516       errmsg = parse_imm16 (cd, strp, MT_OPERAND_IMM16, (long *) (& fields->f_imm16s));
    517       break;
    518     case MT_OPERAND_IMM16L :
    519       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_IMM16L, (unsigned long *) (& fields->f_imm16l));
    520       break;
    521     case MT_OPERAND_IMM16O :
    522       errmsg = parse_imm16 (cd, strp, MT_OPERAND_IMM16O, (unsigned long *) (& fields->f_imm16s));
    523       break;
    524     case MT_OPERAND_IMM16Z :
    525       errmsg = parse_imm16 (cd, strp, MT_OPERAND_IMM16Z, (unsigned long *) (& fields->f_imm16u));
    526       break;
    527     case MT_OPERAND_INCAMT :
    528       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_INCAMT, (unsigned long *) (& fields->f_incamt));
    529       break;
    530     case MT_OPERAND_INCR :
    531       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_INCR, (unsigned long *) (& fields->f_incr));
    532       break;
    533     case MT_OPERAND_LENGTH :
    534       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_LENGTH, (unsigned long *) (& fields->f_length));
    535       break;
    536     case MT_OPERAND_LOOPSIZE :
    537       errmsg = parse_loopsize (cd, strp, MT_OPERAND_LOOPSIZE, (unsigned long *) (& fields->f_loopo));
    538       break;
    539     case MT_OPERAND_MASK :
    540       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_MASK, (unsigned long *) (& fields->f_mask));
    541       break;
    542     case MT_OPERAND_MASK1 :
    543       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_MASK1, (unsigned long *) (& fields->f_mask1));
    544       break;
    545     case MT_OPERAND_MODE :
    546       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_MODE, (unsigned long *) (& fields->f_mode));
    547       break;
    548     case MT_OPERAND_PERM :
    549       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_PERM, (unsigned long *) (& fields->f_perm));
    550       break;
    551     case MT_OPERAND_RBBC :
    552       errmsg = parse_rbbc (cd, strp, MT_OPERAND_RBBC, (unsigned long *) (& fields->f_rbbc));
    553       break;
    554     case MT_OPERAND_RC :
    555       errmsg = parse_rc (cd, strp, MT_OPERAND_RC, (unsigned long *) (& fields->f_rc));
    556       break;
    557     case MT_OPERAND_RC1 :
    558       errmsg = parse_rc (cd, strp, MT_OPERAND_RC1, (unsigned long *) (& fields->f_rc1));
    559       break;
    560     case MT_OPERAND_RC2 :
    561       errmsg = parse_rc (cd, strp, MT_OPERAND_RC2, (unsigned long *) (& fields->f_rc2));
    562       break;
    563     case MT_OPERAND_RC3 :
    564       errmsg = parse_rc (cd, strp, MT_OPERAND_RC3, (unsigned long *) (& fields->f_rc3));
    565       break;
    566     case MT_OPERAND_RCNUM :
    567       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_RCNUM, (unsigned long *) (& fields->f_rcnum));
    568       break;
    569     case MT_OPERAND_RDA :
    570       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_RDA, (unsigned long *) (& fields->f_rda));
    571       break;
    572     case MT_OPERAND_ROWNUM :
    573       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_ROWNUM, (unsigned long *) (& fields->f_rownum));
    574       break;
    575     case MT_OPERAND_ROWNUM1 :
    576       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_ROWNUM1, (unsigned long *) (& fields->f_rownum1));
    577       break;
    578     case MT_OPERAND_ROWNUM2 :
    579       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_ROWNUM2, (unsigned long *) (& fields->f_rownum2));
    580       break;
    581     case MT_OPERAND_SIZE :
    582       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_SIZE, (unsigned long *) (& fields->f_size));
    583       break;
    584     case MT_OPERAND_TYPE :
    585       errmsg = parse_type (cd, strp, MT_OPERAND_TYPE, (unsigned long *) (& fields->f_type));
    586       break;
    587     case MT_OPERAND_WR :
    588       errmsg = cgen_parse_unsigned_integer (cd, strp, MT_OPERAND_WR, (unsigned long *) (& fields->f_wr));
    589       break;
    590     case MT_OPERAND_XMODE :
    591       errmsg = parse_xmode (cd, strp, MT_OPERAND_XMODE, (unsigned long *) (& fields->f_xmode));
    592       break;
    593 
    594     default :
    595       /* xgettext:c-format */
    596       opcodes_error_handler
    597 	(_("internal error: unrecognized field %d while parsing"),
    598 	 opindex);
    599       abort ();
    600   }
    601 
    602   return errmsg;
    603 }
    604 
    605 cgen_parse_fn * const mt_cgen_parse_handlers[] =
    606 {
    607   parse_insn_normal,
    608 };
    609 
    610 void
    611 mt_cgen_init_asm (CGEN_CPU_DESC cd)
    612 {
    613   mt_cgen_init_opcode_table (cd);
    614   mt_cgen_init_ibld_table (cd);
    615   cd->parse_handlers = & mt_cgen_parse_handlers[0];
    616   cd->parse_operand = mt_cgen_parse_operand;
    617 #ifdef CGEN_ASM_INIT_HOOK
    618 CGEN_ASM_INIT_HOOK
    619 #endif
    620 }
    621 
    622 
    623 
    625 /* Regex construction routine.
    626 
    627    This translates an opcode syntax string into a regex string,
    628    by replacing any non-character syntax element (such as an
    629    opcode) with the pattern '.*'
    630 
    631    It then compiles the regex and stores it in the opcode, for
    632    later use by mt_cgen_assemble_insn
    633 
    634    Returns NULL for success, an error message for failure.  */
    635 
    636 char *
    637 mt_cgen_build_insn_regex (CGEN_INSN *insn)
    638 {
    639   CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
    640   const char *mnem = CGEN_INSN_MNEMONIC (insn);
    641   char rxbuf[CGEN_MAX_RX_ELEMENTS];
    642   char *rx = rxbuf;
    643   const CGEN_SYNTAX_CHAR_TYPE *syn;
    644   int reg_err;
    645 
    646   syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
    647 
    648   /* Mnemonics come first in the syntax string.  */
    649   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
    650     return _("missing mnemonic in syntax string");
    651   ++syn;
    652 
    653   /* Generate a case sensitive regular expression that emulates case
    654      insensitive matching in the "C" locale.  We cannot generate a case
    655      insensitive regular expression because in Turkish locales, 'i' and 'I'
    656      are not equal modulo case conversion.  */
    657 
    658   /* Copy the literal mnemonic out of the insn.  */
    659   for (; *mnem; mnem++)
    660     {
    661       char c = *mnem;
    662 
    663       if (ISALPHA (c))
    664 	{
    665 	  *rx++ = '[';
    666 	  *rx++ = TOLOWER (c);
    667 	  *rx++ = TOUPPER (c);
    668 	  *rx++ = ']';
    669 	}
    670       else
    671 	*rx++ = c;
    672     }
    673 
    674   /* Copy any remaining literals from the syntax string into the rx.  */
    675   for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
    676     {
    677       if (CGEN_SYNTAX_CHAR_P (* syn))
    678 	{
    679 	  char c = CGEN_SYNTAX_CHAR (* syn);
    680 
    681 	  switch (c)
    682 	    {
    683 	      /* Escape any regex metacharacters in the syntax.  */
    684 	    case '.': case '[': case '\\':
    685 	    case '*': case '^': case '$':
    686 
    687 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
    688 	    case '?': case '{': case '}':
    689 	    case '(': case ')': case '*':
    690 	    case '|': case '+': case ']':
    691 #endif
    692 	      *rx++ = '\\';
    693 	      *rx++ = c;
    694 	      break;
    695 
    696 	    default:
    697 	      if (ISALPHA (c))
    698 		{
    699 		  *rx++ = '[';
    700 		  *rx++ = TOLOWER (c);
    701 		  *rx++ = TOUPPER (c);
    702 		  *rx++ = ']';
    703 		}
    704 	      else
    705 		*rx++ = c;
    706 	      break;
    707 	    }
    708 	}
    709       else
    710 	{
    711 	  /* Replace non-syntax fields with globs.  */
    712 	  *rx++ = '.';
    713 	  *rx++ = '*';
    714 	}
    715     }
    716 
    717   /* Trailing whitespace ok.  */
    718   * rx++ = '[';
    719   * rx++ = ' ';
    720   * rx++ = '\t';
    721   * rx++ = ']';
    722   * rx++ = '*';
    723 
    724   /* But anchor it after that.  */
    725   * rx++ = '$';
    726   * rx = '\0';
    727 
    728   CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
    729   reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
    730 
    731   if (reg_err == 0)
    732     return NULL;
    733   else
    734     {
    735       static char msg[80];
    736 
    737       regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
    738       regfree ((regex_t *) CGEN_INSN_RX (insn));
    739       free (CGEN_INSN_RX (insn));
    740       (CGEN_INSN_RX (insn)) = NULL;
    741       return msg;
    742     }
    743 }
    744 
    745 
    746 /* Default insn parser.
    748 
    749    The syntax string is scanned and operands are parsed and stored in FIELDS.
    750    Relocs are queued as we go via other callbacks.
    751 
    752    ??? Note that this is currently an all-or-nothing parser.  If we fail to
    753    parse the instruction, we return 0 and the caller will start over from
    754    the beginning.  Backtracking will be necessary in parsing subexpressions,
    755    but that can be handled there.  Not handling backtracking here may get
    756    expensive in the case of the m68k.  Deal with later.
    757 
    758    Returns NULL for success, an error message for failure.  */
    759 
    760 static const char *
    761 parse_insn_normal (CGEN_CPU_DESC cd,
    762 		   const CGEN_INSN *insn,
    763 		   const char **strp,
    764 		   CGEN_FIELDS *fields)
    765 {
    766   /* ??? Runtime added insns not handled yet.  */
    767   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
    768   const char *str = *strp;
    769   const char *errmsg;
    770   const char *p;
    771   const CGEN_SYNTAX_CHAR_TYPE * syn;
    772 #ifdef CGEN_MNEMONIC_OPERANDS
    773   /* FIXME: wip */
    774   int past_opcode_p;
    775 #endif
    776 
    777   /* For now we assume the mnemonic is first (there are no leading operands).
    778      We can parse it without needing to set up operand parsing.
    779      GAS's input scrubber will ensure mnemonics are lowercase, but we may
    780      not be called from GAS.  */
    781   p = CGEN_INSN_MNEMONIC (insn);
    782   while (*p && TOLOWER (*p) == TOLOWER (*str))
    783     ++p, ++str;
    784 
    785   if (* p)
    786     return _("unrecognized instruction");
    787 
    788 #ifndef CGEN_MNEMONIC_OPERANDS
    789   if (* str && ! ISSPACE (* str))
    790     return _("unrecognized instruction");
    791 #endif
    792 
    793   CGEN_INIT_PARSE (cd);
    794   cgen_init_parse_operand (cd);
    795 #ifdef CGEN_MNEMONIC_OPERANDS
    796   past_opcode_p = 0;
    797 #endif
    798 
    799   /* We don't check for (*str != '\0') here because we want to parse
    800      any trailing fake arguments in the syntax string.  */
    801   syn = CGEN_SYNTAX_STRING (syntax);
    802 
    803   /* Mnemonics come first for now, ensure valid string.  */
    804   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
    805     abort ();
    806 
    807   ++syn;
    808 
    809   while (* syn != 0)
    810     {
    811       /* Non operand chars must match exactly.  */
    812       if (CGEN_SYNTAX_CHAR_P (* syn))
    813 	{
    814 	  /* FIXME: While we allow for non-GAS callers above, we assume the
    815 	     first char after the mnemonic part is a space.  */
    816 	  /* FIXME: We also take inappropriate advantage of the fact that
    817 	     GAS's input scrubber will remove extraneous blanks.  */
    818 	  if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
    819 	    {
    820 #ifdef CGEN_MNEMONIC_OPERANDS
    821 	      if (CGEN_SYNTAX_CHAR(* syn) == ' ')
    822 		past_opcode_p = 1;
    823 #endif
    824 	      ++ syn;
    825 	      ++ str;
    826 	    }
    827 	  else if (*str)
    828 	    {
    829 	      /* Syntax char didn't match.  Can't be this insn.  */
    830 	      static char msg [80];
    831 
    832 	      /* xgettext:c-format */
    833 	      sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
    834 		       CGEN_SYNTAX_CHAR(*syn), *str);
    835 	      return msg;
    836 	    }
    837 	  else
    838 	    {
    839 	      /* Ran out of input.  */
    840 	      static char msg [80];
    841 
    842 	      /* xgettext:c-format */
    843 	      sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
    844 		       CGEN_SYNTAX_CHAR(*syn));
    845 	      return msg;
    846 	    }
    847 	  continue;
    848 	}
    849 
    850 #ifdef CGEN_MNEMONIC_OPERANDS
    851       (void) past_opcode_p;
    852 #endif
    853       /* We have an operand of some sort.  */
    854       errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
    855       if (errmsg)
    856 	return errmsg;
    857 
    858       /* Done with this operand, continue with next one.  */
    859       ++ syn;
    860     }
    861 
    862   /* If we're at the end of the syntax string, we're done.  */
    863   if (* syn == 0)
    864     {
    865       /* FIXME: For the moment we assume a valid `str' can only contain
    866 	 blanks now.  IE: We needn't try again with a longer version of
    867 	 the insn and it is assumed that longer versions of insns appear
    868 	 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
    869       while (ISSPACE (* str))
    870 	++ str;
    871 
    872       if (* str != '\0')
    873 	return _("junk at end of line"); /* FIXME: would like to include `str' */
    874 
    875       return NULL;
    876     }
    877 
    878   /* We couldn't parse it.  */
    879   return _("unrecognized instruction");
    880 }
    881 
    882 /* Main entry point.
    884    This routine is called for each instruction to be assembled.
    885    STR points to the insn to be assembled.
    886    We assume all necessary tables have been initialized.
    887    The assembled instruction, less any fixups, is stored in BUF.
    888    Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
    889    still needs to be converted to target byte order, otherwise BUF is an array
    890    of bytes in target byte order.
    891    The result is a pointer to the insn's entry in the opcode table,
    892    or NULL if an error occured (an error message will have already been
    893    printed).
    894 
    895    Note that when processing (non-alias) macro-insns,
    896    this function recurses.
    897 
    898    ??? It's possible to make this cpu-independent.
    899    One would have to deal with a few minor things.
    900    At this point in time doing so would be more of a curiosity than useful
    901    [for example this file isn't _that_ big], but keeping the possibility in
    902    mind helps keep the design clean.  */
    903 
    904 const CGEN_INSN *
    905 mt_cgen_assemble_insn (CGEN_CPU_DESC cd,
    906 			   const char *str,
    907 			   CGEN_FIELDS *fields,
    908 			   CGEN_INSN_BYTES_PTR buf,
    909 			   char **errmsg)
    910 {
    911   const char *start;
    912   CGEN_INSN_LIST *ilist;
    913   const char *parse_errmsg = NULL;
    914   const char *insert_errmsg = NULL;
    915   int recognized_mnemonic = 0;
    916 
    917   /* Skip leading white space.  */
    918   while (ISSPACE (* str))
    919     ++ str;
    920 
    921   /* The instructions are stored in hashed lists.
    922      Get the first in the list.  */
    923   ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
    924 
    925   /* Keep looking until we find a match.  */
    926   start = str;
    927   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
    928     {
    929       const CGEN_INSN *insn = ilist->insn;
    930       recognized_mnemonic = 1;
    931 
    932 #ifdef CGEN_VALIDATE_INSN_SUPPORTED
    933       /* Not usually needed as unsupported opcodes
    934 	 shouldn't be in the hash lists.  */
    935       /* Is this insn supported by the selected cpu?  */
    936       if (! mt_cgen_insn_supported (cd, insn))
    937 	continue;
    938 #endif
    939       /* If the RELAXED attribute is set, this is an insn that shouldn't be
    940 	 chosen immediately.  Instead, it is used during assembler/linker
    941 	 relaxation if possible.  */
    942       if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
    943 	continue;
    944 
    945       str = start;
    946 
    947       /* Skip this insn if str doesn't look right lexically.  */
    948       if (CGEN_INSN_RX (insn) != NULL &&
    949 	  regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
    950 	continue;
    951 
    952       /* Allow parse/insert handlers to obtain length of insn.  */
    953       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
    954 
    955       parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
    956       if (parse_errmsg != NULL)
    957 	continue;
    958 
    959       /* ??? 0 is passed for `pc'.  */
    960       insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
    961 						 (bfd_vma) 0);
    962       if (insert_errmsg != NULL)
    963         continue;
    964 
    965       /* It is up to the caller to actually output the insn and any
    966          queued relocs.  */
    967       return insn;
    968     }
    969 
    970   {
    971     static char errbuf[150];
    972     const char *tmp_errmsg;
    973 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
    974 #define be_verbose 1
    975 #else
    976 #define be_verbose 0
    977 #endif
    978 
    979     if (be_verbose)
    980       {
    981 	/* If requesting verbose error messages, use insert_errmsg.
    982 	   Failing that, use parse_errmsg.  */
    983 	tmp_errmsg = (insert_errmsg ? insert_errmsg :
    984 		      parse_errmsg ? parse_errmsg :
    985 		      recognized_mnemonic ?
    986 		      _("unrecognized form of instruction") :
    987 		      _("unrecognized instruction"));
    988 
    989 	if (strlen (start) > 50)
    990 	  /* xgettext:c-format */
    991 	  sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
    992 	else
    993 	  /* xgettext:c-format */
    994 	  sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
    995       }
    996     else
    997       {
    998 	if (strlen (start) > 50)
    999 	  /* xgettext:c-format */
   1000 	  sprintf (errbuf, _("bad instruction `%.50s...'"), start);
   1001 	else
   1002 	  /* xgettext:c-format */
   1003 	  sprintf (errbuf, _("bad instruction `%.50s'"), start);
   1004       }
   1005 
   1006     *errmsg = errbuf;
   1007     return NULL;
   1008   }
   1009 }
   1010