[PATCH 7/7] arc: Implement NPS-400 dcmac instruction

Graham Markall graham.markall@embecosm.com
Wed Oct 26 12:47:00 GMT 2016


gas/ChangeLog:

       * testsuite/gas/arc/nps-400-9.d: Added.
       * testsuite/gas/arc/nps-400-9.s: Added.

include/ChangeLog:

       * opcode/arc.h: Add PROTOCOL_DECODE to insn_class_t.

opcodes/ChangeLog:

       * arc-dis.c (arc_insn_length): Return length 8 for instructions with
       major opcode 0xa.
       * arc-nps-400-tbl.h: Add dcmac instruction.
       * arc-opc.c (arc_operands): Added operands for dcmac instruction.
       (insert_nps_rbdouble_64): Added.
       (extract_nps_rbdouble_64): Added.
       (insert_nps_proto_size): Added.
       (extract_nps_proto_size): Added.
---
 gas/ChangeLog                    |  5 ++++
 gas/testsuite/gas/arc/nps400-9.d | 44 ++++++++++++++++++++++++++++++++++
 gas/testsuite/gas/arc/nps400-9.s | 51 ++++++++++++++++++++++++++++++++++++++++
 include/ChangeLog                |  4 ++++
 include/opcode/arc.h             |  1 +
 opcodes/ChangeLog                | 11 +++++++++
 opcodes/arc-dis.c                |  4 ++++
 opcodes/arc-nps400-tbl.h         | 38 ++++++++++++++++++++++++++++++
 opcodes/arc-opc.c                | 47 +++++++++++++++++++++++++++++++++++-
 9 files changed, 204 insertions(+), 1 deletion(-)
 create mode 100644 gas/testsuite/gas/arc/nps400-9.d
 create mode 100644 gas/testsuite/gas/arc/nps400-9.s

diff --git a/gas/testsuite/gas/arc/nps400-9.d b/gas/testsuite/gas/arc/nps400-9.d
new file mode 100644
index 0000000..a3d25c0
--- /dev/null
+++ b/gas/testsuite/gas/arc/nps400-9.d
@@ -0,0 +1,44 @@
+#as: -mcpu=arc700 -mnps400
+#objdump: -dr
+
+.*: +file format .*arc.*
+
+Disassembly of section .text:
+
+[0-9a-f]+ <.*>:
+   0:	5000 07c0 2400 0000 	dcmac	r0,\[cm:r0\],\[cm:r0\],r0
+   8:	5044 3fc0 2400 0000 	dcmac	r2,\[cm:r4\],\[cm:r7\],r7
+  10:	53ff ffc0 2400 0000 	dcmac	blink,\[cm:blink\],\[cm:blink\],blink
+  18:	5000 07c0 2600 0000 	dcmac	r0,\[cm:r0\],\[cm:0\],r0
+  20:	5044 3fc0 2600 1234 	dcmac	r2,\[cm:r4\],\[cm:0x1234\],r7
+  28:	53ff ffc0 2600 ffff 	dcmac	blink,\[cm:blink\],\[cm:0xffff\],blink
+  30:	5000 07c0 2700 0000 	dcmac	r0,\[cm:0\],\[cm:r0\],r0
+  38:	5044 3fc0 2700 4321 	dcmac	r2,\[cm:0x4321\],\[cm:r4\],r7
+  40:	53ff ffc0 2700 ffff 	dcmac	blink,\[cm:0xffff\],\[cm:blink\],blink
+  48:	57c0 07c0 2400 0000 	dcmac	0,\[cm:r0\],\[cm:r0\],r0
+  50:	57c4 3fc0 2400 0000 	dcmac	0,\[cm:r4\],\[cm:r7\],r7
+  58:	57df ffc0 2400 0000 	dcmac	0,\[cm:blink\],\[cm:blink\],blink
+  60:	57c0 07c0 2600 0000 	dcmac	0,\[cm:r0\],\[cm:0\],r0
+  68:	57c4 3fc0 2600 1234 	dcmac	0,\[cm:r4\],\[cm:0x1234\],r7
+  70:	57df ffc0 2600 ffff 	dcmac	0,\[cm:blink\],\[cm:0xffff\],blink
+  78:	57c0 07c0 2700 0000 	dcmac	0,\[cm:0\],\[cm:r0\],r0
+  80:	57c4 3fc0 2700 4321 	dcmac	0,\[cm:0x4321\],\[cm:r4\],r7
+  88:	57df ffc0 2700 ffff 	dcmac	0,\[cm:0xffff\],\[cm:blink\],blink
+  90:	5000 07c0 2001 0000 	dcmac	r0,\[cm:r0\],\[cm:r0\],0x1
+  98:	5044 27c0 200f 0000 	dcmac	r2,\[cm:r4\],\[cm:r4\],0xf
+  a0:	53ff ffc0 203f 0000 	dcmac	blink,\[cm:blink\],\[cm:blink\],0x3f
+  a8:	5000 07c0 2201 0000 	dcmac	r0,\[cm:r0\],\[cm:0\],0x1
+  b0:	5044 27c0 220f 1234 	dcmac	r2,\[cm:r4\],\[cm:0x1234\],0xf
+  b8:	53ff ffc0 223f ffff 	dcmac	blink,\[cm:blink\],\[cm:0xffff\],0x3f
+  c0:	5000 07c0 2301 0000 	dcmac	r0,\[cm:0\],\[cm:r0\],0x1
+  c8:	5044 27c0 230f 4321 	dcmac	r2,\[cm:0x4321\],\[cm:r4\],0xf
+  d0:	53ff ffc0 233f ffff 	dcmac	blink,\[cm:0xffff\],\[cm:blink\],0x3f
+  d8:	57c0 07c0 2001 0000 	dcmac	0,\[cm:r0\],\[cm:r0\],0x1
+  e0:	57c4 27c0 200f 0000 	dcmac	0,\[cm:r4\],\[cm:r4\],0xf
+  e8:	57df ffc0 2000 0000 	dcmac	0,\[cm:blink\],\[cm:blink\],0x40
+  f0:	57c0 07c0 2201 0000 	dcmac	0,\[cm:r0\],\[cm:0\],0x1
+  f8:	57c4 27c0 220f 1234 	dcmac	0,\[cm:r4\],\[cm:0x1234\],0xf
+ 100:	57df ffc0 2200 ffff 	dcmac	0,\[cm:blink\],\[cm:0xffff\],0x40
+ 108:	57c0 07c0 2301 0000 	dcmac	0,\[cm:0\],\[cm:r0\],0x1
+ 110:	57c4 27c0 230f 4321 	dcmac	0,\[cm:0x4321\],\[cm:r4\],0xf
+ 118:	57df ffc0 2300 ffff 	dcmac	0,\[cm:0xffff\],\[cm:blink\],0x40
diff --git a/gas/testsuite/gas/arc/nps400-9.s b/gas/testsuite/gas/arc/nps400-9.s
new file mode 100644
index 0000000..a91489d
--- /dev/null
+++ b/gas/testsuite/gas/arc/nps400-9.s
@@ -0,0 +1,51 @@
+        .text
+
+        ;; dcmac
+        dcmac r0,[cm:r0],[cm:r0],r0
+        dcmac r2,[cm:r4],[cm:r4],r7
+        dcmac r31,[cm:r31],[cm:r31],r31
+
+        dcmac r0,[cm:r0],[cm:0x0],r0
+        dcmac r2,[cm:r4],[cm:0x1234],r7
+        dcmac r31,[cm:r31],[cm:0xffff],r31
+
+        dcmac r0,[cm:0x0],[cm:r0],r0
+        dcmac r2,[cm:0x4321],[cm:r4],r7
+        dcmac r31,[cm:0xffff],[cm:r31],r31
+
+        dcmac 0,[cm:r0],[cm:r0],r0
+        dcmac 0,[cm:r4],[cm:r4],r7
+        dcmac 0,[cm:r31],[cm:r31],r31
+
+        dcmac 0,[cm:r0],[cm:0x0],r0
+        dcmac 0,[cm:r4],[cm:0x1234],r7
+        dcmac 0,[cm:r31],[cm:0xffff],r31
+
+        dcmac 0,[cm:0x0],[cm:r0],r0
+        dcmac 0,[cm:0x4321],[cm:r4],r7
+        dcmac 0,[cm:0xffff],[cm:r31],r31
+
+        dcmac r0,[cm:r0],[cm:r0],1
+        dcmac r2,[cm:r4],[cm:r4],0xf
+        dcmac r31,[cm:r31],[cm:r31],0x3f
+
+        dcmac r0,[cm:r0],[cm:0x0],1
+        dcmac r2,[cm:r4],[cm:0x1234],0xf
+        dcmac r31,[cm:r31],[cm:0xffff],0x3f
+
+        dcmac r0,[cm:0x0],[cm:r0],1
+        dcmac r2,[cm:0x4321],[cm:r4],0xf
+        dcmac r31,[cm:0xffff],[cm:r31],0x3f
+
+        dcmac 0,[cm:r0],[cm:r0],1
+        dcmac 0,[cm:r4],[cm:r4],0xf
+        dcmac 0,[cm:r31],[cm:r31],64
+
+        dcmac 0,[cm:r0],[cm:0x0],1
+        dcmac 0,[cm:r4],[cm:0x1234],0xf
+        dcmac 0,[cm:r31],[cm:0xffff],64
+
+        dcmac 0,[cm:0x0],[cm:r0],1
+        dcmac 0,[cm:0x4321],[cm:r4],0xf
+        dcmac 0,[cm:0xffff],[cm:r31],64
+
diff --git a/include/opcode/arc.h b/include/opcode/arc.h
index f5cb9e9..2214b2f 100644
--- a/include/opcode/arc.h
+++ b/include/opcode/arc.h
@@ -56,6 +56,7 @@ typedef enum
   LOGICAL,
   MEMORY,
   NET,
+  PROTOCOL_DECODE,
   PMU,
   XY
 } insn_class_t;
diff --git a/opcodes/arc-dis.c b/opcodes/arc-dis.c
index 1c951ea..31b5a91 100644
--- a/opcodes/arc-dis.c
+++ b/opcodes/arc-dis.c
@@ -595,6 +595,10 @@ arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info)
 	  else if (minor_opcode == 0x10 || minor_opcode == 0x11)
 	    return 8;
         }
+      if (major_opcode == 0xa)
+        {
+          return 8;
+        }
       /* Fall through.  */
     case bfd_mach_arc_arc600:
       return (major_opcode > 0xb) ? 2 : 4;
diff --git a/opcodes/arc-nps400-tbl.h b/opcodes/arc-nps400-tbl.h
index e9a5d95..8585450 100644
--- a/opcodes/arc-nps400-tbl.h
+++ b/opcodes/arc-nps400-tbl.h
@@ -675,3 +675,41 @@ XLDST_LIKE("xst", 0xe)
 
 /* qseq dst, [src1] */
 { "qseq", 0x386f0028, 0xf8ff803f, ARC_OPCODE_ARC700, PMU, NPS400, { RB, BRAKET, RC, BRAKETdup }, { 0 }},
+
+/* Protocol Decode Instructions.  */
+
+/* dcmac  0,[cm:b],[cm:b],c */
+{ "dcmac", 0x57c007c024000000, 0xffe007ffffffffff, ARC_OPCODE_ARC700, PROTOCOL_DECODE, NPS400, { ZA, BRAKET, NPS_CM, COLON, NPS_RB_64, BRAKETdup, BRAKET, NPS_CM, COLON, NPS_RBdup_64, BRAKETdup, NPS_RC_64 }, { 0 }},
+
+/* dcmac  0,[cm:b],[cm:A],c */
+{ "dcmac", 0x57c007c026000000, 0xffe007ffffff0000, ARC_OPCODE_ARC700, PROTOCOL_DECODE, NPS400, { ZA, BRAKET, NPS_CM, COLON, NPS_RB_64, BRAKETdup, BRAKET, NPS_CM, COLON, NPS_UIMM16_0_64, BRAKETdup, NPS_RC_64 }, { 0 }},
+
+/* dcmac  0,[cm:A],[cm:b],c */
+{ "dcmac", 0x57c007c027000000, 0xffe007ffffff0000, ARC_OPCODE_ARC700, PROTOCOL_DECODE, NPS400, { ZA, BRAKET, NPS_CM, COLON, NPS_UIMM16_0_64, BRAKETdup, BRAKET, NPS_CM, COLON, NPS_RB_64, BRAKETdup, NPS_RC_64 }, { 0 }},
+
+/* dcmac  a,[cm:b],[cm:b],c */
+{ "dcmac", 0x500007c024000000, 0xf80007ffffffffff, ARC_OPCODE_ARC700, PROTOCOL_DECODE, NPS400, { NPS_RA_64, BRAKET, NPS_CM, COLON, NPS_RB_64, BRAKETdup, BRAKET, NPS_CM, COLON, NPS_RBdup_64, BRAKETdup, NPS_RC_64 }, { 0 }},
+
+/* dcmac  a,[cm:b],[cm:A],c */
+{ "dcmac", 0x500007c026000000, 0xf80007ffffff0000, ARC_OPCODE_ARC700, PROTOCOL_DECODE, NPS400, { NPS_RA_64, BRAKET, NPS_CM, COLON, NPS_RB_64, BRAKETdup, BRAKET, NPS_CM, COLON, NPS_UIMM16_0_64, BRAKETdup, NPS_RC_64 }, { 0 }},
+
+/* dcmac  a,[cm:A],[cm:b],c */
+{ "dcmac", 0x500007c027000000, 0xf80007ffffff0000, ARC_OPCODE_ARC700, PROTOCOL_DECODE, NPS400, { NPS_RA_64, BRAKET, NPS_CM, COLON, NPS_UIMM16_0_64, BRAKETdup, BRAKET, NPS_CM, COLON, NPS_RB_64, BRAKETdup, NPS_RC_64 }, { 0 }},
+
+/* dcmac  0,[cm:b],[cm:b],size */
+{ "dcmac", 0x57c007c020000000, 0xffe007ffffc0ffff, ARC_OPCODE_ARC700, PROTOCOL_DECODE, NPS400, { ZA, BRAKET, NPS_CM, COLON, NPS_RBdouble_64, BRAKETdup, BRAKET, NPS_CM, COLON, NPS_RBdup_64, BRAKETdup, NPS_PROTO_SIZE }, { 0 }},
+
+/* dcmac  0,[cm:b],[cm:A],size */
+{ "dcmac", 0x57c007c022000000, 0xffe007ffffc00000, ARC_OPCODE_ARC700, PROTOCOL_DECODE, NPS400, { ZA, BRAKET, NPS_CM, COLON, NPS_RBdouble_64, BRAKETdup, BRAKET, NPS_CM, COLON, NPS_UIMM16_0_64, BRAKETdup, NPS_PROTO_SIZE }, { 0 }},
+
+/* dcmac  0,[cm:A],[cm:b],size */
+{ "dcmac", 0x57c007c023000000, 0xffe007ffffc00000, ARC_OPCODE_ARC700, PROTOCOL_DECODE, NPS400, { ZA, BRAKET, NPS_CM, COLON, NPS_UIMM16_0_64, BRAKETdup, BRAKET, NPS_CM, COLON, NPS_RBdouble_64, BRAKETdup, NPS_PROTO_SIZE }, { 0 }},
+
+/* dcmac  a,[cm:b],[cm:b],size */
+{ "dcmac", 0x500007c020000000, 0xf80007ffffc0ffff, ARC_OPCODE_ARC700, PROTOCOL_DECODE, NPS400, { NPS_RA_64, BRAKET, NPS_CM, COLON, NPS_RBdouble_64, BRAKETdup, BRAKET, NPS_CM, COLON, NPS_RBdup_64, BRAKETdup, NPS_PROTO_SIZE }, { 0 }},
+
+/* dcmac  a,[cm:b],[cm:A],size */
+{ "dcmac", 0x500007c022000000, 0xf80007ffffc00000, ARC_OPCODE_ARC700, PROTOCOL_DECODE, NPS400, { NPS_RA_64, BRAKET, NPS_CM, COLON, NPS_RBdouble_64, BRAKETdup, BRAKET, NPS_CM, COLON, NPS_UIMM16_0_64, BRAKETdup, NPS_PROTO_SIZE }, { 0 }},
+
+/* dcmac  a,[cm:A],[cm:b],size */
+{ "dcmac", 0x500007c023000000, 0xf80007ffffc00000, ARC_OPCODE_ARC700, PROTOCOL_DECODE, NPS400, { NPS_RA_64, BRAKET, NPS_CM, COLON, NPS_UIMM16_0_64, BRAKETdup, BRAKET, NPS_CM, COLON, NPS_RBdouble_64, BRAKETdup, NPS_PROTO_SIZE }, { 0 }},
diff --git a/opcodes/arc-opc.c b/opcodes/arc-opc.c
index ee14fed..58b26ea 100644
--- a/opcodes/arc-opc.c
+++ b/opcodes/arc-opc.c
@@ -1026,6 +1026,7 @@ 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)
+MAKE_1BASED_INSERT_EXTRACT_FUNCS (proto_size, 16, 64, 6)
 
 static unsigned long long
 insert_nps_min_hofs (unsigned long long insn ATTRIBUTE_UNUSED,
@@ -1083,6 +1084,30 @@ MAKE_INSERT_NPS_ADDRTYPE (csd, CSD)
 MAKE_INSERT_NPS_ADDRTYPE (cxa, CXA)
 MAKE_INSERT_NPS_ADDRTYPE (cxd, CXD)
 
+static unsigned long long
+insert_nps_rbdouble_64 (unsigned long long insn ATTRIBUTE_UNUSED,
+                        long long int value ATTRIBUTE_UNUSED,
+                        const char **errmsg ATTRIBUTE_UNUSED)
+{
+  if (value < 0 || value > 31)
+    *errmsg = _("Value must be in the range 0 to 31");
+  return insn | (value << 43) | (value << 48);
+}
+
+
+static long long int
+extract_nps_rbdouble_64 (unsigned long long insn ATTRIBUTE_UNUSED,
+                         bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value1 = (insn >> 43) & 0x1F;
+  int value2 = (insn >> 48) & 0x1F;
+
+  if (value1 != value2)
+    *invalid = TRUE;
+
+  return value1;
+}
+
 /* Include the generic extract/insert functions.  Order is important
    as some of the functions present in the .h may be disabled via
    defines.  */
@@ -2088,8 +2113,28 @@ const struct arc_operand arc_operands[] =
 
 #define NPS_R_SRC2_3B_64	(NPS_R_SRC1_3B_64 + 1)
   { 3, 53, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_reg_at_53_src2, extract_nps_3bit_reg_at_53_src2 },
-};
 
+#define NPS_RA_64               (NPS_R_SRC2_3B_64 + 1)
+  { 6, 53, 0, ARC_OPERAND_IR, NULL, NULL },
+
+#define NPS_RB_64               (NPS_RA_64 + 1)
+  { 5, 48, 0, ARC_OPERAND_IR, NULL, NULL },
+
+#define NPS_RBdup_64            (NPS_RB_64 + 1)
+  { 5, 43, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE, NULL, NULL },
+
+#define NPS_RBdouble_64         (NPS_RBdup_64 + 1)
+  { 10, 43, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_rbdouble_64, extract_nps_rbdouble_64 },
+
+#define NPS_RC_64               (NPS_RBdouble_64 + 1)
+  { 5, 43, 0, ARC_OPERAND_IR, NULL, NULL },
+
+#define NPS_UIMM16_0_64         (NPS_RC_64 + 1)
+  { 16, 0, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_PROTO_SIZE         (NPS_UIMM16_0_64 + 1)
+  { 6, 16, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_proto_size, extract_nps_proto_size }
+};
 const unsigned arc_num_operands = ARRAY_SIZE (arc_operands);
 
 const unsigned arc_Toperand = FKT_T;
-- 
2.7.4



More information about the Binutils mailing list