This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][GAS][AArch64] Add dot product support for AArch64 to binutils [Patch (1/2)]


Hi All,

This patch adds assembler and disassembler support for new Dot Product
instructions to AArch64.
    
The support can be enabled through the new "+dotprod" extension.
    
"+dotprod" extension is an optional extension to ARMv8.2-A onwards.

Ok for Trunk?

Ps. I do not have commit access so if OK can someone apply for me?

Thanks,
Tamar


gas/
2017-06-28  Tamar Christina  <tamar.christina@arm.com>


	* config/tc-aarch64.c (aarch64_reg_parse_32_64):
	Accept 4B.
	(aarch64_features): Added dotprod.
	doc/c-aarch64.texi: Added dotprod.

opcodes/
2017-06-28  Tamar Christina  <tamar.christina@arm.com>


	* aarch64-asm.c (aarch64_ins_reglane): Added 4B dotprod.
	* aarch64-dis.c (aarch64_ext_reglane): Likewise.
	* aarch64-tbl.h (QL_V3DOT, QL_V2DOT): New.
	(aarch64_feature_dotprod, DOT_INSN): New.
	(udot, sdot): New.


include/
2017-06-28  Tamar Christina  <tamar.christina@arm.com>


	* opcode/aarch64.h: (AARCH64_FEATURE_DOTPROD): New.
	(aarch64_insn_class): Added dotprod.
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index be01bdd1432b9eda741b781dbd275aecc40144bc..d6be04783649252f9a75925df5f8039a54a73d3a 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -798,7 +798,7 @@ aarch64_reg_parse_32_64 (char **ccp, aarch64_opnd_qualifier_t *qualifier)
    succeeds; otherwise return FALSE.
 
    Accept only one occurrence of:
-   8b 16b 2h 4h 8h 2s 4s 1d 2d
+   4b 8b 16b 2h 4h 8h 2s 4s 1d 2d
    b h s d q  */
 static bfd_boolean
 parse_vector_type_for_operand (aarch64_reg_type reg_type,
@@ -859,8 +859,10 @@ elt_size:
 	first_error (_("missing element size"));
       return FALSE;
     }
-  if (width != 0 && width * element_size != 64 && width * element_size != 128
-      && !(width == 2 && element_size == 16))
+  if (width != 0 && width * element_size != 64
+      && width * element_size != 128
+      && !(width == 2 && element_size == 16)
+      && !(width == 4 && element_size == 8))
     {
       first_error_fmt (_
 		       ("invalid element size %d and vector size combination %c"),
@@ -8479,6 +8481,8 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = {
 					 | AARCH64_FEATURE_SIMD, 0)},
   {"rcpc",		AARCH64_FEATURE (AARCH64_FEATURE_RCPC, 0),
 			AARCH64_ARCH_NONE},
+  {"dotprod",		AARCH64_FEATURE (AARCH64_FEATURE_DOTPROD, 0),
+			AARCH64_ARCH_NONE},
   {NULL,		AARCH64_ARCH_NONE, AARCH64_ARCH_NONE},
 };
 
diff --git a/gas/doc/c-aarch64.texi b/gas/doc/c-aarch64.texi
index 2a01c3f5e7f3e7cf247d9328d53e3c0465da8de7..c16305a4ec26524445b582f0738291c50e5cf72a 100644
--- a/gas/doc/c-aarch64.texi
+++ b/gas/doc/c-aarch64.texi
@@ -163,6 +163,8 @@ automatically cause those extensions to be disabled.
 @item @code{sve} @tab ARMv8.2-A @tab No
  @tab Enable the Scalable Vector Extensions.  This implies @code{fp16},
  @code{simd} and @code{compnum}.
+@item @code{dotprod} @tab ARMv8.2-A @tab No
+ @tab Enable the Dot Product extension.  This implies @code{simd}.
 @end multitable
 
 @node AArch64 Syntax
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 37e2486b3c483765c3c117a4fc3d0f90e902890c..c5788e2d09d90b0c81f4e3386aa588f53c74c5b3 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -55,6 +55,7 @@ typedef uint32_t aarch64_insn;
 #define AARCH64_FEATURE_SVE	0x10000000	/* SVE instructions.  */
 #define AARCH64_FEATURE_RCPC	0x20000000	/* RCPC instructions.  */
 #define AARCH64_FEATURE_COMPNUM	0x40000000	/* Complex # instructions.  */
+#define AARCH64_FEATURE_DOTPROD 0x080000000     /* Dot Product instructions.  */
 
 /* Architectures are the sum of the base and extensions.  */
 #define AARCH64_ARCH_V8		AARCH64_FEATURE (AARCH64_FEATURE_V8, \
@@ -508,6 +509,7 @@ enum aarch64_insn_class
   sve_size_hsd,
   sve_size_sd,
   testbranch,
+  dotproduct,
 };
 
 /* Opcode enumerators.  */
diff --git a/opcodes/aarch64-asm.c b/opcodes/aarch64-asm.c
index 6d2c75a068e94b163618e412b47c546326cc6af5..345d59902e0330afefc7de010e0f6e6272763df1 100644
--- a/opcodes/aarch64-asm.c
+++ b/opcodes/aarch64-asm.c
@@ -121,6 +121,20 @@ aarch64_ins_reglane (const aarch64_operand *self, const aarch64_opnd_info *info,
 	  insert_field (FLD_imm5, code, value, 0);
 	}
     }
+  else if (inst->opcode->iclass == dotproduct)
+    {
+      unsigned reglane_index = info->reglane.index;
+      switch (info->qualifier)
+	{
+	case AARCH64_OPND_QLF_S_B:
+	  /* L:H */
+	  assert (reglane_index < 4);
+	  insert_fields (code, reglane_index, 0, 2, FLD_L, FLD_H);
+	  break;
+	default:
+	  assert (0);
+	}
+    }
   else
     {
       /* index for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
index e5fe61f51d13e06342947437ec80731f692e2628..1d2596f410ad717a939a381b1063b275cb3bb15e 100644
--- a/opcodes/aarch64-dis.c
+++ b/opcodes/aarch64-dis.c
@@ -325,6 +325,21 @@ aarch64_ext_reglane (const aarch64_operand *self, aarch64_opnd_info *info,
 	  info->reglane.index = (unsigned) (value >> 1);
 	}
     }
+  else if (inst->opcode->iclass == dotproduct)
+    {
+      /* Need information in other operand(s) to help decoding.  */
+      info->qualifier = get_expected_qualifier (inst, info->idx);
+      switch (info->qualifier)
+	{
+	case AARCH64_OPND_QLF_S_B:
+	  /* L:H */
+	  info->reglane.index = extract_fields (code, 0, 2, FLD_H, FLD_L);
+	  info->reglane.regno &= 0x1f;
+	  break;
+	default:
+	  return 0;
+	}
+    }
   else
     {
       /* Index only for e.g. SQDMLAL <Va><d>, <Vb><n>, <Vm>.<Ts>[<index>]
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index a7510ff5ead2d87fc06f76d15013a5dcc1bb30cc..61c2582d01167e0b854d83f5d72f68fc80d44053 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -1982,6 +1982,19 @@
 {                                                       \
   QLF3(X,X,NIL),                                        \
 }
+/* e.g. UDOT <Vd>.2S, <Vn>.8B, <Vm>.8B.  */
+#define QL_V3DOT	   \
+{			   \
+  QLF3(V_2S, V_8B,  V_8B), \
+  QLF3(V_4S, V_16B, V_16B),\
+}
+
+/* e.g. UDOT <Vd>.2S, <Vn>.8B, <Vm>.4B[<index>].  */
+#define QL_V2DOT	 \
+{			 \
+  QLF3(V_2S, V_8B,  S_B),\
+  QLF3(V_4S, V_16B, S_B),\
+}
 
 /* Opcode table.  */
 
@@ -2021,6 +2034,8 @@ static const aarch64_feature_set aarch64_feature_compnum =
   AARCH64_FEATURE (AARCH64_FEATURE_COMPNUM, 0);
 static const aarch64_feature_set aarch64_feature_rcpc =
   AARCH64_FEATURE (AARCH64_FEATURE_RCPC, 0);
+static const aarch64_feature_set aarch64_feature_dotprod =
+  AARCH64_FEATURE (AARCH64_FEATURE_V8_2 | AARCH64_FEATURE_DOTPROD, 0);
 
 #define CORE		&aarch64_feature_v8
 #define FP		&aarch64_feature_fp
@@ -2040,6 +2055,7 @@ static const aarch64_feature_set aarch64_feature_rcpc =
 #define FP_V8_3		&aarch64_feature_fp_v8_3
 #define COMPNUM		&aarch64_feature_compnum
 #define RCPC		&aarch64_feature_rcpc
+#define DOTPROD		&aarch64_feature_dotprod
 
 #define CORE_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS) \
   { NAME, OPCODE, MASK, CLASS, OP, CORE, OPS, QUALS, FLAGS, 0, NULL }
@@ -2072,6 +2088,8 @@ static const aarch64_feature_set aarch64_feature_rcpc =
   { NAME, OPCODE, MASK, CLASS, OP, COMPNUM, OPS, QUALS, FLAGS, 0, NULL }
 #define RCPC_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
   { NAME, OPCODE, MASK, CLASS, 0, RCPC, OPS, QUALS, FLAGS, 0, NULL }
+#define DOT_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
+  { NAME, OPCODE, MASK, CLASS, 0, DOTPROD, OPS, QUALS, FLAGS, 0, NULL }
 
 struct aarch64_opcode aarch64_opcode_table[] =
 {
@@ -4137,6 +4155,12 @@ struct aarch64_opcode aarch64_opcode_table[] =
   _SVE_INSN ("fmov", 0x05104000, 0xff30ffe0, sve_size_hsd, 0, OP3 (SVE_Zd, SVE_Pg4_16, FPIMM0), OP_SVE_VM_HSD, F_ALIAS | F_PSEUDO, 0),
   _SVE_INSN ("orn", 0x05000000, 0xfffc0000, sve_limm, 0, OP3 (SVE_Zd, SVE_Zd, SVE_INV_LIMM), OP_SVE_VVU_BHSD, F_ALIAS | F_PSEUDO, 1),
 
+  /* SIMD Dot Product (optional in v8.2-A).  */
+  DOT_INSN ("udot", 0x2e009400, 0xbf20fc00, dotproduct, OP3 (Vd, Vn, Vm), QL_V3DOT, F_SIZEQ),
+  DOT_INSN ("sdot", 0xe009400,  0xbf20fc00, dotproduct, OP3 (Vd, Vn, Vm), QL_V3DOT, F_SIZEQ),
+  DOT_INSN ("udot", 0x2f00e000, 0xbf00f000, dotproduct, OP3 (Vd, Vn, Em), QL_V2DOT, F_SIZEQ),
+  DOT_INSN ("sdot", 0xf00e000,  0xbf00f000, dotproduct, OP3 (Vd, Vn, Em), QL_V2DOT, F_SIZEQ),
+
   {0, 0, 0, 0, 0, 0, {}, {}, 0, 0, NULL},
 };
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]