1/* Copyright (C) 1998-2017 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#define NELEMS(a)  ((int) (sizeof (a) / sizeof ((a)[0])))
33
34static const char*
35ins_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED,
36	  ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED)
37{
38  return "internal error---this shouldn't happen";
39}
40
41static const char*
42ext_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED,
43	  ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED)
44{
45  return "internal error---this shouldn't happen";
46}
47
48static const char*
49ins_const (const struct ia64_operand *self ATTRIBUTE_UNUSED,
50	   ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED)
51{
52  return 0;
53}
54
55static const char*
56ext_const (const struct ia64_operand *self ATTRIBUTE_UNUSED,
57	   ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED)
58{
59  return 0;
60}
61
62static const char*
63ins_reg (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
64{
65  if (value >= 1u << self->field[0].bits)
66    return "register number out of range";
67
68  *code |= value << self->field[0].shift;
69  return 0;
70}
71
72static const char*
73ext_reg (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
74{
75  *valuep = ((code >> self->field[0].shift)
76	     & ((1u << self->field[0].bits) - 1));
77  return 0;
78}
79
80static const char*
81ins_immu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
82{
83  ia64_insn new_insn = 0;
84  int i;
85
86  for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
87    {
88      new_insn |= ((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_insn;
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_immu5b (const struct ia64_operand *self, ia64_insn value,
118	    ia64_insn *code)
119{
120  if (value < 32 || value > 63)
121    return "value must be between 32 and 63";
122  return ins_immu (self, value - 32, code);
123}
124
125static const char*
126ext_immu5b (const struct ia64_operand *self, ia64_insn code,
127	    ia64_insn *valuep)
128{
129  const char *result;
130
131  result = ext_immu (self, code, valuep);
132  if (result)
133    return result;
134
135  *valuep = *valuep + 32;
136  return 0;
137}
138
139static const char*
140ins_immus8 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
141{
142  if (value & 0x7)
143    return "value not an integer multiple of 8";
144  return ins_immu (self, value >> 3, code);
145}
146
147static const char*
148ext_immus8 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
149{
150  const char *result;
151
152  result = ext_immu (self, code, valuep);
153  if (result)
154    return result;
155
156  *valuep = *valuep << 3;
157  return 0;
158}
159
160static const char*
161ins_imms_scaled (const struct ia64_operand *self, ia64_insn value,
162		 ia64_insn *code, int scale)
163{
164  BFD_HOST_64_BIT svalue = value, sign_bit = 0;
165  ia64_insn new_insn = 0;
166  int i;
167
168  svalue >>= scale;
169
170  for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
171    {
172      new_insn |= ((svalue & ((((ia64_insn) 1) << self->field[i].bits) - 1))
173                 << self->field[i].shift);
174      sign_bit = (svalue >> (self->field[i].bits - 1)) & 1;
175      svalue >>= self->field[i].bits;
176    }
177  if ((!sign_bit && svalue != 0) || (sign_bit && svalue != -1))
178    return "integer operand out of range";
179
180  *code |= new_insn;
181  return 0;
182}
183
184static const char*
185ext_imms_scaled (const struct ia64_operand *self, ia64_insn code,
186		 ia64_insn *valuep, int scale)
187{
188  int i, bits = 0, total = 0;
189  BFD_HOST_64_BIT val = 0, sign;
190
191  for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
192    {
193      bits = self->field[i].bits;
194      val |= ((code >> self->field[i].shift)
195	      & ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total;
196      total += bits;
197    }
198  /* sign extend: */
199  sign = (BFD_HOST_64_BIT) 1 << (total - 1);
200  val = (val ^ sign) - sign;
201
202  *valuep = (val << scale);
203  return 0;
204}
205
206static const char*
207ins_imms (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
208{
209  return ins_imms_scaled (self, value, code, 0);
210}
211
212static const char*
213ins_immsu4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
214{
215  value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
216
217  return ins_imms_scaled (self, value, code, 0);
218}
219
220static const char*
221ext_imms (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
222{
223  return ext_imms_scaled (self, code, valuep, 0);
224}
225
226static const char*
227ins_immsm1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
228{
229  --value;
230  return ins_imms_scaled (self, value, code, 0);
231}
232
233static const char*
234ins_immsm1u4 (const struct ia64_operand *self, ia64_insn value,
235	      ia64_insn *code)
236{
237  value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
238
239  --value;
240  return ins_imms_scaled (self, value, code, 0);
241}
242
243static const char*
244ext_immsm1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
245{
246  const char *res = ext_imms_scaled (self, code, valuep, 0);
247
248  ++*valuep;
249  return res;
250}
251
252static const char*
253ins_imms1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
254{
255  return ins_imms_scaled (self, value, code, 1);
256}
257
258static const char*
259ext_imms1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
260{
261  return ext_imms_scaled (self, code, valuep, 1);
262}
263
264static const char*
265ins_imms4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
266{
267  return ins_imms_scaled (self, value, code, 4);
268}
269
270static const char*
271ext_imms4 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
272{
273  return ext_imms_scaled (self, code, valuep, 4);
274}
275
276static const char*
277ins_imms16 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
278{
279  return ins_imms_scaled (self, value, code, 16);
280}
281
282static const char*
283ext_imms16 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
284{
285  return ext_imms_scaled (self, code, valuep, 16);
286}
287
288static const char*
289ins_cimmu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
290{
291  ia64_insn mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
292  return ins_immu (self, value ^ mask, code);
293}
294
295static const char*
296ext_cimmu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
297{
298  const char *result;
299  ia64_insn mask;
300
301  mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
302  result = ext_immu (self, code, valuep);
303  if (!result)
304    {
305      mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
306      *valuep ^= mask;
307    }
308  return result;
309}
310
311static const char*
312ins_cnt (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
313{
314  --value;
315  if (value >= ((BFD_HOST_U_64_BIT) 1) << self->field[0].bits)
316    return "count out of range";
317
318  *code |= value << self->field[0].shift;
319  return 0;
320}
321
322static const char*
323ext_cnt (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
324{
325  *valuep = ((code >> self->field[0].shift)
326	     & ((((BFD_HOST_U_64_BIT) 1) << self->field[0].bits) - 1)) + 1;
327  return 0;
328}
329
330static const char*
331ins_cnt2b (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
332{
333  --value;
334
335  if (value > 2)
336    return "count must be in range 1..3";
337
338  *code |= value << self->field[0].shift;
339  return 0;
340}
341
342static const char*
343ext_cnt2b (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
344{
345  *valuep = ((code >> self->field[0].shift) & 0x3) + 1;
346  return 0;
347}
348
349static const char*
350ins_cnt2c (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
351{
352  switch (value)
353    {
354    case 0:	value = 0; break;
355    case 7:	value = 1; break;
356    case 15:	value = 2; break;
357    case 16:	value = 3; break;
358    default:	return "count must be 0, 7, 15, or 16";
359    }
360  *code |= value << self->field[0].shift;
361  return 0;
362}
363
364static const char*
365ext_cnt2c (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
366{
367  ia64_insn value;
368
369  value = (code >> self->field[0].shift) & 0x3;
370  switch (value)
371    {
372    case 0: value =  0; break;
373    case 1: value =  7; break;
374    case 2: value = 15; break;
375    case 3: value = 16; break;
376    }
377  *valuep = value;
378  return 0;
379}
380
381static const char*
382ins_cnt6a (const struct ia64_operand *self, ia64_insn value,
383	    ia64_insn *code)
384{
385  if (value < 1 || value > 64)
386    return "value must be between 1 and 64";
387  return ins_immu (self, value - 1, code);
388}
389
390static const char*
391ext_cnt6a (const struct ia64_operand *self, ia64_insn code,
392	    ia64_insn *valuep)
393{
394  const char *result;
395
396  result = ext_immu (self, code, valuep);
397  if (result)
398    return result;
399
400  *valuep = *valuep + 1;
401  return 0;
402}
403
404static const char*
405ins_strd5b (const struct ia64_operand *self, ia64_insn value,
406	    ia64_insn *code)
407{
408  if (  value & 0x3f )
409    return "value must be a multiple of 64";
410  return ins_imms_scaled (self, value, code, 6);
411}
412
413static const char*
414ext_strd5b (const struct ia64_operand *self, ia64_insn code,
415	    ia64_insn *valuep)
416{
417  return ext_imms_scaled (self, code, valuep, 6);
418}
419
420
421static const char*
422ins_inc3 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
423{
424  BFD_HOST_64_BIT val = value;
425  BFD_HOST_U_64_BIT sign = 0;
426
427  if (val < 0)
428    {
429      sign = 0x4;
430      value = -value;
431    }
432  switch (value)
433    {
434    case  1:	value = 3; break;
435    case  4:	value = 2; break;
436    case  8:	value = 1; break;
437    case 16:	value = 0; break;
438    default:	return "count must be +/- 1, 4, 8, or 16";
439    }
440  *code |= (sign | value) << self->field[0].shift;
441  return 0;
442}
443
444static const char*
445ext_inc3 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
446{
447  BFD_HOST_64_BIT val;
448  int negate;
449
450  val = (code >> self->field[0].shift) & 0x7;
451  negate = val & 0x4;
452  switch (val & 0x3)
453    {
454    case 0: val = 16; break;
455    case 1: val =  8; break;
456    case 2: val =  4; break;
457    case 3: val =  1; break;
458    }
459  if (negate)
460    val = -val;
461
462  *valuep = val;
463  return 0;
464}
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
475const 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  };
670