Lots of changes from David Mosberger-Tang; see ChangeLog and NOTES for details:
[binutils-gdb.git] / opcodes / arc-opc.c
1 /* Opcode table for the ARC.
2 Copyright 1994 Free Software Foundation, Inc.
3 Contributed by Doug Evans (dje@cygnus.com).
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18
19 #include "ansidecl.h"
20 #include "opcode/arc.h"
21
22 #define INSERT_FN(fn) \
23 static arc_insn fn PARAMS ((arc_insn, const struct arc_operand *, \
24 int, const struct arc_operand_value *, long, \
25 const char **))
26 #define EXTRACT_FN(fn) \
27 static long fn PARAMS ((arc_insn *, const struct arc_operand *, \
28 int, const struct arc_operand_value **, int *))
29
30 INSERT_FN (insert_reg);
31 INSERT_FN (insert_shimmfinish);
32 INSERT_FN (insert_limmfinish);
33 INSERT_FN (insert_shimmoffset);
34 INSERT_FN (insert_shimmzero);
35 INSERT_FN (insert_flag);
36 INSERT_FN (insert_flagfinish);
37 INSERT_FN (insert_cond);
38 INSERT_FN (insert_forcelimm);
39 INSERT_FN (insert_reladdr);
40 INSERT_FN (insert_unopmacro);
41 INSERT_FN (insert_multshift);
42
43 EXTRACT_FN (extract_reg);
44 EXTRACT_FN (extract_flag);
45 EXTRACT_FN (extract_cond);
46 EXTRACT_FN (extract_unopmacro);
47 EXTRACT_FN (extract_multshift);
48
49 /* Various types of ARC operands, including insn suffixes. */
50
51 /* Insn format values:
52
53 'a' REGA register A field
54 'b' REGB register B field
55 'c' REGC register C field
56 'S' SHIMMFINISH finish inserting a shimm value
57 'L' LIMMFINISH finish inserting a limm value
58 'd' SHIMMOFFSET shimm offset in ld,st insns
59 '0' SHIMMZERO 0 shimm value in ld,st insns
60 'f' FLAG F flag
61 'F' FLAGFINISH finish inserting the F flag
62 'G' FLAGINSN insert F flag in "flag" insn
63 'n' DELAY N field (nullify field)
64 'q' COND condition code field
65 'Q' FORCELIMM set `cond_p' to 1 to ensure a constant is a limm
66 'B' BRANCH branch address
67 'z' SIZE1 size field in ld a,[b,c]
68 'Z' SIZE10 size field in ld a,[b,shimm]
69 'y' SIZE22 size field in st c,[b,shimm]
70 'x' SIGN0 sign extend field ld a,[b,c]
71 'X' SIGN9 sign extend field ld a,[b,shimm]
72 'u' ADDRESS3 update field in ld a,[b,c]
73 'v' ADDRESS12 update field in ld a,[b,shimm]
74 'w' ADDRESS24 update field in st c,[b,shimm]
75 'D' CACHEBYPASS5 direct to memory enable (cache bypass) in ld a,[b,c]
76 'e' CACHEBYPASS14 direct to memory enable (cache bypass) in ld a,[b,shimm]
77 'E' CACHEBYPASS26 direct to memory enable (cache bypass) in st c,[b,shimm]
78 'U' UNOPMACRO fake operand to copy REGB to REGC for unop macros
79 'M' MULTSHIFT fake operand to check if target has multiply/shifter
80
81 The following modifiers may appear between the % and char (eg: %.f):
82
83 '.' MODDOT '.' prefix must be present
84 'r' REG generic register value, for register table
85 'A' AUXREG auxiliary register in lr a,[b], sr c,[b]
86
87 Fields are:
88
89 CHAR BITS SHIFT FLAGS INSERT_FN EXTRACT_FN
90 */
91
92 const struct arc_operand arc_operands[] =
93 {
94 /* place holder (??? not sure if needed) */
95 #define UNUSED 0
96 { 0 },
97
98 /* register A or shimm/limm indicator */
99 #define REGA (UNUSED + 1)
100 { 'a', 6, ARC_SHIFT_REGA, 0, insert_reg, extract_reg },
101
102 /* register B or shimm/limm indicator */
103 #define REGB (REGA + 1)
104 { 'b', 6, ARC_SHIFT_REGB, 0, insert_reg, extract_reg },
105
106 /* register C or shimm/limm indicator */
107 #define REGC (REGB + 1)
108 { 'c', 6, ARC_SHIFT_REGC, 0, insert_reg, extract_reg },
109
110 /* fake operand used to insert shimm value into most instructions */
111 #define SHIMMFINISH (REGC + 1)
112 { 'S', 9, 0, ARC_OPERAND_SIGNED + ARC_OPERAND_FAKE, insert_shimmfinish, 0 },
113
114 /* fake operand used to insert limm value into most instructions */
115 #define LIMMFINISH (SHIMMFINISH + 1)
116 { 'L', 32, 32, ARC_OPERAND_ABSOLUTE + ARC_OPERAND_FAKE, insert_limmfinish, 0 },
117
118 /* shimm operand when there is no reg indicator (ld,st) */
119 #define SHIMMOFFSET (LIMMFINISH + 1)
120 { 'd', 9, 0, ARC_OPERAND_SIGNED, insert_shimmoffset, 0 },
121
122 /* 0 shimm operand for ld,st insns */
123 #define SHIMMZERO (SHIMMOFFSET + 1)
124 { '0', 9, 0, ARC_OPERAND_FAKE, insert_shimmzero, 0 },
125
126 /* flag update bit (insertion is defered until we know how) */
127 #define FLAG (SHIMMZERO + 1)
128 { 'f', 1, 8, ARC_OPERAND_SUFFIX, insert_flag, extract_flag },
129
130 /* fake utility operand to finish 'f' suffix handling */
131 #define FLAGFINISH (FLAG + 1)
132 { 'F', 1, 8, ARC_OPERAND_FAKE, insert_flagfinish, 0 },
133
134 /* fake utility operand to set the 'f' flag for the "flag" insn */
135 #define FLAGINSN (FLAGFINISH + 1)
136 { 'G', 1, 8, ARC_OPERAND_FAKE, insert_flag, 0 },
137
138 /* branch delay types */
139 #define DELAY (FLAGINSN + 1)
140 { 'n', 2, 5, ARC_OPERAND_SUFFIX },
141
142 /* conditions */
143 #define COND (DELAY + 1)
144 { 'q', 5, 0, ARC_OPERAND_SUFFIX, insert_cond, extract_cond },
145
146 /* set `cond_p' to 1 to ensure a constant is treated as a limm */
147 #define FORCELIMM (COND + 1)
148 { 'Q', 0, 0, ARC_OPERAND_FAKE, insert_forcelimm },
149
150 /* branch address b, bl, and lp insns */
151 #define BRANCH (FORCELIMM + 1)
152 { 'B', 20, 7, ARC_OPERAND_RELATIVE + ARC_OPERAND_SIGNED, insert_reladdr },
153
154 /* size field, stored in bit 1,2 */
155 #define SIZE1 (BRANCH + 1)
156 { 'z', 2, 1, ARC_OPERAND_SUFFIX },
157
158 /* size field, stored in bit 10,11 */
159 #define SIZE10 (SIZE1 + 1)
160 { 'Z', 2, 10, ARC_OPERAND_SUFFIX, },
161
162 /* size field, stored in bit 22,23 */
163 #define SIZE22 (SIZE10 + 1)
164 { 'y', 2, 22, ARC_OPERAND_SUFFIX, },
165
166 /* sign extend field, stored in bit 0 */
167 #define SIGN0 (SIZE22 + 1)
168 { 'x', 1, 0, ARC_OPERAND_SUFFIX },
169
170 /* sign extend field, stored in bit 9 */
171 #define SIGN9 (SIGN0 + 1)
172 { 'X', 1, 9, ARC_OPERAND_SUFFIX },
173
174 /* address write back, stored in bit 3 */
175 #define ADDRESS3 (SIGN9 + 1)
176 { 'u', 1, 3, ARC_OPERAND_SUFFIX },
177
178 /* address write back, stored in bit 12 */
179 #define ADDRESS12 (ADDRESS3 + 1)
180 { 'v', 1, 12, ARC_OPERAND_SUFFIX },
181
182 /* address write back, stored in bit 24 */
183 #define ADDRESS24 (ADDRESS12 + 1)
184 { 'w', 1, 24, ARC_OPERAND_SUFFIX },
185
186 /* address write back, stored in bit 3 */
187 #define CACHEBYPASS5 (ADDRESS24 + 1)
188 { 'D', 1, 5, ARC_OPERAND_SUFFIX },
189
190 /* address write back, stored in bit 12 */
191 #define CACHEBYPASS14 (CACHEBYPASS5 + 1)
192 { 'e', 1, 14, ARC_OPERAND_SUFFIX },
193
194 /* address write back, stored in bit 24 */
195 #define CACHEBYPASS26 (CACHEBYPASS14 + 1)
196 { 'E', 1, 26, ARC_OPERAND_SUFFIX },
197
198 /* unop macro, used to copy REGB to REGC */
199 #define UNOPMACRO (CACHEBYPASS26 + 1)
200 { 'U', 6, ARC_SHIFT_REGC, ARC_OPERAND_FAKE, insert_unopmacro, extract_unopmacro },
201
202 /* multiply/shifter detector */
203 /* ??? Using ARC_OPERAND_FAKE this way is probably taking things too far. */
204 #define MULTSHIFT (UNOPMACRO + 1)
205 { 'M', 0, 0, ARC_OPERAND_FAKE, insert_multshift, extract_multshift },
206
207 /* '.' modifier ('.' required). */
208 #define MODDOT (MULTSHIFT + 1)
209 { '.', 1, 0, ARC_MOD_DOT },
210
211 /* Dummy 'r' modifier for the register table.
212 It's called a "dummy" because there's no point in inserting an 'r' into all
213 the %a/%b/%c occurrences in the insn table. */
214 #define REG (MODDOT + 1)
215 { 'r', 6, 0, ARC_MOD_REG },
216
217 /* Known auxiliary register modifier (stored in shimm field). */
218 #define AUXREG (REG + 1)
219 { 'A', 9, 0, ARC_MOD_AUXREG },
220
221 /* end of list place holder */
222 { 0 }
223 };
224
225 /* Given a format letter, yields the index into `arc_operands'.
226 eg: arc_operand_map['a'] = REGA. */
227 unsigned char arc_operand_map[256];
228
229 #define I(x) (((x) & 31) << 27)
230 #define A(x) (((x) & ARC_MASK_REG) << ARC_SHIFT_REGA)
231 #define B(x) (((x) & ARC_MASK_REG) << ARC_SHIFT_REGB)
232 #define C(x) (((x) & ARC_MASK_REG) << ARC_SHIFT_REGC)
233 #define R(x,b,m) (((x) & (m)) << (b)) /* value X, mask M, at bit B */
234
235 /* ARC instructions (sorted by at least the first letter, and equivalent
236 opcodes kept together).
237
238 By recording the insns this way, the table is not hashable on the opcode.
239 That's not a real loss though as there are only a few entries for each
240 insn (ld/st being the exception), which are quickly found and since
241 they're stored together (eg: all `ld' variants are together) very little
242 time is spent on the opcode itself. The slow part is parsing the options,
243 but that's always going to be slow.
244
245 Longer versions of insns must appear before shorter ones (if gas sees
246 "lsr r2,r3,1" when it's parsing "lsr %a,%b" it will think the ",1" is
247 junk). */
248
249 /* ??? This table also includes macros: asl, lsl, and mov. The ppc port has
250 a more general facility for dealing with macros which could be used if
251 we need to. */
252 /* ??? As an experiment, the "mov" macro appears at the start so it is
253 prefered to "and" when disassembling. At present, the table needn't be
254 sorted, though all opcodes with the same first letter must be kept
255 together. */
256
257 const struct arc_opcode arc_opcodes[] = {
258 /* Note that "mov" is really an "and". */
259 { "mov%.q%.f %a,%b%F%S%L%U", I(-1), I(12) },
260 { "mul%M%.q%.f %a,%b,%c%F%S%L", I(-1), I(20) },
261 { "mulu%M%.q%.f %a,%b,%c%F%S%L", I(-1), I(21) },
262
263 { "adc%.q%.f %a,%b,%c%F%S%L", I(-1), I(9) },
264 { "add%.q%.f %a,%b,%c%F%S%L", I(-1), I(8) },
265 { "and%.q%.f %a,%b,%c%F%S%L", I(-1), I(12) },
266 { "asl%M%.q%.f %a,%b,%c%F%S%L", I(-1), I(16) },
267 /* Note that "asl" is really an "add". */
268 { "asl%.q%.f %a,%b%F%S%L%U", I(-1), I(8) },
269 { "asr%M%.q%.f %a,%b,%c%F%S%L", I(-1), I(18) },
270 { "asr%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(1) },
271 { "bic%.q%.f %a,%b,%c%F%S%L", I(-1), I(14) },
272 { "b%q%.n %B", I(-1), I(4) },
273 { "bl%q%.n %B", I(-1), I(5) },
274 { "extb%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(7) },
275 { "extw%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(8) },
276 { "flag%.q %b%G%S%L", I(-1)+A(-1)+C(-1), I(3)+A(ARC_REG_SHIMM_UPDATE)+C(0) },
277 /* %Q: force cond_p=1 --> no shimm values */
278 { "j%q%Q%.n%.f %b%L", I(-1)+A(-1)+C(-1)+R(-1,7,1), I(7)+A(0)+C(0)+R(0,7,1) },
279 /* Put opcode 1 ld insns first so shimm gets prefered over limm. */
280 /* "[%b]" is before "[%b,%d]" so 0 offsets don't get printed. */
281 { "ld%Z%.X%.v%.e %0%a,[%b]%L", I(-1)+R(-1,13,1)+R(-1,0,511), I(1)+R(0,13,1)+R(0,0,511) },
282 { "ld%Z%.X%.v%.e %a,[%b,%d]%S%L", I(-1)+R(-1,13,1), I(1)+R(0,13,1) },
283 { "ld%z%.x%.u%.D %a,[%b,%c]", I(-1)+R(-1,4,1)+R(-1,6,7), I(0)+R(0,4,1)+R(0,6,7) },
284 { "lp%q%.n %B", I(-1), I(6), },
285 { "lr %a,[%Ab]%S%L", I(-1)+C(-1), I(1)+C(0x10) },
286 /* Note that "lsl" is really an "add". */
287 { "lsl%.q%.f %a,%b%F%S%L%U", I(-1), I(8) },
288 { "lsr%M%.q%.f %a,%b,%c%F%S%L", I(-1), I(17) },
289 { "lsr%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(2) },
290 /* Note that "nop" is really an "xor". */
291 { "nop", 0xffffffff, 0x7fffffff },
292 { "or%.q%.f %a,%b,%c%F%S%L", I(-1), I(13) },
293 /* Note that "rlc" is really an "adc". */
294 { "rlc%.q%.f %a,%b%F%S%L%U", I(-1), I(9) },
295 { "ror%M%.q%.f %a,%b,%c%F%S%L", I(-1), I(19) },
296 { "ror%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(3) },
297 { "rrc%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(4) },
298 { "sbc%.q%.f %a,%b,%c%F%S%L", I(-1), I(11) },
299 { "sexb%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(5) },
300 { "sexw%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(6) },
301 { "sr %c,[%Ab]%S%L", I(-1)+A(-1), I(2)+A(0x10) },
302 /* "[%b]" is before "[%b,%d]" so 0 offsets don't get printed. */
303 { "st%y%.w%.E %0%c,[%b]%L", I(-1)+R(-1,25,3)+R(-1,21,1)+R(-1,0,511), I(2)+R(0,25,3)+R(0,21,1)+R(0,0,511) },
304 { "st%y%.w%.E %c,[%b,%d]%S%L", I(-1)+R(-1,25,3)+R(-1,21,1), I(2)+R(0,25,3)+R(0,21,1) },
305 { "sub%.q%.f %a,%b,%c%F%S%L", I(-1), I(10) },
306 { "xor%.q%.f %a,%b,%c%F%S%L", I(-1), I(15) }
307 };
308 int arc_opcodes_count = sizeof (arc_opcodes) / sizeof (arc_opcodes[0]);
309
310 const struct arc_operand_value arc_reg_names[] =
311 {
312 /* Sort this so that the first 61 entries are sequential.
313 IE: For each i (i<61), arc_reg_names[i].value == i. */
314
315 { "r0", 0, REG }, { "r1", 1, REG }, { "r2", 2, REG }, { "r3", 3, REG },
316 { "r4", 4, REG }, { "r5", 5, REG }, { "r6", 6, REG }, { "r7", 7, REG },
317 { "r8", 8, REG }, { "r9", 9, REG }, { "r10", 10, REG }, { "r11", 11, REG },
318 { "r12", 12, REG }, { "r13", 13, REG }, { "r14", 14, REG }, { "r15", 15, REG },
319 { "r16", 16, REG }, { "r17", 17, REG }, { "r18", 18, REG }, { "r19", 19, REG },
320 { "r20", 20, REG }, { "r21", 21, REG }, { "r22", 22, REG }, { "r23", 23, REG },
321 { "r24", 24, REG }, { "r25", 25, REG }, { "r26", 26, REG }, { "fp", 27, REG },
322 { "sp", 28, REG }, { "ilink1", 29, REG }, { "ilink2", 30, REG }, { "blink", 31, REG },
323 { "r32", 32, REG }, { "r33", 33, REG }, { "r34", 34, REG }, { "r35", 35, REG },
324 { "r36", 36, REG }, { "r37", 37, REG }, { "r38", 38, REG }, { "r39", 39, REG },
325 { "r40", 40, REG }, { "r41", 41, REG }, { "r42", 42, REG }, { "r43", 43, REG },
326 { "r44", 44, REG }, { "r45", 45, REG }, { "r46", 46, REG }, { "r47", 47, REG },
327 { "r48", 48, REG }, { "r49", 49, REG }, { "r50", 50, REG }, { "r51", 51, REG },
328 { "r52", 52, REG }, { "r53", 53, REG }, { "r54", 54, REG }, { "r55", 55, REG },
329 { "r56", 56, REG }, { "r57", 57, REG }, { "r58", 58, REG }, { "r59", 59, REG },
330 { "lp_count", 60, REG },
331
332 /* I'd prefer to output these as "fp" and "sp" by default, but we still need
333 to recognize the canonical values. */
334 { "r27", 27, REG }, { "r28", 28, REG },
335
336 /* Standard auxiliary registers. */
337 { "status", 0, AUXREG },
338 { "semaphore", 1, AUXREG },
339 { "lp_start", 2, AUXREG },
340 { "lp_end", 3, AUXREG },
341 { "identity", 4, AUXREG },
342 { "debug", 5, AUXREG },
343 };
344 int arc_reg_names_count = sizeof (arc_reg_names) / sizeof (arc_reg_names[0]);
345
346 /* The suffix table.
347 Operands with the same name must be stored together. */
348
349 const struct arc_operand_value arc_suffixes[] =
350 {
351 /* Entry 0 is special, default values aren't printed by the disassembler. */
352 { "", 0, -1 },
353 { "al", 0, COND },
354 { "ra", 0, COND },
355 { "eq", 1, COND },
356 { "z", 1, COND },
357 { "ne", 2, COND },
358 { "nz", 2, COND },
359 { "p", 3, COND },
360 { "pl", 3, COND },
361 { "n", 4, COND },
362 { "mi", 4, COND },
363 { "c", 5, COND },
364 { "cs", 5, COND },
365 { "lo", 5, COND },
366 { "nc", 6, COND },
367 { "cc", 6, COND },
368 { "hs", 6, COND },
369 { "v", 7, COND },
370 { "vs", 7, COND },
371 { "nv", 8, COND },
372 { "vc", 8, COND },
373 { "gt", 9, COND },
374 { "ge", 10, COND },
375 { "lt", 11, COND },
376 { "le", 12, COND },
377 { "hi", 13, COND },
378 { "ls", 14, COND },
379 { "pnz", 15, COND },
380 { "f", 1, FLAG },
381 { "nd", 0, DELAY },
382 { "d", 1, DELAY },
383 { "jd", 2, DELAY },
384 /* { "b", 7, SIZEEXT },*/
385 /* { "b", 5, SIZESEX },*/
386 { "b", 1, SIZE1 },
387 { "b", 1, SIZE10 },
388 { "b", 1, SIZE22 },
389 /* { "w", 8, SIZEEXT },*/
390 /* { "w", 6, SIZESEX },*/
391 { "w", 2, SIZE1 },
392 { "w", 2, SIZE10 },
393 { "w", 2, SIZE22 },
394 { "x", 1, SIGN0 },
395 { "x", 1, SIGN9 },
396 { "a", 1, ADDRESS3 },
397 { "a", 1, ADDRESS12 },
398 { "a", 1, ADDRESS24 },
399 { "di", 1, CACHEBYPASS5 },
400 { "di", 1, CACHEBYPASS14 },
401 { "di", 1, CACHEBYPASS26 },
402 };
403 int arc_suffixes_count = sizeof (arc_suffixes) / sizeof (arc_suffixes[0]);
404
405 /* Configuration flags. */
406
407 /* Various ARC_HAVE_XXX bits. */
408 static int cpu_type;
409
410 /* Initialize any tables that need it.
411 Must be called once at start up (or when first needed).
412
413 CPU is a set of bits that say what version of the cpu we have. */
414
415 void
416 arc_opcode_init_tables (cpu)
417 int cpu;
418 {
419 register int i,n;
420
421 memset (arc_operand_map, 0, sizeof (arc_operand_map));
422 n = sizeof (arc_operands) / sizeof (arc_operands[0]);
423 for (i = 0; i < n; i++)
424 arc_operand_map[arc_operands[i].fmt] = i;
425
426 cpu_type = cpu;
427 }
428 \f
429 /* Nonzero if we've seen an 'f' suffix (in certain insns). */
430 static int flag_p;
431
432 /* Nonzero if we've finished processing the 'f' suffix. */
433 static int flagshimm_handled_p;
434
435 /* Nonzero if we've seen a 'q' suffix (condition code). */
436 static int cond_p;
437
438 /* Nonzero if we've inserted a shimm. */
439 static int shimm_p;
440
441 /* The value of the shimm we inserted (each insn only gets one but it can
442 appear multiple times. */
443 static int shimm;
444
445 /* Nonzero if we've inserted a limm (during assembly) or seen a limm
446 (during disassembly). */
447 static int limm_p;
448
449 /* The value of the limm we inserted. Each insn only gets one but it can
450 appear multiple times. */
451 static long limm;
452
453 /* Called by the assembler before parsing an instruction. */
454
455 void
456 arc_opcode_init_insert ()
457 {
458 flag_p = 0;
459 flagshimm_handled_p = 0;
460 cond_p = 0;
461 shimm_p = 0;
462 limm_p = 0;
463 }
464
465 /* Called by the assembler to see if the insn has a limm operand.
466 Also called by the disassembler to see if the insn contains a limm. */
467
468 int
469 arc_opcode_limm_p (limmp)
470 long *limmp;
471 {
472 if (limmp)
473 *limmp = limm;
474 return limm_p;
475 }
476
477 /* Insert a value into a register field.
478 If REG is NULL, then this is actually a constant.
479
480 We must also handle auxiliary registers for lr/sr insns. */
481
482 static arc_insn
483 insert_reg (insn, operand, mods, reg, value, errmsg)
484 arc_insn insn;
485 const struct arc_operand *operand;
486 int mods;
487 const struct arc_operand_value *reg;
488 long value;
489 const char **errmsg;
490 {
491 static char buf[100];
492
493 if (!reg)
494 {
495 /* We have a constant that also requires a value stored in a register
496 field. Handle these by updating the register field and saving the
497 value for later handling by either %S (shimm) or %L (limm). */
498
499 /* Try to use a shimm value before a limm one. */
500 if (ARC_SHIMM_CONST_P (value)
501 /* If we've seen a conditional suffix we have to use a limm. */
502 && !cond_p
503 /* If we already have a shimm value that is different than ours
504 we have to use a limm. */
505 && (!shimm_p || shimm == value))
506 {
507 int marker = flag_p ? ARC_REG_SHIMM_UPDATE : ARC_REG_SHIMM;
508 flagshimm_handled_p = 1;
509 shimm_p = 1;
510 shimm = value;
511 insn |= marker << operand->shift;
512 /* insn |= value & 511; - done later */
513 }
514 /* We have to use a limm. If we've already seen one they must match. */
515 else if (!limm_p || limm == value)
516 {
517 limm_p = 1;
518 limm = value;
519 insn |= ARC_REG_LIMM << operand->shift;
520 /* The constant is stored later. */
521 }
522 else
523 {
524 *errmsg = "unable to fit different valued constants into instruction";
525 }
526 }
527 else
528 {
529 /* We have to handle both normal and auxiliary registers. */
530
531 if (reg->type == AUXREG)
532 {
533 if (!(mods & ARC_MOD_AUXREG))
534 *errmsg = "auxiliary register not allowed here";
535 else
536 {
537 insn |= ARC_REG_SHIMM << operand->shift;
538 insn |= reg->value << arc_operands[reg->type].shift;
539 }
540 }
541 else
542 {
543 /* We should never get an invalid register number here. */
544 if ((unsigned int) reg->value > 60)
545 {
546 sprintf (buf, "invalid register number `%d'", reg->value);
547 *errmsg = buf;
548 }
549 else
550 insn |= reg->value << operand->shift;
551 }
552 }
553
554 return insn;
555 }
556
557 /* Called when we see an 'f' flag. */
558
559 static arc_insn
560 insert_flag (insn, operand, mods, reg, value, errmsg)
561 arc_insn insn;
562 const struct arc_operand *operand;
563 int mods;
564 const struct arc_operand_value *reg;
565 long value;
566 const char **errmsg;
567 {
568 /* We can't store anything in the insn until we've parsed the registers.
569 Just record the fact that we've got this flag. `insert_reg' will use it
570 to store the correct value (ARC_REG_SHIMM_UPDATE or bit 0x100). */
571 flag_p = 1;
572
573 return insn;
574 }
575
576 /* Called after completely building an insn to ensure the 'f' flag gets set
577 properly. This is needed because we don't know how to set this flag until
578 we've parsed the registers. */
579
580 static arc_insn
581 insert_flagfinish (insn, operand, mods, reg, value, errmsg)
582 arc_insn insn;
583 const struct arc_operand *operand;
584 int mods;
585 const struct arc_operand_value *reg;
586 long value;
587 const char **errmsg;
588 {
589 if (flag_p && !flagshimm_handled_p)
590 {
591 if (shimm_p)
592 abort ();
593 flagshimm_handled_p = 1;
594 insn |= (1 << operand->shift);
595 }
596 return insn;
597 }
598
599 /* Called when we see a conditional flag (eg: .eq). */
600
601 static arc_insn
602 insert_cond (insn, operand, mods, reg, value, errmsg)
603 arc_insn insn;
604 const struct arc_operand *operand;
605 int mods;
606 const struct arc_operand_value *reg;
607 long value;
608 const char **errmsg;
609 {
610 cond_p = 1;
611 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
612 return insn;
613 }
614
615 /* Used in the "j" instruction to prevent constants from being interpreted as
616 shimm values (which the jump insn doesn't accept). This can also be used
617 to force the use of limm values in other situations (eg: ld r0,[foo] uses
618 this).
619 ??? The mechanism is sound. Access to it is a bit klunky right now. */
620
621 static arc_insn
622 insert_forcelimm (insn, operand, mods, reg, value, errmsg)
623 arc_insn insn;
624 const struct arc_operand *operand;
625 int mods;
626 const struct arc_operand_value *reg;
627 long value;
628 const char **errmsg;
629 {
630 cond_p = 1;
631 return insn;
632 }
633
634 /* Used in ld/st insns to handle the shimm offset field. */
635
636 static arc_insn
637 insert_shimmoffset (insn, operand, mods, reg, value, errmsg)
638 arc_insn insn;
639 const struct arc_operand *operand;
640 int mods;
641 const struct arc_operand_value *reg;
642 long value;
643 const char **errmsg;
644 {
645 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
646 return insn;
647 }
648
649 /* Used in ld/st insns when the shimm offset is 0. */
650
651 static arc_insn
652 insert_shimmzero (insn, operand, mods, reg, value, errmsg)
653 arc_insn insn;
654 const struct arc_operand *operand;
655 int mods;
656 const struct arc_operand_value *reg;
657 long value;
658 const char **errmsg;
659 {
660 shimm_p = 1;
661 shimm = 0;
662 return insn;
663 }
664
665 /* Called at the end of processing normal insns (eg: add) to insert a shimm
666 value (if present) into the insn. */
667
668 static arc_insn
669 insert_shimmfinish (insn, operand, mods, reg, value, errmsg)
670 arc_insn insn;
671 const struct arc_operand *operand;
672 int mods;
673 const struct arc_operand_value *reg;
674 long value;
675 const char **errmsg;
676 {
677 if (shimm_p)
678 insn |= (shimm & ((1 << operand->bits) - 1)) << operand->shift;
679 return insn;
680 }
681
682 /* Called at the end of processing normal insns (eg: add) to insert a limm
683 value (if present) into the insn. Actually, there's nothing for us to do
684 as we can't call frag_more, the caller must do that. */
685 /* ??? The extract fns take a pointer to two words. The insert insns could be
686 converted and then we could do something useful. Not sure it's worth it. */
687
688 static arc_insn
689 insert_limmfinish (insn, operand, mods, reg, value, errmsg)
690 arc_insn insn;
691 const struct arc_operand *operand;
692 int mods;
693 const struct arc_operand_value *reg;
694 long value;
695 const char **errmsg;
696 {
697 if (limm_p)
698 ; /* nothing to do */
699 return insn;
700 }
701
702 /* Called at the end of unary operand macros to copy the B field to C. */
703
704 static arc_insn
705 insert_unopmacro (insn, operand, mods, reg, value, errmsg)
706 arc_insn insn;
707 const struct arc_operand *operand;
708 int mods;
709 const struct arc_operand_value *reg;
710 long value;
711 const char **errmsg;
712 {
713 insn |= ((insn >> ARC_SHIFT_REGB) & ARC_MASK_REG) << operand->shift;
714 return insn;
715 }
716
717 /* Insert a relative address for a branch insn (b, bl, or lp). */
718
719 static arc_insn
720 insert_reladdr (insn, operand, mods, reg, value, errmsg)
721 arc_insn insn;
722 const struct arc_operand *operand;
723 int mods;
724 const struct arc_operand_value *reg;
725 long value;
726 const char **errmsg;
727 {
728 /* FIXME: Addresses are stored * 4. Do we want to handle that here? */
729 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
730 return insn;
731 }
732
733 /* Fake operand to disallow the multiply and variable shift insns if the cpu
734 doesn't have them. */
735
736 static arc_insn
737 insert_multshift (insn, operand, mods, reg, value, errmsg)
738 arc_insn insn;
739 const struct arc_operand *operand;
740 int mods;
741 const struct arc_operand_value *reg;
742 long value;
743 const char **errmsg;
744 {
745 if (!(cpu_type & ARC_HAVE_MULT_SHIFT))
746 *errmsg = "cpu doesn't support this insn";
747 return insn;
748 }
749 \f
750 /* Extraction functions.
751
752 The suffix extraction functions' return value is redundant since it can be
753 obtained from (*OPVAL)->value. However, the boolean suffixes don't have
754 a suffix table entry for the "false" case, so values of zero must be
755 obtained from the return value (*OPVAL == NULL). */
756
757 static const struct arc_operand_value *lookup_register (int type, long regno);
758
759 /* Called by the disassembler before printing an instruction. */
760
761 void
762 arc_opcode_init_extract ()
763 {
764 flag_p = 0;
765 flagshimm_handled_p = 0;
766 shimm_p = 0;
767 limm_p = 0;
768 }
769
770 /* As we're extracting registers, keep an eye out for the 'f' indicator
771 (ARC_REG_SHIMM_UPDATE). If we find a register (not a constant marker,
772 like ARC_REG_SHIMM), set OPVAL so our caller will know this is a register.
773
774 We must also handle auxiliary registers for lr/sr insns. They are just
775 constants with special names. */
776
777 static long
778 extract_reg (insn, operand, mods, opval, invalid)
779 arc_insn *insn;
780 const struct arc_operand *operand;
781 int mods;
782 const struct arc_operand_value **opval;
783 int *invalid;
784 {
785 int regno;
786 long value;
787
788 /* Get the register number. */
789 regno = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
790
791 /* Is it a constant marker? */
792 if (regno == ARC_REG_SHIMM)
793 {
794 value = insn[0] & 511;
795 if ((operand->flags & ARC_OPERAND_SIGNED)
796 && (value & 256))
797 value -= 512;
798 flagshimm_handled_p = 1;
799 }
800 else if (regno == ARC_REG_SHIMM_UPDATE)
801 {
802 value = insn[0] & 511;
803 if ((operand->flags & ARC_OPERAND_SIGNED)
804 && (value & 256))
805 value -= 512;
806 flag_p = 1;
807 flagshimm_handled_p = 1;
808 }
809 else if (regno == ARC_REG_LIMM)
810 {
811 value = insn[1];
812 limm_p = 1;
813 }
814 /* It's a register, set OPVAL (that's the only way we distinguish registers
815 from constants here). */
816 else
817 {
818 const struct arc_operand_value *reg = lookup_register (REG, regno);
819
820 if (!reg)
821 abort ();
822 if (opval)
823 *opval = reg;
824 value = regno;
825 }
826
827 /* If this field takes an auxiliary register, see if it's a known one. */
828 if ((mods & ARC_MOD_AUXREG)
829 && ARC_REG_CONSTANT_P (regno))
830 {
831 const struct arc_operand_value *reg = lookup_register (AUXREG, value);
832
833 /* This is really a constant, but tell the caller it has a special
834 name. */
835 if (reg && opval)
836 *opval = reg;
837 }
838
839 return value;
840 }
841
842 /* Return the value of the "flag update" field for shimm insns.
843 This value is actually stored in the register field. */
844
845 static long
846 extract_flag (insn, operand, mods, opval, invalid)
847 arc_insn *insn;
848 const struct arc_operand *operand;
849 int mods;
850 const struct arc_operand_value **opval;
851 int *invalid;
852 {
853 int f;
854 const struct arc_operand_value *val;
855
856 if (flagshimm_handled_p)
857 f = flag_p != 0;
858 else
859 f = (insn[0] & (1 << operand->shift)) != 0;
860
861 /* There is no text for zero values. */
862 if (f == 0)
863 return 0;
864
865 val = arc_opcode_lookup_suffix (operand, 1);
866 if (opval && val)
867 *opval = val;
868 return val->value;
869 }
870
871 /* Extract the condition code (if it exists).
872 If we've seen a shimm value in this insn (meaning that the insn can't have
873 a condition code field), then we don't store anything in OPVAL and return
874 zero. */
875
876 static long
877 extract_cond (insn, operand, mods, opval, invalid)
878 arc_insn *insn;
879 const struct arc_operand *operand;
880 int mods;
881 const struct arc_operand_value **opval;
882 int *invalid;
883 {
884 long cond;
885 const struct arc_operand_value *val;
886
887 if (flagshimm_handled_p)
888 return 0;
889
890 cond = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
891 val = arc_opcode_lookup_suffix (operand, cond);
892
893 /* Ignore NULL values of `val'. Several condition code values aren't
894 implemented yet. */
895 if (opval && val)
896 *opval = val;
897 return cond;
898 }
899
900 /* The only thing this does is set the `invalid' flag if B != C.
901 This is needed because the "mov" macro appears before it's real insn "and"
902 and we don't want the disassembler to confuse them. */
903
904 static long
905 extract_unopmacro (insn, operand, mods, opval, invalid)
906 arc_insn *insn;
907 const struct arc_operand *operand;
908 int mods;
909 const struct arc_operand_value **opval;
910 int *invalid;
911 {
912 /* ??? This misses the case where B == ARC_REG_SHIMM_UPDATE &&
913 C == ARC_REG_SHIMM (or vice versa). No big deal. Those insns will get
914 printed as "and"s. */
915 if (((insn[0] >> ARC_SHIFT_REGB) & ARC_MASK_REG)
916 != ((insn[0] >> ARC_SHIFT_REGC) & ARC_MASK_REG))
917 if (invalid)
918 *invalid = 1;
919
920 return 0;
921 }
922
923 /* Don't recognize the multiply and variable shift insns if the cpu doesn't
924 have them.
925
926 ??? Actually, we probably should anyway. */
927
928 static long
929 extract_multshift (insn, operand, mods, opval, invalid)
930 arc_insn *insn;
931 const struct arc_operand *operand;
932 int mods;
933 const struct arc_operand_value **opval;
934 int *invalid;
935 {
936 return 0;
937 }
938
939 /* Utility for the extraction functions to return the index into
940 `arc_suffixes'. */
941
942 const struct arc_operand_value *
943 arc_opcode_lookup_suffix (type, value)
944 const struct arc_operand *type;
945 int value;
946 {
947 register const struct arc_operand_value *v,*end;
948
949 /* ??? This is a little slow and can be speeded up. */
950
951 for (v = arc_suffixes, end = arc_suffixes + arc_suffixes_count; v < end; ++v)
952 if (type == &arc_operands[v->type]
953 && value == v->value)
954 return v;
955 return 0;
956 }
957
958 static const struct arc_operand_value *
959 lookup_register (type, regno)
960 int type;
961 long regno;
962 {
963 register const struct arc_operand_value *r,*end;
964
965 if (type == REG)
966 return &arc_reg_names[regno];
967
968 /* ??? This is a little slow and can be speeded up. */
969
970 for (r = arc_reg_names, end = arc_reg_names + arc_reg_names_count;
971 r < end; ++r)
972 if (type == r->type && regno == r->value)
973 return r;
974 return 0;
975 }