This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [GAS][ARM][3/3]Add armv8.2 fp16 scalar instruction support. [Based on SE_H instruction shape for .f16, u16, s16, .16 type specifier]
- From: Renlin Li <renlin dot li at foss dot arm dot com>
- To: Nick Clifton <nickc at redhat dot com>, "binutils at sourceware dot org" <binutils at sourceware dot org>
- Cc: Marcus Shawcroft <Marcus dot Shawcroft at arm dot com>, Ramana Radhakrishnan <Ramana dot Radhakrishnan at arm dot com>, Richard Earnshaw <Richard dot Earnshaw at arm dot com>
- Date: Wed, 24 Feb 2016 16:39:31 +0000
- Subject: Re: [GAS][ARM][3/3]Add armv8.2 fp16 scalar instruction support. [Based on SE_H instruction shape for .f16, u16, s16, .16 type specifier]
- Authentication-results: sourceware.org; auth=none
- References: <56C6FB4A dot 7000302 at foss dot arm dot com> <56C6FCE8 dot 2090103 at foss dot arm dot com> <56C6FE36 dot 80509 at foss dot arm dot com> <56CAF509 dot 4010500 at redhat dot com>
Hi Nick,
Skipped all non-elf target, patch updated, OK for trunk?
Regards,
Renlin Li
gas/ChangeLog:
2016-02-24 Renlin Li <renlin.li@arm.com>
* config/tc-arm.c (BAD_FP16): New error message macro.
(do_scalar_fp16_v82_encode): Change the coproc field to 9 for armv8.2
fp16 scalar instructions.
(neon_check_type): Allow different size from key.
(do_vfp_nsyn_add_sub): Add support SE_H shape support.
(try_vfp_nsyn): Likewise.
(do_vfp_nsyn_mla_mls): Likewise.
(do_vfp_nsyn_fma_fms): Likewise.
(do_vfp_nsyn_ldm_stm): Likewise
(do_vfp_nsyn_sqrt): Likewise
(do_vfp_nsyn_div): Likewise
(do_vfp_nsyn_nmul): Likewise.
(do_vfp_nsyn_cmp): Likewise.
(do_neon_shll): Likewise.
(do_vfp_nsyn_cvt_fpv8): Likewise.
(do_neon_cvttb_2): Likewise.
(do_neon_mov): Likewise.
(do_neon_rshift_round_imm): Likewise.
(do_neon_ldr_str): Likewise.
(do_vfp_nsyn_fpv8): Likewise.
(do_vmaxnm): Likewise.
(do_vrint_1): Likewise.
(insns): New entry for vins, vmovx.
(md_apply_fix): Left shift 1 bit for fp16 vldr/vstr.
* testsuite/gas/arm/armv8-2-fp16-scalar-thumb.d: New.
* testsuite/gas/arm/armv8-2-fp16-scalar.d: New.
* testsuite/gas/arm/armv8-2-fp16-scalar.s: New.
* testsuite/gas/arm/armv8-2-fp16-scalar-bad.s: New
* testsuite/gas/arm/armv8-2-fp16-scalar-bad.d: New
* testsuite/gas/arm/armv8-2-fp16-scalar-bad.l: New
On 22/02/16 11:46, Nick Clifton wrote:
Hi Renlin,
diff --git a/gas/testsuite/gas/arm/armv8-2-fp16-scalar-thumb.d b/gas/testsuite/gas/arm/armv8-2-fp16-scalar-thumb.d
new file mode 100644
index 0000000000000000000000000000000000000000..f196c4a5973874cb4cb29c00aeec3c0f10fc2625
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-2-fp16-scalar-thumb.d
@@ -0,0 +1,74 @@
+#name: ARM v8.2 FP16 support on scalar (Thumb)
+#source: armv8-2-fp16-scalar.s
+#objdump: -d
+#as: -march=armv8.2-a+fp16 -mfpu=fp-armv8 -mthumb
Is this new test going to work on PE and COFF based ARM targets ?
Cheers
Nick
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 8d2078bab4a051f47e77bf419ed5de6fee3957de..4a1de7c9613dc9b34ef581d4853f0d5943e98552 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -777,7 +777,8 @@ struct asm_opcode
_("cannot use register index with PC-relative addressing")
#define BAD_PC_WRITEBACK \
_("cannot use writeback with PC-relative addressing")
-#define BAD_RANGE _("branch out of range")
+#define BAD_RANGE _("branch out of range")
+#define BAD_FP16 _("selected processor does not support fp16 instruction")
#define UNPRED_REG(R) _("using " R " results in unpredictable behaviour")
static struct hash_control * arm_ops_hsh;
@@ -7235,6 +7236,26 @@ parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
#define rotate_left(v, n) (v << (n & 31) | v >> ((32 - n) & 31))
+/* If the current inst is scalar ARMv8.2 fp16 instruction, do special encoding.
+
+ The only binary encoding difference is the Coprocessor number. Coprocessor
+ 9 is used for half-precision calculations or conversions. The format of the
+ instruction is the same as the equivalent Coprocessor 10 instuction that
+ exists for Single-Precision operation. */
+
+static void
+do_scalar_fp16_v82_encode (void)
+{
+ if (inst.cond != COND_ALWAYS)
+ as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
+ " the behaviour is UNPREDICTABLE"));
+ constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
+ _(BAD_FP16));
+
+ inst.instruction = (inst.instruction & 0xfffff0ff) | 0x900;
+ mark_feature_used (&arm_ext_fp16);
+}
+
/* If VAL can be encoded in the immediate field of an ARM instruction,
return the encoded form. Otherwise, return FAIL. */
@@ -13841,6 +13862,18 @@ neon_check_type (unsigned els, enum neon_shape ns, ...)
else
match = g_size;
+ /* FP16 will use a single precision register. */
+ if (regwidth == 32 && match == 16)
+ {
+ if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
+ match = regwidth;
+ else
+ {
+ inst.error = _(BAD_FP16);
+ return badtype;
+ }
+ }
+
if (regwidth != match)
{
first_error (_("operand size must match register width"));
@@ -13932,12 +13965,16 @@ do_vfp_nsyn_add_sub (enum neon_shape rs)
{
int is_add = (inst.instruction & 0x0fffffff) == N_MNEM_vadd;
- if (rs == NS_FFF)
+ if (rs == NS_FFF || rs == NS_HHH)
{
if (is_add)
do_vfp_nsyn_opcode ("fadds");
else
do_vfp_nsyn_opcode ("fsubs");
+
+ /* ARMv8.2 fp16 instruction. */
+ if (rs == NS_HHH)
+ do_scalar_fp16_v82_encode ();
}
else
{
@@ -13960,15 +13997,14 @@ try_vfp_nsyn (int args, void (*pfn) (enum neon_shape))
switch (args)
{
case 2:
- rs = neon_select_shape (NS_FF, NS_DD, NS_NULL);
- et = neon_check_type (2, rs,
- N_EQK | N_VFP, N_F32 | N_F64 | N_KEY | N_VFP);
+ rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
+ et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
break;
case 3:
- rs = neon_select_shape (NS_FFF, NS_DDD, NS_NULL);
- et = neon_check_type (3, rs,
- N_EQK | N_VFP, N_EQK | N_VFP, N_F32 | N_F64 | N_KEY | N_VFP);
+ rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
+ et = neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
+ N_F_ALL | N_KEY | N_VFP);
break;
default:
@@ -13990,12 +14026,16 @@ do_vfp_nsyn_mla_mls (enum neon_shape rs)
{
int is_mla = (inst.instruction & 0x0fffffff) == N_MNEM_vmla;
- if (rs == NS_FFF)
+ if (rs == NS_FFF || rs == NS_HHH)
{
if (is_mla)
do_vfp_nsyn_opcode ("fmacs");
else
do_vfp_nsyn_opcode ("fnmacs");
+
+ /* ARMv8.2 fp16 instruction. */
+ if (rs == NS_HHH)
+ do_scalar_fp16_v82_encode ();
}
else
{
@@ -14011,12 +14051,16 @@ do_vfp_nsyn_fma_fms (enum neon_shape rs)
{
int is_fma = (inst.instruction & 0x0fffffff) == N_MNEM_vfma;
- if (rs == NS_FFF)
+ if (rs == NS_FFF || rs == NS_HHH)
{
if (is_fma)
do_vfp_nsyn_opcode ("ffmas");
else
do_vfp_nsyn_opcode ("ffnmas");
+
+ /* ARMv8.2 fp16 instruction. */
+ if (rs == NS_HHH)
+ do_scalar_fp16_v82_encode ();
}
else
{
@@ -14030,8 +14074,14 @@ do_vfp_nsyn_fma_fms (enum neon_shape rs)
static void
do_vfp_nsyn_mul (enum neon_shape rs)
{
- if (rs == NS_FFF)
- do_vfp_nsyn_opcode ("fmuls");
+ if (rs == NS_FFF || rs == NS_HHH)
+ {
+ do_vfp_nsyn_opcode ("fmuls");
+
+ /* ARMv8.2 fp16 instruction. */
+ if (rs == NS_HHH)
+ do_scalar_fp16_v82_encode ();
+ }
else
do_vfp_nsyn_opcode ("fmuld");
}
@@ -14040,14 +14090,18 @@ static void
do_vfp_nsyn_abs_neg (enum neon_shape rs)
{
int is_neg = (inst.instruction & 0x80) != 0;
- neon_check_type (2, rs, N_EQK | N_VFP, N_F32 | N_F64 | N_VFP | N_KEY);
+ neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_VFP | N_KEY);
- if (rs == NS_FF)
+ if (rs == NS_FF || rs == NS_HH)
{
if (is_neg)
do_vfp_nsyn_opcode ("fnegs");
else
do_vfp_nsyn_opcode ("fabss");
+
+ /* ARMv8.2 fp16 instruction. */
+ if (rs == NS_HH)
+ do_scalar_fp16_v82_encode ();
}
else
{
@@ -14084,11 +14138,17 @@ do_vfp_nsyn_ldm_stm (int is_dbmode)
static void
do_vfp_nsyn_sqrt (void)
{
- enum neon_shape rs = neon_select_shape (NS_FF, NS_DD, NS_NULL);
- neon_check_type (2, rs, N_EQK | N_VFP, N_F32 | N_F64 | N_KEY | N_VFP);
+ enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
+ neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
- if (rs == NS_FF)
- do_vfp_nsyn_opcode ("fsqrts");
+ if (rs == NS_FF || rs == NS_HH)
+ {
+ do_vfp_nsyn_opcode ("fsqrts");
+
+ /* ARMv8.2 fp16 instruction. */
+ if (rs == NS_HH)
+ do_scalar_fp16_v82_encode ();
+ }
else
do_vfp_nsyn_opcode ("fsqrtd");
}
@@ -14096,12 +14156,18 @@ do_vfp_nsyn_sqrt (void)
static void
do_vfp_nsyn_div (void)
{
- enum neon_shape rs = neon_select_shape (NS_FFF, NS_DDD, NS_NULL);
+ enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
- N_F32 | N_F64 | N_KEY | N_VFP);
+ N_F_ALL | N_KEY | N_VFP);
- if (rs == NS_FFF)
- do_vfp_nsyn_opcode ("fdivs");
+ if (rs == NS_FFF || rs == NS_HHH)
+ {
+ do_vfp_nsyn_opcode ("fdivs");
+
+ /* ARMv8.2 fp16 instruction. */
+ if (rs == NS_HHH)
+ do_scalar_fp16_v82_encode ();
+ }
else
do_vfp_nsyn_opcode ("fdivd");
}
@@ -14109,14 +14175,18 @@ do_vfp_nsyn_div (void)
static void
do_vfp_nsyn_nmul (void)
{
- enum neon_shape rs = neon_select_shape (NS_FFF, NS_DDD, NS_NULL);
+ enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
- N_F32 | N_F64 | N_KEY | N_VFP);
+ N_F_ALL | N_KEY | N_VFP);
- if (rs == NS_FFF)
+ if (rs == NS_FFF || rs == NS_HHH)
{
NEON_ENCODE (SINGLE, inst);
do_vfp_sp_dyadic ();
+
+ /* ARMv8.2 fp16 instruction. */
+ if (rs == NS_HHH)
+ do_scalar_fp16_v82_encode ();
}
else
{
@@ -14124,17 +14194,19 @@ do_vfp_nsyn_nmul (void)
do_vfp_dp_rd_rn_rm ();
}
do_vfp_cond_or_thumb ();
+
}
static void
do_vfp_nsyn_cmp (void)
{
+ enum neon_shape rs;
if (inst.operands[1].isreg)
{
- enum neon_shape rs = neon_select_shape (NS_FF, NS_DD, NS_NULL);
- neon_check_type (2, rs, N_EQK | N_VFP, N_F32 | N_F64 | N_KEY | N_VFP);
+ rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
+ neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
- if (rs == NS_FF)
+ if (rs == NS_FF || rs == NS_HH)
{
NEON_ENCODE (SINGLE, inst);
do_vfp_sp_monadic ();
@@ -14147,8 +14219,8 @@ do_vfp_nsyn_cmp (void)
}
else
{
- enum neon_shape rs = neon_select_shape (NS_FI, NS_DI, NS_NULL);
- neon_check_type (2, rs, N_F32 | N_F64 | N_KEY | N_VFP, N_EQK);
+ rs = neon_select_shape (NS_HI, NS_FI, NS_DI, NS_NULL);
+ neon_check_type (2, rs, N_F_ALL | N_KEY | N_VFP, N_EQK);
switch (inst.instruction & 0x0fffffff)
{
@@ -14162,7 +14234,7 @@ do_vfp_nsyn_cmp (void)
abort ();
}
- if (rs == NS_FI)
+ if (rs == NS_FI || rs == NS_HI)
{
NEON_ENCODE (SINGLE, inst);
do_vfp_sp_compare_z ();
@@ -14174,6 +14246,10 @@ do_vfp_nsyn_cmp (void)
}
}
do_vfp_cond_or_thumb ();
+
+ /* ARMv8.2 fp16 instruction. */
+ if (rs == NS_HI || rs == NS_HH)
+ do_scalar_fp16_v82_encode ();
}
static void
@@ -15139,6 +15215,13 @@ do_neon_shll (void)
/* Half-precision conversions. */ \
CVT_VAR (f32_f16, N_F32, N_F16, whole_reg, NULL, NULL, NULL) \
CVT_VAR (f16_f32, N_F16, N_F32, whole_reg, NULL, NULL, NULL) \
+ /* New VCVT instructions introduced by ARMv8.2 fp16 extension. \
+ Compared with single/double precision variants, only the co-processor \
+ field is different, so the encoding flow is reused here. */ \
+ CVT_VAR (f16_s32, N_F16 | N_KEY, N_S32, N_VFP, "fsltos", "fsitos", NULL) \
+ CVT_VAR (f16_u32, N_F16 | N_KEY, N_U32, N_VFP, "fultos", "fuitos", NULL) \
+ CVT_VAR (u32_f16, N_U32, N_F16 | N_KEY, N_VFP, "ftouls", "ftouis", "ftouizs")\
+ CVT_VAR (s32_f16, N_S32, N_F16 | N_KEY, N_VFP, "ftosls", "ftosis", "ftosizs")\
/* VFP instructions. */ \
CVT_VAR (f32_f64, N_F32, N_F64, N_VFP, NULL, "fcvtsd", NULL) \
CVT_VAR (f64_f32, N_F64, N_F32, N_VFP, NULL, "fcvtds", NULL) \
@@ -15251,6 +15334,13 @@ do_vfp_nsyn_cvt (enum neon_shape rs, enum neon_cvt_flavour flavour)
if (opname)
do_vfp_nsyn_opcode (opname);
+
+ /* ARMv8.2 fp16 VCVT instruction. */
+ if (flavour == neon_cvt_flavour_s32_f16
+ || flavour == neon_cvt_flavour_u32_f16
+ || flavour == neon_cvt_flavour_f16_u32
+ || flavour == neon_cvt_flavour_f16_s32)
+ do_scalar_fp16_v82_encode ();
}
static void
@@ -15284,6 +15374,11 @@ do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
_(BAD_FPU));
+ if (flavour == neon_cvt_flavour_s32_f16
+ || flavour == neon_cvt_flavour_u32_f16)
+ constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
+ _(BAD_FP16));
+
set_it_insn_type (OUTSIDE_IT_INSN);
switch (flavour)
@@ -15296,6 +15391,10 @@ do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
sz = 0;
op = 1;
break;
+ case neon_cvt_flavour_s32_f16:
+ sz = 0;
+ op = 1;
+ break;
case neon_cvt_flavour_u32_f64:
sz = 1;
op = 0;
@@ -15304,6 +15403,10 @@ do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
sz = 0;
op = 0;
break;
+ case neon_cvt_flavour_u32_f16:
+ sz = 0;
+ op = 0;
+ break;
default:
first_error (_("invalid instruction shape"));
return;
@@ -15322,6 +15425,11 @@ do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
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;
+
+ /* ARMv8.2 fp16 VCVT instruction. */
+ if (flavour == neon_cvt_flavour_s32_f16
+ ||flavour == neon_cvt_flavour_u32_f16)
+ do_scalar_fp16_v82_encode ();
inst.instruction |= op << 7;
inst.instruction |= rm << 16;
inst.instruction |= 0xf0000000;
@@ -15350,6 +15458,18 @@ do_neon_cvt_1 (enum neon_cvt_mode mode)
return;
}
+ /* ARMv8.2 fp16 VCVT conversions. */
+ if (mode == neon_cvt_mode_z
+ && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16)
+ && (flavour == neon_cvt_flavour_s32_f16
+ || flavour == neon_cvt_flavour_u32_f16)
+ && (rs == NS_FH))
+ {
+ do_vfp_nsyn_cvtz ();
+ do_scalar_fp16_v82_encode ();
+ return;
+ }
+
/* VFP rather than Neon conversions. */
if (flavour >= neon_cvt_flavour_first_fp)
{
@@ -15915,8 +16035,9 @@ static void
do_neon_mov (void)
{
enum neon_shape rs = neon_select_shape (NS_RRFF, NS_FFRR, NS_DRR, NS_RRD,
- NS_QQ, NS_DD, NS_QI, NS_DI, NS_SR, NS_RS, NS_FF, NS_FI, NS_RF, NS_FR,
- NS_NULL);
+ NS_QQ, NS_DD, NS_QI, NS_DI, NS_SR,
+ NS_RS, NS_FF, NS_FI, NS_RF, NS_FR,
+ NS_HR, NS_RH, NS_HI, NS_NULL);
struct neon_type_el et;
const char *ldconst = 0;
@@ -16094,6 +16215,7 @@ do_neon_mov (void)
do_vfp_nsyn_opcode ("fcpys");
break;
+ case NS_HI:
case NS_FI: /* case 10 (fconsts). */
ldconst = "fconsts";
encode_fconstd:
@@ -16101,17 +16223,29 @@ do_neon_mov (void)
{
inst.operands[1].imm = neon_qfloat_bits (inst.operands[1].imm);
do_vfp_nsyn_opcode (ldconst);
+
+ /* ARMv8.2 fp16 vmov.f16 instruction. */
+ if (rs == NS_HI)
+ do_scalar_fp16_v82_encode ();
}
else
first_error (_("immediate out of range"));
break;
+ case NS_RH:
case NS_RF: /* case 12 (fmrs). */
do_vfp_nsyn_opcode ("fmrs");
+ /* ARMv8.2 fp16 vmov.f16 instruction. */
+ if (rs == NS_RH)
+ do_scalar_fp16_v82_encode ();
break;
+ case NS_HR:
case NS_FR: /* case 13 (fmsr). */
do_vfp_nsyn_opcode ("fmsr");
+ /* ARMv8.2 fp16 vmov.f16 instruction. */
+ if (rs == NS_HR)
+ do_scalar_fp16_v82_encode ();
break;
/* The encoders for the fmrrs and fmsrr instructions expect three operands
@@ -16168,6 +16302,21 @@ do_neon_rshift_round_imm (void)
}
static void
+do_neon_movhf (void)
+{
+ enum neon_shape rs = neon_select_shape (NS_HH, NS_NULL);
+ constraint (rs != NS_HH, _("invalid suffix"));
+
+ constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
+ _(BAD_FPU));
+
+ do_vfp_sp_monadic ();
+
+ inst.is_neon = 1;
+ inst.instruction |= 0xf0000000;
+}
+
+static void
do_neon_movl (void)
{
struct neon_type_el et = neon_check_type (2, NS_QD,
@@ -16343,6 +16492,10 @@ do_neon_ldr_str (void)
do_vfp_nsyn_opcode ("flds");
else
do_vfp_nsyn_opcode ("fsts");
+
+ /* ARMv8.2 vldr.16/vstr.16 instruction. */
+ if (inst.vectype.el[0].size == 16)
+ do_scalar_fp16_v82_encode ();
}
else
{
@@ -16700,8 +16853,14 @@ do_vfp_nsyn_fpv8 (enum neon_shape rs)
NEON_ENCODE (FPV8, inst);
- if (rs == NS_FFF)
- do_vfp_sp_dyadic ();
+ if (rs == NS_FFF || rs == NS_HHH)
+ {
+ do_vfp_sp_dyadic ();
+
+ /* ARMv8.2 fp16 instruction. */
+ if (rs == NS_HHH)
+ do_scalar_fp16_v82_encode ();
+ }
else
do_vfp_dp_rd_rn_rm ();
@@ -16737,7 +16896,7 @@ do_vmaxnm (void)
static void
do_vrint_1 (enum neon_cvt_mode mode)
{
- enum neon_shape rs = neon_select_shape (NS_FF, NS_DD, NS_QQ, NS_NULL);
+ enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_QQ, NS_NULL);
struct neon_type_el et;
if (rs == NS_NULL)
@@ -16749,7 +16908,8 @@ do_vrint_1 (enum neon_cvt_mode mode)
constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
_(BAD_FPU));
- et = neon_check_type (2, rs, N_EQK | N_VFP, N_F32 | N_F64 | N_KEY | N_VFP);
+ et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY
+ | N_VFP);
if (et.type != NT_invtype)
{
/* VFP encodings. */
@@ -16758,7 +16918,7 @@ do_vrint_1 (enum neon_cvt_mode mode)
set_it_insn_type (OUTSIDE_IT_INSN);
NEON_ENCODE (FPV8, inst);
- if (rs == NS_FF)
+ if (rs == NS_FF || rs == NS_HH)
do_vfp_sp_monadic ();
else
do_vfp_dp_rd_rm ();
@@ -16777,6 +16937,10 @@ do_vrint_1 (enum neon_cvt_mode mode)
inst.instruction |= (rs == NS_DD) << 8;
do_vfp_cond_or_thumb ();
+
+ /* ARMv8.2 fp16 vrint instruction. */
+ if (rs == NS_HH)
+ do_scalar_fp16_v82_encode ();
}
else
{
@@ -19914,6 +20078,15 @@ static const struct asm_opcode insns[] =
NCE(vmov, 0, 1, (VMOV), neon_mov),
NCE(vmovq, 0, 1, (VMOV), neon_mov),
+#undef ARM_VARIANT
+#define ARM_VARIANT & arm_ext_fp16
+#undef THUMB_VARIANT
+#define THUMB_VARIANT & arm_ext_fp16
+ /* New instructions added from v8.2, allowing the extraction and insertion of
+ the upper 16 bits of a 32-bit vector register. */
+ NCE (vmovx, eb00a40, 2, (RVS, RVS), neon_movhf),
+ NCE (vins, eb00ac0, 2, (RVS, RVS), neon_movhf),
+
#undef THUMB_VARIANT
#define THUMB_VARIANT & fpu_neon_ext_v1
#undef ARM_VARIANT
@@ -23027,7 +23200,20 @@ md_apply_fix (fixS * fixP,
case BFD_RELOC_ARM_CP_OFF_IMM:
case BFD_RELOC_ARM_T32_CP_OFF_IMM:
- if (value < -1023 || value > 1023 || (value & 3))
+ if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM)
+ newval = md_chars_to_number (buf, INSN_SIZE);
+ else
+ newval = get_thumb32_insn (buf);
+ if ((newval & 0x0f200f00) == 0x0d000900)
+ {
+ /* This is a fp16 vstr/vldr. The immediate offset in the mnemonic
+ has permitted values that are multiples of 2, in the range 0
+ to 510. */
+ if (value < -510 || value > 510 || (value & 1))
+ as_bad_where (fixP->fx_file, fixP->fx_line,
+ _("co-processor offset out of range"));
+ }
+ else if (value < -1023 || value > 1023 || (value & 3))
as_bad_where (fixP->fx_file, fixP->fx_line,
_("co-processor offset out of range"));
cp_off_common:
@@ -23044,6 +23230,17 @@ md_apply_fix (fixS * fixP,
else
{
newval &= 0xff7fff00;
+ if ((newval & 0x0f200f00) == 0x0d000900)
+ {
+ /* This is a fp16 vstr/vldr.
+
+ It requires the immediate offset in the instruction is shifted
+ left by 1 to be a half-word offset.
+
+ Here, left shift by 1 first, and later right shift by 2
+ should get the right offset. */
+ value <<= 1;
+ }
newval |= (value >> 2) | (sign ? INDEX_UP : 0);
}
if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
diff --git a/gas/testsuite/gas/arm/armv8-2-fp16-scalar-bad.d b/gas/testsuite/gas/arm/armv8-2-fp16-scalar-bad.d
new file mode 100644
index 0000000000000000000000000000000000000000..7a48bcdb9bc4bdacf26e700342f967eba30008ac
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-2-fp16-scalar-bad.d
@@ -0,0 +1,4 @@
+#name: Invalid armv8.2-a scalar fp16
+#source: armv8-2-fp16-scalar-bad.s
+#as: -march=armv8.2-a+fp16 -mfpu=fp-armv8
+#error-output: armv8-2-fp16-scalar-bad.l
diff --git a/gas/testsuite/gas/arm/armv8-2-fp16-scalar-bad.l b/gas/testsuite/gas/arm/armv8-2-fp16-scalar-bad.l
new file mode 100644
index 0000000000000000000000000000000000000000..397028e16efd7c33c78f8d8c5e49bb54f6d5c360
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-2-fp16-scalar-bad.l
@@ -0,0 +1,206 @@
+.*: Assembler messages:
+.*:73: Error: immediate value out of range -- `vcvt.s32.f16 s11,s11,#33'
+.*:74: Error: immediate value out of range, expected range \[1, 32\] -- `vcvt.u32.f16 s11,s11,#0'
+.*:75: Error: immediate value out of range -- `vcvt.f16.s32 s12,s12,#34'
+.*:76: Error: immediate value out of range -- `vcvt.f16.u32 s12,s12,#-1'
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 instruction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:68: Error: co-processor offset out of range
+.*:69: Error: co-processor offset out of range
+.*:70: Error: co-processor offset out of range
diff --git a/gas/testsuite/gas/arm/armv8-2-fp16-scalar-bad.s b/gas/testsuite/gas/arm/armv8-2-fp16-scalar-bad.s
new file mode 100644
index 0000000000000000000000000000000000000000..08cd52bf97fe5691347ec911d667d5c5ecb943bc
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-2-fp16-scalar-bad.s
@@ -0,0 +1,86 @@
+ .macro f16_sss_arithmetic reg0, reg1, reg2
+ .irp op, vdiv, vfma, vfms, vfnma, vfnms, vmla, vmls, vmul, vnmla, vnmls, vnmul, vsub
+ .irp cond, eq.f16, ne.f16, ge.f16, lt.f16, gt.f16, le.f16
+ \op\cond s\reg0, s\reg1, s\reg2
+ .endr
+ .endr
+ .endm
+
+ .macro f16_ss_arithmetic reg0, reg1
+ .irp op, vabs, vadd, vsqrt, vneg
+ .irp cond, eq.f16, ne.f16, ge.f16, lt.f16, gt.f16, le.f16
+ \op\cond s\reg0, s\reg1
+ .endr
+ .endr
+ .endm
+
+ .macro f16_si_cmp reg0, imm
+ .irp op, vcmp, vcmpe
+ .irp cond, eq.f16, ne.f16, ge.f16, lt.f16, gt.f16, le.f16
+ \op\cond s\reg0, \imm
+ .endr
+ .endr
+ .endm
+
+ .macro f16_ss_cmp reg0, reg1
+ .irp op, vcmp, vcmpe
+ .irp cond, eq.f16, ne.f16, ge.f16, lt.f16, gt.f16, le.f16
+ \op\cond s\reg0, s\reg1
+ .endr
+ .endr
+ .endm
+
+ .macro f16_ss_cvt reg0, reg1
+ .irp cond, eq, ne, ge, lt, gt, le
+ .irp mode, .s32.f16, .u32.f16, .f16.s32, .f16.u32
+ vcvt\cond\mode s\reg0, s\reg1
+ .endr
+ .endr
+ .endm
+
+ .macro f16_ssi_cvt_imm32 reg0, reg1, imm
+ .irp cond, eq, ne, ge, lt, gt, le
+ .irp mode, .s32.f16, .u32.f16, .f16.s32, .f16.u32
+ vcvt\cond\mode s\reg0, s\reg1, \imm
+ .endr
+ .endr
+ .endm
+
+ .macro f16_ss_cvt_r reg0, reg1
+ .irp cond, eq, ne, ge, lt, gt, le
+ .irp mode, .s32.f16, .u32.f16
+ vcvtr\cond\mode s\reg0, s\reg1
+ .endr
+ .endr
+ .endm
+
+ .macro f16_ss_vrint reg0, reg1
+ .irp op, vrintr, vrintx, vrintz
+ .irp cond, eq.f16, ne.f16, ge.f16, lt.f16, gt.f16, le.f16
+ \op\cond s\reg0, s\reg1
+ .endr
+ .endr
+ .endm
+
+ .text
+
+ @ invalied immediate range
+ vldr.16 s6, [pc, #-511]
+ vldr.16 s6, [pc, #111]
+ vldr.16 s3, [pc, #511]
+
+ @ invalid immediate range
+ vcvt.s32.f16 s11, s11, #33
+ vcvt.u32.f16 s11, s11, #0
+ vcvt.f16.s32 s12, s12, #34
+ vcvt.f16.u32 s12, s12, #-1
+
+ @ armv8.2 fp16 scalar instruction cannot be conditional
+ f16_sss_arithmetic 0, 1, 2
+ f16_ss_arithmetic 0, 1
+ f16_si_cmp 2, #0.0
+ f16_ss_cmp 0, 1
+ f16_ss_cvt 1, 8
+ f16_ssi_cvt_imm32 2, 2, #29
+ f16_ss_cvt_r 0, 10
+ f16_ss_vrint 3, 11
diff --git a/gas/testsuite/gas/arm/armv8-2-fp16-scalar-thumb.d b/gas/testsuite/gas/arm/armv8-2-fp16-scalar-thumb.d
new file mode 100644
index 0000000000000000000000000000000000000000..912a4474b7af99b6aae88d6343f104651d92b933
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-2-fp16-scalar-thumb.d
@@ -0,0 +1,75 @@
+#name: ARM v8.2 FP16 support on scalar (Thumb)
+#source: armv8-2-fp16-scalar.s
+#objdump: -d
+#as: -march=armv8.2-a+fp16 -mfpu=fp-armv8 -mthumb
+#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd
+
+.*: +file format .*arm.*
+Disassembly of section .text:
+
+00000000 <label-0xc>:
+ 0: ee00 1910 vmov.f16 s0, r1
+ 4: ee10 0990 vmov.f16 r0, s1
+ 8: eeb0 0900 vmov.f16 s0, #0 ; 0x40000000 2.0
+
+0000000c <label>:
+ c: 00000ffe .word 0x00000ffe
+ 10: ed5f 1904 vldr.16 s3, \[pc, #-8\] ; c <label>
+ 14: ed1f 3902 vldr.16 s6, \[pc, #-4\] ; 14 <label\+0x8>
+ 18: eddf 1902 vldr.16 s3, \[pc, #4\] ; 20 <label\+0x14>
+ 1c: edd0 0902 vldr.16 s1, \[r0, #4\]
+ 20: ed10 1902 vldr.16 s2, \[r0, #-4\]
+ 24: ed80 3902 vstr.16 s6, \[r0, #4\]
+ 28: ed40 5902 vstr.16 s11, \[r0, #-4\]
+ 2c: eec6 298c vdiv.f16 s5, s13, s24
+ 30: eee6 298c vfma.f16 s5, s13, s24
+ 34: eee6 29cc vfms.f16 s5, s13, s24
+ 38: eed6 29cc vfnma.f16 s5, s13, s24
+ 3c: eed6 298c vfnms.f16 s5, s13, s24
+ 40: fec6 298c vmaxnm.f16 s5, s13, s24
+ 44: fec6 29cc vminnm.f16 s5, s13, s24
+ 48: ee46 298c vmla.f16 s5, s13, s24
+ 4c: ee46 29cc vmls.f16 s5, s13, s24
+ 50: ee66 298c vmul.f16 s5, s13, s24
+ 54: ee56 29cc vnmla.f16 s5, s13, s24
+ 58: ee56 298c vnmls.f16 s5, s13, s24
+ 5c: ee66 29cc vnmul.f16 s5, s13, s24
+ 60: ee76 29cc vsub.f16 s5, s13, s24
+ 64: eef0 29c6 vabs.f16 s5, s12
+ 68: ee72 2986 vadd.f16 s5, s5, s12
+ 6c: eef1 29c6 vsqrt.f16 s5, s12
+ 70: eef1 2946 vneg.f16 s5, s12
+ 74: eeb5 1940 vcmp.f16 s2, #0.0
+ 78: eeb5 19c0 vcmpe.f16 s2, #0.0
+ 7c: eef4 2966 vcmp.f16 s5, s13
+ 80: eef4 29e6 vcmpe.f16 s5, s13
+ 84: fe46 29ab vseleq.f16 s5, s13, s23
+ 88: fe66 29ab vselge.f16 s5, s13, s23
+ 8c: fe56 29ab vselvs.f16 s5, s13, s23
+ 90: eefd 19c4 vcvt.s32.f16 s3, s8
+ 94: eefc 19c4 vcvt.u32.f16 s3, s8
+ 98: eef8 19c4 vcvt.f16.s32 s3, s8
+ 9c: eef8 1944 vcvt.f16.u32 s3, s8
+ a0: eefa 39e1 vcvt.f16.s32 s7, s7, #29
+ a4: eefb 39e1 vcvt.f16.u32 s7, s7, #29
+ a8: eefe 39e1 vcvt.s32.f16 s7, s7, #29
+ ac: eeff 39e1 vcvt.u32.f16 s7, s7, #29
+ b0: fefc 29c5 vcvta.s32.f16 s5, s10
+ b4: fefc 2945 vcvta.u32.f16 s5, s10
+ b8: feff 29c5 vcvtm.s32.f16 s5, s10
+ bc: feff 2945 vcvtm.u32.f16 s5, s10
+ c0: fefd 29c5 vcvtn.s32.f16 s5, s10
+ c4: fefd 2945 vcvtn.u32.f16 s5, s10
+ c8: fefe 29c5 vcvtp.s32.f16 s5, s10
+ cc: fefe 2945 vcvtp.u32.f16 s5, s10
+ d0: eefc 2945 vcvtr.u32.f16 s5, s10
+ d4: eefd 2945 vcvtr.s32.f16 s5, s10
+ d8: fef8 1965 vrinta.f16 s3, s11
+ dc: fefb 1965 vrintm.f16 s3, s11
+ e0: fef9 1965 vrintn.f16 s3, s11
+ e4: fefa 1965 vrintp.f16 s3, s11
+ e8: eef6 1965 vrintr.f16 s3, s11
+ ec: eef7 1965 vrintx.f16 s3, s11
+ f0: eef6 19e5 vrintz.f16 s3, s11
+ f4: fef0 2ae4 vins.f16 s5, s9
+ f8: fef0 2a64 vmovx.f16 s5, s9
diff --git a/gas/testsuite/gas/arm/armv8-2-fp16-scalar.d b/gas/testsuite/gas/arm/armv8-2-fp16-scalar.d
new file mode 100644
index 0000000000000000000000000000000000000000..023bf67be63cfc48e19f31c5b045fe358aa8cf67
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-2-fp16-scalar.d
@@ -0,0 +1,75 @@
+#name: ARM v8.2 FP16 support on scalar
+#source: armv8-2-fp16-scalar.s
+#objdump: -d
+#as: -march=armv8.2-a+fp16 -mfpu=fp-armv8
+#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd
+
+.*: +file format .*arm.*
+Disassembly of section .text:
+
+00000000 <label-0xc>:
+ 0: ee001910 vmov.f16 s0, r1
+ 4: ee100990 vmov.f16 r0, s1
+ 8: eeb00900 vmov.f16 s0, #0 ; 0x40000000 2.0
+
+0000000c <label>:
+ c: 00000ffe .word 0x00000ffe
+ 10: ed5f1906 vldr.16 s3, \[pc, #-12\] ; c <label>
+ 14: ed1f3902 vldr.16 s6, \[pc, #-4\] ; 18 <label\+0xc>
+ 18: eddf1902 vldr.16 s3, \[pc, #4\] ; 24 <label\+0x18>
+ 1c: edd00902 vldr.16 s1, \[r0, #4\]
+ 20: ed101902 vldr.16 s2, \[r0, #-4\]
+ 24: ed803902 vstr.16 s6, \[r0, #4\]
+ 28: ed405902 vstr.16 s11, \[r0, #-4\]
+ 2c: eec6298c vdiv.f16 s5, s13, s24
+ 30: eee6298c vfma.f16 s5, s13, s24
+ 34: eee629cc vfms.f16 s5, s13, s24
+ 38: eed629cc vfnma.f16 s5, s13, s24
+ 3c: eed6298c vfnms.f16 s5, s13, s24
+ 40: fec6298c vmaxnm.f16 s5, s13, s24
+ 44: fec629cc vminnm.f16 s5, s13, s24
+ 48: ee46298c vmla.f16 s5, s13, s24
+ 4c: ee4629cc vmls.f16 s5, s13, s24
+ 50: ee66298c vmul.f16 s5, s13, s24
+ 54: ee5629cc vnmla.f16 s5, s13, s24
+ 58: ee56298c vnmls.f16 s5, s13, s24
+ 5c: ee6629cc vnmul.f16 s5, s13, s24
+ 60: ee7629cc vsub.f16 s5, s13, s24
+ 64: eef029c6 vabs.f16 s5, s12
+ 68: ee722986 vadd.f16 s5, s5, s12
+ 6c: eef129c6 vsqrt.f16 s5, s12
+ 70: eef12946 vneg.f16 s5, s12
+ 74: eeb51940 vcmp.f16 s2, #0.0
+ 78: eeb519c0 vcmpe.f16 s2, #0.0
+ 7c: eef42966 vcmp.f16 s5, s13
+ 80: eef429e6 vcmpe.f16 s5, s13
+ 84: fe4629ab vseleq.f16 s5, s13, s23
+ 88: fe6629ab vselge.f16 s5, s13, s23
+ 8c: fe5629ab vselvs.f16 s5, s13, s23
+ 90: eefd19c4 vcvt.s32.f16 s3, s8
+ 94: eefc19c4 vcvt.u32.f16 s3, s8
+ 98: eef819c4 vcvt.f16.s32 s3, s8
+ 9c: eef81944 vcvt.f16.u32 s3, s8
+ a0: eefa39e1 vcvt.f16.s32 s7, s7, #29
+ a4: eefb39e1 vcvt.f16.u32 s7, s7, #29
+ a8: eefe39e1 vcvt.s32.f16 s7, s7, #29
+ ac: eeff39e1 vcvt.u32.f16 s7, s7, #29
+ b0: fefc29c5 vcvta.s32.f16 s5, s10
+ b4: fefc2945 vcvta.u32.f16 s5, s10
+ b8: feff29c5 vcvtm.s32.f16 s5, s10
+ bc: feff2945 vcvtm.u32.f16 s5, s10
+ c0: fefd29c5 vcvtn.s32.f16 s5, s10
+ c4: fefd2945 vcvtn.u32.f16 s5, s10
+ c8: fefe29c5 vcvtp.s32.f16 s5, s10
+ cc: fefe2945 vcvtp.u32.f16 s5, s10
+ d0: eefc2945 vcvtr.u32.f16 s5, s10
+ d4: eefd2945 vcvtr.s32.f16 s5, s10
+ d8: fef81965 vrinta.f16 s3, s11
+ dc: fefb1965 vrintm.f16 s3, s11
+ e0: fef91965 vrintn.f16 s3, s11
+ e4: fefa1965 vrintp.f16 s3, s11
+ e8: eef61965 vrintr.f16 s3, s11
+ ec: eef71965 vrintx.f16 s3, s11
+ f0: eef619e5 vrintz.f16 s3, s11
+ f4: fef02ae4 vins.f16 s5, s9
+ f8: fef02a64 vmovx.f16 s5, s9
diff --git a/gas/testsuite/gas/arm/armv8-2-fp16-scalar.s b/gas/testsuite/gas/arm/armv8-2-fp16-scalar.s
new file mode 100644
index 0000000000000000000000000000000000000000..fbb788607fb29ffc907ccfe44d95072f851cffe1
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-2-fp16-scalar.s
@@ -0,0 +1,86 @@
+ .macro f16_sss_arithmetic reg0, reg1, reg2
+ .irp op, vdiv.f16, vfma.f16, vfms.f16, vfnma.f16, vfnms.f16, vmaxnm.f16, vminnm.f16, vmla.f16, vmls.f16, vmul.f16, vnmla.f16, vnmls.f16, vnmul.f16, vsub.f16
+ \op s\reg0, s\reg1, s\reg2
+ .endr
+ .endm
+
+ .macro f16_ss_arithmetic reg0, reg1
+ .irp op, vabs.f16, vadd.f16, vsqrt.f16, vneg.f16
+ \op s\reg0, s\reg1
+ .endr
+ .endm
+
+ .macro f16_si_cmp reg0, imm
+ .irp op, vcmp.f16, vcmpe.f16
+ \op s\reg0, \imm
+ .endr
+ .endm
+
+ .macro f16_ss_cmp reg0, reg1
+ .irp op, vcmp.f16, vcmpe.f16
+ \op s\reg0, s\reg1
+ .endr
+ .endm
+
+ .macro f16_sss_vsel reg0, reg1, reg2
+ .irp op, vseleq.f16 vselge.f16, vselvs.f16
+ \op s\reg0, s\reg1, s\reg2
+ .endr
+ .endm
+
+ .macro f16_ss_cvt reg0, reg1
+ .irp op, vcvt.s32.f16, vcvt.u32.f16, vcvt.f16.s32, vcvt.f16.u32
+ \op s\reg0, s\reg1
+ .endr
+ .endm
+
+ .macro f16_ssi_cvt_imm32 reg0, reg1, imm
+ .irp op, vcvt.f16.s32, vcvt.f16.u32, vcvt.s32.f16, vcvt.u32.f16
+ \op s\reg0, s\reg1, \imm
+ .endr
+ .endm
+
+ .macro f16_ss_cvt_amnpr reg0, reg1
+ .irp op, vcvta.s32.f16, vcvta.u32.f16, vcvtm.s32.f16, vcvtm.u32.f16, vcvtn.s32.f16, vcvtn.u32.f16, vcvtp.s32.f16, vcvtp.u32.f16, vcvtr.u32.f16, vcvtr.s32.f16
+ \op s\reg0, s\reg1
+ .endr
+ .endm
+
+ .macro f16_ss_vrint reg0, reg1
+ .irp op, vrinta.f16, vrintm.f16, vrintn.f16, vrintp.f16, vrintr.f16, vrintx.f16, vrintz.f16
+ \op s\reg0, s\reg1
+ .endr
+ .endm
+
+ .macro f16_ss_mov reg0, reg1
+ .irp op, vins.f16, vmovx.f16
+ \op s\reg0, s\reg1
+ .endr
+ .endm
+
+ .text
+
+ vmov.f16 s0, r1
+ vmov.f16 r0, s1
+ vmov.f16 s0, #2.0
+ label:
+ .word 0xffe
+ vldr.16 s3, label
+
+ vldr.16 s6, [pc, #-4]
+ vldr.16 s3, [pc, #4]
+ vldr.16 s1, [r0, #4]
+ vldr.16 s2, [r0, #-4]
+ vstr.16 s6 , [r0, #4]
+ vstr.16 s11 , [r0, #-4]
+
+ f16_sss_arithmetic 5, 13, 24
+ f16_ss_arithmetic 5, 12
+ f16_si_cmp 2, #0.0
+ f16_ss_cmp 5, 13
+ f16_sss_vsel 5, 13, 23
+ f16_ss_cvt 3, 8
+ f16_ssi_cvt_imm32 7, 7, #29
+ f16_ss_cvt_amnpr 5, 10
+ f16_ss_vrint 3, 11
+ f16_ss_mov 5, 9