Home | History | Annotate | Download | only in bfd
      1 /* Copyright (C) 1998-2014 Free Software Foundation, Inc.
      2    Contributed by David Mosberger-Tang <davidm (at) 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 
     34 static const char*
     35 ins_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED,
     36 	  ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED)
     37 {
     38   return "internal error---this shouldn't happen";
     39 }
     40 
     41 static const char*
     42 ext_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED,
     43 	  ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED)
     44 {
     45   return "internal error---this shouldn't happen";
     46 }
     47 
     48 static const char*
     49 ins_const (const struct ia64_operand *self ATTRIBUTE_UNUSED,
     50 	   ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED)
     51 {
     52   return 0;
     53 }
     54 
     55 static const char*
     56 ext_const (const struct ia64_operand *self ATTRIBUTE_UNUSED,
     57 	   ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED)
     58 {
     59   return 0;
     60 }
     61 
     62 static const char*
     63 ins_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 
     72 static const char*
     73 ext_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 
     80 static const char*
     81 ins_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 
     99 static const char*
    100 ext_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 
    116 static const char*
    117 ins_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 
    125 static const char*
    126 ext_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 
    139 static const char*
    140 ins_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 
    147 static const char*
    148 ext_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 
    160 static const char*
    161 ins_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 
    184 static const char*
    185 ext_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 
    206 static const char*
    207 ins_imms (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
    208 {
    209   return ins_imms_scaled (self, value, code, 0);
    210 }
    211 
    212 static const char*
    213 ins_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 
    220 static const char*
    221 ext_imms (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
    222 {
    223   return ext_imms_scaled (self, code, valuep, 0);
    224 }
    225 
    226 static const char*
    227 ins_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 
    233 static const char*
    234 ins_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 
    243 static const char*
    244 ext_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 
    252 static const char*
    253 ins_imms1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
    254 {
    255   return ins_imms_scaled (self, value, code, 1);
    256 }
    257 
    258 static const char*
    259 ext_imms1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
    260 {
    261   return ext_imms_scaled (self, code, valuep, 1);
    262 }
    263 
    264 static const char*
    265 ins_imms4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
    266 {
    267   return ins_imms_scaled (self, value, code, 4);
    268 }
    269 
    270 static const char*
    271 ext_imms4 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
    272 {
    273   return ext_imms_scaled (self, code, valuep, 4);
    274 }
    275 
    276 static const char*
    277 ins_imms16 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
    278 {
    279   return ins_imms_scaled (self, value, code, 16);
    280 }
    281 
    282 static const char*
    283 ext_imms16 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
    284 {
    285   return ext_imms_scaled (self, code, valuep, 16);
    286 }
    287 
    288 static const char*
    289 ins_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 
    295 static const char*
    296 ext_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 
    311 static const char*
    312 ins_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 
    322 static const char*
    323 ext_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 
    330 static const char*
    331 ins_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 
    342 static const char*
    343 ext_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 
    349 static const char*
    350 ins_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 
    364 static const char*
    365 ext_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 
    381 static const char*
    382 ins_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 
    390 static const char*
    391 ext_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 
    404 static const char*
    405 ins_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 
    413 static const char*
    414 ext_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 
    421 static const char*
    422 ins_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 
    444 static const char*
    445 ext_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 
    475 const struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] =
    476   {
    477     /* constants: */
    478     { CST, ins_const, ext_const, "NIL",		{{ 0, 0}}, 0, "<none>" },
    479     { CST, ins_const, ext_const, "ar.csd",	{{ 0, 0}}, 0, "ar.csd" },
    480     { CST, ins_const, ext_const, "ar.ccv",	{{ 0, 0}}, 0, "ar.ccv" },
    481     { CST, ins_const, ext_const, "ar.pfs",	{{ 0, 0}}, 0, "ar.pfs" },
    482     { CST, ins_const, ext_const, "1",		{{ 0, 0}}, 0, "1" },
    483     { CST, ins_const, ext_const, "8",		{{ 0, 0}}, 0, "8" },
    484     { CST, ins_const, ext_const, "16",		{{ 0, 0}}, 0, "16" },
    485     { CST, ins_const, ext_const, "r0",		{{ 0, 0}}, 0, "r0" },
    486     { CST, ins_const, ext_const, "ip",		{{ 0, 0}}, 0, "ip" },
    487     { CST, ins_const, ext_const, "pr",		{{ 0, 0}}, 0, "pr" },
    488     { CST, ins_const, ext_const, "pr.rot",	{{ 0, 0}}, 0, "pr.rot" },
    489     { CST, ins_const, ext_const, "psr",		{{ 0, 0}}, 0, "psr" },
    490     { CST, ins_const, ext_const, "psr.l",	{{ 0, 0}}, 0, "psr.l" },
    491     { CST, ins_const, ext_const, "psr.um",	{{ 0, 0}}, 0, "psr.um" },
    492 
    493     /* register operands: */
    494     { REG, ins_reg,   ext_reg,	"ar", {{ 7, 20}}, 0,		/* AR3 */
    495       "an application register" },
    496     { REG, ins_reg,   ext_reg,	 "b", {{ 3,  6}}, 0,		/* B1 */
    497       "a branch register" },
    498     { REG, ins_reg,   ext_reg,	 "b", {{ 3, 13}}, 0,		/* B2 */
    499       "a branch register"},
    500     { REG, ins_reg,   ext_reg,	"cr", {{ 7, 20}}, 0,		/* CR */
    501       "a control register"},
    502     { REG, ins_reg,   ext_reg,	 "f", {{ 7,  6}}, 0,		/* F1 */
    503       "a floating-point register" },
    504     { REG, ins_reg,   ext_reg,	 "f", {{ 7, 13}}, 0,		/* F2 */
    505       "a floating-point register" },
    506     { REG, ins_reg,   ext_reg,	 "f", {{ 7, 20}}, 0,		/* F3 */
    507       "a floating-point register" },
    508     { REG, ins_reg,   ext_reg,	 "f", {{ 7, 27}}, 0,		/* F4 */
    509       "a floating-point register" },
    510     { REG, ins_reg,   ext_reg,	 "p", {{ 6,  6}}, 0,		/* P1 */
    511       "a predicate register" },
    512     { REG, ins_reg,   ext_reg,	 "p", {{ 6, 27}}, 0,		/* P2 */
    513       "a predicate register" },
    514     { REG, ins_reg,   ext_reg,	 "r", {{ 7,  6}}, 0,		/* R1 */
    515       "a general register" },
    516     { REG, ins_reg,   ext_reg,	 "r", {{ 7, 13}}, 0,		/* R2 */
    517       "a general register" },
    518     { REG, ins_reg,   ext_reg,	 "r", {{ 7, 20}}, 0,		/* R3 */
    519       "a general register" },
    520     { REG, ins_reg,   ext_reg,	 "r", {{ 2, 20}}, 0,		/* R3_2 */
    521       "a general register r0-r3" },
    522     { REG, ins_reg,   ext_reg,	 "dahr", {{ 3, 23}}, 0,		/* DAHR */
    523       "a dahr register dahr0-7" },
    524 
    525     /* memory operands: */
    526     { IND, ins_reg,   ext_reg,	"",      {{7, 20}}, 0,		/* MR3 */
    527       "a memory address" },
    528 
    529     /* indirect operands: */
    530     { IND, ins_reg,   ext_reg,	"cpuid", {{7, 20}}, 0,		/* CPUID_R3 */
    531       "a cpuid register" },
    532     { IND, ins_reg,   ext_reg,	"dbr",   {{7, 20}}, 0,		/* DBR_R3 */
    533       "a dbr register" },
    534     { IND, ins_reg,   ext_reg,	"dtr",   {{7, 20}}, 0,		/* DTR_R3 */
    535       "a dtr register" },
    536     { IND, ins_reg,   ext_reg,	"itr",   {{7, 20}}, 0,		/* ITR_R3 */
    537       "an itr register" },
    538     { IND, ins_reg,   ext_reg,	"ibr",   {{7, 20}}, 0,		/* IBR_R3 */
    539       "an ibr register" },
    540     { IND, ins_reg,   ext_reg,	"msr",   {{7, 20}}, 0,		/* MSR_R3 */
    541       "an msr register" },
    542     { IND, ins_reg,   ext_reg,	"pkr",   {{7, 20}}, 0,		/* PKR_R3 */
    543       "a pkr register" },
    544     { IND, ins_reg,   ext_reg,	"pmc",   {{7, 20}}, 0,		/* PMC_R3 */
    545       "a pmc register" },
    546     { IND, ins_reg,   ext_reg,	"pmd",   {{7, 20}}, 0,		/* PMD_R3 */
    547       "a pmd register" },
    548     { IND, ins_reg,   ext_reg,	"dahr",  {{7, 20}}, 0,		/* DAHR_R3 */
    549       "a dahr register" },
    550     { IND, ins_reg,   ext_reg,	"rr",    {{7, 20}}, 0,		/* RR_R3 */
    551       "an rr register" },
    552 
    553     /* immediate operands: */
    554     { ABS, ins_cimmu, ext_cimmu, 0, {{ 5, 20 }}, UDEC,		/* CCNT5 */
    555       "a 5-bit count (0-31)" },
    556     { ABS, ins_cnt,   ext_cnt,   0, {{ 2, 27 }}, UDEC,		/* CNT2a */
    557       "a 2-bit count (1-4)" },
    558     { ABS, ins_cnt2b, ext_cnt2b, 0, {{ 2, 27 }}, UDEC,		/* CNT2b */
    559       "a 2-bit count (1-3)" },
    560     { ABS, ins_cnt2c, ext_cnt2c, 0, {{ 2, 30 }}, UDEC,		/* CNT2c */
    561       "a count (0, 7, 15, or 16)" },
    562     { ABS, ins_immu,  ext_immu,  0, {{ 5, 14}}, UDEC,		/* CNT5 */
    563       "a 5-bit count (0-31)" },
    564     { ABS, ins_immu,  ext_immu,  0, {{ 6, 27}}, UDEC,		/* CNT6 */
    565       "a 6-bit count (0-63)" },
    566     { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 20}}, UDEC,		/* CPOS6a */
    567       "a 6-bit bit pos (0-63)" },
    568     { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 14}}, UDEC,		/* CPOS6b */
    569       "a 6-bit bit pos (0-63)" },
    570     { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 31}}, UDEC,		/* CPOS6c */
    571       "a 6-bit bit pos (0-63)" },
    572     { ABS, ins_imms,  ext_imms,  0, {{ 1, 36}}, SDEC,		/* IMM1 */
    573       "a 1-bit integer (-1, 0)" },
    574     { ABS, ins_immu,  ext_immu,  0, {{ 2, 13}}, UDEC,		/* IMMU2 */
    575       "a 2-bit unsigned (0-3)" },
    576     { ABS, ins_immu5b,  ext_immu5b,  0, {{ 5, 14}}, UDEC,	/* IMMU5b */
    577       "a 5-bit unsigned (32 + (0-31))" },
    578     { ABS, ins_immu,  ext_immu,  0, {{ 7, 13}}, 0,		/* IMMU7a */
    579       "a 7-bit unsigned (0-127)" },
    580     { ABS, ins_immu,  ext_immu,  0, {{ 7, 20}}, 0,		/* IMMU7b */
    581       "a 7-bit unsigned (0-127)" },
    582     { ABS, ins_immu,  ext_immu,  0, {{ 7, 13}}, UDEC,		/* SOF */
    583       "a frame size (register count)" },
    584     { ABS, ins_immu,  ext_immu,  0, {{ 7, 20}}, UDEC,		/* SOL */
    585       "a local register count" },
    586     { ABS, ins_immus8,ext_immus8,0, {{ 4, 27}}, UDEC,		/* SOR */
    587       "a rotating register count (integer multiple of 8)" },
    588     { ABS, ins_imms,  ext_imms,  0,				/* IMM8 */
    589       {{ 7, 13}, { 1, 36}}, SDEC,
    590       "an 8-bit integer (-128-127)" },
    591     { ABS, ins_immsu4,  ext_imms,  0,				/* IMM8U4 */
    592       {{ 7, 13}, { 1, 36}}, SDEC,
    593       "an 8-bit signed integer for 32-bit unsigned compare (-128-127)" },
    594     { ABS, ins_immsm1,  ext_immsm1,  0,				/* IMM8M1 */
    595       {{ 7, 13}, { 1, 36}}, SDEC,
    596       "an 8-bit integer (-127-128)" },
    597     { ABS, ins_immsm1u4,  ext_immsm1,  0,			/* IMM8M1U4 */
    598       {{ 7, 13}, { 1, 36}}, SDEC,
    599       "an 8-bit integer for 32-bit unsigned compare (-127-(-1),1-128,0x100000000)" },
    600     { ABS, ins_immsm1,  ext_immsm1,  0,				/* IMM8M1U8 */
    601       {{ 7, 13}, { 1, 36}}, SDEC,
    602       "an 8-bit integer for 64-bit unsigned compare (-127-(-1),1-128,0x10000000000000000)" },
    603     { ABS, ins_immu,  ext_immu,  0, {{ 2, 33}, { 7, 20}}, 0,	/* IMMU9 */
    604       "a 9-bit unsigned (0-511)" },
    605     { ABS, ins_imms,  ext_imms,  0,				/* IMM9a */
    606       {{ 7,  6}, { 1, 27}, { 1, 36}}, SDEC,
    607       "a 9-bit integer (-256-255)" },
    608     { ABS, ins_imms,  ext_imms, 0,				/* IMM9b */
    609       {{ 7, 13}, { 1, 27}, { 1, 36}}, SDEC,
    610       "a 9-bit integer (-256-255)" },
    611     { ABS, ins_imms,  ext_imms, 0,				/* IMM14 */
    612       {{ 7, 13}, { 6, 27}, { 1, 36}}, SDEC,
    613       "a 14-bit integer (-8192-8191)" },
    614     { ABS, ins_immu,  ext_immu,  0,				/* IMMU16 */
    615       {{4,  6}, {11, 12}, { 1, 36}}, UDEC,
    616       "a 16-bit unsigned" },
    617     { ABS, ins_imms1, ext_imms1, 0,				/* IMM17 */
    618       {{ 7,  6}, { 8, 24}, { 1, 36}}, 0,
    619       "a 17-bit integer (-65536-65535)" },
    620     { ABS, ins_immu,  ext_immu,  0,				/* IMMU19 */
    621       {{4,  6}, {14, 12}, { 1, 36}}, UDEC,
    622       "a 19-bit unsigned" },
    623     { ABS, ins_immu,  ext_immu,  0, {{20,  6}, { 1, 36}}, 0,	/* IMMU21 */
    624       "a 21-bit unsigned" },
    625     { ABS, ins_imms,  ext_imms,  0,				/* IMM22 */
    626       {{ 7, 13}, { 9, 27}, { 5, 22}, { 1, 36}}, SDEC,
    627       "a 22-bit signed integer" },
    628     { ABS, ins_immu,  ext_immu,  0,				/* IMMU24 */
    629       {{21,  6}, { 2, 31}, { 1, 36}}, 0,
    630       "a 24-bit unsigned" },
    631     { ABS, ins_imms16,ext_imms16,0, {{27,  6}, { 1, 36}}, 0,	/* IMM44 */
    632       "a 44-bit unsigned (least 16 bits ignored/zeroes)" },
    633     { ABS, ins_rsvd,  ext_rsvd,	0, {{0,  0}}, 0,		/* IMMU62 */
    634       "a 62-bit unsigned" },
    635     { ABS, ins_rsvd,  ext_rsvd,	0, {{0,  0}}, 0,		/* IMMU64 */
    636       "a 64-bit unsigned" },
    637     { ABS, ins_inc3,  ext_inc3,  0, {{ 3, 13}}, SDEC,		/* INC3 */
    638       "an increment (+/- 1, 4, 8, or 16)" },
    639     { ABS, ins_cnt,   ext_cnt,   0, {{ 4, 27}}, UDEC,		/* LEN4 */
    640       "a 4-bit length (1-16)" },
    641     { ABS, ins_cnt,   ext_cnt,   0, {{ 6, 27}}, UDEC,		/* LEN6 */
    642       "a 6-bit length (1-64)" },
    643     { ABS, ins_immu,  ext_immu,  0, {{ 4, 20}},	0,		/* MBTYPE4 */
    644       "a mix type (@rev, @mix, @shuf, @alt, or @brcst)" },
    645     { ABS, ins_immu,  ext_immu,  0, {{ 8, 20}},	0,		/* MBTYPE8 */
    646       "an 8-bit mix type" },
    647     { ABS, ins_immu,  ext_immu,  0, {{ 6, 14}}, UDEC,		/* POS6 */
    648       "a 6-bit bit pos (0-63)" },
    649     { REL, ins_imms4, ext_imms4, 0, {{ 7,  6}, { 2, 33}}, 0,	/* TAG13 */
    650       "a branch tag" },
    651     { REL, ins_imms4, ext_imms4, 0, {{ 9, 24}}, 0,		/* TAG13b */
    652       "a branch tag" },
    653     { REL, ins_imms4, ext_imms4, 0, {{20,  6}, { 1, 36}}, 0,	/* TGT25 */
    654       "a branch target" },
    655     { REL, ins_imms4, ext_imms4, 0,				/* TGT25b */
    656       {{ 7,  6}, {13, 20}, { 1, 36}}, 0,
    657       "a branch target" },
    658     { REL, ins_imms4, ext_imms4, 0, {{20, 13}, { 1, 36}}, 0,	/* TGT25c */
    659       "a branch target" },
    660     { REL, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0,                  /* TGT64  */
    661       "a branch target" },
    662 
    663     { ABS, ins_const, ext_const, 0, {{0, 0}}, 0,		/* LDXMOV */
    664       "ldxmov target" },
    665     { ABS, ins_cnt6a, ext_cnt6a, 0, {{6, 6}}, UDEC,		/* CNT6a */
    666       "lfetch count" },
    667     { ABS, ins_strd5b, ext_strd5b, 0, {{5, 13}}, SDEC,		/* STRD5b*/
    668       "lfetch stride" },
    669   };
    670