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