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