Commit | Line | Data |
---|---|---|
32a0dad5 DE |
1 | /* Opcode table for the ARC. |
2 | Copyright 1994, 1995 Free Software Foundation, Inc. | |
3 | Contributed by Doug Evans (dje@cygnus.com). | |
4 | ||
5 | This program is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 2, or (at your option) | |
8 | any later version. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with this program; if not, write to the Free Software | |
17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
18 | ||
19 | /* List of the various cpu types. | |
20 | The tables currently use bit masks to say whether the instruction or | |
21 | whatever is supported by a particular cpu. This lets us have one entry | |
22 | apply to several cpus. | |
4ad003d1 | 23 | There may be more ARCs in the future, beyond the current project. |
32a0dad5 | 24 | |
4ad003d1 DE |
25 | This duplicates bfd_mach_arc_xxx. For now I wish to isolate this from bfd |
26 | and bfd from this. Also note that these numbers are bit values as we want | |
27 | to allow for things available on more than one ARC (but not necessarily all | |
28 | ARCs). */ | |
29 | ||
30 | /* The `base' cpu must be 0 (table entries are omitted for the base cpu). | |
31 | The cpu type is treated independently of endianness. | |
32 | The complete `mach' number includes endianness. */ | |
32a0dad5 DE |
33 | #define ARC_MACH_BASE 0 |
34 | #define ARC_MACH_HOST 1 | |
35 | #define ARC_MACH_GRAPHICS 2 | |
36 | #define ARC_MACH_AUDIO 4 | |
4ad003d1 | 37 | #define ARC_MACH_BIG 8 |
32a0dad5 DE |
38 | |
39 | /* Mask of number of bits necessary to record cpu type. */ | |
4ad003d1 DE |
40 | #define ARC_MACH_CPU_MASK 7 |
41 | /* Mask of number of bits necessary to record cpu type + endianness. */ | |
42 | #define ARC_MACH_MASK 15 | |
32a0dad5 DE |
43 | |
44 | /* Type to denote an ARC instruction (at least a 32 bit unsigned long). */ | |
45 | typedef unsigned long arc_insn; | |
46 | ||
47 | struct arc_opcode { | |
48 | char *syntax; /* syntax of insn */ | |
49 | unsigned long mask, value; /* recognize instruction if (op&mask)==value */ | |
50 | int flags; /* various flag bits */ | |
51 | ||
52 | /* Values for `flags'. */ | |
53 | ||
4ad003d1 DE |
54 | /* Return CPU number, given flag bits. */ |
55 | #define ARC_OPCODE_CPU(bits) ((bits) & ARC_MACH_CPU_MASK) | |
32a0dad5 DE |
56 | /* Return MACH number, given flag bits. */ |
57 | #define ARC_OPCODE_MACH(bits) ((bits) & ARC_MACH_MASK) | |
58 | }; | |
59 | ||
60 | struct arc_operand_value { | |
61 | char *name; /* eg: "eq" */ | |
62 | short value; /* eg: 1 */ | |
63 | unsigned char type; /* index into `arc_operands' */ | |
64 | unsigned char flags; /* various flag bits */ | |
65 | ||
66 | /* Values for `flags'. */ | |
67 | ||
4ad003d1 DE |
68 | /* Return CPU number, given flag bits. */ |
69 | #define ARC_OPVAL_CPU(bits) ((bits) & ARC_MACH_CPU_MASK) | |
32a0dad5 DE |
70 | /* Return MACH number, given flag bits. */ |
71 | #define ARC_OPVAL_MACH(bits) ((bits) & ARC_MACH_MASK) | |
72 | }; | |
73 | ||
74 | struct arc_operand { | |
75 | /* One of the insn format chars. */ | |
76 | unsigned char fmt; | |
77 | ||
78 | /* The number of bits in the operand (may be unused for a modifier). */ | |
79 | unsigned char bits; | |
80 | ||
81 | /* How far the operand is left shifted in the instruction, or | |
82 | the modifier's flag bit (may be unused for a modifier. */ | |
83 | unsigned char shift; | |
84 | ||
85 | /* Various flag bits. */ | |
86 | int flags; | |
87 | ||
88 | /* Values for `flags'. */ | |
89 | ||
90 | /* This operand is a suffix to the opcode. */ | |
91 | #define ARC_OPERAND_SUFFIX 1 | |
92 | ||
93 | /* This operand is a relative branch displacement. The disassembler | |
94 | prints these symbolically if possible. */ | |
4ad003d1 | 95 | #define ARC_OPERAND_RELATIVE_BRANCH 2 |
32a0dad5 DE |
96 | |
97 | /* This operand is an absolute branch address. The disassembler | |
98 | prints these symbolically if possible. */ | |
4ad003d1 DE |
99 | #define ARC_OPERAND_ABSOLUTE_BRANCH 4 |
100 | ||
101 | /* This operand is an address. The disassembler | |
102 | prints these symbolically if possible. */ | |
103 | #define ARC_OPERAND_ADDRESS 8 | |
104 | ||
105 | /* This operand is a long immediate value. */ | |
106 | #define ARC_OPERAND_LIMM 0x10 | |
32a0dad5 DE |
107 | |
108 | /* This operand takes signed values. */ | |
4ad003d1 | 109 | #define ARC_OPERAND_SIGNED 0x20 |
32a0dad5 DE |
110 | |
111 | /* This operand takes signed values, but also accepts a full positive | |
112 | range of values. That is, if bits is 16, it takes any value from | |
113 | -0x8000 to 0xffff. */ | |
4ad003d1 | 114 | #define ARC_OPERAND_SIGNOPT 0x40 |
32a0dad5 DE |
115 | |
116 | /* This operand should be regarded as a negative number for the | |
117 | purposes of overflow checking (i.e., the normal most negative | |
118 | number is disallowed and one more than the normal most positive | |
119 | number is allowed). This flag will only be set for a signed | |
120 | operand. */ | |
4ad003d1 | 121 | #define ARC_OPERAND_NEGATIVE 0x80 |
32a0dad5 DE |
122 | |
123 | /* This operand doesn't really exist. The program uses these operands | |
124 | in special ways. */ | |
4ad003d1 | 125 | #define ARC_OPERAND_FAKE 0x100 |
32a0dad5 DE |
126 | |
127 | /* Modifier values. */ | |
128 | /* A dot is required before a suffix. Eg: .le */ | |
129 | #define ARC_MOD_DOT 0x1000 | |
130 | ||
131 | /* A normal register is allowed (not used, but here for completeness). */ | |
132 | #define ARC_MOD_REG 0x2000 | |
133 | ||
134 | /* An auxiliary register name is expected. */ | |
135 | #define ARC_MOD_AUXREG 0x4000 | |
136 | ||
137 | /* Sum of all ARC_MOD_XXX bits. */ | |
138 | #define ARC_MOD_BITS 0x7000 | |
139 | ||
140 | /* Non-zero if the operand type is really a modifier. */ | |
141 | #define ARC_MOD_P(X) ((X) & ARC_MOD_BITS) | |
142 | ||
143 | /* Insertion function. This is used by the assembler. To insert an | |
144 | operand value into an instruction, check this field. | |
145 | ||
146 | If it is NULL, execute | |
147 | i |= (p & ((1 << o->bits) - 1)) << o->shift; | |
148 | (I is the instruction which we are filling in, O is a pointer to | |
149 | this structure, and OP is the opcode value; this assumes twos | |
150 | complement arithmetic). | |
151 | ||
152 | If this field is not NULL, then simply call it with the | |
153 | instruction and the operand value. It will return the new value | |
154 | of the instruction. If the ERRMSG argument is not NULL, then if | |
155 | the operand value is illegal, *ERRMSG will be set to a warning | |
156 | string (the operand will be inserted in any case). If the | |
157 | operand value is legal, *ERRMSG will be unchanged. | |
158 | ||
159 | REG is non-NULL when inserting a register value. */ | |
160 | ||
161 | arc_insn (*insert) PARAMS ((arc_insn insn, | |
162 | const struct arc_operand *operand, int mods, | |
163 | const struct arc_operand_value *reg, long value, | |
164 | const char **errmsg)); | |
165 | ||
166 | /* Extraction function. This is used by the disassembler. To | |
167 | extract this operand type from an instruction, check this field. | |
168 | ||
169 | If it is NULL, compute | |
170 | op = ((i) >> o->shift) & ((1 << o->bits) - 1); | |
171 | if ((o->flags & ARC_OPERAND_SIGNED) != 0 | |
172 | && (op & (1 << (o->bits - 1))) != 0) | |
173 | op -= 1 << o->bits; | |
174 | (I is the instruction, O is a pointer to this structure, and OP | |
175 | is the result; this assumes twos complement arithmetic). | |
176 | ||
177 | If this field is not NULL, then simply call it with the | |
178 | instruction value. It will return the value of the operand. If | |
179 | the INVALID argument is not NULL, *INVALID will be set to | |
180 | non-zero if this operand type can not actually be extracted from | |
181 | this operand (i.e., the instruction does not match). If the | |
182 | operand is valid, *INVALID will not be changed. | |
183 | ||
184 | INSN is a pointer to an array of two `arc_insn's. The first element is | |
185 | the insn, the second is the limm if present. | |
186 | ||
187 | Operands that have a printable form like registers and suffixes have | |
188 | their struct arc_operand_value pointer stored in OPVAL. */ | |
189 | ||
190 | long (*extract) PARAMS ((arc_insn *insn, | |
191 | const struct arc_operand *operand, | |
192 | int mods, const struct arc_operand_value **opval, | |
193 | int *invalid)); | |
194 | }; | |
195 | ||
196 | /* Bits that say what version of cpu we have. | |
197 | These should be passed to arc_init_opcode_tables. | |
198 | At present, all there is is the cpu type. */ | |
199 | ||
4ad003d1 DE |
200 | /* CPU number, given value passed to `arc_init_opcode_tables'. */ |
201 | #define ARC_HAVE_CPU(bits) ((bits) & ARC_MACH_CPU_MASK) | |
32a0dad5 DE |
202 | /* MACH number, given value passed to `arc_init_opcode_tables'. */ |
203 | #define ARC_HAVE_MACH(bits) ((bits) & ARC_MACH_MASK) | |
204 | ||
205 | /* Special register values: */ | |
206 | #define ARC_REG_SHIMM_UPDATE 61 | |
207 | #define ARC_REG_SHIMM 63 | |
208 | #define ARC_REG_LIMM 62 | |
209 | ||
210 | /* Non-zero if REG is a constant marker. */ | |
211 | #define ARC_REG_CONSTANT_P(REG) ((REG) >= 61) | |
212 | ||
213 | /* Positions and masks of various fields: */ | |
214 | #define ARC_SHIFT_REGA 21 | |
215 | #define ARC_SHIFT_REGB 15 | |
216 | #define ARC_SHIFT_REGC 9 | |
217 | #define ARC_MASK_REG 63 | |
218 | ||
219 | /* Non-zero if X will fit in a signed 9 bit field. */ | |
220 | #define ARC_SHIMM_CONST_P(x) ((long) (x) >= -256 && (long) (x) <= 255) | |
221 | ||
222 | extern const struct arc_operand arc_operands[]; | |
223 | extern const int arc_operand_count; | |
224 | extern const struct arc_opcode arc_opcodes[]; | |
225 | extern const int arc_opcodes_count; | |
226 | extern const struct arc_operand_value arc_suffixes[]; | |
227 | extern const int arc_suffixes_count; | |
228 | extern const struct arc_operand_value arc_reg_names[]; | |
229 | extern const int arc_reg_names_count; | |
230 | extern unsigned char arc_operand_map[]; | |
231 | ||
232 | /* Utility fns in arc-opc.c. */ | |
4ad003d1 | 233 | int arc_get_opcode_mach PARAMS ((int, int)); |
32a0dad5 DE |
234 | /* `arc_opcode_init_tables' must be called before `arc_xxx_supported'. */ |
235 | void arc_opcode_init_tables PARAMS ((int)); | |
236 | void arc_opcode_init_insert PARAMS ((void)); | |
237 | void arc_opcode_init_extract PARAMS ((void)); | |
238 | int arc_opcode_limm_p PARAMS ((long *)); | |
239 | const struct arc_operand_value *arc_opcode_lookup_suffix PARAMS ((const struct arc_operand *type, int value)); | |
240 | int arc_opcode_supported PARAMS ((const struct arc_opcode *)); | |
241 | int arc_opval_supported PARAMS ((const struct arc_operand_value *)); |