X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=opcodes%2Farc-opc.c;h=44dd7b2d32a0f3763e4a8449ac9923502497c2aa;hb=5af962df4dda65216b83d0a954ea355296517f4b;hp=4dac8de79207d595f9adc89d40b40b35a81dfa72;hpb=d9eca1df01c0e6f7f22566c154e63b1df9315790;p=deliverable%2Fbinutils-gdb.git diff --git a/opcodes/arc-opc.c b/opcodes/arc-opc.c index 4dac8de792..44dd7b2d32 100644 --- a/opcodes/arc-opc.c +++ b/opcodes/arc-opc.c @@ -27,9 +27,7 @@ #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. */ @@ -130,7 +128,7 @@ static int extract_rhv1 (unsigned insn ATTRIBUTE_UNUSED, bfd_boolean * invalid ATTRIBUTE_UNUSED) { - int value = 0; + int value = ((insn & 0x7) << 3) | ((insn >> 5) & 0x7); return value; } @@ -681,6 +679,43 @@ extract_nps_3bit_dst (unsigned insn ATTRIBUTE_UNUSED, 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, @@ -718,6 +753,43 @@ extract_nps_3bit_src2 (unsigned insn 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, @@ -866,13 +938,13 @@ extract_nps_##NAME##_pos (unsigned insn 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 "."); \ @@ -884,18 +956,23 @@ insert_nps_##NAME##_size (unsigned insn ATTRIBUTE_UNUSED, \ } \ \ 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, @@ -967,6 +1044,160 @@ extract_nps_calc_entry_size (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. */ @@ -1171,6 +1402,48 @@ const struct arc_flag_operand arc_flag_operands[] = #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); @@ -1277,6 +1550,39 @@ const struct arc_flag_class arc_flag_classes[] = #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 }; @@ -1295,9 +1601,13 @@ const struct arc_operand arc_operands[] = 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 }, @@ -1638,7 +1948,10 @@ const struct arc_operand arc_operands[] = #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) @@ -1682,6 +1995,193 @@ const struct arc_operand arc_operands[] = #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); @@ -2053,3 +2553,92 @@ const struct arc_opcode arc_relax_opcodes[] = }; 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);