* gas/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.
	* 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.
This commit is contained in:
Matthew Gretton-Dann 2012-08-24 08:09:50 +00:00
parent 6b9a8b6790
commit 7e8e678496
9 changed files with 238 additions and 24 deletions

View 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.

View 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). */

View File

@ -1,3 +1,10 @@
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.

View 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

View File

@ -28,6 +28,14 @@
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
@ -54,3 +62,11 @@
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

View 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

View File

@ -19,6 +19,14 @@
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
@ -37,3 +45,11 @@
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

View File

@ -1,3 +1,9 @@
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.

View 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':