Home | History | Annotate | Download | only in opcodes
      1 /* Assembler interface for targets using CGEN. -*- C -*-
      2    CGEN: Cpu tools GENerator
      3 
      4    THIS FILE IS MACHINE GENERATED WITH CGEN.
      5    - the resultant file is machine generated, cgen-asm.in isn't
      6 
      7    Copyright (C) 1996-2014 Free Software Foundation, Inc.
      8 
      9    This file is part of libopcodes.
     10 
     11    This library is free software; you can redistribute it and/or modify
     12    it under the terms of the GNU General Public License as published by
     13    the Free Software Foundation; either version 3, or (at your option)
     14    any later version.
     15 
     16    It is distributed in the hope that it will be useful, but WITHOUT
     17    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     18    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     19    License for more details.
     20 
     21    You should have received a copy of the GNU General Public License
     22    along with this program; if not, write to the Free Software Foundation, Inc.,
     23    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
     24 
     25 
     26 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
     27    Keep that in mind.  */
     28 
     29 #include "sysdep.h"
     30 #include <stdio.h>
     31 #include "ansidecl.h"
     32 #include "bfd.h"
     33 #include "symcat.h"
     34 #include "frv-desc.h"
     35 #include "frv-opc.h"
     36 #include "opintl.h"
     37 #include "xregex.h"
     38 #include "libiberty.h"
     39 #include "safe-ctype.h"
     40 
     41 #undef  min
     42 #define min(a,b) ((a) < (b) ? (a) : (b))
     43 #undef  max
     44 #define max(a,b) ((a) > (b) ? (a) : (b))
     45 
     46 static const char * parse_insn_normal
     47   (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *);
     48 
     49 /* -- assembler routines inserted here.  */
     51 
     52 /* -- asm.c */
     53 inline static const char *
     54 parse_symbolic_address (CGEN_CPU_DESC cd,
     55 			const char **strp,
     56 			int opindex,
     57 			int opinfo,
     58 			enum cgen_parse_operand_result *resultp,
     59 			bfd_vma *valuep)
     60 {
     61   enum cgen_parse_operand_result result_type;
     62   const char *errmsg = (* cd->parse_operand_fn)
     63     (cd, CGEN_PARSE_OPERAND_SYMBOLIC, strp, opindex, opinfo,
     64      &result_type, valuep);
     65 
     66   if (errmsg == NULL
     67       && result_type != CGEN_PARSE_OPERAND_RESULT_QUEUED)
     68     return "symbolic expression required";
     69 
     70   if (resultp)
     71     *resultp = result_type;
     72 
     73   return errmsg;
     74 }
     75 
     76 static const char *
     77 parse_ldd_annotation (CGEN_CPU_DESC cd,
     78 		      const char **strp,
     79 		      int opindex,
     80 		      unsigned long *valuep)
     81 {
     82   const char *errmsg;
     83   enum cgen_parse_operand_result result_type;
     84   bfd_vma value;
     85 
     86   if (**strp == '#' || **strp == '%')
     87     {
     88       if (strncasecmp (*strp + 1, "tlsdesc(", 8) == 0)
     89 	{
     90 	  *strp += 9;
     91 	  errmsg = parse_symbolic_address (cd, strp, opindex,
     92 					   BFD_RELOC_FRV_TLSDESC_RELAX,
     93 					   &result_type, &value);
     94 	  if (**strp != ')')
     95 	    return "missing ')'";
     96 	  if (valuep)
     97 	    *valuep = value;
     98 	  ++*strp;
     99 	  if (errmsg)
    100 	    return errmsg;
    101 	}
    102     }
    103 
    104   while (**strp == ' ' || **strp == '\t')
    105     ++*strp;
    106 
    107   if (**strp != '@')
    108     return "missing `@'";
    109 
    110   ++*strp;
    111 
    112   return NULL;
    113 }
    114 
    115 static const char *
    116 parse_call_annotation (CGEN_CPU_DESC cd,
    117 		       const char **strp,
    118 		       int opindex,
    119 		       unsigned long *valuep)
    120 {
    121   const char *errmsg;
    122   enum cgen_parse_operand_result result_type;
    123   bfd_vma value;
    124 
    125   if (**strp == '#' || **strp == '%')
    126     {
    127       if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
    128 	{
    129 	  *strp += 11;
    130 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    131 					   BFD_RELOC_FRV_GETTLSOFF_RELAX,
    132 					   &result_type, &value);
    133 	  if (**strp != ')')
    134 	    return "missing ')'";
    135 	  if (valuep)
    136 	    *valuep = value;
    137 	  ++*strp;
    138 	  if (errmsg)
    139 	    return errmsg;
    140 	}
    141     }
    142 
    143   while (**strp == ' ' || **strp == '\t')
    144     ++*strp;
    145 
    146   if (**strp != '@')
    147     return "missing `@'";
    148 
    149   ++*strp;
    150 
    151   return NULL;
    152 }
    153 
    154 static const char *
    155 parse_ld_annotation (CGEN_CPU_DESC cd,
    156 		     const char **strp,
    157 		     int opindex,
    158 		     unsigned long *valuep)
    159 {
    160   const char *errmsg;
    161   enum cgen_parse_operand_result result_type;
    162   bfd_vma value;
    163 
    164   if (**strp == '#' || **strp == '%')
    165     {
    166       if (strncasecmp (*strp + 1, "tlsoff(", 7) == 0)
    167 	{
    168 	  *strp += 8;
    169 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    170 					   BFD_RELOC_FRV_TLSOFF_RELAX,
    171 					   &result_type, &value);
    172 	  if (**strp != ')')
    173 	    return "missing ')'";
    174 	  if (valuep)
    175 	    *valuep = value;
    176 	  ++*strp;
    177 	  if (errmsg)
    178 	    return errmsg;
    179 	}
    180     }
    181 
    182   while (**strp == ' ' || **strp == '\t')
    183     ++*strp;
    184 
    185   if (**strp != '@')
    186     return "missing `@'";
    187 
    188   ++*strp;
    189 
    190   return NULL;
    191 }
    192 
    193 static const char *
    194 parse_ulo16 (CGEN_CPU_DESC cd,
    195 	     const char **strp,
    196 	     int opindex,
    197 	     unsigned long *valuep)
    198 {
    199   const char *errmsg;
    200   enum cgen_parse_operand_result result_type;
    201   bfd_vma value;
    202 
    203   if (**strp == '#' || **strp == '%')
    204     {
    205       if (strncasecmp (*strp + 1, "lo(", 3) == 0)
    206 	{
    207 	  *strp += 4;
    208 	  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
    209 				       & result_type, & value);
    210 	  if (**strp != ')')
    211 	    return "missing `)'";
    212 	  ++*strp;
    213 	  if (errmsg == NULL
    214 	      && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    215 	    value &= 0xffff;
    216 	  *valuep = value;
    217 	  return errmsg;
    218 	}
    219       if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
    220 	{
    221 	  *strp += 9;
    222 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    223 					   BFD_RELOC_FRV_GPRELLO,
    224 					   & result_type, & value);
    225 	  if (**strp != ')')
    226 	    return "missing ')'";
    227 	  ++*strp;
    228 	  *valuep = value;
    229 	  return errmsg;
    230 	}
    231       else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
    232 	{
    233 	  *strp += 7;
    234 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    235 					   BFD_RELOC_FRV_GOTLO,
    236 					   & result_type, & value);
    237 	  if (**strp != ')')
    238 	    return "missing ')'";
    239 	  ++*strp;
    240 	  *valuep = value;
    241 	  return errmsg;
    242 	}
    243       else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
    244 	{
    245 	  *strp += 15;
    246 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    247 					   BFD_RELOC_FRV_FUNCDESC_GOTLO,
    248 					   & result_type, & value);
    249 	  if (**strp != ')')
    250 	    return "missing ')'";
    251 	  ++*strp;
    252 	  *valuep = value;
    253 	  return errmsg;
    254 	}
    255       else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
    256 	{
    257 	  *strp += 10;
    258 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    259 					   BFD_RELOC_FRV_GOTOFFLO,
    260 					   & result_type, & value);
    261 	  if (**strp != ')')
    262 	    return "missing ')'";
    263 	  ++*strp;
    264 	  *valuep = value;
    265 	  return errmsg;
    266 	}
    267       else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
    268 	{
    269 	  *strp += 18;
    270 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    271 					   BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
    272 					   & result_type, & value);
    273 	  if (**strp != ')')
    274 	    return "missing ')'";
    275 	  ++*strp;
    276 	  *valuep = value;
    277 	  return errmsg;
    278 	}
    279       else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
    280 	{
    281 	  *strp += 14;
    282 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    283 					   BFD_RELOC_FRV_GOTTLSDESCLO,
    284 					   & result_type, & value);
    285 	  if (**strp != ')')
    286 	    return "missing ')'";
    287 	  ++*strp;
    288 	  *valuep = value;
    289 	  return errmsg;
    290 	}
    291       else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
    292 	{
    293 	  *strp += 11;
    294 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    295 					   BFD_RELOC_FRV_TLSMOFFLO,
    296 					   & result_type, & value);
    297 	  if (**strp != ')')
    298 	    return "missing ')'";
    299 	  ++*strp;
    300 	  *valuep = value;
    301 	  return errmsg;
    302 	}
    303       else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
    304 	{
    305 	  *strp += 13;
    306 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    307 					   BFD_RELOC_FRV_GOTTLSOFFLO,
    308 					   & result_type, & value);
    309 	  if (**strp != ')')
    310 	    return "missing ')'";
    311 	  ++*strp;
    312 	  *valuep = value;
    313 	  return errmsg;
    314 	}
    315     }
    316   return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
    317 }
    318 
    319 static const char *
    320 parse_uslo16 (CGEN_CPU_DESC cd,
    321 	      const char **strp,
    322 	      int opindex,
    323 	      signed long *valuep)
    324 {
    325   const char *errmsg;
    326   enum cgen_parse_operand_result result_type;
    327   bfd_vma value;
    328 
    329   if (**strp == '#' || **strp == '%')
    330     {
    331       if (strncasecmp (*strp + 1, "lo(", 3) == 0)
    332 	{
    333 	  *strp += 4;
    334 	  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_LO16,
    335 				       & result_type, & value);
    336 	  if (**strp != ')')
    337 	    return "missing `)'";
    338 	  ++*strp;
    339 	  if (errmsg == NULL
    340 	      && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    341 	    value &= 0xffff;
    342 	  *valuep = value;
    343 	  return errmsg;
    344 	}
    345       else if (strncasecmp (*strp + 1, "gprello(", 8) == 0)
    346 	{
    347 	  *strp += 9;
    348 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    349 					   BFD_RELOC_FRV_GPRELLO,
    350 					   & result_type, & value);
    351 	  if (**strp != ')')
    352 	    return "missing ')'";
    353 	  ++*strp;
    354 	  *valuep = value;
    355 	  return errmsg;
    356 	}
    357       else if (strncasecmp (*strp + 1, "gotlo(", 6) == 0)
    358 	{
    359 	  *strp += 7;
    360 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    361 					   BFD_RELOC_FRV_GOTLO,
    362 					   & result_type, & value);
    363 	  if (**strp != ')')
    364 	    return "missing ')'";
    365 	  ++*strp;
    366 	  *valuep = value;
    367 	  return errmsg;
    368 	}
    369       else if (strncasecmp (*strp + 1, "gotfuncdesclo(", 14) == 0)
    370 	{
    371 	  *strp += 15;
    372 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    373 					   BFD_RELOC_FRV_FUNCDESC_GOTLO,
    374 					   & result_type, & value);
    375 	  if (**strp != ')')
    376 	    return "missing ')'";
    377 	  ++*strp;
    378 	  *valuep = value;
    379 	  return errmsg;
    380 	}
    381       else if (strncasecmp (*strp + 1, "gotofflo(", 9) == 0)
    382 	{
    383 	  *strp += 10;
    384 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    385 					   BFD_RELOC_FRV_GOTOFFLO,
    386 					   & result_type, & value);
    387 	  if (**strp != ')')
    388 	    return "missing ')'";
    389 	  ++*strp;
    390 	  *valuep = value;
    391 	  return errmsg;
    392 	}
    393       else if (strncasecmp (*strp + 1, "gotofffuncdesclo(", 17) == 0)
    394 	{
    395 	  *strp += 18;
    396 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    397 					   BFD_RELOC_FRV_FUNCDESC_GOTOFFLO,
    398 					   & result_type, & value);
    399 	  if (**strp != ')')
    400 	    return "missing ')'";
    401 	  ++*strp;
    402 	  *valuep = value;
    403 	  return errmsg;
    404 	}
    405       else if (strncasecmp (*strp + 1, "gottlsdesclo(", 13) == 0)
    406 	{
    407 	  *strp += 14;
    408 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    409 					   BFD_RELOC_FRV_GOTTLSDESCLO,
    410 					   & result_type, & value);
    411 	  if (**strp != ')')
    412 	    return "missing ')'";
    413 	  ++*strp;
    414 	  *valuep = value;
    415 	  return errmsg;
    416 	}
    417       else if (strncasecmp (*strp + 1, "tlsmofflo(", 10) == 0)
    418 	{
    419 	  *strp += 11;
    420 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    421 					   BFD_RELOC_FRV_TLSMOFFLO,
    422 					   & result_type, & value);
    423 	  if (**strp != ')')
    424 	    return "missing ')'";
    425 	  ++*strp;
    426 	  *valuep = value;
    427 	  return errmsg;
    428 	}
    429       else if (strncasecmp (*strp + 1, "gottlsofflo(", 12) == 0)
    430 	{
    431 	  *strp += 13;
    432 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    433 					   BFD_RELOC_FRV_GOTTLSOFFLO,
    434 					   & result_type, & value);
    435 	  if (**strp != ')')
    436 	    return "missing ')'";
    437 	  ++*strp;
    438 	  *valuep = value;
    439 	  return errmsg;
    440 	}
    441     }
    442   return cgen_parse_signed_integer (cd, strp, opindex, valuep);
    443 }
    444 
    445 static const char *
    446 parse_uhi16 (CGEN_CPU_DESC cd,
    447 	     const char **strp,
    448 	     int opindex,
    449 	     unsigned long *valuep)
    450 {
    451   const char *errmsg;
    452   enum cgen_parse_operand_result result_type;
    453   bfd_vma value;
    454 
    455   if (**strp == '#' || **strp == '%')
    456     {
    457       if (strncasecmp (*strp + 1, "hi(", 3) == 0)
    458 	{
    459 	  *strp += 4;
    460 	  errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_FRV_HI16,
    461 				       & result_type, & value);
    462 	  if (**strp != ')')
    463 	    return "missing `)'";
    464 	  ++*strp;
    465 	  if (errmsg == NULL
    466 	      && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
    467 	    {
    468  	      /* If value is wider than 32 bits then be
    469  		 careful about how we extract bits 16-31.  */
    470  	      if (sizeof (value) > 4)
    471  		value &= (((bfd_vma)1 << 16) << 16) - 1;
    472 
    473 	      value >>= 16;
    474 	    }
    475 	  *valuep = value;
    476 	  return errmsg;
    477 	}
    478       else if (strncasecmp (*strp + 1, "gprelhi(", 8) == 0)
    479 	{
    480 	  *strp += 9;
    481 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    482 					   BFD_RELOC_FRV_GPRELHI,
    483 					   & result_type, & value);
    484 	  if (**strp != ')')
    485 	    return "missing ')'";
    486 	  ++*strp;
    487 	  *valuep = value;
    488 	  return errmsg;
    489 	}
    490       else if (strncasecmp (*strp + 1, "gothi(", 6) == 0)
    491 	{
    492 	  *strp += 7;
    493 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    494 					   BFD_RELOC_FRV_GOTHI,
    495 					   & result_type, & value);
    496 	  if (**strp != ')')
    497 	    return "missing ')'";
    498 	  ++*strp;
    499 	  *valuep = value;
    500 	  return errmsg;
    501 	}
    502       else if (strncasecmp (*strp + 1, "gotfuncdeschi(", 14) == 0)
    503 	{
    504 	  *strp += 15;
    505 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    506 					   BFD_RELOC_FRV_FUNCDESC_GOTHI,
    507 					   & result_type, & value);
    508 	  if (**strp != ')')
    509 	    return "missing ')'";
    510 	  ++*strp;
    511 	  *valuep = value;
    512 	  return errmsg;
    513 	}
    514       else if (strncasecmp (*strp + 1, "gotoffhi(", 9) == 0)
    515 	{
    516 	  *strp += 10;
    517 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    518 					   BFD_RELOC_FRV_GOTOFFHI,
    519 					   & result_type, & value);
    520 	  if (**strp != ')')
    521 	    return "missing ')'";
    522 	  ++*strp;
    523 	  *valuep = value;
    524 	  return errmsg;
    525 	}
    526       else if (strncasecmp (*strp + 1, "gotofffuncdeschi(", 17) == 0)
    527 	{
    528 	  *strp += 18;
    529 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    530 					   BFD_RELOC_FRV_FUNCDESC_GOTOFFHI,
    531 					   & result_type, & value);
    532 	  if (**strp != ')')
    533 	    return "missing ')'";
    534 	  ++*strp;
    535 	  *valuep = value;
    536 	  return errmsg;
    537 	}
    538       else if (strncasecmp (*strp + 1, "gottlsdeschi(", 13) == 0)
    539 	{
    540 	  *strp += 14;
    541 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    542 					   BFD_RELOC_FRV_GOTTLSDESCHI,
    543 					   &result_type, &value);
    544 	  if (**strp != ')')
    545 	    return "missing ')'";
    546 	  ++*strp;
    547 	  *valuep = value;
    548 	  return errmsg;
    549 	}
    550       else if (strncasecmp (*strp + 1, "tlsmoffhi(", 10) == 0)
    551 	{
    552 	  *strp += 11;
    553 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    554 					   BFD_RELOC_FRV_TLSMOFFHI,
    555 					   & result_type, & value);
    556 	  if (**strp != ')')
    557 	    return "missing ')'";
    558 	  ++*strp;
    559 	  *valuep = value;
    560 	  return errmsg;
    561 	}
    562       else if (strncasecmp (*strp + 1, "gottlsoffhi(", 12) == 0)
    563 	{
    564 	  *strp += 13;
    565 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    566 					   BFD_RELOC_FRV_GOTTLSOFFHI,
    567 					   & result_type, & value);
    568 	  if (**strp != ')')
    569 	    return "missing ')'";
    570 	  ++*strp;
    571 	  *valuep = value;
    572 	  return errmsg;
    573 	}
    574     }
    575   return cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
    576 }
    577 
    578 static long
    579 parse_register_number (const char **strp)
    580 {
    581   int regno;
    582 
    583   if (**strp < '0' || **strp > '9')
    584     return -1; /* error */
    585 
    586   regno = **strp - '0';
    587   for (++*strp; **strp >= '0' && **strp <= '9'; ++*strp)
    588     regno = regno * 10 + (**strp - '0');
    589 
    590   return regno;
    591 }
    592 
    593 static const char *
    594 parse_spr (CGEN_CPU_DESC cd,
    595 	   const char **strp,
    596 	   CGEN_KEYWORD * table,
    597 	   long *valuep)
    598 {
    599   const char *save_strp;
    600   long regno;
    601 
    602   /* Check for spr index notation.  */
    603   if (strncasecmp (*strp, "spr[", 4) == 0)
    604     {
    605       *strp += 4;
    606       regno = parse_register_number (strp);
    607       if (**strp != ']')
    608         return _("missing `]'");
    609       ++*strp;
    610       if (! spr_valid (regno))
    611 	return _("Special purpose register number is out of range");
    612       *valuep = regno;
    613       return NULL;
    614     }
    615 
    616   save_strp = *strp;
    617   regno = parse_register_number (strp);
    618   if (regno != -1)
    619     {
    620       if (! spr_valid (regno))
    621 	return _("Special purpose register number is out of range");
    622       *valuep = regno;
    623       return NULL;
    624     }
    625 
    626   *strp = save_strp;
    627   return cgen_parse_keyword (cd, strp, table, valuep);
    628 }
    629 
    630 static const char *
    631 parse_d12 (CGEN_CPU_DESC cd,
    632 	   const char **strp,
    633 	   int opindex,
    634 	   long *valuep)
    635 {
    636   const char *errmsg;
    637   enum cgen_parse_operand_result result_type;
    638   bfd_vma value;
    639 
    640   /* Check for small data reference.  */
    641   if (**strp == '#' || **strp == '%')
    642     {
    643       if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
    644         {
    645           *strp += 9;
    646           errmsg = parse_symbolic_address (cd, strp, opindex,
    647 					   BFD_RELOC_FRV_GPREL12,
    648 					   & result_type, & value);
    649           if (**strp != ')')
    650             return "missing `)'";
    651           ++*strp;
    652           *valuep = value;
    653           return errmsg;
    654         }
    655       else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
    656 	{
    657 	  *strp += 7;
    658 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    659 					   BFD_RELOC_FRV_GOT12,
    660 					   & result_type, & value);
    661 	  if (**strp != ')')
    662 	    return "missing ')'";
    663 	  ++*strp;
    664 	  *valuep = value;
    665 	  return errmsg;
    666 	}
    667       else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
    668 	{
    669 	  *strp += 15;
    670 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    671 					   BFD_RELOC_FRV_FUNCDESC_GOT12,
    672 					   & result_type, & value);
    673 	  if (**strp != ')')
    674 	    return "missing ')'";
    675 	  ++*strp;
    676 	  *valuep = value;
    677 	  return errmsg;
    678 	}
    679       else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
    680 	{
    681 	  *strp += 10;
    682 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    683 					   BFD_RELOC_FRV_GOTOFF12,
    684 					   & result_type, & value);
    685 	  if (**strp != ')')
    686 	    return "missing ')'";
    687 	  ++*strp;
    688 	  *valuep = value;
    689 	  return errmsg;
    690 	}
    691       else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
    692 	{
    693 	  *strp += 18;
    694 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    695 					   BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
    696 					   & result_type, & value);
    697 	  if (**strp != ')')
    698 	    return "missing ')'";
    699 	  ++*strp;
    700 	  *valuep = value;
    701 	  return errmsg;
    702 	}
    703       else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
    704 	{
    705 	  *strp += 14;
    706 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    707 					   BFD_RELOC_FRV_GOTTLSDESC12,
    708 					   & result_type, & value);
    709 	  if (**strp != ')')
    710 	    return "missing ')'";
    711 	  ++*strp;
    712 	  *valuep = value;
    713 	  return errmsg;
    714 	}
    715       else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
    716 	{
    717 	  *strp += 11;
    718 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    719 					   BFD_RELOC_FRV_TLSMOFF12,
    720 					   & result_type, & value);
    721 	  if (**strp != ')')
    722 	    return "missing ')'";
    723 	  ++*strp;
    724 	  *valuep = value;
    725 	  return errmsg;
    726 	}
    727       else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
    728 	{
    729 	  *strp += 13;
    730 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    731 					   BFD_RELOC_FRV_GOTTLSOFF12,
    732 					   & result_type, & value);
    733 	  if (**strp != ')')
    734 	    return "missing ')'";
    735 	  ++*strp;
    736 	  *valuep = value;
    737 	  return errmsg;
    738 	}
    739     }
    740   return cgen_parse_signed_integer (cd, strp, opindex, valuep);
    741 }
    742 
    743 static const char *
    744 parse_s12 (CGEN_CPU_DESC cd,
    745 	   const char **strp,
    746 	   int opindex,
    747 	   long *valuep)
    748 {
    749   const char *errmsg;
    750   enum cgen_parse_operand_result result_type;
    751   bfd_vma value;
    752 
    753   /* Check for small data reference.  */
    754   if (**strp == '#' || **strp == '%')
    755     {
    756       if (strncasecmp (*strp + 1, "gprel12(", 8) == 0)
    757 	{
    758 	  *strp += 9;
    759 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    760 					   BFD_RELOC_FRV_GPREL12,
    761 					   & result_type, & value);
    762 	  if (**strp != ')')
    763 	    return "missing `)'";
    764 	  ++*strp;
    765 	  *valuep = value;
    766 	  return errmsg;
    767 	}
    768       else if (strncasecmp (*strp + 1, "got12(", 6) == 0)
    769 	{
    770 	  *strp += 7;
    771 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    772 					   BFD_RELOC_FRV_GOT12,
    773 					   & result_type, & value);
    774 	  if (**strp != ')')
    775 	    return "missing ')'";
    776 	  ++*strp;
    777 	  *valuep = value;
    778 	  return errmsg;
    779 	}
    780       else if (strncasecmp (*strp + 1, "gotfuncdesc12(", 14) == 0)
    781 	{
    782 	  *strp += 15;
    783 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    784 					   BFD_RELOC_FRV_FUNCDESC_GOT12,
    785 					   & result_type, & value);
    786 	  if (**strp != ')')
    787 	    return "missing ')'";
    788 	  ++*strp;
    789 	  *valuep = value;
    790 	  return errmsg;
    791 	}
    792       else if (strncasecmp (*strp + 1, "gotoff12(", 9) == 0)
    793 	{
    794 	  *strp += 10;
    795 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    796 					   BFD_RELOC_FRV_GOTOFF12,
    797 					   & result_type, & value);
    798 	  if (**strp != ')')
    799 	    return "missing ')'";
    800 	  ++*strp;
    801 	  *valuep = value;
    802 	  return errmsg;
    803 	}
    804       else if (strncasecmp (*strp + 1, "gotofffuncdesc12(", 17) == 0)
    805 	{
    806 	  *strp += 18;
    807 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    808 					   BFD_RELOC_FRV_FUNCDESC_GOTOFF12,
    809 					   & result_type, & value);
    810 	  if (**strp != ')')
    811 	    return "missing ')'";
    812 	  ++*strp;
    813 	  *valuep = value;
    814 	  return errmsg;
    815 	}
    816       else if (strncasecmp (*strp + 1, "gottlsdesc12(", 13) == 0)
    817 	{
    818 	  *strp += 14;
    819 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    820 					   BFD_RELOC_FRV_GOTTLSDESC12,
    821 					   & result_type, & value);
    822 	  if (**strp != ')')
    823 	    return "missing ')'";
    824 	  ++*strp;
    825 	  *valuep = value;
    826 	  return errmsg;
    827 	}
    828       else if (strncasecmp (*strp + 1, "tlsmoff12(", 10) == 0)
    829 	{
    830 	  *strp += 11;
    831 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    832 					   BFD_RELOC_FRV_TLSMOFF12,
    833 					   & result_type, & value);
    834 	  if (**strp != ')')
    835 	    return "missing ')'";
    836 	  ++*strp;
    837 	  *valuep = value;
    838 	  return errmsg;
    839 	}
    840       else if (strncasecmp (*strp + 1, "gottlsoff12(", 12) == 0)
    841 	{
    842 	  *strp += 13;
    843 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    844 					   BFD_RELOC_FRV_GOTTLSOFF12,
    845 					   & result_type, & value);
    846 	  if (**strp != ')')
    847 	    return "missing ')'";
    848 	  ++*strp;
    849 	  *valuep = value;
    850 	  return errmsg;
    851 	}
    852     }
    853 
    854   if (**strp == '#')
    855     ++*strp;
    856   return cgen_parse_signed_integer (cd, strp, opindex, valuep);
    857 }
    858 
    859 static const char *
    860 parse_u12 (CGEN_CPU_DESC cd,
    861 	   const char **strp,
    862 	   int opindex,
    863 	   long *valuep)
    864 {
    865   const char *errmsg;
    866   enum cgen_parse_operand_result result_type;
    867   bfd_vma value;
    868 
    869   /* Check for small data reference.  */
    870   if ((**strp == '#' || **strp == '%')
    871       && strncasecmp (*strp + 1, "gprel12(", 8) == 0)
    872     {
    873       *strp += 9;
    874       errmsg = parse_symbolic_address (cd, strp, opindex,
    875 				       BFD_RELOC_FRV_GPRELU12,
    876 				       & result_type, & value);
    877       if (**strp != ')')
    878         return "missing `)'";
    879       ++*strp;
    880       *valuep = value;
    881       return errmsg;
    882     }
    883   else
    884     {
    885       if (**strp == '#')
    886         ++*strp;
    887       return cgen_parse_signed_integer (cd, strp, opindex, valuep);
    888     }
    889 }
    890 
    891 static const char *
    892 parse_A (CGEN_CPU_DESC cd,
    893 	 const char **strp,
    894 	 int opindex,
    895 	 unsigned long *valuep,
    896 	 unsigned long A)
    897 {
    898   const char *errmsg;
    899 
    900   if (**strp == '#')
    901     ++*strp;
    902 
    903   errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, valuep);
    904   if (errmsg)
    905     return errmsg;
    906 
    907   if (*valuep != A)
    908     return _("Value of A operand must be 0 or 1");
    909 
    910   return NULL;
    911 }
    912 
    913 static const char *
    914 parse_A0 (CGEN_CPU_DESC cd,
    915 	  const char **strp,
    916 	  int opindex,
    917 	  unsigned long *valuep)
    918 {
    919   return parse_A (cd, strp, opindex, valuep, 0);
    920 }
    921 
    922 static const char *
    923 parse_A1 (CGEN_CPU_DESC cd,
    924 	  const char **strp,
    925 	  int opindex,
    926 	  unsigned long *valuep)
    927 {
    928   return parse_A (cd, strp, opindex, valuep, 1);
    929 }
    930 
    931 static const char *
    932 parse_even_register (CGEN_CPU_DESC  cd,
    933 		     const char **  strP,
    934 		     CGEN_KEYWORD * tableP,
    935 		     long *         valueP)
    936 {
    937   const char * errmsg;
    938   const char * saved_star_strP = * strP;
    939 
    940   errmsg = cgen_parse_keyword (cd, strP, tableP, valueP);
    941 
    942   if (errmsg == NULL && ((* valueP) & 1))
    943     {
    944       errmsg = _("register number must be even");
    945       * strP = saved_star_strP;
    946     }
    947 
    948   return errmsg;
    949 }
    950 
    951 static const char *
    952 parse_call_label (CGEN_CPU_DESC cd,
    953 		  const char **strp,
    954 		  int opindex,
    955 		  int opinfo,
    956 		  enum cgen_parse_operand_result *resultp,
    957 		  bfd_vma *valuep)
    958 {
    959   const char *errmsg;
    960   bfd_vma value;
    961 
    962   /* Check for small data reference.  */
    963   if (opinfo == 0 && (**strp == '#' || **strp == '%'))
    964     {
    965       if (strncasecmp (*strp + 1, "gettlsoff(", 10) == 0)
    966 	{
    967 	  *strp += 11;
    968 	  errmsg = parse_symbolic_address (cd, strp, opindex,
    969 					   BFD_RELOC_FRV_GETTLSOFF,
    970 					   resultp, &value);
    971 	  if (**strp != ')')
    972 	    return _("missing `)'");
    973 	  ++*strp;
    974 	  *valuep = value;
    975 	  return errmsg;
    976 	}
    977     }
    978 
    979   return cgen_parse_address (cd, strp, opindex, opinfo, resultp, valuep);
    980 }
    981 
    982 /* -- */
    983 
    984 const char * frv_cgen_parse_operand
    985   (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
    986 
    987 /* Main entry point for operand parsing.
    988 
    989    This function is basically just a big switch statement.  Earlier versions
    990    used tables to look up the function to use, but
    991    - if the table contains both assembler and disassembler functions then
    992      the disassembler contains much of the assembler and vice-versa,
    993    - there's a lot of inlining possibilities as things grow,
    994    - using a switch statement avoids the function call overhead.
    995 
    996    This function could be moved into `parse_insn_normal', but keeping it
    997    separate makes clear the interface between `parse_insn_normal' and each of
    998    the handlers.  */
    999 
   1000 const char *
   1001 frv_cgen_parse_operand (CGEN_CPU_DESC cd,
   1002 			   int opindex,
   1003 			   const char ** strp,
   1004 			   CGEN_FIELDS * fields)
   1005 {
   1006   const char * errmsg = NULL;
   1007   /* Used by scalar operands that still need to be parsed.  */
   1008   long junk ATTRIBUTE_UNUSED;
   1009 
   1010   switch (opindex)
   1011     {
   1012     case FRV_OPERAND_A0 :
   1013       errmsg = parse_A0 (cd, strp, FRV_OPERAND_A0, (unsigned long *) (& fields->f_A));
   1014       break;
   1015     case FRV_OPERAND_A1 :
   1016       errmsg = parse_A1 (cd, strp, FRV_OPERAND_A1, (unsigned long *) (& fields->f_A));
   1017       break;
   1018     case FRV_OPERAND_ACC40SI :
   1019       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Si);
   1020       break;
   1021     case FRV_OPERAND_ACC40SK :
   1022       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Sk);
   1023       break;
   1024     case FRV_OPERAND_ACC40UI :
   1025       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Ui);
   1026       break;
   1027     case FRV_OPERAND_ACC40UK :
   1028       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_acc_names, & fields->f_ACC40Uk);
   1029       break;
   1030     case FRV_OPERAND_ACCGI :
   1031       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGi);
   1032       break;
   1033     case FRV_OPERAND_ACCGK :
   1034       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_accg_names, & fields->f_ACCGk);
   1035       break;
   1036     case FRV_OPERAND_CCI :
   1037       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CCi);
   1038       break;
   1039     case FRV_OPERAND_CPRDOUBLEK :
   1040       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
   1041       break;
   1042     case FRV_OPERAND_CPRI :
   1043       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRi);
   1044       break;
   1045     case FRV_OPERAND_CPRJ :
   1046       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRj);
   1047       break;
   1048     case FRV_OPERAND_CPRK :
   1049       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cpr_names, & fields->f_CPRk);
   1050       break;
   1051     case FRV_OPERAND_CRI :
   1052       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRi);
   1053       break;
   1054     case FRV_OPERAND_CRJ :
   1055       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj);
   1056       break;
   1057     case FRV_OPERAND_CRJ_FLOAT :
   1058       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_float);
   1059       break;
   1060     case FRV_OPERAND_CRJ_INT :
   1061       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRj_int);
   1062       break;
   1063     case FRV_OPERAND_CRK :
   1064       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_cccr_names, & fields->f_CRk);
   1065       break;
   1066     case FRV_OPERAND_FCCI_1 :
   1067       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_1);
   1068       break;
   1069     case FRV_OPERAND_FCCI_2 :
   1070       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_2);
   1071       break;
   1072     case FRV_OPERAND_FCCI_3 :
   1073       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCi_3);
   1074       break;
   1075     case FRV_OPERAND_FCCK :
   1076       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fccr_names, & fields->f_FCCk);
   1077       break;
   1078     case FRV_OPERAND_FRDOUBLEI :
   1079       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
   1080       break;
   1081     case FRV_OPERAND_FRDOUBLEJ :
   1082       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
   1083       break;
   1084     case FRV_OPERAND_FRDOUBLEK :
   1085       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
   1086       break;
   1087     case FRV_OPERAND_FRI :
   1088       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
   1089       break;
   1090     case FRV_OPERAND_FRINTI :
   1091       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
   1092       break;
   1093     case FRV_OPERAND_FRINTIEVEN :
   1094       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRi);
   1095       break;
   1096     case FRV_OPERAND_FRINTJ :
   1097       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
   1098       break;
   1099     case FRV_OPERAND_FRINTJEVEN :
   1100       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
   1101       break;
   1102     case FRV_OPERAND_FRINTK :
   1103       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
   1104       break;
   1105     case FRV_OPERAND_FRINTKEVEN :
   1106       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
   1107       break;
   1108     case FRV_OPERAND_FRJ :
   1109       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRj);
   1110       break;
   1111     case FRV_OPERAND_FRK :
   1112       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
   1113       break;
   1114     case FRV_OPERAND_FRKHI :
   1115       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
   1116       break;
   1117     case FRV_OPERAND_FRKLO :
   1118       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_fr_names, & fields->f_FRk);
   1119       break;
   1120     case FRV_OPERAND_GRDOUBLEK :
   1121       errmsg = parse_even_register (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
   1122       break;
   1123     case FRV_OPERAND_GRI :
   1124       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRi);
   1125       break;
   1126     case FRV_OPERAND_GRJ :
   1127       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRj);
   1128       break;
   1129     case FRV_OPERAND_GRK :
   1130       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
   1131       break;
   1132     case FRV_OPERAND_GRKHI :
   1133       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
   1134       break;
   1135     case FRV_OPERAND_GRKLO :
   1136       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_gr_names, & fields->f_GRk);
   1137       break;
   1138     case FRV_OPERAND_ICCI_1 :
   1139       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_1);
   1140       break;
   1141     case FRV_OPERAND_ICCI_2 :
   1142       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_2);
   1143       break;
   1144     case FRV_OPERAND_ICCI_3 :
   1145       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_iccr_names, & fields->f_ICCi_3);
   1146       break;
   1147     case FRV_OPERAND_LI :
   1148       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LI, (unsigned long *) (& fields->f_LI));
   1149       break;
   1150     case FRV_OPERAND_LRAD :
   1151       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAD, (unsigned long *) (& fields->f_LRAD));
   1152       break;
   1153     case FRV_OPERAND_LRAE :
   1154       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAE, (unsigned long *) (& fields->f_LRAE));
   1155       break;
   1156     case FRV_OPERAND_LRAS :
   1157       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LRAS, (unsigned long *) (& fields->f_LRAS));
   1158       break;
   1159     case FRV_OPERAND_TLBPRL :
   1160       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_TLBPRL, (unsigned long *) (& fields->f_TLBPRL));
   1161       break;
   1162     case FRV_OPERAND_TLBPROPX :
   1163       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_TLBPROPX, (unsigned long *) (& fields->f_TLBPRopx));
   1164       break;
   1165     case FRV_OPERAND_AE :
   1166       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_AE, (unsigned long *) (& fields->f_ae));
   1167       break;
   1168     case FRV_OPERAND_CALLANN :
   1169       errmsg = parse_call_annotation (cd, strp, FRV_OPERAND_CALLANN, (unsigned long *) (& fields->f_reloc_ann));
   1170       break;
   1171     case FRV_OPERAND_CCOND :
   1172       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_CCOND, (unsigned long *) (& fields->f_ccond));
   1173       break;
   1174     case FRV_OPERAND_COND :
   1175       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_COND, (unsigned long *) (& fields->f_cond));
   1176       break;
   1177     case FRV_OPERAND_D12 :
   1178       errmsg = parse_d12 (cd, strp, FRV_OPERAND_D12, (long *) (& fields->f_d12));
   1179       break;
   1180     case FRV_OPERAND_DEBUG :
   1181       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_DEBUG, (unsigned long *) (& fields->f_debug));
   1182       break;
   1183     case FRV_OPERAND_EIR :
   1184       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_EIR, (unsigned long *) (& fields->f_eir));
   1185       break;
   1186     case FRV_OPERAND_HINT :
   1187       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_HINT, (unsigned long *) (& fields->f_hint));
   1188       break;
   1189     case FRV_OPERAND_HINT_NOT_TAKEN :
   1190       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_not_taken, & fields->f_hint);
   1191       break;
   1192     case FRV_OPERAND_HINT_TAKEN :
   1193       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_hint_taken, & fields->f_hint);
   1194       break;
   1195     case FRV_OPERAND_LABEL16 :
   1196       {
   1197         bfd_vma value = 0;
   1198         errmsg = cgen_parse_address (cd, strp, FRV_OPERAND_LABEL16, 0, NULL,  & value);
   1199         fields->f_label16 = value;
   1200       }
   1201       break;
   1202     case FRV_OPERAND_LABEL24 :
   1203       {
   1204         bfd_vma value = 0;
   1205         errmsg = parse_call_label (cd, strp, FRV_OPERAND_LABEL24, 0, NULL,  & value);
   1206         fields->f_label24 = value;
   1207       }
   1208       break;
   1209     case FRV_OPERAND_LDANN :
   1210       errmsg = parse_ld_annotation (cd, strp, FRV_OPERAND_LDANN, (unsigned long *) (& fields->f_reloc_ann));
   1211       break;
   1212     case FRV_OPERAND_LDDANN :
   1213       errmsg = parse_ldd_annotation (cd, strp, FRV_OPERAND_LDDANN, (unsigned long *) (& fields->f_reloc_ann));
   1214       break;
   1215     case FRV_OPERAND_LOCK :
   1216       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_LOCK, (unsigned long *) (& fields->f_lock));
   1217       break;
   1218     case FRV_OPERAND_PACK :
   1219       errmsg = cgen_parse_keyword (cd, strp, & frv_cgen_opval_h_pack, & fields->f_pack);
   1220       break;
   1221     case FRV_OPERAND_S10 :
   1222       errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S10, (long *) (& fields->f_s10));
   1223       break;
   1224     case FRV_OPERAND_S12 :
   1225       errmsg = parse_s12 (cd, strp, FRV_OPERAND_S12, (long *) (& fields->f_d12));
   1226       break;
   1227     case FRV_OPERAND_S16 :
   1228       errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S16, (long *) (& fields->f_s16));
   1229       break;
   1230     case FRV_OPERAND_S5 :
   1231       errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S5, (long *) (& fields->f_s5));
   1232       break;
   1233     case FRV_OPERAND_S6 :
   1234       errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6, (long *) (& fields->f_s6));
   1235       break;
   1236     case FRV_OPERAND_S6_1 :
   1237       errmsg = cgen_parse_signed_integer (cd, strp, FRV_OPERAND_S6_1, (long *) (& fields->f_s6_1));
   1238       break;
   1239     case FRV_OPERAND_SLO16 :
   1240       errmsg = parse_uslo16 (cd, strp, FRV_OPERAND_SLO16, (long *) (& fields->f_s16));
   1241       break;
   1242     case FRV_OPERAND_SPR :
   1243       errmsg = parse_spr (cd, strp, & frv_cgen_opval_spr_names, & fields->f_spr);
   1244       break;
   1245     case FRV_OPERAND_U12 :
   1246       errmsg = parse_u12 (cd, strp, FRV_OPERAND_U12, (long *) (& fields->f_u12));
   1247       break;
   1248     case FRV_OPERAND_U16 :
   1249       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U16, (unsigned long *) (& fields->f_u16));
   1250       break;
   1251     case FRV_OPERAND_U6 :
   1252       errmsg = cgen_parse_unsigned_integer (cd, strp, FRV_OPERAND_U6, (unsigned long *) (& fields->f_u6));
   1253       break;
   1254     case FRV_OPERAND_UHI16 :
   1255       errmsg = parse_uhi16 (cd, strp, FRV_OPERAND_UHI16, (unsigned long *) (& fields->f_u16));
   1256       break;
   1257     case FRV_OPERAND_ULO16 :
   1258       errmsg = parse_ulo16 (cd, strp, FRV_OPERAND_ULO16, (unsigned long *) (& fields->f_u16));
   1259       break;
   1260 
   1261     default :
   1262       /* xgettext:c-format */
   1263       fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex);
   1264       abort ();
   1265   }
   1266 
   1267   return errmsg;
   1268 }
   1269 
   1270 cgen_parse_fn * const frv_cgen_parse_handlers[] =
   1271 {
   1272   parse_insn_normal,
   1273 };
   1274 
   1275 void
   1276 frv_cgen_init_asm (CGEN_CPU_DESC cd)
   1277 {
   1278   frv_cgen_init_opcode_table (cd);
   1279   frv_cgen_init_ibld_table (cd);
   1280   cd->parse_handlers = & frv_cgen_parse_handlers[0];
   1281   cd->parse_operand = frv_cgen_parse_operand;
   1282 #ifdef CGEN_ASM_INIT_HOOK
   1283 CGEN_ASM_INIT_HOOK
   1284 #endif
   1285 }
   1286 
   1287 
   1288 
   1290 /* Regex construction routine.
   1291 
   1292    This translates an opcode syntax string into a regex string,
   1293    by replacing any non-character syntax element (such as an
   1294    opcode) with the pattern '.*'
   1295 
   1296    It then compiles the regex and stores it in the opcode, for
   1297    later use by frv_cgen_assemble_insn
   1298 
   1299    Returns NULL for success, an error message for failure.  */
   1300 
   1301 char *
   1302 frv_cgen_build_insn_regex (CGEN_INSN *insn)
   1303 {
   1304   CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn);
   1305   const char *mnem = CGEN_INSN_MNEMONIC (insn);
   1306   char rxbuf[CGEN_MAX_RX_ELEMENTS];
   1307   char *rx = rxbuf;
   1308   const CGEN_SYNTAX_CHAR_TYPE *syn;
   1309   int reg_err;
   1310 
   1311   syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc));
   1312 
   1313   /* Mnemonics come first in the syntax string.  */
   1314   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
   1315     return _("missing mnemonic in syntax string");
   1316   ++syn;
   1317 
   1318   /* Generate a case sensitive regular expression that emulates case
   1319      insensitive matching in the "C" locale.  We cannot generate a case
   1320      insensitive regular expression because in Turkish locales, 'i' and 'I'
   1321      are not equal modulo case conversion.  */
   1322 
   1323   /* Copy the literal mnemonic out of the insn.  */
   1324   for (; *mnem; mnem++)
   1325     {
   1326       char c = *mnem;
   1327 
   1328       if (ISALPHA (c))
   1329 	{
   1330 	  *rx++ = '[';
   1331 	  *rx++ = TOLOWER (c);
   1332 	  *rx++ = TOUPPER (c);
   1333 	  *rx++ = ']';
   1334 	}
   1335       else
   1336 	*rx++ = c;
   1337     }
   1338 
   1339   /* Copy any remaining literals from the syntax string into the rx.  */
   1340   for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn)
   1341     {
   1342       if (CGEN_SYNTAX_CHAR_P (* syn))
   1343 	{
   1344 	  char c = CGEN_SYNTAX_CHAR (* syn);
   1345 
   1346 	  switch (c)
   1347 	    {
   1348 	      /* Escape any regex metacharacters in the syntax.  */
   1349 	    case '.': case '[': case '\\':
   1350 	    case '*': case '^': case '$':
   1351 
   1352 #ifdef CGEN_ESCAPE_EXTENDED_REGEX
   1353 	    case '?': case '{': case '}':
   1354 	    case '(': case ')': case '*':
   1355 	    case '|': case '+': case ']':
   1356 #endif
   1357 	      *rx++ = '\\';
   1358 	      *rx++ = c;
   1359 	      break;
   1360 
   1361 	    default:
   1362 	      if (ISALPHA (c))
   1363 		{
   1364 		  *rx++ = '[';
   1365 		  *rx++ = TOLOWER (c);
   1366 		  *rx++ = TOUPPER (c);
   1367 		  *rx++ = ']';
   1368 		}
   1369 	      else
   1370 		*rx++ = c;
   1371 	      break;
   1372 	    }
   1373 	}
   1374       else
   1375 	{
   1376 	  /* Replace non-syntax fields with globs.  */
   1377 	  *rx++ = '.';
   1378 	  *rx++ = '*';
   1379 	}
   1380     }
   1381 
   1382   /* Trailing whitespace ok.  */
   1383   * rx++ = '[';
   1384   * rx++ = ' ';
   1385   * rx++ = '\t';
   1386   * rx++ = ']';
   1387   * rx++ = '*';
   1388 
   1389   /* But anchor it after that.  */
   1390   * rx++ = '$';
   1391   * rx = '\0';
   1392 
   1393   CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t));
   1394   reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB);
   1395 
   1396   if (reg_err == 0)
   1397     return NULL;
   1398   else
   1399     {
   1400       static char msg[80];
   1401 
   1402       regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80);
   1403       regfree ((regex_t *) CGEN_INSN_RX (insn));
   1404       free (CGEN_INSN_RX (insn));
   1405       (CGEN_INSN_RX (insn)) = NULL;
   1406       return msg;
   1407     }
   1408 }
   1409 
   1410 
   1411 /* Default insn parser.
   1413 
   1414    The syntax string is scanned and operands are parsed and stored in FIELDS.
   1415    Relocs are queued as we go via other callbacks.
   1416 
   1417    ??? Note that this is currently an all-or-nothing parser.  If we fail to
   1418    parse the instruction, we return 0 and the caller will start over from
   1419    the beginning.  Backtracking will be necessary in parsing subexpressions,
   1420    but that can be handled there.  Not handling backtracking here may get
   1421    expensive in the case of the m68k.  Deal with later.
   1422 
   1423    Returns NULL for success, an error message for failure.  */
   1424 
   1425 static const char *
   1426 parse_insn_normal (CGEN_CPU_DESC cd,
   1427 		   const CGEN_INSN *insn,
   1428 		   const char **strp,
   1429 		   CGEN_FIELDS *fields)
   1430 {
   1431   /* ??? Runtime added insns not handled yet.  */
   1432   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
   1433   const char *str = *strp;
   1434   const char *errmsg;
   1435   const char *p;
   1436   const CGEN_SYNTAX_CHAR_TYPE * syn;
   1437 #ifdef CGEN_MNEMONIC_OPERANDS
   1438   /* FIXME: wip */
   1439   int past_opcode_p;
   1440 #endif
   1441 
   1442   /* For now we assume the mnemonic is first (there are no leading operands).
   1443      We can parse it without needing to set up operand parsing.
   1444      GAS's input scrubber will ensure mnemonics are lowercase, but we may
   1445      not be called from GAS.  */
   1446   p = CGEN_INSN_MNEMONIC (insn);
   1447   while (*p && TOLOWER (*p) == TOLOWER (*str))
   1448     ++p, ++str;
   1449 
   1450   if (* p)
   1451     return _("unrecognized instruction");
   1452 
   1453 #ifndef CGEN_MNEMONIC_OPERANDS
   1454   if (* str && ! ISSPACE (* str))
   1455     return _("unrecognized instruction");
   1456 #endif
   1457 
   1458   CGEN_INIT_PARSE (cd);
   1459   cgen_init_parse_operand (cd);
   1460 #ifdef CGEN_MNEMONIC_OPERANDS
   1461   past_opcode_p = 0;
   1462 #endif
   1463 
   1464   /* We don't check for (*str != '\0') here because we want to parse
   1465      any trailing fake arguments in the syntax string.  */
   1466   syn = CGEN_SYNTAX_STRING (syntax);
   1467 
   1468   /* Mnemonics come first for now, ensure valid string.  */
   1469   if (! CGEN_SYNTAX_MNEMONIC_P (* syn))
   1470     abort ();
   1471 
   1472   ++syn;
   1473 
   1474   while (* syn != 0)
   1475     {
   1476       /* Non operand chars must match exactly.  */
   1477       if (CGEN_SYNTAX_CHAR_P (* syn))
   1478 	{
   1479 	  /* FIXME: While we allow for non-GAS callers above, we assume the
   1480 	     first char after the mnemonic part is a space.  */
   1481 	  /* FIXME: We also take inappropriate advantage of the fact that
   1482 	     GAS's input scrubber will remove extraneous blanks.  */
   1483 	  if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn)))
   1484 	    {
   1485 #ifdef CGEN_MNEMONIC_OPERANDS
   1486 	      if (CGEN_SYNTAX_CHAR(* syn) == ' ')
   1487 		past_opcode_p = 1;
   1488 #endif
   1489 	      ++ syn;
   1490 	      ++ str;
   1491 	    }
   1492 	  else if (*str)
   1493 	    {
   1494 	      /* Syntax char didn't match.  Can't be this insn.  */
   1495 	      static char msg [80];
   1496 
   1497 	      /* xgettext:c-format */
   1498 	      sprintf (msg, _("syntax error (expected char `%c', found `%c')"),
   1499 		       CGEN_SYNTAX_CHAR(*syn), *str);
   1500 	      return msg;
   1501 	    }
   1502 	  else
   1503 	    {
   1504 	      /* Ran out of input.  */
   1505 	      static char msg [80];
   1506 
   1507 	      /* xgettext:c-format */
   1508 	      sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"),
   1509 		       CGEN_SYNTAX_CHAR(*syn));
   1510 	      return msg;
   1511 	    }
   1512 	  continue;
   1513 	}
   1514 
   1515 #ifdef CGEN_MNEMONIC_OPERANDS
   1516       (void) past_opcode_p;
   1517 #endif
   1518       /* We have an operand of some sort.  */
   1519       errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), &str, fields);
   1520       if (errmsg)
   1521 	return errmsg;
   1522 
   1523       /* Done with this operand, continue with next one.  */
   1524       ++ syn;
   1525     }
   1526 
   1527   /* If we're at the end of the syntax string, we're done.  */
   1528   if (* syn == 0)
   1529     {
   1530       /* FIXME: For the moment we assume a valid `str' can only contain
   1531 	 blanks now.  IE: We needn't try again with a longer version of
   1532 	 the insn and it is assumed that longer versions of insns appear
   1533 	 before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3).  */
   1534       while (ISSPACE (* str))
   1535 	++ str;
   1536 
   1537       if (* str != '\0')
   1538 	return _("junk at end of line"); /* FIXME: would like to include `str' */
   1539 
   1540       return NULL;
   1541     }
   1542 
   1543   /* We couldn't parse it.  */
   1544   return _("unrecognized instruction");
   1545 }
   1546 
   1547 /* Main entry point.
   1549    This routine is called for each instruction to be assembled.
   1550    STR points to the insn to be assembled.
   1551    We assume all necessary tables have been initialized.
   1552    The assembled instruction, less any fixups, is stored in BUF.
   1553    Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value
   1554    still needs to be converted to target byte order, otherwise BUF is an array
   1555    of bytes in target byte order.
   1556    The result is a pointer to the insn's entry in the opcode table,
   1557    or NULL if an error occured (an error message will have already been
   1558    printed).
   1559 
   1560    Note that when processing (non-alias) macro-insns,
   1561    this function recurses.
   1562 
   1563    ??? It's possible to make this cpu-independent.
   1564    One would have to deal with a few minor things.
   1565    At this point in time doing so would be more of a curiosity than useful
   1566    [for example this file isn't _that_ big], but keeping the possibility in
   1567    mind helps keep the design clean.  */
   1568 
   1569 const CGEN_INSN *
   1570 frv_cgen_assemble_insn (CGEN_CPU_DESC cd,
   1571 			   const char *str,
   1572 			   CGEN_FIELDS *fields,
   1573 			   CGEN_INSN_BYTES_PTR buf,
   1574 			   char **errmsg)
   1575 {
   1576   const char *start;
   1577   CGEN_INSN_LIST *ilist;
   1578   const char *parse_errmsg = NULL;
   1579   const char *insert_errmsg = NULL;
   1580   int recognized_mnemonic = 0;
   1581 
   1582   /* Skip leading white space.  */
   1583   while (ISSPACE (* str))
   1584     ++ str;
   1585 
   1586   /* The instructions are stored in hashed lists.
   1587      Get the first in the list.  */
   1588   ilist = CGEN_ASM_LOOKUP_INSN (cd, str);
   1589 
   1590   /* Keep looking until we find a match.  */
   1591   start = str;
   1592   for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist))
   1593     {
   1594       const CGEN_INSN *insn = ilist->insn;
   1595       recognized_mnemonic = 1;
   1596 
   1597 #ifdef CGEN_VALIDATE_INSN_SUPPORTED
   1598       /* Not usually needed as unsupported opcodes
   1599 	 shouldn't be in the hash lists.  */
   1600       /* Is this insn supported by the selected cpu?  */
   1601       if (! frv_cgen_insn_supported (cd, insn))
   1602 	continue;
   1603 #endif
   1604       /* If the RELAXED attribute is set, this is an insn that shouldn't be
   1605 	 chosen immediately.  Instead, it is used during assembler/linker
   1606 	 relaxation if possible.  */
   1607       if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0)
   1608 	continue;
   1609 
   1610       str = start;
   1611 
   1612       /* Skip this insn if str doesn't look right lexically.  */
   1613       if (CGEN_INSN_RX (insn) != NULL &&
   1614 	  regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH)
   1615 	continue;
   1616 
   1617       /* Allow parse/insert handlers to obtain length of insn.  */
   1618       CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
   1619 
   1620       parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields);
   1621       if (parse_errmsg != NULL)
   1622 	continue;
   1623 
   1624       /* ??? 0 is passed for `pc'.  */
   1625       insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf,
   1626 						 (bfd_vma) 0);
   1627       if (insert_errmsg != NULL)
   1628         continue;
   1629 
   1630       /* It is up to the caller to actually output the insn and any
   1631          queued relocs.  */
   1632       return insn;
   1633     }
   1634 
   1635   {
   1636     static char errbuf[150];
   1637     const char *tmp_errmsg;
   1638 #ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS
   1639 #define be_verbose 1
   1640 #else
   1641 #define be_verbose 0
   1642 #endif
   1643 
   1644     if (be_verbose)
   1645       {
   1646 	/* If requesting verbose error messages, use insert_errmsg.
   1647 	   Failing that, use parse_errmsg.  */
   1648 	tmp_errmsg = (insert_errmsg ? insert_errmsg :
   1649 		      parse_errmsg ? parse_errmsg :
   1650 		      recognized_mnemonic ?
   1651 		      _("unrecognized form of instruction") :
   1652 		      _("unrecognized instruction"));
   1653 
   1654 	if (strlen (start) > 50)
   1655 	  /* xgettext:c-format */
   1656 	  sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start);
   1657 	else
   1658 	  /* xgettext:c-format */
   1659 	  sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start);
   1660       }
   1661     else
   1662       {
   1663 	if (strlen (start) > 50)
   1664 	  /* xgettext:c-format */
   1665 	  sprintf (errbuf, _("bad instruction `%.50s...'"), start);
   1666 	else
   1667 	  /* xgettext:c-format */
   1668 	  sprintf (errbuf, _("bad instruction `%.50s'"), start);
   1669       }
   1670 
   1671     *errmsg = errbuf;
   1672     return NULL;
   1673   }
   1674 }
   1675