* gas/config/tc-arm.c (NEON_ENC_TAB): Add vcvta entry.
authorMatthew Gretton-Dann <matthew.gretton-dann@arm.com>
Fri, 24 Aug 2012 08:09:50 +0000 (08:09 +0000)
committerMatthew Gretton-Dann <matthew.gretton-dann@arm.com>
Fri, 24 Aug 2012 08:09:50 +0000 (08:09 +0000)
(neon_cvt_mode): New enumeration.
(do_vfp_nsyn_cvt_fpv8): New function.
(do_neon_cvt_1): Add support for new conversions.
(do_neon_cvtr): Use neon_cvt_mode enumerator.
(do_neon_cvt): Likewise.
(do_neon_cvta): New function.
(do_neon_cvtn): Likewise.
(do_neon_cvtp): Likewise.
(do_neon_cvtm): Likewise.
(insns): Add new VCVT instructions.
* gas/testsuite/gas/arm/armv8-a+fp.d: Update testcase.
* gas/testsuite/gas/arm/armv8-a+fp.s: Likewise.
* gas/testsuite/gas/arm/armv8-a+simd.d: Likewise.
* gas/testsuite/gas/arm/armv8-a+simd.s: Likewise.
* opcodes/arm-dis.c (coprocessor_opcodes): Add support for new VCVT
variants.
(neon_opcodes): Likewise.

gas/ChangeLog
gas/config/tc-arm.c
gas/testsuite/ChangeLog
gas/testsuite/gas/arm/armv8-a+fp.d
gas/testsuite/gas/arm/armv8-a+fp.s
gas/testsuite/gas/arm/armv8-a+simd.d
gas/testsuite/gas/arm/armv8-a+simd.s
opcodes/ChangeLog
opcodes/arm-dis.c

index 8083dce..a798ef4 100644 (file)
@@ -1,3 +1,17 @@
+2012-08-24  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
+
+       * config/tc-arm.c (NEON_ENC_TAB): Add vcvta entry.
+       (neon_cvt_mode): New enumeration.
+       (do_vfp_nsyn_cvt_fpv8): New function.
+       (do_neon_cvt_1): Add support for new conversions.
+       (do_neon_cvtr): Use neon_cvt_mode enumerator.
+       (do_neon_cvt): Likewise.
+       (do_neon_cvta): New function.
+       (do_neon_cvtn): Likewise.
+       (do_neon_cvtp): Likewise.
+       (do_neon_cvtm): Likewise.
+       (insns): Add new VCVT instructions.
+
 2012-08-24  Matthew Gretton-Dann  <matthew.gretton-dann@arm>
 
        * config/tc-arm.c (CVT_FLAVOUR_VAR): New define.
index 7dc938b..f7749b3 100644 (file)
@@ -12347,7 +12347,8 @@ struct neon_tab_entry
   X(vselge,    0xe200a00, N_INV,     N_INV),           \
   X(vselgt,    0xe300a00, N_INV,     N_INV),           \
   X(vmaxnm,    0xe800a00, 0x3000f10, N_INV),           \
-  X(vminnm,    0xe800a40, 0x3200f10, N_INV)
+  X(vminnm,    0xe800a40, 0x3200f10, N_INV),           \
+  X(vcvta,     0xebc0a40, 0x3bb0000, N_INV)
 
 enum neon_opc
 {
@@ -14574,6 +14575,16 @@ get_neon_cvt_flavour (enum neon_shape rs)
 #undef CVT_VAR
 }
 
+enum neon_cvt_mode
+{
+  neon_cvt_mode_a,
+  neon_cvt_mode_n,
+  neon_cvt_mode_p,
+  neon_cvt_mode_m,
+  neon_cvt_mode_z,
+  neon_cvt_mode_x
+};
+
 /* Neon-syntax VFP conversions.  */
 
 static void
@@ -14638,14 +14649,65 @@ do_vfp_nsyn_cvtz (void)
 }
 
 static void
-do_neon_cvt_1 (bfd_boolean round_to_zero ATTRIBUTE_UNUSED)
+do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour, 
+                     enum neon_cvt_mode mode)
+{
+  int sz, op;
+  int rm;
+
+  set_it_insn_type (OUTSIDE_IT_INSN);
+
+  switch (flavour)
+    {
+    case neon_cvt_flavour_s32_f64:
+      sz = 1;
+      op = 0;
+      break;
+    case neon_cvt_flavour_s32_f32:
+      sz = 0;
+      op = 1;
+      break;
+    case neon_cvt_flavour_u32_f64:
+      sz = 1;
+      op = 0;
+      break;
+    case neon_cvt_flavour_u32_f32:
+      sz = 0;
+      op = 0;
+      break;
+    default:
+      first_error (_("invalid instruction shape"));
+      return;
+    }
+
+  switch (mode)
+    {
+    case neon_cvt_mode_a: rm = 0; break;
+    case neon_cvt_mode_n: rm = 1; break;
+    case neon_cvt_mode_p: rm = 2; break;
+    case neon_cvt_mode_m: rm = 3; break;
+    default: first_error (_("invalid rounding mode")); return;
+    }
+
+  NEON_ENCODE (FPV8, inst);
+  encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
+  encode_arm_vfp_reg (inst.operands[1].reg, sz == 1 ? VFP_REG_Dm : VFP_REG_Sm);
+  inst.instruction |= sz << 8;
+  inst.instruction |= op << 7;
+  inst.instruction |= rm << 16;
+  inst.instruction |= 0xf0000000;
+  inst.is_neon = TRUE;
+}
+
+static void
+do_neon_cvt_1 (enum neon_cvt_mode mode)
 {
   enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_FFI, NS_DD, NS_QQ,
     NS_FD, NS_DF, NS_FF, NS_QD, NS_DQ, NS_NULL);
   enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
 
   /* PR11109: Handle round-to-zero for VCVT conversions.  */
-  if (round_to_zero
+  if (mode == neon_cvt_mode_z
       && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_vfp_v2)
       && (flavour == neon_cvt_flavour_s32_f32 
          || flavour == neon_cvt_flavour_u32_f32 
@@ -14660,7 +14722,11 @@ do_neon_cvt_1 (bfd_boolean round_to_zero ATTRIBUTE_UNUSED)
   /* VFP rather than Neon conversions.  */
   if (flavour >= neon_cvt_flavour_first_fp)
     {
-      do_vfp_nsyn_cvt (rs, flavour);
+      if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
+       do_vfp_nsyn_cvt (rs, flavour);
+      else
+       do_vfp_nsyn_cvt_fpv8 (flavour, mode);
+
       return;
     }
 
@@ -14697,28 +14763,51 @@ do_neon_cvt_1 (bfd_boolean round_to_zero ATTRIBUTE_UNUSED)
 
     case NS_DD:
     case NS_QQ:
+      if (mode != neon_cvt_mode_x && mode != neon_cvt_mode_z)
+       {
+         NEON_ENCODE (FLOAT, inst);
+         set_it_insn_type (OUTSIDE_IT_INSN);
+
+         if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
+           return;
+
+         inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+         inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+         inst.instruction |= LOW4 (inst.operands[1].reg);
+         inst.instruction |= HI1 (inst.operands[1].reg) << 5;
+         inst.instruction |= neon_quad (rs) << 6;
+         inst.instruction |= (flavour == neon_cvt_flavour_u32_f32) << 7;
+         inst.instruction |= mode << 8;
+         if (thumb_mode)
+           inst.instruction |= 0xfc000000;
+         else
+           inst.instruction |= 0xf0000000;
+       }
+      else
+       {
     int_encode:
-      {
-        unsigned enctab[] = { 0x100, 0x180, 0x0, 0x080 };
+         {
+           unsigned enctab[] = { 0x100, 0x180, 0x0, 0x080 };
 
-        NEON_ENCODE (INTEGER, inst);
+           NEON_ENCODE (INTEGER, inst);
 
-        if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
-          return;
+           if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
+             return;
 
-        if (flavour != neon_cvt_flavour_invalid)
-          inst.instruction |= enctab[flavour];
+           if (flavour != neon_cvt_flavour_invalid)
+             inst.instruction |= enctab[flavour];
 
-        inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
-        inst.instruction |= HI1 (inst.operands[0].reg) << 22;
-        inst.instruction |= LOW4 (inst.operands[1].reg);
-        inst.instruction |= HI1 (inst.operands[1].reg) << 5;
-        inst.instruction |= neon_quad (rs) << 6;
-        inst.instruction |= 2 << 18;
+           inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
+           inst.instruction |= HI1 (inst.operands[0].reg) << 22;
+           inst.instruction |= LOW4 (inst.operands[1].reg);
+           inst.instruction |= HI1 (inst.operands[1].reg) << 5;
+           inst.instruction |= neon_quad (rs) << 6;
+           inst.instruction |= 2 << 18;
 
-        neon_dp_fixup (&inst);
-      }
-    break;
+           neon_dp_fixup (&inst);
+         }
+       }
+      break;
 
     /* Half-precision conversions for Advanced SIMD -- neon.  */
     case NS_QD:
@@ -14752,20 +14841,47 @@ do_neon_cvt_1 (bfd_boolean round_to_zero ATTRIBUTE_UNUSED)
 
     default:
       /* Some VFP conversions go here (s32 <-> f32, u32 <-> f32).  */
-      do_vfp_nsyn_cvt (rs, flavour);
+      if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
+       do_vfp_nsyn_cvt (rs, flavour);
+      else
+       do_vfp_nsyn_cvt_fpv8 (flavour, mode);
     }
 }
 
 static void
 do_neon_cvtr (void)
 {
-  do_neon_cvt_1 (FALSE);
+  do_neon_cvt_1 (neon_cvt_mode_x);
 }
 
 static void
 do_neon_cvt (void)
 {
-  do_neon_cvt_1 (TRUE);
+  do_neon_cvt_1 (neon_cvt_mode_z);
+}
+
+static void
+do_neon_cvta (void)
+{
+  do_neon_cvt_1 (neon_cvt_mode_a);
+}
+
+static void
+do_neon_cvtn (void)
+{
+  do_neon_cvt_1 (neon_cvt_mode_n);
+}
+
+static void
+do_neon_cvtp (void)
+{
+  do_neon_cvt_1 (neon_cvt_mode_p);
+}
+
+static void
+do_neon_cvtm (void)
+{
+  do_neon_cvt_1 (neon_cvt_mode_m);
 }
 
 static void
@@ -18100,6 +18216,10 @@ static const struct asm_opcode insns[] =
   nUF(vselgt, _vselgt, 3, (RVSD, RVSD, RVSD),          vsel),
   nUF(vmaxnm, _vmaxnm, 3, (RNSDQ, oRNSDQ, RNSDQ),      vmaxnm),
   nUF(vminnm, _vminnm, 3, (RNSDQ, oRNSDQ, RNSDQ),      vmaxnm),
+  nUF(vcvta,  _vcvta,  2, (RNSDQ, oRNSDQ),             neon_cvta),
+  nUF(vcvtn,  _vcvta,  2, (RNSDQ, oRNSDQ),             neon_cvtn),
+  nUF(vcvtp,  _vcvta,  2, (RNSDQ, oRNSDQ),             neon_cvtp),
+  nUF(vcvtm,  _vcvta,  2, (RNSDQ, oRNSDQ),             neon_cvtm),
 
 #undef  ARM_VARIANT
 #define ARM_VARIANT  & fpu_fpa_ext_v1  /* Core FPA instruction set (V1).  */
index 11bae09..4d05067 100644 (file)
@@ -1,5 +1,12 @@
 2012-08-24  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
 
+       * gas/arm/armv8-a+fp.d: Update testcase.
+       * gas/arm/armv8-a+fp.s: Likewise.
+       * gas/arm/armv8-a+simd.d: Likewise.
+       * gas/arm/armv8-a+simd.s: Likewise.
+
+2012-08-24  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
+
        * gas/testsuite/gas/armv8-a+fp.d: Update testcase.
        * gas/testsuite/gas/armv8-a+fp.s: Likewise.
        * gas/testsuite/gas/armv8-a+simd.d: New testcase.
index c902874..ef54277 100644 (file)
@@ -28,6 +28,14 @@ Disassembly of section .text:
 0[0-9a-f]+ <[^>]+> fec00be0    vminnm.f64      d16, d16, d16
 0[0-9a-f]+ <[^>]+> fe8ffb4f    vminnm.f64      d15, d15, d15
 0[0-9a-f]+ <[^>]+> fecffbef    vminnm.f64      d31, d31, d31
+0[0-9a-f]+ <[^>]+> febc0ac0    vcvta.s32.f32   s0, s0
+0[0-9a-f]+ <[^>]+> fefd0ae0    vcvtn.s32.f32   s1, s1
+0[0-9a-f]+ <[^>]+> febefa4f    vcvtp.u32.f32   s30, s30
+0[0-9a-f]+ <[^>]+> fefffa6f    vcvtm.u32.f32   s31, s31
+0[0-9a-f]+ <[^>]+> febc0b40    vcvta.u32.f64   s0, d0
+0[0-9a-f]+ <[^>]+> fefd0b60    vcvtn.u32.f64   s1, d16
+0[0-9a-f]+ <[^>]+> febefb4f    vcvtp.u32.f64   s30, d15
+0[0-9a-f]+ <[^>]+> fefffb6f    vcvtm.u32.f64   s31, 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
@@ -52,3 +60,11 @@ Disassembly of section .text:
 0[0-9a-f]+ <[^>]+> fec0 0be0   vminnm.f64      d16, d16, d16
 0[0-9a-f]+ <[^>]+> fe8f fb4f   vminnm.f64      d15, d15, d15
 0[0-9a-f]+ <[^>]+> fecf fbef   vminnm.f64      d31, d31, d31
+0[0-9a-f]+ <[^>]+> febc 0ac0   vcvta.s32.f32   s0, s0
+0[0-9a-f]+ <[^>]+> fefd 0ae0   vcvtn.s32.f32   s1, s1
+0[0-9a-f]+ <[^>]+> febe fa4f   vcvtp.u32.f32   s30, s30
+0[0-9a-f]+ <[^>]+> feff fa6f   vcvtm.u32.f32   s31, s31
+0[0-9a-f]+ <[^>]+> febc 0b40   vcvta.u32.f64   s0, d0
+0[0-9a-f]+ <[^>]+> fefd 0b60   vcvtn.u32.f64   s1, d16
+0[0-9a-f]+ <[^>]+> febe fb4f   vcvtp.u32.f64   s30, d15
+0[0-9a-f]+ <[^>]+> feff fb6f   vcvtm.u32.f64   s31, d31
index e967b1a..a95e989 100644 (file)
        vminnm.f64      d16, d16, d16
        vminnm.f64      d15, d15, d15
        vminnm.f64      d31, d31, d31
+       vcvta.s32.f32   s0, s0
+       vcvtn.s32.f32   s1, s1
+       vcvtp.u32.f32   s30, s30
+       vcvtm.u32.f32   s31, s31
+       vcvta.s32.f64   s0, d0
+       vcvtn.s32.f64   s1, d16
+       vcvtp.u32.f64   s30, d15
+       vcvtm.u32.f64   s31, d31
 
        .thumb
        vseleq.f32      s0, s0, s0
        vminnm.f64      d16, d16, d16
        vminnm.f64      d15, d15, d15
        vminnm.f64      d31, d31, d31
+       vcvta.s32.f32   s0, s0
+       vcvtn.s32.f32   s1, s1
+       vcvtp.u32.f32   s30, s30
+       vcvtm.u32.f32   s31, s31
+       vcvta.s32.f64   s0, d0
+       vcvtn.s32.f64   s1, d16
+       vcvtp.u32.f64   s30, d15
+       vcvtm.u32.f64   s31, d31
index d194ccb..f10140f 100644 (file)
@@ -20,6 +20,14 @@ Disassembly of section .text:
 0[0-9a-f]+ <[^>]+> f3600ff0    vminnm.f32      q8, q8, q8
 0[0-9a-f]+ <[^>]+> f32eef5e    vminnm.f32      q7, q7, q7
 0[0-9a-f]+ <[^>]+> f36eeffe    vminnm.f32      q15, q15, q15
+0[0-9a-f]+ <[^>]+> f3bb0000    vcvta.s32.f32   d0, d0
+0[0-9a-f]+ <[^>]+> f3fb0120    vcvtn.s32.f32   d16, d16
+0[0-9a-f]+ <[^>]+> f3bbf28f    vcvtp.u32.f32   d15, d15
+0[0-9a-f]+ <[^>]+> f3fbf3af    vcvtm.u32.f32   d31, d31
+0[0-9a-f]+ <[^>]+> f3bb0040    vcvta.s32.f32   q0, q0
+0[0-9a-f]+ <[^>]+> f3fb0160    vcvtn.s32.f32   q8, q8
+0[0-9a-f]+ <[^>]+> f3bbe2ce    vcvtp.u32.f32   q7, q7
+0[0-9a-f]+ <[^>]+> f3fbe3ee    vcvtm.u32.f32   q15, q15
 0[0-9a-f]+ <[^>]+> ff00 0f10   vmaxnm.f32      d0, d0, d0
 0[0-9a-f]+ <[^>]+> ff40 0fb0   vmaxnm.f32      d16, d16, d16
 0[0-9a-f]+ <[^>]+> ff0f ff1f   vmaxnm.f32      d15, d15, d15
@@ -36,3 +44,11 @@ Disassembly of section .text:
 0[0-9a-f]+ <[^>]+> ff60 0ff0   vminnm.f32      q8, q8, q8
 0[0-9a-f]+ <[^>]+> ff2e ef5e   vminnm.f32      q7, q7, q7
 0[0-9a-f]+ <[^>]+> ff6e effe   vminnm.f32      q15, q15, q15
+0[0-9a-f]+ <[^>]+> ffbb 0000   vcvta.s32.f32   d0, d0
+0[0-9a-f]+ <[^>]+> fffb 0120   vcvtn.s32.f32   d16, d16
+0[0-9a-f]+ <[^>]+> ffbb f28f   vcvtp.u32.f32   d15, d15
+0[0-9a-f]+ <[^>]+> fffb f3af   vcvtm.u32.f32   d31, d31
+0[0-9a-f]+ <[^>]+> ffbb 0040   vcvta.s32.f32   q0, q0
+0[0-9a-f]+ <[^>]+> fffb 0160   vcvtn.s32.f32   q8, q8
+0[0-9a-f]+ <[^>]+> ffbb e2ce   vcvtp.u32.f32   q7, q7
+0[0-9a-f]+ <[^>]+> fffb e3ee   vcvtm.u32.f32   q15, q15
index f11103c..0578902 100644 (file)
        vminnm.f32      q8, q8, q8
        vminnm.f32      q7, q7, q7
        vminnm.f32      q15, q15, q15
+       vcvta.s32.f32   d0, d0
+       vcvtn.s32.f32   d16, d16
+       vcvtp.u32.f32   d15, d15
+       vcvtm.u32.f32   d31, d31
+       vcvta.s32.f32   q0, q0
+       vcvtn.s32.f32   q8, q8
+       vcvtp.u32.f32   q7, q7
+       vcvtm.u32.f32   q15, q15
 
        .thumb
        vmaxnm.f32      d0, d0, d0
        vminnm.f32      q8, q8, q8
        vminnm.f32      q7, q7, q7
        vminnm.f32      q15, q15, q15
+       vcvta.s32.f32   d0, d0
+       vcvtn.s32.f32   d16, d16
+       vcvtp.u32.f32   d15, d15
+       vcvtm.u32.f32   d31, d31
+       vcvta.s32.f32   q0, q0
+       vcvtn.s32.f32   q8, q8
+       vcvtp.u32.f32   q7, q7
+       vcvtm.u32.f32   q15, q15
index abc851c..10a541d 100644 (file)
@@ -1,5 +1,11 @@
 2012-08-24  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
 
+       * arm-dis.c (coprocessor_opcodes): Add support for new VCVT
+       variants.
+       (neon_opcodes): Likewise.
+
+2012-08-24  Matthew Gretton-Dann  <matthew.gretton-dann@arm.com>
+
        * arm-dis.c (coprocessor_opcodes): Add VMAXNM/VMINNM.
        (neon_opcodes): Likewise.
 
index 9757c20..9d77432 100644 (file)
@@ -494,6 +494,8 @@ static const struct opcode32 coprocessor_opcodes[] =
   {FPU_VFP_EXT_ARMV8, 0xfe800b00, 0xffb00f40, "vmaxnm%u.f64\t%z1, %z2, %z0"},
   {FPU_VFP_EXT_ARMV8, 0xfe800a40, 0xffb00f40, "vminnm%u.f32\t%y1, %y2, %y0"},
   {FPU_VFP_EXT_ARMV8, 0xfe800b40, 0xffb00f40, "vminnm%u.f64\t%z1, %z2, %z0"},
+  {FPU_VFP_EXT_ARMV8, 0xfebc0a40, 0xffbc0f50, "vcvt%16-17?mpna%u.%7?su32.f32\t%y1, %y0"},
+  {FPU_VFP_EXT_ARMV8, 0xfebc0b40, 0xffbc0f50, "vcvt%16-17?mpna%u.%7?su32.f64\t%y1, %z0"},
 
   /* Generic coprocessor instructions.  */
   { 0, SENTINEL_GENERIC_START, 0, "" },
@@ -576,6 +578,7 @@ static const struct opcode32 neon_opcodes[] =
   {FPU_NEON_EXT_FMA, 0xf2200c10, 0xffa00f10, "vfms%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
 
   /* Two registers, miscellaneous.  */
+  {FPU_NEON_EXT_ARMV8, 0xf3bb0000, 0xffbf0c10, "vcvt%8-9?mpna%u.%7?us32.f32\t%12-15,22R, %0-3,5R"},
   {FPU_NEON_EXT_V1, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
   {FPU_NEON_EXT_V1, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
   {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
@@ -2917,7 +2920,7 @@ print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
                          func (stream, "{d%d-d%d}", regno, regno + num);
                      }
                      break;
-      
+
 
                    case '0': case '1': case '2': case '3': case '4':
                    case '5': case '6': case '7': case '8': case '9':