Add generic and ARM specific support for half-precision IEEE 754 floating point numbe...
authorBarnaby Wilks <barnaby.wilks@arm.com>
Mon, 12 Aug 2019 10:08:36 +0000 (11:08 +0100)
committerNick Clifton <nickc@redhat.com>
Mon, 12 Aug 2019 10:08:36 +0000 (11:08 +0100)
Half precision floating point numbers will be encoded using the IEEE 754
half precision floating point format - 16 bits in total, 1 for sign, 5
for exponent and 10 bits of  mantissa.

This patch implements the float16 directive for both the IEEE 754 format
and the Arm alternative format for the Arm backend.

The syntax of the directive is:

  .float16 <0-n decimal numbers>
e.g.
  .float16 12.0
  .float16 0.23, 433.1, 0.06

The Arm alternative format is almost identical to the IEEE 754 format,
except that it doesn't encode for NaNs or Infinity (instead an exponent
of 0x1F represents a normalized number in the range 65536 to 131008).

The alternative format is documented in the reference manual:

  https://static.docs.arm.com/ddi0487/db/DDI0487D_b_armv8_arm.pdf?_ga=2.72318806.49764181.1561632697-999473562.1560847439

Which format is used is controlled by the .float16_format <format>
directive, where if <format> = ieee, then use the IEEE 754
half-precision format else if <format> = alternative, then use the
Arm alternative format

Or the format can be set on the command line via the -mfp16-format
option that has a similar syntax.  -mfp16-format=<ieee|alternative>.
This also fixes the format and it cannot be changed by any directives.

Once the format has been set (either by the command line option or a directive) it cannot be changed,
and any attempts to change it (i.e. with the float16_format directive) will result in a warning and the
line being ignored.

For ELF targets the appropriate EABI attribute will be written out at the end of assembling
if the format has been explicitly specified. If no format has been explicitly specified then no
EABI attributes will be written.

If the format is not explicitly specified then any float16 directives are encoding using the IEEE 754-2008
format by default until the format is fixed or changed with the float16_format directive.

gas * config/tc-arm.c (enum fp_16bit_format): Add enum to represent the 2 float16 encodings.
(md_atof): Set precision for float16 type.
(arm_is_largest_exponent_ok): Check for whether to encode with the IEEE or alternative
format.
(set_fp16_format): Parse a float16_format directive.
(arm_parse_fp16_opt): Parse the fp16-format command line option.
(aeabi_set_public_attributes): For ELF encode the FP16 format EABI attribute.
* config/tc-arm.h (TC_LARGEST_EXPONENT_IS_NORMAL): Macro that expands to
arm_is_largest_exponent_ok.
(arm_is_largest_exponent_ok): Add prototype for arm_is_largest_exponent_ok function.
* doc/c-arm.texi: Add documentation for .float16, .float16_format and -mfp16-format=
* testsuite/gas/arm/float16-bad.d: New test.
* testsuite/gas/arm/float16-bad.l: New test.
* testsuite/gas/arm/float16-bad.s: New test.
* testsuite/gas/arm/float16-be.d: New test.
* testsuite/gas/arm/float16-format-bad.d: New test.
* testsuite/gas/arm/float16-format-bad.l: New test.
* testsuite/gas/arm/float16-format-bad.s: New test.
* testsuite/gas/arm/float16-format-opt-bad.d: New test.
* testsuite/gas/arm/float16-format-opt-bad.l: New test.
* testsuite/gas/arm/float16-le.d: New test.
* testsuite/gas/arm/float16.s: New test.
* testsuite/gas/arm/float16-eabi-alternative-format.d: New test.
* testsuite/gas/arm/float16-eabi-ieee-format.d: New test.
* testsuite/gas/arm/float16-eabi-no-format.d: New test.
* testsuite/gas/arm/float16-eabi.s: New test.

* config/atof-ieee.c (H_PRECISION): Macro for precision of float16
type.
(atof_ieee): Set precision and exponent bits for encoding float16
types.
(gen_to_words): NaN and Infinity encoding for float16.
(ieee_md_atof): Set precision for encoding float16 type.

20 files changed:
gas/ChangeLog
gas/config/atof-ieee.c
gas/config/tc-arm.c
gas/config/tc-arm.h
gas/doc/c-arm.texi
gas/testsuite/gas/arm/float16-bad.d [new file with mode: 0644]
gas/testsuite/gas/arm/float16-bad.l [new file with mode: 0644]
gas/testsuite/gas/arm/float16-bad.s [new file with mode: 0644]
gas/testsuite/gas/arm/float16-be.d [new file with mode: 0644]
gas/testsuite/gas/arm/float16-eabi-alternative-format.d [new file with mode: 0644]
gas/testsuite/gas/arm/float16-eabi-ieee-format.d [new file with mode: 0644]
gas/testsuite/gas/arm/float16-eabi-no-format.d [new file with mode: 0644]
gas/testsuite/gas/arm/float16-eabi.s [new file with mode: 0644]
gas/testsuite/gas/arm/float16-format-bad.d [new file with mode: 0644]
gas/testsuite/gas/arm/float16-format-bad.l [new file with mode: 0644]
gas/testsuite/gas/arm/float16-format-bad.s [new file with mode: 0644]
gas/testsuite/gas/arm/float16-format-opt-bad.d [new file with mode: 0644]
gas/testsuite/gas/arm/float16-format-opt-bad.l [new file with mode: 0644]
gas/testsuite/gas/arm/float16-le.d [new file with mode: 0644]
gas/testsuite/gas/arm/float16.s [new file with mode: 0644]

index 68c40022323edfb6b3d656c1b52ac64de6b26df7..d7e0840ec8a153aba6ff6a4081ca0667569d933a 100644 (file)
@@ -1,3 +1,41 @@
+2019-08-12  Barnaby Wilks  <barnaby.wilks@arm.com>
+
+       * config/tc-arm.c (enum fp_16bit_format): Add enum to represent the 2 float16 encodings.
+       (md_atof): Set precision for float16 type.
+       (arm_is_largest_exponent_ok): Check for whether to encode with the IEEE or alternative
+       format.
+       (set_fp16_format): Parse a float16_format directive.
+       (arm_parse_fp16_opt): Parse the fp16-format command line option.
+       (aeabi_set_public_attributes): For ELF encode the FP16 format EABI attribute.
+       * config/tc-arm.h (TC_LARGEST_EXPONENT_IS_NORMAL): Macro that expands to
+       arm_is_largest_exponent_ok.
+       (arm_is_largest_exponent_ok): Add prototype for arm_is_largest_exponent_ok function.
+       * doc/c-arm.texi: Add documentation for .float16, .float16_format and -mfp16-format=
+       * testsuite/gas/arm/float16-bad.d: New test.
+       * testsuite/gas/arm/float16-bad.l: New test.
+       * testsuite/gas/arm/float16-bad.s: New test.
+       * testsuite/gas/arm/float16-be.d: New test.
+       * testsuite/gas/arm/float16-format-bad.d: New test.
+       * testsuite/gas/arm/float16-format-bad.l: New test.
+       * testsuite/gas/arm/float16-format-bad.s: New test.
+       * testsuite/gas/arm/float16-format-opt-bad.d: New test.
+       * testsuite/gas/arm/float16-format-opt-bad.l: New test.
+       * testsuite/gas/arm/float16-le.d: New test.
+       * testsuite/gas/arm/float16.s: New test.
+       * testsuite/gas/arm/float16-eabi-alternative-format.d: New test.
+       * testsuite/gas/arm/float16-eabi-ieee-format.d: New test.
+       * testsuite/gas/arm/float16-eabi-no-format.d: New test.
+       * testsuite/gas/arm/float16-eabi.s: New test.
+
+2019-08-12  Barnaby Wilks  <barnaby.wilks@arm.com>
+
+       * config/atof-ieee.c (H_PRECISION): Macro for precision of float16
+       type.
+       (atof_ieee): Set precision and exponent bits for encoding float16
+       types.
+       (gen_to_words): NaN and Infinity encoding for float16.
+       (ieee_md_atof): Set precision for encoding float16 type.
+
 2019-08-12  Alan Modra  <amodra@gmail.com>
 
        PR 24851
index 9bb9e55d26658a8d3b34d424a17062fb2074618b..944c8a46ff486ddc4cedc7fe4679b2e1d862a5f5 100644 (file)
@@ -26,6 +26,7 @@ extern FLONUM_TYPE generic_floating_point_number;
 /* Precision in LittleNums.  */
 /* Don't count the gap in the m68k extended precision format.  */
 #define MAX_PRECISION  5
+#define H_PRECISION    1
 #define F_PRECISION    2
 #define D_PRECISION    4
 #define X_PRECISION    5
@@ -190,6 +191,12 @@ atof_ieee (char *str,                      /* Text to convert to binary.  */
 
   switch (what_kind)
     {
+    case 'h':
+    case 'H':
+      precision = H_PRECISION;
+      exponent_bits = 5;
+      break;
+
     case 'f':
     case 'F':
     case 's':
@@ -283,8 +290,13 @@ gen_to_words (LITTLENUM_TYPE *words, int precision, long exponent_bits)
   if (generic_floating_point_number.sign == 0)
     {
       if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
-       as_warn (_("NaNs are not supported by this target\n"));
-      if (precision == F_PRECISION)
+       as_warn (_("NaNs are not supported by this target"));
+
+      if (precision == H_PRECISION)
+       {
+         words[0] = 0x7fff;
+       }
+      else if (precision == F_PRECISION)
        {
          words[0] = 0x7fff;
          words[1] = 0xffff;
@@ -322,10 +334,14 @@ gen_to_words (LITTLENUM_TYPE *words, int precision, long exponent_bits)
   else if (generic_floating_point_number.sign == 'P')
     {
       if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
-       as_warn (_("Infinities are not supported by this target\n"));
+       as_warn (_("Infinities are not supported by this target"));
 
       /* +INF:  Do the right thing.  */
-      if (precision == F_PRECISION)
+      if (precision == H_PRECISION)
+       {
+         words[0] = 0x7c00;
+       }
+      else if (precision == F_PRECISION)
        {
          words[0] = 0x7f80;
          words[1] = 0;
@@ -363,10 +379,14 @@ gen_to_words (LITTLENUM_TYPE *words, int precision, long exponent_bits)
   else if (generic_floating_point_number.sign == 'N')
     {
       if (TC_LARGEST_EXPONENT_IS_NORMAL (precision))
-       as_warn (_("Infinities are not supported by this target\n"));
+       as_warn (_("Infinities are not supported by this target"));
 
       /* Negative INF.  */
-      if (precision == F_PRECISION)
+      if (precision == H_PRECISION)
+       {
+         words[0] = 0xfc00;
+       }
+      else if (precision == F_PRECISION)
        {
          words[0] = 0xff80;
          words[1] = 0x0;
@@ -721,6 +741,11 @@ ieee_md_atof (int type,
     {
       switch (type)
        {
+       case 'H':
+       case 'h':
+         prec = H_PRECISION;
+         break;
+
        case 'f':
        case 'F':
        case 's':
index f7bebc1b5a40ac9b9702e8963240b45d5c91d6a1..714121b0c2b4705904ecf3700beffc9b6d6622db 100644 (file)
@@ -1037,7 +1037,7 @@ const char EXP_CHARS[] = "eE";
 /* As in 0f12.456  */
 /* or   0d1.2345e12  */
 
-const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
+const char FLT_CHARS[] = "rRsSfFdDxXeEpPHh";
 
 /* Prefix characters that indicate the start of an immediate
    value.  */
@@ -1047,6 +1047,16 @@ const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
 
 #define skip_whitespace(str)  do { if (*(str) == ' ') ++(str); } while (0)
 
+enum fp_16bit_format
+{
+  ARM_FP16_FORMAT_IEEE         = 0x1,
+  ARM_FP16_FORMAT_ALTERNATIVE  = 0x2,
+  ARM_FP16_FORMAT_DEFAULT      = 0x3
+};
+
+static enum fp_16bit_format fp16_format = ARM_FP16_FORMAT_DEFAULT;
+
+
 static inline int
 skip_past_char (char ** str, char c)
 {
@@ -1188,6 +1198,11 @@ md_atof (int type, char * litP, int * sizeP)
 
   switch (type)
     {
+    case 'H':
+    case 'h':
+      prec = 1;
+      break;
+
     case 'f':
     case 'F':
     case 's':
@@ -4925,6 +4940,55 @@ pe_directive_secrel (int dummy ATTRIBUTE_UNUSED)
 }
 #endif /* TE_PE */
 
+int
+arm_is_largest_exponent_ok (int precision)
+{
+  /* precision == 1 ensures that this will only return
+     true for 16 bit floats.  */
+  return (precision == 1) && (fp16_format == ARM_FP16_FORMAT_ALTERNATIVE);
+}
+
+static void
+set_fp16_format (int dummy ATTRIBUTE_UNUSED)
+{
+  char saved_char;
+  char* name;
+  enum fp_16bit_format new_format;
+
+  new_format = ARM_FP16_FORMAT_DEFAULT;
+
+  name = input_line_pointer;
+  while (*input_line_pointer && !ISSPACE (*input_line_pointer))
+    input_line_pointer++;
+
+  saved_char = *input_line_pointer;
+  *input_line_pointer = 0;
+
+  if (strcasecmp (name, "ieee") == 0)
+    new_format = ARM_FP16_FORMAT_IEEE;
+  else if (strcasecmp (name, "alternative") == 0)
+    new_format = ARM_FP16_FORMAT_ALTERNATIVE;
+  else
+    {
+      as_bad (_("unrecognised float16 format \"%s\""), name);
+      goto cleanup;
+    }
+
+  /* Only set fp16_format if it is still the default (aka not already
+     been set yet).  */
+  if (fp16_format == ARM_FP16_FORMAT_DEFAULT)
+    fp16_format = new_format;
+  else
+    {
+      if (new_format != fp16_format)
+       as_warn (_("float16 format cannot be set more than once, ignoring."));
+    }
+
+cleanup:
+  *input_line_pointer = saved_char;
+  ignore_rest_of_line ();
+}
+
 /* This table describes all the machine specific pseudo-ops the assembler
    has to support.  The fields are:
      pseudo-op name without dot
@@ -5002,9 +5066,12 @@ const pseudo_typeS md_pseudo_table[] =
   {"asmfunc",      s_ccs_asmfunc,    0},
   {"endasmfunc",   s_ccs_endasmfunc, 0},
 
+  {"float16", float_cons, 'h' },
+  {"float16_format", set_fp16_format, 0 },
+
   { 0, 0, 0 }
 };
-\f
+
 /* Parser functions used exclusively in instruction operands.  */
 
 /* Generic immediate-value read function for use in insn parsing.
@@ -31239,6 +31306,22 @@ arm_parse_extension (const char *str, const arm_feature_set *opt_set,
   return TRUE;
 }
 
+static bfd_boolean
+arm_parse_fp16_opt (const char *str)
+{
+  if (strcasecmp (str, "ieee") == 0)
+    fp16_format = ARM_FP16_FORMAT_IEEE;
+  else if (strcasecmp (str, "alternative") == 0)
+    fp16_format = ARM_FP16_FORMAT_ALTERNATIVE;
+  else
+    {
+      as_bad (_("unrecognised float16 format \"%s\""), str);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
 static bfd_boolean
 arm_parse_cpu (const char *str)
 {
@@ -31430,6 +31513,12 @@ struct arm_long_option_table arm_long_opts[] =
    arm_parse_it_mode, NULL},
   {"mccs", N_("\t\t\t  TI CodeComposer Studio syntax compatibility mode"),
    arm_ccs_mode, NULL},
+  {"mfp16-format=",
+   N_("[ieee|alternative]\n\
+                          set the encoding for half precision floating point "
+                         "numbers to IEEE\n\
+                          or Arm alternative format."),
+   arm_parse_fp16_opt, NULL },
   {NULL, NULL, 0, NULL}
 };
 
@@ -32011,6 +32100,9 @@ aeabi_set_public_attributes (void)
     virt_sec |= 2;
   if (virt_sec != 0)
     aeabi_set_attribute_int (Tag_Virtualization_use, virt_sec);
+
+  if (fp16_format != ARM_FP16_FORMAT_DEFAULT)
+    aeabi_set_attribute_int (Tag_ABI_FP_16bit_format, fp16_format);
 }
 
 /* Post relaxation hook.  Recompute ARM attributes now that relaxation is
index 39cc9680b96524c730c15fff1af22b180b9c70d1..8a73bebe6c5b5a027242d02f18b6d51273abcacb 100644 (file)
@@ -385,3 +385,7 @@ extern char arm_line_separator_chars[];
 
 #define TC_EQUAL_IN_INSN(c, s) arm_tc_equal_in_insn ((c), (s))
 extern bfd_boolean arm_tc_equal_in_insn (int, char *);
+
+#define TC_LARGEST_EXPONENT_IS_NORMAL(PRECISION) \
+       arm_is_largest_exponent_ok ((PRECISION))
+int arm_is_largest_exponent_ok (int precision);
index fa642177b2c3b7605feecce37d8b4d21fb1a1e0a..481eddf0cfe6a4483717fab9dd21b3c185340fc0 100644 (file)
@@ -493,6 +493,22 @@ The default is dependent on the processor selected.  For Architecture 5 or
 later, the default is to assemble for VFP instructions; for earlier
 architectures the default is to assemble for FPA instructions.
 
+@cindex @code{-mfp16-format=} command-line option
+@item -mfp16-format=@var{format}
+This option specifies the half-precision floating point format to use
+when assembling floating point numbers emitted by the @code{.float16}
+directive.
+The following format options are recognized:
+@code{ieee},
+@code{alternative}.
+If @code{ieee} is specified then the IEEE 754-2008 half-precision floating
+point format is used, if @code{alternative} is specified then the Arm
+alternative half-precision format is used. If this option is set on the
+command line then the format is fixed and cannot be changed with
+the @code{float16_format} directive. If this value is not set then
+the IEEE 754-2008 format is used until the format is explicitly set with
+the @code{float16_format} directive.
+
 @cindex @code{-mthumb} command-line option, ARM
 @item -mthumb
 This option specifies that the assembler should start assembling Thumb
@@ -934,6 +950,23 @@ or ABIs.
 
 @c FFFFFFFFFFFFFFFFFFFFFFFFFF
 
+@cindex @code{.float16} directive, ARM
+@item .float16 @var{value [,...,value_n]}
+Place the half precision floating point representation of one or more
+floating-point values into the current section. The exact format of the
+encoding is specified by @code{.float16_format}. If the format has not
+been explicitly set yet (either via the @code{.float16_format} directive or
+the command line option) then the IEEE 754-2008 format is used.
+
+@cindex @code{.float16_format} directive, ARM
+@item .float16_format @var{format}
+Set the format to use when encoding float16 values emitted by
+the @code{.float16} directive.
+Once the format has been set it cannot be changed.
+@code{format} should be one of the following: @code{ieee} (encode in
+the IEEE 754-2008 half precision format) or @code{alternative} (encode in
+the Arm alternative half precision format).
+
 @anchor{arm_fnend}
 @cindex @code{.fnend} directive, ARM
 @item .fnend
diff --git a/gas/testsuite/gas/arm/float16-bad.d b/gas/testsuite/gas/arm/float16-bad.d
new file mode 100644 (file)
index 0000000..8eac0af
--- /dev/null
@@ -0,0 +1,3 @@
+# name: Invalid float16 literals (IEEE 754 & Alternative)
+# source: float16-bad.s
+# error_output: float16-bad.l
diff --git a/gas/testsuite/gas/arm/float16-bad.l b/gas/testsuite/gas/arm/float16-bad.l
new file mode 100644 (file)
index 0000000..83978b7
--- /dev/null
@@ -0,0 +1,10 @@
+[^:]*: Assembler messages:
+[^:]*:2: Error: cannot create floating-point number
+[^:]*:3: Error: cannot create floating-point number
+[^:]*:4: Error: cannot create floating-point number
+[^:]*:7: Warning: NaNs are not supported by this target
+[^:]*:8: Warning: NaNs are not supported by this target
+[^:]*:9: Warning: NaNs are not supported by this target
+[^:]*:11: Warning: Infinities are not supported by this target
+[^:]*:12: Warning: Infinities are not supported by this target
+[^:]*:13: Warning: Infinities are not supported by this target
diff --git a/gas/testsuite/gas/arm/float16-bad.s b/gas/testsuite/gas/arm/float16-bad.s
new file mode 100644 (file)
index 0000000..6f09073
--- /dev/null
@@ -0,0 +1,13 @@
+.data
+       .float16 9999999999999.0
+       .float16 -999999999999.0
+       .float16 131008.0
+
+.float16_format alternative
+       .float16 NaN
+       .float16 -NaN
+       .float16 +NaN
+
+       .float16 Inf
+       .float16 -Inf
+       .float16 +Inf
diff --git a/gas/testsuite/gas/arm/float16-be.d b/gas/testsuite/gas/arm/float16-be.d
new file mode 100644 (file)
index 0000000..e31d9fb
--- /dev/null
@@ -0,0 +1,11 @@
+# name: Big endian float16 literals (IEEE 754 & Alternative)
+# source: float16.s
+# objdump: -s --section=.data
+# as: -mbig-endian
+
+.*: +file format .*arm.*
+
+Contents of section \.data:
+ 0000 4a002fdf 1c197bff 000103ff 04003c00.*
+ 0010 3c017fff 7c00fc00 00008000 bc00bbe7.*
+ 0020 fbff4200 4a00603e 38567fff ffff7204.*
diff --git a/gas/testsuite/gas/arm/float16-eabi-alternative-format.d b/gas/testsuite/gas/arm/float16-eabi-alternative-format.d
new file mode 100644 (file)
index 0000000..0729a5c
--- /dev/null
@@ -0,0 +1,10 @@
+# name: Tag_ABI_FP_16bit_format EABI attribute written for Arm alternative format.
+# readelf: -A
+# notarget: *-*pe *-*-wince
+# source: float16-eabi.s
+# as: -mfp16-format=alternative
+Attribute Section: aeabi
+File Attributes
+  Tag_ARM_ISA_use: Yes
+  Tag_THUMB_ISA_use: Thumb-1
+  Tag_ABI_FP_16bit_format: Alternative Format
diff --git a/gas/testsuite/gas/arm/float16-eabi-ieee-format.d b/gas/testsuite/gas/arm/float16-eabi-ieee-format.d
new file mode 100644 (file)
index 0000000..d02ed73
--- /dev/null
@@ -0,0 +1,10 @@
+# name: Tag_ABI_FP_16bit_format written for IEEE float16 format.
+# readelf: -A
+# notarget: *-*pe *-*wince
+# source: float16-eabi.s
+# as: -mfp16-format=ieee
+Attribute Section: aeabi
+File Attributes
+  Tag_ARM_ISA_use: Yes
+  Tag_THUMB_ISA_use: Thumb-1
+  Tag_ABI_FP_16bit_format: IEEE 754
diff --git a/gas/testsuite/gas/arm/float16-eabi-no-format.d b/gas/testsuite/gas/arm/float16-eabi-no-format.d
new file mode 100644 (file)
index 0000000..0d54f84
--- /dev/null
@@ -0,0 +1,8 @@
+# name: Tag_ABI_FP_16bit_format EABI attribute not written when format not specified
+# readelf: -A
+# notarget: *-*pe *-*-wince
+# source: float16-eabi.s
+Attribute Section: aeabi
+File Attributes
+  Tag_ARM_ISA_use: Yes
+  Tag_THUMB_ISA_use: Thumb-1
diff --git a/gas/testsuite/gas/arm/float16-eabi.s b/gas/testsuite/gas/arm/float16-eabi.s
new file mode 100644 (file)
index 0000000..9183637
--- /dev/null
@@ -0,0 +1,2 @@
+.float16 10.1
+.float16 0.5
diff --git a/gas/testsuite/gas/arm/float16-format-bad.d b/gas/testsuite/gas/arm/float16-format-bad.d
new file mode 100644 (file)
index 0000000..38da287
--- /dev/null
@@ -0,0 +1,3 @@
+# name: Invalid float16 formats
+# source: float16-format-bad.s
+# error_output: float16-format-bad.l
diff --git a/gas/testsuite/gas/arm/float16-format-bad.l b/gas/testsuite/gas/arm/float16-format-bad.l
new file mode 100644 (file)
index 0000000..1f2356f
--- /dev/null
@@ -0,0 +1,5 @@
+[^:]*: Assembler messages:
+[^:]*:2: Warning: float16 format cannot be set more than once, ignoring.
+[^:]*:3: Error: unrecognised float16 format "monkeys"
+[^:]*:4: Error: unrecognised float16 format "..."
+[^:]*:5: Error: unrecognised float16 format ""
diff --git a/gas/testsuite/gas/arm/float16-format-bad.s b/gas/testsuite/gas/arm/float16-format-bad.s
new file mode 100644 (file)
index 0000000..69e99e5
--- /dev/null
@@ -0,0 +1,5 @@
+.float16_format ieee
+.float16_format alternative
+.float16_format monkeys
+.float16_format ...
+.float16_format
diff --git a/gas/testsuite/gas/arm/float16-format-opt-bad.d b/gas/testsuite/gas/arm/float16-format-opt-bad.d
new file mode 100644 (file)
index 0000000..8611258
--- /dev/null
@@ -0,0 +1,4 @@
+# name: Invalid combination of command line arguments and directives
+# source: float16.s
+# error_output: float16-format-opt-bad.l
+# as: -mfp16-format=ieee
diff --git a/gas/testsuite/gas/arm/float16-format-opt-bad.l b/gas/testsuite/gas/arm/float16-format-opt-bad.l
new file mode 100644 (file)
index 0000000..6743c93
--- /dev/null
@@ -0,0 +1,4 @@
+[^:]*: Assembler messages:
+[^:]*:21: Warning: float16 format cannot be set more than once, ignoring.
+[^:]*:23: Error: cannot create floating-point number
+[^:]*:24: Error: cannot create floating-point number
diff --git a/gas/testsuite/gas/arm/float16-le.d b/gas/testsuite/gas/arm/float16-le.d
new file mode 100644 (file)
index 0000000..c1fe7c2
--- /dev/null
@@ -0,0 +1,11 @@
+# name: Little endian float16 literals (IEEE 754 & Alternative)
+# source: float16.s
+# objdump: -s --section=.data
+# as: -mlittle-endian
+
+.*: +file format .*arm.*
+
+Contents of section \.data:
+ 0000 004adf2f 191cff7b 0100ff03 0004003c.*
+ 0010 013cff7f 007c00fc 00000080 00bce7bb.*
+ 0020 fffb0042 004a3e60 5638ff7f ffff0472.*
diff --git a/gas/testsuite/gas/arm/float16.s b/gas/testsuite/gas/arm/float16.s
new file mode 100644 (file)
index 0000000..3a295c5
--- /dev/null
@@ -0,0 +1,25 @@
+.data
+       .float16 12.0
+       .float16 0.123
+       .float16 0.004
+       .float16 65504
+       .float16 5.9605e-8
+       .float16 6.0976e-5
+       .float16 6.1035e-5
+       .float16 1
+       .float16 1.001
+       .float16 NaN
+       .float16 +Inf
+       .float16 -Inf
+       .float16 +0
+       .float16 -0
+       .float16 -1
+       .float16 -0.98765
+       .float16 -65504
+       .float16 3.0, 12.0, 543.123
+
+.float16_format alternative
+       .float16 0.542
+       .float16 131008.0
+       .float16 -131008.0
+       .float16 12323.1234