This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[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: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Cc: Nicholas Clifton <nickc at redhat dot com>, 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: Fri, 19 Feb 2016 11:36:22 +0000
- Subject: [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>
Hi all,
This patch add the armv8.2 fp16 scalar instructions into gas based on
previous SE_H support.
The new armv8.2 fp16 scalar instructions are identified by the neon shape.
for example:
vadd.f16 s0, s1, s2: NS_HHH
vabs.f16 s0, s1: NS_HH
vmov.f16 s0, r1: NS_HR
vmov.f16 r0, s1: NS_RH
vcvt.f16.s32 s2, s2, #29: NS_HFI
vcvt.u16.s32 s2, s2, #8: NS_HFI
vshl.u16 q3,q4,q5 NS_QQQ ---> not changed
If the SE_H is part of the shape, do_scalar_fp16_v82_encode function
will be called
to change to coproc field to 9 to refection the encoding difference. The
encoding of
the other parts is shared.
To be specific, the following instructions are added.
New VMOVX and VINS instructions are added to allow the extraction and
insertion of the
upper 16 bits of a 32-bit vector register.
vins.f16
vmovx.f16
vabs.f16
vadd.f16
vcmp.f16
vcmpe.f16
VCVT (between floating-point and fixed-point)
vcvt.f16.s32
vcvt.f16.u32
vcvt.s32.f16
vcvt.u32.f16
VCVT (between floating-point and integer, both directions)
vcvt.s32.f16
vcvt.u32.f16
vcvt.f16.u32
vcvt.f16.s32
vcvta.u32.f16
vcvta.s32.f16
vcvtm.u32.f16
vcvtm.s32.f16
vcvtn.u32.f16
vcvtn.s32.f16
vcvtp.u32.f16
vcvtp.s32.f16
vcvtr.u32.f16
vcvtr.s32.f16
vdiv.f16
vfma.f16
vfms.f16
vfnma.f16
vfnms.f16
vmaxnm.f16
vminnm.f16
fmla.f16
vmls.f16
VMOV(between general-purpose register and half-precision register,
immediate)
vmov.f16
vmov.f16
vmul.f16
vneg.f16
vnmla.f16
vnmls.f16
vnmul.f16
vrinta.f16
vrintm.f16
vrintn.f16
vrintp.f16
vrintr.f16
vrintx.f16
vrintz.f16
vseleq.f16
vselge.f16
vselgt.f16
vselvs.f16
vsqrt.f16
vsub.f16
load/store literal or address from register with optional offset
vldr.16
vstr.16
Binutils checked without any issues.
gas/ChangeLog:
2016-02-19 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 19/02/16 11:30, Renlin Li wrote:
Hi all,
This patch makes generic change to add a new neon shape SE_H to
represent VFP single
precision register operand whose type specifier is .f16, .16, u16, s16.
This will facilitate further patch to add ARMv8.2 fp16 instruction
support into GAS.
for example, after the change, the new instruction share for the
following instruction is changed:
vcvtt.f16.f64 s0, d0: NS_HD, instead of NS_FD
vcvtt.f64.f16 d0, s0: NS_DH, instead of NS_DF
vcvtb s2.f16, s5.f32: NS_HF, instead of NS_FF
vcvtb.f16.f32 s2, s5: NS_HF, instead of NS_FF
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..2751102031531591eca659a9837b99dd33905707
--- /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 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:79: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:80: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:81: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:82: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:83: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:84: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:85: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction cannot be conditional, the behaviour is UNPREDICTABLE
+.*:86: Warning: ARMv8.2 scalar fp16 insturction 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..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
+
+.*: +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..f729cfba7b020db06c5c0bc366a256e5c1b5df89
--- /dev/null
+++ b/gas/testsuite/gas/arm/armv8-2-fp16-scalar.d
@@ -0,0 +1,74 @@
+#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
+
+.*: +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