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][gas] Make gas accept vcmp[e].f{32,64} <reg>, #0.0


Hi all,

The ARM ARM says that the VFP compare with zero instructions (vcmp, vcmpe) accept the zero in the form of a #0.0 immediate. However, gas currently only accepts #0. This patch fixes that and some simple tests are added.

The new parse_ifimm_zerofunction is rather simple and is modelled on the parse_qfloat_immediate below it and didn't blow up in my testing.


make check on gas passes and a gcc testsuite run doesn't show any problems.

Ok for trunk?

Thanks,
Kyrill

[gas/]
2014-06-24  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

    * config/tc-arm.c (parse_ifimm_zero): New function.
    (enum operand_parse_code): Add OP_RSVD_FI0 value.
    (parse_operands): Handle OP_RSVD_FI0.
    (asm_opcode_insns): Use RSVD_FI0 for second operand of vcmp, vcmpe.

[gas/testsuite/]
2014-06-24  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>

    * gas/arm/ual-vcmp.s: New file.
    * gas/arm/ual-vcmp.d: Likewise.
commit 158cda927a11dde18509fe8b77fb78cbca525e55
Author: Kyrylo Tkachov <kyrylo.tkachov@arm.com>
Date:   Thu Jul 24 15:24:55 2014 +0100

    [ARM][gas] Accept vcmp <reg>, #0.0

diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 75fb233..74ac40d 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -4944,6 +4944,39 @@ is_quarter_float (unsigned imm)
   return (imm & 0x7ffff) == 0 && ((imm & 0x7e000000) ^ bs) == 0;
 }
 
+
+/* Detect the presence of a floating point or integer zero constant,
+   i.e. #0.0 or #0.  */
+
+static bfd_boolean
+parse_ifimm_zero (char **in)
+{
+  char *str = *in;
+  char* fpnum;
+
+  skip_past_char (&str, '#');
+  fpnum = str;
+  skip_whitespace (fpnum);
+
+  if (*fpnum != '0')
+    return FALSE;
+
+  fpnum++;
+  if (strncmp (fpnum, ".0", 2) == 0)
+    {
+      fpnum += 2;
+      *in = fpnum;
+      return TRUE;
+    }
+  else if (*fpnum == '\0' || *fpnum == ' ' || *fpnum == '\n')
+    {
+      *in = fpnum;
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
 /* Parse an 8-bit "quarter-precision" floating point number of the form:
    0baBbbbbbc defgh000 00000000 00000000.
    The zero and minus-zero cases need special handling, since they can't be
@@ -6417,6 +6450,7 @@ 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_RR_RNSC,   /* ARM reg or Neon scalar.  */
   OP_RNSDQ_RNSC, /* Vector S, D or Q reg, or Neon scalar.  */
   OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar.  */
@@ -6700,6 +6734,18 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
 	  po_reg_or_goto (REG_TYPE_VFSD, try_imm0);
 	  break;
 
+	case OP_RSVD_FI0:
+	  {
+	    po_reg_or_goto (REG_TYPE_VFSD, try_ifimm0);
+	    break;
+	    try_ifimm0:
+	    if (parse_ifimm_zero (&str))
+	      inst.operands[i].imm = 0;
+	    else
+	      goto failure;
+	  }
+	  break;
+
 	case OP_RR_RNSC:
 	  {
 	    po_scalar_or_goto (8, try_rr);
@@ -19552,8 +19598,8 @@ 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, RVSD_I0),    vfp_nsyn_cmp),
- nCE(vcmpe,     _vcmpe,   2, (RVSD, RVSD_I0),    vfp_nsyn_cmp),
+ 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),
diff --git a/gas/testsuite/gas/arm/ual-vcmp.d b/gas/testsuite/gas/arm/ual-vcmp.d
new file mode 100644
index 0000000..e6c3bea
--- /dev/null
+++ b/gas/testsuite/gas/arm/ual-vcmp.d
@@ -0,0 +1,16 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: UAL vcmp with 0
+#as: -mfpu=vfpv3
+
+.*: +file format .*arm.*
+
+
+Disassembly of section .text:
+0+000 <[^>]*> eeb50a40 	vcmp.f32	s0, #0.0
+0+004 <[^>]*> eef50a40 	vcmp.f32	s1, #0.0
+0+008 <[^>]*> eef51ac0 	vcmpe.f32	s3, #0.0
+0+00c <[^>]*> eeb52ac0 	vcmpe.f32	s4, #0.0
+0+010 <[^>]*> eeb50b40 	vcmp.f64	d0, #0.0
+0+014 <[^>]*> eeb51b40 	vcmp.f64	d1, #0.0
+0+018 <[^>]*> eeb52bc0 	vcmpe.f64	d2, #0.0
+0+01c <[^>]*> eeb53bc0 	vcmpe.f64	d3, #0.0
diff --git a/gas/testsuite/gas/arm/ual-vcmp.s b/gas/testsuite/gas/arm/ual-vcmp.s
new file mode 100644
index 0000000..d821ff6
--- /dev/null
+++ b/gas/testsuite/gas/arm/ual-vcmp.s
@@ -0,0 +1,13 @@
+.text
+.arm
+.syntax unified
+
+vcmp.f32	s0, #0.0
+vcmp.f32	s1, #0
+vcmpe.f32	s3, #0.0
+vcmpe.f32	s4, #0
+
+vcmp.f64	d0, #0.0
+vcmp.f64	d1, #0
+vcmpe.f64	d2, #0.0
+vcmpe.f64	d3, #0

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