Home | History | Annotate | Line # | Download | only in opcodes
or1k-asm.c revision 1.1.1.4
      1  1.1.1.3  christos /* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
      2      1.1      matt /* Assembler interface for targets using CGEN. -*- C -*-
      3      1.1      matt    CGEN: Cpu tools GENerator
      4      1.1      matt 
      5      1.1      matt    THIS FILE IS MACHINE GENERATED WITH CGEN.
      6      1.1      matt    - the resultant file is machine generated, cgen-asm.in isn't
      7      1.1      matt 
      8  1.1.1.3  christos    Copyright (C) 1996-2018 Free Software Foundation, Inc.
      9      1.1      matt 
     10      1.1      matt    This file is part of libopcodes.
     11      1.1      matt 
     12      1.1      matt    This library is free software; you can redistribute it and/or modify
     13      1.1      matt    it under the terms of the GNU General Public License as published by
     14      1.1      matt    the Free Software Foundation; either version 3, or (at your option)
     15      1.1      matt    any later version.
     16      1.1      matt 
     17      1.1      matt    It is distributed in the hope that it will be useful, but WITHOUT
     18      1.1      matt    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     19      1.1      matt    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     20      1.1      matt    License for more details.
     21      1.1      matt 
     22      1.1      matt    You should have received a copy of the GNU General Public License
     23      1.1      matt    along with this program; if not, write to the Free Software Foundation, Inc.,
     24      1.1      matt    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
     25      1.1      matt 
     26      1.1      matt 
     27      1.1      matt /* ??? Eventually more and more of this stuff can go to cpu-independent files.
     28      1.1      matt    Keep that in mind.  */
     29      1.1      matt 
     30      1.1      matt #include "sysdep.h"
     31      1.1      matt #include <stdio.h>
     32      1.1      matt #include "ansidecl.h"
     33      1.1      matt #include "bfd.h"
     34      1.1      matt #include "symcat.h"
     35      1.1      matt #include "or1k-desc.h"
     36      1.1      matt #include "or1k-opc.h"
     37      1.1      matt #include "opintl.h"
     38      1.1      matt #include "xregex.h"
     39      1.1      matt #include "libiberty.h"
     40      1.1      matt #include "safe-ctype.h"
     41      1.1      matt 
     42      1.1      matt #undef  min
     43      1.1      matt #define min(a,b) ((a) < (b) ? (a) : (b))
     44      1.1      matt #undef  max
     45      1.1      matt #define max(a,b) ((a) > (b) ? (a) : (b))
     46      1.1      matt 
     47      1.1      matt static const char * parse_insn_normal
     48      1.1      matt   (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
     49      1.1      matt 
     50      1.1      matt /* -- assembler routines inserted here.  */
     52      1.1      matt 
     53      1.1      matt /* -- asm.c */
     54      1.1      matt 
     55      1.1      matt static const char * MISSING_CLOSING_PARENTHESIS = N_("missing `)'");
     56      1.1      matt 
     57      1.1      matt #define CGEN_VERBOSE_ASSEMBLER_ERRORS
     58      1.1      matt 
     59      1.1      matt static const char *
     60      1.1      matt parse_disp26 (CGEN_CPU_DESC cd,
     61      1.1      matt 	      const char ** strp,
     62      1.1      matt 	      int opindex,
     63      1.1      matt 	      int opinfo,
     64      1.1      matt 	      enum cgen_parse_operand_result * resultp,
     65      1.1      matt 	      bfd_vma * valuep)
     66      1.1      matt {
     67      1.1      matt   const char *errmsg = NULL;
     68      1.1      matt   enum cgen_parse_operand_result result_type;
     69      1.1      matt 
     70      1.1      matt   if (strncasecmp (*strp, "plt(", 4) == 0)
     71      1.1      matt     {
     72      1.1      matt       bfd_vma value;
     73      1.1      matt 
     74      1.1      matt       *strp += 4;
     75      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_PLT26,
     76      1.1      matt 				   & result_type, & value);
     77      1.1      matt       if (**strp != ')')
     78      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
     79      1.1      matt       ++*strp;
     80      1.1      matt       if (errmsg == NULL
     81      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
     82      1.1      matt 	value = (value >> 2) & 0xffff;
     83      1.1      matt       *valuep = value;
     84      1.1      matt       return errmsg;
     85      1.1      matt     }
     86      1.1      matt   return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
     87      1.1      matt }
     88      1.1      matt 
     89      1.1      matt static const char *
     90      1.1      matt parse_simm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, long * valuep)
     91      1.1      matt {
     92      1.1      matt   const char *errmsg;
     93      1.1      matt   enum cgen_parse_operand_result result_type;
     94      1.1      matt   long ret;
     95      1.1      matt 
     96      1.1      matt   if (**strp == '#')
     97      1.1      matt     ++*strp;
     98      1.1      matt 
     99      1.1      matt   if (strncasecmp (*strp, "hi(", 3) == 0)
    100      1.1      matt     {
    101      1.1      matt       bfd_vma value;
    102      1.1      matt 
    103      1.1      matt       *strp += 3;
    104      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_HI16,
    105      1.1      matt 				   & result_type, & value);
    106      1.1      matt       if (**strp != ')')
    107      1.1      matt 	errmsg = MISSING_CLOSING_PARENTHESIS;
    108      1.1      matt       ++*strp;
    109      1.1      matt 
    110      1.1      matt       ret = value;
    111      1.1      matt 
    112      1.1      matt       if (errmsg == NULL
    113      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    114      1.1      matt 	{
    115      1.1      matt 	  ret >>= 16;
    116      1.1      matt 	  ret &= 0xffff;
    117      1.1      matt 	  ret = (ret ^ 0x8000) - 0x8000;
    118      1.1      matt 	}
    119      1.1      matt     }
    120      1.1      matt   else if (strncasecmp (*strp, "lo(", 3) == 0)
    121      1.1      matt     {
    122      1.1      matt       bfd_vma value;
    123      1.1      matt 
    124      1.1      matt       *strp += 3;
    125      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_LO16,
    126      1.1      matt 				   & result_type, & value);
    127      1.1      matt       if (**strp != ')')
    128      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    129      1.1      matt       ++*strp;
    130      1.1      matt 
    131      1.1      matt       ret = value;
    132      1.1      matt 
    133      1.1      matt       if (result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    134      1.1      matt 	{
    135      1.1      matt 	  ret &= 0xffff;
    136      1.1      matt 	  ret = (ret ^ 0x8000) - 0x8000;
    137      1.1      matt 	}
    138      1.1      matt     }
    139      1.1      matt   else if (strncasecmp (*strp, "got(", 4) == 0)
    140      1.1      matt     {
    141      1.1      matt       bfd_vma value;
    142      1.1      matt 
    143      1.1      matt       *strp += 4;
    144      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_OR1K_GOT16,
    145      1.1      matt 				   & result_type, & value);
    146      1.1      matt       if (**strp != ')')
    147      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    148      1.1      matt       ++*strp;
    149      1.1      matt       if (errmsg == NULL
    150      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    151      1.1      matt 	value &= 0xffff;
    152      1.1      matt       *valuep = value;
    153      1.1      matt       return errmsg;
    154      1.1      matt     }
    155      1.1      matt   else if (strncasecmp (*strp, "gotpchi(", 8) == 0)
    156      1.1      matt     {
    157      1.1      matt       bfd_vma value;
    158      1.1      matt 
    159      1.1      matt       *strp += 8;
    160      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex,
    161      1.1      matt 				   BFD_RELOC_OR1K_GOTPC_HI16,
    162      1.1      matt 				   & result_type, & value);
    163      1.1      matt       if (**strp != ')')
    164      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    165      1.1      matt       ++*strp;
    166      1.1      matt       if (errmsg == NULL
    167      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    168      1.1      matt 	value = (value >> 16) & 0xffff;
    169      1.1      matt       *valuep = value;
    170      1.1      matt       return errmsg;
    171      1.1      matt     }
    172      1.1      matt   else if (strncasecmp (*strp, "gotpclo(", 8) == 0)
    173      1.1      matt     {
    174      1.1      matt       bfd_vma value;
    175      1.1      matt 
    176      1.1      matt       *strp += 8;
    177      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex,
    178      1.1      matt 				   BFD_RELOC_OR1K_GOTPC_LO16,
    179      1.1      matt 				   &result_type, &value);
    180      1.1      matt       if (**strp != ')')
    181      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    182      1.1      matt       ++*strp;
    183      1.1      matt       if (errmsg == NULL
    184      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    185      1.1      matt 	value &= 0xffff;
    186      1.1      matt       *valuep = value;
    187      1.1      matt       return errmsg;
    188      1.1      matt     }
    189      1.1      matt   else if (strncasecmp (*strp, "gotoffhi(", 9) == 0)
    190      1.1      matt     {
    191      1.1      matt       bfd_vma value;
    192      1.1      matt 
    193      1.1      matt       *strp += 9;
    194      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex,
    195      1.1      matt 				   BFD_RELOC_OR1K_GOTOFF_HI16,
    196      1.1      matt 				   & result_type, & value);
    197      1.1      matt 
    198      1.1      matt       if (**strp != ')')
    199      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    200      1.1      matt       ++*strp;
    201      1.1      matt       if (errmsg == NULL
    202      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    203      1.1      matt 	value = (value >> 16) & 0xffff;
    204      1.1      matt       *valuep = value;
    205      1.1      matt       return errmsg;
    206      1.1      matt     }
    207      1.1      matt   else if (strncasecmp (*strp, "gotofflo(", 9) == 0)
    208      1.1      matt     {
    209      1.1      matt       bfd_vma value;
    210      1.1      matt 
    211      1.1      matt       *strp += 9;
    212      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex,
    213      1.1      matt 				   BFD_RELOC_OR1K_GOTOFF_LO16,
    214      1.1      matt 				   &result_type, &value);
    215      1.1      matt       if (**strp != ')')
    216      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    217      1.1      matt       ++*strp;
    218      1.1      matt       if (errmsg == NULL
    219      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    220      1.1      matt 	value &= 0xffff;
    221      1.1      matt       *valuep = value;
    222      1.1      matt       return errmsg;
    223      1.1      matt     }
    224      1.1      matt   else if (strncasecmp (*strp, "tlsgdhi(", 8) == 0)
    225      1.1      matt     {
    226      1.1      matt       bfd_vma value;
    227      1.1      matt 
    228      1.1      matt       *strp += 8;
    229      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex,
    230      1.1      matt 				   BFD_RELOC_OR1K_TLS_GD_HI16,
    231      1.1      matt 				   & result_type, & value);
    232      1.1      matt 
    233      1.1      matt       if (**strp != ')')
    234      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    235      1.1      matt       ++*strp;
    236      1.1      matt       if (errmsg == NULL
    237      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    238      1.1      matt 	value = (value >> 16) & 0xffff;
    239      1.1      matt       *valuep = value;
    240      1.1      matt       return errmsg;
    241      1.1      matt     }
    242      1.1      matt   else if (strncasecmp (*strp, "tlsgdlo(", 8) == 0)
    243      1.1      matt     {
    244      1.1      matt       bfd_vma value;
    245      1.1      matt 
    246      1.1      matt       *strp += 8;
    247      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex,
    248      1.1      matt 				   BFD_RELOC_OR1K_TLS_GD_LO16,
    249      1.1      matt 				   &result_type, &value);
    250      1.1      matt       if (**strp != ')')
    251      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    252      1.1      matt       ++*strp;
    253      1.1      matt       if (errmsg == NULL
    254      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    255      1.1      matt 	value &= 0xffff;
    256      1.1      matt       *valuep = value;
    257      1.1      matt       return errmsg;
    258      1.1      matt     }
    259      1.1      matt   else if (strncasecmp (*strp, "tlsldmhi(", 9) == 0)
    260      1.1      matt     {
    261      1.1      matt       bfd_vma value;
    262      1.1      matt 
    263      1.1      matt       *strp += 9;
    264      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex,
    265      1.1      matt 				   BFD_RELOC_OR1K_TLS_LDM_HI16,
    266      1.1      matt 				   & result_type, & value);
    267      1.1      matt 
    268      1.1      matt       if (**strp != ')')
    269      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    270      1.1      matt       ++*strp;
    271      1.1      matt       if (errmsg == NULL
    272      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    273      1.1      matt 	value = (value >> 16) & 0xffff;
    274      1.1      matt       *valuep = value;
    275      1.1      matt       return errmsg;
    276      1.1      matt     }
    277      1.1      matt   else if (strncasecmp (*strp, "tlsldmlo(", 9) == 0)
    278      1.1      matt     {
    279      1.1      matt       bfd_vma value;
    280      1.1      matt 
    281      1.1      matt       *strp += 9;
    282      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex,
    283      1.1      matt 				   BFD_RELOC_OR1K_TLS_LDM_LO16,
    284      1.1      matt 				   &result_type, &value);
    285      1.1      matt       if (**strp != ')')
    286      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    287      1.1      matt       ++*strp;
    288      1.1      matt       if (errmsg == NULL
    289      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    290      1.1      matt 	value &= 0xffff;
    291      1.1      matt       *valuep = value;
    292      1.1      matt       return errmsg;
    293      1.1      matt     }
    294      1.1      matt   else if (strncasecmp (*strp, "dtpoffhi(", 9) == 0)
    295      1.1      matt     {
    296      1.1      matt       bfd_vma value;
    297      1.1      matt 
    298      1.1      matt       *strp += 9;
    299      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex,
    300      1.1      matt 				   BFD_RELOC_OR1K_TLS_LDO_HI16,
    301      1.1      matt 				   & result_type, & value);
    302      1.1      matt 
    303      1.1      matt       if (**strp != ')')
    304      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    305      1.1      matt       ++*strp;
    306      1.1      matt       if (errmsg == NULL
    307      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    308      1.1      matt 	value = (value >> 16) & 0xffff;
    309      1.1      matt       *valuep = value;
    310      1.1      matt       return errmsg;
    311      1.1      matt     }
    312      1.1      matt   else if (strncasecmp (*strp, "dtpofflo(", 9) == 0)
    313      1.1      matt     {
    314      1.1      matt       bfd_vma value;
    315      1.1      matt 
    316      1.1      matt       *strp += 9;
    317      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex,
    318      1.1      matt 				   BFD_RELOC_OR1K_TLS_LDO_LO16,
    319      1.1      matt 				   &result_type, &value);
    320      1.1      matt       if (**strp != ')')
    321      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    322      1.1      matt       ++*strp;
    323      1.1      matt       if (errmsg == NULL
    324      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    325      1.1      matt 	value &= 0xffff;
    326      1.1      matt       *valuep = value;
    327      1.1      matt       return errmsg;
    328      1.1      matt     }
    329      1.1      matt   else if (strncasecmp (*strp, "gottpoffhi(", 11) == 0)
    330      1.1      matt     {
    331      1.1      matt       bfd_vma value;
    332      1.1      matt 
    333      1.1      matt       *strp += 11;
    334      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex,
    335      1.1      matt 				   BFD_RELOC_OR1K_TLS_IE_HI16,
    336      1.1      matt 				   & result_type, & value);
    337      1.1      matt 
    338      1.1      matt       if (**strp != ')')
    339      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    340      1.1      matt       ++*strp;
    341      1.1      matt       if (errmsg == NULL
    342      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    343      1.1      matt 	value = (value >> 16) & 0xffff;
    344      1.1      matt       *valuep = value;
    345      1.1      matt       return errmsg;
    346      1.1      matt     }
    347      1.1      matt   else if (strncasecmp (*strp, "gottpofflo(", 11) == 0)
    348      1.1      matt     {
    349      1.1      matt       bfd_vma value;
    350      1.1      matt 
    351      1.1      matt       *strp += 11;
    352      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex,
    353      1.1      matt 				   BFD_RELOC_OR1K_TLS_IE_LO16,
    354      1.1      matt 				   &result_type, &value);
    355      1.1      matt       if (**strp != ')')
    356      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    357      1.1      matt       ++*strp;
    358      1.1      matt       if (errmsg == NULL
    359      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    360      1.1      matt 	value &= 0xffff;
    361      1.1      matt       *valuep = value;
    362      1.1      matt       return errmsg;
    363      1.1      matt     }
    364      1.1      matt   else if (strncasecmp (*strp, "tpoffhi(", 8) == 0)
    365      1.1      matt     {
    366      1.1      matt       bfd_vma value;
    367      1.1      matt 
    368      1.1      matt       *strp += 8;
    369      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex,
    370      1.1      matt 				   BFD_RELOC_OR1K_TLS_LE_HI16,
    371      1.1      matt 				   & result_type, & value);
    372      1.1      matt 
    373      1.1      matt       if (**strp != ')')
    374      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    375      1.1      matt       ++*strp;
    376      1.1      matt       if (errmsg == NULL
    377      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    378      1.1      matt 	value = (value >> 16) & 0xffff;
    379      1.1      matt       *valuep = value;
    380      1.1      matt       return errmsg;
    381      1.1      matt     }
    382      1.1      matt   else if (strncasecmp (*strp, "tpofflo(", 8) == 0)
    383      1.1      matt     {
    384      1.1      matt       bfd_vma value;
    385      1.1      matt 
    386      1.1      matt       *strp += 8;
    387      1.1      matt       errmsg = cgen_parse_address (cd, strp, opindex,
    388      1.1      matt 				   BFD_RELOC_OR1K_TLS_LE_LO16,
    389      1.1      matt 				   &result_type, &value);
    390      1.1      matt       if (**strp != ')')
    391      1.1      matt 	return MISSING_CLOSING_PARENTHESIS;
    392      1.1      matt       ++*strp;
    393      1.1      matt       if (errmsg == NULL
    394      1.1      matt 	  && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    395      1.1      matt 	value &= 0xffff;
    396      1.1      matt       *valuep = value;
    397      1.1      matt       return errmsg;
    398      1.1      matt     }
    399      1.1      matt   else
    400      1.1      matt     {
    401      1.1      matt       long value;
    402      1.1      matt       errmsg = cgen_parse_signed_integer (cd, strp, opindex, &value);
    403      1.1      matt       ret = value;
    404      1.1      matt     }
    405      1.1      matt 
    406      1.1      matt   if (errmsg == NULL)
    407      1.1      matt     *valuep = ret;
    408      1.1      matt 
    409      1.1      matt   return errmsg;
    410      1.1      matt }
    411      1.1      matt 
    412      1.1      matt static const char *
    413      1.1      matt parse_uimm16 (CGEN_CPU_DESC cd, const char ** strp, int opindex, unsigned long * valuep)
    414      1.1      matt {
    415      1.1      matt   const char *errmsg = parse_simm16(cd, strp, opindex, (long *) valuep);
    416      1.1      matt 
    417      1.1      matt   if (errmsg == NULL)
    418      1.1      matt     *valuep &= 0xffff;
    419      1.1      matt   return errmsg;
    420      1.1      matt }
    421      1.1      matt 
    422      1.1      matt /* -- */
    423      1.1      matt 
    424      1.1      matt const char * or1k_cgen_parse_operand
    425      1.1      matt   (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
    426      1.1      matt 
    427      1.1      matt /* Main entry point for operand parsing.
    428      1.1      matt 
    429      1.1      matt    This function is basically just a big switch statement.  Earlier versions
    430      1.1      matt    used tables to look up the function to use, but
    431      1.1      matt    - if the table contains both assembler and disassembler functions then
    432      1.1      matt      the disassembler contains much of the assembler and vice-versa,
    433      1.1      matt    - there's a lot of inlining possibilities as things grow,
    434      1.1      matt    - using a switch statement avoids the function call overhead.
    435      1.1      matt 
    436      1.1      matt    This function could be moved into `parse_insn_normal', but keeping it
    437      1.1      matt    separate makes clear the interface between `parse_insn_normal' and each of
    438      1.1      matt    the handlers.  */
    439      1.1      matt 
    440      1.1      matt const char *
    441      1.1      matt or1k_cgen_parse_operand (CGEN_CPU_DESC cd,
    442      1.1      matt 			   int opindex,
    443      1.1      matt 			   const char ** strp,
    444      1.1      matt 			   CGEN_FIELDS * fields)
    445      1.1      matt {
    446      1.1      matt   const char * errmsg = NULL;
    447      1.1      matt   /* Used by scalar operands that still need to be parsed.  */
    448      1.1      matt   long junk ATTRIBUTE_UNUSED;
    449      1.1      matt 
    450      1.1      matt   switch (opindex)
    451      1.1      matt     {
    452      1.1      matt     case OR1K_OPERAND_DISP26 :
    453      1.1      matt       {
    454      1.1      matt         bfd_vma value = 0;
    455      1.1      matt         errmsg = parse_disp26 (cd, strp, OR1K_OPERAND_DISP26, 0, NULL,  & value);
    456      1.1      matt         fields->f_disp26 = value;
    457      1.1      matt       }
    458      1.1      matt       break;
    459      1.1      matt     case OR1K_OPERAND_RA :
    460      1.1      matt       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_gpr, & fields->f_r2);
    461      1.1      matt       break;
    462      1.1      matt     case OR1K_OPERAND_RADF :
    463      1.1      matt       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fdr, & fields->f_r1);
    464      1.1      matt       break;
    465      1.1      matt     case OR1K_OPERAND_RASF :
    466      1.1      matt       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fsr, & fields->f_r2);
    467      1.1      matt       break;
    468      1.1      matt     case OR1K_OPERAND_RB :
    469      1.1      matt       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_gpr, & fields->f_r3);
    470      1.1      matt       break;
    471      1.1      matt     case OR1K_OPERAND_RBDF :
    472      1.1      matt       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fdr, & fields->f_r1);
    473      1.1      matt       break;
    474      1.1      matt     case OR1K_OPERAND_RBSF :
    475      1.1      matt       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fsr, & fields->f_r3);
    476      1.1      matt       break;
    477      1.1      matt     case OR1K_OPERAND_RD :
    478      1.1      matt       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_gpr, & fields->f_r1);
    479      1.1      matt       break;
    480      1.1      matt     case OR1K_OPERAND_RDDF :
    481      1.1      matt       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fdr, & fields->f_r1);
    482      1.1      matt       break;
    483      1.1      matt     case OR1K_OPERAND_RDSF :
    484      1.1      matt       errmsg = cgen_parse_keyword (cd, strp, & or1k_cgen_opval_h_fsr, & fields->f_r1);
    485      1.1      matt       break;
    486      1.1      matt     case OR1K_OPERAND_SIMM16 :
    487      1.1      matt       errmsg = parse_simm16 (cd, strp, OR1K_OPERAND_SIMM16, (long *) (& fields->f_simm16));
    488      1.1      matt       break;
    489      1.1      matt     case OR1K_OPERAND_SIMM16_SPLIT :
    490      1.1      matt       errmsg = parse_simm16 (cd, strp, OR1K_OPERAND_SIMM16_SPLIT, (long *) (& fields->f_simm16_split));
    491      1.1      matt       break;
    492      1.1      matt     case OR1K_OPERAND_UIMM16 :
    493      1.1      matt       errmsg = parse_uimm16 (cd, strp, OR1K_OPERAND_UIMM16, (unsigned long *) (& fields->f_uimm16));
    494      1.1      matt       break;
    495      1.1      matt     case OR1K_OPERAND_UIMM16_SPLIT :
    496      1.1      matt       errmsg = parse_uimm16 (cd, strp, OR1K_OPERAND_UIMM16_SPLIT, (unsigned long *) (& fields->f_uimm16_split));
    497      1.1      matt       break;
    498      1.1      matt     case OR1K_OPERAND_UIMM6 :
    499      1.1      matt       errmsg = cgen_parse_unsigned_integer (cd, strp, OR1K_OPERAND_UIMM6, (unsigned long *) (& fields->f_uimm6));
    500      1.1      matt       break;
    501      1.1      matt 
    502      1.1      matt     default :
    503  1.1.1.4  christos       /* xgettext:c-format */
    504  1.1.1.4  christos       opcodes_error_handler
    505  1.1.1.4  christos 	(_("internal error: unrecognized field %d while parsing"),
    506      1.1      matt 	 opindex);
    507      1.1      matt       abort ();
    508      1.1      matt   }
    509      1.1      matt 
    510      1.1      matt   return errmsg;
    511      1.1      matt }
    512  1.1.1.1  christos 
    513      1.1      matt cgen_parse_fn * const or1k_cgen_parse_handlers[] =
    514      1.1      matt {
    515      1.1      matt   parse_insn_normal,
    516      1.1      matt };
    517      1.1      matt 
    518      1.1      matt void
    519      1.1      matt or1k_cgen_init_asm (CGEN_CPU_DESC cd)
    520      1.1      matt {
    521      1.1      matt   or1k_cgen_init_opcode_table (cd);
    522      1.1      matt   or1k_cgen_init_ibld_table (cd);
    523      1.1      matt   cd->parse_handlers = & or1k_cgen_parse_handlers[0];
    524      1.1      matt   cd->parse_operand = or1k_cgen_parse_operand;
    525      1.1      matt #ifdef CGEN_ASM_INIT_HOOK
    526      1.1      matt CGEN_ASM_INIT_HOOK
    527      1.1      matt #endif
    528      1.1      matt }
    529      1.1      matt 
    530      1.1      matt 
    531      1.1      matt 
    533      1.1      matt /* Regex construction routine.
    534      1.1      matt 
    535      1.1      matt    This translates an opcode syntax string into a regex string,
    536      1.1      matt    by replacing any non-character syntax element (such as an
    537      1.1      matt    opcode) with the pattern '.*'
    538      1.1      matt 
    539      1.1      matt    It then compiles the regex and stores it in the opcode, for
    540      1.1      matt    later use by or1k_cgen_assemble_insn
    541      1.1      matt 
    542  1.1.1.1  christos    Returns NULL for success, an error message for failure.  */
    543      1.1      matt 
    544  1.1.1.1  christos char *
    545      1.1      matt or1k_cgen_build_insn_regex (CGEN_INSN *insn)
    546      1.1      matt {
    547      1.1      matt   CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
    548      1.1      matt   const char *mnem = CGEN_INSN_MNEMONIC (insn);
    549      1.1      matt   char rxbuf[CGEN_MAX_RX_ELEMENTS];
    550      1.1      matt   char *rx = rxbuf;
    551      1.1      matt   const CGEN_SYNTAX_CHAR_TYPE *syn;
    552      1.1      matt   int reg_err;
    553      1.1      matt 
    554      1.1      matt   syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
    555      1.1      matt 
    556      1.1      matt   /* Mnemonics come first in the syntax string.  */
    557      1.1      matt   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
    558      1.1      matt     return _("missing mnemonic in syntax string");
    559      1.1      matt   ++syn;
    560      1.1      matt 
    561      1.1      matt   /* Generate a case sensitive regular expression that emulates case
    562      1.1      matt      insensitive matching in the "C" locale.  We cannot generate a case
    563      1.1      matt      insensitive regular expression because in Turkish locales, 'i' and 'I'
    564      1.1      matt      are not equal modulo case conversion.  */
    565      1.1      matt 
    566      1.1      matt   /* Copy the literal mnemonic out of the insn.  */
    567      1.1      matt   for (; *mnem; mnem++)
    568      1.1      matt     {
    569      1.1      matt       char c = *mnem;
    570      1.1      matt 
    571      1.1      matt       if (ISALPHA (c))
    572      1.1      matt 	{
    573      1.1      matt 	  *rx++ = '[';
    574      1.1      matt 	  *rx++ = TOLOWER (c);
    575      1.1      matt 	  *rx++ = TOUPPER (c);
    576      1.1      matt 	  *rx++ = ']';
    577      1.1      matt 	}
    578      1.1      matt       else
    579      1.1      matt 	*rx++ = c;
    580      1.1      matt     }
    581      1.1      matt 
    582      1.1      matt   /* Copy any remaining literals from the syntax string into the rx.  */
    583  1.1.1.1  christos   for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
    584      1.1      matt     {
    585      1.1      matt       if (CGEN_SYNTAX_CHAR_P (* syn))
    586      1.1      matt 	{
    587  1.1.1.1  christos 	  char c = CGEN_SYNTAX_CHAR (* syn);
    588      1.1      matt 
    589      1.1      matt 	  switch (c)
    590  1.1.1.1  christos 	    {
    591  1.1.1.1  christos 	      /* Escape any regex metacharacters in the syntax.  */
    592      1.1      matt 	    case '.': case '[': case '\\':
    593      1.1      matt 	    case '*': case '^': case '$':
    594  1.1.1.1  christos 
    595      1.1      matt #ifdef CGEN_ESCAPE_EXTENDED_REGEX
    596      1.1      matt 	    case '?': case '{': case '}':
    597      1.1      matt 	    case '(': case ')': case '*':
    598      1.1      matt 	    case '|': case '+': case ']':
    599      1.1      matt #endif
    600      1.1      matt 	      *rx++ = '\\';
    601      1.1      matt 	      *rx++ = c;
    602      1.1      matt 	      break;
    603      1.1      matt 
    604      1.1      matt 	    default:
    605      1.1      matt 	      if (ISALPHA (c))
    606      1.1      matt 		{
    607      1.1      matt 		  *rx++ = '[';
    608      1.1      matt 		  *rx++ = TOLOWER (c);
    609      1.1      matt 		  *rx++ = TOUPPER (c);
    610      1.1      matt 		  *rx++ = ']';
    611      1.1      matt 		}
    612      1.1      matt 	      else
    613      1.1      matt 		*rx++ = c;
    614      1.1      matt 	      break;
    615      1.1      matt 	    }
    616      1.1      matt 	}
    617      1.1      matt       else
    618      1.1      matt 	{
    619      1.1      matt 	  /* Replace non-syntax fields with globs.  */
    620      1.1      matt 	  *rx++ = '.';
    621      1.1      matt 	  *rx++ = '*';
    622      1.1      matt 	}
    623      1.1      matt     }
    624  1.1.1.1  christos 
    625  1.1.1.1  christos   /* Trailing whitespace ok.  */
    626  1.1.1.1  christos   * rx++ = '[';
    627  1.1.1.1  christos   * rx++ = ' ';
    628  1.1.1.1  christos   * rx++ = '\t';
    629      1.1      matt   * rx++ = ']';
    630      1.1      matt   * rx++ = '*';
    631  1.1.1.1  christos 
    632      1.1      matt   /* But anchor it after that.  */
    633      1.1      matt   * rx++ = '$';
    634      1.1      matt   * rx = '\0';
    635      1.1      matt 
    636      1.1      matt   CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
    637  1.1.1.1  christos   reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
    638      1.1      matt 
    639      1.1      matt   if (reg_err == 0)
    640      1.1      matt     return NULL;
    641      1.1      matt   else
    642      1.1      matt     {
    643      1.1      matt       static char msg[80];
    644      1.1      matt 
    645      1.1      matt       regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
    646      1.1      matt       regfree ((regex_t *) CGEN_INSN_RX (insn));
    647      1.1      matt       free (CGEN_INSN_RX (insn));
    648      1.1      matt       (CGEN_INSN_RX (insn)) = NULL;
    649      1.1      matt       return msg;
    650      1.1      matt     }
    651      1.1      matt }
    652      1.1      matt 
    653      1.1      matt 
    654      1.1      matt /* Default insn parser.
    656      1.1      matt 
    657      1.1      matt    The syntax string is scanned and operands are parsed and stored in FIELDS.
    658      1.1      matt    Relocs are queued as we go via other callbacks.
    659      1.1      matt 
    660      1.1      matt    ??? Note that this is currently an all-or-nothing parser.  If we fail to
    661      1.1      matt    parse the instruction, we return 0 and the caller will start over from
    662      1.1      matt    the beginning.  Backtracking will be necessary in parsing subexpressions,
    663      1.1      matt    but that can be handled there.  Not handling backtracking here may get
    664      1.1      matt    expensive in the case of the m68k.  Deal with later.
    665      1.1      matt 
    666      1.1      matt    Returns NULL for success, an error message for failure.  */
    667      1.1      matt 
    668      1.1      matt static const char *
    669      1.1      matt parse_insn_normal (CGEN_CPU_DESC cd,
    670      1.1      matt 		   const CGEN_INSN *insn,
    671      1.1      matt 		   const char **strp,
    672      1.1      matt 		   CGEN_FIELDS *fields)
    673      1.1      matt {
    674      1.1      matt   /* ??? Runtime added insns not handled yet.  */
    675      1.1      matt   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
    676      1.1      matt   const char *str = *strp;
    677      1.1      matt   const char *errmsg;
    678      1.1      matt   const char *p;
    679      1.1      matt   const CGEN_SYNTAX_CHAR_TYPE * syn;
    680      1.1      matt #ifdef CGEN_MNEMONIC_OPERANDS
    681      1.1      matt   /* FIXME: wip */
    682      1.1      matt   int past_opcode_p;
    683      1.1      matt #endif
    684      1.1      matt 
    685      1.1      matt   /* For now we assume the mnemonic is first (there are no leading operands).
    686      1.1      matt      We can parse it without needing to set up operand parsing.
    687      1.1      matt      GAS's input scrubber will ensure mnemonics are lowercase, but we may
    688      1.1      matt      not be called from GAS.  */
    689      1.1      matt   p = CGEN_INSN_MNEMONIC (insn);
    690      1.1      matt   while (*p && TOLOWER (*p) == TOLOWER (*str))
    691      1.1      matt     ++p, ++str;
    692      1.1      matt 
    693      1.1      matt   if (* p)
    694      1.1      matt     return _("unrecognized instruction");
    695      1.1      matt 
    696      1.1      matt #ifndef CGEN_MNEMONIC_OPERANDS
    697      1.1      matt   if (* str && ! ISSPACE (* str))
    698      1.1      matt     return _("unrecognized instruction");
    699      1.1      matt #endif
    700      1.1      matt 
    701      1.1      matt   CGEN_INIT_PARSE (cd);
    702      1.1      matt   cgen_init_parse_operand (cd);
    703      1.1      matt #ifdef CGEN_MNEMONIC_OPERANDS
    704      1.1      matt   past_opcode_p = 0;
    705      1.1      matt #endif
    706      1.1      matt 
    707      1.1      matt   /* We don't check for (*str != '\0') here because we want to parse
    708      1.1      matt      any trailing fake arguments in the syntax string.  */
    709      1.1      matt   syn = CGEN_SYNTAX_STRING (syntax);
    710      1.1      matt 
    711      1.1      matt   /* Mnemonics come first for now, ensure valid string.  */
    712      1.1      matt   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
    713      1.1      matt     abort ();
    714      1.1      matt 
    715      1.1      matt   ++syn;
    716      1.1      matt 
    717      1.1      matt   while (* syn != 0)
    718      1.1      matt     {
    719      1.1      matt       /* Non operand chars must match exactly.  */
    720      1.1      matt       if (CGEN_SYNTAX_CHAR_P (* syn))
    721      1.1      matt 	{
    722      1.1      matt 	  /* FIXME: While we allow for non-GAS callers above, we assume the
    723      1.1      matt 	     first char after the mnemonic part is a space.  */
    724      1.1      matt 	  /* FIXME: We also take inappropriate advantage of the fact that
    725      1.1      matt 	     GAS's input scrubber will remove extraneous blanks.  */
    726      1.1      matt 	  if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
    727      1.1      matt 	    {
    728      1.1      matt #ifdef CGEN_MNEMONIC_OPERANDS
    729      1.1      matt 	      if (CGEN_SYNTAX_CHAR(* syn) == ' ')
    730      1.1      matt 		past_opcode_p = 1;
    731      1.1      matt #endif
    732      1.1      matt 	      ++ syn;
    733      1.1      matt 	      ++ str;
    734      1.1      matt 	    }
    735      1.1      matt 	  else if (*str)
    736      1.1      matt 	    {
    737      1.1      matt 	      /* Syntax char didn't match.  Can't be this insn.  */
    738      1.1      matt 	      static char msg [80];
    739      1.1      matt 
    740      1.1      matt 	      /* xgettext:c-format */
    741      1.1      matt 	      sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
    742      1.1      matt 		       CGEN_SYNTAX_CHAR(*syn), *str);
    743      1.1      matt 	      return msg;
    744      1.1      matt 	    }
    745      1.1      matt 	  else
    746      1.1      matt 	    {
    747      1.1      matt 	      /* Ran out of input.  */
    748      1.1      matt 	      static char msg [80];
    749      1.1      matt 
    750      1.1      matt 	      /* xgettext:c-format */
    751      1.1      matt 	      sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
    752      1.1      matt 		       CGEN_SYNTAX_CHAR(*syn));
    753      1.1      matt 	      return msg;
    754      1.1      matt 	    }
    755      1.1      matt 	  continue;
    756      1.1      matt 	}
    757      1.1      matt 
    758      1.1      matt #ifdef CGEN_MNEMONIC_OPERANDS
    759      1.1      matt       (void) past_opcode_p;
    760      1.1      matt #endif
    761      1.1      matt       /* We have an operand of some sort.  */
    762      1.1      matt       errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
    763      1.1      matt       if (errmsg)
    764      1.1      matt 	return errmsg;
    765      1.1      matt 
    766      1.1      matt       /* Done with this operand, continue with next one.  */
    767      1.1      matt       ++ syn;
    768      1.1      matt     }
    769      1.1      matt 
    770      1.1      matt   /* If we're at the end of the syntax string, we're done.  */
    771      1.1      matt   if (* syn == 0)
    772      1.1      matt     {
    773      1.1      matt       /* FIXME: For the moment we assume a valid `str' can only contain
    774      1.1      matt 	 blanks now.  IE: We needn't try again with a longer version of
    775      1.1      matt 	 the insn and it is assumed that longer versions of insns appear
    776      1.1      matt 	 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
    777      1.1      matt       while (ISSPACE (* str))
    778      1.1      matt 	++ str;
    779      1.1      matt 
    780      1.1      matt       if (* str != '\0')
    781      1.1      matt 	return _("junk at end of line"); /* FIXME: would like to include `str' */
    782      1.1      matt 
    783      1.1      matt       return NULL;
    784      1.1      matt     }
    785      1.1      matt 
    786      1.1      matt   /* We couldn't parse it.  */
    787      1.1      matt   return _("unrecognized instruction");
    788      1.1      matt }
    789      1.1      matt 
    790      1.1      matt /* Main entry point.
    792      1.1      matt    This routine is called for each instruction to be assembled.
    793      1.1      matt    STR points to the insn to be assembled.
    794      1.1      matt    We assume all necessary tables have been initialized.
    795      1.1      matt    The assembled instruction, less any fixups, is stored in BUF.
    796      1.1      matt    Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
    797      1.1      matt    still needs to be converted to target byte order, otherwise BUF is an array
    798      1.1      matt    of bytes in target byte order.
    799      1.1      matt    The result is a pointer to the insn's entry in the opcode table,
    800      1.1      matt    or NULL if an error occured (an error message will have already been
    801      1.1      matt    printed).
    802      1.1      matt 
    803      1.1      matt    Note that when processing (non-alias) macro-insns,
    804      1.1      matt    this function recurses.
    805      1.1      matt 
    806      1.1      matt    ??? It's possible to make this cpu-independent.
    807      1.1      matt    One would have to deal with a few minor things.
    808      1.1      matt    At this point in time doing so would be more of a curiosity than useful
    809      1.1      matt    [for example this file isn't _that_ big], but keeping the possibility in
    810      1.1      matt    mind helps keep the design clean.  */
    811      1.1      matt 
    812      1.1      matt const CGEN_INSN *
    813      1.1      matt or1k_cgen_assemble_insn (CGEN_CPU_DESC cd,
    814      1.1      matt 			   const char *str,
    815      1.1      matt 			   CGEN_FIELDS *fields,
    816      1.1      matt 			   CGEN_INSN_BYTES_PTR buf,
    817      1.1      matt 			   char **errmsg)
    818      1.1      matt {
    819      1.1      matt   const char *start;
    820      1.1      matt   CGEN_INSN_LIST *ilist;
    821      1.1      matt   const char *parse_errmsg = NULL;
    822      1.1      matt   const char *insert_errmsg = NULL;
    823      1.1      matt   int recognized_mnemonic = 0;
    824      1.1      matt 
    825      1.1      matt   /* Skip leading white space.  */
    826      1.1      matt   while (ISSPACE (* str))
    827      1.1      matt     ++ str;
    828      1.1      matt 
    829      1.1      matt   /* The instructions are stored in hashed lists.
    830      1.1      matt      Get the first in the list.  */
    831      1.1      matt   ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
    832      1.1      matt 
    833      1.1      matt   /* Keep looking until we find a match.  */
    834      1.1      matt   start = str;
    835      1.1      matt   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
    836  1.1.1.1  christos     {
    837      1.1      matt       const CGEN_INSN *insn = ilist->insn;
    838      1.1      matt       recognized_mnemonic = 1;
    839      1.1      matt 
    840      1.1      matt #ifdef CGEN_VALIDATE_INSN_SUPPORTED
    841      1.1      matt       /* Not usually needed as unsupported opcodes
    842      1.1      matt 	 shouldn't be in the hash lists.  */
    843      1.1      matt       /* Is this insn supported by the selected cpu?  */
    844      1.1      matt       if (! or1k_cgen_insn_supported (cd, insn))
    845      1.1      matt 	continue;
    846      1.1      matt #endif
    847      1.1      matt       /* If the RELAXED attribute is set, this is an insn that shouldn't be
    848      1.1      matt 	 chosen immediately.  Instead, it is used during assembler/linker
    849      1.1      matt 	 relaxation if possible.  */
    850      1.1      matt       if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
    851      1.1      matt 	continue;
    852      1.1      matt 
    853      1.1      matt       str = start;
    854      1.1      matt 
    855      1.1      matt       /* Skip this insn if str doesn't look right lexically.  */
    856      1.1      matt       if (CGEN_INSN_RX (insn) != NULL &&
    857      1.1      matt 	  regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
    858      1.1      matt 	continue;
    859      1.1      matt 
    860      1.1      matt       /* Allow parse/insert handlers to obtain length of insn.  */
    861      1.1      matt       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
    862      1.1      matt 
    863      1.1      matt       parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
    864      1.1      matt       if (parse_errmsg != NULL)
    865      1.1      matt 	continue;
    866      1.1      matt 
    867      1.1      matt       /* ??? 0 is passed for `pc'.  */
    868      1.1      matt       insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
    869      1.1      matt 						 (bfd_vma) 0);
    870      1.1      matt       if (insert_errmsg != NULL)
    871      1.1      matt         continue;
    872      1.1      matt 
    873      1.1      matt       /* It is up to the caller to actually output the insn and any
    874      1.1      matt          queued relocs.  */
    875      1.1      matt       return insn;
    876      1.1      matt     }
    877      1.1      matt 
    878      1.1      matt   {
    879      1.1      matt     static char errbuf[150];
    880      1.1      matt     const char *tmp_errmsg;
    881      1.1      matt #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
    882      1.1      matt #define be_verbose 1
    883      1.1      matt #else
    884      1.1      matt #define be_verbose 0
    885      1.1      matt #endif
    886      1.1      matt 
    887      1.1      matt     if (be_verbose)
    888      1.1      matt       {
    889      1.1      matt 	/* If requesting verbose error messages, use insert_errmsg.
    890      1.1      matt 	   Failing that, use parse_errmsg.  */
    891      1.1      matt 	tmp_errmsg = (insert_errmsg ? insert_errmsg :
    892      1.1      matt 		      parse_errmsg ? parse_errmsg :
    893      1.1      matt 		      recognized_mnemonic ?
    894      1.1      matt 		      _("unrecognized form of instruction") :
    895      1.1      matt 		      _("unrecognized instruction"));
    896  1.1.1.1  christos 
    897      1.1      matt 	if (strlen (start) > 50)
    898      1.1      matt 	  /* xgettext:c-format */
    899      1.1      matt 	  sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
    900      1.1      matt 	else
    901      1.1      matt 	  /* xgettext:c-format */
    902      1.1      matt 	  sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
    903      1.1      matt       }
    904      1.1      matt     else
    905  1.1.1.1  christos       {
    906      1.1      matt 	if (strlen (start) > 50)
    907      1.1      matt 	  /* xgettext:c-format */
    908      1.1      matt 	  sprintf (errbuf, _("bad instruction `%.50s...'"), start);
    909  1.1.1.1  christos 	else
    910      1.1      matt 	  /* xgettext:c-format */
    911      1.1      matt 	  sprintf (errbuf, _("bad instruction `%.50s'"), start);
    912      1.1      matt       }
    913      1.1      matt 
    914                        *errmsg = errbuf;
    915                        return NULL;
    916                      }
    917                    }
    918