This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[GAS][ARM][3/3]Add armv8.2 fp16 scalar instruction support. [Based on SE_H instruction shape for .f16, u16, s16, .16 type specifier]


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]