/src/binutils-gdb/bfd/cpu-ia64-opc.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 1998-2023 Free Software Foundation, Inc. |
2 | | Contributed by David Mosberger-Tang <davidm@hpl.hp.com> |
3 | | |
4 | | This file is part of BFD, the Binary File Descriptor library. |
5 | | |
6 | | This program is free software; you can redistribute it and/or modify |
7 | | it under the terms of the GNU General Public License as published by |
8 | | the Free Software Foundation; either version 3 of the License, or |
9 | | (at your option) any later version. |
10 | | |
11 | | This program is distributed in the hope that it will be useful, |
12 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | GNU General Public License for more details. |
15 | | |
16 | | You should have received a copy of the GNU General Public License |
17 | | along with this program; if not, write to the Free Software |
18 | | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
19 | | MA 02110-1301, USA. */ |
20 | | |
21 | | /* Logically, this code should be part of libopcode but since some of |
22 | | the operand insertion/extraction functions help bfd to implement |
23 | | relocations, this code is included as part of cpu-ia64.c. This |
24 | | avoids circular dependencies between libopcode and libbfd and also |
25 | | obviates the need for applications to link in libopcode when all |
26 | | they really want is libbfd. |
27 | | |
28 | | --davidm Mon Apr 13 22:14:02 1998 */ |
29 | | |
30 | | #include "../opcodes/ia64-opc.h" |
31 | | |
32 | 0 | #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0]))) |
33 | | |
34 | | static const char* |
35 | | ins_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED, |
36 | | ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED) |
37 | 0 | { |
38 | 0 | return "internal error---this shouldn't happen"; |
39 | 0 | } |
40 | | |
41 | | static const char* |
42 | | ext_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED, |
43 | | ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED) |
44 | 0 | { |
45 | 0 | return "internal error---this shouldn't happen"; |
46 | 0 | } |
47 | | |
48 | | static const char* |
49 | | ins_const (const struct ia64_operand *self ATTRIBUTE_UNUSED, |
50 | | ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED) |
51 | 0 | { |
52 | 0 | return 0; |
53 | 0 | } |
54 | | |
55 | | static const char* |
56 | | ext_const (const struct ia64_operand *self ATTRIBUTE_UNUSED, |
57 | | ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED) |
58 | 0 | { |
59 | 0 | return 0; |
60 | 0 | } |
61 | | |
62 | | static const char* |
63 | | ins_reg (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) |
64 | 0 | { |
65 | 0 | if (value >= 1u << self->field[0].bits) |
66 | 0 | return "register number out of range"; |
67 | | |
68 | 0 | *code |= value << self->field[0].shift; |
69 | 0 | return 0; |
70 | 0 | } |
71 | | |
72 | | static const char* |
73 | | ext_reg (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) |
74 | 0 | { |
75 | 0 | *valuep = ((code >> self->field[0].shift) |
76 | 0 | & ((1u << self->field[0].bits) - 1)); |
77 | 0 | return 0; |
78 | 0 | } |
79 | | |
80 | | static const char* |
81 | | ins_immu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) |
82 | 0 | { |
83 | 0 | ia64_insn new_insn = 0; |
84 | 0 | int i; |
85 | |
|
86 | 0 | for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) |
87 | 0 | { |
88 | 0 | new_insn |= ((value & ((((ia64_insn) 1) << self->field[i].bits) - 1)) |
89 | 0 | << self->field[i].shift); |
90 | 0 | value >>= self->field[i].bits; |
91 | 0 | } |
92 | 0 | if (value) |
93 | 0 | return "integer operand out of range"; |
94 | | |
95 | 0 | *code |= new_insn; |
96 | 0 | return 0; |
97 | 0 | } |
98 | | |
99 | | static const char* |
100 | | ext_immu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) |
101 | 0 | { |
102 | 0 | uint64_t value = 0; |
103 | 0 | int i, bits = 0, total = 0; |
104 | |
|
105 | 0 | for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) |
106 | 0 | { |
107 | 0 | bits = self->field[i].bits; |
108 | 0 | value |= ((code >> self->field[i].shift) |
109 | 0 | & (((uint64_t) 1 << bits) - 1)) << total; |
110 | 0 | total += bits; |
111 | 0 | } |
112 | 0 | *valuep = value; |
113 | 0 | return 0; |
114 | 0 | } |
115 | | |
116 | | static const char* |
117 | | ins_immu5b (const struct ia64_operand *self, ia64_insn value, |
118 | | ia64_insn *code) |
119 | 0 | { |
120 | 0 | if (value < 32 || value > 63) |
121 | 0 | return "value must be between 32 and 63"; |
122 | 0 | return ins_immu (self, value - 32, code); |
123 | 0 | } |
124 | | |
125 | | static const char* |
126 | | ext_immu5b (const struct ia64_operand *self, ia64_insn code, |
127 | | ia64_insn *valuep) |
128 | 0 | { |
129 | 0 | const char *result; |
130 | |
|
131 | 0 | result = ext_immu (self, code, valuep); |
132 | 0 | if (result) |
133 | 0 | return result; |
134 | | |
135 | 0 | *valuep = *valuep + 32; |
136 | 0 | return 0; |
137 | 0 | } |
138 | | |
139 | | static const char* |
140 | | ins_immus8 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) |
141 | 0 | { |
142 | 0 | if (value & 0x7) |
143 | 0 | return "value not an integer multiple of 8"; |
144 | 0 | return ins_immu (self, value >> 3, code); |
145 | 0 | } |
146 | | |
147 | | static const char* |
148 | | ext_immus8 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) |
149 | 0 | { |
150 | 0 | const char *result; |
151 | |
|
152 | 0 | result = ext_immu (self, code, valuep); |
153 | 0 | if (result) |
154 | 0 | return result; |
155 | | |
156 | 0 | *valuep = *valuep << 3; |
157 | 0 | return 0; |
158 | 0 | } |
159 | | |
160 | | static const char* |
161 | | ins_imms_scaled (const struct ia64_operand *self, ia64_insn value, |
162 | | ia64_insn *code, int scale) |
163 | 0 | { |
164 | 0 | int64_t svalue = value, sign_bit = 0; |
165 | 0 | ia64_insn new_insn = 0; |
166 | 0 | int i; |
167 | |
|
168 | 0 | svalue >>= scale; |
169 | |
|
170 | 0 | for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) |
171 | 0 | { |
172 | 0 | new_insn |= ((svalue & ((((ia64_insn) 1) << self->field[i].bits) - 1)) |
173 | 0 | << self->field[i].shift); |
174 | 0 | sign_bit = (svalue >> (self->field[i].bits - 1)) & 1; |
175 | 0 | svalue >>= self->field[i].bits; |
176 | 0 | } |
177 | 0 | if ((!sign_bit && svalue != 0) || (sign_bit && svalue != -1)) |
178 | 0 | return "integer operand out of range"; |
179 | | |
180 | 0 | *code |= new_insn; |
181 | 0 | return 0; |
182 | 0 | } |
183 | | |
184 | | static const char* |
185 | | ext_imms_scaled (const struct ia64_operand *self, ia64_insn code, |
186 | | ia64_insn *valuep, int scale) |
187 | 0 | { |
188 | 0 | int i, bits = 0, total = 0; |
189 | 0 | uint64_t val = 0, sign; |
190 | |
|
191 | 0 | for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i) |
192 | 0 | { |
193 | 0 | bits = self->field[i].bits; |
194 | 0 | val |= ((code >> self->field[i].shift) |
195 | 0 | & (((uint64_t) 1 << bits) - 1)) << total; |
196 | 0 | total += bits; |
197 | 0 | } |
198 | | /* sign extend: */ |
199 | 0 | sign = (uint64_t) 1 << (total - 1); |
200 | 0 | val = (val ^ sign) - sign; |
201 | |
|
202 | 0 | *valuep = val << scale; |
203 | 0 | return 0; |
204 | 0 | } |
205 | | |
206 | | static const char* |
207 | | ins_imms (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) |
208 | 0 | { |
209 | 0 | return ins_imms_scaled (self, value, code, 0); |
210 | 0 | } |
211 | | |
212 | | static const char* |
213 | | ins_immsu4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) |
214 | 0 | { |
215 | 0 | value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000; |
216 | |
|
217 | 0 | return ins_imms_scaled (self, value, code, 0); |
218 | 0 | } |
219 | | |
220 | | static const char* |
221 | | ext_imms (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) |
222 | 0 | { |
223 | 0 | return ext_imms_scaled (self, code, valuep, 0); |
224 | 0 | } |
225 | | |
226 | | static const char* |
227 | | ins_immsm1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) |
228 | 0 | { |
229 | 0 | --value; |
230 | 0 | return ins_imms_scaled (self, value, code, 0); |
231 | 0 | } |
232 | | |
233 | | static const char* |
234 | | ins_immsm1u4 (const struct ia64_operand *self, ia64_insn value, |
235 | | ia64_insn *code) |
236 | 0 | { |
237 | 0 | value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000; |
238 | |
|
239 | 0 | --value; |
240 | 0 | return ins_imms_scaled (self, value, code, 0); |
241 | 0 | } |
242 | | |
243 | | static const char* |
244 | | ext_immsm1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) |
245 | 0 | { |
246 | 0 | const char *res = ext_imms_scaled (self, code, valuep, 0); |
247 | |
|
248 | 0 | ++*valuep; |
249 | 0 | return res; |
250 | 0 | } |
251 | | |
252 | | static const char* |
253 | | ins_imms1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) |
254 | 0 | { |
255 | 0 | return ins_imms_scaled (self, value, code, 1); |
256 | 0 | } |
257 | | |
258 | | static const char* |
259 | | ext_imms1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) |
260 | 0 | { |
261 | 0 | return ext_imms_scaled (self, code, valuep, 1); |
262 | 0 | } |
263 | | |
264 | | static const char* |
265 | | ins_imms4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) |
266 | 0 | { |
267 | 0 | return ins_imms_scaled (self, value, code, 4); |
268 | 0 | } |
269 | | |
270 | | static const char* |
271 | | ext_imms4 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) |
272 | 0 | { |
273 | 0 | return ext_imms_scaled (self, code, valuep, 4); |
274 | 0 | } |
275 | | |
276 | | static const char* |
277 | | ins_imms16 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) |
278 | 0 | { |
279 | 0 | return ins_imms_scaled (self, value, code, 16); |
280 | 0 | } |
281 | | |
282 | | static const char* |
283 | | ext_imms16 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) |
284 | 0 | { |
285 | 0 | return ext_imms_scaled (self, code, valuep, 16); |
286 | 0 | } |
287 | | |
288 | | static const char* |
289 | | ins_cimmu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) |
290 | 0 | { |
291 | 0 | ia64_insn mask = (((ia64_insn) 1) << self->field[0].bits) - 1; |
292 | 0 | return ins_immu (self, value ^ mask, code); |
293 | 0 | } |
294 | | |
295 | | static const char* |
296 | | ext_cimmu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) |
297 | 0 | { |
298 | 0 | const char *result; |
299 | 0 | ia64_insn mask; |
300 | |
|
301 | 0 | mask = (((ia64_insn) 1) << self->field[0].bits) - 1; |
302 | 0 | result = ext_immu (self, code, valuep); |
303 | 0 | if (!result) |
304 | 0 | { |
305 | 0 | mask = (((ia64_insn) 1) << self->field[0].bits) - 1; |
306 | 0 | *valuep ^= mask; |
307 | 0 | } |
308 | 0 | return result; |
309 | 0 | } |
310 | | |
311 | | static const char* |
312 | | ins_cnt (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) |
313 | 0 | { |
314 | 0 | --value; |
315 | 0 | if (value >= (uint64_t) 1 << self->field[0].bits) |
316 | 0 | return "count out of range"; |
317 | | |
318 | 0 | *code |= value << self->field[0].shift; |
319 | 0 | return 0; |
320 | 0 | } |
321 | | |
322 | | static const char* |
323 | | ext_cnt (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) |
324 | 0 | { |
325 | 0 | *valuep = ((code >> self->field[0].shift) |
326 | 0 | & (((uint64_t) 1 << self->field[0].bits) - 1)) + 1; |
327 | 0 | return 0; |
328 | 0 | } |
329 | | |
330 | | static const char* |
331 | | ins_cnt2b (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) |
332 | 0 | { |
333 | 0 | --value; |
334 | |
|
335 | 0 | if (value > 2) |
336 | 0 | return "count must be in range 1..3"; |
337 | | |
338 | 0 | *code |= value << self->field[0].shift; |
339 | 0 | return 0; |
340 | 0 | } |
341 | | |
342 | | static const char* |
343 | | ext_cnt2b (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) |
344 | 0 | { |
345 | 0 | *valuep = ((code >> self->field[0].shift) & 0x3) + 1; |
346 | 0 | return 0; |
347 | 0 | } |
348 | | |
349 | | static const char* |
350 | | ins_cnt2c (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) |
351 | 0 | { |
352 | 0 | switch (value) |
353 | 0 | { |
354 | 0 | case 0: value = 0; break; |
355 | 0 | case 7: value = 1; break; |
356 | 0 | case 15: value = 2; break; |
357 | 0 | case 16: value = 3; break; |
358 | 0 | default: return "count must be 0, 7, 15, or 16"; |
359 | 0 | } |
360 | 0 | *code |= value << self->field[0].shift; |
361 | 0 | return 0; |
362 | 0 | } |
363 | | |
364 | | static const char* |
365 | | ext_cnt2c (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) |
366 | 0 | { |
367 | 0 | ia64_insn value; |
368 | |
|
369 | 0 | value = (code >> self->field[0].shift) & 0x3; |
370 | 0 | switch (value) |
371 | 0 | { |
372 | 0 | case 0: value = 0; break; |
373 | 0 | case 1: value = 7; break; |
374 | 0 | case 2: value = 15; break; |
375 | 0 | case 3: value = 16; break; |
376 | 0 | } |
377 | 0 | *valuep = value; |
378 | 0 | return 0; |
379 | 0 | } |
380 | | |
381 | | static const char* |
382 | | ins_cnt6a (const struct ia64_operand *self, ia64_insn value, |
383 | | ia64_insn *code) |
384 | 0 | { |
385 | 0 | if (value < 1 || value > 64) |
386 | 0 | return "value must be between 1 and 64"; |
387 | 0 | return ins_immu (self, value - 1, code); |
388 | 0 | } |
389 | | |
390 | | static const char* |
391 | | ext_cnt6a (const struct ia64_operand *self, ia64_insn code, |
392 | | ia64_insn *valuep) |
393 | 0 | { |
394 | 0 | const char *result; |
395 | |
|
396 | 0 | result = ext_immu (self, code, valuep); |
397 | 0 | if (result) |
398 | 0 | return result; |
399 | | |
400 | 0 | *valuep = *valuep + 1; |
401 | 0 | return 0; |
402 | 0 | } |
403 | | |
404 | | static const char* |
405 | | ins_strd5b (const struct ia64_operand *self, ia64_insn value, |
406 | | ia64_insn *code) |
407 | 0 | { |
408 | 0 | if ( value & 0x3f ) |
409 | 0 | return "value must be a multiple of 64"; |
410 | 0 | return ins_imms_scaled (self, value, code, 6); |
411 | 0 | } |
412 | | |
413 | | static const char* |
414 | | ext_strd5b (const struct ia64_operand *self, ia64_insn code, |
415 | | ia64_insn *valuep) |
416 | 0 | { |
417 | 0 | return ext_imms_scaled (self, code, valuep, 6); |
418 | 0 | } |
419 | | |
420 | | |
421 | | static const char* |
422 | | ins_inc3 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code) |
423 | 0 | { |
424 | 0 | int64_t val = value; |
425 | 0 | uint64_t sign = 0; |
426 | |
|
427 | 0 | if (val < 0) |
428 | 0 | { |
429 | 0 | sign = 0x4; |
430 | 0 | value = -value; |
431 | 0 | } |
432 | 0 | switch (value) |
433 | 0 | { |
434 | 0 | case 1: value = 3; break; |
435 | 0 | case 4: value = 2; break; |
436 | 0 | case 8: value = 1; break; |
437 | 0 | case 16: value = 0; break; |
438 | 0 | default: return "count must be +/- 1, 4, 8, or 16"; |
439 | 0 | } |
440 | 0 | *code |= (sign | value) << self->field[0].shift; |
441 | 0 | return 0; |
442 | 0 | } |
443 | | |
444 | | static const char* |
445 | | ext_inc3 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep) |
446 | 0 | { |
447 | 0 | int64_t val; |
448 | 0 | int negate; |
449 | |
|
450 | 0 | val = (code >> self->field[0].shift) & 0x7; |
451 | 0 | negate = val & 0x4; |
452 | 0 | switch (val & 0x3) |
453 | 0 | { |
454 | 0 | case 0: val = 16; break; |
455 | 0 | case 1: val = 8; break; |
456 | 0 | case 2: val = 4; break; |
457 | 0 | case 3: val = 1; break; |
458 | 0 | } |
459 | 0 | if (negate) |
460 | 0 | val = -val; |
461 | |
|
462 | 0 | *valuep = val; |
463 | 0 | return 0; |
464 | 0 | } |
465 | | |
466 | | #define CST IA64_OPND_CLASS_CST |
467 | | #define REG IA64_OPND_CLASS_REG |
468 | | #define IND IA64_OPND_CLASS_IND |
469 | | #define ABS IA64_OPND_CLASS_ABS |
470 | | #define REL IA64_OPND_CLASS_REL |
471 | | |
472 | | #define SDEC IA64_OPND_FLAG_DECIMAL_SIGNED |
473 | | #define UDEC IA64_OPND_FLAG_DECIMAL_UNSIGNED |
474 | | |
475 | | const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] = |
476 | | { |
477 | | /* constants: */ |
478 | | { CST, ins_const, ext_const, "NIL", {{ 0, 0}}, 0, "<none>" }, |
479 | | { CST, ins_const, ext_const, "ar.csd", {{ 0, 0}}, 0, "ar.csd" }, |
480 | | { CST, ins_const, ext_const, "ar.ccv", {{ 0, 0}}, 0, "ar.ccv" }, |
481 | | { CST, ins_const, ext_const, "ar.pfs", {{ 0, 0}}, 0, "ar.pfs" }, |
482 | | { CST, ins_const, ext_const, "1", {{ 0, 0}}, 0, "1" }, |
483 | | { CST, ins_const, ext_const, "8", {{ 0, 0}}, 0, "8" }, |
484 | | { CST, ins_const, ext_const, "16", {{ 0, 0}}, 0, "16" }, |
485 | | { CST, ins_const, ext_const, "r0", {{ 0, 0}}, 0, "r0" }, |
486 | | { CST, ins_const, ext_const, "ip", {{ 0, 0}}, 0, "ip" }, |
487 | | { CST, ins_const, ext_const, "pr", {{ 0, 0}}, 0, "pr" }, |
488 | | { CST, ins_const, ext_const, "pr.rot", {{ 0, 0}}, 0, "pr.rot" }, |
489 | | { CST, ins_const, ext_const, "psr", {{ 0, 0}}, 0, "psr" }, |
490 | | { CST, ins_const, ext_const, "psr.l", {{ 0, 0}}, 0, "psr.l" }, |
491 | | { CST, ins_const, ext_const, "psr.um", {{ 0, 0}}, 0, "psr.um" }, |
492 | | |
493 | | /* register operands: */ |
494 | | { REG, ins_reg, ext_reg, "ar", {{ 7, 20}}, 0, /* AR3 */ |
495 | | "an application register" }, |
496 | | { REG, ins_reg, ext_reg, "b", {{ 3, 6}}, 0, /* B1 */ |
497 | | "a branch register" }, |
498 | | { REG, ins_reg, ext_reg, "b", {{ 3, 13}}, 0, /* B2 */ |
499 | | "a branch register"}, |
500 | | { REG, ins_reg, ext_reg, "cr", {{ 7, 20}}, 0, /* CR */ |
501 | | "a control register"}, |
502 | | { REG, ins_reg, ext_reg, "f", {{ 7, 6}}, 0, /* F1 */ |
503 | | "a floating-point register" }, |
504 | | { REG, ins_reg, ext_reg, "f", {{ 7, 13}}, 0, /* F2 */ |
505 | | "a floating-point register" }, |
506 | | { REG, ins_reg, ext_reg, "f", {{ 7, 20}}, 0, /* F3 */ |
507 | | "a floating-point register" }, |
508 | | { REG, ins_reg, ext_reg, "f", {{ 7, 27}}, 0, /* F4 */ |
509 | | "a floating-point register" }, |
510 | | { REG, ins_reg, ext_reg, "p", {{ 6, 6}}, 0, /* P1 */ |
511 | | "a predicate register" }, |
512 | | { REG, ins_reg, ext_reg, "p", {{ 6, 27}}, 0, /* P2 */ |
513 | | "a predicate register" }, |
514 | | { REG, ins_reg, ext_reg, "r", {{ 7, 6}}, 0, /* R1 */ |
515 | | "a general register" }, |
516 | | { REG, ins_reg, ext_reg, "r", {{ 7, 13}}, 0, /* R2 */ |
517 | | "a general register" }, |
518 | | { REG, ins_reg, ext_reg, "r", {{ 7, 20}}, 0, /* R3 */ |
519 | | "a general register" }, |
520 | | { REG, ins_reg, ext_reg, "r", {{ 2, 20}}, 0, /* R3_2 */ |
521 | | "a general register r0-r3" }, |
522 | | { REG, ins_reg, ext_reg, "dahr", {{ 3, 23}}, 0, /* DAHR */ |
523 | | "a dahr register dahr0-7" }, |
524 | | |
525 | | /* memory operands: */ |
526 | | { IND, ins_reg, ext_reg, "", {{7, 20}}, 0, /* MR3 */ |
527 | | "a memory address" }, |
528 | | |
529 | | /* indirect operands: */ |
530 | | { IND, ins_reg, ext_reg, "cpuid", {{7, 20}}, 0, /* CPUID_R3 */ |
531 | | "a cpuid register" }, |
532 | | { IND, ins_reg, ext_reg, "dbr", {{7, 20}}, 0, /* DBR_R3 */ |
533 | | "a dbr register" }, |
534 | | { IND, ins_reg, ext_reg, "dtr", {{7, 20}}, 0, /* DTR_R3 */ |
535 | | "a dtr register" }, |
536 | | { IND, ins_reg, ext_reg, "itr", {{7, 20}}, 0, /* ITR_R3 */ |
537 | | "an itr register" }, |
538 | | { IND, ins_reg, ext_reg, "ibr", {{7, 20}}, 0, /* IBR_R3 */ |
539 | | "an ibr register" }, |
540 | | { IND, ins_reg, ext_reg, "msr", {{7, 20}}, 0, /* MSR_R3 */ |
541 | | "an msr register" }, |
542 | | { IND, ins_reg, ext_reg, "pkr", {{7, 20}}, 0, /* PKR_R3 */ |
543 | | "a pkr register" }, |
544 | | { IND, ins_reg, ext_reg, "pmc", {{7, 20}}, 0, /* PMC_R3 */ |
545 | | "a pmc register" }, |
546 | | { IND, ins_reg, ext_reg, "pmd", {{7, 20}}, 0, /* PMD_R3 */ |
547 | | "a pmd register" }, |
548 | | { IND, ins_reg, ext_reg, "dahr", {{7, 20}}, 0, /* DAHR_R3 */ |
549 | | "a dahr register" }, |
550 | | { IND, ins_reg, ext_reg, "rr", {{7, 20}}, 0, /* RR_R3 */ |
551 | | "an rr register" }, |
552 | | |
553 | | /* immediate operands: */ |
554 | | { ABS, ins_cimmu, ext_cimmu, 0, {{ 5, 20 }}, UDEC, /* CCNT5 */ |
555 | | "a 5-bit count (0-31)" }, |
556 | | { ABS, ins_cnt, ext_cnt, 0, {{ 2, 27 }}, UDEC, /* CNT2a */ |
557 | | "a 2-bit count (1-4)" }, |
558 | | { ABS, ins_cnt2b, ext_cnt2b, 0, {{ 2, 27 }}, UDEC, /* CNT2b */ |
559 | | "a 2-bit count (1-3)" }, |
560 | | { ABS, ins_cnt2c, ext_cnt2c, 0, {{ 2, 30 }}, UDEC, /* CNT2c */ |
561 | | "a count (0, 7, 15, or 16)" }, |
562 | | { ABS, ins_immu, ext_immu, 0, {{ 5, 14}}, UDEC, /* CNT5 */ |
563 | | "a 5-bit count (0-31)" }, |
564 | | { ABS, ins_immu, ext_immu, 0, {{ 6, 27}}, UDEC, /* CNT6 */ |
565 | | "a 6-bit count (0-63)" }, |
566 | | { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 20}}, UDEC, /* CPOS6a */ |
567 | | "a 6-bit bit pos (0-63)" }, |
568 | | { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 14}}, UDEC, /* CPOS6b */ |
569 | | "a 6-bit bit pos (0-63)" }, |
570 | | { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 31}}, UDEC, /* CPOS6c */ |
571 | | "a 6-bit bit pos (0-63)" }, |
572 | | { ABS, ins_imms, ext_imms, 0, {{ 1, 36}}, SDEC, /* IMM1 */ |
573 | | "a 1-bit integer (-1, 0)" }, |
574 | | { ABS, ins_immu, ext_immu, 0, {{ 2, 13}}, UDEC, /* IMMU2 */ |
575 | | "a 2-bit unsigned (0-3)" }, |
576 | | { ABS, ins_immu5b, ext_immu5b, 0, {{ 5, 14}}, UDEC, /* IMMU5b */ |
577 | | "a 5-bit unsigned (32 + (0-31))" }, |
578 | | { ABS, ins_immu, ext_immu, 0, {{ 7, 13}}, 0, /* IMMU7a */ |
579 | | "a 7-bit unsigned (0-127)" }, |
580 | | { ABS, ins_immu, ext_immu, 0, {{ 7, 20}}, 0, /* IMMU7b */ |
581 | | "a 7-bit unsigned (0-127)" }, |
582 | | { ABS, ins_immu, ext_immu, 0, {{ 7, 13}}, UDEC, /* SOF */ |
583 | | "a frame size (register count)" }, |
584 | | { ABS, ins_immu, ext_immu, 0, {{ 7, 20}}, UDEC, /* SOL */ |
585 | | "a local register count" }, |
586 | | { ABS, ins_immus8,ext_immus8,0, {{ 4, 27}}, UDEC, /* SOR */ |
587 | | "a rotating register count (integer multiple of 8)" }, |
588 | | { ABS, ins_imms, ext_imms, 0, /* IMM8 */ |
589 | | {{ 7, 13}, { 1, 36}}, SDEC, |
590 | | "an 8-bit integer (-128-127)" }, |
591 | | { ABS, ins_immsu4, ext_imms, 0, /* IMM8U4 */ |
592 | | {{ 7, 13}, { 1, 36}}, SDEC, |
593 | | "an 8-bit signed integer for 32-bit unsigned compare (-128-127)" }, |
594 | | { ABS, ins_immsm1, ext_immsm1, 0, /* IMM8M1 */ |
595 | | {{ 7, 13}, { 1, 36}}, SDEC, |
596 | | "an 8-bit integer (-127-128)" }, |
597 | | { ABS, ins_immsm1u4, ext_immsm1, 0, /* IMM8M1U4 */ |
598 | | {{ 7, 13}, { 1, 36}}, SDEC, |
599 | | "an 8-bit integer for 32-bit unsigned compare (-127-(-1),1-128,0x100000000)" }, |
600 | | { ABS, ins_immsm1, ext_immsm1, 0, /* IMM8M1U8 */ |
601 | | {{ 7, 13}, { 1, 36}}, SDEC, |
602 | | "an 8-bit integer for 64-bit unsigned compare (-127-(-1),1-128,0x10000000000000000)" }, |
603 | | { ABS, ins_immu, ext_immu, 0, {{ 2, 33}, { 7, 20}}, 0, /* IMMU9 */ |
604 | | "a 9-bit unsigned (0-511)" }, |
605 | | { ABS, ins_imms, ext_imms, 0, /* IMM9a */ |
606 | | {{ 7, 6}, { 1, 27}, { 1, 36}}, SDEC, |
607 | | "a 9-bit integer (-256-255)" }, |
608 | | { ABS, ins_imms, ext_imms, 0, /* IMM9b */ |
609 | | {{ 7, 13}, { 1, 27}, { 1, 36}}, SDEC, |
610 | | "a 9-bit integer (-256-255)" }, |
611 | | { ABS, ins_imms, ext_imms, 0, /* IMM14 */ |
612 | | {{ 7, 13}, { 6, 27}, { 1, 36}}, SDEC, |
613 | | "a 14-bit integer (-8192-8191)" }, |
614 | | { ABS, ins_immu, ext_immu, 0, /* IMMU16 */ |
615 | | {{4, 6}, {11, 12}, { 1, 36}}, UDEC, |
616 | | "a 16-bit unsigned" }, |
617 | | { ABS, ins_imms1, ext_imms1, 0, /* IMM17 */ |
618 | | {{ 7, 6}, { 8, 24}, { 1, 36}}, 0, |
619 | | "a 17-bit integer (-65536-65535)" }, |
620 | | { ABS, ins_immu, ext_immu, 0, /* IMMU19 */ |
621 | | {{4, 6}, {14, 12}, { 1, 36}}, UDEC, |
622 | | "a 19-bit unsigned" }, |
623 | | { ABS, ins_immu, ext_immu, 0, {{20, 6}, { 1, 36}}, 0, /* IMMU21 */ |
624 | | "a 21-bit unsigned" }, |
625 | | { ABS, ins_imms, ext_imms, 0, /* IMM22 */ |
626 | | {{ 7, 13}, { 9, 27}, { 5, 22}, { 1, 36}}, SDEC, |
627 | | "a 22-bit signed integer" }, |
628 | | { ABS, ins_immu, ext_immu, 0, /* IMMU24 */ |
629 | | {{21, 6}, { 2, 31}, { 1, 36}}, 0, |
630 | | "a 24-bit unsigned" }, |
631 | | { ABS, ins_imms16,ext_imms16,0, {{27, 6}, { 1, 36}}, 0, /* IMM44 */ |
632 | | "a 44-bit unsigned (least 16 bits ignored/zeroes)" }, |
633 | | { ABS, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* IMMU62 */ |
634 | | "a 62-bit unsigned" }, |
635 | | { ABS, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* IMMU64 */ |
636 | | "a 64-bit unsigned" }, |
637 | | { ABS, ins_inc3, ext_inc3, 0, {{ 3, 13}}, SDEC, /* INC3 */ |
638 | | "an increment (+/- 1, 4, 8, or 16)" }, |
639 | | { ABS, ins_cnt, ext_cnt, 0, {{ 4, 27}}, UDEC, /* LEN4 */ |
640 | | "a 4-bit length (1-16)" }, |
641 | | { ABS, ins_cnt, ext_cnt, 0, {{ 6, 27}}, UDEC, /* LEN6 */ |
642 | | "a 6-bit length (1-64)" }, |
643 | | { ABS, ins_immu, ext_immu, 0, {{ 4, 20}}, 0, /* MBTYPE4 */ |
644 | | "a mix type (@rev, @mix, @shuf, @alt, or @brcst)" }, |
645 | | { ABS, ins_immu, ext_immu, 0, {{ 8, 20}}, 0, /* MBTYPE8 */ |
646 | | "an 8-bit mix type" }, |
647 | | { ABS, ins_immu, ext_immu, 0, {{ 6, 14}}, UDEC, /* POS6 */ |
648 | | "a 6-bit bit pos (0-63)" }, |
649 | | { REL, ins_imms4, ext_imms4, 0, {{ 7, 6}, { 2, 33}}, 0, /* TAG13 */ |
650 | | "a branch tag" }, |
651 | | { REL, ins_imms4, ext_imms4, 0, {{ 9, 24}}, 0, /* TAG13b */ |
652 | | "a branch tag" }, |
653 | | { REL, ins_imms4, ext_imms4, 0, {{20, 6}, { 1, 36}}, 0, /* TGT25 */ |
654 | | "a branch target" }, |
655 | | { REL, ins_imms4, ext_imms4, 0, /* TGT25b */ |
656 | | {{ 7, 6}, {13, 20}, { 1, 36}}, 0, |
657 | | "a branch target" }, |
658 | | { REL, ins_imms4, ext_imms4, 0, {{20, 13}, { 1, 36}}, 0, /* TGT25c */ |
659 | | "a branch target" }, |
660 | | { REL, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0, /* TGT64 */ |
661 | | "a branch target" }, |
662 | | |
663 | | { ABS, ins_const, ext_const, 0, {{0, 0}}, 0, /* LDXMOV */ |
664 | | "ldxmov target" }, |
665 | | { ABS, ins_cnt6a, ext_cnt6a, 0, {{6, 6}}, UDEC, /* CNT6a */ |
666 | | "lfetch count" }, |
667 | | { ABS, ins_strd5b, ext_strd5b, 0, {{5, 13}}, SDEC, /* STRD5b*/ |
668 | | "lfetch stride" }, |
669 | | }; |