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