~ubuntu-branches/ubuntu/utopic/binutils-arm64-cross/utopic

« back to all changes in this revision

Viewing changes to binutils-2.23.52.20130611/opcodes/arc-opc.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-06-20 17:38:09 UTC
  • Revision ID: package-import@ubuntu.com-20130620173809-app8lzgvymy5fg6c
Tags: 0.7
Build-depend on binutils-source (>= 2.23.52.20130620-1~).

Show diffs side-by-side

added added

removed removed

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