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 10/57][Arm][GAS] Add support for MVE instructions: vcmp and vpt


Hi,

This patch adds support for MVE instructions VCMP and VPT. These instructions allow the use of the scalar ZR (zero) register, this is encoded as register 15.

gas/ChangeLog:

2019-05-01  Andre Vieira  <andre.simoesdiasvieira@arm.com>

	* config/tc-arm.c (MVE_BAD_QREG): New error message.
	(enum operand_parse_code): Define new operand.
	(parse_operands): Handle new operand.
	(do_mve_vpt): Change for VPT blocks.
	(NEON_SHAPE_DEF): New shape.
	(neon_logbits): Moved.
	(LOW4): Moved
	(HI1): Moved
	(mve_get_vcmp_vpt_cond): New function to translate vpt
        conditions.
	(do_mve_vcmp): New encoding function.
	(do_vfp_nsyn_cmp): Changed to support MVE variants.
	(insns): Change to support MVE variants of vcmp and add
        vpt.
	* testsuite/gas/arm/mve-vcmp-bad-1.d: New test.
	* testsuite/gas/arm/mve-vcmp-bad-1.l: New test.
	* testsuite/gas/arm/mve-vcmp-bad-1.s: New test.
	* testsuite/gas/arm/mve-vcmp-bad-2.d: New test.
	* testsuite/gas/arm/mve-vcmp-bad-2.l: New test.
	* testsuite/gas/arm/mve-vcmp-bad-2.s: New test.
	* testsuite/gas/arm/mve-vpt-bad-1.d: New test.
	* testsuite/gas/arm/mve-vpt-bad-1.l: New test.
	* testsuite/gas/arm/mve-vpt-bad-1.s: New test.
	* testsuite/gas/arm/mve-vpt-bad-2.d: New test.
	* testsuite/gas/arm/mve-vpt-bad-2.l: New test.
	* testsuite/gas/arm/mve-vpt-bad-2.s: New test.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index a212380c9d01bafc1326b0b10b82d2534b54efc6..b6ca4a48626f199347b7f1b2d281065198fd43ca 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -522,6 +522,7 @@ struct arm_it
     unsigned isvec      : 1;  /* Is a single, double or quad VFP/Neon reg.  */
     unsigned isquad     : 1;  /* Operand is SIMD quad register.  */
     unsigned issingle   : 1;  /* Operand is VFP single-precision register.  */
+    unsigned iszr	: 1;  /* Operand is ZR register.  */
     unsigned hasreloc	: 1;  /* Operand has relocation suffix.  */
     unsigned writeback	: 1;  /* Operand has trailing !  */
     unsigned preind	: 1;  /* Preindexed address.  */
@@ -649,6 +650,7 @@ enum arm_reg_type
   REG_TYPE_MMXWCG,
   REG_TYPE_XSCALE,
   REG_TYPE_RNB,
+  REG_TYPE_ZR
 };
 
 /* Structure for a hash table entry for a register.
@@ -901,6 +903,7 @@ struct asm_opcode
 #define BAD_MVE_SRCDEST	_("Warning: 32-bit element size and same destination "\
 			  "and source operands makes instruction UNPREDICTABLE")
 #define BAD_EL_TYPE	_("bad element type for instruction")
+#define MVE_BAD_QREG	_("MVE vector register Q[0..7] expected")
 
 static struct hash_control * arm_ops_hsh;
 static struct hash_control * arm_cond_hsh;
@@ -6897,6 +6900,7 @@ enum operand_parse_code
   OP_RNQ,	/* Neon quad precision register */
   OP_RNQMQ,	/* Neon quad or MVE vector register.  */
   OP_RVSD,	/* VFP single or double precision register */
+  OP_RVSD_COND,	/* VFP single, double precision register or condition code.  */
   OP_RVSDMQ,	/* VFP single, double precision or MVE vector register.  */
   OP_RNSD,      /* Neon single or double precision register */
   OP_RNDQ,      /* Neon double or quad precision register */
@@ -6920,6 +6924,7 @@ enum operand_parse_code
   OP_RNSDQMQR,	/* Neon single, double or quad register, MVE vector register or
 		   GPR (no SP/SP)  */
   OP_RMQ,	/* MVE vector register.  */
+  OP_RMQRZ,	/* MVE vector or ARM register including ZR.  */
 
   /* New operands for Armv8.1-M Mainline.  */
   OP_LR,	/* ARM LR register */
@@ -6941,6 +6946,8 @@ enum operand_parse_code
   OP_RNDQ_I0,   /* Neon D or Q reg, or immediate zero.  */
   OP_RVSD_I0,	/* VFP S or D reg, or immediate zero.  */
   OP_RSVD_FI0, /* VFP S or D reg, or floating point immediate zero.  */
+  OP_RSVDMQ_FI0, /* VFP S, D, MVE vector register or floating point immediate
+		    zero.  */
   OP_RR_RNSC,   /* ARM reg or Neon scalar.  */
   OP_RNSD_RNSC, /* Neon S or D reg, or Neon scalar.  */
   OP_RNSDQ_RNSC, /* Vector S, D or Q reg, or Neon scalar.  */
@@ -7031,6 +7038,8 @@ enum operand_parse_code
   OP_oROR,	 /* ROR 0/8/16/24 */
   OP_oBARRIER_I15, /* Option argument for a barrier instruction.  */
 
+  OP_oRMQRZ,	/* optional MVE vector or ARM register including ZR.  */
+
   /* Some pre-defined mixed (ARM/THUMB) operands.  */
   OP_RR_npcsp		= MIX_ARM_THUMB_OPERANDS (OP_RR, OP_RRnpcsp),
   OP_RRnpc_npcsp	= MIX_ARM_THUMB_OPERANDS (OP_RRnpc, OP_RRnpcsp),
@@ -7080,6 +7089,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
       inst.operands[i].isvec = (rtype == REG_TYPE_VFS		\
 			     || rtype == REG_TYPE_VFD		\
 			     || rtype == REG_TYPE_NQ);		\
+      inst.operands[i].iszr = (rtype == REG_TYPE_ZR);		\
     }								\
   while (0)
 
@@ -7098,6 +7108,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
       inst.operands[i].isvec = (rtype == REG_TYPE_VFS		\
 			     || rtype == REG_TYPE_VFD		\
 			     || rtype == REG_TYPE_NQ);		\
+      inst.operands[i].iszr = (rtype == REG_TYPE_ZR);		\
     }								\
   while (0)
 
@@ -7243,6 +7254,9 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  break;
 	try_rvsd:
 	case OP_RVSD:  po_reg_or_fail (REG_TYPE_VFSD);    break;
+	case OP_RVSD_COND:
+	  po_reg_or_goto (REG_TYPE_VFSD, try_cond);
+	  break;
 	case OP_oRNSDQ:
 	case OP_RNSDQ: po_reg_or_fail (REG_TYPE_NSDQ);    break;
 	case OP_RNSDQMQR:
@@ -7277,6 +7291,10 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  po_reg_or_goto (REG_TYPE_VFSD, try_imm0);
 	  break;
 
+	case OP_RSVDMQ_FI0:
+	  po_reg_or_goto (REG_TYPE_MQ, try_rsvd_fi0);
+	  break;
+	try_rsvd_fi0:
 	case OP_RSVD_FI0:
 	  {
 	    po_reg_or_goto (REG_TYPE_VFSD, try_ifimm0);
@@ -7551,6 +7569,7 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	case OP_CPSF:	 val = parse_cps_flags (&str);		break;
 	case OP_ENDI:	 val = parse_endian_specifier (&str);	break;
 	case OP_oROR:	 val = parse_ror (&str);		break;
+	try_cond:
 	case OP_COND:	 val = parse_cond (&str);		break;
 	case OP_oBARRIER_I15:
 	  po_barrier_or_imm (str); break;
@@ -7724,6 +7743,17 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_OR_ASR_IMMEDIATE));
 	  break;
 
+	case OP_RMQRZ:
+	case OP_oRMQRZ:
+	  po_reg_or_goto (REG_TYPE_MQ, try_rr_zr);
+	  break;
+	try_rr_zr:
+	  po_reg_or_goto (REG_TYPE_RN, ZR);
+	  break;
+	ZR:
+	  po_reg_or_fail (REG_TYPE_ZR);
+	  break;
+
 	default:
 	  as_fatal (_("unhandled operand code %d"), op_parse_code);
 	}
@@ -7767,10 +7797,12 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	    inst.error = BAD_PC;
 	  break;
 
+	case OP_RVSD_COND:
 	case OP_VLDR:
 	  if (inst.operands[i].isreg)
 	    break;
 	/* fall through.  */
+
 	case OP_CPSF:
 	case OP_ENDI:
 	case OP_oROR:
@@ -7799,6 +7831,12 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	    inst.error = _("operand must be LR register");
 	  break;
 
+	case OP_RMQRZ:
+	case OP_oRMQRZ:
+	  if (!inst.operands[i].iszr && inst.operands[i].reg == REG_PC)
+	    inst.error = BAD_PC;
+	  break;
+
 	case OP_RRe:
 	  if (inst.operands[i].isreg
 	      && (inst.operands[i].reg & 0x00000001) != 0)
@@ -12009,18 +12047,6 @@ do_t_it (void)
   inst.instruction |= cond << 4;
 }
 
-static void
-do_mve_vpt (void)
-{
-  /* We are dealing with a vector predicated block.  */
-  set_pred_insn_type (VPT_INSN);
-  now_pred.cc = 0;
-  now_pred.mask = ((inst.instruction & 0x00400000) >> 19)
-		  | ((inst.instruction & 0xe000) >> 13);
-  now_pred.warn_deprecated = FALSE;
-  now_pred.type = VECTOR_PRED;
-}
-
 /* Helper function used for both push/pop and ldm/stm.  */
 static void
 encode_thumb2_multi (bfd_boolean do_io, int base, unsigned mask,
@@ -14279,6 +14305,8 @@ NEON_ENC_TAB
 #define NEON_SHAPE_DEF			\
   X(4, (R, R, S, S), QUAD),		\
   X(4, (S, S, R, R), QUAD),		\
+  X(3, (I, Q, Q), QUAD),		\
+  X(3, (I, Q, R), QUAD),		\
   X(3, (R, Q, Q), QUAD),		\
   X(3, (D, D, D), DOUBLE),		\
   X(3, (Q, Q, Q), QUAD),		\
@@ -15317,10 +15345,239 @@ do_vfp_nsyn_nmul (void)
 
 }
 
+/* Turn a size (8, 16, 32, 64) into the respective bit number minus 3
+   (0, 1, 2, 3).  */
+
+static unsigned
+neon_logbits (unsigned x)
+{
+  return ffs (x) - 4;
+}
+
+#define LOW4(R) ((R) & 0xf)
+#define HI1(R) (((R) >> 4) & 1)
+
+static unsigned
+mve_get_vcmp_vpt_cond (struct neon_type_el et)
+{
+  switch (et.type)
+    {
+    default:
+      first_error (BAD_EL_TYPE);
+      return 0;
+    case NT_float:
+      switch (inst.operands[0].imm)
+	{
+	default:
+	  first_error (_("invalid condition"));
+	  return 0;
+	case 0x0:
+	  /* eq.  */
+	  return 0;
+	case 0x1:
+	  /* ne.  */
+	  return 1;
+	case 0xa:
+	  /* ge/  */
+	  return 4;
+	case 0xb:
+	  /* lt.  */
+	  return 5;
+	case 0xc:
+	  /* gt.  */
+	  return 6;
+	case 0xd:
+	  /* le.  */
+	  return 7;
+	}
+    case NT_integer:
+      /* only accept eq and ne.  */
+      if (inst.operands[0].imm > 1)
+	{
+	  first_error (_("invalid condition"));
+	  return 0;
+	}
+      return inst.operands[0].imm;
+    case NT_unsigned:
+      if (inst.operands[0].imm == 0x2)
+	return 2;
+      else if (inst.operands[0].imm == 0x8)
+	return 3;
+      else
+	{
+	  first_error (_("invalid condition"));
+	  return 0;
+	}
+    case NT_signed:
+      switch (inst.operands[0].imm)
+	{
+	  default:
+	    first_error (_("invalid condition"));
+	    return 0;
+	  case 0xa:
+	    /* ge.  */
+	    return 4;
+	  case 0xb:
+	    /* lt.  */
+	    return 5;
+	  case 0xc:
+	    /* gt.  */
+	    return 6;
+	  case 0xd:
+	    /* le.  */
+	    return 7;
+	}
+    }
+  /* Should be unreachable.  */
+  abort ();
+}
+
+static void
+do_mve_vpt (void)
+{
+  /* We are dealing with a vector predicated block.  */
+  if (inst.operands[0].present)
+    {
+      enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
+      struct neon_type_el et
+	= neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
+			   N_EQK);
+
+      unsigned fcond = mve_get_vcmp_vpt_cond (et);
+
+      constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
+
+      if (et.type == NT_invtype)
+	return;
+
+      if (et.type == NT_float)
+	{
+	  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
+		      BAD_FPU);
+	  constraint (et.size != 16 && et.size != 32, BAD_EL_TYPE);
+	  inst.instruction |= (et.size == 16) << 28;
+	  inst.instruction |= 0x3 << 20;
+	}
+      else
+	{
+	  constraint (et.size != 8 && et.size != 16 && et.size != 32,
+		      BAD_EL_TYPE);
+	  inst.instruction |= 1 << 28;
+	  inst.instruction |= neon_logbits (et.size) << 20;
+	}
+
+      if (inst.operands[2].isquad)
+	{
+	  inst.instruction |= HI1 (inst.operands[2].reg) << 5;
+	  inst.instruction |= LOW4 (inst.operands[2].reg);
+	  inst.instruction |= (fcond & 0x2) >> 1;
+	}
+      else
+	{
+	  if (inst.operands[2].reg == REG_SP)
+	    as_tsktsk (MVE_BAD_SP);
+	  inst.instruction |= 1 << 6;
+	  inst.instruction |= (fcond & 0x2) << 4;
+	  inst.instruction |= inst.operands[2].reg;
+	}
+      inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
+      inst.instruction |= (fcond & 0x4) << 10;
+      inst.instruction |= (fcond & 0x1) << 7;
+
+    }
+    set_pred_insn_type (VPT_INSN);
+    now_pred.cc = 0;
+    now_pred.mask = ((inst.instruction & 0x00400000) >> 19)
+		    | ((inst.instruction & 0xe000) >> 13);
+    now_pred.warn_deprecated = FALSE;
+    now_pred.type = VECTOR_PRED;
+    inst.is_neon = 1;
+}
+
+static void
+do_mve_vcmp (void)
+{
+  constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_ext), BAD_FPU);
+  if (!inst.operands[1].isreg || !inst.operands[1].isquad)
+    first_error (_(reg_expected_msgs[REG_TYPE_MQ]));
+  if (!inst.operands[2].present)
+    first_error (_("MVE vector or ARM register expected"));
+  constraint (inst.operands[1].reg > 14, MVE_BAD_QREG);
+
+  /* Deal with 'else' conditional MVE's vcmp, it will be parsed as vcmpe.  */
+  if ((inst.instruction & 0xffffffff) == N_MNEM_vcmpe
+      && inst.operands[1].isquad)
+    {
+      inst.instruction = N_MNEM_vcmp;
+      inst.cond = 0x10;
+    }
+
+  if (inst.cond > COND_ALWAYS)
+    inst.pred_insn_type = INSIDE_VPT_INSN;
+  else
+    inst.pred_insn_type = MVE_OUTSIDE_PRED_INSN;
+
+  enum neon_shape rs = neon_select_shape (NS_IQQ, NS_IQR, NS_NULL);
+  struct neon_type_el et
+    = neon_check_type (3, rs, N_EQK, N_KEY | N_F_MVE | N_I_MVE | N_SU_32,
+		       N_EQK);
+
+  constraint (rs == NS_IQR && inst.operands[2].reg == REG_PC
+	      && !inst.operands[2].iszr, BAD_PC);
+
+  unsigned fcond = mve_get_vcmp_vpt_cond (et);
+
+  inst.instruction = 0xee010f00;
+  inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
+  inst.instruction |= (fcond & 0x4) << 10;
+  inst.instruction |= (fcond & 0x1) << 7;
+  if (et.type == NT_float)
+    {
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, mve_fp_ext),
+		  BAD_FPU);
+      inst.instruction |= (et.size == 16) << 28;
+      inst.instruction |= 0x3 << 20;
+    }
+  else
+    {
+      inst.instruction |= 1 << 28;
+      inst.instruction |= neon_logbits (et.size) << 20;
+    }
+  if (inst.operands[2].isquad)
+    {
+      inst.instruction |= HI1 (inst.operands[2].reg) << 5;
+      inst.instruction |= (fcond & 0x2) >> 1;
+      inst.instruction |= LOW4 (inst.operands[2].reg);
+    }
+  else
+    {
+      if (inst.operands[2].reg == REG_SP)
+	as_tsktsk (MVE_BAD_SP);
+      inst.instruction |= 1 << 6;
+      inst.instruction |= (fcond & 0x2) << 4;
+      inst.instruction |= inst.operands[2].reg;
+    }
+
+  inst.is_neon = 1;
+  return;
+}
+
 static void
 do_vfp_nsyn_cmp (void)
 {
   enum neon_shape rs;
+  if (!inst.operands[0].isreg)
+    {
+      do_mve_vcmp ();
+      return;
+    }
+  else
+    {
+      constraint (inst.operands[2].present, BAD_SYNTAX);
+      constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1xd),
+		  BAD_FPU);
+    }
+
   if (inst.operands[1].isreg)
     {
       rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
@@ -15438,18 +15695,6 @@ neon_dp_fixup (struct arm_it* insn)
   insn->instruction = i;
 }
 
-/* Turn a size (8, 16, 32, 64) into the respective bit number minus 3
-   (0, 1, 2, 3).  */
-
-static unsigned
-neon_logbits (unsigned x)
-{
-  return ffs (x) - 4;
-}
-
-#define LOW4(R) ((R) & 0xf)
-#define HI1(R) (((R) >> 4) & 1)
-
 static void
 mve_encode_qqr (int size, int fp)
 {
@@ -21098,6 +21343,10 @@ static const struct reg_entry reg_names[] =
   REGDEF(WR, 7,RN), REGDEF(SB, 9,RN), REGDEF(SL,10,RN), REGDEF(FP,11,RN),
   REGDEF(IP,12,RN), REGDEF(SP,13,RN), REGDEF(LR,14,RN), REGDEF(PC,15,RN),
 
+  /* Defining the new Zero register from ARMv8.1-M.  */
+  REGDEF(zr,15,ZR),
+  REGDEF(ZR,15,ZR),
+
   /* Coprocessor numbers.  */
   REGSET(p, CP), REGSET(P, CP),
 
@@ -22913,8 +23162,6 @@ static const struct asm_opcode insns[] =
  nCE(vnmul,     _vnmul,   3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
  nCE(vnmla,     _vnmla,   3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
  nCE(vnmls,     _vnmls,   3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
- nCE(vcmp,      _vcmp,    2, (RVSD, RSVD_FI0),    vfp_nsyn_cmp),
- nCE(vcmpe,     _vcmpe,   2, (RVSD, RSVD_FI0),    vfp_nsyn_cmp),
  NCE(vpush,     0,       1, (VRSDLST),          vfp_nsyn_push),
  NCE(vpop,      0,       1, (VRSDLST),          vfp_nsyn_pop),
  NCE(vcvtz,     0,       2, (RVSD, RVSD),       vfp_nsyn_cvtz),
@@ -23630,6 +23877,23 @@ static const struct asm_opcode insns[] =
 
 #undef  THUMB_VARIANT
 #define THUMB_VARIANT & mve_ext
+
+ ToC("vpt",	ee410f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vptt",	ee018f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vpte",	ee418f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vpttt",	ee014f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vptte",	ee01cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vptet",	ee41cf00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vptee",	ee414f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vptttt",	ee012f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vpttte",	ee016f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vpttet",	ee01ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vpttee",	ee01af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vptett",	ee41af00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vptete",	ee41ef00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vpteet",	ee416f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+ ToC("vpteee",	ee412f00, 3, (COND, RMQ, RMQRZ), mve_vpt),
+
  ToC("vpst",	fe710f4d, 0, (), mve_vpt),
  ToC("vpstt",	fe318f4d, 0, (), mve_vpt),
  ToC("vpste",	fe718f4d, 0, (), mve_vpt),
@@ -23709,6 +23973,9 @@ static const struct asm_opcode insns[] =
  mCEF(vmovlt, _vmovlt,	1, (VMOV),		mve_movl),
  mCEF(vmovlb, _vmovlb,	1, (VMOV),		mve_movl),
 
+ mnCE(vcmp,      _vcmp,    3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ),    vfp_nsyn_cmp),
+ mnCE(vcmpe,     _vcmpe,   3, (RVSD_COND, RSVDMQ_FI0, oRMQRZ),    vfp_nsyn_cmp),
+
 #undef  ARM_VARIANT
 #define ARM_VARIANT  & fpu_vfp_ext_v2
 
diff --git a/gas/testsuite/gas/arm/mve-vcmp-bad-1.d b/gas/testsuite/gas/arm/mve-vcmp-bad-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..dd2706f084f9abc8e714f35289fbe7d88c142b78
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmp-bad-1.d
@@ -0,0 +1,5 @@
+#name: bad MVE VCMP instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vcmp-bad-1.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vcmp-bad-1.l b/gas/testsuite/gas/arm/mve-vcmp-bad-1.l
new file mode 100644
index 0000000000000000000000000000000000000000..65db78ab61ed5439d09834671a4d40615d84fc65
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmp-bad-1.l
@@ -0,0 +1,31 @@
+[^:]*: Assembler messages:
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Error: selected FPU does not support instruction -- `vcmp.f32 eq,q0,q1'
+[^:]*:25: Error: selected FPU does not support instruction -- `vcmp.f32 eq,q0,r1'
+[^:]*:26: Error: bad type in SIMD instruction -- `vcmp.i64 eq,q0,q1'
+[^:]*:27: Error: invalid condition -- `vcmp.s32 eq,q0,q1'
+[^:]*:28: Error: invalid condition -- `vcmp.s16 cs,q0,q1'
+[^:]*:29: Error: invalid condition -- `vcmp.u8 le,q0,q1'
+[^:]*:30: Error: condition required -- `vcmp.s16 q0,q1'
+[^:]*:31: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:33: Error: syntax error -- `vcmpeq.i32 eq,q0,q1'
+[^:]*:34: Error: syntax error -- `vcmpeq.i32 eq,q0,q1'
+[^:]*:36: Error: syntax error -- `vcmpeq.i32 eq,q0,q1'
+[^:]*:37: Error: vector predicated instruction should be in VPT/VPST block -- `vcmpt.i32 eq,q0,q1'
+[^:]*:39: Error: instruction missing MVE vector predication code -- `vcmp.i32 eq,q0,q1'
+[^:]*:41: Error: syntax error -- `vcmpeq.i32 eq,q0,r1'
+[^:]*:42: Error: syntax error -- `vcmpeq.i32 eq,q0,r1'
+[^:]*:44: Error: syntax error -- `vcmpeq.i32 eq,q0,r1'
+[^:]*:45: Error: vector predicated instruction should be in VPT/VPST block -- `vcmpt.i32 eq,q0,r1'
+[^:]*:47: Error: instruction missing MVE vector predication code -- `vcmp.i32 eq,q0,r1'
diff --git a/gas/testsuite/gas/arm/mve-vcmp-bad-1.s b/gas/testsuite/gas/arm/mve-vcmp-bad-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..116e23a80979321d3e8054cc25c523e969e359d9
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmp-bad-1.s
@@ -0,0 +1,47 @@
+.macro cond1
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .
+it \cond
+vcmp.s32 gt, q0, q1
+.endr
+.endr
+.endm
+
+.macro cond2
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .
+it \cond
+vcmp.i16 eq, q0, r1
+.endr
+.endr
+.endm
+
+.syntax unified
+.thumb
+
+cond1
+cond2
+vcmp.f32 eq, q0, q1
+vcmp.f32 eq, q0, r1
+vcmp.i64 eq, q0, q1
+vcmp.s32 eq, q0, q1
+vcmp.s16 cs, q0, q1
+vcmp.u8 le, q0, q1
+vcmp.s16 q0, q1
+vcmp.i32 eq, q0, sp
+it eq
+vcmpeq.i32 eq, q0, q1
+vcmpeq.i32 eq, q0, q1
+vpst
+vcmpeq.i32 eq, q0, q1
+vcmpt.i32 eq, q0, q1
+vpst
+vcmp.i32 eq, q0, q1
+it eq
+vcmpeq.i32 eq, q0, r1
+vcmpeq.i32 eq, q0, r1
+vpst
+vcmpeq.i32 eq, q0, r1
+vcmpt.i32 eq, q0, r1
+vpst
+vcmp.i32 eq, q0, r1
diff --git a/gas/testsuite/gas/arm/mve-vcmp-bad-2.d b/gas/testsuite/gas/arm/mve-vcmp-bad-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..7d262517cc6324f0dbc1fca3420df29baa8f8e0c
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmp-bad-2.d
@@ -0,0 +1,5 @@
+#name: bad MVE FP VCMP instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vcmp-bad-2.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vcmp-bad-2.l b/gas/testsuite/gas/arm/mve-vcmp-bad-2.l
new file mode 100644
index 0000000000000000000000000000000000000000..1305f0697329b108c48b9e7b55e1a064ff680a88
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmp-bad-2.l
@@ -0,0 +1,25 @@
+[^:]*: Assembler messages:
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:22: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:23: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:24: Error: bad type in SIMD instruction -- `vcmp.f64 eq,q0,q1'
+[^:]*:25: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:27: Error: syntax error -- `vcmpeq.f32 eq,q0,q1'
+[^:]*:28: Error: syntax error -- `vcmpeq.f32 eq,q0,q1'
+[^:]*:30: Error: syntax error -- `vcmpeq.f32 eq,q0,q1'
+[^:]*:31: Error: vector predicated instruction should be in VPT/VPST block -- `vcmpt.f32 eq,q0,q1'
+[^:]*:33: Error: instruction missing MVE vector predication code -- `vcmp.f32 eq,q0,q1'
+[^:]*:35: Error: syntax error -- `vcmpeq.f32 eq,q0,r1'
+[^:]*:36: Error: syntax error -- `vcmpeq.f32 eq,q0,r1'
+[^:]*:38: Error: syntax error -- `vcmpeq.f32 eq,q0,r1'
+[^:]*:39: Error: vector predicated instruction should be in VPT/VPST block -- `vcmpt.f32 eq,q0,r1'
+[^:]*:41: Error: instruction missing MVE vector predication code -- `vcmp.f32 eq,q0,r1'
diff --git a/gas/testsuite/gas/arm/mve-vcmp-bad-2.s b/gas/testsuite/gas/arm/mve-vcmp-bad-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..c54b0e94043232cecb8c6496ac41643a39c778b4
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vcmp-bad-2.s
@@ -0,0 +1,41 @@
+.macro cond1
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .
+it \cond
+vcmp.f32 gt, q0, q1
+.endr
+.endr
+.endm
+
+.macro cond2
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .
+it \cond
+vcmp.f16 eq, q0, r1
+.endr
+.endr
+.endm
+
+.syntax unified
+.thumb
+
+cond1
+cond2
+vcmp.f64 eq, q0, q1
+vcmp.f32 eq, q0, sp
+it eq
+vcmpeq.f32 eq, q0, q1
+vcmpeq.f32 eq, q0, q1
+vpst
+vcmpeq.f32 eq, q0, q1
+vcmpt.f32 eq, q0, q1
+vpst
+vcmp.f32 eq, q0, q1
+it eq
+vcmpeq.f32 eq, q0, r1
+vcmpeq.f32 eq, q0, r1
+vpst
+vcmpeq.f32 eq, q0, r1
+vcmpt.f32 eq, q0, r1
+vpst
+vcmp.f32 eq, q0, r1
diff --git a/gas/testsuite/gas/arm/mve-vpt-bad-1.d b/gas/testsuite/gas/arm/mve-vpt-bad-1.d
new file mode 100644
index 0000000000000000000000000000000000000000..8a4fe5371e8084afd0fcee1dd4da042192dbdedf
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpt-bad-1.d
@@ -0,0 +1,5 @@
+#name: bad MVE VPT instructions
+#as: -march=armv8.1-m.main+mve
+#error_output: mve-vpt-bad-1.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vpt-bad-1.l b/gas/testsuite/gas/arm/mve-vpt-bad-1.l
new file mode 100644
index 0000000000000000000000000000000000000000..28bd9d6047de0fc0592b7b75ee48f3b086f1f879
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpt-bad-1.l
@@ -0,0 +1,23 @@
+[^:]*: Assembler messages:
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:17: Error: bad type in SIMD instruction -- `vpt.i64 eq,q0,q1'
+[^:]*:18: Error: selected FPU does not support instruction -- `vpt.f16 eq,q0,q1'
+[^:]*:19: Error: selected FPU does not support instruction -- `vpt.f32 eq,q0,q1'
+[^:]*:20: Error: bad type in SIMD instruction -- `vpt.f64 eq,q0,q1'
+[^:]*:22: Error: syntax error -- `vpteq.i8 eq,q0,q1'
+[^:]*:23: Error: syntax error -- `vpteq.i8 eq,q0,q1'
+[^:]*:26: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:27: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:30: Warning: section '.text' finished with an open VPT/VPST block.
diff --git a/gas/testsuite/gas/arm/mve-vpt-bad-1.s b/gas/testsuite/gas/arm/mve-vpt-bad-1.s
new file mode 100644
index 0000000000000000000000000000000000000000..66d9980998f7f0d44ae036a8d7a08742aa549d61
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpt-bad-1.s
@@ -0,0 +1,30 @@
+.macro cond1, lastreg
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .
+it \cond
+vpt.i8 eq, q0, \lastreg
+vaddt.i32 q0, q1, q2
+.endr
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond1 q1
+cond1 r1
+vpt.i8 eq, q0, sp
+vaddt.i32 q0, q1, q2
+vpt.i64 eq, q0, q1
+vpt.f16 eq, q0, q1
+vpt.f32 eq, q0, q1
+vpt.f64 eq, q0, q1
+it eq
+vpteq.i8 eq, q0, q1
+vpteq.i8 eq, q0, q1
+vaddt.i32 q0, q0, q1
+vpst
+vptt.i8 eq, q0, q1
+vptt.i8 eq, q0, q1
+vaddt.i32 q0, q0, q1
+vaddt.i32 q0, q0, q1
+vpt.i8 eq, q0, q1
diff --git a/gas/testsuite/gas/arm/mve-vpt-bad-2.d b/gas/testsuite/gas/arm/mve-vpt-bad-2.d
new file mode 100644
index 0000000000000000000000000000000000000000..27a5171aa2e9c401a4fc974da998d8f1e984c614
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpt-bad-2.d
@@ -0,0 +1,5 @@
+#name: bad MVE FP VPT instructions
+#as: -march=armv8.1-m.main+mve.fp
+#error_output: mve-vpt-bad-2.l
+
+.*: +file format .*arm.*
diff --git a/gas/testsuite/gas/arm/mve-vpt-bad-2.l b/gas/testsuite/gas/arm/mve-vpt-bad-2.l
new file mode 100644
index 0000000000000000000000000000000000000000..678a824eef64d15a7a1add12d84157f80f1555f7
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpt-bad-2.l
@@ -0,0 +1,21 @@
+[^:]*: Assembler messages:
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:13: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:14: Warning: instruction is UNPREDICTABLE in an IT block
+[^:]*:15: Warning: instruction is UNPREDICTABLE with SP operand
+[^:]*:17: Error: bad type in SIMD instruction -- `vpt.f64 eq,q0,q1'
+[^:]*:19: Error: syntax error -- `vpteq.f32 eq,q0,q1'
+[^:]*:20: Error: syntax error -- `vpteq.f32 eq,q0,q1'
+[^:]*:23: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:24: Warning: instruction is UNPREDICTABLE in a VPT block
+[^:]*:27: Warning: section '.text' finished with an open VPT/VPST block.
+
diff --git a/gas/testsuite/gas/arm/mve-vpt-bad-2.s b/gas/testsuite/gas/arm/mve-vpt-bad-2.s
new file mode 100644
index 0000000000000000000000000000000000000000..83e9fd5b38773163161df955473f9b0961af9a26
--- /dev/null
+++ b/gas/testsuite/gas/arm/mve-vpt-bad-2.s
@@ -0,0 +1,27 @@
+.macro cond1, lastreg
+.irp cond, eq, ne, gt, ge, lt, le
+.irp size, .
+it \cond
+vpt.f16 eq, q0, \lastreg
+vaddt.i32 q0, q1, q2
+.endr
+.endr
+.endm
+
+.syntax unified
+.thumb
+cond1 q1
+cond1 r1
+vpt.f16 eq, q0, sp
+vaddt.i32 q0, q1, q2
+vpt.f64 eq, q0, q1
+it eq
+vpteq.f32 eq, q0, q1
+vpteq.f32 eq, q0, q1
+vaddt.i32 q0, q0, q1
+vpst
+vptt.f16 eq, q0, q1
+vptt.f16 eq, q0, q1
+vaddt.i32 q0, q0, q1
+vaddt.i32 q0, q0, q1
+vpt.f32 eq, q0, q1

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