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