#include "libiberty.h"
/* ARC NPS400 Support: The ARC NPS400 core is an ARC700 with some custom
- instructions. Support for this target is available when binutils is
- configured and built for the 'arc*-mellanox-*-*' target. As far as
- possible all ARC NPS400 features are built into all ARC target builds as
+ instructions. All NPS400 features are built into all ARC target builds as
this reduces the chances that regressions might creep in. */
/* Insert RB register into a 32-bit opcode. */
extract_rhv1 (unsigned insn ATTRIBUTE_UNUSED,
bfd_boolean * invalid ATTRIBUTE_UNUSED)
{
- int value = 0;
+ int value = ((insn & 0x7) << 3) | ((insn >> 5) & 0x7);
return value;
}
return value;
}
+static unsigned
+insert_nps_3bit_dst_short (unsigned insn ATTRIBUTE_UNUSED,
+ int value ATTRIBUTE_UNUSED,
+ const char **errmsg ATTRIBUTE_UNUSED)
+{
+ switch (value)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ insn |= value << 8;
+ break;
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ insn |= (value - 8) << 8;
+ break;
+ default:
+ *errmsg = _("Register must be either r0-r3 or r12-r15.");
+ break;
+ }
+ return insn;
+}
+
+static int
+extract_nps_3bit_dst_short (unsigned insn ATTRIBUTE_UNUSED,
+ bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+ int value = (insn >> 8) & 0x07;
+ if (value > 3)
+ return (value + 8);
+ else
+ return value;
+}
+
static unsigned
insert_nps_3bit_src2 (unsigned insn ATTRIBUTE_UNUSED,
int value ATTRIBUTE_UNUSED,
return value;
}
+static unsigned
+insert_nps_3bit_src2_short (unsigned insn ATTRIBUTE_UNUSED,
+ int value ATTRIBUTE_UNUSED,
+ const char **errmsg ATTRIBUTE_UNUSED)
+{
+ switch (value)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ insn |= value << 5;
+ break;
+ case 12:
+ case 13:
+ case 14:
+ case 15:
+ insn |= (value - 8) << 5;
+ break;
+ default:
+ *errmsg = _("Register must be either r0-r3 or r12-r15.");
+ break;
+ }
+ return insn;
+}
+
+static int
+extract_nps_3bit_src2_short (unsigned insn ATTRIBUTE_UNUSED,
+ bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+ int value = (insn >> 5) & 0x07;
+ if (value > 3)
+ return (value + 8);
+ else
+ return value;
+}
+
static unsigned
insert_nps_bitop_size_2b (unsigned insn ATTRIBUTE_UNUSED,
int value ATTRIBUTE_UNUSED,
MAKE_SRC_POS_INSERT_EXTRACT_FUNCS (src2, 12)
MAKE_SRC_POS_INSERT_EXTRACT_FUNCS (src1, 10)
-#define MAKE_SIZE_INSERT_EXTRACT_FUNCS(NAME,LOWER,UPPER,BITS,BIAS,SHIFT)\
+#define MAKE_BIAS_INSERT_EXTRACT_FUNCS(NAME,LOWER,UPPER,BITS,BIAS,SHIFT)\
static unsigned \
-insert_nps_##NAME##_size (unsigned insn ATTRIBUTE_UNUSED, \
- int value ATTRIBUTE_UNUSED, \
- const char **errmsg ATTRIBUTE_UNUSED) \
+insert_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED, \
+ int value ATTRIBUTE_UNUSED, \
+ const char **errmsg ATTRIBUTE_UNUSED) \
{ \
- if (value < LOWER || value > 32) \
+ if (value < LOWER || value > UPPER) \
{ \
*errmsg = _("Invalid size, value must be " \
#LOWER " to " #UPPER "."); \
} \
\
static int \
-extract_nps_##NAME##_size (unsigned insn ATTRIBUTE_UNUSED, \
- bfd_boolean * invalid ATTRIBUTE_UNUSED) \
+extract_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED, \
+ bfd_boolean * invalid ATTRIBUTE_UNUSED) \
{ \
return ((insn >> SHIFT) & ((1 << BITS) - 1)) + BIAS; \
}
-MAKE_SIZE_INSERT_EXTRACT_FUNCS(addb,2,32,5,1,5)
-MAKE_SIZE_INSERT_EXTRACT_FUNCS(andb,1,32,5,1,5)
-MAKE_SIZE_INSERT_EXTRACT_FUNCS(fxorb,8,32,5,8,5)
-MAKE_SIZE_INSERT_EXTRACT_FUNCS(wxorb,16,32,5,16,5)
-MAKE_SIZE_INSERT_EXTRACT_FUNCS(bitop,1,32,5,1,10)
-MAKE_SIZE_INSERT_EXTRACT_FUNCS(qcmp,1,8,3,1,9)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (addb_size,2,32,5,1,5)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (andb_size,1,32,5,1,5)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (fxorb_size,8,32,5,8,5)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (wxorb_size,16,32,5,16,5)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (bitop_size,1,32,5,1,10)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (qcmp_size,1,8,3,1,9)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (bitop1_size,1,32,5,1,20)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (bitop2_size,1,32,5,1,25)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (hash_width,1,32,5,1,6)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (hash_len,1,8,3,1,2)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (index3,4,7,2,4,0)
static int
extract_nps_qcmp_m3 (unsigned insn ATTRIBUTE_UNUSED,
return 1 << entry_size;
}
+static unsigned
+insert_nps_bitop_mod4_msb (unsigned insn ATTRIBUTE_UNUSED,
+ int value ATTRIBUTE_UNUSED,
+ const char **errmsg ATTRIBUTE_UNUSED)
+{
+ return insn | ((value & 0x2) << 30);
+}
+
+static int
+extract_nps_bitop_mod4_msb (unsigned insn ATTRIBUTE_UNUSED,
+ bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+ return (insn >> 30) & 0x2;
+}
+
+static unsigned
+insert_nps_bitop_mod4_lsb (unsigned insn ATTRIBUTE_UNUSED,
+ int value ATTRIBUTE_UNUSED,
+ const char **errmsg ATTRIBUTE_UNUSED)
+{
+ return insn | ((value & 0x1) << 15);
+}
+
+static int
+extract_nps_bitop_mod4_lsb (unsigned insn ATTRIBUTE_UNUSED,
+ bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+ return (insn >> 15) & 0x1;
+}
+
+static unsigned
+insert_nps_bitop_dst_pos3_pos4 (unsigned insn ATTRIBUTE_UNUSED,
+ int value ATTRIBUTE_UNUSED,
+ const char **errmsg ATTRIBUTE_UNUSED)
+{
+ return insn | (value << 10) | (value << 5);
+}
+
+static int
+extract_nps_bitop_dst_pos3_pos4 (unsigned insn ATTRIBUTE_UNUSED,
+ bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+ if (((insn >> 10) & 0x1f) != ((insn >> 5) & 0x1f))
+ *invalid = TRUE;
+ return ((insn >> 5) & 0x1f);
+}
+
+static unsigned
+insert_nps_bitop_ins_ext (unsigned insn ATTRIBUTE_UNUSED,
+ int value ATTRIBUTE_UNUSED,
+ const char **errmsg ATTRIBUTE_UNUSED)
+{
+ if (value < 0 || value > 28)
+ *errmsg = _("Value must be in the range 0 to 28");
+ return insn | (value << 20);
+}
+
+static int
+extract_nps_bitop_ins_ext (unsigned insn ATTRIBUTE_UNUSED,
+ bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+ int value = (insn >> 20) & 0x1f;
+ if (value > 28)
+ *invalid = TRUE;
+ return value;
+}
+
+#define MAKE_1BASED_INSERT_EXTRACT_FUNCS(NAME,SHIFT,UPPER,BITS) \
+static unsigned \
+insert_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED, \
+ int value ATTRIBUTE_UNUSED, \
+ const char **errmsg ATTRIBUTE_UNUSED) \
+{ \
+ if (value < 1 || value > UPPER) \
+ *errmsg = _("Value must be in the range 1 to " #UPPER); \
+ if (value == UPPER) \
+ value = 0; \
+ return insn | (value << SHIFT); \
+} \
+ \
+static int \
+extract_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED, \
+ bfd_boolean * invalid ATTRIBUTE_UNUSED) \
+{ \
+ int value = (insn >> SHIFT) & ((1 << BITS) - 1); \
+ if (value == 0) \
+ value = UPPER; \
+ return value; \
+}
+
+MAKE_1BASED_INSERT_EXTRACT_FUNCS (field_size, 6, 8, 3)
+MAKE_1BASED_INSERT_EXTRACT_FUNCS (shift_factor, 9, 8, 3)
+MAKE_1BASED_INSERT_EXTRACT_FUNCS (bits_to_scramble, 12, 8, 3)
+MAKE_1BASED_INSERT_EXTRACT_FUNCS (bdlen_max_len, 5, 256, 8)
+MAKE_1BASED_INSERT_EXTRACT_FUNCS (bd_num_buff, 6, 8, 3)
+MAKE_1BASED_INSERT_EXTRACT_FUNCS (pmu_num_job, 6, 4, 2)
+
+static unsigned
+insert_nps_min_hofs (unsigned insn ATTRIBUTE_UNUSED,
+ int value ATTRIBUTE_UNUSED,
+ const char **errmsg ATTRIBUTE_UNUSED)
+{
+ if (value < 0 || value > 240)
+ *errmsg = _("Value must be in the range 0 to 240");
+ if ((value % 16) != 0)
+ *errmsg = _("Value must be a multiple of 16");
+ value = value / 16;
+ return insn | (value << 6);
+}
+
+static int
+extract_nps_min_hofs (unsigned insn ATTRIBUTE_UNUSED,
+ bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+ int value = (insn >> 6) & 0xF;
+ return value * 16;
+}
+
+#define MAKE_INSERT_NPS_ADDRTYPE(NAME,VALUE) \
+static unsigned \
+insert_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED, \
+ int value ATTRIBUTE_UNUSED, \
+ const char **errmsg ATTRIBUTE_UNUSED) \
+{ \
+ if (value != ARC_NPS400_ADDRTYPE_##VALUE) \
+ *errmsg = _("Invalid address type for operand"); \
+ return insn; \
+} \
+ \
+static int \
+extract_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED, \
+ bfd_boolean * invalid ATTRIBUTE_UNUSED) \
+{ \
+ return ARC_NPS400_ADDRTYPE_##VALUE; \
+}
+
+MAKE_INSERT_NPS_ADDRTYPE (bd, BD)
+MAKE_INSERT_NPS_ADDRTYPE (jid, JID)
+MAKE_INSERT_NPS_ADDRTYPE (lbd, LBD)
+MAKE_INSERT_NPS_ADDRTYPE (mbd, MBD)
+MAKE_INSERT_NPS_ADDRTYPE (sd, SD)
+MAKE_INSERT_NPS_ADDRTYPE (sm, SM)
+MAKE_INSERT_NPS_ADDRTYPE (xa, XA)
+MAKE_INSERT_NPS_ADDRTYPE (xd, XD)
+MAKE_INSERT_NPS_ADDRTYPE (cd, CD)
+MAKE_INSERT_NPS_ADDRTYPE (cbd, CBD)
+MAKE_INSERT_NPS_ADDRTYPE (cjid, CJID)
+MAKE_INSERT_NPS_ADDRTYPE (clbd, CLBD)
+MAKE_INSERT_NPS_ADDRTYPE (cm, CM)
+MAKE_INSERT_NPS_ADDRTYPE (csd, CSD)
+MAKE_INSERT_NPS_ADDRTYPE (cxa, CXA)
+MAKE_INSERT_NPS_ADDRTYPE (cxd, CXD)
+
+
/* Include the generic extract/insert functions. Order is important
as some of the functions present in the .h may be disabled via
defines. */
{ "d", 1, 1, 5, 1 },
#define F_DFAKE (F_D + 1)
{ "d", 0, 0, 0, 1 },
+#define F_DNZ_ND (F_DFAKE + 1)
+ { "nd", 0, 1, 16, 0 },
+#define F_DNZ_D (F_DNZ_ND + 1)
+ { "d", 1, 1, 16, 1 },
/* Data size. */
-#define F_SIZEB1 (F_DFAKE + 1)
+#define F_SIZEB1 (F_DNZ_D + 1)
{ "b", 1, 2, 1, 1 },
#define F_SIZEB7 (F_SIZEB1 + 1)
{ "b", 1, 2, 7, 1 },
#define F_NPS_AL (F_NPS_AR + 1)
{ "al", 1, 1, 0, 1 },
+
+#define F_NPS_S (F_NPS_AL + 1)
+ { "s", 0, 0, 0, 1 },
+
+#define F_NPS_ZNCV_RD (F_NPS_S + 1)
+ { "rd", 0, 1, 15, 1 },
+
+#define F_NPS_ZNCV_WR (F_NPS_ZNCV_RD + 1)
+ { "wr", 1, 1, 15, 1 },
+
+#define F_NPS_P0 (F_NPS_ZNCV_WR + 1)
+ { "p0", 0, 0, 0, 1 },
+
+#define F_NPS_P1 (F_NPS_P0 + 1)
+ { "p1", 0, 0, 0, 1 },
+
+#define F_NPS_P2 (F_NPS_P1 + 1)
+ { "p2", 0, 0, 0, 1 },
+
+#define F_NPS_P3 (F_NPS_P2 + 1)
+ { "p3", 0, 0, 0, 1 },
+
+#define F_NPS_LDBIT_DI (F_NPS_P3 + 1)
+ { "di", 0, 0, 0, 1 },
+
+#define F_NPS_LDBIT_CL1 (F_NPS_LDBIT_DI + 1)
+ { "cl", 1, 1, 6, 1 },
+
+#define F_NPS_LDBIT_CL2 (F_NPS_LDBIT_CL1 + 1)
+ { "cl", 1, 1, 16, 1 },
+
+#define F_NPS_LDBIT_X2_1 (F_NPS_LDBIT_CL2 + 1)
+ { "x2", 1, 2, 9, 1 },
+
+#define F_NPS_LDBIT_X2_2 (F_NPS_LDBIT_X2_1 + 1)
+ { "x2", 1, 2, 22, 1 },
+
+#define F_NPS_LDBIT_X4_1 (F_NPS_LDBIT_X2_2 + 1)
+ { "x4", 2, 2, 9, 1 },
+
+#define F_NPS_LDBIT_X4_2 (F_NPS_LDBIT_X4_1 + 1)
+ { "x4", 2, 2, 22, 1 },
};
const unsigned arc_num_flag_operands = ARRAY_SIZE (arc_flag_operands);
{ F_CLASS_NONE, { F_NULL } },
#define C_CC (C_EMPTY + 1)
- { F_CLASS_OPTIONAL | F_CLASS_EXTEND,
+ { F_CLASS_OPTIONAL | F_CLASS_EXTEND | F_CLASS_COND,
{ F_ALWAYS, F_RA, F_EQUAL, F_ZERO, F_NOTEQUAL,
F_NOTZERO, F_POZITIVE, F_PL, F_NEGATIVE, F_MINUS,
F_CARRY, F_CARRYSET, F_LOWER, F_CARRYCLR,
{ F_CLASS_OPTIONAL, { F_NT, F_T, F_NULL } },
#define C_D (C_T + 1)
{ F_CLASS_OPTIONAL, { F_ND, F_D, F_NULL } },
+#define C_DNZ_D (C_D + 1)
+ { F_CLASS_OPTIONAL, { F_DNZ_ND, F_DNZ_D, F_NULL } },
-#define C_DHARD (C_D + 1)
+#define C_DHARD (C_DNZ_D + 1)
{ F_CLASS_OPTIONAL, { F_DFAKE, F_NULL } },
#define C_DI20 (C_DHARD + 1)
#define C_NPS_AR_AL (C_NPS_SX + 1)
{ F_CLASS_REQUIRED, { F_NPS_AR, F_NPS_AL, F_NULL}},
+
+#define C_NPS_S (C_NPS_AR_AL + 1)
+ { F_CLASS_REQUIRED, { F_NPS_S, F_NULL}},
+
+#define C_NPS_ZNCV (C_NPS_S + 1)
+ { F_CLASS_REQUIRED, { F_NPS_ZNCV_RD, F_NPS_ZNCV_WR, F_NULL}},
+
+#define C_NPS_P0 (C_NPS_ZNCV + 1)
+ { F_CLASS_REQUIRED, { F_NPS_P0, F_NULL }},
+
+#define C_NPS_P1 (C_NPS_P0 + 1)
+ { F_CLASS_REQUIRED, { F_NPS_P1, F_NULL }},
+
+#define C_NPS_P2 (C_NPS_P1 + 1)
+ { F_CLASS_REQUIRED, { F_NPS_P2, F_NULL }},
+
+#define C_NPS_P3 (C_NPS_P2 + 1)
+ { F_CLASS_REQUIRED, { F_NPS_P3, F_NULL }},
+
+#define C_NPS_LDBIT_DI (C_NPS_P3 + 1)
+ { F_CLASS_REQUIRED, { F_NPS_LDBIT_DI, F_NULL }},
+
+#define C_NPS_LDBIT_CL1 (C_NPS_LDBIT_DI + 1)
+ { F_CLASS_OPTIONAL, { F_NPS_LDBIT_CL1, F_NULL }},
+
+#define C_NPS_LDBIT_CL2 (C_NPS_LDBIT_CL1 + 1)
+ { F_CLASS_OPTIONAL, { F_NPS_LDBIT_CL2, F_NULL }},
+
+#define C_NPS_LDBIT_X_1 (C_NPS_LDBIT_CL2 + 1)
+ { F_CLASS_OPTIONAL, { F_NPS_LDBIT_X2_1, F_NPS_LDBIT_X4_1, F_NULL }},
+
+#define C_NPS_LDBIT_X_2 (C_NPS_LDBIT_X_1 + 1)
+ { F_CLASS_OPTIONAL, { F_NPS_LDBIT_X2_2, F_NPS_LDBIT_X4_2, F_NULL }},
};
const unsigned char flags_none[] = { 0 };
index is used to indicate end-of-list. */
#define UNUSED 0
{ 0, 0, 0, 0, 0, 0 },
+
+#define IGNORED (UNUSED + 1)
+ { 0, 0, 0, ARC_OPERAND_IGNORE | ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, 0, 0 },
+
/* The plain integer register fields. Used by 32 bit
instructions. */
-#define RA (UNUSED + 1)
+#define RA (IGNORED + 1)
{ 6, 0, 0, ARC_OPERAND_IR, 0, 0 },
#define RB (RA + 1)
{ 6, 12, 0, ARC_OPERAND_IR, insert_rb, extract_rb },
#define NPS_UIMM16 (NPS_BITOP_UIMM8 + 1)
{ 16, 0, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
-#define NPS_RFLT_UIMM6 (NPS_UIMM16 + 1)
+#define NPS_SIMM16 (NPS_UIMM16 + 1)
+ { 16, 0, 0, ARC_OPERAND_SIGNED, NULL, NULL },
+
+#define NPS_RFLT_UIMM6 (NPS_SIMM16 + 1)
{ 6, 6, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_rflt_uimm6, extract_nps_rflt_uimm6 },
#define NPS_XLDST_UIMM16 (NPS_RFLT_UIMM6 + 1)
#define NPS_CALC_ENTRY_SIZE (NPS_QCMP_M3 + 1)
{ 0, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_calc_entry_size, extract_nps_calc_entry_size },
+
+#define NPS_R_DST_3B_SHORT (NPS_CALC_ENTRY_SIZE + 1)
+ { 3, 8, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_dst_short, extract_nps_3bit_dst_short },
+
+#define NPS_R_SRC1_3B_SHORT (NPS_R_DST_3B_SHORT + 1)
+ { 3, 8, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE | ARC_OPERAND_NCHK, insert_nps_3bit_dst_short, extract_nps_3bit_dst_short },
+
+#define NPS_R_SRC2_3B_SHORT (NPS_R_SRC1_3B_SHORT + 1)
+ { 3, 5, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_src2_short, extract_nps_3bit_src2_short },
+
+#define NPS_BITOP_SIZE2 (NPS_R_SRC2_3B_SHORT + 1)
+ { 5, 25, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_bitop2_size, extract_nps_bitop2_size },
+
+#define NPS_BITOP_SIZE1 (NPS_BITOP_SIZE2 + 1)
+ { 5, 20, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_bitop1_size, extract_nps_bitop1_size },
+
+#define NPS_BITOP_DST_POS3_POS4 (NPS_BITOP_SIZE1 + 1)
+ { 5, 0, 0, ARC_OPERAND_UNSIGNED, insert_nps_bitop_dst_pos3_pos4, extract_nps_bitop_dst_pos3_pos4 },
+
+#define NPS_BITOP_DST_POS4 (NPS_BITOP_DST_POS3_POS4 + 1)
+ { 5, 10, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_BITOP_DST_POS3 (NPS_BITOP_DST_POS4 + 1)
+ { 5, 5, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_BITOP_DST_POS2 (NPS_BITOP_DST_POS3 + 1)
+ { 5, 15, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_BITOP_DST_POS1 (NPS_BITOP_DST_POS2 + 1)
+ { 5, 10, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_BITOP_SRC_POS4 (NPS_BITOP_DST_POS1 + 1)
+ { 5, 0, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_BITOP_SRC_POS3 (NPS_BITOP_SRC_POS4 + 1)
+ { 5, 20, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_BITOP_SRC_POS2 (NPS_BITOP_SRC_POS3 + 1)
+ { 5, 5, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_BITOP_SRC_POS1 (NPS_BITOP_SRC_POS2 + 1)
+ { 5, 0, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_BITOP_MOD4_MSB (NPS_BITOP_SRC_POS1 + 1)
+ { 2, 0, 0, ARC_OPERAND_UNSIGNED, insert_nps_bitop_mod4_msb, extract_nps_bitop_mod4_msb },
+
+#define NPS_BITOP_MOD4_LSB (NPS_BITOP_MOD4_MSB + 1)
+ { 2, 0, 0, ARC_OPERAND_UNSIGNED, insert_nps_bitop_mod4_lsb, extract_nps_bitop_mod4_lsb },
+
+#define NPS_BITOP_MOD3 (NPS_BITOP_MOD4_LSB + 1)
+ { 2, 29, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_BITOP_MOD2 (NPS_BITOP_MOD3 + 1)
+ { 2, 27, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_BITOP_MOD1 (NPS_BITOP_MOD2 + 1)
+ { 2, 25, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_BITOP_INS_EXT (NPS_BITOP_MOD1 + 1)
+ { 5, 20, 0, ARC_OPERAND_UNSIGNED, insert_nps_bitop_ins_ext, extract_nps_bitop_ins_ext },
+
+#define NPS_FIELD_START_POS (NPS_BITOP_INS_EXT + 1)
+ { 3, 3, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_FIELD_SIZE (NPS_FIELD_START_POS + 1)
+ { 3, 6, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_field_size, extract_nps_field_size },
+
+#define NPS_SHIFT_FACTOR (NPS_FIELD_SIZE + 1)
+ { 3, 9, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_shift_factor, extract_nps_shift_factor },
+
+#define NPS_BITS_TO_SCRAMBLE (NPS_SHIFT_FACTOR + 1)
+ { 3, 12, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_bits_to_scramble, extract_nps_bits_to_scramble },
+
+#define NPS_SRC2_POS_5B (NPS_BITS_TO_SCRAMBLE + 1)
+ { 5, 5, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_BDLEN_MAX_LEN (NPS_SRC2_POS_5B + 1)
+ { 8, 5, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_bdlen_max_len, extract_nps_bdlen_max_len },
+
+#define NPS_MIN_HOFS (NPS_BDLEN_MAX_LEN + 1)
+ { 4, 6, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_min_hofs, extract_nps_min_hofs },
+
+#define NPS_PSBC (NPS_MIN_HOFS + 1)
+ { 1, 11, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_DPI_DST (NPS_PSBC + 1)
+ { 5, 11, 0, ARC_OPERAND_IR, NULL, NULL },
+
+ /* NPS_DPI_SRC1_3B is similar to NPS_R_SRC1_3B but doesn't duplicate an operand */
+#define NPS_DPI_SRC1_3B (NPS_DPI_DST + 1)
+ { 3, 24, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_dst, extract_nps_3bit_dst },
+
+#define NPS_HASH_WIDTH (NPS_DPI_SRC1_3B + 1)
+ { 5, 6, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_hash_width, extract_nps_hash_width },
+
+#define NPS_HASH_PERM (NPS_HASH_WIDTH + 1)
+ { 3, 2, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_HASH_NONLINEAR (NPS_HASH_PERM + 1)
+ { 1, 5, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_HASH_BASEMAT (NPS_HASH_NONLINEAR + 1)
+ { 2, 0, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_HASH_LEN (NPS_HASH_BASEMAT + 1)
+ { 3, 2, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_hash_len, extract_nps_hash_len },
+
+#define NPS_HASH_OFS (NPS_HASH_LEN + 1)
+ { 2, 0, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_HASH_BASEMAT2 (NPS_HASH_OFS + 1)
+ { 1, 5, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_E4BY_INDEX0 (NPS_HASH_BASEMAT2 + 1)
+ { 3, 8, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_E4BY_INDEX1 (NPS_E4BY_INDEX0 + 1)
+ { 3, 5, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_E4BY_INDEX2 (NPS_E4BY_INDEX1 + 1)
+ { 3, 2, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_E4BY_INDEX3 (NPS_E4BY_INDEX2 + 1)
+ { 2, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_index3, extract_nps_index3 },
+
+#define COLON (NPS_E4BY_INDEX3 + 1)
+ { 0, 0, 0, ARC_OPERAND_COLON | ARC_OPERAND_FAKE, NULL, NULL },
+
+#define NPS_BD (COLON + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_bd, extract_nps_bd },
+
+#define NPS_JID (NPS_BD + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_jid, extract_nps_jid },
+
+#define NPS_LBD (NPS_JID + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_lbd, extract_nps_lbd },
+
+#define NPS_MBD (NPS_LBD + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_mbd, extract_nps_mbd },
+
+#define NPS_SD (NPS_MBD + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_sd, extract_nps_sd },
+
+#define NPS_SM (NPS_SD + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_sm, extract_nps_sm },
+
+#define NPS_XA (NPS_SM + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_xa, extract_nps_xa },
+
+#define NPS_XD (NPS_XA + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_xd, extract_nps_xd },
+
+#define NPS_CD (NPS_XD + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_cd, extract_nps_cd },
+
+#define NPS_CBD (NPS_CD + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_cbd, extract_nps_cbd },
+
+#define NPS_CJID (NPS_CBD + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_cjid, extract_nps_cjid },
+
+#define NPS_CLBD (NPS_CJID + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_clbd, extract_nps_clbd },
+
+#define NPS_CM (NPS_CLBD + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_cm, extract_nps_cm },
+
+#define NPS_CSD (NPS_CM + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_csd, extract_nps_csd },
+
+#define NPS_CXA (NPS_CSD + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_cxa, extract_nps_cxa },
+
+#define NPS_CXD (NPS_CXA + 1)
+ { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_cxd, extract_nps_cxd },
+
+#define NPS_BD_TYPE (NPS_CXD + 1)
+ { 1, 10, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_BMU_NUM (NPS_BD_TYPE + 1)
+ { 3, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_bd_num_buff, extract_nps_bd_num_buff },
+
+#define NPS_PMU_NXT_DST (NPS_BMU_NUM + 1)
+ { 4, 6, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_PMU_NUM_JOB (NPS_PMU_NXT_DST + 1)
+ { 2, 6, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_pmu_num_job, extract_nps_pmu_num_job },
};
const unsigned arc_num_operands = ARRAY_SIZE (arc_operands);
};
const unsigned arc_num_relax_opcodes = ARRAY_SIZE (arc_relax_opcodes);
+
+/* The following instructions are all either 48 or 64 bits long, and
+ require special handling in the assembler and disassembler.
+
+ The first part of each ARC_LONG_OPCODE is the base ARC_OPCODE, this is
+ either the 16 or 32 bit base instruction, and its opcode list will
+ always end in a LIMM.
+
+ The rest of the ARC_LONG_OPCODE describes how to build the LIMM from the
+ instruction operands. There are therefore two lists of operands for
+ each ARC_LONG_OPCODE, the second list contains operands that are merged
+ into the limm template, in the same way that a standard 32-bit
+ instruction is built. This generated limm is then added to the list of
+ tokens that is passed to the standard instruction encoder, along with
+ the first list of operands (from the base arc_opcode).
+
+ The first list of operands then, describes how to build the base
+ instruction, and includes the 32-bit limm that was previously generated
+ as the last operand.
+
+ In most cases operands are either encoded into the base instruction or
+ into the limm. When this happens the operand slot will be filled with
+ an operand identifier in one list, and will be IGNORED in the other
+ list, this special operand value causes the operand to be ignored,
+ without being encoded at this point.
+
+ However, in some cases, an operand is split between the base instruction
+ and the 32-bit limm, in this case the operand slot will be filled in
+ both operand lists (see mov4b for one example of this). */
+const struct arc_long_opcode arc_long_opcodes[] =
+ {
+ /* mrgb - (48 bit instruction). */
+ { { "mrgb", 0x5803, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC1_3B_SHORT, NPS_R_SRC2_3B_SHORT, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { 0 }},
+ 0x00000000, 0x80000000, { IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_SRC_POS1, NPS_BITOP_SIZE1, NPS_BITOP_DST_POS2, NPS_BITOP_SRC_POS2, NPS_BITOP_SIZE2 }},
+
+ /* mrgb.cl - (48 bit instruction). */
+ { { "mrgb", 0x5803, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC1_3B_SHORT, NPS_R_SRC2_3B_SHORT, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { C_NPS_CL }},
+ 0x80000000, 0x80000000, { IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_SRC_POS1, NPS_BITOP_SIZE1, NPS_BITOP_DST_POS2, NPS_BITOP_SRC_POS2, NPS_BITOP_SIZE2 }},
+
+ /* mov2b - (48 bit instruction). */
+ { { "mov2b", 0x5800, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC1_3B_SHORT, NPS_R_SRC2_3B_SHORT, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { 0 }},
+ 0x00000000, 0x80000000, { IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2 }},
+
+ /* mov2b.cl - (48 bit instruction). */
+ { { "mov2b", 0x5800, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC2_3B_SHORT, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { C_NPS_CL }},
+ 0x80000000, 0x80000000, { IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2 }},
+
+ /* ext4 - (48 bit instruction). */
+ { { "ext4b", 0x5801, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC1_3B_SHORT, NPS_R_SRC2_3B_SHORT, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { 0 }},
+ 0x00000000, 0x80000000, { IGNORED, IGNORED, IGNORED, NPS_BITOP_INS_EXT, NPS_BITOP_SRC_POS1, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS1, NPS_BITOP_DST_POS2 }},
+
+ /* ext4.cl - (48 bit instruction). */
+ { { "ext4b", 0x5801, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC2_3B_SHORT, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { C_NPS_CL }},
+ 0x80000000, 0x80000000, { IGNORED, IGNORED, NPS_BITOP_INS_EXT, NPS_BITOP_SRC_POS1, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS1, NPS_BITOP_DST_POS2 }},
+
+ /* ins4 - (48 bit instruction). */
+ { { "ins4b", 0x5802, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC1_3B_SHORT, NPS_R_SRC2_3B_SHORT, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { 0 }},
+ 0x00000000, 0x80000000, { IGNORED, IGNORED, IGNORED, NPS_BITOP_SRC_POS1, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_INS_EXT }},
+
+ /* ins4.cl - (48 bit instruction). */
+ { { "ins4b", 0x5802, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC2_3B_SHORT, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { C_NPS_CL }},
+ 0x80000000, 0x80000000, { IGNORED, IGNORED, NPS_BITOP_SRC_POS1, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_INS_EXT }},
+
+ /* mov3b - (64 bit instruction). */
+ { { "mov3b", 0x58100000, 0xf81f801f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B, NPS_R_SRC1_3B, NPS_R_SRC2_3B, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS3_POS4, IGNORED, IGNORED, LIMM }, { 0 }},
+ 0x80000000, 0x80000000, { IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, IGNORED, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3 }},
+
+ /* mov4b - (64 bit instruction). */
+ { { "mov4b", 0x58100000, 0xf81f0000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B, NPS_R_SRC1_3B, NPS_R_SRC2_3B, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS3, IGNORED, IGNORED, NPS_BITOP_DST_POS4, NPS_BITOP_MOD4_LSB, NPS_BITOP_SRC_POS4, LIMM }, { 0 }},
+ 0x00000000, 0x00000000, { IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, IGNORED, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3, IGNORED, NPS_BITOP_MOD4_MSB, IGNORED}},
+
+ /* mov3bcl - (64 bit instruction). */
+ { { "mov3bcl", 0x58110000, 0xf81f801f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B, NPS_R_SRC2_3B, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS3_POS4, IGNORED, IGNORED, LIMM }, { 0 }},
+ 0x80000000, 0x80000000, { IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, IGNORED, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3 }},
+
+ /* mov4bcl - (64 bit instruction). */
+ { { "mov4bcl", 0x58110000, 0xf81f0000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B, NPS_R_SRC2_3B, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS3, IGNORED, IGNORED, NPS_BITOP_DST_POS4, NPS_BITOP_MOD4_LSB, NPS_BITOP_SRC_POS4, LIMM }, { 0 }},
+ 0x00000000, 0x00000000, { IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, IGNORED, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3, IGNORED, NPS_BITOP_MOD4_MSB, IGNORED}},
+
+ /* mov3b.cl - (64 bit instruction). */
+ { { "mov3b", 0x58110000, 0xf81f801f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B, NPS_R_SRC2_3B, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS3_POS4, IGNORED, IGNORED, LIMM }, { C_NPS_CL }},
+ 0x80000000, 0x80000000, { IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, IGNORED, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3 }},
+
+ /* mov4b.cl - (64 bit instruction). */
+ { { "mov4b", 0x58110000, 0xf81f0000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B, NPS_R_SRC2_3B, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS3, IGNORED, IGNORED, NPS_BITOP_DST_POS4, NPS_BITOP_MOD4_LSB, NPS_BITOP_SRC_POS4, LIMM }, { C_NPS_CL }},
+ 0x00000000, 0x00000000, { IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, IGNORED, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3, IGNORED, NPS_BITOP_MOD4_MSB, IGNORED}},
+};
+
+const unsigned arc_num_long_opcodes = ARRAY_SIZE (arc_long_opcodes);