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