From db18dbabad8e7b63e98d47813ef20acac7072350 Mon Sep 17 00:00:00 2001 From: Graham Markall Date: Wed, 27 Jul 2016 15:57:18 +0100 Subject: [PATCH] Begin implementing ARC NPS-400 Accelerator instructions opcodes * arc-nps400-tbl.h: Change block comments to GNU format. * arc-dis.c: Add new globals addrtypenames, addrtypenames_max, and addtypeunknown. (get_addrtype): New function. (print_insn_arc): Print colons and address types when required. * arc-opc.c: Add MAKE_INSERT_NPS_ADDRTYPE macro and use to define insert and extract functions for all address types. (arc_operands): Add operands for colon and all address types. * arc-nps-400-tbl.h: Add NPS-400 BMU instructions to opcode table. * arc-opc.c: Add NPS_BD_TYPE and NPS_BMU_NUM operands, insert_nps_bd_num_buff and extract_nps_bd_num_buff functions. * arc-nps-400-tbl.h: Add NPS-400 PMU instructions to opcode table. * arc-opc.c: Add NPS_PMU_NXT_DST and NPS_PMU_NUM_JOB operands, insert_nps_pmu_num_job and extract_nps_pmu_num_job functions. include * opcode/arc.h: Add ARC_OPERAND_ADDRTYPE, ARC_OPERAND_COLON. Add the arc_nps_address_type enum and ARC_NUM_ADDRTYPES. * opcode/arc.h: Add BMU to insn_class_t enum. * opcode/arc.h: Add PMU to insn_class_t enum. gas * config/tc-arc.c: Add new global arc_addrtype_hash. Define O_colon and O_addrtype. (debug_exp): Add O_colon and O_addrtype. (tokenize_arguments): Handle colon and address type tokens. (declare_addrtype): New function. (md_begin): Initialise arc_addrtype_hash. (arc_parse_name): Add lookup of address types. (assemble_insn): Handle colons and address types by ignoring them. * testsuite/gas/arc/nps400-8.s: New file. * testsuite/gas/arc/nps400-8.d: New file. * testsuite/gas/arc/nps400-8.s: Add PMU instruction tests. * testsuite/gas/arc/nps400-8.d: Add expected PMU instruction output. --- gas/ChangeLog | 18 +++ gas/config/tc-arc.c | 152 ++++++++++++++++++------ gas/testsuite/gas/arc/nps400-8.d | 71 +++++++++++ gas/testsuite/gas/arc/nps400-8.s | 92 +++++++++++++++ include/ChangeLog | 8 ++ include/opcode/arc.h | 194 +++++++++++++++++++++---------- opcodes/ChangeLog | 19 +++ opcodes/arc-dis.c | 45 ++++++- opcodes/arc-ext.c | 10 +- opcodes/arc-nps400-tbl.h | 110 ++++++++++++++++-- opcodes/arc-opc.c | 131 ++++++++++++++++++--- 11 files changed, 724 insertions(+), 126 deletions(-) create mode 100644 gas/testsuite/gas/arc/nps400-8.d create mode 100644 gas/testsuite/gas/arc/nps400-8.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 617fccdb1c..c2d132ecfe 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,21 @@ +2016-07-27 Graham Markall + + * config/tc-arc.c: Add new global arc_addrtype_hash. + Define O_colon and O_addrtype. + (debug_exp): Add O_colon and O_addrtype. + (tokenize_arguments): Handle colon and address type + tokens. + (declare_addrtype): New function. + (md_begin): Initialise arc_addrtype_hash. + (arc_parse_name): Add lookup of address types. + (assemble_insn): Handle colons and address types by + ignoring them. + * testsuite/gas/arc/nps400-8.s: New file. + * testsuite/gas/arc/nps400-8.d: New file. + * testsuite/gas/arc/nps400-8.s: Add PMU instruction tests. + * testsuite/gas/arc/nps400-8.d: Add expected PMU + instruction output. + 2016-07-26 Maciej W. Rozycki * config/tc-mips.c (RELAX_MICROMIPS_ENCODE): Add `insn32' flag. diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c index 70886dd55e..4e4dcb37df 100644 --- a/gas/config/tc-arc.c +++ b/gas/config/tc-arc.c @@ -45,8 +45,8 @@ #define MAJOR_OPCODE(x) (((x) & 0xF8000000) >> 27) #define SUB_OPCODE(x) (((x) & 0x003F0000) >> 16) -#define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) && \ - (SUB_OPCODE (x) == 0x28)) +#define LP_INSN(x) ((MAJOR_OPCODE (x) == 0x4) \ + && (SUB_OPCODE (x) == 0x28)) /* Equal to MAX_PRECISION in atof-ieee.c. */ #define MAX_LITTLENUMS 6 @@ -102,7 +102,8 @@ enum arc_rlx_types #define is_spfp_p(op) (((sc) == SPX)) #define is_dpfp_p(op) (((sc) == DPX)) #define is_fpuda_p(op) (((sc) == DPA)) -#define is_br_jmp_insn_p(op) (((op)->insn_class == BRANCH || (op)->insn_class == JUMP)) +#define is_br_jmp_insn_p(op) (((op)->insn_class == BRANCH \ + || (op)->insn_class == JUMP)) #define is_kernel_insn_p(op) (((op)->insn_class == KERNEL)) #define is_nps400_p(op) (((sc) == NPS400)) @@ -420,6 +421,9 @@ static struct hash_control *arc_reg_hash; /* The hash table of aux register symbols. */ static struct hash_control *arc_aux_hash; +/* The hash table of address types. */ +static struct hash_control *arc_addrtype_hash; + /* A table of CPU names and opcode sets. */ static const struct cpu_type { @@ -461,6 +465,12 @@ static const struct cpu_type /* Used to define a bracket as operand in tokens. */ #define O_bracket O_md32 +/* Used to define a colon as an operand in tokens. */ +#define O_colon O_md31 + +/* Used to define address types in nps400. */ +#define O_addrtype O_md30 + /* Dummy relocation, to be sorted out. */ #define DUMMY_RELOC_ARC_ENTRY (BFD_RELOC_UNUSED + 1) @@ -553,56 +563,56 @@ const relax_typeS md_relax_table[] = /* BL_S s13 -> BL s25. */ - RELAX_TABLE_ENTRY(13, 1, 2, ARC_RLX_BL), - RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE), + RELAX_TABLE_ENTRY (13, 1, 2, ARC_RLX_BL), + RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE), /* B_S s10 -> B s25. */ - RELAX_TABLE_ENTRY(10, 1, 2, ARC_RLX_B), - RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE), + RELAX_TABLE_ENTRY (10, 1, 2, ARC_RLX_B), + RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE), /* ADD_S c,b, u3 -> ADD<.f> a,b,u6 -> ADD<.f> a,b,limm. */ - RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_ADD_U6), - RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_LIMM), - RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE), + RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_ADD_U6), + RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_LIMM), + RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE), /* LD_S a, [b, u7] -> LD<.x><.aa><.di> a, [b, s9] -> LD<.x><.aa><.di> a, [b, limm] */ - RELAX_TABLE_ENTRY(7, 0, 2, ARC_RLX_LD_S9), - RELAX_TABLE_ENTRY(9, 1, 4, ARC_RLX_LD_LIMM), - RELAX_TABLE_ENTRY_MAX(1, 8, ARC_RLX_NONE), + RELAX_TABLE_ENTRY (7, 0, 2, ARC_RLX_LD_S9), + RELAX_TABLE_ENTRY (9, 1, 4, ARC_RLX_LD_LIMM), + RELAX_TABLE_ENTRY_MAX (1, 8, ARC_RLX_NONE), /* MOV_S b, u8 -> MOV<.f> b, s12 -> MOV<.f> b, limm. */ - RELAX_TABLE_ENTRY(8, 0, 2, ARC_RLX_MOV_S12), - RELAX_TABLE_ENTRY(8, 0, 4, ARC_RLX_MOV_LIMM), - RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE), + RELAX_TABLE_ENTRY (8, 0, 2, ARC_RLX_MOV_S12), + RELAX_TABLE_ENTRY (8, 0, 4, ARC_RLX_MOV_LIMM), + RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE), /* SUB_S c, b, u3 -> SUB<.f> a, b, u6 -> SUB<.f> a, b, limm. */ - RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_SUB_U6), - RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_SUB_LIMM), - RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE), + RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_SUB_U6), + RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_SUB_LIMM), + RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE), /* MPY<.f> a, b, u6 -> MPY<.f> a, b, limm. */ - RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MPY_LIMM), - RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE), + RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MPY_LIMM), + RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE), /* MOV<.f><.cc> b, u6 -> MOV<.f><.cc> b, limm. */ - RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MOV_RLIMM), - RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE), + RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MOV_RLIMM), + RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE), /* ADD<.f><.cc> b, b, u6 -> ADD<.f><.cc> b, b, limm. */ - RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_RRLIMM), - RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE), + RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_RRLIMM), + RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE), }; /* Order of this table's entries matters! */ @@ -979,6 +989,8 @@ debug_exp (expressionS *t) case O_logical_or: name = "O_logical_or"; break; case O_index: name = "O_index"; break; case O_bracket: name = "O_bracket"; break; + case O_colon: name = "O_colon"; break; + case O_addrtype: name = "O_addrtype"; break; } switch (t->X_md) @@ -1067,6 +1079,16 @@ tokenize_arguments (char *str, ++num_args; break; + case ':': + input_line_pointer++; + if (!saw_arg || num_args == ntok) + goto err; + tok->X_op = O_colon; + saw_arg = FALSE; + ++tok; + ++num_args; + break; + case '@': /* We have labels, function names and relocations, all starting with @ symbol. Sort them out. */ @@ -1693,8 +1715,7 @@ find_opcode_match (const struct arc_opcode_hash_entry *entry, const struct arc_operand *operand = &arc_operands[*opidx]; /* Only take input from real operands. */ - if ((operand->flags & ARC_OPERAND_FAKE) - && !(operand->flags & ARC_OPERAND_BRAKET)) + if (ARC_OPERAND_IS_FAKE (operand)) continue; /* When we expect input, make sure we have it. */ @@ -1704,6 +1725,12 @@ find_opcode_match (const struct arc_opcode_hash_entry *entry, /* Match operand type with expression type. */ switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK) { + case ARC_OPERAND_ADDRTYPE: + /* Check to be an address type. */ + if (tok[tokidx].X_op != O_addrtype) + goto match_failed; + break; + case ARC_OPERAND_IR: /* Check to be a register. */ if ((tok[tokidx].X_op != O_register @@ -1755,6 +1782,12 @@ find_opcode_match (const struct arc_opcode_hash_entry *entry, goto match_failed; break; + case ARC_OPERAND_COLON: + /* Check if colon is also in opcode table as operand. */ + if (tok[tokidx].X_op != O_colon) + goto match_failed; + break; + case ARC_OPERAND_LIMM: case ARC_OPERAND_SIGNED: case ARC_OPERAND_UNSIGNED: @@ -2010,8 +2043,9 @@ pseudo_operand_match (const expressionS *tok, case O_symbol: /* Handle all symbols as long immediates or signed 9. */ - if (operand_real->flags & ARC_OPERAND_LIMM || - ((operand_real->flags & ARC_OPERAND_SIGNED) && operand_real->bits == 9)) + if (operand_real->flags & ARC_OPERAND_LIMM + || ((operand_real->flags & ARC_OPERAND_SIGNED) + && operand_real->bits == 9)) ret = TRUE; break; @@ -2094,8 +2128,8 @@ find_special_case_pseudo (const char *opname, operand_pseudo = &pseudo_insn->operand[i]; operand_real = &arc_operands[operand_pseudo->operand_idx]; - if (operand_real->flags & ARC_OPERAND_BRAKET && - !operand_pseudo->needs_insert) + if (operand_real->flags & ARC_OPERAND_BRAKET + && !operand_pseudo->needs_insert) continue; /* Has to be inserted (i.e. this token does not exist yet). */ @@ -2461,6 +2495,22 @@ declare_register_set (void) } } +/* Construct a symbol for an address type. */ + +static void +declare_addrtype (const char *name, int number) +{ + const char *err; + symbolS *addrtypeS = symbol_create (name, undefined_section, + number, &zero_address_frag); + + err = hash_insert (arc_addrtype_hash, S_GET_NAME (addrtypeS), + (void *) addrtypeS); + if (err) + as_fatal (_("Inserting \"%s\" into address type table failed: %s"), + name, err); +} + /* Port-specific assembler initialization. This function is called once, at assembler startup time. */ @@ -2575,6 +2625,28 @@ md_begin (void) as_fatal (_("internal error: can't hash aux register '%s': %s"), auxr->name, retval); } + + /* Address type declaration. */ + arc_addrtype_hash = hash_new (); + if (arc_addrtype_hash == NULL) + as_fatal (_("Virtual memory exhausted")); + + declare_addrtype ("bd", ARC_NPS400_ADDRTYPE_BD); + declare_addrtype ("jid", ARC_NPS400_ADDRTYPE_JID); + declare_addrtype ("lbd", ARC_NPS400_ADDRTYPE_LBD); + declare_addrtype ("mbd", ARC_NPS400_ADDRTYPE_MBD); + declare_addrtype ("sd", ARC_NPS400_ADDRTYPE_SD); + declare_addrtype ("sm", ARC_NPS400_ADDRTYPE_SM); + declare_addrtype ("xa", ARC_NPS400_ADDRTYPE_XA); + declare_addrtype ("xd", ARC_NPS400_ADDRTYPE_XD); + declare_addrtype ("cd", ARC_NPS400_ADDRTYPE_CD); + declare_addrtype ("cbd", ARC_NPS400_ADDRTYPE_CBD); + declare_addrtype ("cjid", ARC_NPS400_ADDRTYPE_CJID); + declare_addrtype ("clbd", ARC_NPS400_ADDRTYPE_CLBD); + declare_addrtype ("cm", ARC_NPS400_ADDRTYPE_CM); + declare_addrtype ("csd", ARC_NPS400_ADDRTYPE_CSD); + declare_addrtype ("cxa", ARC_NPS400_ADDRTYPE_CXA); + declare_addrtype ("cxd", ARC_NPS400_ADDRTYPE_CXD); } /* Write a value out to the object file, using the appropriate @@ -3254,7 +3326,7 @@ arc_parse_name (const char *name, if (!assembling_insn) return FALSE; - /* Handle only registers. */ + /* Handle only registers and address types. */ if (e->X_op != O_absent) return FALSE; @@ -3265,6 +3337,15 @@ arc_parse_name (const char *name, e->X_add_number = S_GET_VALUE (sym); return TRUE; } + + sym = hash_find (arc_addrtype_hash, name); + if (sym) + { + e->X_op = O_addrtype; + e->X_add_number = S_GET_VALUE (sym); + return TRUE; + } + return FALSE; } @@ -3726,8 +3807,7 @@ assemble_insn (const struct arc_opcode *opcode, const struct arc_operand *operand = &arc_operands[*argidx]; const expressionS *t = (const expressionS *) 0; - if ((operand->flags & ARC_OPERAND_FAKE) - && !(operand->flags & ARC_OPERAND_BRAKET)) + if (ARC_OPERAND_IS_FAKE (operand)) continue; if (operand->flags & ARC_OPERAND_DUPLICATE) @@ -3764,7 +3844,9 @@ assemble_insn (const struct arc_opcode *opcode, break; case O_bracket: - /* Ignore brackets. */ + case O_colon: + case O_addrtype: + /* Ignore brackets, colons, and address types. */ break; case O_absent: diff --git a/gas/testsuite/gas/arc/nps400-8.d b/gas/testsuite/gas/arc/nps400-8.d new file mode 100644 index 0000000000..9f5344c2d2 --- /dev/null +++ b/gas/testsuite/gas/arc/nps400-8.d @@ -0,0 +1,71 @@ +#as: -mcpu=arc700 -mnps400 +#objdump: -dr + +.*: +file format .*arc.* + +Disassembly of section .text: + +[0-9a-f]+ <.*>: + 0: 3810 0000 bdalc r0,\[cm:r0\],r0,r0 + 4: 3a10 00c1 bdalc r1,\[cm:r2\],r2,r3 + 8: 3850 0840 bdalc r0,\[cm:r0\],r0,0,0x1 + c: 3b50 0c42 bdalc r2,\[cm:r3\],r3,0x1,0x1 + 10: 3c50 0c03 bdalc r3,\[cm:r4\],r4,0x1,0x8 + 14: 3850 0040 sbdalc r0,r0,0 + 18: 3c50 0443 sbdalc r3,r4,0x1 + 1c: 3811 003e bdfre 0,\[cm:r0\],r0,r0 + 20: 3911 00be bdfre 0,\[cm:r1\],r1,r2 + 24: 3851 007e bdfre 0,\[cm:r0\],r0,0x1 + 28: 3a51 003e bdfre 0,\[cm:r2\],r2,0x8 + 2c: 3851 087e bdfre 0,\[cm:r0\],r0,0,0x1 + 30: 3e51 083e bdfre 0,\[cm:r6\],r6,0,0x8 + 34: 3851 0c7e bdfre 0,\[cm:r0\],r0,0x1,0x1 + 38: 3e51 0c3e bdfre 0,\[cm:r6\],r6,0x1,0x8 + 3c: 3817 003e sbdfre 0,r0,r0 + 40: 3917 00be sbdfre 0,r1,r2 + 44: 3818 003e bdbgt 0,r0,r0 + 48: 3c18 01be bdbgt 0,r4,r6 + 4c: 381c 0000 idxalc r0,\[cm:r0\],r0,r0 + 50: 3a1c 00c1 idxalc r1,\[cm:r2\],r2,r3 + 54: 3d5c 0884 idxalc r4,\[cm:r5\],r5,0x2 + 58: 385c 0040 sidxalc r0,r0 + 5c: 3a5c 0044 sidxalc r4,r2 + 60: 381e 003e idxfre 0,\[cm:r0\],r0,r0 + 64: 391e 00be idxfre 0,\[cm:r1\],r1,r2 + 68: 385e 007e idxfre 0,\[cm:r0\],r0,0x1 + 6c: 3a5e 003e idxfre 0,\[cm:r2\],r2,0x8 + 70: 381d 003e sidxfre 0,r0,r0 + 74: 391d 00be sidxfre 0,r1,r2 + 78: 3819 003e idxbgt 0,r0,r0 + 7c: 3f19 023e idxbgt 0,r7,r8 + 80: 3e0d 703e 0000 0000 efabgt 0,0,r0 + 88: 3e0d 70fe ffff ffff efabgt 0,0xffffffff,r3 + 90: 380d 0fbe 0000 0000 efabgt 0,r0,0 + 98: 3c0d 0fbe ffff ffff efabgt 0,r4,0xffffffff + a0: 380d 003e efabgt 0,r0,r0 + a4: 3f0d 023e efabgt 0,r7,r8 + a8: 3e0d 7000 0000 0000 efabgt r0,0,r0 + b0: 3e0d 7184 ffff ffff efabgt r4,0xffffffff,r6 + b8: 380d 0f80 0000 0000 efabgt r0,r0,0 + c0: 3b0d 0f82 ffff ffff efabgt r2,r3,0xffffffff + c8: 380d 0000 efabgt r0,r0,r0 + cc: 380d 1247 efabgt r7,r8,r9 + d0: 3e2f 7020 jobget 0,\[cjid:r0\] + d4: 3e2f 71a0 jobget 0,\[cjid:r6\] + d8: 3e2f 7021 jobget.cl 0,\[cjid:r0\] + dc: 3e2f 71a1 jobget.cl 0,\[cjid:r6\] + e0: 3812 003e jobdn 0,\[cjid:r0\],r0,r0 + e4: 3a12 013e jobdn 0,\[cjid:r2\],r2,r4 + e8: 3852 003e jobdn 0,\[cjid:r0\],r0,0 + ec: 3a52 03fe jobdn 0,\[cjid:r2\],r2,0xf + f0: 381f 0000 jobalc r0,\[cm:r0\],r0,r0 + f4: 3a1f 00c1 jobalc r1,\[cm:r2\],r2,r3 + f8: 385f 0840 jobalc r0,\[cm:r0\],r0,0x1 + fc: 3a5f 0801 jobalc r1,\[cm:r2\],r2,0x4 + 100: 385f 0040 sjobalc r0,r0 + 104: 3d5f 0046 sjobalc r6,r5 + 108: 381a 0000 jobbgt r0,r0,r0 + 10c: 3d1a 0182 jobbgt r2,r5,r6 + 110: 3e6f 70ff cnljob 0 + 114: 386f 0028 qseq r0,\[r0\] + 118: 3a6f 0128 qseq r2,\[r4\] diff --git a/gas/testsuite/gas/arc/nps400-8.s b/gas/testsuite/gas/arc/nps400-8.s new file mode 100644 index 0000000000..1042183f1d --- /dev/null +++ b/gas/testsuite/gas/arc/nps400-8.s @@ -0,0 +1,92 @@ + .text + + ;; bdalc / sbdalc + bdalc r0,[cm:r0],r0,r0 + bdalc r1,[cm:r2],r2,r3 + bdalc r0,[cm:r0],r0,0,1 + bdalc r2,[cm:r3],r3,1,1 + bdalc r3,[cm:r4],r4,1,8 + sbdalc r0, r0, 0 + sbdalc r3, r4, 1 + + ;; bdfre / sbdfre + bdfre 0,[cm:r0],r0,r0 + bdfre 0,[cm:r1],r1,r2 + bdfre 0,[cm:r0],r0,1 + bdfre 0,[cm:r2],r2,8 + bdfre 0,[cm:r0],r0,0,1 + bdfre 0,[cm:r6],r6,0,8 + bdfre 0,[cm:r0],r0,1,1 + bdfre 0,[cm:r6],r6,1,8 + sbdfre 0, r0, r0 + sbdfre 0, r1, r2 + + ;; bdbgt + bdbgt 0,r0,r0 + bdbgt 0,r4,r6 + + ;; idxalc / sidxalc + idxalc r0,[cm:r0],r0,r0 + idxalc r1,[cm:r2],r2,r3 + idxalc r4,[cm:r5],r5,2 + sidxalc r0,r0 + sidxalc r4,r2 + + ;; idxfre / sidxfre + idxfre 0,[cm:r0],r0,r0 + idxfre 0,[cm:r1],r1,r2 + idxfre 0,[cm:r0],r0,1 + idxfre 0,[cm:r2],r2,8 + sidxfre 0, r0, r0 + sidxfre 0, r1, r2 + + ;; idxbgt + idxbgt 0,r0,r0 + idxbgt 0,r7,r8 + + ;; efabgt + efabgt 0,0x0,r0 + efabgt 0,0xffffffff,r3 + efabgt 0,r0,0x0 + efabgt 0,r4,0xffffffff + efabgt 0,r0,r0 + efabgt 0,r7,r8 + efabgt r0,0x0,r0 + efabgt r4,0xffffffff,r6 + efabgt r0,r0,0x0 + efabgt r2,r3,0xffffffff + efabgt r0,r0,r0 + efabgt r7,r8,r9 + + ;; jobget + jobget 0,[cjid:r0] + jobget 0,[cjid:r6] + jobget.cl 0,[cjid:r0] + jobget.cl 0,[cjid:r6] + + ;; jobdn + jobdn 0,[cjid:r0],r0,r0 + jobdn 0,[cjid:r2],r2,r4 + jobdn 0,[cjid:r0],r0,0 + jobdn 0,[cjid:r2],r2,15 + + ;; jobalc / sjobalc + jobalc r0,[cm:r0],r0,r0 + jobalc r1,[cm:r2],r2,r3 + jobalc r0,[cm:r0],r0,1 + jobalc r1,[cm:r2],r2,4 + sjobalc r0,r0 + sjobalc r6,r5 + + ;; jobbgt + + jobbgt r0,r0,r0 + jobbgt r2,r5,r6 + + ;; cnljob + + cnljob 0 + + ;; qseq + qseq r0,[r0] + qseq r2,[r4] diff --git a/include/ChangeLog b/include/ChangeLog index 158be711ba..a87c9b6048 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,11 @@ +2016-07-27 Graham Markall + + * opcode/arc.h: Add ARC_OPERAND_ADDRTYPE, + ARC_OPERAND_COLON. Add the arc_nps_address_type enum and + ARC_NUM_ADDRTYPES. + * opcode/arc.h: Add BMU to insn_class_t enum. + * opcode/arc.h: Add PMU to insn_class_t enum. + 2016-07-20 Claudiu Zissulescu * dis-asm.h: Declare print_arc_disassembler_options. diff --git a/include/opcode/arc.h b/include/opcode/arc.h index f0fefbbc93..faa63dcdcb 100644 --- a/include/opcode/arc.h +++ b/include/opcode/arc.h @@ -38,71 +38,73 @@ extern "C" { /* Instruction Class. */ typedef enum - { - ACL, - ARITH, - AUXREG, - BITOP, - BRANCH, - CONTROL, - DPI, - DSP, - FLOAT, - INVALID, - JUMP, - KERNEL, - LOGICAL, - MEMORY, - NET, - } insn_class_t; +{ + ACL, + ARITH, + AUXREG, + BITOP, + BMU, + BRANCH, + CONTROL, + DPI, + DSP, + FLOAT, + INVALID, + JUMP, + KERNEL, + LOGICAL, + MEMORY, + NET, + PMU +} insn_class_t; /* Instruction Subclass. */ typedef enum - { - NONE, - CVT, - BTSCN, - CD1, - CD2, - COND, - DIV, - DP, - DPA, - DPX, - MPY1E, - MPY6E, - MPY7E, - MPY8E, - MPY9E, - NPS400, - QUARKSE, - SHFT1, - SHFT2, - SWAP, - SP, - SPX - } insn_subclass_t; +{ + NONE, + CVT, + BTSCN, + CD1, + CD2, + COND, + DIV, + DP, + DPA, + DPX, + MPY1E, + MPY6E, + MPY7E, + MPY8E, + MPY9E, + NPS400, + QUARKSE, + SHFT1, + SHFT2, + SWAP, + SP, + SPX +} insn_subclass_t; /* Flags class. */ typedef enum - { - F_CLASS_NONE = 0, +{ + F_CLASS_NONE = 0, - /* At most one flag from the set of flags can appear in the - instruction. */ - F_CLASS_OPTIONAL = (1 << 0), + /* At most one flag from the set of flags can appear in the + instruction. */ + F_CLASS_OPTIONAL = (1 << 0), - /* Exactly one from from the set of flags must appear in the - instruction. */ - F_CLASS_REQUIRED = (1 << 1), + /* Exactly one from from the set of flags must appear in the + instruction. */ + F_CLASS_REQUIRED = (1 << 1), - /* The conditional code can be extended over the standard variants - via .extCondCode pseudo-op. */ - F_CLASS_EXTEND = (1 << 2), + /* The conditional code can be extended over the standard variants + via .extCondCode pseudo-op. */ + F_CLASS_EXTEND = (1 << 2), - /* Condition code flag. */ - F_CLASS_COND = (1 << 3) - } flag_class_t; + /* Condition code flag. */ + F_CLASS_COND = (1 << 3) +} flag_class_t; /* The opcode table is an array of struct arc_opcode. */ struct arc_opcode @@ -336,11 +338,24 @@ extern const unsigned arc_NToperand; /* Mark the braket possition. */ #define ARC_OPERAND_BRAKET 0x1000 +/* Address type operand for NPS400. */ +#define ARC_OPERAND_ADDRTYPE 0x2000 + +/* Mark the colon position. */ +#define ARC_OPERAND_COLON 0x4000 + /* Mask for selecting the type for typecheck purposes. */ -#define ARC_OPERAND_TYPECHECK_MASK \ - (ARC_OPERAND_IR | \ - ARC_OPERAND_LIMM | ARC_OPERAND_SIGNED | \ - ARC_OPERAND_UNSIGNED | ARC_OPERAND_BRAKET) +#define ARC_OPERAND_TYPECHECK_MASK \ + (ARC_OPERAND_IR \ + | ARC_OPERAND_LIMM | ARC_OPERAND_SIGNED \ + | ARC_OPERAND_UNSIGNED | ARC_OPERAND_BRAKET \ + | ARC_OPERAND_ADDRTYPE | ARC_OPERAND_COLON) + +/* Macro to determine if an operand is a fake operand. */ +#define ARC_OPERAND_IS_FAKE(op) \ + ((operand->flags & ARC_OPERAND_FAKE) \ + && !((operand->flags & ARC_OPERAND_BRAKET) \ + || (operand->flags & ARC_OPERAND_COLON))) /* The flags structure. */ struct arc_flag_operand @@ -608,6 +623,67 @@ extern const unsigned char arg_32bit_rc[MAX_INSN_ARGS + 1]; extern const unsigned char arg_32bit_u6[MAX_INSN_ARGS + 1]; extern const unsigned char arg_32bit_limm[MAX_INSN_ARGS + 1]; +/* Address types used in the NPS-400. See page 367 of the NPS-400 CTOP + Instruction Set Reference Manual v2.4 for a description of address types. */ + +typedef enum +{ + /* Addresses in memory. */ + + /* Buffer descriptor. */ + ARC_NPS400_ADDRTYPE_BD, + + /* Job identifier. */ + ARC_NPS400_ADDRTYPE_JID, + + /* Linked Buffer Descriptor. */ + ARC_NPS400_ADDRTYPE_LBD, + + /* Multicast Buffer Descriptor. */ + ARC_NPS400_ADDRTYPE_MBD, + + /* Summarized Address. */ + ARC_NPS400_ADDRTYPE_SD, + + /* SMEM Security Context Local Memory. */ + ARC_NPS400_ADDRTYPE_SM, + + /* Extended Address. */ + ARC_NPS400_ADDRTYPE_XA, + + /* Extended Summarized Address. */ + ARC_NPS400_ADDRTYPE_XD, + + /* CMEM offset addresses. */ + + /* On-demand Counter Descriptor. */ + ARC_NPS400_ADDRTYPE_CD, + + /* CMEM Buffer Descriptor. */ + ARC_NPS400_ADDRTYPE_CBD, + + /* CMEM Job Identifier. */ + ARC_NPS400_ADDRTYPE_CJID, + + /* CMEM Linked Buffer Descriptor. */ + ARC_NPS400_ADDRTYPE_CLBD, + + /* CMEM Offset. */ + ARC_NPS400_ADDRTYPE_CM, + + /* CMEM Summarized Address. */ + ARC_NPS400_ADDRTYPE_CSD, + + /* CMEM Extended Address. */ + ARC_NPS400_ADDRTYPE_CXA, + + /* CMEM Extended Summarized Address. */ + ARC_NPS400_ADDRTYPE_CXD + +} arc_nps_address_type; + +#define ARC_NUM_ADDRTYPES 16 + #ifdef __cplusplus } #endif diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 66551db3c1..c218197aec 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,22 @@ +2016-07-27 Graham Markall + + * arc-nps400-tbl.h: Change block comments to GNU format. + * arc-dis.c: Add new globals addrtypenames, + addrtypenames_max, and addtypeunknown. + (get_addrtype): New function. + (print_insn_arc): Print colons and address types when + required. + * arc-opc.c: Add MAKE_INSERT_NPS_ADDRTYPE macro and use to + define insert and extract functions for all address types. + (arc_operands): Add operands for colon and all address + types. + * arc-nps-400-tbl.h: Add NPS-400 BMU instructions to opcode table. + * arc-opc.c: Add NPS_BD_TYPE and NPS_BMU_NUM operands, + insert_nps_bd_num_buff and extract_nps_bd_num_buff functions. + * arc-nps-400-tbl.h: Add NPS-400 PMU instructions to opcode table. + * arc-opc.c: Add NPS_PMU_NXT_DST and NPS_PMU_NUM_JOB operands, + insert_nps_pmu_num_job and extract_nps_pmu_num_job functions. + 2016-07-21 H.J. Lu * configure: Regenerated. diff --git a/opcodes/arc-dis.c b/opcodes/arc-dis.c index 7b78bdcb24..73d648d8cf 100644 --- a/opcodes/arc-dis.c +++ b/opcodes/arc-dis.c @@ -85,6 +85,16 @@ static const char * const regnames[64] = "r56", "r57", "ACCL", "ACCH", "lp_count", "rezerved", "LIMM", "pcl" }; +static const char * const addrtypenames[ARC_NUM_ADDRTYPES] = +{ + "bd", "jid", "lbd", "mbd", "sd", "sm", "xa", "xd", + "cd", "cbd", "cjid", "clbd", "cm", "csd", "cxa", "cxd" +}; + +static int addrtypenames_max = ARC_NUM_ADDRTYPES - 1; + +static const char * const addrtypeunknown = "unknown"; + /* This structure keeps track which instruction class(es) should be ignored durring disassembling. */ @@ -175,7 +185,7 @@ skip_this_opcode (const struct arc_opcode * opcode, /* If we found an incompatibility then we must skip. */ if (t != NULL) return TRUE; - + /* Even if we do not precisely know the if the right mnemonics is correctly displayed, keep the disassmbled code class consistent. */ @@ -653,6 +663,18 @@ get_auxreg (const struct arc_opcode *opcode, return NULL; } +/* Convert a value representing an address type to a string used to refer to + the address type in assembly code. */ + +static const char * +get_addrtype (int value) +{ + if (value < 0 || value > addrtypenames_max) + return addrtypeunknown; + + return addrtypenames[value]; +} + /* Calculate the instruction length for an instruction starting with MSB and LSB, the most and least significant byte. The ISA_MASK is used to filter the instructions considered to only those that are part of the @@ -1104,8 +1126,7 @@ print_insn_arc (bfd_vma memaddr, } /* Only take input from real operands. */ - if ((operand->flags & ARC_OPERAND_FAKE) - && !(operand->flags & ARC_OPERAND_BRAKET)) + if (ARC_OPERAND_IS_FAKE (operand)) continue; if ((operand->flags & ARC_OPERAND_IGNORE) @@ -1113,6 +1134,12 @@ print_insn_arc (bfd_vma memaddr, && value == -1) continue; + if (operand->flags & ARC_OPERAND_COLON) + { + (*info->fprintf_func) (info->stream, ":"); + continue; + } + if (need_comma) (*info->fprintf_func) (info->stream, ","); @@ -1124,6 +1151,8 @@ print_insn_arc (bfd_vma memaddr, continue; } + need_comma = TRUE; + /* Print the operand as directed by the flags. */ if (operand->flags & ARC_OPERAND_IR) { @@ -1145,6 +1174,7 @@ print_insn_arc (bfd_vma memaddr, else if (operand->flags & ARC_OPERAND_LIMM) { const char *rname = get_auxreg (opcode, value, isa_mask); + if (rname && open_braket) (*info->fprintf_func) (info->stream, "%s", rname); else @@ -1172,6 +1202,13 @@ print_insn_arc (bfd_vma memaddr, else (*info->fprintf_func) (info->stream, "%d", value); } + else if (operand->flags & ARC_OPERAND_ADDRTYPE) + { + const char *addrtype = get_addrtype (value); + (*info->fprintf_func) (info->stream, "%s", addrtype); + /* A colon follow an address type. */ + need_comma = FALSE; + } else { if (operand->flags & ARC_OPERAND_TRUNCATE @@ -1189,8 +1226,6 @@ print_insn_arc (bfd_vma memaddr, (*info->fprintf_func) (info->stream, "%#x", value); } } - - need_comma = TRUE; } return insn_len; diff --git a/opcodes/arc-ext.c b/opcodes/arc-ext.c index f7d2191f8d..c12cabee58 100644 --- a/opcodes/arc-ext.c +++ b/opcodes/arc-ext.c @@ -53,16 +53,16 @@ struct ExtAuxRegister { - long address; - char* name; - struct ExtAuxRegister* next; + long address; + char * name; + struct ExtAuxRegister * next; }; struct ExtCoreRegister { short number; enum ExtReadWrite rw; - char* name; + char * name; }; struct arcExtMap @@ -70,7 +70,7 @@ struct arcExtMap struct ExtAuxRegister* auxRegisters; struct ExtInstruction* instructions[INST_HASH_SIZE]; struct ExtCoreRegister coreRegisters[NUM_EXT_CORE]; - char* condCodes[NUM_EXT_COND]; + char * condCodes[NUM_EXT_COND]; }; diff --git a/opcodes/arc-nps400-tbl.h b/opcodes/arc-nps400-tbl.h index 580659a815..4ac038c475 100644 --- a/opcodes/arc-nps400-tbl.h +++ b/opcodes/arc-nps400-tbl.h @@ -1,4 +1,4 @@ -/**** Bit Manipulation Instructions ****/ +/* Bit Manipulation Instructions. */ /* movl<.cl> */ { "movh", 0x48080000, 0xf81f0000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST, NPS_R_SRC1, NPS_UIMM16 }, { 0 }}, @@ -148,7 +148,7 @@ /* crc32<.r> 0,limm,u6 00111 110 01 110100 R 111 uuuuuu 111110 */ { "crc32", 0x3e74703e, 0xffff703f, ARC_OPCODE_ARC700, BITOP, NPS400, { ZA, LIMM, UIMM6_20 }, { C_NPS_R }}, -/**** Arithmetic & Logic Instructions ****/ +/* Arithmetic & Logic Instructions. */ #define ADDB_LIKE(NAME,SUBOP2) \ { NAME, (0x48000000 | SUBOP2), 0xf80f001f, ARC_OPCODE_ARC700, ARITH, NPS400, { 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 }}, @@ -367,7 +367,7 @@ ADDL_LIKE ("xorl", 0xE, NPS_UIMM16) /* hofs a,b,min_hofs,psbc */ { "hofs", 0x38760000, 0xf8ff0000, ARC_OPCODE_ARC700, ARITH, NPS400, { RA, RB, NPS_MIN_HOFS, NPS_PSBC }, { C_F }}, -/**** Protocol Decoder Instructions ****/ +/* Protocol Decoder Instructions. */ /* dctcp b,c 00111bbb001011110bbbcccccc000000 */ { "dctcp", 0x382f0000, 0xf8ff803f, ARC_OPCODE_ARC700, NET, NPS400, { RB, RC }, { 0 }}, @@ -381,12 +381,12 @@ ADDL_LIKE ("xorl", 0xE, NPS_UIMM16) /* dcet a,b,c 00111bbb001000000bbbccccccaaaaaa */ { "dcet", 0x38200000, 0xf8ff8000, ARC_OPCODE_ARC700, NET, NPS400, { RA, RB, RC }, { 0 }}, -/**** ACL Instructions ****/ +/* ACL Instructions. */ /* dcacl<.f> a,b,c 00111bbb001001010bbbccccccaaaaaa */ { "dcacl", 0x38250000, 0xf8ff0000, ARC_OPCODE_ARC700, ACL, NPS400, { RA, RB, RC }, { C_F }}, -/**** DPI Instructions ****/ +/* DPI Instructions. */ /* hash dst,src1,src2,width,perm,nonlinear,basemat */ { "hash", 0x58180000, 0xf81f0000, ARC_OPCODE_ARC700, DPI, NPS400, { NPS_DPI_DST, NPS_DPI_SRC1_3B, NPS_R_SRC2_3B, NPS_HASH_WIDTH, NPS_HASH_PERM, NPS_HASH_NONLINEAR, NPS_HASH_BASEMAT }, { 0 }}, @@ -524,7 +524,7 @@ HASH_P(3, 0xC) /* ldbit<.x2|.x4>.di<.cl> a,[limm,c] 001001100011011X1111CCCCCCAAAAAA */ { "ldbit", 0x2636f000, 0xff3ef000, ARC_OPCODE_ARC700, DPI, NPS400, { RA, BRAKET, LIMM, RC, BRAKETdup }, { C_NPS_LDBIT_X_2, C_NPS_LDBIT_DI, C_NPS_LDBIT_CL2 }}, -/**** Pipeline Control Instructions ****/ +/* Pipeline Control Instructions. */ /* schd<.rw|.rd> */ { "schd", 0x3e6f7004, 0xffffff7f, ARC_OPCODE_ARC700, CONTROL, NPS400, { 0 }, { C_NPS_SCHD_RW }}, @@ -541,7 +541,7 @@ HASH_P(3, 0xC) /* hwscd.restore 0,C */ { "hwschd", 0x3e6f7003, 0xfffff03f, ARC_OPCODE_ARC700, CONTROL, NPS400, { ZA, RC }, { C_NPS_HWS_RESTORE }}, -/**** Load / Store From (0x57f00000 + Offset) Instructions ****/ +/* Load / Store From (0x57f00000 + Offset) Instructions. */ #define XLDST_LIKE(NAME,SUBOP2) \ { NAME, (0x58000000 | (SUBOP2 << 16)), 0xf81f0000, ARC_OPCODE_ARC700, MEMORY, NPS400, { NPS_R_DST, BRAKET, NPS_XLDST_UIMM16, BRAKETdup }, { 0 }}, @@ -552,3 +552,99 @@ XLDST_LIKE("xld", 0xa) XLDST_LIKE("xstb", 0xc) XLDST_LIKE("xstw", 0xd) XLDST_LIKE("xst", 0xe) + +/* BMU Instructions. */ + +/* sbdalc dst, src1, type */ +{ "sbdalc", 0x38500040, 0xf8ff09c0, ARC_OPCODE_ARC700, BMU, NPS400, { RA, RB, NPS_BD_TYPE }, { 0 }}, + +/* bdalc dst, [cm:src1], src1, src2 */ +{ "bdalc", 0x38100000, 0xf8ff0000, ARC_OPCODE_ARC700, BMU, NPS400, { RA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, RC }, { 0 }}, + +/* bdalc dst, [cm:src1], src1, type, num_buff */ +{ "bdalc", 0x38500800, 0xf8ff0800, ARC_OPCODE_ARC700, BMU, NPS400, { RA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, NPS_BD_TYPE, NPS_BMU_NUM }, { 0 }}, + +/* sbdfre 0, src1, src2 */ +{ "sbdfre", 0x3817003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, RB, RC }, { 0 }}, + +/* bdfre 0, [cm:src1], src1, src2 */ +{ "bdfre", 0x3811003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, RC }, { 0 }}, + +/* bdfre 0, [cm:src1], src1, type, num_buff */ +{ "bdfre", 0x3851083e, 0xf8ff083f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, NPS_BD_TYPE, NPS_BMU_NUM }, { 0 }}, + +/* bdfre 0, [cm:src1], src1, num_buff */ +{ "bdfre", 0x3851003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, NPS_BMU_NUM }, { 0 }}, + +/* bdbgt 0, src1, src2 */ +{ "bdbgt", 0x3818003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, RB, RC }, { 0 }}, + +/* sidxalc dst, src1 */ +{ "sidxalc", 0x385c0040, 0xf8ff0040, ARC_OPCODE_ARC700, BMU, NPS400, { RA, RB }, { 0 }}, + +/* idxalc dst, [cm:src1], src1, src2 */ +{ "idxalc", 0x381c0000, 0xf8ff0000, ARC_OPCODE_ARC700, BMU, NPS400, { RA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, RC }, { 0 }}, + +/* idxalc dst, [cm:src1], src1, num_idx */ +{ "idxalc", 0x385c0800, 0xf8ff0800, ARC_OPCODE_ARC700, BMU, NPS400, { RA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, NPS_BMU_NUM }, { 0 }}, + +/* sidxfre 0, src1, src2 */ +{ "sidxfre", 0x381d003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, RB, RC }, { 0 }}, + +/* idxfre 0, [cm:src1], src1, src2 */ +{ "idxfre", 0x381e003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, RC }, { 0 }}, + +/* idxfre 0, [cm:src1], src1, num_buff */ +{ "idxfre", 0x385e003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, NPS_BMU_NUM }, { 0 }}, + +/* idxbgt 0, src1, src2 */ +{ "idxbgt", 0x3819003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, RB, RC }, { 0 }}, + +/* efabgt 0, limm, src2 */ +{ "efabgt", 0x3e0d703e, 0xfffff03f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, LIMM, RC }, { 0 }}, + +/* efabgt 0, src1, limm */ +{ "efabgt", 0x380d0fbe, 0xf8ff80ff, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, RB, LIMM }, { 0 }}, + +/* efabgt 0, src1, src2 */ +{ "efabgt", 0x380d003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, RB, RC }, { 0 }}, + +/* efabgt dst, limm, src2 */ +{ "efabgt", 0x3e0d7000, 0xfffff000, ARC_OPCODE_ARC700, BMU, NPS400, { RA, LIMM, RC }, { 0 }}, + +/* efabgt dst, src1, limm */ +{ "efabgt", 0x380d0f80, 0xf8ff0fc0, ARC_OPCODE_ARC700, BMU, NPS400, { RA, RB, LIMM }, { 0 }}, + +/* efabgt dst, src1, src2 */ +{ "efabgt", 0x380d0000, 0xf8ff8000, ARC_OPCODE_ARC700, BMU, NPS400, { RA, RB, RC }, { 0 }}, + +/* PMU Instructions. */ + +/* jobget<.cl> 0, [cjid:src1] */ +{ "jobget", 0x3e2f7020, 0xfffff03f, ARC_OPCODE_ARC700, PMU, NPS400, { ZA, BRAKET, NPS_CJID, COLON, RC, BRAKET }, { 0 }}, + +{ "jobget", 0x3e2f7021, 0xfffff03f, ARC_OPCODE_ARC700, PMU, NPS400, { ZA, BRAKET, NPS_CJID, COLON, RC, BRAKET }, { C_NPS_CL }}, + +/* jobdn 0, [cjid:src1], src1, src2 */ +{ "jobdn", 0x3812003e, 0xf8ff803f, ARC_OPCODE_ARC700, PMU, NPS400, { ZA, BRAKET, NPS_CJID, COLON, RB, BRAKETdup, RBdup, RC }, { 0 }}, + +/* jobdn 0, [cjid:src1], src1, nxt_dst */ +{ "jobdn", 0x3852003e, 0xf8ff803f, ARC_OPCODE_ARC700, PMU, NPS400, { ZA, BRAKET, NPS_CJID, COLON, RB, BRAKETdup, RBdup, NPS_PMU_NXT_DST }, { 0 }}, + +/* sjobalc dst, src1 */ +{ "sjobalc", 0x385f0040, 0xf8ff8fc0, ARC_OPCODE_ARC700, PMU, NPS400, { RA, RB }, { 0 }}, + +/* jobalc dst, [cm:src1], src1, num_job */ +{ "jobalc", 0x385f0800, 0xf8ff8800, ARC_OPCODE_ARC700, PMU, NPS400, { RA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, NPS_PMU_NUM_JOB }, { 0 }}, + +/* jobalc dst, [cm:src1], src1, src2 */ +{ "jobalc", 0x381f0000, 0xf8ff8000, ARC_OPCODE_ARC700, PMU, NPS400, { RA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, RC }, { 0 }}, + +/* jobbgt dst, src1, src2 */ +{ "jobbgt", 0x381a0000, 0xf8ff0000, ARC_OPCODE_ARC700, PMU, NPS400, { RA, RB, RC }, { 0 }}, + +/* cnljob 0 */ +{ "cnljob", 0x3e6f70ff, 0xffffffff, ARC_OPCODE_ARC700, PMU, NPS400, { ZA }, { 0 }}, + +/* qseq dst, [src1] */ +{ "qseq", 0x386f0028, 0xf8ff803f, ARC_OPCODE_ARC700, PMU, NPS400, { RB, BRAKET, RC, BRAKETdup }, { 0 }}, diff --git a/opcodes/arc-opc.c b/opcodes/arc-opc.c index ad50ebca42..44dd7b2d32 100644 --- a/opcodes/arc-opc.c +++ b/opcodes/arc-opc.c @@ -962,17 +962,17 @@ extract_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED, \ return ((insn >> SHIFT) & ((1 << BITS) - 1)) + BIAS; \ } -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) +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, @@ -1134,10 +1134,12 @@ extract_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED, \ 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 (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, @@ -1160,6 +1162,42 @@ extract_nps_min_hofs (unsigned insn ATTRIBUTE_UNUSED, 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. */ @@ -2081,6 +2119,69 @@ const struct arc_operand arc_operands[] = #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);