From 7e8e6784961bb3d4dad66fd2a0d076628531acfa Mon Sep 17 00:00:00 2001 From: Matthew Gretton-Dann Date: Fri, 24 Aug 2012 08:09:50 +0000 Subject: [PATCH] * 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. --- gas/ChangeLog | 14 +++ gas/config/tc-arm.c | 166 ++++++++++++++++++++++++++++++----- gas/testsuite/ChangeLog | 7 ++ gas/testsuite/gas/arm/armv8-a+fp.d | 16 ++++ gas/testsuite/gas/arm/armv8-a+fp.s | 16 ++++ gas/testsuite/gas/arm/armv8-a+simd.d | 16 ++++ gas/testsuite/gas/arm/armv8-a+simd.s | 16 ++++ opcodes/ChangeLog | 6 ++ opcodes/arm-dis.c | 5 +- 9 files changed, 238 insertions(+), 24 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 8083dce..a798ef4 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,17 @@ +2012-08-24 Matthew Gretton-Dann + + * 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 * config/tc-arm.c (CVT_FLAVOUR_VAR): New define. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 7dc938b..f7749b3 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -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). */ diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 11bae09..4d05067 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,5 +1,12 @@ 2012-08-24 Matthew Gretton-Dann + * 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 + * 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. diff --git a/gas/testsuite/gas/arm/armv8-a+fp.d b/gas/testsuite/gas/arm/armv8-a+fp.d index c902874..ef54277 100644 --- a/gas/testsuite/gas/arm/armv8-a+fp.d +++ b/gas/testsuite/gas/arm/armv8-a+fp.d @@ -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 diff --git a/gas/testsuite/gas/arm/armv8-a+fp.s b/gas/testsuite/gas/arm/armv8-a+fp.s index e967b1a..a95e989 100644 --- a/gas/testsuite/gas/arm/armv8-a+fp.s +++ b/gas/testsuite/gas/arm/armv8-a+fp.s @@ -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 diff --git a/gas/testsuite/gas/arm/armv8-a+simd.d b/gas/testsuite/gas/arm/armv8-a+simd.d index d194ccb..f10140f 100644 --- a/gas/testsuite/gas/arm/armv8-a+simd.d +++ b/gas/testsuite/gas/arm/armv8-a+simd.d @@ -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 diff --git a/gas/testsuite/gas/arm/armv8-a+simd.s b/gas/testsuite/gas/arm/armv8-a+simd.s index f11103c..0578902 100644 --- a/gas/testsuite/gas/arm/armv8-a+simd.s +++ b/gas/testsuite/gas/arm/armv8-a+simd.s @@ -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 diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index abc851c..10a541d 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,5 +1,11 @@ 2012-08-24 Matthew Gretton-Dann + * arm-dis.c (coprocessor_opcodes): Add support for new VCVT + variants. + (neon_opcodes): Likewise. + +2012-08-24 Matthew Gretton-Dann + * arm-dis.c (coprocessor_opcodes): Add VMAXNM/VMINNM. (neon_opcodes): Likewise. diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index 9757c20..9d77432 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -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': -- 2.7.4