xref: /openbsd-src/gnu/usr.bin/binutils-2.17/include/opcode/arc.h (revision 3d8817e467ea46cf4772788d6804dd293abfb01a)
1*3d8817e4Smiod /* Opcode table for the ARC.
2*3d8817e4Smiod    Copyright 1994, 1995, 1997, 2001, 2002, 2003
3*3d8817e4Smiod    Free Software Foundation, Inc.
4*3d8817e4Smiod    Contributed by Doug Evans (dje@cygnus.com).
5*3d8817e4Smiod 
6*3d8817e4Smiod    This file is part of GAS, the GNU Assembler, GDB, the GNU debugger, and
7*3d8817e4Smiod    the GNU Binutils.
8*3d8817e4Smiod 
9*3d8817e4Smiod    GAS/GDB is free software; you can redistribute it and/or modify
10*3d8817e4Smiod    it under the terms of the GNU General Public License as published by
11*3d8817e4Smiod    the Free Software Foundation; either version 2, or (at your option)
12*3d8817e4Smiod    any later version.
13*3d8817e4Smiod 
14*3d8817e4Smiod    GAS/GDB is distributed in the hope that it will be useful,
15*3d8817e4Smiod    but WITHOUT ANY WARRANTY; without even the implied warranty of
16*3d8817e4Smiod    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
17*3d8817e4Smiod    GNU General Public License for more details.
18*3d8817e4Smiod 
19*3d8817e4Smiod    You should have received a copy of the GNU General Public License
20*3d8817e4Smiod    along with GAS or GDB; see the file COPYING.	If not, write to
21*3d8817e4Smiod    the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
22*3d8817e4Smiod    MA 02110-1301, USA.  */
23*3d8817e4Smiod 
24*3d8817e4Smiod 
25*3d8817e4Smiod /* List of the various cpu types.
26*3d8817e4Smiod    The tables currently use bit masks to say whether the instruction or
27*3d8817e4Smiod    whatever is supported by a particular cpu.  This lets us have one entry
28*3d8817e4Smiod    apply to several cpus.
29*3d8817e4Smiod 
30*3d8817e4Smiod    The `base' cpu must be 0. The cpu type is treated independently of
31*3d8817e4Smiod    endianness. The complete `mach' number includes endianness.
32*3d8817e4Smiod    These values are internal to opcodes/bfd/binutils/gas.  */
33*3d8817e4Smiod #define ARC_MACH_5 0
34*3d8817e4Smiod #define ARC_MACH_6 1
35*3d8817e4Smiod #define ARC_MACH_7 2
36*3d8817e4Smiod #define ARC_MACH_8 4
37*3d8817e4Smiod 
38*3d8817e4Smiod /* Additional cpu values can be inserted here and ARC_MACH_BIG moved down.  */
39*3d8817e4Smiod #define ARC_MACH_BIG 16
40*3d8817e4Smiod 
41*3d8817e4Smiod /* Mask of number of bits necessary to record cpu type.  */
42*3d8817e4Smiod #define ARC_MACH_CPU_MASK (ARC_MACH_BIG - 1)
43*3d8817e4Smiod 
44*3d8817e4Smiod /* Mask of number of bits necessary to record cpu type + endianness.  */
45*3d8817e4Smiod #define ARC_MACH_MASK ((ARC_MACH_BIG << 1) - 1)
46*3d8817e4Smiod 
47*3d8817e4Smiod /* Type to denote an ARC instruction (at least a 32 bit unsigned int).  */
48*3d8817e4Smiod 
49*3d8817e4Smiod typedef unsigned int arc_insn;
50*3d8817e4Smiod 
51*3d8817e4Smiod struct arc_opcode {
52*3d8817e4Smiod   char *syntax;              /* syntax of insn  */
53*3d8817e4Smiod   unsigned long mask, value; /* recognize insn if (op&mask) == value  */
54*3d8817e4Smiod   int flags;                 /* various flag bits  */
55*3d8817e4Smiod 
56*3d8817e4Smiod /* Values for `flags'.  */
57*3d8817e4Smiod 
58*3d8817e4Smiod /* Return CPU number, given flag bits.  */
59*3d8817e4Smiod #define ARC_OPCODE_CPU(bits) ((bits) & ARC_MACH_CPU_MASK)
60*3d8817e4Smiod 
61*3d8817e4Smiod /* Return MACH number, given flag bits.  */
62*3d8817e4Smiod #define ARC_OPCODE_MACH(bits) ((bits) & ARC_MACH_MASK)
63*3d8817e4Smiod 
64*3d8817e4Smiod /* First opcode flag bit available after machine mask.  */
65*3d8817e4Smiod #define ARC_OPCODE_FLAG_START (ARC_MACH_MASK + 1)
66*3d8817e4Smiod 
67*3d8817e4Smiod /* This insn is a conditional branch.  */
68*3d8817e4Smiod #define ARC_OPCODE_COND_BRANCH (ARC_OPCODE_FLAG_START)
69*3d8817e4Smiod #define SYNTAX_3OP             (ARC_OPCODE_COND_BRANCH << 1)
70*3d8817e4Smiod #define SYNTAX_LENGTH          (SYNTAX_3OP                 )
71*3d8817e4Smiod #define SYNTAX_2OP             (SYNTAX_3OP             << 1)
72*3d8817e4Smiod #define OP1_MUST_BE_IMM        (SYNTAX_2OP             << 1)
73*3d8817e4Smiod #define OP1_IMM_IMPLIED        (OP1_MUST_BE_IMM        << 1)
74*3d8817e4Smiod #define SYNTAX_VALID           (OP1_IMM_IMPLIED        << 1)
75*3d8817e4Smiod 
76*3d8817e4Smiod #define I(x) (((x) & 31) << 27)
77*3d8817e4Smiod #define A(x) (((x) & ARC_MASK_REG) << ARC_SHIFT_REGA)
78*3d8817e4Smiod #define B(x) (((x) & ARC_MASK_REG) << ARC_SHIFT_REGB)
79*3d8817e4Smiod #define C(x) (((x) & ARC_MASK_REG) << ARC_SHIFT_REGC)
80*3d8817e4Smiod #define R(x,b,m) (((x) & (m)) << (b)) /* value X, mask M, at bit B */
81*3d8817e4Smiod 
82*3d8817e4Smiod /* These values are used to optimize assembly and disassembly.  Each insn
83*3d8817e4Smiod    is on a list of related insns (same first letter for assembly, same
84*3d8817e4Smiod    insn code for disassembly).  */
85*3d8817e4Smiod 
86*3d8817e4Smiod   struct arc_opcode *next_asm;	/* Next instr to try during assembly.  */
87*3d8817e4Smiod   struct arc_opcode *next_dis;	/* Next instr to try during disassembly.  */
88*3d8817e4Smiod 
89*3d8817e4Smiod /* Macros to create the hash values for the lists.  */
90*3d8817e4Smiod #define ARC_HASH_OPCODE(string) \
91*3d8817e4Smiod   ((string)[0] >= 'a' && (string)[0] <= 'z' ? (string)[0] - 'a' : 26)
92*3d8817e4Smiod #define ARC_HASH_ICODE(insn) \
93*3d8817e4Smiod   ((unsigned int) (insn) >> 27)
94*3d8817e4Smiod 
95*3d8817e4Smiod  /* Macros to access `next_asm', `next_dis' so users needn't care about the
96*3d8817e4Smiod     underlying mechanism.  */
97*3d8817e4Smiod #define ARC_OPCODE_NEXT_ASM(op) ((op)->next_asm)
98*3d8817e4Smiod #define ARC_OPCODE_NEXT_DIS(op) ((op)->next_dis)
99*3d8817e4Smiod };
100*3d8817e4Smiod 
101*3d8817e4Smiod /* this is an "insert at front" linked list per Metaware spec
102*3d8817e4Smiod    that new definitions override older ones.  */
103*3d8817e4Smiod extern struct arc_opcode *arc_ext_opcodes;
104*3d8817e4Smiod 
105*3d8817e4Smiod struct arc_operand_value {
106*3d8817e4Smiod   char *name;          /* eg: "eq"  */
107*3d8817e4Smiod   short value;         /* eg: 1  */
108*3d8817e4Smiod   unsigned char type;  /* index into `arc_operands'  */
109*3d8817e4Smiod   unsigned char flags; /* various flag bits  */
110*3d8817e4Smiod 
111*3d8817e4Smiod /* Values for `flags'.  */
112*3d8817e4Smiod 
113*3d8817e4Smiod /* Return CPU number, given flag bits.  */
114*3d8817e4Smiod #define ARC_OPVAL_CPU(bits) ((bits) & ARC_MACH_CPU_MASK)
115*3d8817e4Smiod /* Return MACH number, given flag bits.  */
116*3d8817e4Smiod #define ARC_OPVAL_MACH(bits) ((bits) & ARC_MACH_MASK)
117*3d8817e4Smiod };
118*3d8817e4Smiod 
119*3d8817e4Smiod struct arc_ext_operand_value {
120*3d8817e4Smiod   struct arc_ext_operand_value *next;
121*3d8817e4Smiod   struct arc_operand_value operand;
122*3d8817e4Smiod };
123*3d8817e4Smiod 
124*3d8817e4Smiod extern struct arc_ext_operand_value *arc_ext_operands;
125*3d8817e4Smiod 
126*3d8817e4Smiod struct arc_operand {
127*3d8817e4Smiod /* One of the insn format chars.  */
128*3d8817e4Smiod   unsigned char fmt;
129*3d8817e4Smiod 
130*3d8817e4Smiod /* The number of bits in the operand (may be unused for a modifier).  */
131*3d8817e4Smiod   unsigned char bits;
132*3d8817e4Smiod 
133*3d8817e4Smiod /* How far the operand is left shifted in the instruction, or
134*3d8817e4Smiod    the modifier's flag bit (may be unused for a modifier.  */
135*3d8817e4Smiod   unsigned char shift;
136*3d8817e4Smiod 
137*3d8817e4Smiod /* Various flag bits.  */
138*3d8817e4Smiod   int flags;
139*3d8817e4Smiod 
140*3d8817e4Smiod /* Values for `flags'.  */
141*3d8817e4Smiod 
142*3d8817e4Smiod /* This operand is a suffix to the opcode.  */
143*3d8817e4Smiod #define ARC_OPERAND_SUFFIX 1
144*3d8817e4Smiod 
145*3d8817e4Smiod /* This operand is a relative branch displacement.  The disassembler
146*3d8817e4Smiod    prints these symbolically if possible.  */
147*3d8817e4Smiod #define ARC_OPERAND_RELATIVE_BRANCH 2
148*3d8817e4Smiod 
149*3d8817e4Smiod /* This operand is an absolute branch address.  The disassembler
150*3d8817e4Smiod    prints these symbolically if possible.  */
151*3d8817e4Smiod #define ARC_OPERAND_ABSOLUTE_BRANCH 4
152*3d8817e4Smiod 
153*3d8817e4Smiod /* This operand is an address.  The disassembler
154*3d8817e4Smiod    prints these symbolically if possible.  */
155*3d8817e4Smiod #define ARC_OPERAND_ADDRESS 8
156*3d8817e4Smiod 
157*3d8817e4Smiod /* This operand is a long immediate value.  */
158*3d8817e4Smiod #define ARC_OPERAND_LIMM 0x10
159*3d8817e4Smiod 
160*3d8817e4Smiod /* This operand takes signed values.  */
161*3d8817e4Smiod #define ARC_OPERAND_SIGNED 0x20
162*3d8817e4Smiod 
163*3d8817e4Smiod /* This operand takes signed values, but also accepts a full positive
164*3d8817e4Smiod    range of values.  That is, if bits is 16, it takes any value from
165*3d8817e4Smiod    -0x8000 to 0xffff.  */
166*3d8817e4Smiod #define ARC_OPERAND_SIGNOPT 0x40
167*3d8817e4Smiod 
168*3d8817e4Smiod /* This operand should be regarded as a negative number for the
169*3d8817e4Smiod    purposes of overflow checking (i.e., the normal most negative
170*3d8817e4Smiod    number is disallowed and one more than the normal most positive
171*3d8817e4Smiod    number is allowed).  This flag will only be set for a signed
172*3d8817e4Smiod    operand.  */
173*3d8817e4Smiod #define ARC_OPERAND_NEGATIVE 0x80
174*3d8817e4Smiod 
175*3d8817e4Smiod /* This operand doesn't really exist.  The program uses these operands
176*3d8817e4Smiod    in special ways.  */
177*3d8817e4Smiod #define ARC_OPERAND_FAKE 0x100
178*3d8817e4Smiod 
179*3d8817e4Smiod /* separate flags operand for j and jl instructions  */
180*3d8817e4Smiod #define ARC_OPERAND_JUMPFLAGS 0x200
181*3d8817e4Smiod 
182*3d8817e4Smiod /* allow warnings and errors to be issued after call to insert_xxxxxx  */
183*3d8817e4Smiod #define ARC_OPERAND_WARN  0x400
184*3d8817e4Smiod #define ARC_OPERAND_ERROR 0x800
185*3d8817e4Smiod 
186*3d8817e4Smiod /* this is a load operand */
187*3d8817e4Smiod #define ARC_OPERAND_LOAD  0x8000
188*3d8817e4Smiod 
189*3d8817e4Smiod /* this is a store operand */
190*3d8817e4Smiod #define ARC_OPERAND_STORE 0x10000
191*3d8817e4Smiod 
192*3d8817e4Smiod /* Modifier values.  */
193*3d8817e4Smiod /* A dot is required before a suffix.  Eg: .le  */
194*3d8817e4Smiod #define ARC_MOD_DOT 0x1000
195*3d8817e4Smiod 
196*3d8817e4Smiod /* A normal register is allowed (not used, but here for completeness).  */
197*3d8817e4Smiod #define ARC_MOD_REG 0x2000
198*3d8817e4Smiod 
199*3d8817e4Smiod /* An auxiliary register name is expected.  */
200*3d8817e4Smiod #define ARC_MOD_AUXREG 0x4000
201*3d8817e4Smiod 
202*3d8817e4Smiod /* Sum of all ARC_MOD_XXX bits.  */
203*3d8817e4Smiod #define ARC_MOD_BITS 0x7000
204*3d8817e4Smiod 
205*3d8817e4Smiod /* Non-zero if the operand type is really a modifier.  */
206*3d8817e4Smiod #define ARC_MOD_P(X) ((X) & ARC_MOD_BITS)
207*3d8817e4Smiod 
208*3d8817e4Smiod /* enforce read/write only register restrictions  */
209*3d8817e4Smiod #define ARC_REGISTER_READONLY    0x01
210*3d8817e4Smiod #define ARC_REGISTER_WRITEONLY   0x02
211*3d8817e4Smiod #define ARC_REGISTER_NOSHORT_CUT 0x04
212*3d8817e4Smiod 
213*3d8817e4Smiod /* Insertion function.  This is used by the assembler.  To insert an
214*3d8817e4Smiod    operand value into an instruction, check this field.
215*3d8817e4Smiod 
216*3d8817e4Smiod    If it is NULL, execute
217*3d8817e4Smiod    i |= (p & ((1 << o->bits) - 1)) << o->shift;
218*3d8817e4Smiod    (I is the instruction which we are filling in, O is a pointer to
219*3d8817e4Smiod    this structure, and OP is the opcode value; this assumes twos
220*3d8817e4Smiod    complement arithmetic).
221*3d8817e4Smiod 
222*3d8817e4Smiod    If this field is not NULL, then simply call it with the
223*3d8817e4Smiod    instruction and the operand value.  It will return the new value
224*3d8817e4Smiod    of the instruction.  If the ERRMSG argument is not NULL, then if
225*3d8817e4Smiod    the operand value is illegal, *ERRMSG will be set to a warning
226*3d8817e4Smiod    string (the operand will be inserted in any case).  If the
227*3d8817e4Smiod    operand value is legal, *ERRMSG will be unchanged.
228*3d8817e4Smiod 
229*3d8817e4Smiod    REG is non-NULL when inserting a register value.  */
230*3d8817e4Smiod 
231*3d8817e4Smiod   arc_insn (*insert)
232*3d8817e4Smiod     (arc_insn insn, const struct arc_operand *operand, int mods,
233*3d8817e4Smiod      const struct arc_operand_value *reg, long value, const char **errmsg);
234*3d8817e4Smiod 
235*3d8817e4Smiod /* Extraction function.  This is used by the disassembler.  To
236*3d8817e4Smiod    extract this operand type from an instruction, check this field.
237*3d8817e4Smiod 
238*3d8817e4Smiod    If it is NULL, compute
239*3d8817e4Smiod      op = ((i) >> o->shift) & ((1 << o->bits) - 1);
240*3d8817e4Smiod      if ((o->flags & ARC_OPERAND_SIGNED) != 0
241*3d8817e4Smiod           && (op & (1 << (o->bits - 1))) != 0)
242*3d8817e4Smiod        op -= 1 << o->bits;
243*3d8817e4Smiod    (I is the instruction, O is a pointer to this structure, and OP
244*3d8817e4Smiod    is the result; this assumes twos complement arithmetic).
245*3d8817e4Smiod 
246*3d8817e4Smiod    If this field is not NULL, then simply call it with the
247*3d8817e4Smiod    instruction value.  It will return the value of the operand.  If
248*3d8817e4Smiod    the INVALID argument is not NULL, *INVALID will be set to
249*3d8817e4Smiod    non-zero if this operand type can not actually be extracted from
250*3d8817e4Smiod    this operand (i.e., the instruction does not match).  If the
251*3d8817e4Smiod    operand is valid, *INVALID will not be changed.
252*3d8817e4Smiod 
253*3d8817e4Smiod    INSN is a pointer to an array of two `arc_insn's.  The first element is
254*3d8817e4Smiod    the insn, the second is the limm if present.
255*3d8817e4Smiod 
256*3d8817e4Smiod    Operands that have a printable form like registers and suffixes have
257*3d8817e4Smiod    their struct arc_operand_value pointer stored in OPVAL.  */
258*3d8817e4Smiod 
259*3d8817e4Smiod   long (*extract)
260*3d8817e4Smiod     (arc_insn *insn, const struct arc_operand *operand, int mods,
261*3d8817e4Smiod      const struct arc_operand_value **opval, int *invalid);
262*3d8817e4Smiod };
263*3d8817e4Smiod 
264*3d8817e4Smiod /* Bits that say what version of cpu we have. These should be passed to
265*3d8817e4Smiod    arc_init_opcode_tables. At present, all there is is the cpu type.  */
266*3d8817e4Smiod 
267*3d8817e4Smiod /* CPU number, given value passed to `arc_init_opcode_tables'.  */
268*3d8817e4Smiod #define ARC_HAVE_CPU(bits) ((bits) & ARC_MACH_CPU_MASK)
269*3d8817e4Smiod /* MACH number, given value passed to `arc_init_opcode_tables'.  */
270*3d8817e4Smiod #define ARC_HAVE_MACH(bits) ((bits) & ARC_MACH_MASK)
271*3d8817e4Smiod 
272*3d8817e4Smiod /* Special register values:  */
273*3d8817e4Smiod #define ARC_REG_SHIMM_UPDATE 61
274*3d8817e4Smiod #define ARC_REG_SHIMM 63
275*3d8817e4Smiod #define ARC_REG_LIMM 62
276*3d8817e4Smiod 
277*3d8817e4Smiod /* Non-zero if REG is a constant marker.  */
278*3d8817e4Smiod #define ARC_REG_CONSTANT_P(REG) ((REG) >= 61)
279*3d8817e4Smiod 
280*3d8817e4Smiod /* Positions and masks of various fields:  */
281*3d8817e4Smiod #define ARC_SHIFT_REGA 21
282*3d8817e4Smiod #define ARC_SHIFT_REGB 15
283*3d8817e4Smiod #define ARC_SHIFT_REGC 9
284*3d8817e4Smiod #define ARC_MASK_REG 63
285*3d8817e4Smiod 
286*3d8817e4Smiod /* Delay slot types.  */
287*3d8817e4Smiod #define ARC_DELAY_NONE 0   /* no delay slot */
288*3d8817e4Smiod #define ARC_DELAY_NORMAL 1 /* delay slot in both cases */
289*3d8817e4Smiod #define ARC_DELAY_JUMP 2   /* delay slot only if branch taken */
290*3d8817e4Smiod 
291*3d8817e4Smiod /* Non-zero if X will fit in a signed 9 bit field.  */
292*3d8817e4Smiod #define ARC_SHIMM_CONST_P(x) ((long) (x) >= -256 && (long) (x) <= 255)
293*3d8817e4Smiod 
294*3d8817e4Smiod extern const struct arc_operand arc_operands[];
295*3d8817e4Smiod extern const int arc_operand_count;
296*3d8817e4Smiod extern struct arc_opcode arc_opcodes[];
297*3d8817e4Smiod extern const int arc_opcodes_count;
298*3d8817e4Smiod extern const struct arc_operand_value arc_suffixes[];
299*3d8817e4Smiod extern const int arc_suffixes_count;
300*3d8817e4Smiod extern const struct arc_operand_value arc_reg_names[];
301*3d8817e4Smiod extern const int arc_reg_names_count;
302*3d8817e4Smiod extern unsigned char arc_operand_map[];
303*3d8817e4Smiod 
304*3d8817e4Smiod /* Utility fns in arc-opc.c.  */
305*3d8817e4Smiod int arc_get_opcode_mach (int, int);
306*3d8817e4Smiod 
307*3d8817e4Smiod /* `arc_opcode_init_tables' must be called before `arc_xxx_supported'.  */
308*3d8817e4Smiod void arc_opcode_init_tables (int);
309*3d8817e4Smiod void arc_opcode_init_insert (void);
310*3d8817e4Smiod void arc_opcode_init_extract (void);
311*3d8817e4Smiod const struct arc_opcode *arc_opcode_lookup_asm (const char *);
312*3d8817e4Smiod const struct arc_opcode *arc_opcode_lookup_dis (unsigned int);
313*3d8817e4Smiod int arc_opcode_limm_p (long *);
314*3d8817e4Smiod const struct arc_operand_value *arc_opcode_lookup_suffix
315*3d8817e4Smiod   (const struct arc_operand *type, int value);
316*3d8817e4Smiod int arc_opcode_supported (const struct arc_opcode *);
317*3d8817e4Smiod int arc_opval_supported (const struct arc_operand_value *);
318*3d8817e4Smiod int arc_limm_fixup_adjust (arc_insn);
319*3d8817e4Smiod int arc_insn_is_j (arc_insn);
320*3d8817e4Smiod int arc_insn_not_jl (arc_insn);
321*3d8817e4Smiod int arc_operand_type (int);
322*3d8817e4Smiod struct arc_operand_value *get_ext_suffix (char *);
323*3d8817e4Smiod int arc_get_noshortcut_flag (void);
324