OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [gdb-5.0/] [opcodes/] [arc-opc.c] - Blame information for rev 1778

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.