1218822Sdim/* Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006
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
19218822SdimFoundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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*
117218822Sdimins_immu5b (const struct ia64_operand *self, ia64_insn value,
118218822Sdim	    ia64_insn *code)
119218822Sdim{
120218822Sdim  if (value < 32 || value > 63)
121218822Sdim    return "value must be between 32 and 63";
122218822Sdim  return ins_immu (self, value - 32, code);
123218822Sdim}
124218822Sdim
125218822Sdimstatic const char*
126218822Sdimext_immu5b (const struct ia64_operand *self, ia64_insn code,
127218822Sdim	    ia64_insn *valuep)
128218822Sdim{
129218822Sdim  const char *result;
130218822Sdim
131218822Sdim  result = ext_immu (self, code, valuep);
132218822Sdim  if (result)
133218822Sdim    return result;
134218822Sdim
135218822Sdim  *valuep = *valuep + 32;
136218822Sdim  return 0;
137218822Sdim}
138218822Sdim
139218822Sdimstatic const char*
14084865Sobrienins_immus8 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
14184865Sobrien{
14284865Sobrien  if (value & 0x7)
14384865Sobrien    return "value not an integer multiple of 8";
14484865Sobrien  return ins_immu (self, value >> 3, code);
14584865Sobrien}
14684865Sobrien
14784865Sobrienstatic const char*
14884865Sobrienext_immus8 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
14984865Sobrien{
15084865Sobrien  const char *result;
15184865Sobrien
15284865Sobrien  result = ext_immu (self, code, valuep);
15384865Sobrien  if (result)
15484865Sobrien    return result;
15584865Sobrien
15684865Sobrien  *valuep = *valuep << 3;
15784865Sobrien  return 0;
15884865Sobrien}
15984865Sobrien
16084865Sobrienstatic const char*
16184865Sobrienins_imms_scaled (const struct ia64_operand *self, ia64_insn value,
16284865Sobrien		 ia64_insn *code, int scale)
16384865Sobrien{
16484865Sobrien  BFD_HOST_64_BIT svalue = value, sign_bit = 0;
16584865Sobrien  ia64_insn new = 0;
16684865Sobrien  int i;
16784865Sobrien
16884865Sobrien  svalue >>= scale;
16984865Sobrien
17084865Sobrien  for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
17184865Sobrien    {
17284865Sobrien      new |= ((svalue & ((((ia64_insn) 1) << self->field[i].bits) - 1))
17384865Sobrien	      << self->field[i].shift);
17484865Sobrien      sign_bit = (svalue >> (self->field[i].bits - 1)) & 1;
17584865Sobrien      svalue >>= self->field[i].bits;
17684865Sobrien    }
17784865Sobrien  if ((!sign_bit && svalue != 0) || (sign_bit && svalue != -1))
17884865Sobrien    return "integer operand out of range";
17984865Sobrien
18084865Sobrien  *code |= new;
18184865Sobrien  return 0;
18284865Sobrien}
18384865Sobrien
18484865Sobrienstatic const char*
18584865Sobrienext_imms_scaled (const struct ia64_operand *self, ia64_insn code,
18684865Sobrien		 ia64_insn *valuep, int scale)
18784865Sobrien{
188130561Sobrien  int i, bits = 0, total = 0;
189130561Sobrien  BFD_HOST_64_BIT val = 0, sign;
19084865Sobrien
19184865Sobrien  for (i = 0; i < NELEMS (self->field) && self->field[i].bits; ++i)
19284865Sobrien    {
19384865Sobrien      bits = self->field[i].bits;
19484865Sobrien      val |= ((code >> self->field[i].shift)
19584865Sobrien	      & ((((BFD_HOST_U_64_BIT) 1) << bits) - 1)) << total;
19684865Sobrien      total += bits;
19784865Sobrien    }
19884865Sobrien  /* sign extend: */
199130561Sobrien  sign = (BFD_HOST_64_BIT) 1 << (total - 1);
200130561Sobrien  val = (val ^ sign) - sign;
20184865Sobrien
20284865Sobrien  *valuep = (val << scale);
20384865Sobrien  return 0;
20484865Sobrien}
20584865Sobrien
20684865Sobrienstatic const char*
20784865Sobrienins_imms (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
20884865Sobrien{
20984865Sobrien  return ins_imms_scaled (self, value, code, 0);
21084865Sobrien}
21184865Sobrien
21284865Sobrienstatic const char*
21384865Sobrienins_immsu4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
21484865Sobrien{
215130561Sobrien  value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
21684865Sobrien
21784865Sobrien  return ins_imms_scaled (self, value, code, 0);
21884865Sobrien}
21984865Sobrien
22084865Sobrienstatic const char*
22184865Sobrienext_imms (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
22284865Sobrien{
22384865Sobrien  return ext_imms_scaled (self, code, valuep, 0);
22484865Sobrien}
22584865Sobrien
22684865Sobrienstatic const char*
22784865Sobrienins_immsm1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
22884865Sobrien{
22984865Sobrien  --value;
23084865Sobrien  return ins_imms_scaled (self, value, code, 0);
23184865Sobrien}
23284865Sobrien
23384865Sobrienstatic const char*
23484865Sobrienins_immsm1u4 (const struct ia64_operand *self, ia64_insn value,
23584865Sobrien	      ia64_insn *code)
23684865Sobrien{
237130561Sobrien  value = ((value & 0xffffffff) ^ 0x80000000) - 0x80000000;
23884865Sobrien
23984865Sobrien  --value;
24084865Sobrien  return ins_imms_scaled (self, value, code, 0);
24184865Sobrien}
24284865Sobrien
24384865Sobrienstatic const char*
24484865Sobrienext_immsm1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
24584865Sobrien{
24684865Sobrien  const char *res = ext_imms_scaled (self, code, valuep, 0);
24784865Sobrien
24884865Sobrien  ++*valuep;
24984865Sobrien  return res;
25084865Sobrien}
25184865Sobrien
25284865Sobrienstatic const char*
25384865Sobrienins_imms1 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
25484865Sobrien{
25584865Sobrien  return ins_imms_scaled (self, value, code, 1);
25684865Sobrien}
25784865Sobrien
25884865Sobrienstatic const char*
25984865Sobrienext_imms1 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
26084865Sobrien{
26184865Sobrien  return ext_imms_scaled (self, code, valuep, 1);
26284865Sobrien}
26384865Sobrien
26484865Sobrienstatic const char*
26584865Sobrienins_imms4 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
26684865Sobrien{
26784865Sobrien  return ins_imms_scaled (self, value, code, 4);
26884865Sobrien}
26984865Sobrien
27084865Sobrienstatic const char*
27184865Sobrienext_imms4 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
27284865Sobrien{
27384865Sobrien  return ext_imms_scaled (self, code, valuep, 4);
27484865Sobrien}
27584865Sobrien
27684865Sobrienstatic const char*
27784865Sobrienins_imms16 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
27884865Sobrien{
27984865Sobrien  return ins_imms_scaled (self, value, code, 16);
28084865Sobrien}
28184865Sobrien
28284865Sobrienstatic const char*
28384865Sobrienext_imms16 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
28484865Sobrien{
28584865Sobrien  return ext_imms_scaled (self, code, valuep, 16);
28684865Sobrien}
28784865Sobrien
28884865Sobrienstatic const char*
28984865Sobrienins_cimmu (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
29084865Sobrien{
29184865Sobrien  ia64_insn mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
29284865Sobrien  return ins_immu (self, value ^ mask, code);
29384865Sobrien}
29484865Sobrien
29584865Sobrienstatic const char*
29684865Sobrienext_cimmu (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
29784865Sobrien{
29884865Sobrien  const char *result;
29984865Sobrien  ia64_insn mask;
30084865Sobrien
30184865Sobrien  mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
30284865Sobrien  result = ext_immu (self, code, valuep);
30384865Sobrien  if (!result)
30484865Sobrien    {
30584865Sobrien      mask = (((ia64_insn) 1) << self->field[0].bits) - 1;
30684865Sobrien      *valuep ^= mask;
30784865Sobrien    }
30884865Sobrien  return result;
30984865Sobrien}
31084865Sobrien
31184865Sobrienstatic const char*
31284865Sobrienins_cnt (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
31384865Sobrien{
31484865Sobrien  --value;
31584865Sobrien  if (value >= ((BFD_HOST_U_64_BIT) 1) << self->field[0].bits)
31684865Sobrien    return "count out of range";
31784865Sobrien
31884865Sobrien  *code |= value << self->field[0].shift;
31984865Sobrien  return 0;
32084865Sobrien}
32184865Sobrien
32284865Sobrienstatic const char*
32384865Sobrienext_cnt (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
32484865Sobrien{
32584865Sobrien  *valuep = ((code >> self->field[0].shift)
32684865Sobrien	     & ((((BFD_HOST_U_64_BIT) 1) << self->field[0].bits) - 1)) + 1;
32784865Sobrien  return 0;
32884865Sobrien}
32984865Sobrien
33084865Sobrienstatic const char*
33184865Sobrienins_cnt2b (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
33284865Sobrien{
33384865Sobrien  --value;
33484865Sobrien
33584865Sobrien  if (value > 2)
33684865Sobrien    return "count must be in range 1..3";
33784865Sobrien
33884865Sobrien  *code |= value << self->field[0].shift;
33984865Sobrien  return 0;
34084865Sobrien}
34184865Sobrien
34284865Sobrienstatic const char*
34384865Sobrienext_cnt2b (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
34484865Sobrien{
34584865Sobrien  *valuep = ((code >> self->field[0].shift) & 0x3) + 1;
34684865Sobrien  return 0;
34784865Sobrien}
34884865Sobrien
34984865Sobrienstatic const char*
35084865Sobrienins_cnt2c (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
35184865Sobrien{
35284865Sobrien  switch (value)
35384865Sobrien    {
35484865Sobrien    case 0:	value = 0; break;
35584865Sobrien    case 7:	value = 1; break;
35684865Sobrien    case 15:	value = 2; break;
35784865Sobrien    case 16:	value = 3; break;
35884865Sobrien    default:	return "count must be 0, 7, 15, or 16";
35984865Sobrien    }
36084865Sobrien  *code |= value << self->field[0].shift;
36184865Sobrien  return 0;
36284865Sobrien}
36384865Sobrien
36484865Sobrienstatic const char*
36584865Sobrienext_cnt2c (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
36684865Sobrien{
36784865Sobrien  ia64_insn value;
36884865Sobrien
36984865Sobrien  value = (code >> self->field[0].shift) & 0x3;
37084865Sobrien  switch (value)
37184865Sobrien    {
37284865Sobrien    case 0: value =  0; break;
37384865Sobrien    case 1: value =  7; break;
37484865Sobrien    case 2: value = 15; break;
37584865Sobrien    case 3: value = 16; break;
37684865Sobrien    }
37784865Sobrien  *valuep = value;
37884865Sobrien  return 0;
37984865Sobrien}
38084865Sobrien
38184865Sobrienstatic const char*
38284865Sobrienins_inc3 (const struct ia64_operand *self, ia64_insn value, ia64_insn *code)
38384865Sobrien{
38484865Sobrien  BFD_HOST_64_BIT val = value;
38584865Sobrien  BFD_HOST_U_64_BIT sign = 0;
38684865Sobrien
38784865Sobrien  if (val < 0)
38884865Sobrien    {
38984865Sobrien      sign = 0x4;
39084865Sobrien      value = -value;
39184865Sobrien    }
39284865Sobrien  switch (value)
39384865Sobrien    {
39484865Sobrien    case  1:	value = 3; break;
39584865Sobrien    case  4:	value = 2; break;
39684865Sobrien    case  8:	value = 1; break;
39784865Sobrien    case 16:	value = 0; break;
39884865Sobrien    default:	return "count must be +/- 1, 4, 8, or 16";
39984865Sobrien    }
40084865Sobrien  *code |= (sign | value) << self->field[0].shift;
40184865Sobrien  return 0;
40284865Sobrien}
40384865Sobrien
40484865Sobrienstatic const char*
40584865Sobrienext_inc3 (const struct ia64_operand *self, ia64_insn code, ia64_insn *valuep)
40684865Sobrien{
40784865Sobrien  BFD_HOST_64_BIT val;
40884865Sobrien  int negate;
40984865Sobrien
41084865Sobrien  val = (code >> self->field[0].shift) & 0x7;
41184865Sobrien  negate = val & 0x4;
41284865Sobrien  switch (val & 0x3)
41384865Sobrien    {
41484865Sobrien    case 0: val = 16; break;
41584865Sobrien    case 1: val =  8; break;
41684865Sobrien    case 2: val =  4; break;
41784865Sobrien    case 3: val =  1; break;
41884865Sobrien    }
41984865Sobrien  if (negate)
42084865Sobrien    val = -val;
42184865Sobrien
42284865Sobrien  *valuep = val;
42384865Sobrien  return 0;
42484865Sobrien}
42584865Sobrien
42684865Sobrien#define CST	IA64_OPND_CLASS_CST
42784865Sobrien#define REG	IA64_OPND_CLASS_REG
42884865Sobrien#define IND	IA64_OPND_CLASS_IND
42984865Sobrien#define ABS	IA64_OPND_CLASS_ABS
43084865Sobrien#define REL	IA64_OPND_CLASS_REL
43184865Sobrien
43284865Sobrien#define SDEC	IA64_OPND_FLAG_DECIMAL_SIGNED
43384865Sobrien#define UDEC	IA64_OPND_FLAG_DECIMAL_UNSIGNED
43484865Sobrien
43584865Sobrienconst struct ia64_operand elf64_ia64_operands[IA64_OPND_COUNT] =
43684865Sobrien  {
43784865Sobrien    /* constants: */
43884865Sobrien    { CST, ins_const, ext_const, "NIL",		{{ 0, 0}}, 0, "<none>" },
439130561Sobrien    { CST, ins_const, ext_const, "ar.csd",	{{ 0, 0}}, 0, "ar.csd" },
44084865Sobrien    { CST, ins_const, ext_const, "ar.ccv",	{{ 0, 0}}, 0, "ar.ccv" },
44184865Sobrien    { CST, ins_const, ext_const, "ar.pfs",	{{ 0, 0}}, 0, "ar.pfs" },
44284865Sobrien    { CST, ins_const, ext_const, "1",		{{ 0, 0}}, 0, "1" },
44384865Sobrien    { CST, ins_const, ext_const, "8",		{{ 0, 0}}, 0, "8" },
44484865Sobrien    { CST, ins_const, ext_const, "16",		{{ 0, 0}}, 0, "16" },
44584865Sobrien    { CST, ins_const, ext_const, "r0",		{{ 0, 0}}, 0, "r0" },
44684865Sobrien    { CST, ins_const, ext_const, "ip",		{{ 0, 0}}, 0, "ip" },
44784865Sobrien    { CST, ins_const, ext_const, "pr",		{{ 0, 0}}, 0, "pr" },
44884865Sobrien    { CST, ins_const, ext_const, "pr.rot",	{{ 0, 0}}, 0, "pr.rot" },
44984865Sobrien    { CST, ins_const, ext_const, "psr",		{{ 0, 0}}, 0, "psr" },
45084865Sobrien    { CST, ins_const, ext_const, "psr.l",	{{ 0, 0}}, 0, "psr.l" },
45184865Sobrien    { CST, ins_const, ext_const, "psr.um",	{{ 0, 0}}, 0, "psr.um" },
45284865Sobrien
45384865Sobrien    /* register operands: */
45484865Sobrien    { REG, ins_reg,   ext_reg,	"ar", {{ 7, 20}}, 0,		/* AR3 */
45584865Sobrien      "an application register" },
45684865Sobrien    { REG, ins_reg,   ext_reg,	 "b", {{ 3,  6}}, 0,		/* B1 */
45784865Sobrien      "a branch register" },
45884865Sobrien    { REG, ins_reg,   ext_reg,	 "b", {{ 3, 13}}, 0,		/* B2 */
45984865Sobrien      "a branch register"},
46084865Sobrien    { REG, ins_reg,   ext_reg,	"cr", {{ 7, 20}}, 0,		/* CR */
46184865Sobrien      "a control register"},
46284865Sobrien    { REG, ins_reg,   ext_reg,	 "f", {{ 7,  6}}, 0,		/* F1 */
46384865Sobrien      "a floating-point register" },
46484865Sobrien    { REG, ins_reg,   ext_reg,	 "f", {{ 7, 13}}, 0,		/* F2 */
46584865Sobrien      "a floating-point register" },
46684865Sobrien    { REG, ins_reg,   ext_reg,	 "f", {{ 7, 20}}, 0,		/* F3 */
46784865Sobrien      "a floating-point register" },
46884865Sobrien    { REG, ins_reg,   ext_reg,	 "f", {{ 7, 27}}, 0,		/* F4 */
46984865Sobrien      "a floating-point register" },
47084865Sobrien    { REG, ins_reg,   ext_reg,	 "p", {{ 6,  6}}, 0,		/* P1 */
47184865Sobrien      "a predicate register" },
47284865Sobrien    { REG, ins_reg,   ext_reg,	 "p", {{ 6, 27}}, 0,		/* P2 */
47384865Sobrien      "a predicate register" },
47484865Sobrien    { REG, ins_reg,   ext_reg,	 "r", {{ 7,  6}}, 0,		/* R1 */
47584865Sobrien      "a general register" },
47684865Sobrien    { REG, ins_reg,   ext_reg,	 "r", {{ 7, 13}}, 0,		/* R2 */
47784865Sobrien      "a general register" },
47884865Sobrien    { REG, ins_reg,   ext_reg,	 "r", {{ 7, 20}}, 0,		/* R3 */
47984865Sobrien      "a general register" },
48084865Sobrien    { REG, ins_reg,   ext_reg,	 "r", {{ 2, 20}}, 0,		/* R3_2 */
48184865Sobrien      "a general register r0-r3" },
48284865Sobrien
483218822Sdim    /* memory operands: */
484218822Sdim    { IND, ins_reg,   ext_reg,	"",      {{7, 20}}, 0,		/* MR3 */
485218822Sdim      "a memory address" },
486218822Sdim
48784865Sobrien    /* indirect operands: */
48884865Sobrien    { IND, ins_reg,   ext_reg,	"cpuid", {{7, 20}}, 0,		/* CPUID_R3 */
48984865Sobrien      "a cpuid register" },
49084865Sobrien    { IND, ins_reg,   ext_reg,	"dbr",   {{7, 20}}, 0,		/* DBR_R3 */
49184865Sobrien      "a dbr register" },
49284865Sobrien    { IND, ins_reg,   ext_reg,	"dtr",   {{7, 20}}, 0,		/* DTR_R3 */
49384865Sobrien      "a dtr register" },
49484865Sobrien    { IND, ins_reg,   ext_reg,	"itr",   {{7, 20}}, 0,		/* ITR_R3 */
49584865Sobrien      "an itr register" },
49684865Sobrien    { IND, ins_reg,   ext_reg,	"ibr",   {{7, 20}}, 0,		/* IBR_R3 */
49784865Sobrien      "an ibr register" },
49884865Sobrien    { IND, ins_reg,   ext_reg,	"msr",   {{7, 20}}, 0,		/* MSR_R3 */
49984865Sobrien      "an msr register" },
50084865Sobrien    { IND, ins_reg,   ext_reg,	"pkr",   {{7, 20}}, 0,		/* PKR_R3 */
50184865Sobrien      "a pkr register" },
50284865Sobrien    { IND, ins_reg,   ext_reg,	"pmc",   {{7, 20}}, 0,		/* PMC_R3 */
50384865Sobrien      "a pmc register" },
50484865Sobrien    { IND, ins_reg,   ext_reg,	"pmd",   {{7, 20}}, 0,		/* PMD_R3 */
50584865Sobrien      "a pmd register" },
50684865Sobrien    { IND, ins_reg,   ext_reg,	"rr",    {{7, 20}}, 0,		/* RR_R3 */
50784865Sobrien      "an rr register" },
50884865Sobrien
50984865Sobrien    /* immediate operands: */
51084865Sobrien    { ABS, ins_cimmu, ext_cimmu, 0, {{ 5, 20 }}, UDEC,		/* CCNT5 */
51184865Sobrien      "a 5-bit count (0-31)" },
51284865Sobrien    { ABS, ins_cnt,   ext_cnt,   0, {{ 2, 27 }}, UDEC,		/* CNT2a */
51384865Sobrien      "a 2-bit count (1-4)" },
51484865Sobrien    { ABS, ins_cnt2b, ext_cnt2b, 0, {{ 2, 27 }}, UDEC,		/* CNT2b */
51584865Sobrien      "a 2-bit count (1-3)" },
51684865Sobrien    { ABS, ins_cnt2c, ext_cnt2c, 0, {{ 2, 30 }}, UDEC,		/* CNT2c */
51784865Sobrien      "a count (0, 7, 15, or 16)" },
51884865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 5, 14}}, UDEC,		/* CNT5 */
51984865Sobrien      "a 5-bit count (0-31)" },
52084865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 6, 27}}, UDEC,		/* CNT6 */
52184865Sobrien      "a 6-bit count (0-63)" },
52284865Sobrien    { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 20}}, UDEC,		/* CPOS6a */
52384865Sobrien      "a 6-bit bit pos (0-63)" },
52484865Sobrien    { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 14}}, UDEC,		/* CPOS6b */
52584865Sobrien      "a 6-bit bit pos (0-63)" },
52684865Sobrien    { ABS, ins_cimmu, ext_cimmu, 0, {{ 6, 31}}, UDEC,		/* CPOS6c */
52784865Sobrien      "a 6-bit bit pos (0-63)" },
52884865Sobrien    { ABS, ins_imms,  ext_imms,  0, {{ 1, 36}}, SDEC,		/* IMM1 */
52984865Sobrien      "a 1-bit integer (-1, 0)" },
53084865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 2, 13}}, UDEC,		/* IMMU2 */
53184865Sobrien      "a 2-bit unsigned (0-3)" },
532218822Sdim    { ABS, ins_immu5b,  ext_immu5b,  0, {{ 5, 14}}, UDEC,	/* IMMU5b */
533218822Sdim      "a 5-bit unsigned (32 + (0-31))" },
53484865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 7, 13}}, 0,		/* IMMU7a */
53584865Sobrien      "a 7-bit unsigned (0-127)" },
53684865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 7, 20}}, 0,		/* IMMU7b */
53784865Sobrien      "a 7-bit unsigned (0-127)" },
53884865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 7, 13}}, UDEC,		/* SOF */
53984865Sobrien      "a frame size (register count)" },
54084865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 7, 20}}, UDEC,		/* SOL */
54184865Sobrien      "a local register count" },
54284865Sobrien    { ABS, ins_immus8,ext_immus8,0, {{ 4, 27}}, UDEC,		/* SOR */
54384865Sobrien      "a rotating register count (integer multiple of 8)" },
54484865Sobrien    { ABS, ins_imms,  ext_imms,  0,				/* IMM8 */
54584865Sobrien      {{ 7, 13}, { 1, 36}}, SDEC,
54684865Sobrien      "an 8-bit integer (-128-127)" },
54784865Sobrien    { ABS, ins_immsu4,  ext_imms,  0,				/* IMM8U4 */
54884865Sobrien      {{ 7, 13}, { 1, 36}}, SDEC,
54984865Sobrien      "an 8-bit signed integer for 32-bit unsigned compare (-128-127)" },
55084865Sobrien    { ABS, ins_immsm1,  ext_immsm1,  0,				/* IMM8M1 */
55184865Sobrien      {{ 7, 13}, { 1, 36}}, SDEC,
55284865Sobrien      "an 8-bit integer (-127-128)" },
55384865Sobrien    { ABS, ins_immsm1u4,  ext_immsm1,  0,			/* IMM8M1U4 */
55484865Sobrien      {{ 7, 13}, { 1, 36}}, SDEC,
55584865Sobrien      "an 8-bit integer for 32-bit unsigned compare (-127-(-1),1-128,0x100000000)" },
55684865Sobrien    { ABS, ins_immsm1,  ext_immsm1,  0,				/* IMM8M1U8 */
55784865Sobrien      {{ 7, 13}, { 1, 36}}, SDEC,
55884865Sobrien      "an 8-bit integer for 64-bit unsigned compare (-127-(-1),1-128,0x10000000000000000)" },
55984865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 2, 33}, { 7, 20}}, 0,	/* IMMU9 */
56084865Sobrien      "a 9-bit unsigned (0-511)" },
56184865Sobrien    { ABS, ins_imms,  ext_imms,  0,				/* IMM9a */
56284865Sobrien      {{ 7,  6}, { 1, 27}, { 1, 36}}, SDEC,
56384865Sobrien      "a 9-bit integer (-256-255)" },
56484865Sobrien    { ABS, ins_imms,  ext_imms, 0,				/* IMM9b */
56584865Sobrien      {{ 7, 13}, { 1, 27}, { 1, 36}}, SDEC,
56684865Sobrien      "a 9-bit integer (-256-255)" },
56784865Sobrien    { ABS, ins_imms,  ext_imms, 0,				/* IMM14 */
56884865Sobrien      {{ 7, 13}, { 6, 27}, { 1, 36}}, SDEC,
56984865Sobrien      "a 14-bit integer (-8192-8191)" },
57084865Sobrien    { ABS, ins_imms1, ext_imms1, 0,				/* IMM17 */
57184865Sobrien      {{ 7,  6}, { 8, 24}, { 1, 36}}, 0,
57284865Sobrien      "a 17-bit integer (-65536-65535)" },
57384865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{20,  6}, { 1, 36}}, 0,	/* IMMU21 */
57484865Sobrien      "a 21-bit unsigned" },
57584865Sobrien    { ABS, ins_imms,  ext_imms,  0,				/* IMM22 */
57684865Sobrien      {{ 7, 13}, { 9, 27}, { 5, 22}, { 1, 36}}, SDEC,
57784865Sobrien      "a 22-bit signed integer" },
57884865Sobrien    { ABS, ins_immu,  ext_immu,  0,				/* IMMU24 */
57984865Sobrien      {{21,  6}, { 2, 31}, { 1, 36}}, 0,
58084865Sobrien      "a 24-bit unsigned" },
58184865Sobrien    { ABS, ins_imms16,ext_imms16,0, {{27,  6}, { 1, 36}}, 0,	/* IMM44 */
58284865Sobrien      "a 44-bit unsigned (least 16 bits ignored/zeroes)" },
58384865Sobrien    { ABS, ins_rsvd,  ext_rsvd,	0, {{0,  0}}, 0,		/* IMMU62 */
58484865Sobrien      "a 62-bit unsigned" },
58584865Sobrien    { ABS, ins_rsvd,  ext_rsvd,	0, {{0,  0}}, 0,		/* IMMU64 */
58684865Sobrien      "a 64-bit unsigned" },
58784865Sobrien    { ABS, ins_inc3,  ext_inc3,  0, {{ 3, 13}}, SDEC,		/* INC3 */
58884865Sobrien      "an increment (+/- 1, 4, 8, or 16)" },
58984865Sobrien    { ABS, ins_cnt,   ext_cnt,   0, {{ 4, 27}}, UDEC,		/* LEN4 */
59084865Sobrien      "a 4-bit length (1-16)" },
59184865Sobrien    { ABS, ins_cnt,   ext_cnt,   0, {{ 6, 27}}, UDEC,		/* LEN6 */
59284865Sobrien      "a 6-bit length (1-64)" },
59384865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 4, 20}},	0,		/* MBTYPE4 */
59484865Sobrien      "a mix type (@rev, @mix, @shuf, @alt, or @brcst)" },
59584865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 8, 20}},	0,		/* MBTYPE8 */
59684865Sobrien      "an 8-bit mix type" },
59784865Sobrien    { ABS, ins_immu,  ext_immu,  0, {{ 6, 14}}, UDEC,		/* POS6 */
59884865Sobrien      "a 6-bit bit pos (0-63)" },
59984865Sobrien    { REL, ins_imms4, ext_imms4, 0, {{ 7,  6}, { 2, 33}}, 0,	/* TAG13 */
60084865Sobrien      "a branch tag" },
60184865Sobrien    { REL, ins_imms4, ext_imms4, 0, {{ 9, 24}}, 0,		/* TAG13b */
60284865Sobrien      "a branch tag" },
60384865Sobrien    { REL, ins_imms4, ext_imms4, 0, {{20,  6}, { 1, 36}}, 0,	/* TGT25 */
60484865Sobrien      "a branch target" },
60584865Sobrien    { REL, ins_imms4, ext_imms4, 0,				/* TGT25b */
60684865Sobrien      {{ 7,  6}, {13, 20}, { 1, 36}}, 0,
60784865Sobrien      "a branch target" },
60884865Sobrien    { REL, ins_imms4, ext_imms4, 0, {{20, 13}, { 1, 36}}, 0,	/* TGT25c */
60984865Sobrien      "a branch target" },
61084865Sobrien    { REL, ins_rsvd, ext_rsvd, 0, {{0, 0}}, 0,                  /* TGT64  */
61184865Sobrien      "a branch target" },
612130561Sobrien
613130561Sobrien    { ABS, ins_const, ext_const, 0, {{0, 0}}, 0,		/* LDXMOV */
614130561Sobrien      "ldxmov target" },
61584865Sobrien  };
616