cpu-ia64-opc.c revision 130561
1603Smalenkov/* Copyright 1998, 1999, 2000, 2001, 2002, 2003
29330Slana   Free Software Foundation, Inc.
3603Smalenkov   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4603Smalenkov
5603SmalenkovThis file is part of BFD, the Binary File Descriptor library.
6603Smalenkov
7603SmalenkovThis program is free software; you can redistribute it and/or modify
8603Smalenkovit under the terms of the GNU General Public License as published by
9603Smalenkovthe Free Software Foundation; either version 2 of the License, or
10603Smalenkov(at your option) any later version.
11603Smalenkov
12603SmalenkovThis program is distributed in the hope that it will be useful,
13603Smalenkovbut WITHOUT ANY WARRANTY; without even the implied warranty of
14603SmalenkovMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15603SmalenkovGNU General Public License for more details.
16603Smalenkov
17603SmalenkovYou should have received a copy of the GNU General Public License
18603Smalenkovalong with this program; if not, write to the Free Software
192362SohairFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
202362Sohair
212362Sohair/* Logically, this code should be part of libopcode but since some of
22603Smalenkov   the operand insertion/extraction functions help bfd to implement
23603Smalenkov   relocations, this code is included as part of cpu-ia64.c.  This
24603Smalenkov   avoids circular dependencies between libopcode and libbfd and also
25603Smalenkov   obviates the need for applications to link in libopcode when all
26603Smalenkov   they really want is libbfd.
27603Smalenkov
28603Smalenkov   --davidm Mon Apr 13 22:14:02 1998 */
29603Smalenkov
30603Smalenkov#include "../opcodes/ia64-opc.h"
31603Smalenkov
32603Smalenkov#define NELEMS(a)  ((int) (sizeof (a) / sizeof ((a)[0])))
33603Smalenkov
34603Smalenkovstatic const char*
35603Smalenkovins_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED,
36603Smalenkov	  ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED)
37603Smalenkov{
38603Smalenkov  return "internal error---this shouldn't happen";
39603Smalenkov}
40603Smalenkov
41603Smalenkovstatic const char*
42603Smalenkovext_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED,
43603Smalenkov	  ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED)
44603Smalenkov{
45603Smalenkov  return "internal error---this shouldn't happen";
46603Smalenkov}
47603Smalenkov
48603Smalenkovstatic const char*
49603Smalenkovins_const (const struct ia64_operand *self ATTRIBUTE_UNUSED,
50603Smalenkov	   ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED)
51603Smalenkov{
52603Smalenkov  return 0;
53603Smalenkov}
54603Smalenkov
55603Smalenkovstatic const char*
56603Smalenkovext_const (const struct ia64_operand *self ATTRIBUTE_UNUSED,
57603Smalenkov	   ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED)
58603Smalenkov{
59603Smalenkov  return 0;
60603Smalenkov}
61603Smalenkov
62603Smalenkovstatic const char*
63603Smalenkovins_reg (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
64603Smalenkov{
65603Smalenkov  if (value >= 1u << self->field[0].bits)
66603Smalenkov    return "register number out of range";
67603Smalenkov
68603Smalenkov  *code |= value << self->field[0].shift;
69603Smalenkov  return 0;
70603Smalenkov}
71603Smalenkov
726996Smalenkovstatic const char*
736996Smalenkovext_reg (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
74603Smalenkov{
75603Smalenkov  *valuep = ((code >> self->field[0].shift)
76603Smalenkov	     & ((1u << self->field[0].bits) - 1));
77603Smalenkov  return 0;
78603Smalenkov}
79603Smalenkov
80603Smalenkovstatic const char*
81ins_immu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
82{
83  ia64_insn new = 0;
84  int i;
85
86  for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
87    {
88      new |= ((value & ((((ia64_insn) 1) << self->field[i].bits) - 1))
89	      << self->field[i].shift);
90      value >>= self->field[i].bits;
91    }
92  if (value)
93    return "integer operand out of range";
94
95  *code |= new;
96  return 0;
97}
98
99static const char*
100ext_immu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
101{
102  BFD_HOST_U_64_BIT value = 0;
103  int i, bits = 0, total = 0;
104
105  for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
106    {
107      bits = self->field[i].bits;
108      value |= ((code >> self->field[i].shift)
109		& ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total;
110      total += bits;
111    }
112  *valuep = value;
113  return 0;
114}
115
116static const char*
117ins_immus8 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
118{
119  if (value & 0x7)
120    return "value not an integer multiple of 8";
121  return ins_immu (self, value >> 3, code);
122}
123
124static const char*
125ext_immus8 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
126{
127  const char *result;
128
129  result = ext_immu (self, code, valuep);
130  if (result)
131    return result;
132
133  *valuep = *valuep << 3;
134  return 0;
135}
136
137static const char*
138ins_imms_scaled (const struct ia64_operand *self, ia64_insn value,
139		 ia64_insn *code, int scale)
140{
141  BFD_HOST_64_BIT svalue = value, sign_bit = 0;
142  ia64_insn new = 0;
143  int i;
144
145  svalue >>= scale;
146
147  for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
148    {
149      new |= ((svalue & ((((ia64_insn) 1) << self->field[i].bits) - 1))
150	      << self->field[i].shift);
151      sign_bit = (svalue >> (self->field[i].bits - 1)) & 1;
152      svalue >>= self->field[i].bits;
153    }
154  if ((!sign_bit && svalue != 0) || (sign_bit && svalue != -1))
155    return "integer operand out of range";
156
157  *code |= new;
158  return 0;
159}
160
161static const char*
162ext_imms_scaled (const struct ia64_operand *self, ia64_insn code,
163		 ia64_insn *valuep, int scale)
164{
165  int i, bits = 0, total = 0;
166  BFD_HOST_64_BIT val = 0, sign;
167
168  for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
169    {
170      bits = self->field[i].bits;
171      val |= ((code >> self->field[i].shift)
172	      & ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total;
173      total += bits;
174    }
175  /* sign extend: */
176  sign = (BFD_HOST_64_BIT) 1 << (total - 1);
177  val = (val ^ sign) - sign;
178
179  *valuep = (val << scale);
180  return 0;
181}
182
183static const char*
184ins_imms (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
185{
186  return ins_imms_scaled (self, value, code, 0);
187}
188
189static const char*
190ins_immsu4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
191{
192  value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
193
194  return ins_imms_scaled (self, value, code, 0);
195}
196
197static const char*
198ext_imms (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
199{
200  return ext_imms_scaled (self, code, valuep, 0);
201}
202
203static const char*
204ins_immsm1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
205{
206  --value;
207  return ins_imms_scaled (self, value, code, 0);
208}
209
210static const char*
211ins_immsm1u4 (const struct ia64_operand *self, ia64_insn value,
212	      ia64_insn *code)
213{
214  value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
215
216  --value;
217  return ins_imms_scaled (self, value, code, 0);
218}
219
220static const char*
221ext_immsm1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
222{
223  const char *res = ext_imms_scaled (self, code, valuep, 0);
224
225  ++*valuep;
226  return res;
227}
228
229static const char*
230ins_imms1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
231{
232  return ins_imms_scaled (self, value, code, 1);
233}
234
235static const char*
236ext_imms1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
237{
238  return ext_imms_scaled (self, code, valuep, 1);
239}
240
241static const char*
242ins_imms4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
243{
244  return ins_imms_scaled (self, value, code, 4);
245}
246
247static const char*
248ext_imms4 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
249{
250  return ext_imms_scaled (self, code, valuep, 4);
251}
252
253static const char*
254ins_imms16 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
255{
256  return ins_imms_scaled (self, value, code, 16);
257}
258
259static const char*
260ext_imms16 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
261{
262  return ext_imms_scaled (self, code, valuep, 16);
263}
264
265static const char*
266ins_cimmu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
267{
268  ia64_insn mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
269  return ins_immu (self, value ^ mask, code);
270}
271
272static const char*
273ext_cimmu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
274{
275  const char *result;
276  ia64_insn mask;
277
278  mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
279  result = ext_immu (self, code, valuep);
280  if (!result)
281    {
282      mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
283      *valuep ^= mask;
284    }
285  return result;
286}
287
288static const char*
289ins_cnt (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
290{
291  --value;
292  if (value >= ((BFD_HOST_U_64_BIT) 1) << self->field[0].bits)
293    return "count out of range";
294
295  *code |= value << self->field[0].shift;
296  return 0;
297}
298
299static const char*
300ext_cnt (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
301{
302  *valuep = ((code >> self->field[0].shift)
303	     & ((((BFD_HOST_U_64_BIT) 1) << self->field[0].bits) - 1)) + 1;
304  return 0;
305}
306
307static const char*
308ins_cnt2b (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
309{
310  --value;
311
312  if (value > 2)
313    return "count must be in range 1..3";
314
315  *code |= value << self->field[0].shift;
316  return 0;
317}
318
319static const char*
320ext_cnt2b (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
321{
322  *valuep = ((code >> self->field[0].shift) & 0x3) + 1;
323  return 0;
324}
325
326static const char*
327ins_cnt2c (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
328{
329  switch (value)
330    {
331    case 0:	value = 0; break;
332    case 7:	value = 1; break;
333    case 15:	value = 2; break;
334    case 16:	value = 3; break;
335    default:	return "count must be 0, 7, 15, or 16";
336    }
337  *code |= value << self->field[0].shift;
338  return 0;
339}
340
341static const char*
342ext_cnt2c (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
343{
344  ia64_insn value;
345
346  value = (code >> self->field[0].shift) & 0x3;
347  switch (value)
348    {
349    case 0: value =  0; break;
350    case 1: value =  7; break;
351    case 2: value = 15; break;
352    case 3: value = 16; break;
353    }
354  *valuep = value;
355  return 0;
356}
357
358static const char*
359ins_inc3 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
360{
361  BFD_HOST_64_BIT val = value;
362  BFD_HOST_U_64_BIT sign = 0;
363
364  if (val < 0)
365    {
366      sign = 0x4;
367      value = -value;
368    }
369  switch (value)
370    {
371    case  1:	value = 3; break;
372    case  4:	value = 2; break;
373    case  8:	value = 1; break;
374    case 16:	value = 0; break;
375    default:	return "count must be +/- 1, 4, 8, or 16";
376    }
377  *code |= (sign | value) << self->field[0].shift;
378  return 0;
379}
380
381static const char*
382ext_inc3 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
383{
384  BFD_HOST_64_BIT val;
385  int negate;
386
387  val = (code >> self->field[0].shift) & 0x7;
388  negate = val & 0x4;
389  switch (val & 0x3)
390    {
391    case 0: val = 16; break;
392    case 1: val =  8; break;
393    case 2: val =  4; break;
394    case 3: val =  1; break;
395    }
396  if (negate)
397    val = -val;
398
399  *valuep = val;
400  return 0;
401}
402
403#define CST	IA64_OPND_CLASS_CST
404#define REG	IA64_OPND_CLASS_REG
405#define IND	IA64_OPND_CLASS_IND
406#define ABS	IA64_OPND_CLASS_ABS
407#define REL	IA64_OPND_CLASS_REL
408
409#define SDEC	IA64_OPND_FLAG_DECIMAL_SIGNED
410#define UDEC	IA64_OPND_FLAG_DECIMAL_UNSIGNED
411
412const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] =
413  {
414    /* constants: */
415    { CST, ins_const, ext_const, "NIL",		{{ 0, 0}}, 0, "<none>" },
416    { CST, ins_const, ext_const, "ar.csd",	{{ 0, 0}}, 0, "ar.csd" },
417    { CST, ins_const, ext_const, "ar.ccv",	{{ 0, 0}}, 0, "ar.ccv" },
418    { CST, ins_const, ext_const, "ar.pfs",	{{ 0, 0}}, 0, "ar.pfs" },
419    { CST, ins_const, ext_const, "1",		{{ 0, 0}}, 0, "1" },
420    { CST, ins_const, ext_const, "8",		{{ 0, 0}}, 0, "8" },
421    { CST, ins_const, ext_const, "16",		{{ 0, 0}}, 0, "16" },
422    { CST, ins_const, ext_const, "r0",		{{ 0, 0}}, 0, "r0" },
423    { CST, ins_const, ext_const, "ip",		{{ 0, 0}}, 0, "ip" },
424    { CST, ins_const, ext_const, "pr",		{{ 0, 0}}, 0, "pr" },
425    { CST, ins_const, ext_const, "pr.rot",	{{ 0, 0}}, 0, "pr.rot" },
426    { CST, ins_const, ext_const, "psr",		{{ 0, 0}}, 0, "psr" },
427    { CST, ins_const, ext_const, "psr.l",	{{ 0, 0}}, 0, "psr.l" },
428    { CST, ins_const, ext_const, "psr.um",	{{ 0, 0}}, 0, "psr.um" },
429
430    /* register operands: */
431    { REG, ins_reg,   ext_reg,	"ar", {{ 7, 20}}, 0,		/* AR3 */
432      "an application register" },
433    { REG, ins_reg,   ext_reg,	 "b", {{ 3,  6}}, 0,		/* B1 */
434      "a branch register" },
435    { REG, ins_reg,   ext_reg,	 "b", {{ 3, 13}}, 0,		/* B2 */
436      "a branch register"},
437    { REG, ins_reg,   ext_reg,	"cr", {{ 7, 20}}, 0,		/* CR */
438      "a control register"},
439    { REG, ins_reg,   ext_reg,	 "f", {{ 7,  6}}, 0,		/* F1 */
440      "a floating-point register" },
441    { REG, ins_reg,   ext_reg,	 "f", {{ 7, 13}}, 0,		/* F2 */
442      "a floating-point register" },
443    { REG, ins_reg,   ext_reg,	 "f", {{ 7, 20}}, 0,		/* F3 */
444      "a floating-point register" },
445    { REG, ins_reg,   ext_reg,	 "f", {{ 7, 27}}, 0,		/* F4 */
446      "a floating-point register" },
447    { REG, ins_reg,   ext_reg,	 "p", {{ 6,  6}}, 0,		/* P1 */
448      "a predicate register" },
449    { REG, ins_reg,   ext_reg,	 "p", {{ 6, 27}}, 0,		/* P2 */
450      "a predicate register" },
451    { REG, ins_reg,   ext_reg,	 "r", {{ 7,  6}}, 0,		/* R1 */
452      "a general register" },
453    { REG, ins_reg,   ext_reg,	 "r", {{ 7, 13}}, 0,		/* R2 */
454      "a general register" },
455    { REG, ins_reg,   ext_reg,	 "r", {{ 7, 20}}, 0,		/* R3 */
456      "a general register" },
457    { REG, ins_reg,   ext_reg,	 "r", {{ 2, 20}}, 0,		/* R3_2 */
458      "a general register r0-r3" },
459
460    /* indirect operands: */
461    { IND, ins_reg,   ext_reg,	"cpuid", {{7, 20}}, 0,		/* CPUID_R3 */
462      "a cpuid register" },
463    { IND, ins_reg,   ext_reg,	"dbr",   {{7, 20}}, 0,		/* DBR_R3 */
464      "a dbr register" },
465    { IND, ins_reg,   ext_reg,	"dtr",   {{7, 20}}, 0,		/* DTR_R3 */
466      "a dtr register" },
467    { IND, ins_reg,   ext_reg,	"itr",   {{7, 20}}, 0,		/* ITR_R3 */
468      "an itr register" },
469    { IND, ins_reg,   ext_reg,	"ibr",   {{7, 20}}, 0,		/* IBR_R3 */
470      "an ibr register" },
471    { IND, ins_reg,   ext_reg,	"",      {{7, 20}}, 0,		/* MR3 */
472      "an indirect memory address" },
473    { IND, ins_reg,   ext_reg,	"msr",   {{7, 20}}, 0,		/* MSR_R3 */
474      "an msr register" },
475    { IND, ins_reg,   ext_reg,	"pkr",   {{7, 20}}, 0,		/* PKR_R3 */
476      "a pkr register" },
477    { IND, ins_reg,   ext_reg,	"pmc",   {{7, 20}}, 0,		/* PMC_R3 */
478      "a pmc register" },
479    { IND, ins_reg,   ext_reg,	"pmd",   {{7, 20}}, 0,		/* PMD_R3 */
480      "a pmd register" },
481    { IND, ins_reg,   ext_reg,	"rr",    {{7, 20}}, 0,		/* RR_R3 */
482      "an rr register" },
483
484    /* immediate operands: */
485    { ABS, ins_cimmu, ext_cimmu, 0, {{ 5, 20 }}, UDEC,		/* CCNT5 */
486      "a 5-bit count (0-31)" },
487    { ABS, ins_cnt,   ext_cnt,   0, {{ 2, 27 }}, UDEC,		/* CNT2a */
488      "a 2-bit count (1-4)" },
489    { ABS, ins_cnt2b, ext_cnt2b, 0, {{ 2, 27 }}, UDEC,		/* CNT2b */
490      "a 2-bit count (1-3)" },
491    { ABS, ins_cnt2c, ext_cnt2c, 0, {{ 2, 30 }}, UDEC,		/* CNT2c */
492      "a count (0, 7, 15, or 16)" },
493    { ABS, ins_immu,  ext_immu,  0, {{ 5, 14}}, UDEC,		/* CNT5 */
494      "a 5-bit count (0-31)" },
495    { ABS, ins_immu,  ext_immu,  0, {{ 6, 27}}, UDEC,		/* CNT6 */
496      "a 6-bit count (0-63)" },
497    { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 20}}, UDEC,		/* CPOS6a */
498      "a 6-bit bit pos (0-63)" },
499    { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 14}}, UDEC,		/* CPOS6b */
500      "a 6-bit bit pos (0-63)" },
501    { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 31}}, UDEC,		/* CPOS6c */
502      "a 6-bit bit pos (0-63)" },
503    { ABS, ins_imms,  ext_imms,  0, {{ 1, 36}}, SDEC,		/* IMM1 */
504      "a 1-bit integer (-1, 0)" },
505    { ABS, ins_immu,  ext_immu,  0, {{ 2, 13}}, UDEC,		/* IMMU2 */
506      "a 2-bit unsigned (0-3)" },
507    { ABS, ins_immu,  ext_immu,  0, {{ 7, 13}}, 0,		/* IMMU7a */
508      "a 7-bit unsigned (0-127)" },
509    { ABS, ins_immu,  ext_immu,  0, {{ 7, 20}}, 0,		/* IMMU7b */
510      "a 7-bit unsigned (0-127)" },
511    { ABS, ins_immu,  ext_immu,  0, {{ 7, 13}}, UDEC,		/* SOF */
512      "a frame size (register count)" },
513    { ABS, ins_immu,  ext_immu,  0, {{ 7, 20}}, UDEC,		/* SOL */
514      "a local register count" },
515    { ABS, ins_immus8,ext_immus8,0, {{ 4, 27}}, UDEC,		/* SOR */
516      "a rotating register count (integer multiple of 8)" },
517    { ABS, ins_imms,  ext_imms,  0,				/* IMM8 */
518      {{ 7, 13}, { 1, 36}}, SDEC,
519      "an 8-bit integer (-128-127)" },
520    { ABS, ins_immsu4,  ext_imms,  0,				/* IMM8U4 */
521      {{ 7, 13}, { 1, 36}}, SDEC,
522      "an 8-bit signed integer for 32-bit unsigned compare (-128-127)" },
523    { ABS, ins_immsm1,  ext_immsm1,  0,				/* IMM8M1 */
524      {{ 7, 13}, { 1, 36}}, SDEC,
525      "an 8-bit integer (-127-128)" },
526    { ABS, ins_immsm1u4,  ext_immsm1,  0,			/* IMM8M1U4 */
527      {{ 7, 13}, { 1, 36}}, SDEC,
528      "an 8-bit integer for 32-bit unsigned compare (-127-(-1),1-128,0x100000000)" },
529    { ABS, ins_immsm1,  ext_immsm1,  0,				/* IMM8M1U8 */
530      {{ 7, 13}, { 1, 36}}, SDEC,
531      "an 8-bit integer for 64-bit unsigned compare (-127-(-1),1-128,0x10000000000000000)" },
532    { ABS, ins_immu,  ext_immu,  0, {{ 2, 33}, { 7, 20}}, 0,	/* IMMU9 */
533      "a 9-bit unsigned (0-511)" },
534    { ABS, ins_imms,  ext_imms,  0,				/* IMM9a */
535      {{ 7,  6}, { 1, 27}, { 1, 36}}, SDEC,
536      "a 9-bit integer (-256-255)" },
537    { ABS, ins_imms,  ext_imms, 0,				/* IMM9b */
538      {{ 7, 13}, { 1, 27}, { 1, 36}}, SDEC,
539      "a 9-bit integer (-256-255)" },
540    { ABS, ins_imms,  ext_imms, 0,				/* IMM14 */
541      {{ 7, 13}, { 6, 27}, { 1, 36}}, SDEC,
542      "a 14-bit integer (-8192-8191)" },
543    { ABS, ins_imms1, ext_imms1, 0,				/* IMM17 */
544      {{ 7,  6}, { 8, 24}, { 1, 36}}, 0,
545      "a 17-bit integer (-65536-65535)" },
546    { ABS, ins_immu,  ext_immu,  0, {{20,  6}, { 1, 36}}, 0,	/* IMMU21 */
547      "a 21-bit unsigned" },
548    { ABS, ins_imms,  ext_imms,  0,				/* IMM22 */
549      {{ 7, 13}, { 9, 27}, { 5, 22}, { 1, 36}}, SDEC,
550      "a 22-bit signed integer" },
551    { ABS, ins_immu,  ext_immu,  0,				/* IMMU24 */
552      {{21,  6}, { 2, 31}, { 1, 36}}, 0,
553      "a 24-bit unsigned" },
554    { ABS, ins_imms16,ext_imms16,0, {{27,  6}, { 1, 36}}, 0,	/* IMM44 */
555      "a 44-bit unsigned (least 16 bits ignored/zeroes)" },
556    { ABS, ins_rsvd,  ext_rsvd,	0, {{0,  0}}, 0,		/* IMMU62 */
557      "a 62-bit unsigned" },
558    { ABS, ins_rsvd,  ext_rsvd,	0, {{0,  0}}, 0,		/* IMMU64 */
559      "a 64-bit unsigned" },
560    { ABS, ins_inc3,  ext_inc3,  0, {{ 3, 13}}, SDEC,		/* INC3 */
561      "an increment (+/- 1, 4, 8, or 16)" },
562    { ABS, ins_cnt,   ext_cnt,   0, {{ 4, 27}}, UDEC,		/* LEN4 */
563      "a 4-bit length (1-16)" },
564    { ABS, ins_cnt,   ext_cnt,   0, {{ 6, 27}}, UDEC,		/* LEN6 */
565      "a 6-bit length (1-64)" },
566    { ABS, ins_immu,  ext_immu,  0, {{ 4, 20}},	0,		/* MBTYPE4 */
567      "a mix type (@rev, @mix, @shuf, @alt, or @brcst)" },
568    { ABS, ins_immu,  ext_immu,  0, {{ 8, 20}},	0,		/* MBTYPE8 */
569      "an 8-bit mix type" },
570    { ABS, ins_immu,  ext_immu,  0, {{ 6, 14}}, UDEC,		/* POS6 */
571      "a 6-bit bit pos (0-63)" },
572    { REL, ins_imms4, ext_imms4, 0, {{ 7,  6}, { 2, 33}}, 0,	/* TAG13 */
573      "a branch tag" },
574    { REL, ins_imms4, ext_imms4, 0, {{ 9, 24}}, 0,		/* TAG13b */
575      "a branch tag" },
576    { REL, ins_imms4, ext_imms4, 0, {{20,  6}, { 1, 36}}, 0,	/* TGT25 */
577      "a branch target" },
578    { REL, ins_imms4, ext_imms4, 0,				/* TGT25b */
579      {{ 7,  6}, {13, 20}, { 1, 36}}, 0,
580      "a branch target" },
581    { REL, ins_imms4, ext_imms4, 0, {{20, 13}, { 1, 36}}, 0,	/* TGT25c */
582      "a branch target" },
583    { REL, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0,                  /* TGT64  */
584      "a branch target" },
585
586    { ABS, ins_const, ext_const, 0, {{0, 0}}, 0,		/* LDXMOV */
587      "ldxmov target" },
588  };
589