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