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]

[RFA/ARM 12/21] Add support for VSEL.


ARMv8 adds a VSEL instruction to A32/T32.

This patch adds support for it.

gas/ChangeLog:
2012-08-23  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>

	* config/tc-arm.c (NEON_ENC_TAB): Add entries for VSEL.
	(NEON_ENC_FPV8_): New define.
	(do_vfp_nsyn_fpv8): New function.
	(do_vsel): Likewise.
	(insns): Add VSEL instructions.

gas/testsuite/ChangeLog:
2012-08-23  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>

	* gas/arm/armv8-a+fp.d: New testcase.
	* gas/arm/armv8-a+fp.s: Likewise.

opcodes/ChangeLog:
2012-08-23  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>

	* arm-dis.c (coprocessor_opcodes): Add VSEL.
	(print_insn_coprocessor): Add new %<>c bitfield format
	specifier.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 93542e3..5612d7e 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -12341,7 +12341,11 @@ struct neon_tab_entry
   X(vcmp,	0xeb40a40, 0xeb40b40, N_INV),		\
   X(vcmpz,	0xeb50a40, 0xeb50b40, N_INV),		\
   X(vcmpe,	0xeb40ac0, 0xeb40bc0, N_INV),		\
-  X(vcmpez,     0xeb50ac0, 0xeb50bc0, N_INV)
+  X(vcmpez,     0xeb50ac0, 0xeb50bc0, N_INV),		\
+  X(vseleq,	0xe000a00, N_INV,     N_INV),		\
+  X(vselvs,	0xe100a00, N_INV,     N_INV),		\
+  X(vselge,	0xe200a00, N_INV,     N_INV),		\
+  X(vselgt,	0xe300a00, N_INV,     N_INV)
 
 enum neon_opc
 {
@@ -12371,6 +12375,8 @@ NEON_ENC_TAB
   ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf0000000))
 #define NEON_ENC_DOUBLE_(X) \
   ((neon_enc_tab[(X) & 0x0fffffff].float_or_poly) | ((X) & 0xf0000000))
+#define NEON_ENC_FPV8_(X) \
+  ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf000000))
 
 #define NEON_ENCODE(type, inst)					\
   do								\
@@ -15841,6 +15847,33 @@ do_neon_ldx_stx (void)
   else
     inst.instruction |= 0xf4000000;
 }
+
+/* FP v8.  */
+static void
+do_vfp_nsyn_fpv8 (enum neon_shape rs)
+{
+  NEON_ENCODE (FPV8, inst);
+
+  if (rs == NS_FFF)
+    do_vfp_sp_dyadic ();
+  else
+    do_vfp_dp_rd_rn_rm ();
+
+  if (rs == NS_DDD)
+    inst.instruction |= 0x100;
+
+  inst.instruction |= 0xf0000000;
+}
+
+static void
+do_vsel (void)
+{
+  set_it_insn_type (OUTSIDE_IT_INSN);
+
+  if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) != SUCCESS)
+    first_error (_("invalid instruction shape"));
+}
+
 
 /* Overall per-instruction processing.	*/
 
@@ -18044,6 +18077,17 @@ static const struct asm_opcode insns[] =
  TUF("dcps2",	0,	 f78f8002, 0, (),	noargs, noargs),
  TUF("dcps3",	0,	 f78f8003, 0, (),	noargs, noargs),
 
+  /* FP for ARMv8.  */
+#undef  ARM_VARIANT
+#define ARM_VARIANT & fpu_vfp_ext_armv8
+#undef  THUMB_VARIANT
+#define THUMB_VARIANT & fpu_vfp_ext_armv8
+
+  nUF(vseleq, _vseleq, 3, (RVSD, RVSD, RVSD),		vsel),
+  nUF(vselvs, _vselvs, 3, (RVSD, RVSD, RVSD),		vsel),
+  nUF(vselge, _vselge, 3, (RVSD, RVSD, RVSD),		vsel),
+  nUF(vselgt, _vselgt, 3, (RVSD, RVSD, RVSD),		vsel),
+
 #undef  ARM_VARIANT
 #define ARM_VARIANT  & fpu_fpa_ext_v1  /* Core FPA instruction set (V1).  */
 #undef  THUMB_VARIANT
diff --git a/gas/testsuite/gas/arm/armv8-a+fp.d b/gas/testsuite/gas/arm/armv8-a+fp.d
new file mode 100644
index 0000000..568d317
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-a+fp.d
@@ -0,0 +1,22 @@
+#name: Valid v8-a+fp
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> fe000a00 	vseleq.f32	s0, s0, s0
+0[0-9a-f]+ <[^>]+> fe500aa0 	vselvs.f32	s1, s1, s1
+0[0-9a-f]+ <[^>]+> fe2ffa0f 	vselge.f32	s30, s30, s30
+0[0-9a-f]+ <[^>]+> fe7ffaaf 	vselgt.f32	s31, s31, s31
+0[0-9a-f]+ <[^>]+> fe000b00 	vseleq.f64	d0, d0, d0
+0[0-9a-f]+ <[^>]+> fe500ba0 	vselvs.f64	d16, d16, d16
+0[0-9a-f]+ <[^>]+> fe2ffb0f 	vselge.f64	d15, d15, d15
+0[0-9a-f]+ <[^>]+> fe7ffbaf 	vselgt.f64	d31, d31, d31
+0[0-9a-f]+ <[^>]+> fe00 0a00 	vseleq.f32	s0, s0, s0
+0[0-9a-f]+ <[^>]+> fe50 0aa0 	vselvs.f32	s1, s1, s1
+0[0-9a-f]+ <[^>]+> fe2f fa0f 	vselge.f32	s30, s30, s30
+0[0-9a-f]+ <[^>]+> fe7f faaf 	vselgt.f32	s31, s31, s31
+0[0-9a-f]+ <[^>]+> fe00 0b00 	vseleq.f64	d0, d0, d0
+0[0-9a-f]+ <[^>]+> fe50 0ba0 	vselvs.f64	d16, d16, d16
+0[0-9a-f]+ <[^>]+> fe2f fb0f 	vselge.f64	d15, d15, d15
+0[0-9a-f]+ <[^>]+> fe7f fbaf 	vselgt.f64	d31, d31, d31
diff --git a/gas/testsuite/gas/arm/armv8-a+fp.s b/gas/testsuite/gas/arm/armv8-a+fp.s
new file mode 100644
index 0000000..ec79f99
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-a+fp.s
@@ -0,0 +1,24 @@
+	.syntax unified
+	.text
+	.arch armv8-a
+	.arch_extension fp
+
+	.arm
+	vseleq.f32	s0, s0, s0
+	vselvs.f32	s1, s1, s1
+	vselge.f32	s30, s30, s30
+	vselgt.f32	s31, s31, s31
+	vseleq.f64	d0, d0, d0
+	vselvs.f64	d16, d16, d16
+	vselge.f64	d15, d15, d15
+	vselgt.f64	d31, d31, d31
+
+	.thumb
+	vseleq.f32	s0, s0, s0
+	vselvs.f32	s1, s1, s1
+	vselge.f32	s30, s30, s30
+	vselgt.f32	s31, s31, s31
+	vseleq.f64	d0, d0, d0
+	vselvs.f64	d16, d16, d16
+	vselge.f64	d15, d15, d15
+	vselgt.f64	d31, d31, d31
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 9bc466c..2e4b333 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -102,6 +102,7 @@ struct opcode16
    %Q			print floating point precision in ldf/stf insn
    %R			print floating point rounding mode
 
+   %<bitfield>c		print as a condition code (for vsel)
    %<bitfield>r		print as an ARM register
    %<bitfield>R		as %<>r but r15 is UNPREDICTABLE
    %<bitfield>ru        as %<>r but each u register must be unique.
@@ -486,6 +487,10 @@ static const struct opcode32 coprocessor_opcodes[] =
   {FPU_VFP_EXT_FMA, 0x0e900a00, 0x0fb00f50, "vfnms%c.f32\t%y1, %y2, %y0"},
   {FPU_VFP_EXT_FMA, 0x0e900b00, 0x0fb00f50, "vfnms%c.f64\t%z1, %z2, %z0"},
 
+  /* FP v5.  */
+  {FPU_VFP_EXT_ARMV8, 0xfe000a00, 0xff800f00, "vsel%20-21c%u.f32\t%y1, %y2, %y0"},
+  {FPU_VFP_EXT_ARMV8, 0xfe000b00, 0xff800f00, "vsel%20-21c%u.f64\t%z1, %z2, %z0"},
+
   /* Generic coprocessor instructions.  */
   { 0, SENTINEL_GENERIC_START, 0, "" },
   {ARM_EXT_V5E, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15R, %16-19r, cr%0-3d"},
@@ -2198,6 +2203,31 @@ print_insn_coprocessor (bfd_vma pc,
 			func (stream, "0x%lx", (value & 0xffffffffUL));
 			break;
 
+		      case 'c':
+			switch (value)
+			  {
+			  case 0:
+			    func (stream, "eq");
+			    break;
+
+			  case 1:
+			    func (stream, "vs");
+			    break;
+
+			  case 2:
+			    func (stream, "ge");
+			    break;
+
+			  case 3:
+			    func (stream, "gt");
+			    break;
+
+			  default:
+			    func (stream, "??");
+			    break;
+			  }
+			break;
+
 		      case '`':
 			c++;
 			if (value == 0)

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