diff options
author | Andrew Burgess <andrew.burgess@embecosm.com> | 2016-04-01 19:51:50 +0100 |
---|---|---|
committer | Andrew Burgess <andrew.burgess@embecosm.com> | 2016-04-19 22:51:27 +0100 |
commit | 537aefaf18444430df8126b474cf11ff7201b4c6 (patch) | |
tree | db19856dded7bea0f5ff6e68ad2577bd49e4df0b /opcodes | |
parent | c8f785f220bab3c17fc93445ac509495d00d5afe (diff) | |
download | binutils-gdb-537aefaf18444430df8126b474cf11ff7201b4c6.tar.gz |
opcodes/arc: Add yet more nps instructions
Add some more arc/nps400 instructions and the associated operands.
There's also a test added into the assembler.
gas/ChangeLog:
* testsuite/gas/arc/nps400-6.d: New file.
* testsuite/gas/arc/nps400-6.s: New file.
include/ChangeLog:
* opcode/arc.h (MAX_INSN_ARGS): Increase 6 to 8.
opcodes/ChangeLog:
* arc-nps400-tbl.h: Add addb, subb, adcb, sbcb, andb, xorb, orb,
fxorb, wxorb, shlb, shrb, notb, cntbb, div, mod, divm, and qcmp
instructions.
* arc-opc.c (insert_nps_bitop_size): Delete.
(extract_nps_bitop_size): Delete.
(MAKE_SRC_POS_INSERT_EXTRACT_FUNCS): Define, and use.
(extract_nps_qcmp_m3): Define.
(extract_nps_qcmp_m2): Define.
(extract_nps_qcmp_m1): Define.
(arc_flag_operands): Add F_NPS_SX, F_NPS_AR, F_NPS_AL.
(arc_flag_classes): Add C_NPS_SX, C_NPS_AR_AL
(arc_operands): Add NPS_SRC2_POS, NPS_SRC1_POS, NPS_ADDB_SIZE,
NPS_ANDB_SIZE, NPS_FXORB_SIZ, NPS_WXORB_SIZ, NPS_R_XLDST,
NPS_DIV_UIMM4, NPS_QCMP_SIZE, NPS_QCMP_M1, NPS_QCMP_M2, and
NPS_QCMP_M3.
Diffstat (limited to 'opcodes')
-rw-r--r-- | opcodes/ChangeLog | 18 | ||||
-rw-r--r-- | opcodes/arc-nps400-tbl.h | 43 | ||||
-rw-r--r-- | opcodes/arc-opc.c | 208 |
3 files changed, 246 insertions, 23 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index f231ea38e49..383cebf35a0 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,5 +1,23 @@ 2016-04-19 Andrew Burgess <andrew.burgess@embecosm.com> + * arc-nps400-tbl.h: Add addb, subb, adcb, sbcb, andb, xorb, orb, + fxorb, wxorb, shlb, shrb, notb, cntbb, div, mod, divm, qcmp, + calcsd, and calcxd instructions. + * arc-opc.c (insert_nps_bitop_size): Delete. + (extract_nps_bitop_size): Delete. + (MAKE_SRC_POS_INSERT_EXTRACT_FUNCS): Define, and use. + (extract_nps_qcmp_m3): Define. + (extract_nps_qcmp_m2): Define. + (extract_nps_qcmp_m1): Define. + (arc_flag_operands): Add F_NPS_SX, F_NPS_AR, F_NPS_AL. + (arc_flag_classes): Add C_NPS_SX, C_NPS_AR_AL + (arc_operands): Add NPS_SRC2_POS, NPS_SRC1_POS, NPS_ADDB_SIZE, + NPS_ANDB_SIZE, NPS_FXORB_SIZ, NPS_WXORB_SIZ, NPS_R_XLDST, + NPS_DIV_UIMM4, NPS_QCMP_SIZE, NPS_QCMP_M1, NPS_QCMP_M2, and + NPS_QCMP_M3. + +2016-04-19 Andrew Burgess <andrew.burgess@embecosm.com> + * arc-nps400-tbl.h: Add dctcp, dcip, dcet, and dcacl instructions. 2016-04-15 H.J. Lu <hongjiu.lu@intel.com> diff --git a/opcodes/arc-nps400-tbl.h b/opcodes/arc-nps400-tbl.h index ebafc159da6..5716119f74d 100644 --- a/opcodes/arc-nps400-tbl.h +++ b/opcodes/arc-nps400-tbl.h @@ -124,6 +124,49 @@ /* crc32<.r> 0,limm,u6 00111 110 01 110100 R 111 uuuuuu 111110 */ { "crc32", 0x3e74703e, 0xffff703f, ARC_OPCODE_NPS400, BITOP, NONE, { ZA, LIMM, UIMM6_20 }, { C_NPS_R }}, +/**** Arithmetic & Logic Instructions ****/ + +#define ADDB_LIKE(NAME,SUBOP2) \ + { NAME, (0x48000000 | SUBOP2), 0xf80f001f, ARC_OPCODE_NPS400, ARITH, NONE, { NPS_R_DST_3B, NPS_R_SRC1_3B, NPS_R_SRC2_3B, NPS_SRC1_POS, NPS_SRC2_POS, NPS_ADDB_SIZE }, { C_NPS_F, C_NPS_SX }}, + +ADDB_LIKE ("addb", 0) +ADDB_LIKE ("subb", 4) +ADDB_LIKE ("adcb", 5) +ADDB_LIKE ("sbcb", 6) + +#define ANDB_LIKE(NAME,SUBOP2,SIZE_OPERAND) \ + { NAME, (0x48000000 | SUBOP2), 0xf80f001f, ARC_OPCODE_NPS400, ARITH, NONE, { NPS_R_DST_3B, NPS_R_SRC1_3B, NPS_R_SRC2_3B, NPS_SRC1_POS, NPS_SRC2_POS, SIZE_OPERAND }, { C_NPS_F }}, + +ANDB_LIKE ("andb", 1, NPS_ANDB_SIZE) +ANDB_LIKE ("xorb", 2, NPS_ANDB_SIZE) +ANDB_LIKE ("orb", 3, NPS_ANDB_SIZE) +ANDB_LIKE ("fxorb", 7, NPS_FXORB_SIZE) +ANDB_LIKE ("wxorb", 8, NPS_WXORB_SIZE) +ANDB_LIKE ("shlb", 0xb, NPS_ANDB_SIZE) +ANDB_LIKE ("shrb", 0xc, NPS_ANDB_SIZE) + +#define NOTB_LIKE(NAME,SUBOP2) \ + { NAME, (0x48000000 | SUBOP2), 0xf80f001f, ARC_OPCODE_NPS400, ARITH, NONE, { NPS_R_DST_3B, NPS_R_SRC2_3B, NPS_SRC2_POS, NPS_ANDB_SIZE }, { C_NPS_F }}, + +NOTB_LIKE ("notb", 0x9) +NOTB_LIKE ("cntbb", 0xa) + +#define DIV_LIKE(NAME,DIV_MODE) \ + { NAME, (0x4800000d | DIV_MODE << 14), 0xf80fc3ff, ARC_OPCODE_NPS400, ARITH, NONE, { NPS_R_DST_3B, NPS_R_SRC1_3B, NPS_R_SRC2_3B, NPS_SRC1_POS, NPS_SRC2_POS, }, { C_NPS_F }}, \ + { NAME, (0x4800020d | DIV_MODE << 14), 0xf8efc21f, ARC_OPCODE_NPS400, ARITH, NONE, { NPS_R_DST_3B, NPS_R_SRC1_3B, NPS_DIV_UIMM4, NPS_SRC1_POS }, { C_NPS_F }}, + +DIV_LIKE ("div", 0x1) +DIV_LIKE ("mod", 0x2) +DIV_LIKE ("divm", 0x0) + +{ "qcmp", 0x4810000e, 0xf81f001e, ARC_OPCODE_NPS400, ARITH, NONE, { NPS_R_DST_3B, NPS_R_SRC1_3B, NPS_R_SRC2_3B, NPS_SRC2_POS, NPS_QCMP_SIZE, NPS_QCMP_M1, NPS_QCMP_M2, NPS_QCMP_M3 }, { C_NPS_AR_AL }}, +{ "qcmp", 0x481001ee, 0xf81f01fe, ARC_OPCODE_NPS400, ARITH, NONE, { NPS_R_DST_3B, NPS_R_SRC1_3B, NPS_R_SRC2_3B, NPS_SRC2_POS, NPS_QCMP_SIZE, NPS_QCMP_M1, NPS_QCMP_M2 }, { C_NPS_AR_AL }}, +{ "qcmp", 0x481001ee, 0xf81f81fe, ARC_OPCODE_NPS400, ARITH, NONE, { NPS_R_DST_3B, NPS_R_SRC1_3B, NPS_R_SRC2_3B, NPS_SRC2_POS, NPS_QCMP_SIZE, NPS_QCMP_M1 }, { C_NPS_AR_AL }}, +{ "qcmp", 0x481001ee, 0xf81fc1fe, ARC_OPCODE_NPS400, ARITH, NONE, { NPS_R_DST_3B, NPS_R_SRC1_3B, NPS_R_SRC2_3B, NPS_SRC2_POS, NPS_QCMP_SIZE }, { C_NPS_AR_AL }}, + +{ "calcsd", 0x48000010, 0xf80f407f, ARC_OPCODE_NPS400, ARITH, NONE, { NPS_R_DST_3B, NPS_R_SRC1_3B, NPS_R_SRC2_3B, NPS_CALC_ENTRY_SIZE }, { C_NPS_F }}, +{ "calcxd", 0x48004010, 0xf80f407f, ARC_OPCODE_NPS400, ARITH, NONE, { NPS_R_DST_3B, NPS_R_SRC1_3B, NPS_R_SRC2_3B, NPS_CALC_ENTRY_SIZE }, { C_NPS_F }}, + /**** Protocol Decoder Instructions ****/ /* dctcp b,c 00111bbb001011110bbbcccccc000000 */ diff --git a/opcodes/arc-opc.c b/opcodes/arc-opc.c index 2ce885317a4..9effbaf90d3 100644 --- a/opcodes/arc-opc.c +++ b/opcodes/arc-opc.c @@ -719,29 +719,6 @@ extract_nps_3bit_src2 (unsigned insn ATTRIBUTE_UNUSED, } static unsigned -insert_nps_bitop_size (unsigned insn ATTRIBUTE_UNUSED, - int value ATTRIBUTE_UNUSED, - const char **errmsg ATTRIBUTE_UNUSED) -{ - if (value < 1 || value > 32) - { - *errmsg = _("Invalid bit size, should be between 1 and 32 inclusive."); - return insn; - } - - --value; - insn |= ((value & 0x1f) << 10); - return insn; -} - -static int -extract_nps_bitop_size (unsigned insn ATTRIBUTE_UNUSED, - bfd_boolean * invalid ATTRIBUTE_UNUSED) -{ - return ((insn >> 10) & 0x1f) + 1; -} - -static unsigned insert_nps_bitop_size_2b (unsigned insn ATTRIBUTE_UNUSED, int value ATTRIBUTE_UNUSED, const char **errmsg ATTRIBUTE_UNUSED) @@ -857,6 +834,139 @@ extract_nps_cmem_uimm16 (unsigned insn ATTRIBUTE_UNUSED, return (NPS_CMEM_HIGH_VALUE << 16) | (insn & 0xffff); } +#define MAKE_SRC_POS_INSERT_EXTRACT_FUNCS(NAME,SHIFT) \ +static unsigned \ +insert_nps_##NAME##_pos (unsigned insn ATTRIBUTE_UNUSED, \ + int value ATTRIBUTE_UNUSED, \ + const char **errmsg ATTRIBUTE_UNUSED) \ +{ \ + switch (value) \ + { \ + case 0: \ + case 8: \ + case 16: \ + case 24: \ + value = value / 8; \ + break; \ + default: \ + *errmsg = _("Invalid position, should be 0, 8, 16, or 24."); \ + value = 0; \ + } \ + insn |= (value << SHIFT); \ + return insn; \ +} \ + \ +static int \ +extract_nps_##NAME##_pos (unsigned insn ATTRIBUTE_UNUSED, \ + bfd_boolean * invalid ATTRIBUTE_UNUSED) \ +{ \ + return ((insn >> SHIFT) & 0x3) * 8; \ +} + +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)\ +static unsigned \ +insert_nps_##NAME##_size (unsigned insn ATTRIBUTE_UNUSED, \ + int value ATTRIBUTE_UNUSED, \ + const char **errmsg ATTRIBUTE_UNUSED) \ + { \ + if (value < LOWER || value > 32) \ + { \ + *errmsg = _("Invalid size, value must be " \ + #LOWER " to " #UPPER "."); \ + return insn; \ + } \ + value -= BIAS; \ + insn |= (value << SHIFT); \ + return insn; \ + } \ + \ +static int \ +extract_nps_##NAME##_size (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) + +static int +extract_nps_qcmp_m3 (unsigned insn ATTRIBUTE_UNUSED, + bfd_boolean * invalid ATTRIBUTE_UNUSED) +{ + int m3 = (insn >> 5) & 0xf; + if (m3 == 0xf) + *invalid = TRUE; + return m3; +} + +static int +extract_nps_qcmp_m2 (unsigned insn ATTRIBUTE_UNUSED, + bfd_boolean * invalid ATTRIBUTE_UNUSED) +{ + bfd_boolean tmp_invalid = FALSE; + int m2 = (insn >> 15) & 0x1; + int m3 = extract_nps_qcmp_m3 (insn, &tmp_invalid); + + if (m2 == 0 && m3 == 0xf) + *invalid = TRUE; + return m2; +} + +static int +extract_nps_qcmp_m1 (unsigned insn ATTRIBUTE_UNUSED, + bfd_boolean * invalid ATTRIBUTE_UNUSED) +{ + bfd_boolean tmp_invalid = FALSE; + int m1 = (insn >> 14) & 0x1; + int m2 = extract_nps_qcmp_m2 (insn, &tmp_invalid); + int m3 = extract_nps_qcmp_m3 (insn, &tmp_invalid); + + if (m1 == 0 && m2 == 0 && m3 == 0xf) + *invalid = TRUE; + return m1; +} + +static unsigned +insert_nps_calc_entry_size (unsigned insn ATTRIBUTE_UNUSED, + int value ATTRIBUTE_UNUSED, + const char **errmsg ATTRIBUTE_UNUSED) +{ + unsigned pwr; + + if (value < 1 || value > 256) + { + *errmsg = _("value out of range 1 - 256"); + return 0; + } + + for (pwr = 0; (value & 1) == 0; value >>= 1) + ++pwr; + + if (value != 1) + { + *errmsg = _("value must be power of 2"); + return 0; + } + + return insn | (pwr << 8); +} + +static int +extract_nps_calc_entry_size (unsigned insn ATTRIBUTE_UNUSED, + bfd_boolean * invalid ATTRIBUTE_UNUSED) +{ + unsigned entry_size = (insn >> 8) & 0xf; + return 1 << entry_size; +} + /* Include the generic extract/insert functions. Order is important as some of the functions present in the .h may be disabled via defines. */ @@ -1053,6 +1163,14 @@ const struct arc_flag_operand arc_flag_operands[] = #define F_NPS_HWS_RESTORE (F_NPS_HWS_OFF + 1) { "restore", 0, 0, 0, 1 }, +#define F_NPS_SX (F_NPS_HWS_RESTORE + 1) + { "sx", 1, 1, 14, 1 }, + +#define F_NPS_AR (F_NPS_SX + 1) + { "ar", 0, 1, 0, 1 }, + +#define F_NPS_AL (F_NPS_AR + 1) + { "al", 1, 1, 0, 1 }, }; const unsigned arc_num_flag_operands = ARRAY_SIZE (arc_flag_operands); @@ -1154,6 +1272,11 @@ const struct arc_flag_class arc_flag_classes[] = #define C_NPS_HWS_RESTORE (C_NPS_HWS_OFF + 1) { F_CLASS_REQUIRED, { F_NPS_HWS_RESTORE, F_NULL}}, +#define C_NPS_SX (C_NPS_HWS_RESTORE + 1) + { F_CLASS_OPTIONAL, { F_NPS_SX, F_NULL}}, + +#define C_NPS_AR_AL (C_NPS_SX + 1) + { F_CLASS_REQUIRED, { F_NPS_AR, F_NPS_AL, F_NULL}}, }; const unsigned char flags_none[] = { 0 }; @@ -1520,6 +1643,45 @@ const struct arc_operand arc_operands[] = #define NPS_XLDST_UIMM16 (NPS_RFLT_UIMM6 + 1) { 16, 0, BFD_RELOC_ARC_NPS_CMEM16, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_cmem_uimm16, extract_nps_cmem_uimm16 }, + +#define NPS_SRC2_POS (NPS_XLDST_UIMM16 + 1) + { 0, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_src2_pos, extract_nps_src2_pos }, + +#define NPS_SRC1_POS (NPS_SRC2_POS + 1) + { 0, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_src1_pos, extract_nps_src1_pos }, + +#define NPS_ADDB_SIZE (NPS_SRC1_POS + 1) + { 0, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_addb_size, extract_nps_addb_size }, + +#define NPS_ANDB_SIZE (NPS_ADDB_SIZE + 1) + { 0, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_andb_size, extract_nps_andb_size }, + +#define NPS_FXORB_SIZE (NPS_ANDB_SIZE + 1) + { 0, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_fxorb_size, extract_nps_fxorb_size }, + +#define NPS_WXORB_SIZE (NPS_FXORB_SIZE + 1) + { 0, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_wxorb_size, extract_nps_wxorb_size }, + +#define NPS_R_XLDST (NPS_WXORB_SIZE + 1) + { 6, 5, 0, ARC_OPERAND_IR, NULL, NULL }, + +#define NPS_DIV_UIMM4 (NPS_R_XLDST + 1) + { 4, 5, 0, ARC_OPERAND_UNSIGNED, NULL, NULL }, + +#define NPS_QCMP_SIZE (NPS_DIV_UIMM4 + 1) + { 0, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_qcmp_size, extract_nps_qcmp_size }, + +#define NPS_QCMP_M1 (NPS_QCMP_SIZE + 1) + { 1, 14, 0, ARC_OPERAND_UNSIGNED, NULL, extract_nps_qcmp_m1 }, + +#define NPS_QCMP_M2 (NPS_QCMP_M1 + 1) + { 1, 15, 0, ARC_OPERAND_UNSIGNED, NULL, extract_nps_qcmp_m2 }, + +#define NPS_QCMP_M3 (NPS_QCMP_M2 + 1) + { 4, 5, 0, ARC_OPERAND_UNSIGNED, NULL, extract_nps_qcmp_m3 }, + +#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 }, }; const unsigned arc_num_operands = ARRAY_SIZE (arc_operands); |