Home | History | Annotate | Download | only in opcodes
      1 /* Opcode table for the ARC.
      2    Copyright (C) 1994-2014 Free Software Foundation, Inc.
      3    Contributed by Doug Evans (dje (at) cygnus.com).
      4 
      5    This file is part of libopcodes.
      6 
      7    This library is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3, or (at your option)
     10    any later version.
     11 
     12    It is distributed in the hope that it will be useful, but WITHOUT
     13    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     14    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     15    License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with this program; if not, write to the Free Software Foundation,
     19    Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
     20 
     21 #include "sysdep.h"
     22 #include <stdio.h>
     23 #include "ansidecl.h"
     24 #include "bfd.h"
     25 #include "opcode/arc.h"
     26 #include "opintl.h"
     27 
     28 enum operand {OP_NONE,OP_REG,OP_SHIMM,OP_LIMM};
     29 
     30 #define OPERANDS 3
     31 
     32 enum operand ls_operand[OPERANDS];
     33 
     34 struct arc_opcode *arc_ext_opcodes;
     35 struct arc_ext_operand_value *arc_ext_operands;
     36 
     37 #define LS_VALUE  0
     38 #define LS_DEST   0
     39 #define LS_BASE   1
     40 #define LS_OFFSET 2
     41 
     42 /* Given a format letter, yields the index into `arc_operands'.
     43    eg: arc_operand_map['a'] = REGA.  */
     44 unsigned char arc_operand_map[256];
     45 
     46 /* Nonzero if we've seen an 'f' suffix (in certain insns).  */
     47 static int flag_p;
     48 
     49 /* Nonzero if we've finished processing the 'f' suffix.  */
     50 static int flagshimm_handled_p;
     51 
     52 /* Nonzero if we've seen a 'a' suffix (address writeback).  */
     53 static int addrwb_p;
     54 
     55 /* Nonzero if we've seen a 'q' suffix (condition code).  */
     56 static int cond_p;
     57 
     58 /* Nonzero if we've inserted a nullify condition.  */
     59 static int nullify_p;
     60 
     61 /* The value of the a nullify condition we inserted.  */
     62 static int nullify;
     63 
     64 /* Nonzero if we've inserted jumpflags.  */
     65 static int jumpflags_p;
     66 
     67 /* Nonzero if we've inserted a shimm.  */
     68 static int shimm_p;
     69 
     70 /* The value of the shimm we inserted (each insn only gets one but it can
     71    appear multiple times).  */
     72 static int shimm;
     73 
     74 /* Nonzero if we've inserted a limm (during assembly) or seen a limm
     75    (during disassembly).  */
     76 static int limm_p;
     77 
     78 /* The value of the limm we inserted.  Each insn only gets one but it can
     79    appear multiple times.  */
     80 static long limm;
     81 
     82 #define INSERT_FN(fn) \
     84 static arc_insn fn (arc_insn, const struct arc_operand *, \
     85 		    int, const struct arc_operand_value *, long, \
     86 		    const char **)
     87 
     88 #define EXTRACT_FN(fn) \
     89 static long fn (arc_insn *, const struct arc_operand *, \
     90 		int, const struct arc_operand_value **, int *)
     91 
     92 INSERT_FN (insert_reg);
     93 INSERT_FN (insert_shimmfinish);
     94 INSERT_FN (insert_limmfinish);
     95 INSERT_FN (insert_offset);
     96 INSERT_FN (insert_base);
     97 INSERT_FN (insert_st_syntax);
     98 INSERT_FN (insert_ld_syntax);
     99 INSERT_FN (insert_addr_wb);
    100 INSERT_FN (insert_flag);
    101 INSERT_FN (insert_nullify);
    102 INSERT_FN (insert_flagfinish);
    103 INSERT_FN (insert_cond);
    104 INSERT_FN (insert_forcelimm);
    105 INSERT_FN (insert_reladdr);
    106 INSERT_FN (insert_absaddr);
    107 INSERT_FN (insert_jumpflags);
    108 INSERT_FN (insert_unopmacro);
    109 
    110 EXTRACT_FN (extract_reg);
    111 EXTRACT_FN (extract_ld_offset);
    112 EXTRACT_FN (extract_ld_syntax);
    113 EXTRACT_FN (extract_st_offset);
    114 EXTRACT_FN (extract_st_syntax);
    115 EXTRACT_FN (extract_flag);
    116 EXTRACT_FN (extract_cond);
    117 EXTRACT_FN (extract_reladdr);
    118 EXTRACT_FN (extract_jumpflags);
    119 EXTRACT_FN (extract_unopmacro);
    120 
    121 /* Various types of ARC operands, including insn suffixes.  */
    122 
    123 /* Insn format values:
    124 
    125    'a'	REGA		register A field
    126    'b'	REGB		register B field
    127    'c'	REGC		register C field
    128    'S'	SHIMMFINISH	finish inserting a shimm value
    129    'L'	LIMMFINISH	finish inserting a limm value
    130    'o'	OFFSET		offset in st insns
    131    'O'	OFFSET		offset in ld insns
    132    '0'	SYNTAX_ST_NE	enforce store insn syntax, no errors
    133    '1'	SYNTAX_LD_NE	enforce load insn syntax, no errors
    134    '2'  SYNTAX_ST       enforce store insn syntax, errors, last pattern only
    135    '3'  SYNTAX_LD       enforce load insn syntax, errors, last pattern only
    136    's'  BASE            base in st insn
    137    'f'	FLAG		F flag
    138    'F'	FLAGFINISH	finish inserting the F flag
    139    'G'	FLAGINSN	insert F flag in "flag" insn
    140    'n'	DELAY		N field (nullify field)
    141    'q'	COND		condition code field
    142    'Q'	FORCELIMM	set `cond_p' to 1 to ensure a constant is a limm
    143    'B'	BRANCH		branch address (22 bit pc relative)
    144    'J'	JUMP		jump address (26 bit absolute)
    145    'j'  JUMPFLAGS       optional high order bits of 'J'
    146    'z'	SIZE1		size field in ld a,[b,c]
    147    'Z'	SIZE10		size field in ld a,[b,shimm]
    148    'y'	SIZE22		size field in st c,[b,shimm]
    149    'x'	SIGN0		sign extend field ld a,[b,c]
    150    'X'	SIGN9		sign extend field ld a,[b,shimm]
    151    'w'	ADDRESS3	write-back field in ld a,[b,c]
    152    'W'	ADDRESS12	write-back field in ld a,[b,shimm]
    153    'v'	ADDRESS24	write-back field in st c,[b,shimm]
    154    'e'	CACHEBYPASS5	cache bypass in ld a,[b,c]
    155    'E'	CACHEBYPASS14	cache bypass in ld a,[b,shimm]
    156    'D'	CACHEBYPASS26	cache bypass in st c,[b,shimm]
    157    'U'	UNOPMACRO	fake operand to copy REGB to REGC for unop macros
    158 
    159    The following modifiers may appear between the % and char (eg: %.f):
    160 
    161    '.'	MODDOT		'.' prefix must be present
    162    'r'	REG		generic register value, for register table
    163    'A'	AUXREG		auxiliary register in lr a,[b], sr c,[b]
    164 
    165    Fields are:
    166 
    167    CHAR BITS SHIFT FLAGS INSERT_FN EXTRACT_FN  */
    168 
    169 const struct arc_operand arc_operands[] =
    170 {
    171 /* Place holder (??? not sure if needed).  */
    172 #define UNUSED 0
    173   { 0, 0, 0, 0, 0, 0 },
    174 
    175 /* Register A or shimm/limm indicator.  */
    176 #define REGA (UNUSED + 1)
    177   { 'a', 6, ARC_SHIFT_REGA, ARC_OPERAND_SIGNED | ARC_OPERAND_ERROR, insert_reg, extract_reg },
    178 
    179 /* Register B or shimm/limm indicator.  */
    180 #define REGB (REGA + 1)
    181   { 'b', 6, ARC_SHIFT_REGB, ARC_OPERAND_SIGNED | ARC_OPERAND_ERROR, insert_reg, extract_reg },
    182 
    183 /* Register C or shimm/limm indicator.  */
    184 #define REGC (REGB + 1)
    185   { 'c', 6, ARC_SHIFT_REGC, ARC_OPERAND_SIGNED | ARC_OPERAND_ERROR, insert_reg, extract_reg },
    186 
    187 /* Fake operand used to insert shimm value into most instructions.  */
    188 #define SHIMMFINISH (REGC + 1)
    189   { 'S', 9, 0, ARC_OPERAND_SIGNED + ARC_OPERAND_FAKE, insert_shimmfinish, 0 },
    190 
    191 /* Fake operand used to insert limm value into most instructions.  */
    192 #define LIMMFINISH (SHIMMFINISH + 1)
    193   { 'L', 32, 32, ARC_OPERAND_ADDRESS + ARC_OPERAND_LIMM + ARC_OPERAND_FAKE, insert_limmfinish, 0 },
    194 
    195 /* Shimm operand when there is no reg indicator (st).  */
    196 #define ST_OFFSET (LIMMFINISH + 1)
    197   { 'o', 9, 0, ARC_OPERAND_LIMM | ARC_OPERAND_SIGNED | ARC_OPERAND_STORE, insert_offset, extract_st_offset },
    198 
    199 /* Shimm operand when there is no reg indicator (ld).  */
    200 #define LD_OFFSET (ST_OFFSET + 1)
    201   { 'O', 9, 0,ARC_OPERAND_LIMM | ARC_OPERAND_SIGNED | ARC_OPERAND_LOAD, insert_offset, extract_ld_offset },
    202 
    203 /* Operand for base.  */
    204 #define BASE (LD_OFFSET + 1)
    205   { 's', 6, ARC_SHIFT_REGB, ARC_OPERAND_LIMM | ARC_OPERAND_SIGNED, insert_base, extract_reg},
    206 
    207 /* 0 enforce syntax for st insns.  */
    208 #define SYNTAX_ST_NE (BASE + 1)
    209   { '0', 9, 0, ARC_OPERAND_FAKE, insert_st_syntax, extract_st_syntax },
    210 
    211 /* 1 enforce syntax for ld insns.  */
    212 #define SYNTAX_LD_NE (SYNTAX_ST_NE + 1)
    213   { '1', 9, 0, ARC_OPERAND_FAKE, insert_ld_syntax, extract_ld_syntax },
    214 
    215 /* 0 enforce syntax for st insns.  */
    216 #define SYNTAX_ST (SYNTAX_LD_NE + 1)
    217   { '2', 9, 0, ARC_OPERAND_FAKE | ARC_OPERAND_ERROR, insert_st_syntax, extract_st_syntax },
    218 
    219 /* 0 enforce syntax for ld insns.  */
    220 #define SYNTAX_LD (SYNTAX_ST + 1)
    221   { '3', 9, 0, ARC_OPERAND_FAKE | ARC_OPERAND_ERROR, insert_ld_syntax, extract_ld_syntax },
    222 
    223 /* Flag update bit (insertion is defered until we know how).  */
    224 #define FLAG (SYNTAX_LD + 1)
    225   { 'f', 1, 8, ARC_OPERAND_SUFFIX, insert_flag, extract_flag },
    226 
    227 /* Fake utility operand to finish 'f' suffix handling.  */
    228 #define FLAGFINISH (FLAG + 1)
    229   { 'F', 1, 8, ARC_OPERAND_FAKE, insert_flagfinish, 0 },
    230 
    231 /* Fake utility operand to set the 'f' flag for the "flag" insn.  */
    232 #define FLAGINSN (FLAGFINISH + 1)
    233   { 'G', 1, 8, ARC_OPERAND_FAKE, insert_flag, 0 },
    234 
    235 /* Branch delay types.  */
    236 #define DELAY (FLAGINSN + 1)
    237   { 'n', 2, 5, ARC_OPERAND_SUFFIX , insert_nullify, 0 },
    238 
    239 /* Conditions.  */
    240 #define COND (DELAY + 1)
    241   { 'q', 5, 0, ARC_OPERAND_SUFFIX, insert_cond, extract_cond },
    242 
    243 /* Set `cond_p' to 1 to ensure a constant is treated as a limm.  */
    244 #define FORCELIMM (COND + 1)
    245   { 'Q', 0, 0, ARC_OPERAND_FAKE, insert_forcelimm, 0 },
    246 
    247 /* Branch address; b, bl, and lp insns.  */
    248 #define BRANCH (FORCELIMM + 1)
    249   { 'B', 20, 7, (ARC_OPERAND_RELATIVE_BRANCH + ARC_OPERAND_SIGNED) | ARC_OPERAND_ERROR, insert_reladdr, extract_reladdr },
    250 
    251 /* Jump address; j insn (this is basically the same as 'L' except that the
    252    value is right shifted by 2).  */
    253 #define JUMP (BRANCH + 1)
    254   { 'J', 24, 32, ARC_OPERAND_ERROR | (ARC_OPERAND_ABSOLUTE_BRANCH + ARC_OPERAND_LIMM + ARC_OPERAND_FAKE), insert_absaddr, 0 },
    255 
    256 /* Jump flags; j{,l} insn value or'ed into 'J' addr for flag values.  */
    257 #define JUMPFLAGS (JUMP + 1)
    258   { 'j', 6, 26, ARC_OPERAND_JUMPFLAGS | ARC_OPERAND_ERROR, insert_jumpflags, extract_jumpflags },
    259 
    260 /* Size field, stored in bit 1,2.  */
    261 #define SIZE1 (JUMPFLAGS + 1)
    262   { 'z', 2, 1, ARC_OPERAND_SUFFIX, 0, 0 },
    263 
    264 /* Size field, stored in bit 10,11.  */
    265 #define SIZE10 (SIZE1 + 1)
    266   { 'Z', 2, 10, ARC_OPERAND_SUFFIX, 0, 0 },
    267 
    268 /* Size field, stored in bit 22,23.  */
    269 #define SIZE22 (SIZE10 + 1)
    270   { 'y', 2, 22, ARC_OPERAND_SUFFIX, 0, 0 },
    271 
    272 /* Sign extend field, stored in bit 0.  */
    273 #define SIGN0 (SIZE22 + 1)
    274   { 'x', 1, 0, ARC_OPERAND_SUFFIX, 0, 0 },
    275 
    276 /* Sign extend field, stored in bit 9.  */
    277 #define SIGN9 (SIGN0 + 1)
    278   { 'X', 1, 9, ARC_OPERAND_SUFFIX, 0, 0 },
    279 
    280 /* Address write back, stored in bit 3.  */
    281 #define ADDRESS3 (SIGN9 + 1)
    282   { 'w', 1, 3, ARC_OPERAND_SUFFIX, insert_addr_wb, 0},
    283 
    284 /* Address write back, stored in bit 12.  */
    285 #define ADDRESS12 (ADDRESS3 + 1)
    286   { 'W', 1, 12, ARC_OPERAND_SUFFIX, insert_addr_wb, 0},
    287 
    288 /* Address write back, stored in bit 24.  */
    289 #define ADDRESS24 (ADDRESS12 + 1)
    290   { 'v', 1, 24, ARC_OPERAND_SUFFIX, insert_addr_wb, 0},
    291 
    292 /* Cache bypass, stored in bit 5.  */
    293 #define CACHEBYPASS5 (ADDRESS24 + 1)
    294   { 'e', 1, 5, ARC_OPERAND_SUFFIX, 0, 0 },
    295 
    296 /* Cache bypass, stored in bit 14.  */
    297 #define CACHEBYPASS14 (CACHEBYPASS5 + 1)
    298   { 'E', 1, 14, ARC_OPERAND_SUFFIX, 0, 0 },
    299 
    300 /* Cache bypass, stored in bit 26.  */
    301 #define CACHEBYPASS26 (CACHEBYPASS14 + 1)
    302   { 'D', 1, 26, ARC_OPERAND_SUFFIX, 0, 0 },
    303 
    304 /* Unop macro, used to copy REGB to REGC.  */
    305 #define UNOPMACRO (CACHEBYPASS26 + 1)
    306   { 'U', 6, ARC_SHIFT_REGC, ARC_OPERAND_FAKE, insert_unopmacro, extract_unopmacro },
    307 
    308 /* '.' modifier ('.' required).  */
    309 #define MODDOT (UNOPMACRO + 1)
    310   { '.', 1, 0, ARC_MOD_DOT, 0, 0 },
    311 
    312 /* Dummy 'r' modifier for the register table.
    313    It's called a "dummy" because there's no point in inserting an 'r' into all
    314    the %a/%b/%c occurrences in the insn table.  */
    315 #define REG (MODDOT + 1)
    316   { 'r', 6, 0, ARC_MOD_REG, 0, 0 },
    317 
    318 /* Known auxiliary register modifier (stored in shimm field).  */
    319 #define AUXREG (REG + 1)
    320   { 'A', 9, 0, ARC_MOD_AUXREG, 0, 0 },
    321 
    322 /* End of list place holder.  */
    323   { 0, 0, 0, 0, 0, 0 }
    324 };
    325 
    326 /* Insert a value into a register field.
    328    If REG is NULL, then this is actually a constant.
    329 
    330    We must also handle auxiliary registers for lr/sr insns.  */
    331 
    332 static arc_insn
    333 insert_reg (arc_insn insn,
    334 	    const struct arc_operand *operand,
    335 	    int mods,
    336 	    const struct arc_operand_value *reg,
    337 	    long value,
    338 	    const char **errmsg)
    339 {
    340   static char buf[100];
    341   enum operand op_type = OP_NONE;
    342 
    343   if (reg == NULL)
    344     {
    345       /* We have a constant that also requires a value stored in a register
    346 	 field.  Handle these by updating the register field and saving the
    347 	 value for later handling by either %S (shimm) or %L (limm).  */
    348 
    349       /* Try to use a shimm value before a limm one.  */
    350       if (ARC_SHIMM_CONST_P (value)
    351 	  /* If we've seen a conditional suffix we have to use a limm.  */
    352 	  && !cond_p
    353 	  /* If we already have a shimm value that is different than ours
    354 	     we have to use a limm.  */
    355 	  && (!shimm_p || shimm == value))
    356 	{
    357 	  int marker;
    358 
    359 	  op_type = OP_SHIMM;
    360 	  /* Forget about shimm as dest mlm.  */
    361 
    362 	  if ('a' != operand->fmt)
    363 	    {
    364 	      shimm_p = 1;
    365 	      shimm = value;
    366 	      flagshimm_handled_p = 1;
    367 	      marker = flag_p ? ARC_REG_SHIMM_UPDATE : ARC_REG_SHIMM;
    368 	    }
    369 	  else
    370 	    {
    371 	      /* Don't request flag setting on shimm as dest.  */
    372 	      marker = ARC_REG_SHIMM;
    373 	    }
    374 	  insn |= marker << operand->shift;
    375 	  /* insn |= value & 511; - done later.  */
    376 	}
    377       /* We have to use a limm.  If we've already seen one they must match.  */
    378       else if (!limm_p || limm == value)
    379 	{
    380 	  op_type = OP_LIMM;
    381 	  limm_p = 1;
    382 	  limm = value;
    383 	  insn |= ARC_REG_LIMM << operand->shift;
    384 	  /* The constant is stored later.  */
    385 	}
    386       else
    387 	*errmsg = _("unable to fit different valued constants into instruction");
    388     }
    389   else
    390     {
    391       /* We have to handle both normal and auxiliary registers.  */
    392 
    393       if (reg->type == AUXREG)
    394 	{
    395 	  if (!(mods & ARC_MOD_AUXREG))
    396 	    *errmsg = _("auxiliary register not allowed here");
    397 	  else
    398 	    {
    399 	      if ((insn & I(-1)) == I(2)) /* Check for use validity.  */
    400 		{
    401 		  if (reg->flags & ARC_REGISTER_READONLY)
    402 		    *errmsg = _("attempt to set readonly register");
    403 		}
    404 	      else
    405 		{
    406 		  if (reg->flags & ARC_REGISTER_WRITEONLY)
    407 		    *errmsg = _("attempt to read writeonly register");
    408 		}
    409 	      insn |= ARC_REG_SHIMM << operand->shift;
    410 	      insn |= reg->value << arc_operands[reg->type].shift;
    411 	    }
    412 	}
    413       else
    414 	{
    415 	  /* check for use validity.  */
    416 	  if ('a' == operand->fmt || ((insn & I(-1)) < I(2)))
    417 	    {
    418 	      if (reg->flags & ARC_REGISTER_READONLY)
    419 		*errmsg = _("attempt to set readonly register");
    420 	    }
    421 	  if ('a' != operand->fmt)
    422 	    {
    423 	      if (reg->flags & ARC_REGISTER_WRITEONLY)
    424 		*errmsg = _("attempt to read writeonly register");
    425 	    }
    426 	  /* We should never get an invalid register number here.  */
    427 	  if ((unsigned int) reg->value > 60)
    428 	    {
    429 	      sprintf (buf, _("invalid register number `%d'"), reg->value);
    430 	      *errmsg = buf;
    431 	    }
    432 	  insn |= reg->value << operand->shift;
    433 	  op_type = OP_REG;
    434 	}
    435     }
    436 
    437   switch (operand->fmt)
    438     {
    439     case 'a':
    440       ls_operand[LS_DEST] = op_type;
    441       break;
    442     case 's':
    443       ls_operand[LS_BASE] = op_type;
    444       break;
    445     case 'c':
    446       if ((insn & I(-1)) == I(2))
    447 	ls_operand[LS_VALUE] = op_type;
    448       else
    449 	ls_operand[LS_OFFSET] = op_type;
    450       break;
    451     case 'o': case 'O':
    452       ls_operand[LS_OFFSET] = op_type;
    453       break;
    454     }
    455 
    456   return insn;
    457 }
    458 
    459 /* Called when we see an 'f' flag.  */
    460 
    461 static arc_insn
    462 insert_flag (arc_insn insn,
    463 	     const struct arc_operand *operand ATTRIBUTE_UNUSED,
    464 	     int mods ATTRIBUTE_UNUSED,
    465 	     const struct arc_operand_value *reg ATTRIBUTE_UNUSED,
    466 	     long value ATTRIBUTE_UNUSED,
    467 	     const char **errmsg ATTRIBUTE_UNUSED)
    468 {
    469   /* We can't store anything in the insn until we've parsed the registers.
    470      Just record the fact that we've got this flag.  `insert_reg' will use it
    471      to store the correct value (ARC_REG_SHIMM_UPDATE or bit 0x100).  */
    472   flag_p = 1;
    473   return insn;
    474 }
    475 
    476 /* Called when we see an nullify condition.  */
    477 
    478 static arc_insn
    479 insert_nullify (arc_insn insn,
    480 		const struct arc_operand *operand,
    481 		int mods ATTRIBUTE_UNUSED,
    482 		const struct arc_operand_value *reg ATTRIBUTE_UNUSED,
    483 		long value,
    484 		const char **errmsg ATTRIBUTE_UNUSED)
    485 {
    486   nullify_p = 1;
    487   insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
    488   nullify = value;
    489   return insn;
    490 }
    491 
    492 /* Called after completely building an insn to ensure the 'f' flag gets set
    493    properly.  This is needed because we don't know how to set this flag until
    494    we've parsed the registers.  */
    495 
    496 static arc_insn
    497 insert_flagfinish (arc_insn insn,
    498 		   const struct arc_operand *operand,
    499 		   int mods ATTRIBUTE_UNUSED,
    500 		   const struct arc_operand_value *reg ATTRIBUTE_UNUSED,
    501 		   long value ATTRIBUTE_UNUSED,
    502 		   const char **errmsg ATTRIBUTE_UNUSED)
    503 {
    504   if (flag_p && !flagshimm_handled_p)
    505     {
    506       if (shimm_p)
    507 	abort ();
    508       flagshimm_handled_p = 1;
    509       insn |= (1 << operand->shift);
    510     }
    511   return insn;
    512 }
    513 
    514 /* Called when we see a conditional flag (eg: .eq).  */
    515 
    516 static arc_insn
    517 insert_cond (arc_insn insn,
    518 	     const struct arc_operand *operand,
    519 	     int mods ATTRIBUTE_UNUSED,
    520 	     const struct arc_operand_value *reg ATTRIBUTE_UNUSED,
    521 	     long value,
    522 	     const char **errmsg ATTRIBUTE_UNUSED)
    523 {
    524   cond_p = 1;
    525   insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
    526   return insn;
    527 }
    528 
    529 /* Used in the "j" instruction to prevent constants from being interpreted as
    530    shimm values (which the jump insn doesn't accept).  This can also be used
    531    to force the use of limm values in other situations (eg: ld r0,[foo] uses
    532    this).
    533    ??? The mechanism is sound.  Access to it is a bit klunky right now.  */
    534 
    535 static arc_insn
    536 insert_forcelimm (arc_insn insn,
    537 		  const struct arc_operand *operand ATTRIBUTE_UNUSED,
    538 		  int mods ATTRIBUTE_UNUSED,
    539 		  const struct arc_operand_value *reg ATTRIBUTE_UNUSED,
    540 		  long value ATTRIBUTE_UNUSED,
    541 		  const char **errmsg ATTRIBUTE_UNUSED)
    542 {
    543   cond_p = 1;
    544   return insn;
    545 }
    546 
    547 static arc_insn
    548 insert_addr_wb (arc_insn insn,
    549 		const struct arc_operand *operand,
    550 		int mods ATTRIBUTE_UNUSED,
    551 		const struct arc_operand_value *reg ATTRIBUTE_UNUSED,
    552 		long value ATTRIBUTE_UNUSED,
    553 		const char **errmsg ATTRIBUTE_UNUSED)
    554 {
    555   addrwb_p = 1 << operand->shift;
    556   return insn;
    557 }
    558 
    559 static arc_insn
    560 insert_base (arc_insn insn,
    561 	     const struct arc_operand *operand,
    562 	     int mods,
    563 	     const struct arc_operand_value *reg,
    564 	     long value,
    565 	     const char **errmsg)
    566 {
    567   if (reg != NULL)
    568     {
    569       arc_insn myinsn;
    570       myinsn = insert_reg (0, operand,mods, reg, value, errmsg) >> operand->shift;
    571       insn |= B(myinsn);
    572       ls_operand[LS_BASE] = OP_REG;
    573     }
    574   else if (ARC_SHIMM_CONST_P (value) && !cond_p)
    575     {
    576       if (shimm_p && value != shimm)
    577 	{
    578 	  /* Convert the previous shimm operand to a limm.  */
    579 	  limm_p = 1;
    580 	  limm = shimm;
    581 	  insn &= ~C(-1); /* We know where the value is in insn.  */
    582 	  insn |= C(ARC_REG_LIMM);
    583 	  ls_operand[LS_VALUE] = OP_LIMM;
    584 	}
    585       insn |= ARC_REG_SHIMM << operand->shift;
    586       shimm_p = 1;
    587       shimm = value;
    588       ls_operand[LS_BASE] = OP_SHIMM;
    589       ls_operand[LS_OFFSET] = OP_SHIMM;
    590     }
    591   else
    592     {
    593       if (limm_p && value != limm)
    594 	{
    595 	  *errmsg = _("too many long constants");
    596 	  return insn;
    597 	}
    598       limm_p = 1;
    599       limm = value;
    600       insn |= B(ARC_REG_LIMM);
    601       ls_operand[LS_BASE] = OP_LIMM;
    602     }
    603 
    604   return insn;
    605 }
    606 
    607 /* Used in ld/st insns to handle the offset field. We don't try to
    608    match operand syntax here. we catch bad combinations later.  */
    609 
    610 static arc_insn
    611 insert_offset (arc_insn insn,
    612 	       const struct arc_operand *operand,
    613 	       int mods,
    614 	       const struct arc_operand_value *reg,
    615 	       long value,
    616 	       const char **errmsg)
    617 {
    618   long minval, maxval;
    619 
    620   if (reg != NULL)
    621     {
    622       arc_insn myinsn;
    623       myinsn = insert_reg (0,operand,mods,reg,value,errmsg) >> operand->shift;
    624       ls_operand[LS_OFFSET] = OP_REG;
    625       if (operand->flags & ARC_OPERAND_LOAD) /* Not if store, catch it later.  */
    626 	if ((insn & I(-1)) != I(1)) /* Not if opcode == 1, catch it later.  */
    627 	  insn |= C (myinsn);
    628     }
    629   else
    630     {
    631       /* This is *way* more general than necessary, but maybe some day it'll
    632 	 be useful.  */
    633       if (operand->flags & ARC_OPERAND_SIGNED)
    634 	{
    635 	  minval = -(1 << (operand->bits - 1));
    636 	  maxval = (1 << (operand->bits - 1)) - 1;
    637 	}
    638       else
    639 	{
    640 	  minval = 0;
    641 	  maxval = (1 << operand->bits) - 1;
    642 	}
    643       if ((cond_p && !limm_p) || (value < minval || value > maxval))
    644 	{
    645 	  if (limm_p && value != limm)
    646 	    *errmsg = _("too many long constants");
    647 
    648 	  else
    649 	    {
    650 	      limm_p = 1;
    651 	      limm = value;
    652 	      if (operand->flags & ARC_OPERAND_STORE)
    653 		insn |= B(ARC_REG_LIMM);
    654 	      if (operand->flags & ARC_OPERAND_LOAD)
    655 		insn |= C(ARC_REG_LIMM);
    656 	      ls_operand[LS_OFFSET] = OP_LIMM;
    657 	    }
    658 	}
    659       else
    660 	{
    661 	  if ((value < minval || value > maxval))
    662 	    *errmsg = "need too many limms";
    663 	  else if (shimm_p && value != shimm)
    664 	    {
    665 	      /* Check for bad operand combinations
    666 		 before we lose info about them.  */
    667 	      if ((insn & I(-1)) == I(1))
    668 		{
    669 		  *errmsg = _("too many shimms in load");
    670 		  goto out;
    671 		}
    672 	      if (limm_p && operand->flags & ARC_OPERAND_LOAD)
    673 		{
    674 		  *errmsg = _("too many long constants");
    675 		  goto out;
    676 		}
    677 	      /* Convert what we thought was a shimm to a limm.  */
    678 	      limm_p = 1;
    679 	      limm = shimm;
    680 	      if (ls_operand[LS_VALUE] == OP_SHIMM
    681 		  && operand->flags & ARC_OPERAND_STORE)
    682 		{
    683 		  insn &= ~C(-1);
    684 		  insn |= C(ARC_REG_LIMM);
    685 		  ls_operand[LS_VALUE] = OP_LIMM;
    686 		}
    687 	      if (ls_operand[LS_BASE] == OP_SHIMM
    688 		  && operand->flags & ARC_OPERAND_STORE)
    689 		{
    690 		  insn &= ~B(-1);
    691 		  insn |= B(ARC_REG_LIMM);
    692 		  ls_operand[LS_BASE] = OP_LIMM;
    693 		}
    694 	    }
    695 	  shimm = value;
    696 	  shimm_p = 1;
    697 	  ls_operand[LS_OFFSET] = OP_SHIMM;
    698 	}
    699     }
    700  out:
    701   return insn;
    702 }
    703 
    704 /* Used in st insns to do final disasemble syntax check.  */
    705 
    706 static long
    707 extract_st_syntax (arc_insn *insn,
    708 		   const struct arc_operand *operand ATTRIBUTE_UNUSED,
    709 		   int mods ATTRIBUTE_UNUSED,
    710 		   const struct arc_operand_value **opval ATTRIBUTE_UNUSED,
    711 		   int *invalid)
    712 {
    713 #define ST_SYNTAX(V,B,O) \
    714 ((ls_operand[LS_VALUE]  == (V) && \
    715   ls_operand[LS_BASE]   == (B) && \
    716   ls_operand[LS_OFFSET] == (O)))
    717 
    718   if (!((ST_SYNTAX(OP_REG,OP_REG,OP_NONE) && (insn[0] & 511) == 0)
    719 	|| ST_SYNTAX(OP_REG,OP_LIMM,OP_NONE)
    720 	|| (ST_SYNTAX(OP_SHIMM,OP_REG,OP_NONE) && (insn[0] & 511) == 0)
    721 	|| (ST_SYNTAX(OP_SHIMM,OP_SHIMM,OP_NONE) && (insn[0] & 511) == 0)
    722 	|| ST_SYNTAX(OP_SHIMM,OP_LIMM,OP_NONE)
    723 	|| ST_SYNTAX(OP_SHIMM,OP_LIMM,OP_SHIMM)
    724 	|| ST_SYNTAX(OP_SHIMM,OP_SHIMM,OP_SHIMM)
    725 	|| (ST_SYNTAX(OP_LIMM,OP_REG,OP_NONE) && (insn[0] & 511) == 0)
    726 	|| ST_SYNTAX(OP_REG,OP_REG,OP_SHIMM)
    727 	|| ST_SYNTAX(OP_REG,OP_SHIMM,OP_SHIMM)
    728 	|| ST_SYNTAX(OP_SHIMM,OP_REG,OP_SHIMM)
    729 	|| ST_SYNTAX(OP_LIMM,OP_SHIMM,OP_SHIMM)
    730 	|| ST_SYNTAX(OP_LIMM,OP_SHIMM,OP_NONE)
    731 	|| ST_SYNTAX(OP_LIMM,OP_REG,OP_SHIMM)))
    732     *invalid = 1;
    733   return 0;
    734 }
    735 
    736 int
    737 arc_limm_fixup_adjust (arc_insn insn)
    738 {
    739   int retval = 0;
    740 
    741   /* Check for st shimm,[limm].  */
    742   if ((insn & (I(-1) | C(-1) | B(-1))) ==
    743       (I(2) | C(ARC_REG_SHIMM) | B(ARC_REG_LIMM)))
    744     {
    745       retval = insn & 0x1ff;
    746       if (retval & 0x100) /* Sign extend 9 bit offset.  */
    747 	retval |= ~0x1ff;
    748     }
    749   return -retval; /* Negate offset for return.  */
    750 }
    751 
    752 /* Used in st insns to do final syntax check.  */
    753 
    754 static arc_insn
    755 insert_st_syntax (arc_insn insn,
    756 		  const struct arc_operand *operand ATTRIBUTE_UNUSED,
    757 		  int mods ATTRIBUTE_UNUSED,
    758 		  const struct arc_operand_value *reg ATTRIBUTE_UNUSED,
    759 		  long value ATTRIBUTE_UNUSED,
    760 		  const char **errmsg)
    761 {
    762   if (ST_SYNTAX (OP_SHIMM,OP_REG,OP_NONE) && shimm != 0)
    763     {
    764       /* Change an illegal insn into a legal one, it's easier to
    765 	 do it here than to try to handle it during operand scan.  */
    766       limm_p = 1;
    767       limm = shimm;
    768       shimm_p = 0;
    769       shimm = 0;
    770       insn = insn & ~(C(-1) | 511);
    771       insn |= ARC_REG_LIMM << ARC_SHIFT_REGC;
    772       ls_operand[LS_VALUE] = OP_LIMM;
    773     }
    774 
    775   if (ST_SYNTAX (OP_REG, OP_SHIMM, OP_NONE)
    776       || ST_SYNTAX (OP_LIMM, OP_SHIMM, OP_NONE))
    777     {
    778       /* Try to salvage this syntax.  */
    779       if (shimm & 0x1) /* Odd shimms won't work.  */
    780 	{
    781 	  if (limm_p) /* Do we have a limm already?  */
    782 	    *errmsg = _("impossible store");
    783 
    784 	  limm_p = 1;
    785 	  limm = shimm;
    786 	  shimm = 0;
    787 	  shimm_p = 0;
    788 	  insn = insn & ~(B(-1) | 511);
    789 	  insn |= B(ARC_REG_LIMM);
    790 	  ls_operand[LS_BASE] = OP_LIMM;
    791 	}
    792       else
    793 	{
    794 	  shimm >>= 1;
    795 	  insn = insn & ~511;
    796 	  insn |= shimm;
    797 	  ls_operand[LS_OFFSET] = OP_SHIMM;
    798 	}
    799     }
    800   if (ST_SYNTAX(OP_SHIMM,OP_LIMM,OP_NONE))
    801     limm += arc_limm_fixup_adjust(insn);
    802 
    803   if (!   (ST_SYNTAX (OP_REG,OP_REG,OP_NONE)
    804 	|| ST_SYNTAX (OP_REG,OP_LIMM,OP_NONE)
    805 	|| ST_SYNTAX (OP_REG,OP_REG,OP_SHIMM)
    806 	|| ST_SYNTAX (OP_REG,OP_SHIMM,OP_SHIMM)
    807 	|| (ST_SYNTAX (OP_SHIMM,OP_SHIMM,OP_NONE) && (shimm == 0))
    808 	|| ST_SYNTAX (OP_SHIMM,OP_LIMM,OP_NONE)
    809 	|| ST_SYNTAX (OP_SHIMM,OP_REG,OP_NONE)
    810 	|| ST_SYNTAX (OP_SHIMM,OP_REG,OP_SHIMM)
    811 	|| ST_SYNTAX (OP_SHIMM,OP_SHIMM,OP_SHIMM)
    812 	|| ST_SYNTAX (OP_LIMM,OP_SHIMM,OP_SHIMM)
    813 	|| ST_SYNTAX (OP_LIMM,OP_REG,OP_NONE)
    814 	|| ST_SYNTAX (OP_LIMM,OP_REG,OP_SHIMM)))
    815     *errmsg = _("st operand error");
    816   if (addrwb_p)
    817     {
    818       if (ls_operand[LS_BASE] != OP_REG)
    819 	*errmsg = _("address writeback not allowed");
    820       insn |= addrwb_p;
    821     }
    822   if (ST_SYNTAX(OP_SHIMM,OP_REG,OP_NONE) && shimm)
    823     *errmsg = _("store value must be zero");
    824   return insn;
    825 }
    826 
    827 /* Used in ld insns to do final syntax check.  */
    828 
    829 static arc_insn
    830 insert_ld_syntax (arc_insn insn,
    831 		  const struct arc_operand *operand ATTRIBUTE_UNUSED,
    832 		  int mods ATTRIBUTE_UNUSED,
    833 		  const struct arc_operand_value *reg ATTRIBUTE_UNUSED,
    834 		  long value ATTRIBUTE_UNUSED,
    835 		  const char **errmsg)
    836 {
    837 #define LD_SYNTAX(D, B, O) \
    838   (   (ls_operand[LS_DEST]   == (D) \
    839     && ls_operand[LS_BASE]   == (B) \
    840     && ls_operand[LS_OFFSET] == (O)))
    841 
    842   int test = insn & I (-1);
    843 
    844   if (!(test == I (1)))
    845     {
    846       if ((ls_operand[LS_DEST] == OP_SHIMM || ls_operand[LS_BASE] == OP_SHIMM
    847 	   || ls_operand[LS_OFFSET] == OP_SHIMM))
    848 	*errmsg = _("invalid load/shimm insn");
    849     }
    850   if (!(LD_SYNTAX(OP_REG,OP_REG,OP_NONE)
    851 	|| LD_SYNTAX(OP_REG,OP_REG,OP_REG)
    852 	|| LD_SYNTAX(OP_REG,OP_REG,OP_SHIMM)
    853 	|| (LD_SYNTAX(OP_REG,OP_LIMM,OP_REG) && !(test == I(1)))
    854 	|| (LD_SYNTAX(OP_REG,OP_REG,OP_LIMM) && !(test == I(1)))
    855 	|| LD_SYNTAX(OP_REG,OP_SHIMM,OP_SHIMM)
    856 	|| (LD_SYNTAX(OP_REG,OP_LIMM,OP_NONE) && (test == I(1)))))
    857     *errmsg = _("ld operand error");
    858   if (addrwb_p)
    859     {
    860       if (ls_operand[LS_BASE] != OP_REG)
    861 	*errmsg = _("address writeback not allowed");
    862       insn |= addrwb_p;
    863     }
    864   return insn;
    865 }
    866 
    867 /* Used in ld insns to do final syntax check.  */
    868 
    869 static long
    870 extract_ld_syntax (arc_insn *insn,
    871 		   const struct arc_operand *operand ATTRIBUTE_UNUSED,
    872 		   int mods ATTRIBUTE_UNUSED,
    873 		   const struct arc_operand_value **opval ATTRIBUTE_UNUSED,
    874 		   int *invalid)
    875 {
    876   int test = insn[0] & I(-1);
    877 
    878   if (!(test == I(1)))
    879     {
    880       if ((ls_operand[LS_DEST] == OP_SHIMM || ls_operand[LS_BASE] == OP_SHIMM
    881 	   || ls_operand[LS_OFFSET] == OP_SHIMM))
    882 	*invalid = 1;
    883     }
    884   if (!(   (LD_SYNTAX (OP_REG, OP_REG, OP_NONE) && (test == I(1)))
    885 	||  LD_SYNTAX (OP_REG, OP_REG, OP_REG)
    886 	||  LD_SYNTAX (OP_REG, OP_REG, OP_SHIMM)
    887 	|| (LD_SYNTAX (OP_REG, OP_REG, OP_LIMM) && !(test == I(1)))
    888 	|| (LD_SYNTAX (OP_REG, OP_LIMM, OP_REG) && !(test == I(1)))
    889 	|| (LD_SYNTAX (OP_REG, OP_SHIMM, OP_NONE) && (shimm == 0))
    890 	||  LD_SYNTAX (OP_REG, OP_SHIMM, OP_SHIMM)
    891 	|| (LD_SYNTAX (OP_REG, OP_LIMM, OP_NONE) && (test == I(1)))))
    892     *invalid = 1;
    893   return 0;
    894 }
    895 
    896 /* Called at the end of processing normal insns (eg: add) to insert a shimm
    897    value (if present) into the insn.  */
    898 
    899 static arc_insn
    900 insert_shimmfinish (arc_insn insn,
    901 		    const struct arc_operand *operand,
    902 		    int mods ATTRIBUTE_UNUSED,
    903 		    const struct arc_operand_value *reg ATTRIBUTE_UNUSED,
    904 		    long value ATTRIBUTE_UNUSED,
    905 		    const char **errmsg ATTRIBUTE_UNUSED)
    906 {
    907   if (shimm_p)
    908     insn |= (shimm & ((1 << operand->bits) - 1)) << operand->shift;
    909   return insn;
    910 }
    911 
    912 /* Called at the end of processing normal insns (eg: add) to insert a limm
    913    value (if present) into the insn.
    914 
    915    Note that this function is only intended to handle instructions (with 4 byte
    916    immediate operands).  It is not intended to handle data.  */
    917 
    918 /* ??? Actually, there's nothing for us to do as we can't call frag_more, the
    919    caller must do that.  The extract fns take a pointer to two words.  The
    920    insert fns could be converted and then we could do something useful, but
    921    then the reloc handlers would have to know to work on the second word of
    922    a 2 word quantity.  That's too much so we don't handle them.  */
    923 
    924 static arc_insn
    925 insert_limmfinish (arc_insn insn,
    926 		   const struct arc_operand *operand ATTRIBUTE_UNUSED,
    927 		   int mods ATTRIBUTE_UNUSED,
    928 		   const struct arc_operand_value *reg ATTRIBUTE_UNUSED,
    929 		   long value ATTRIBUTE_UNUSED,
    930 		   const char **errmsg ATTRIBUTE_UNUSED)
    931 {
    932   return insn;
    933 }
    934 
    935 static arc_insn
    936 insert_jumpflags (arc_insn insn,
    937 		  const struct arc_operand *operand,
    938 		  int mods ATTRIBUTE_UNUSED,
    939 		  const struct arc_operand_value *reg ATTRIBUTE_UNUSED,
    940 		  long value,
    941 		  const char **errmsg)
    942 {
    943   if (!flag_p)
    944     *errmsg = _("jump flags, but no .f seen");
    945 
    946   else if (!limm_p)
    947     *errmsg = _("jump flags, but no limm addr");
    948 
    949   else if (limm & 0xfc000000)
    950     *errmsg = _("flag bits of jump address limm lost");
    951 
    952   else if (limm & 0x03000000)
    953     *errmsg = _("attempt to set HR bits");
    954 
    955   else if ((value & ((1 << operand->bits) - 1)) != value)
    956     *errmsg = _("bad jump flags value");
    957 
    958   jumpflags_p = 1;
    959   limm = ((limm & ((1 << operand->shift) - 1))
    960 	  | ((value & ((1 << operand->bits) - 1)) << operand->shift));
    961   return insn;
    962 }
    963 
    964 /* Called at the end of unary operand macros to copy the B field to C.  */
    965 
    966 static arc_insn
    967 insert_unopmacro (arc_insn insn,
    968 		  const struct arc_operand *operand,
    969 		  int mods ATTRIBUTE_UNUSED,
    970 		  const struct arc_operand_value *reg ATTRIBUTE_UNUSED,
    971 		  long value ATTRIBUTE_UNUSED,
    972 		  const char **errmsg ATTRIBUTE_UNUSED)
    973 {
    974   insn |= ((insn >> ARC_SHIFT_REGB) & ARC_MASK_REG) << operand->shift;
    975   return insn;
    976 }
    977 
    978 /* Insert a relative address for a branch insn (b, bl, or lp).  */
    979 
    980 static arc_insn
    981 insert_reladdr (arc_insn insn,
    982 		const struct arc_operand *operand,
    983 		int mods ATTRIBUTE_UNUSED,
    984 		const struct arc_operand_value *reg ATTRIBUTE_UNUSED,
    985 		long value,
    986 		const char **errmsg)
    987 {
    988   if (value & 3)
    989     *errmsg = _("branch address not on 4 byte boundary");
    990   insn |= ((value >> 2) & ((1 << operand->bits) - 1)) << operand->shift;
    991   return insn;
    992 }
    993 
    994 /* Insert a limm value as a 26 bit address right shifted 2 into the insn.
    995 
    996    Note that this function is only intended to handle instructions (with 4 byte
    997    immediate operands).  It is not intended to handle data.  */
    998 
    999 /* ??? Actually, there's little for us to do as we can't call frag_more, the
   1000    caller must do that.  The extract fns take a pointer to two words.  The
   1001    insert fns could be converted and then we could do something useful, but
   1002    then the reloc handlers would have to know to work on the second word of
   1003    a 2 word quantity.  That's too much so we don't handle them.
   1004 
   1005    We do check for correct usage of the nullify suffix, or we
   1006    set the default correctly, though.  */
   1007 
   1008 static arc_insn
   1009 insert_absaddr (arc_insn insn,
   1010 		const struct arc_operand *operand ATTRIBUTE_UNUSED,
   1011 		int mods ATTRIBUTE_UNUSED,
   1012 		const struct arc_operand_value *reg ATTRIBUTE_UNUSED,
   1013 		long value ATTRIBUTE_UNUSED,
   1014 		const char **errmsg)
   1015 {
   1016   if (limm_p)
   1017     {
   1018       /* If it is a jump and link, .jd must be specified.  */
   1019       if (insn & R (-1, 9, 1))
   1020 	{
   1021 	  if (!nullify_p)
   1022 	    insn |=  0x02 << 5;  /* Default nullify to .jd.  */
   1023 
   1024 	  else if (nullify != 0x02)
   1025 	    *errmsg = _("must specify .jd or no nullify suffix");
   1026 	}
   1027     }
   1028   return insn;
   1029 }
   1030 
   1031 /* Extraction functions.
   1033 
   1034    The suffix extraction functions' return value is redundant since it can be
   1035    obtained from (*OPVAL)->value.  However, the boolean suffixes don't have
   1036    a suffix table entry for the "false" case, so values of zero must be
   1037    obtained from the return value (*OPVAL == NULL).  */
   1038 
   1039 /* Called by the disassembler before printing an instruction.  */
   1040 
   1041 void
   1042 arc_opcode_init_extract (void)
   1043 {
   1044   arc_opcode_init_insert ();
   1045 }
   1046 
   1047 static const struct arc_operand_value *
   1048 lookup_register (int type, long regno)
   1049 {
   1050   const struct arc_operand_value *r,*end;
   1051   struct arc_ext_operand_value *ext_oper = arc_ext_operands;
   1052 
   1053   while (ext_oper)
   1054     {
   1055       if (ext_oper->operand.type == type && ext_oper->operand.value == regno)
   1056 	return (&ext_oper->operand);
   1057       ext_oper = ext_oper->next;
   1058     }
   1059 
   1060   if (type == REG)
   1061     return &arc_reg_names[regno];
   1062 
   1063   /* ??? This is a little slow and can be speeded up.  */
   1064   for (r = arc_reg_names, end = arc_reg_names + arc_reg_names_count;
   1065        r < end; ++r)
   1066     if (type == r->type	&& regno == r->value)
   1067       return r;
   1068   return 0;
   1069 }
   1070 
   1071 /* As we're extracting registers, keep an eye out for the 'f' indicator
   1072    (ARC_REG_SHIMM_UPDATE).  If we find a register (not a constant marker,
   1073    like ARC_REG_SHIMM), set OPVAL so our caller will know this is a register.
   1074 
   1075    We must also handle auxiliary registers for lr/sr insns.  They are just
   1076    constants with special names.  */
   1077 
   1078 static long
   1079 extract_reg (arc_insn *insn,
   1080 	     const struct arc_operand *operand,
   1081 	     int mods,
   1082 	     const struct arc_operand_value **opval,
   1083 	     int *invalid ATTRIBUTE_UNUSED)
   1084 {
   1085   int regno;
   1086   long value;
   1087   enum operand op_type;
   1088 
   1089   /* Get the register number.  */
   1090   regno = (*insn >> operand->shift) & ((1 << operand->bits) - 1);
   1091 
   1092   /* Is it a constant marker?  */
   1093   if (regno == ARC_REG_SHIMM)
   1094     {
   1095       op_type = OP_SHIMM;
   1096       /* Always return zero if dest is a shimm  mlm.  */
   1097 
   1098       if ('a' != operand->fmt)
   1099 	{
   1100 	  value = *insn & 511;
   1101 	  if ((operand->flags & ARC_OPERAND_SIGNED)
   1102 	      && (value & 256))
   1103 	    value -= 512;
   1104 	  if (!flagshimm_handled_p)
   1105 	    flag_p = 0;
   1106 	  flagshimm_handled_p = 1;
   1107 	}
   1108       else
   1109 	value = 0;
   1110     }
   1111   else if (regno == ARC_REG_SHIMM_UPDATE)
   1112     {
   1113       op_type = OP_SHIMM;
   1114 
   1115       /* Always return zero if dest is a shimm  mlm.  */
   1116       if ('a' != operand->fmt)
   1117 	{
   1118 	  value = *insn & 511;
   1119 	  if ((operand->flags & ARC_OPERAND_SIGNED) && (value & 256))
   1120 	    value -= 512;
   1121 	}
   1122       else
   1123 	value = 0;
   1124 
   1125       flag_p = 1;
   1126       flagshimm_handled_p = 1;
   1127     }
   1128   else if (regno == ARC_REG_LIMM)
   1129     {
   1130       op_type = OP_LIMM;
   1131       value = insn[1];
   1132       limm_p = 1;
   1133 
   1134       /* If this is a jump instruction (j,jl), show new pc correctly.  */
   1135       if (0x07 == ((*insn & I(-1)) >> 27))
   1136 	value = (value & 0xffffff);
   1137     }
   1138 
   1139   /* It's a register, set OPVAL (that's the only way we distinguish registers
   1140      from constants here).  */
   1141   else
   1142     {
   1143       const struct arc_operand_value *reg = lookup_register (REG, regno);
   1144 
   1145       op_type = OP_REG;
   1146 
   1147       if (reg == NULL)
   1148 	abort ();
   1149       if (opval != NULL)
   1150 	*opval = reg;
   1151       value = regno;
   1152     }
   1153 
   1154   /* If this field takes an auxiliary register, see if it's a known one.  */
   1155   if ((mods & ARC_MOD_AUXREG)
   1156       && ARC_REG_CONSTANT_P (regno))
   1157     {
   1158       const struct arc_operand_value *reg = lookup_register (AUXREG, value);
   1159 
   1160       /* This is really a constant, but tell the caller it has a special
   1161 	 name.  */
   1162       if (reg != NULL && opval != NULL)
   1163 	*opval = reg;
   1164     }
   1165 
   1166   switch(operand->fmt)
   1167     {
   1168     case 'a':
   1169       ls_operand[LS_DEST] = op_type;
   1170       break;
   1171     case 's':
   1172       ls_operand[LS_BASE] = op_type;
   1173       break;
   1174     case 'c':
   1175       if ((insn[0]& I(-1)) == I(2))
   1176 	ls_operand[LS_VALUE] = op_type;
   1177       else
   1178 	ls_operand[LS_OFFSET] = op_type;
   1179       break;
   1180     case 'o': case 'O':
   1181       ls_operand[LS_OFFSET] = op_type;
   1182       break;
   1183     }
   1184 
   1185   return value;
   1186 }
   1187 
   1188 /* Return the value of the "flag update" field for shimm insns.
   1189    This value is actually stored in the register field.  */
   1190 
   1191 static long
   1192 extract_flag (arc_insn *insn,
   1193 	      const struct arc_operand *operand,
   1194 	      int mods ATTRIBUTE_UNUSED,
   1195 	      const struct arc_operand_value **opval,
   1196 	      int *invalid ATTRIBUTE_UNUSED)
   1197 {
   1198   int f;
   1199   const struct arc_operand_value *val;
   1200 
   1201   if (flagshimm_handled_p)
   1202     f = flag_p != 0;
   1203   else
   1204     f = (*insn & (1 << operand->shift)) != 0;
   1205 
   1206   /* There is no text for zero values.  */
   1207   if (f == 0)
   1208     return 0;
   1209   flag_p = 1;
   1210   val = arc_opcode_lookup_suffix (operand, 1);
   1211   if (opval != NULL && val != NULL)
   1212     *opval = val;
   1213   return val->value;
   1214 }
   1215 
   1216 /* Extract the condition code (if it exists).
   1217    If we've seen a shimm value in this insn (meaning that the insn can't have
   1218    a condition code field), then we don't store anything in OPVAL and return
   1219    zero.  */
   1220 
   1221 static long
   1222 extract_cond (arc_insn *insn,
   1223 	      const struct arc_operand *operand,
   1224 	      int mods ATTRIBUTE_UNUSED,
   1225 	      const struct arc_operand_value **opval,
   1226 	      int *invalid ATTRIBUTE_UNUSED)
   1227 {
   1228   long cond;
   1229   const struct arc_operand_value *val;
   1230 
   1231   if (flagshimm_handled_p)
   1232     return 0;
   1233 
   1234   cond = (*insn >> operand->shift) & ((1 << operand->bits) - 1);
   1235   val = arc_opcode_lookup_suffix (operand, cond);
   1236 
   1237   /* Ignore NULL values of `val'.  Several condition code values are
   1238      reserved for extensions.  */
   1239   if (opval != NULL && val != NULL)
   1240     *opval = val;
   1241   return cond;
   1242 }
   1243 
   1244 /* Extract a branch address.
   1245    We return the value as a real address (not right shifted by 2).  */
   1246 
   1247 static long
   1248 extract_reladdr (arc_insn *insn,
   1249 		 const struct arc_operand *operand,
   1250 		 int mods ATTRIBUTE_UNUSED,
   1251 		 const struct arc_operand_value **opval ATTRIBUTE_UNUSED,
   1252 		 int *invalid ATTRIBUTE_UNUSED)
   1253 {
   1254   long addr;
   1255 
   1256   addr = (*insn >> operand->shift) & ((1 << operand->bits) - 1);
   1257   if ((operand->flags & ARC_OPERAND_SIGNED)
   1258       && (addr & (1 << (operand->bits - 1))))
   1259     addr -= 1 << operand->bits;
   1260   return addr << 2;
   1261 }
   1262 
   1263 /* Extract the flags bits from a j or jl long immediate.  */
   1264 
   1265 static long
   1266 extract_jumpflags (arc_insn *insn,
   1267 		   const struct arc_operand *operand,
   1268 		   int mods ATTRIBUTE_UNUSED,
   1269 		   const struct arc_operand_value **opval ATTRIBUTE_UNUSED,
   1270 		   int *invalid)
   1271 {
   1272   if (!flag_p || !limm_p)
   1273     *invalid = 1;
   1274   return ((flag_p && limm_p)
   1275 	  ? (insn[1] >> operand->shift) & ((1 << operand->bits) -1): 0);
   1276 }
   1277 
   1278 /* Extract st insn's offset.  */
   1279 
   1280 static long
   1281 extract_st_offset (arc_insn *insn,
   1282 		   const struct arc_operand *operand,
   1283 		   int mods ATTRIBUTE_UNUSED,
   1284 		   const struct arc_operand_value **opval ATTRIBUTE_UNUSED,
   1285 		   int *invalid)
   1286 {
   1287   int value = 0;
   1288 
   1289   if (ls_operand[LS_VALUE] != OP_SHIMM || ls_operand[LS_BASE] != OP_LIMM)
   1290     {
   1291       value = insn[0] & 511;
   1292       if ((operand->flags & ARC_OPERAND_SIGNED) && (value & 256))
   1293 	value -= 512;
   1294       if (value)
   1295 	ls_operand[LS_OFFSET] = OP_SHIMM;
   1296     }
   1297   else
   1298     *invalid = 1;
   1299 
   1300   return value;
   1301 }
   1302 
   1303 /* Extract ld insn's offset.  */
   1304 
   1305 static long
   1306 extract_ld_offset (arc_insn *insn,
   1307 		   const struct arc_operand *operand,
   1308 		   int mods,
   1309 		   const struct arc_operand_value **opval,
   1310 		   int *invalid)
   1311 {
   1312   int test = insn[0] & I(-1);
   1313   int value;
   1314 
   1315   if (test)
   1316     {
   1317       value = insn[0] & 511;
   1318       if ((operand->flags & ARC_OPERAND_SIGNED) && (value & 256))
   1319 	value -= 512;
   1320       if (value)
   1321 	ls_operand[LS_OFFSET] = OP_SHIMM;
   1322 
   1323       return value;
   1324     }
   1325   /* If it isn't in the insn, it's concealed behind reg 'c'.  */
   1326   return extract_reg (insn, &arc_operands[arc_operand_map['c']],
   1327 		      mods, opval, invalid);
   1328 }
   1329 
   1330 /* The only thing this does is set the `invalid' flag if B != C.
   1331    This is needed because the "mov" macro appears before it's real insn "and"
   1332    and we don't want the disassembler to confuse them.  */
   1333 
   1334 static long
   1335 extract_unopmacro (arc_insn *insn,
   1336 		   const struct arc_operand *operand ATTRIBUTE_UNUSED,
   1337 		   int mods ATTRIBUTE_UNUSED,
   1338 		   const struct arc_operand_value **opval ATTRIBUTE_UNUSED,
   1339 		   int *invalid)
   1340 {
   1341   /* This misses the case where B == ARC_REG_SHIMM_UPDATE &&
   1342      C == ARC_REG_SHIMM (or vice versa).  No big deal.  Those insns will get
   1343      printed as "and"s.  */
   1344   if (((*insn >> ARC_SHIFT_REGB) & ARC_MASK_REG)
   1345       != ((*insn >> ARC_SHIFT_REGC) & ARC_MASK_REG))
   1346     if (invalid != NULL)
   1347       *invalid = 1;
   1348   return 0;
   1349 }
   1350 
   1351 /* ARC instructions.
   1353 
   1354    Longer versions of insns must appear before shorter ones (if gas sees
   1355    "lsr r2,r3,1" when it's parsing "lsr %a,%b" it will think the ",1" is
   1356    junk).  This isn't necessary for `ld' because of the trailing ']'.
   1357 
   1358    Instructions that are really macros based on other insns must appear
   1359    before the real insn so they're chosen when disassembling.  Eg: The `mov'
   1360    insn is really the `and' insn.  */
   1361 
   1362 struct arc_opcode arc_opcodes[] =
   1363 {
   1364   /* Base case instruction set (core versions 5-8).  */
   1365 
   1366   /* "mov" is really an "and".  */
   1367   { "mov%.q%.f %a,%b%F%S%L%U", I(-1), I(12), ARC_MACH_5, 0, 0 },
   1368   /* "asl" is really an "add".  */
   1369   { "asl%.q%.f %a,%b%F%S%L%U", I(-1), I(8), ARC_MACH_5, 0, 0 },
   1370   /* "lsl" is really an "add".  */
   1371   { "lsl%.q%.f %a,%b%F%S%L%U", I(-1), I(8), ARC_MACH_5, 0, 0 },
   1372   /* "nop" is really an "xor".  */
   1373   { "nop", 0x7fffffff, 0x7fffffff, ARC_MACH_5, 0, 0 },
   1374   /* "rlc" is really an "adc".  */
   1375   { "rlc%.q%.f %a,%b%F%S%L%U", I(-1), I(9), ARC_MACH_5, 0, 0 },
   1376   { "adc%.q%.f %a,%b,%c%F%S%L", I(-1), I(9), ARC_MACH_5, 0, 0 },
   1377   { "add%.q%.f %a,%b,%c%F%S%L", I(-1), I(8), ARC_MACH_5, 0, 0 },
   1378   { "and%.q%.f %a,%b,%c%F%S%L", I(-1), I(12), ARC_MACH_5, 0, 0 },
   1379   { "asr%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(1), ARC_MACH_5, 0, 0 },
   1380   { "bic%.q%.f %a,%b,%c%F%S%L",	I(-1), I(14), ARC_MACH_5, 0, 0 },
   1381   { "b%q%.n %B", I(-1), I(4), ARC_MACH_5 | ARC_OPCODE_COND_BRANCH, 0, 0 },
   1382   { "bl%q%.n %B", I(-1), I(5), ARC_MACH_5 | ARC_OPCODE_COND_BRANCH, 0, 0 },
   1383   { "extb%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(7), ARC_MACH_5, 0, 0 },
   1384   { "extw%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(8), ARC_MACH_5, 0, 0 },
   1385   { "flag%.q %b%G%S%L", I(-1)|A(-1)|C(-1), I(3)|A(ARC_REG_SHIMM_UPDATE)|C(0), ARC_MACH_5, 0, 0 },
   1386   { "brk", 0x1ffffe00, 0x1ffffe00, ARC_MACH_7, 0, 0 },
   1387   { "sleep", 0x1ffffe01, 0x1ffffe01, ARC_MACH_7, 0, 0 },
   1388   { "swi", 0x1ffffe02, 0x1ffffe02, ARC_MACH_8, 0, 0 },
   1389   /* %Q: force cond_p=1 -> no shimm values. This insn allows an
   1390      optional flags spec.  */
   1391   { "j%q%Q%.n%.f %b%F%J,%j", I(-1)|A(-1)|C(-1)|R(-1,7,1), I(7)|A(0)|C(0)|R(0,7,1), ARC_MACH_5 | ARC_OPCODE_COND_BRANCH, 0, 0 },
   1392   { "j%q%Q%.n%.f %b%F%J", I(-1)|A(-1)|C(-1)|R(-1,7,1), I(7)|A(0)|C(0)|R(0,7,1), ARC_MACH_5 | ARC_OPCODE_COND_BRANCH, 0, 0 },
   1393   /* This insn allows an optional flags spec.  */
   1394   { "jl%q%Q%.n%.f %b%F%J,%j", I(-1)|A(-1)|C(-1)|R(-1,7,1)|R(-1,9,1), I(7)|A(0)|C(0)|R(0,7,1)|R(1,9,1), ARC_MACH_6 | ARC_OPCODE_COND_BRANCH, 0, 0 },
   1395   { "jl%q%Q%.n%.f %b%F%J", I(-1)|A(-1)|C(-1)|R(-1,7,1)|R(-1,9,1), I(7)|A(0)|C(0)|R(0,7,1)|R(1,9,1), ARC_MACH_6 | ARC_OPCODE_COND_BRANCH, 0, 0 },
   1396   /* Put opcode 1 ld insns first so shimm gets prefered over limm.
   1397      "[%b]" is before "[%b,%o]" so 0 offsets don't get printed.  */
   1398   { "ld%Z%.X%.W%.E %a,[%s]%S%L%1", I(-1)|R(-1,13,1)|R(-1,0,511), I(1)|R(0,13,1)|R(0,0,511), ARC_MACH_5, 0, 0 },
   1399   { "ld%z%.x%.w%.e %a,[%s]%S%L%1", I(-1)|R(-1,4,1)|R(-1,6,7), I(0)|R(0,4,1)|R(0,6,7), ARC_MACH_5, 0, 0 },
   1400   { "ld%z%.x%.w%.e %a,[%s,%O]%S%L%1", I(-1)|R(-1,4,1)|R(-1,6,7), I(0)|R(0,4,1)|R(0,6,7), ARC_MACH_5, 0, 0 },
   1401   { "ld%Z%.X%.W%.E %a,[%s,%O]%S%L%3", I(-1)|R(-1,13,1),	I(1)|R(0,13,1), ARC_MACH_5, 0, 0 },
   1402   { "lp%q%.n %B", I(-1), I(6), ARC_MACH_5, 0, 0 },
   1403   { "lr %a,[%Ab]%S%L", I(-1)|C(-1), I(1)|C(0x10), ARC_MACH_5, 0, 0 },
   1404   { "lsr%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(2), ARC_MACH_5, 0, 0 },
   1405   { "or%.q%.f %a,%b,%c%F%S%L", I(-1), I(13), ARC_MACH_5, 0, 0 },
   1406   { "ror%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(3), ARC_MACH_5, 0, 0 },
   1407   { "rrc%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(4), ARC_MACH_5, 0, 0 },
   1408   { "sbc%.q%.f %a,%b,%c%F%S%L",	I(-1), I(11), ARC_MACH_5, 0, 0 },
   1409   { "sexb%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(5), ARC_MACH_5, 0, 0 },
   1410   { "sexw%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(6), ARC_MACH_5, 0, 0 },
   1411   { "sr %c,[%Ab]%S%L", I(-1)|A(-1), I(2)|A(0x10), ARC_MACH_5, 0, 0 },
   1412   /* "[%b]" is before "[%b,%o]" so 0 offsets don't get printed.  */
   1413   { "st%y%.v%.D %c,[%s]%L%S%0", I(-1)|R(-1,25,1)|R(-1,21,1), I(2)|R(0,25,1)|R(0,21,1), ARC_MACH_5, 0, 0 },
   1414   { "st%y%.v%.D %c,[%s,%o]%S%L%2", I(-1)|R(-1,25,1)|R(-1,21,1), I(2)|R(0,25,1)|R(0,21,1), ARC_MACH_5, 0, 0 },
   1415   { "sub%.q%.f %a,%b,%c%F%S%L",	I(-1), I(10), ARC_MACH_5, 0, 0 },
   1416   { "xor%.q%.f %a,%b,%c%F%S%L",	I(-1), I(15), ARC_MACH_5, 0, 0 }
   1417 };
   1418 
   1419 const int arc_opcodes_count = sizeof (arc_opcodes) / sizeof (arc_opcodes[0]);
   1420 
   1421 const struct arc_operand_value arc_reg_names[] =
   1422 {
   1423   /* Core register set r0-r63.  */
   1424 
   1425   /* r0-r28 - general purpose registers.  */
   1426   { "r0", 0, REG, 0 }, { "r1", 1, REG, 0 }, { "r2", 2, REG, 0 },
   1427   { "r3", 3, REG, 0 }, { "r4", 4, REG, 0 }, { "r5", 5, REG, 0 },
   1428   { "r6", 6, REG, 0 }, { "r7", 7, REG, 0 }, { "r8", 8, REG, 0 },
   1429   { "r9", 9, REG, 0 }, { "r10", 10, REG, 0 }, { "r11", 11, REG, 0 },
   1430   { "r12", 12, REG, 0 }, { "r13", 13, REG, 0 }, { "r14", 14, REG, 0 },
   1431   { "r15", 15, REG, 0 }, { "r16", 16, REG, 0 }, { "r17", 17, REG, 0 },
   1432   { "r18", 18, REG, 0 }, { "r19", 19, REG, 0 }, { "r20", 20, REG, 0 },
   1433   { "r21", 21, REG, 0 }, { "r22", 22, REG, 0 }, { "r23", 23, REG, 0 },
   1434   { "r24", 24, REG, 0 }, { "r25", 25, REG, 0 }, { "r26", 26, REG, 0 },
   1435   { "r27", 27, REG, 0 }, { "r28", 28, REG, 0 },
   1436   /* Maskable interrupt link register.  */
   1437   { "ilink1", 29, REG, 0 },
   1438   /* Maskable interrupt link register.  */
   1439   { "ilink2", 30, REG, 0 },
   1440   /* Branch-link register.  */
   1441   { "blink", 31, REG, 0 },
   1442 
   1443   /* r32-r59 reserved for extensions.  */
   1444   { "r32", 32, REG, 0 }, { "r33", 33, REG, 0 }, { "r34", 34, REG, 0 },
   1445   { "r35", 35, REG, 0 }, { "r36", 36, REG, 0 }, { "r37", 37, REG, 0 },
   1446   { "r38", 38, REG, 0 }, { "r39", 39, REG, 0 }, { "r40", 40, REG, 0 },
   1447   { "r41", 41, REG, 0 }, { "r42", 42, REG, 0 }, { "r43", 43, REG, 0 },
   1448   { "r44", 44, REG, 0 }, { "r45", 45, REG, 0 }, { "r46", 46, REG, 0 },
   1449   { "r47", 47, REG, 0 }, { "r48", 48, REG, 0 }, { "r49", 49, REG, 0 },
   1450   { "r50", 50, REG, 0 }, { "r51", 51, REG, 0 }, { "r52", 52, REG, 0 },
   1451   { "r53", 53, REG, 0 }, { "r54", 54, REG, 0 }, { "r55", 55, REG, 0 },
   1452   { "r56", 56, REG, 0 }, { "r57", 57, REG, 0 }, { "r58", 58, REG, 0 },
   1453   { "r59", 59, REG, 0 },
   1454 
   1455   /* Loop count register (24 bits).  */
   1456   { "lp_count", 60, REG, 0 },
   1457   /* Short immediate data indicator setting flags.  */
   1458   { "r61", 61, REG, ARC_REGISTER_READONLY },
   1459   /* Long immediate data indicator setting flags.  */
   1460   { "r62", 62, REG, ARC_REGISTER_READONLY },
   1461   /* Short immediate data indicator not setting flags.  */
   1462   { "r63", 63, REG, ARC_REGISTER_READONLY },
   1463 
   1464   /* Small-data base register.  */
   1465   { "gp", 26, REG, 0 },
   1466   /* Frame pointer.  */
   1467   { "fp", 27, REG, 0 },
   1468   /* Stack pointer.  */
   1469   { "sp", 28, REG, 0 },
   1470 
   1471   { "r29", 29, REG, 0 },
   1472   { "r30", 30, REG, 0 },
   1473   { "r31", 31, REG, 0 },
   1474   { "r60", 60, REG, 0 },
   1475 
   1476   /* Auxiliary register set.  */
   1477 
   1478   /* Auxiliary register address map:
   1479      0xffffffff-0xffffff00 (-1..-256) - customer shimm allocation
   1480      0xfffffeff-0x80000000 - customer limm allocation
   1481      0x7fffffff-0x00000100 - ARC limm allocation
   1482      0x000000ff-0x00000000 - ARC shimm allocation  */
   1483 
   1484   /* Base case auxiliary registers (shimm address).  */
   1485   { "status",         0x00, AUXREG, 0 },
   1486   { "semaphore",      0x01, AUXREG, 0 },
   1487   { "lp_start",       0x02, AUXREG, 0 },
   1488   { "lp_end",         0x03, AUXREG, 0 },
   1489   { "identity",       0x04, AUXREG, ARC_REGISTER_READONLY },
   1490   { "debug",          0x05, AUXREG, 0 },
   1491 };
   1492 
   1493 const int arc_reg_names_count =
   1494   sizeof (arc_reg_names) / sizeof (arc_reg_names[0]);
   1495 
   1496 /* The suffix table.
   1497    Operands with the same name must be stored together.  */
   1498 
   1499 const struct arc_operand_value arc_suffixes[] =
   1500 {
   1501   /* Entry 0 is special, default values aren't printed by the disassembler.  */
   1502   { "", 0, -1, 0 },
   1503 
   1504   /* Base case condition codes.  */
   1505   { "al", 0, COND, 0 },
   1506   { "ra", 0, COND, 0 },
   1507   { "eq", 1, COND, 0 },
   1508   { "z", 1, COND, 0 },
   1509   { "ne", 2, COND, 0 },
   1510   { "nz", 2, COND, 0 },
   1511   { "pl", 3, COND, 0 },
   1512   { "p", 3, COND, 0 },
   1513   { "mi", 4, COND, 0 },
   1514   { "n", 4, COND, 0 },
   1515   { "cs", 5, COND, 0 },
   1516   { "c", 5, COND, 0 },
   1517   { "lo", 5, COND, 0 },
   1518   { "cc", 6, COND, 0 },
   1519   { "nc", 6, COND, 0 },
   1520   { "hs", 6, COND, 0 },
   1521   { "vs", 7, COND, 0 },
   1522   { "v", 7, COND, 0 },
   1523   { "vc", 8, COND, 0 },
   1524   { "nv", 8, COND, 0 },
   1525   { "gt", 9, COND, 0 },
   1526   { "ge", 10, COND, 0 },
   1527   { "lt", 11, COND, 0 },
   1528   { "le", 12, COND, 0 },
   1529   { "hi", 13, COND, 0 },
   1530   { "ls", 14, COND, 0 },
   1531   { "pnz", 15, COND, 0 },
   1532 
   1533   /* Condition codes 16-31 reserved for extensions.  */
   1534 
   1535   { "f", 1, FLAG, 0 },
   1536 
   1537   { "nd", ARC_DELAY_NONE, DELAY, 0 },
   1538   { "d", ARC_DELAY_NORMAL, DELAY, 0 },
   1539   { "jd", ARC_DELAY_JUMP, DELAY, 0 },
   1540 
   1541   { "b", 1, SIZE1, 0 },
   1542   { "b", 1, SIZE10, 0 },
   1543   { "b", 1, SIZE22, 0 },
   1544   { "w", 2, SIZE1, 0 },
   1545   { "w", 2, SIZE10, 0 },
   1546   { "w", 2, SIZE22, 0 },
   1547   { "x", 1, SIGN0, 0 },
   1548   { "x", 1, SIGN9, 0 },
   1549   { "a", 1, ADDRESS3, 0 },
   1550   { "a", 1, ADDRESS12, 0 },
   1551   { "a", 1, ADDRESS24, 0 },
   1552 
   1553   { "di", 1, CACHEBYPASS5, 0 },
   1554   { "di", 1, CACHEBYPASS14, 0 },
   1555   { "di", 1, CACHEBYPASS26, 0 },
   1556 };
   1557 
   1558 const int arc_suffixes_count =
   1559   sizeof (arc_suffixes) / sizeof (arc_suffixes[0]);
   1560 
   1561 /* Indexed by first letter of opcode.  Points to chain of opcodes with same
   1562    first letter.  */
   1563 static struct arc_opcode *opcode_map[26 + 1];
   1564 
   1565 /* Indexed by insn code.  Points to chain of opcodes with same insn code.  */
   1566 static struct arc_opcode *icode_map[32];
   1567 
   1568 /* Configuration flags.  */
   1570 
   1571 /* Various ARC_HAVE_XXX bits.  */
   1572 static int cpu_type;
   1573 
   1574 /* Translate a bfd_mach_arc_xxx value to a ARC_MACH_XXX value.  */
   1575 
   1576 int
   1577 arc_get_opcode_mach (int bfd_mach, int big_p)
   1578 {
   1579   static int mach_type_map[] =
   1580   {
   1581     ARC_MACH_5,
   1582     ARC_MACH_6,
   1583     ARC_MACH_7,
   1584     ARC_MACH_8
   1585   };
   1586   return mach_type_map[bfd_mach - bfd_mach_arc_5] | (big_p ? ARC_MACH_BIG : 0);
   1587 }
   1588 
   1589 /* Initialize any tables that need it.
   1590    Must be called once at start up (or when first needed).
   1591 
   1592    FLAGS is a set of bits that say what version of the cpu we have,
   1593    and in particular at least (one of) ARC_MACH_XXX.  */
   1594 
   1595 void
   1596 arc_opcode_init_tables (int flags)
   1597 {
   1598   static int init_p = 0;
   1599 
   1600   cpu_type = flags;
   1601 
   1602   /* We may be intentionally called more than once (for example gdb will call
   1603      us each time the user switches cpu).  These tables only need to be init'd
   1604      once though.  */
   1605   if (!init_p)
   1606     {
   1607       int i,n;
   1608 
   1609       memset (arc_operand_map, 0, sizeof (arc_operand_map));
   1610       n = sizeof (arc_operands) / sizeof (arc_operands[0]);
   1611       for (i = 0; i < n; ++i)
   1612 	arc_operand_map[arc_operands[i].fmt] = i;
   1613 
   1614       memset (opcode_map, 0, sizeof (opcode_map));
   1615       memset (icode_map, 0, sizeof (icode_map));
   1616       /* Scan the table backwards so macros appear at the front.  */
   1617       for (i = arc_opcodes_count - 1; i >= 0; --i)
   1618 	{
   1619 	  int opcode_hash = ARC_HASH_OPCODE (arc_opcodes[i].syntax);
   1620 	  int icode_hash = ARC_HASH_ICODE (arc_opcodes[i].value);
   1621 
   1622 	  arc_opcodes[i].next_asm = opcode_map[opcode_hash];
   1623 	  opcode_map[opcode_hash] = &arc_opcodes[i];
   1624 
   1625 	  arc_opcodes[i].next_dis = icode_map[icode_hash];
   1626 	  icode_map[icode_hash] = &arc_opcodes[i];
   1627 	}
   1628 
   1629       init_p = 1;
   1630     }
   1631 }
   1632 
   1633 /* Return non-zero if OPCODE is supported on the specified cpu.
   1634    Cpu selection is made when calling `arc_opcode_init_tables'.  */
   1635 
   1636 int
   1637 arc_opcode_supported (const struct arc_opcode *opcode)
   1638 {
   1639   if (ARC_OPCODE_CPU (opcode->flags) <= cpu_type)
   1640     return 1;
   1641   return 0;
   1642 }
   1643 
   1644 /* Return the first insn in the chain for assembling INSN.  */
   1645 
   1646 const struct arc_opcode *
   1647 arc_opcode_lookup_asm (const char *insn)
   1648 {
   1649   return opcode_map[ARC_HASH_OPCODE (insn)];
   1650 }
   1651 
   1652 /* Return the first insn in the chain for disassembling INSN.  */
   1653 
   1654 const struct arc_opcode *
   1655 arc_opcode_lookup_dis (unsigned int insn)
   1656 {
   1657   return icode_map[ARC_HASH_ICODE (insn)];
   1658 }
   1659 
   1660 /* Called by the assembler before parsing an instruction.  */
   1661 
   1662 void
   1663 arc_opcode_init_insert (void)
   1664 {
   1665   int i;
   1666 
   1667   for(i = 0; i < OPERANDS; i++)
   1668     ls_operand[i] = OP_NONE;
   1669 
   1670   flag_p = 0;
   1671   flagshimm_handled_p = 0;
   1672   cond_p = 0;
   1673   addrwb_p = 0;
   1674   shimm_p = 0;
   1675   limm_p = 0;
   1676   jumpflags_p = 0;
   1677   nullify_p = 0;
   1678   nullify = 0; /* The default is important.  */
   1679 }
   1680 
   1681 /* Called by the assembler to see if the insn has a limm operand.
   1682    Also called by the disassembler to see if the insn contains a limm.  */
   1683 
   1684 int
   1685 arc_opcode_limm_p (long *limmp)
   1686 {
   1687   if (limmp)
   1688     *limmp = limm;
   1689   return limm_p;
   1690 }
   1691 
   1692 /* Utility for the extraction functions to return the index into
   1693    `arc_suffixes'.  */
   1694 
   1695 const struct arc_operand_value *
   1696 arc_opcode_lookup_suffix (const struct arc_operand *type, int value)
   1697 {
   1698   const struct arc_operand_value *v,*end;
   1699   struct arc_ext_operand_value *ext_oper = arc_ext_operands;
   1700 
   1701   while (ext_oper)
   1702     {
   1703       if (type == &arc_operands[ext_oper->operand.type]
   1704 	  && value == ext_oper->operand.value)
   1705 	return (&ext_oper->operand);
   1706       ext_oper = ext_oper->next;
   1707     }
   1708 
   1709   /* ??? This is a little slow and can be speeded up.  */
   1710   for (v = arc_suffixes, end = arc_suffixes + arc_suffixes_count; v < end; ++v)
   1711     if (type == &arc_operands[v->type]
   1712 	&& value == v->value)
   1713       return v;
   1714   return 0;
   1715 }
   1716 
   1717 int
   1718 arc_insn_is_j (arc_insn insn)
   1719 {
   1720   return (insn & (I(-1))) == I(0x7);
   1721 }
   1722 
   1723 int
   1724 arc_insn_not_jl (arc_insn insn)
   1725 {
   1726   return ((insn & (I(-1)|A(-1)|C(-1)|R(-1,7,1)|R(-1,9,1)))
   1727 	  != (I(0x7) | R(-1,9,1)));
   1728 }
   1729 
   1730 int
   1731 arc_operand_type (int opertype)
   1732 {
   1733   switch (opertype)
   1734     {
   1735     case 0:
   1736       return COND;
   1737       break;
   1738     case 1:
   1739       return REG;
   1740       break;
   1741     case 2:
   1742       return AUXREG;
   1743       break;
   1744     }
   1745   return -1;
   1746 }
   1747 
   1748 struct arc_operand_value *
   1749 get_ext_suffix (char *s)
   1750 {
   1751   struct arc_ext_operand_value *suffix = arc_ext_operands;
   1752 
   1753   while (suffix)
   1754     {
   1755       if ((COND == suffix->operand.type)
   1756 	  && !strcmp(s,suffix->operand.name))
   1757 	return(&suffix->operand);
   1758       suffix = suffix->next;
   1759     }
   1760   return NULL;
   1761 }
   1762 
   1763 int
   1764 arc_get_noshortcut_flag (void)
   1765 {
   1766   return ARC_REGISTER_NOSHORT_CUT;
   1767 }
   1768