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