cpu-ia64-opc.c revision 84865
184865Sobrien/* Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
284865Sobrien   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
384865Sobrien
484865SobrienThis file is part of BFD, the Binary File Descriptor library.
584865Sobrien
684865SobrienThis program is free software; you can redistribute it and/or modify
784865Sobrienit under the terms of the GNU General Public License as published by
884865Sobrienthe Free Software Foundation; either version 2 of the License, or
984865Sobrien(at your option) any later version.
1084865Sobrien
1184865SobrienThis program is distributed in the hope that it will be useful,
1284865Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1384865SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1484865SobrienGNU General Public License for more details.
1584865Sobrien
1684865SobrienYou should have received a copy of the GNU General Public License
1784865Sobrienalong with this program; if not, write to the Free Software
1884865SobrienFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
1984865Sobrien
2084865Sobrien/* Logically, this code should be part of libopcode but since some of
2184865Sobrien   the operand insertion/extraction functions help bfd to implement
2284865Sobrien   relocations, this code is included as part of elf64-ia64.c.  This
2384865Sobrien   avoids circular dependencies between libopcode and libbfd and also
2484865Sobrien   obviates the need for applications to link in libopcode when all
2584865Sobrien   they really want is libbfd.
2684865Sobrien
2784865Sobrien   --davidm Mon Apr 13 22:14:02 1998 */
2884865Sobrien
2984865Sobrien#include "../opcodes/ia64-opc.h"
3084865Sobrien
3184865Sobrien#define NELEMS(a)  ((int) (sizeof (a) / sizeof ((a)[0])))
3284865Sobrien
3384865Sobrienstatic const char*
3484865Sobrienins_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED,
3584865Sobrien	  ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED)
3684865Sobrien{
3784865Sobrien  return "internal error---this shouldn't happen";
3884865Sobrien}
3984865Sobrien
4084865Sobrienstatic const char*
4184865Sobrienext_rsvd (const struct ia64_operand *self ATTRIBUTE_UNUSED,
4284865Sobrien	  ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED)
4384865Sobrien{
4484865Sobrien  return "internal error---this shouldn't happen";
4584865Sobrien}
4684865Sobrien
4784865Sobrienstatic const char*
4884865Sobrienins_const (const struct ia64_operand *self ATTRIBUTE_UNUSED,
4984865Sobrien	   ia64_insn value ATTRIBUTE_UNUSED, ia64_insn *code ATTRIBUTE_UNUSED)
5084865Sobrien{
5184865Sobrien  return 0;
5284865Sobrien}
5384865Sobrien
5484865Sobrienstatic const char*
5584865Sobrienext_const (const struct ia64_operand *self ATTRIBUTE_UNUSED,
5684865Sobrien	   ia64_insn code ATTRIBUTE_UNUSED, ia64_insn *valuep ATTRIBUTE_UNUSED)
5784865Sobrien{
5884865Sobrien  return 0;
5984865Sobrien}
6084865Sobrien
6184865Sobrienstatic const char*
6284865Sobrienins_reg (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
6384865Sobrien{
6484865Sobrien  if (value >= 1u << self->field[0].bits)
6584865Sobrien    return "register number out of range";
6684865Sobrien
6784865Sobrien  *code |= value << self->field[0].shift;
6884865Sobrien  return 0;
6984865Sobrien}
7084865Sobrien
7184865Sobrienstatic const char*
7284865Sobrienext_reg (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
7384865Sobrien{
7484865Sobrien  *valuep = ((code >> self->field[0].shift)
7584865Sobrien	     & ((1u << self->field[0].bits) - 1));
7684865Sobrien  return 0;
7784865Sobrien}
7884865Sobrien
7984865Sobrienstatic const char*
8084865Sobrienins_immu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
8184865Sobrien{
8284865Sobrien  ia64_insn new = 0;
8384865Sobrien  int i;
8484865Sobrien
8584865Sobrien  for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
8684865Sobrien    {
8784865Sobrien      new |= ((value & ((((ia64_insn) 1) << self->field[i].bits) - 1))
8884865Sobrien	      << self->field[i].shift);
8984865Sobrien      value >>= self->field[i].bits;
9084865Sobrien    }
9184865Sobrien  if (value)
9284865Sobrien    return "integer operand out of range";
9384865Sobrien
9484865Sobrien  *code |= new;
9584865Sobrien  return 0;
9684865Sobrien}
9784865Sobrien
9884865Sobrienstatic const char*
9984865Sobrienext_immu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
10084865Sobrien{
10184865Sobrien  BFD_HOST_U_64_BIT value = 0;
10284865Sobrien  int i, bits = 0, total = 0;
10384865Sobrien
10484865Sobrien  for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
10584865Sobrien    {
10684865Sobrien      bits = self->field[i].bits;
10784865Sobrien      value |= ((code >> self->field[i].shift)
10884865Sobrien		& ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total;
10984865Sobrien      total += bits;
11084865Sobrien    }
11184865Sobrien  *valuep = value;
11284865Sobrien  return 0;
11384865Sobrien}
11484865Sobrien
11584865Sobrienstatic const char*
11684865Sobrienins_immus8 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
11784865Sobrien{
11884865Sobrien  if (value & 0x7)
11984865Sobrien    return "value not an integer multiple of 8";
12084865Sobrien  return ins_immu (self, value >> 3, code);
12184865Sobrien}
12284865Sobrien
12384865Sobrienstatic const char*
12484865Sobrienext_immus8 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
12584865Sobrien{
12684865Sobrien  const char *result;
12784865Sobrien
12884865Sobrien  result = ext_immu (self, code, valuep);
12984865Sobrien  if (result)
13084865Sobrien    return result;
13184865Sobrien
13284865Sobrien  *valuep = *valuep << 3;
13384865Sobrien  return 0;
13484865Sobrien}
13584865Sobrien
13684865Sobrienstatic const char*
13784865Sobrienins_imms_scaled (const struct ia64_operand *self, ia64_insn value,
13884865Sobrien		 ia64_insn *code, int scale)
13984865Sobrien{
14084865Sobrien  BFD_HOST_64_BIT svalue = value, sign_bit = 0;
14184865Sobrien  ia64_insn new = 0;
14284865Sobrien  int i;
14384865Sobrien
14484865Sobrien  svalue >>= scale;
14584865Sobrien
14684865Sobrien  for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
14784865Sobrien    {
14884865Sobrien      new |= ((svalue & ((((ia64_insn) 1) << self->field[i].bits) - 1))
14984865Sobrien	      << self->field[i].shift);
15084865Sobrien      sign_bit = (svalue >> (self->field[i].bits - 1)) & 1;
15184865Sobrien      svalue >>= self->field[i].bits;
15284865Sobrien    }
15384865Sobrien  if ((!sign_bit && svalue != 0) || (sign_bit && svalue != -1))
15484865Sobrien    return "integer operand out of range";
15584865Sobrien
15684865Sobrien  *code |= new;
15784865Sobrien  return 0;
15884865Sobrien}
15984865Sobrien
16084865Sobrienstatic const char*
16184865Sobrienext_imms_scaled (const struct ia64_operand *self, ia64_insn code,
16284865Sobrien		 ia64_insn *valuep, int scale)
16384865Sobrien{
16484865Sobrien  int i, bits = 0, total = 0, shift;
16584865Sobrien  BFD_HOST_64_BIT val = 0;
16684865Sobrien
16784865Sobrien  for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
16884865Sobrien    {
16984865Sobrien      bits = self->field[i].bits;
17084865Sobrien      val |= ((code >> self->field[i].shift)
17184865Sobrien	      & ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total;
17284865Sobrien      total += bits;
17384865Sobrien    }
17484865Sobrien  /* sign extend: */
17584865Sobrien  shift = 8*sizeof (val) - total;
17684865Sobrien  val = (val << shift) >> shift;
17784865Sobrien
17884865Sobrien  *valuep = (val << scale);
17984865Sobrien  return 0;
18084865Sobrien}
18184865Sobrien
18284865Sobrienstatic const char*
18384865Sobrienins_imms (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
18484865Sobrien{
18584865Sobrien  return ins_imms_scaled (self, value, code, 0);
18684865Sobrien}
18784865Sobrien
18884865Sobrienstatic const char*
18984865Sobrienins_immsu4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
19084865Sobrien{
19184865Sobrien  if (value == (BFD_HOST_U_64_BIT) 0x100000000)
19284865Sobrien    value = 0;
19384865Sobrien  else
19484865Sobrien    value = (((BFD_HOST_64_BIT)value << 32) >> 32);
19584865Sobrien
19684865Sobrien  return ins_imms_scaled (self, value, code, 0);
19784865Sobrien}
19884865Sobrien
19984865Sobrienstatic const char*
20084865Sobrienext_imms (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
20184865Sobrien{
20284865Sobrien  return ext_imms_scaled (self, code, valuep, 0);
20384865Sobrien}
20484865Sobrien
20584865Sobrienstatic const char*
20684865Sobrienins_immsm1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
20784865Sobrien{
20884865Sobrien  --value;
20984865Sobrien  return ins_imms_scaled (self, value, code, 0);
21084865Sobrien}
21184865Sobrien
21284865Sobrienstatic const char*
21384865Sobrienins_immsm1u4 (const struct ia64_operand *self, ia64_insn value,
21484865Sobrien	      ia64_insn *code)
21584865Sobrien{
21684865Sobrien  if (value == (BFD_HOST_U_64_BIT) 0x100000000)
21784865Sobrien    value = 0;
21884865Sobrien  else
21984865Sobrien    value = (((BFD_HOST_64_BIT)value << 32) >> 32);
22084865Sobrien
22184865Sobrien  --value;
22284865Sobrien  return ins_imms_scaled (self, value, code, 0);
22384865Sobrien}
22484865Sobrien
22584865Sobrienstatic const char*
22684865Sobrienext_immsm1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
22784865Sobrien{
22884865Sobrien  const char *res = ext_imms_scaled (self, code, valuep, 0);
22984865Sobrien
23084865Sobrien  ++*valuep;
23184865Sobrien  return res;
23284865Sobrien}
23384865Sobrien
23484865Sobrienstatic const char*
23584865Sobrienins_imms1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
23684865Sobrien{
23784865Sobrien  return ins_imms_scaled (self, value, code, 1);
23884865Sobrien}
23984865Sobrien
24084865Sobrienstatic const char*
24184865Sobrienext_imms1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
24284865Sobrien{
24384865Sobrien  return ext_imms_scaled (self, code, valuep, 1);
24484865Sobrien}
24584865Sobrien
24684865Sobrienstatic const char*
24784865Sobrienins_imms4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
24884865Sobrien{
24984865Sobrien  return ins_imms_scaled (self, value, code, 4);
25084865Sobrien}
25184865Sobrien
25284865Sobrienstatic const char*
25384865Sobrienext_imms4 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
25484865Sobrien{
25584865Sobrien  return ext_imms_scaled (self, code, valuep, 4);
25684865Sobrien}
25784865Sobrien
25884865Sobrienstatic const char*
25984865Sobrienins_imms16 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
26084865Sobrien{
26184865Sobrien  return ins_imms_scaled (self, value, code, 16);
26284865Sobrien}
26384865Sobrien
26484865Sobrienstatic const char*
26584865Sobrienext_imms16 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
26684865Sobrien{
26784865Sobrien  return ext_imms_scaled (self, code, valuep, 16);
26884865Sobrien}
26984865Sobrien
27084865Sobrienstatic const char*
27184865Sobrienins_cimmu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
27284865Sobrien{
27384865Sobrien  ia64_insn mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
27484865Sobrien  return ins_immu (self, value ^ mask, code);
27584865Sobrien}
27684865Sobrien
27784865Sobrienstatic const char*
27884865Sobrienext_cimmu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
27984865Sobrien{
28084865Sobrien  const char *result;
28184865Sobrien  ia64_insn mask;
28284865Sobrien
28384865Sobrien  mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
28484865Sobrien  result = ext_immu (self, code, valuep);
28584865Sobrien  if (!result)
28684865Sobrien    {
28784865Sobrien      mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
28884865Sobrien      *valuep ^= mask;
28984865Sobrien    }
29084865Sobrien  return result;
29184865Sobrien}
29284865Sobrien
29384865Sobrienstatic const char*
29484865Sobrienins_cnt (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
29584865Sobrien{
29684865Sobrien  --value;
29784865Sobrien  if (value >= ((BFD_HOST_U_64_BIT) 1) << self->field[0].bits)
29884865Sobrien    return "count out of range";
29984865Sobrien
30084865Sobrien  *code |= value << self->field[0].shift;
30184865Sobrien  return 0;
30284865Sobrien}
30384865Sobrien
30484865Sobrienstatic const char*
30584865Sobrienext_cnt (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
30684865Sobrien{
30784865Sobrien  *valuep = ((code >> self->field[0].shift)
30884865Sobrien	     & ((((BFD_HOST_U_64_BIT) 1) << self->field[0].bits) - 1)) + 1;
30984865Sobrien  return 0;
31084865Sobrien}
31184865Sobrien
31284865Sobrienstatic const char*
31384865Sobrienins_cnt2b (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
31484865Sobrien{
31584865Sobrien  --value;
31684865Sobrien
31784865Sobrien  if (value > 2)
31884865Sobrien    return "count must be in range 1..3";
31984865Sobrien
32084865Sobrien  *code |= value << self->field[0].shift;
32184865Sobrien  return 0;
32284865Sobrien}
32384865Sobrien
32484865Sobrienstatic const char*
32584865Sobrienext_cnt2b (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
32684865Sobrien{
32784865Sobrien  *valuep = ((code >> self->field[0].shift) & 0x3) + 1;
32884865Sobrien  return 0;
32984865Sobrien}
33084865Sobrien
33184865Sobrienstatic const char*
33284865Sobrienins_cnt2c (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
33384865Sobrien{
33484865Sobrien  switch (value)
33584865Sobrien    {
33684865Sobrien    case 0:	value = 0; break;
33784865Sobrien    case 7:	value = 1; break;
33884865Sobrien    case 15:	value = 2; break;
33984865Sobrien    case 16:	value = 3; break;
34084865Sobrien    default:	return "count must be 0, 7, 15, or 16";
34184865Sobrien    }
34284865Sobrien  *code |= value << self->field[0].shift;
34384865Sobrien  return 0;
34484865Sobrien}
34584865Sobrien
34684865Sobrienstatic const char*
34784865Sobrienext_cnt2c (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
34884865Sobrien{
34984865Sobrien  ia64_insn value;
35084865Sobrien
35184865Sobrien  value = (code >> self->field[0].shift) & 0x3;
35284865Sobrien  switch (value)
35384865Sobrien    {
35484865Sobrien    case 0: value =  0; break;
35584865Sobrien    case 1: value =  7; break;
35684865Sobrien    case 2: value = 15; break;
35784865Sobrien    case 3: value = 16; break;
35884865Sobrien    }
35984865Sobrien  *valuep = value;
36084865Sobrien  return 0;
36184865Sobrien}
36284865Sobrien
36384865Sobrienstatic const char*
36484865Sobrienins_inc3 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
36584865Sobrien{
36684865Sobrien  BFD_HOST_64_BIT val = value;
36784865Sobrien  BFD_HOST_U_64_BIT sign = 0;
36884865Sobrien
36984865Sobrien  if (val < 0)
37084865Sobrien    {
37184865Sobrien      sign = 0x4;
37284865Sobrien      value = -value;
37384865Sobrien    }
37484865Sobrien  switch (value)
37584865Sobrien    {
37684865Sobrien    case  1:	value = 3; break;
37784865Sobrien    case  4:	value = 2; break;
37884865Sobrien    case  8:	value = 1; break;
37984865Sobrien    case 16:	value = 0; break;
38084865Sobrien    default:	return "count must be +/- 1, 4, 8, or 16";
38184865Sobrien    }
38284865Sobrien  *code |= (sign | value) << self->field[0].shift;
38384865Sobrien  return 0;
38484865Sobrien}
38584865Sobrien
38684865Sobrienstatic const char*
38784865Sobrienext_inc3 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
38884865Sobrien{
38984865Sobrien  BFD_HOST_64_BIT val;
39084865Sobrien  int negate;
39184865Sobrien
39284865Sobrien  val = (code >> self->field[0].shift) & 0x7;
39384865Sobrien  negate = val & 0x4;
39484865Sobrien  switch (val & 0x3)
39584865Sobrien    {
39684865Sobrien    case 0: val = 16; break;
39784865Sobrien    case 1: val =  8; break;
39884865Sobrien    case 2: val =  4; break;
39984865Sobrien    case 3: val =  1; break;
40084865Sobrien    }
40184865Sobrien  if (negate)
40284865Sobrien    val = -val;
40384865Sobrien
40484865Sobrien  *valuep = val;
40584865Sobrien  return 0;
40684865Sobrien}
40784865Sobrien
40884865Sobrien#define CST	IA64_OPND_CLASS_CST
40984865Sobrien#define REG	IA64_OPND_CLASS_REG
41084865Sobrien#define IND	IA64_OPND_CLASS_IND
41184865Sobrien#define ABS	IA64_OPND_CLASS_ABS
41284865Sobrien#define REL	IA64_OPND_CLASS_REL
41384865Sobrien
41484865Sobrien#define SDEC	IA64_OPND_FLAG_DECIMAL_SIGNED
41584865Sobrien#define UDEC	IA64_OPND_FLAG_DECIMAL_UNSIGNED
41684865Sobrien
41784865Sobrienconst struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] =
41884865Sobrien  {
41984865Sobrien    /* constants: */
42084865Sobrien    { CST, ins_const, ext_const, "NIL",		{{ 0, 0}}, 0, "<none>" },
42184865Sobrien    { CST, ins_const, ext_const, "ar.ccv",	{{ 0, 0}}, 0, "ar.ccv" },
42284865Sobrien    { CST, ins_const, ext_const, "ar.pfs",	{{ 0, 0}}, 0, "ar.pfs" },
42384865Sobrien    { CST, ins_const, ext_const, "1",		{{ 0, 0}}, 0, "1" },
42484865Sobrien    { CST, ins_const, ext_const, "8",		{{ 0, 0}}, 0, "8" },
42584865Sobrien    { CST, ins_const, ext_const, "16",		{{ 0, 0}}, 0, "16" },
42684865Sobrien    { CST, ins_const, ext_const, "r0",		{{ 0, 0}}, 0, "r0" },
42784865Sobrien    { CST, ins_const, ext_const, "ip",		{{ 0, 0}}, 0, "ip" },
42884865Sobrien    { CST, ins_const, ext_const, "pr",		{{ 0, 0}}, 0, "pr" },
42984865Sobrien    { CST, ins_const, ext_const, "pr.rot",	{{ 0, 0}}, 0, "pr.rot" },
43084865Sobrien    { CST, ins_const, ext_const, "psr",		{{ 0, 0}}, 0, "psr" },
43184865Sobrien    { CST, ins_const, ext_const, "psr.l",	{{ 0, 0}}, 0, "psr.l" },
43284865Sobrien    { CST, ins_const, ext_const, "psr.um",	{{ 0, 0}}, 0, "psr.um" },
43384865Sobrien
43484865Sobrien    /* register operands: */
43584865Sobrien    { REG, ins_reg,   ext_reg,	"ar", {{ 7, 20}}, 0,		/* AR3 */
43684865Sobrien      "an application register" },
43784865Sobrien    { REG, ins_reg,   ext_reg,	 "b", {{ 3,  6}}, 0,		/* B1 */
43884865Sobrien      "a branch register" },
43984865Sobrien    { REG, ins_reg,   ext_reg,	 "b", {{ 3, 13}}, 0,		/* B2 */
44084865Sobrien      "a branch register"},
44184865Sobrien    { REG, ins_reg,   ext_reg,	"cr", {{ 7, 20}}, 0,		/* CR */
44284865Sobrien      "a control register"},
44384865Sobrien    { REG, ins_reg,   ext_reg,	 "f", {{ 7,  6}}, 0,		/* F1 */
44484865Sobrien      "a floating-point register" },
44584865Sobrien    { REG, ins_reg,   ext_reg,	 "f", {{ 7, 13}}, 0,		/* F2 */
44684865Sobrien      "a floating-point register" },
44784865Sobrien    { REG, ins_reg,   ext_reg,	 "f", {{ 7, 20}}, 0,		/* F3 */
44884865Sobrien      "a floating-point register" },
44984865Sobrien    { REG, ins_reg,   ext_reg,	 "f", {{ 7, 27}}, 0,		/* F4 */
45084865Sobrien      "a floating-point register" },
45184865Sobrien    { REG, ins_reg,   ext_reg,	 "p", {{ 6,  6}}, 0,		/* P1 */
45284865Sobrien      "a predicate register" },
45384865Sobrien    { REG, ins_reg,   ext_reg,	 "p", {{ 6, 27}}, 0,		/* P2 */
45484865Sobrien      "a predicate register" },
45584865Sobrien    { REG, ins_reg,   ext_reg,	 "r", {{ 7,  6}}, 0,		/* R1 */
45684865Sobrien      "a general register" },
45784865Sobrien    { REG, ins_reg,   ext_reg,	 "r", {{ 7, 13}}, 0,		/* R2 */
45884865Sobrien      "a general register" },
45984865Sobrien    { REG, ins_reg,   ext_reg,	 "r", {{ 7, 20}}, 0,		/* R3 */
46084865Sobrien      "a general register" },
46184865Sobrien    { REG, ins_reg,   ext_reg,	 "r", {{ 2, 20}}, 0,		/* R3_2 */
46284865Sobrien      "a general register r0-r3" },
46384865Sobrien
46484865Sobrien    /* indirect operands: */
46584865Sobrien    { IND, ins_reg,   ext_reg,	"cpuid", {{7, 20}}, 0,		/* CPUID_R3 */
46684865Sobrien      "a cpuid register" },
46784865Sobrien    { IND, ins_reg,   ext_reg,	"dbr",   {{7, 20}}, 0,		/* DBR_R3 */
46884865Sobrien      "a dbr register" },
46984865Sobrien    { IND, ins_reg,   ext_reg,	"dtr",   {{7, 20}}, 0,		/* DTR_R3 */
47084865Sobrien      "a dtr register" },
47184865Sobrien    { IND, ins_reg,   ext_reg,	"itr",   {{7, 20}}, 0,		/* ITR_R3 */
47284865Sobrien      "an itr register" },
47384865Sobrien    { IND, ins_reg,   ext_reg,	"ibr",   {{7, 20}}, 0,		/* IBR_R3 */
47484865Sobrien      "an ibr register" },
47584865Sobrien    { IND, ins_reg,   ext_reg,	"",      {{7, 20}}, 0,		/* MR3 */
47684865Sobrien      "an indirect memory address" },
47784865Sobrien    { IND, ins_reg,   ext_reg,	"msr",   {{7, 20}}, 0,		/* MSR_R3 */
47884865Sobrien      "an msr register" },
47984865Sobrien    { IND, ins_reg,   ext_reg,	"pkr",   {{7, 20}}, 0,		/* PKR_R3 */
48084865Sobrien      "a pkr register" },
48184865Sobrien    { IND, ins_reg,   ext_reg,	"pmc",   {{7, 20}}, 0,		/* PMC_R3 */
48284865Sobrien      "a pmc register" },
48384865Sobrien    { IND, ins_reg,   ext_reg,	"pmd",   {{7, 20}}, 0,		/* PMD_R3 */
48484865Sobrien      "a pmd register" },
48584865Sobrien    { IND, ins_reg,   ext_reg,	"rr",    {{7, 20}}, 0,		/* RR_R3 */
48684865Sobrien      "an rr register" },
48784865Sobrien
48884865Sobrien    /* immediate operands: */
48984865Sobrien    { ABS, ins_cimmu, ext_cimmu, 0, {{ 5, 20 }}, UDEC,		/* CCNT5 */
49084865Sobrien      "a 5-bit count (0-31)" },
49184865Sobrien    { ABS, ins_cnt,   ext_cnt,   0, {{ 2, 27 }}, UDEC,		/* CNT2a */
49284865Sobrien      "a 2-bit count (1-4)" },
49384865Sobrien    { ABS, ins_cnt2b, ext_cnt2b, 0, {{ 2, 27 }}, UDEC,		/* CNT2b */
49484865Sobrien      "a 2-bit count (1-3)" },
49584865Sobrien    { ABS, ins_cnt2c, ext_cnt2c, 0, {{ 2, 30 }}, UDEC,		/* CNT2c */
49684865Sobrien      "a count (0, 7, 15, or 16)" },
49784865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 5, 14}}, UDEC,		/* CNT5 */
49884865Sobrien      "a 5-bit count (0-31)" },
49984865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 6, 27}}, UDEC,		/* CNT6 */
50084865Sobrien      "a 6-bit count (0-63)" },
50184865Sobrien    { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 20}}, UDEC,		/* CPOS6a */
50284865Sobrien      "a 6-bit bit pos (0-63)" },
50384865Sobrien    { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 14}}, UDEC,		/* CPOS6b */
50484865Sobrien      "a 6-bit bit pos (0-63)" },
50584865Sobrien    { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 31}}, UDEC,		/* CPOS6c */
50684865Sobrien      "a 6-bit bit pos (0-63)" },
50784865Sobrien    { ABS, ins_imms,  ext_imms,  0, {{ 1, 36}}, SDEC,		/* IMM1 */
50884865Sobrien      "a 1-bit integer (-1, 0)" },
50984865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 2, 13}}, UDEC,		/* IMMU2 */
51084865Sobrien      "a 2-bit unsigned (0-3)" },
51184865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 7, 13}}, 0,		/* IMMU7a */
51284865Sobrien      "a 7-bit unsigned (0-127)" },
51384865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 7, 20}}, 0,		/* IMMU7b */
51484865Sobrien      "a 7-bit unsigned (0-127)" },
51584865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 7, 13}}, UDEC,		/* SOF */
51684865Sobrien      "a frame size (register count)" },
51784865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 7, 20}}, UDEC,		/* SOL */
51884865Sobrien      "a local register count" },
51984865Sobrien    { ABS, ins_immus8,ext_immus8,0, {{ 4, 27}}, UDEC,		/* SOR */
52084865Sobrien      "a rotating register count (integer multiple of 8)" },
52184865Sobrien    { ABS, ins_imms,  ext_imms,  0,				/* IMM8 */
52284865Sobrien      {{ 7, 13}, { 1, 36}}, SDEC,
52384865Sobrien      "an 8-bit integer (-128-127)" },
52484865Sobrien    { ABS, ins_immsu4,  ext_imms,  0,				/* IMM8U4 */
52584865Sobrien      {{ 7, 13}, { 1, 36}}, SDEC,
52684865Sobrien      "an 8-bit signed integer for 32-bit unsigned compare (-128-127)" },
52784865Sobrien    { ABS, ins_immsm1,  ext_immsm1,  0,				/* IMM8M1 */
52884865Sobrien      {{ 7, 13}, { 1, 36}}, SDEC,
52984865Sobrien      "an 8-bit integer (-127-128)" },
53084865Sobrien    { ABS, ins_immsm1u4,  ext_immsm1,  0,			/* IMM8M1U4 */
53184865Sobrien      {{ 7, 13}, { 1, 36}}, SDEC,
53284865Sobrien      "an 8-bit integer for 32-bit unsigned compare (-127-(-1),1-128,0x100000000)" },
53384865Sobrien    { ABS, ins_immsm1,  ext_immsm1,  0,				/* IMM8M1U8 */
53484865Sobrien      {{ 7, 13}, { 1, 36}}, SDEC,
53584865Sobrien      "an 8-bit integer for 64-bit unsigned compare (-127-(-1),1-128,0x10000000000000000)" },
53684865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 2, 33}, { 7, 20}}, 0,	/* IMMU9 */
53784865Sobrien      "a 9-bit unsigned (0-511)" },
53884865Sobrien    { ABS, ins_imms,  ext_imms,  0,				/* IMM9a */
53984865Sobrien      {{ 7,  6}, { 1, 27}, { 1, 36}}, SDEC,
54084865Sobrien      "a 9-bit integer (-256-255)" },
54184865Sobrien    { ABS, ins_imms,  ext_imms, 0,				/* IMM9b */
54284865Sobrien      {{ 7, 13}, { 1, 27}, { 1, 36}}, SDEC,
54384865Sobrien      "a 9-bit integer (-256-255)" },
54484865Sobrien    { ABS, ins_imms,  ext_imms, 0,				/* IMM14 */
54584865Sobrien      {{ 7, 13}, { 6, 27}, { 1, 36}}, SDEC,
54684865Sobrien      "a 14-bit integer (-8192-8191)" },
54784865Sobrien    { ABS, ins_imms1, ext_imms1, 0,				/* IMM17 */
54884865Sobrien      {{ 7,  6}, { 8, 24}, { 1, 36}}, 0,
54984865Sobrien      "a 17-bit integer (-65536-65535)" },
55084865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{20,  6}, { 1, 36}}, 0,	/* IMMU21 */
55184865Sobrien      "a 21-bit unsigned" },
55284865Sobrien    { ABS, ins_imms,  ext_imms,  0,				/* IMM22 */
55384865Sobrien      {{ 7, 13}, { 9, 27}, { 5, 22}, { 1, 36}}, SDEC,
55484865Sobrien      "a 22-bit signed integer" },
55584865Sobrien    { ABS, ins_immu,  ext_immu,  0,				/* IMMU24 */
55684865Sobrien      {{21,  6}, { 2, 31}, { 1, 36}}, 0,
55784865Sobrien      "a 24-bit unsigned" },
55884865Sobrien    { ABS, ins_imms16,ext_imms16,0, {{27,  6}, { 1, 36}}, 0,	/* IMM44 */
55984865Sobrien      "a 44-bit unsigned (least 16 bits ignored/zeroes)" },
56084865Sobrien    { ABS, ins_rsvd,  ext_rsvd,	0, {{0,  0}}, 0,		/* IMMU62 */
56184865Sobrien      "a 62-bit unsigned" },
56284865Sobrien    { ABS, ins_rsvd,  ext_rsvd,	0, {{0,  0}}, 0,		/* IMMU64 */
56384865Sobrien      "a 64-bit unsigned" },
56484865Sobrien    { ABS, ins_inc3,  ext_inc3,  0, {{ 3, 13}}, SDEC,		/* INC3 */
56584865Sobrien      "an increment (+/- 1, 4, 8, or 16)" },
56684865Sobrien    { ABS, ins_cnt,   ext_cnt,   0, {{ 4, 27}}, UDEC,		/* LEN4 */
56784865Sobrien      "a 4-bit length (1-16)" },
56884865Sobrien    { ABS, ins_cnt,   ext_cnt,   0, {{ 6, 27}}, UDEC,		/* LEN6 */
56984865Sobrien      "a 6-bit length (1-64)" },
57084865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 4, 20}},	0,		/* MBTYPE4 */
57184865Sobrien      "a mix type (@rev, @mix, @shuf, @alt, or @brcst)" },
57284865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 8, 20}},	0,		/* MBTYPE8 */
57384865Sobrien      "an 8-bit mix type" },
57484865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 6, 14}}, UDEC,		/* POS6 */
57584865Sobrien      "a 6-bit bit pos (0-63)" },
57684865Sobrien    { REL, ins_imms4, ext_imms4, 0, {{ 7,  6}, { 2, 33}}, 0,	/* TAG13 */
57784865Sobrien      "a branch tag" },
57884865Sobrien    { REL, ins_imms4, ext_imms4, 0, {{ 9, 24}}, 0,		/* TAG13b */
57984865Sobrien      "a branch tag" },
58084865Sobrien    { REL, ins_imms4, ext_imms4, 0, {{20,  6}, { 1, 36}}, 0,	/* TGT25 */
58184865Sobrien      "a branch target" },
58284865Sobrien    { REL, ins_imms4, ext_imms4, 0,				/* TGT25b */
58384865Sobrien      {{ 7,  6}, {13, 20}, { 1, 36}}, 0,
58484865Sobrien      "a branch target" },
58584865Sobrien    { REL, ins_imms4, ext_imms4, 0, {{20, 13}, { 1, 36}}, 0,	/* TGT25c */
58684865Sobrien      "a branch target" },
58784865Sobrien    { REL, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0,                  /* TGT64  */
58884865Sobrien      "a branch target" },
58984865Sobrien  };
590