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