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