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][ARM][BINUTILS] Modification to arm encoding and decoding of SQRSHRL and UQRSHLL MVE instructions.


Hello,

This patch modifies the arm encoding and decoding of SQRSHRL and UQRSHLL MVE instructions.
This is a change to the first published specifications [1][a] but since there is no hardware
out there that uses the old instructions we do not want to support the old variant.
This changes are done based on the latest published specifications [1][b].

[1] https://developer.arm.com/architectures/cpu-architecture/m-profile/docs/ddi0553/latest/armv81-m-architecture-reference-manual
    [a] version bf
    [b] version bh

Bootstrapped on arm-none-linux-gnueabihf and regression tested on arm-none-eabi with no regressions.

Ok for master? If ok, could someone please commit on
my behalf, I don't have the commit rights.

Thanks,
Srinath.

gas ChangeLog:

2019-08-12  Srinath Parvathaneni  <srinath.parvathaneni@arm.com>

	* config/tc-arm.c (enum operand_parse_code): Add the entry OP_I48_I64.
	(po_imm1_or_imm2_or_fail): Marco to check the immediate is either of
        48 or 64.
	(parse_operands): Add case OP_I48_I64.
	(do_mve_scalar_shift1): Add function to encode the MVE shift
        instructions with 4 arguments.
	* testsuite/gas/arm/mve-shift-bad.l: Modify.
	* testsuite/gas/arm/mve-shift-bad.s: Likewise.
	* testsuite/gas/arm/mve-shift.d: Likewise.
	* testsuite/gas/arm/mve-shift.s: Likewise.

opcodes ChangeLog:

2019-08-12  Srinath Parvathaneni  <srinath.parvathaneni@arm.com>

	* arm-dis.c (struct mopcode32 mve_opcodes): Modify the mask for
	cases MVE_SQRSHRL and MVE_UQRSHLL.
	(print_insn_mve): Add case for specifier 'k' to check
	specific bit of the instruction.


###############     Attachment also inlined for ease of reply    ###############


diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index f7bebc1b5a40ac9b9702e8963240b45d5c91d6a1..6ac7726112782d26f1b339f3d8f64cdc6da913e3 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -6983,6 +6983,7 @@ enum operand_parse_code
   OP_I31w,	/*		   0 .. 31, optional trailing ! */
   OP_I32,	/*		   1 .. 32 */
   OP_I32z,	/*		   0 .. 32 */
+  OP_I48_I64,	/*		   48 or 64 */
   OP_I63,	/*		   0 .. 63 */
   OP_I63s,	/*		 -64 .. 63 */
   OP_I64,	/*		   1 .. 64 */
@@ -7134,6 +7135,25 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
     }								\
   while (0)
 
+#define po_imm1_or_imm2_or_fail(imm1, imm2, popt)		\
+  do								\
+    {								\
+      expressionS exp;						\
+      my_get_expression (&exp, &str, popt);			\
+      if (exp.X_op != O_constant)				\
+	{							\
+	  inst.error = _("constant expression required");	\
+	  goto failure;						\
+	}							\
+      if (exp.X_add_number != imm1 && exp.X_add_number != imm2) \
+	{							\
+	  inst.error = _("immediate value 48 or 64 expected");	\
+	  goto failure;						\
+	}							\
+      inst.operands[i].imm = exp.X_add_number;			\
+    }								\
+  while (0)
+
 #define po_scalar_or_goto(elsz, label, reg_type)			\
   do									\
     {									\
@@ -7478,6 +7498,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	case OP_I31:	 po_imm_or_fail (  0,	  31, FALSE);	break;
 	case OP_I32:	 po_imm_or_fail (  1,	  32, FALSE);	break;
 	case OP_I32z:	 po_imm_or_fail (  0,     32, FALSE);   break;
+	case OP_I48_I64: po_imm1_or_imm2_or_fail (48, 64, FALSE); break;
 	case OP_I63s:	 po_imm_or_fail (-64,	  63, FALSE);	break;
 	case OP_I63:	 po_imm_or_fail (  0,     63, FALSE);   break;
 	case OP_I64:	 po_imm_or_fail (  1,     64, FALSE);   break;
@@ -14278,6 +14299,24 @@ v8_1_loop_reloc (int is_le)
     }
 }
 
+/* For shifts with four operands in MVE.  */
+static void
+do_mve_scalar_shift1 (void)
+{
+  unsigned int value = inst.operands[2].imm;
+
+  inst.instruction |= inst.operands[0].reg << 16;
+  inst.instruction |= inst.operands[1].reg << 8;
+
+  /* Setting the bit for saturation.  */
+  inst.instruction |= ((value == 64) ? 0: 1) << 7;
+
+  /* Assuming Rm is already checked not to be 11x1.  */
+  constraint (inst.operands[3].reg == inst.operands[0].reg, BAD_OVERLAP);
+  constraint (inst.operands[3].reg == inst.operands[1].reg, BAD_OVERLAP);
+  inst.instruction |= inst.operands[3].reg << 12;
+}
+
 /* For shifts in MVE.  */
 static void
 do_mve_scalar_shift (void)
@@ -25338,8 +25377,8 @@ static const struct asm_opcode insns[] =
  ToC("lsll",	ea50010d, 3, (RRe, RRo, RRnpcsp_I32), mve_scalar_shift),
  ToC("lsrl",	ea50011f, 3, (RRe, RRo, I32),	      mve_scalar_shift),
  ToC("asrl",	ea50012d, 3, (RRe, RRo, RRnpcsp_I32), mve_scalar_shift),
- ToC("uqrshll",	ea51010d, 3, (RRe, RRo, RRnpcsp),     mve_scalar_shift),
- ToC("sqrshrl",	ea51012d, 3, (RRe, RRo, RRnpcsp),     mve_scalar_shift),
+ ToC("uqrshll",	ea51010d, 4, (RRe, RRo, I48_I64, RRnpcsp), mve_scalar_shift1),
+ ToC("sqrshrl",	ea51012d, 4, (RRe, RRo, I48_I64, RRnpcsp), mve_scalar_shift1),
  ToC("uqshll",	ea51010f, 3, (RRe, RRo, I32),	      mve_scalar_shift),
  ToC("urshrl",	ea51011f, 3, (RRe, RRo, I32),	      mve_scalar_shift),
  ToC("srshrl",	ea51012f, 3, (RRe, RRo, I32),	      mve_scalar_shift),
diff --git a/gas/testsuite/gas/arm/mve-shift-bad.l b/gas/testsuite/gas/arm/mve-shift-bad.l
index 5e7bfeda997d1de7966717375953f46de0e4cee8..835d0e37f41162defb447f6285eb17f346893867 100644
--- a/gas/testsuite/gas/arm/mve-shift-bad.l
+++ b/gas/testsuite/gas/arm/mve-shift-bad.l
@@ -5,8 +5,14 @@
 .*: Error: Even register not allowed here -- `lsll r2,r4,#5'
 .*: Error: r15 not allowed here -- `lsll r2,r15,r5'
 .*: Warning: instruction is UNPREDICTABLE with SP operand
-.*: Error: registers may not be the same -- `sqrshrl r2,r3,r3'
+.*: Error: registers may not be the same -- `sqrshrl r2,r3,#64,r3'
+.*: Error: registers may not be the same -- `sqrshrl r2,r3,#48,r3'
+.*: Error: constant expression required -- `sqrshrl r2,r3,r3'
+.*: Error: immediate value 48 or 64 expected -- `sqrshrl r2,r3,#40,r3'
 .*: Error: registers may not be the same -- `sqrshr r2,r2'
-.*: Error: registers may not be the same -- `uqrshll r2,r3,r2'
+.*: Error: registers may not be the same -- `uqrshll r2,r3,#64,r2'
+.*: Error: registers may not be the same -- `uqrshll r2,r3,#48,r2'
+.*: Error: constant expression required -- `uqrshll r2,r3,r2'
+.*: Error: immediate value 48 or 64 expected -- `uqrshll r2,r3,#40,r2'
 .*: Error: thumb conditional instruction should be in IT block -- `uqshlgt r2,#32'
 .*: Error: constant expression required -- `urshrlle r2,r3,r5'
diff --git a/gas/testsuite/gas/arm/mve-shift-bad.s b/gas/testsuite/gas/arm/mve-shift-bad.s
index 7b38359a7df22240e381ef20a31c5b5f419f2d6c..0470487978816cef4810c210de7138f55c2f6923 100644
--- a/gas/testsuite/gas/arm/mve-shift-bad.s
+++ b/gas/testsuite/gas/arm/mve-shift-bad.s
@@ -8,8 +8,14 @@ foo:
 	lsll	r2, r4, #5
 	lsll	r2, r15, r5
 	lsrl	r2, r13, #5
+	sqrshrl	r2, r3, #64, r3
+	sqrshrl	r2, r3, #48, r3
 	sqrshrl	r2, r3, r3
+	sqrshrl	r2, r3, #40,r3
 	sqrshr	r2, r2
+	uqrshll	r2, r3, #64, r2
+	uqrshll	r2, r3, #48, r2
 	uqrshll	r2, r3, r2
+	uqrshll	r2, r3, #40, r2
 	uqshlgt		r2, #32
 	urshrlle	r2, r3, r5
diff --git a/gas/testsuite/gas/arm/mve-shift.d b/gas/testsuite/gas/arm/mve-shift.d
index be5cd4682f534ccf40d462f06089bfb13b2a6507..94172adea0c024ffab190ffac6e2069599d0ccdc 100644
--- a/gas/testsuite/gas/arm/mve-shift.d
+++ b/gas/testsuite/gas/arm/mve-shift.d
@@ -11,13 +11,15 @@ Disassembly of section .text:
 0[0-9a-f]+ <[^>]+> ea52 134f 	lsll	r2, r3, #5
 0[0-9a-f]+ <[^>]+> ea52 530d 	lsll	r2, r3, r5
 0[0-9a-f]+ <[^>]+> ea52 135f 	lsrl	r2, r3, #5
-0[0-9a-f]+ <[^>]+> ea53 532d 	sqrshrl	r2, r3, r5
+0[0-9a-f]+ <[^>]+> ea53 53ad 	sqrshrl	r2, r3, #48, r5
+0[0-9a-f]+ <[^>]+> ea53 532d 	sqrshrl	r2, r3, #64, r5
 0[0-9a-f]+ <[^>]+> ea52 5f2d 	sqrshr	r2, r5
 0[0-9a-f]+ <[^>]+> ea53 137f 	sqshll	r2, r3, #5
 0[0-9a-f]+ <[^>]+> ea52 1f7f 	sqshl	r2, #5
 0[0-9a-f]+ <[^>]+> ea53 73ef 	srshrl	r2, r3, #31
 0[0-9a-f]+ <[^>]+> ea52 7fef 	srshr	r2, #31
-0[0-9a-f]+ <[^>]+> ea53 530d 	uqrshll	r2, r3, r5
+0[0-9a-f]+ <[^>]+> ea53 538d 	uqrshll	r2, r3, #48, r5
+0[0-9a-f]+ <[^>]+> ea53 530d 	uqrshll	r2, r3, #64, r5
 0[0-9a-f]+ <[^>]+> ea52 5f0d 	uqrshl	r2, r5
 0[0-9a-f]+ <[^>]+> ea53 73cf 	uqshll	r2, r3, #31
 0[0-9a-f]+ <[^>]+> bfce      	itee	gt
diff --git a/gas/testsuite/gas/arm/mve-shift.s b/gas/testsuite/gas/arm/mve-shift.s
index 267e3fbb9ac95bee6cd68aa6ed1a18312adb7a00..3038a0df9cbd5ef2fac74ed6f16721247e6e18e4 100644
--- a/gas/testsuite/gas/arm/mve-shift.s
+++ b/gas/testsuite/gas/arm/mve-shift.s
@@ -6,13 +6,15 @@ foo:
 	lsll	r2, r3, #5
 	lsll	r2, r3, r5
 	lsrl	r2, r3, #5
-	sqrshrl	r2, r3, r5
+	sqrshrl	r2, r3, #48, r5
+	sqrshrl	r2, r3, #64, r5
 	sqrshr	r2, r5
 	sqshll	r2, r3, #5
 	sqshl	r2, #5
 	srshrl	r2, r3, #31
 	srshr	r2, #31
-	uqrshll	r2, r3, r5
+	uqrshll	r2, r3, #48, r5
+	uqrshll	r2, r3, #64, r5
 	uqrshl	r2, r5
 	uqshll	r2, r3, #31
 	itee	gt
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 033725dbad99fb93f8f9506a32f0f55c63b2ae42..50d1306c19d950ba0c22cb72fcb2ccfd317795c8 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -2073,6 +2073,7 @@ static const struct opcode32 neon_opcodes[] =
    %u			print 'U' (unsigned) or 'S' for various mve instructions
    %i			print MVE predicate(s) for vpt and vpst
    %j			print a 5-bit immediate from hw2[14:12,7:6]
+   %k			print 48 if the 7th position bit is set else print 64.
    %m			print rounding mode for vcvt and vrint
    %n			print vector comparison code for predicated instruction
    %s			print size for various vcvt instructions
@@ -3373,8 +3374,8 @@ static const struct mopcode32 mve_opcodes[] =
 
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_SQRSHRL,
-   0xea51012d, 0xfff101ff,
-   "sqrshrl%c\t%17-19l, %9-11h, %12-15S"},
+   0xea51012d, 0xfff1017f,
+   "sqrshrl%c\t%17-19l, %9-11h, %k, %12-15S"},
 
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_SQRSHR,
@@ -3403,8 +3404,8 @@ static const struct mopcode32 mve_opcodes[] =
 
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_UQRSHLL,
-   0xea51010d, 0xfff101ff,
-   "uqrshll%c\t%17-19l, %9-11h, %12-15S"},
+   0xea51010d, 0xfff1017f,
+   "uqrshll%c\t%17-19l, %9-11h, %k, %12-15S"},
 
   {ARM_FEATURE_COPROC (FPU_MVE),
    MVE_UQRSHL,
@@ -9254,6 +9255,11 @@ print_insn_mve (struct disassemble_info *info, long given)
 		      }
 		      break;
 
+		    case 'k':
+		      func (stream, "#%u",
+			    (arm_decode_field (given, 7, 7) == 0) ? 64 : 48);
+		      break;
+
 		    case 'n':
 		      print_vec_condition (info, given, insn->mve_op);
 		      break;

Attachment: rb11586.patch
Description: rb11586.patch


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