OSDN Git Service

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