qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Alex Bennée" <alex.bennee@linaro.org>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: Richard Henderson <richard.henderson@linaro.org>,
	Laurent Vivier <laurent@vivier.eu>,
	bharata@linux.vnet.ibm.com,
	Andrew Dutcher <andrew@andrewdutcher.com>,
	QEMU Developers <qemu-devel@nongnu.org>,
	Aurelien Jarno <aurelien@aurel32.net>
Subject: Re: [Qemu-devel] [PATCH v2 11/20] fpu/softfloat: re-factor add/sub
Date: Thu, 18 Jan 2018 16:43:54 +0000	[thread overview]
Message-ID: <87r2qnnmlx.fsf@linaro.org> (raw)
In-Reply-To: <CAFEAcA-3nkmeJMHFqMeiwZtQycmieXdPiaCvKZsFuKY3MqtdCQ@mail.gmail.com>


Peter Maydell <peter.maydell@linaro.org> writes:

> On 9 January 2018 at 12:22, Alex Bennée <alex.bennee@linaro.org> wrote:
>> We can now add float16_add/sub and use the common decompose and
>> canonicalize functions to have a single implementation for
>> float16/32/64 add and sub functions.
>>
>> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>  fpu/softfloat.c         | 904 +++++++++++++++++++++++++-----------------------
>>  include/fpu/softfloat.h |   4 +
>>  2 files changed, 481 insertions(+), 427 deletions(-)
>>
>> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
>> index fcba28d3f8..f89e47e3ef 100644
>> --- a/fpu/softfloat.c
>> +++ b/fpu/softfloat.c
>> @@ -195,7 +195,7 @@ typedef enum {
>>      float_class_zero,
>>      float_class_normal,
>>      float_class_inf,
>> -    float_class_qnan,
>> +    float_class_qnan,  /* all NaNs from here */
>
> This comment change should be squashed into the previous patch.
>
>>      float_class_snan,
>>      float_class_dnan,
>>      float_class_msnan, /* maybe silenced */
>> @@ -254,6 +254,482 @@ static const decomposed_params float64_params = {
>>      FRAC_PARAMS(DECOMPOSED_BINARY_POINT - 52)
>>  };
>>
>> +/* Unpack a float16 to parts, but do not canonicalize.  */
>> +static inline decomposed_parts float16_unpack_raw(float16 f)
>> +{
>> +    return (decomposed_parts){
>> +        .cls = float_class_unclassified,
>> +        .sign = extract32(f, 15, 1),
>> +        .exp = extract32(f, 10, 5),
>> +        .frac = extract32(f, 0, 10)
>
> In the previous patch we defined a bunch of structs that
> give information about each float format, so it seems a bit
> odd to be hardcoding bit numbers here.

So something like this:

  /* Structure holding all of the relevant parameters for a format.
   *   exp_bias: the offset applied to the exponent field
   *   exp_max: the maximum normalised exponent
   * The following are computed based the size of fraction
   *   frac_shift: shift to normalise the fraction with DECOMPOSED_BINARY_POINT
   *   frac_lsb: least significant bit of fraction
   *   fram_lsbm1: the bit bellow the least significant bit (for rounding)
   *   round_mask/roundeven_mask: masks used for rounding
   */
  typedef struct {
      int exp_bias;
      int exp_max;
      int exp_size;
      int frac_size;
      int frac_shift;
      uint64_t frac_lsb;
      uint64_t frac_lsbm1;
      uint64_t round_mask;
      uint64_t roundeven_mask;
  } FloatFmt;

  /* Expand fields based on the size of exponent and fraction */
  #define FRAC_PARAMS(E, F)                                            \
      .exp_size       = E,                                             \
      .frac_size      = F,                                             \
      .frac_shift     = DECOMPOSED_BINARY_POINT - F,                   \
      .frac_lsb       = 1ull << (DECOMPOSED_BINARY_POINT - F),         \
      .frac_lsbm1     = 1ull << ((DECOMPOSED_BINARY_POINT - F) - 1),   \
      .round_mask     = (1ull << (DECOMPOSED_BINARY_POINT - F)) - 1,   \
      .roundeven_mask = (2ull << (DECOMPOSED_BINARY_POINT - F)) - 1

  static const FloatFmt float16_params = {
      .exp_bias       = 0x0f,
      .exp_max        = 0x1f,
      FRAC_PARAMS(5, 10)
  };

  static const FloatFmt float32_params = {
      .exp_bias       = 0x7f,
      .exp_max        = 0xff,
      FRAC_PARAMS(8, 23)
  };

  static const FloatFmt float64_params = {
      .exp_bias       = 0x3ff,
      .exp_max        = 0x7ff,
      FRAC_PARAMS(11, 52)
  };

  /* Unpack a float to parts, but do not canonicalize.  */
  static inline FloatParts unpack_raw(FloatFmt fmt, uint64_t raw)
  {
      return (FloatParts){
          .cls = float_class_unclassified,
          .sign = extract64(raw, fmt.frac_size + fmt.exp_size, 1),
          .exp = extract64(raw, fmt.frac_size, fmt.exp_size),
          .frac = extract64(raw, 0, fmt.frac_size),
      };
  }

  static inline FloatParts float16_unpack_raw(float16 f)
  {
      return unpack_raw(float16_params, f);
  }

  static inline FloatParts float32_unpack_raw(float32 f)
  {
      return unpack_raw(float32_params, f);
  }

  static inline FloatParts float64_unpack_raw(float64 f)
  {
      return unpack_raw(float64_params, f);
  }

  /* Pack a float from parts, but do not canonicalize.  */
  static inline uint64_t pack_raw(FloatFmt fmt, FloatParts p)
  {
      uint64_t ret = p.frac;
      ret = deposit64(ret, fmt.frac_size, fmt.exp_size, p.exp);
      ret = deposit32(ret, fmt.frac_size + fmt.exp_size, 1, p.sign);
      return make_float16(ret);
  }

  static inline float16 float16_pack_raw(FloatParts p)
  {
      return make_float16(pack_raw(float16_params, p));
  }

  static inline float32 float32_pack_raw(FloatParts p)
  {
      return make_float32(pack_raw(float32_params, p));
  }

  static inline float64 float64_pack_raw(FloatParts p)
  {
      return make_float64(pack_raw(float64_params, p));
  }


>
>> +    };
>> +}
>> +
>> +/* Unpack a float32 to parts, but do not canonicalize.  */
>> +static inline decomposed_parts float32_unpack_raw(float32 f)
>> +{
>> +    return (decomposed_parts){
>> +        .cls = float_class_unclassified,
>> +        .sign = extract32(f, 31, 1),
>> +        .exp = extract32(f, 23, 8),
>> +        .frac = extract32(f, 0, 23)
>> +    };
>> +}
>> +
>> +/* Unpack a float64 to parts, but do not canonicalize.  */
>> +static inline decomposed_parts float64_unpack_raw(float64 f)
>> +{
>> +    return (decomposed_parts){
>> +        .cls = float_class_unclassified,
>> +        .sign = extract64(f, 63, 1),
>> +        .exp = extract64(f, 52, 11),
>> +        .frac = extract64(f, 0, 52),
>> +    };
>> +}
>> +
>> +/* Pack a float32 from parts, but do not canonicalize.  */
>> +static inline float16 float16_pack_raw(decomposed_parts p)
>> +{
>> +    uint32_t ret = p.frac;
>> +    ret = deposit32(ret, 10, 5, p.exp);
>> +    ret = deposit32(ret, 15, 1, p.sign);
>> +    return make_float16(ret);
>> +}
>> +
>> +/* Pack a float32 from parts, but do not canonicalize.  */
>> +static inline float32 float32_pack_raw(decomposed_parts p)
>> +{
>> +    uint32_t ret = p.frac;
>> +    ret = deposit32(ret, 23, 8, p.exp);
>> +    ret = deposit32(ret, 31, 1, p.sign);
>> +    return make_float32(ret);
>> +}
>> +
>> +/* Pack a float64 from parts, but do not canonicalize.  */
>> +static inline float64 float64_pack_raw(decomposed_parts p)
>> +{
>> +    uint64_t ret = p.frac;
>> +    ret = deposit64(ret, 52, 11, p.exp);
>> +    ret = deposit64(ret, 63, 1, p.sign);
>> +    return make_float64(ret);
>> +}
>> +
>> +/* Canonicalize EXP and FRAC, setting CLS.  */
>> +static decomposed_parts decomposed_canonicalize(decomposed_parts part,
>> +                                        const decomposed_params *parm,
>
> If you pick more compact names for your decomposed_params and
> decomposed_parts structs, you won't have such awkwardness trying
> to format function prototypes. (checkpatch complains that you have
> an overlong line somewhere in this patch for this reason.)
>
> In particular "decomposed_params" I think should change -- it's
> confusingly similar to decomposed_parts, and it isn't really
> a decomposed anything. It's just a collection of useful information
> describing the float format. Try 'fmtinfo', maybe?

I've gone for FloatParts and FloatParams

>
> I see we're passing and returning decomposed_parts structs everywhere
> rather than pointers to them. How well does that compile? (I guess
> everything ends up inlining...)

Yes - if you use the bitfield struct. Without it you end up with quite a
messy preamble.


--
Alex Bennée

  parent reply	other threads:[~2018-01-18 16:44 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-09 12:22 [Qemu-devel] [PATCH v2 00/20] re-factor softfloat and add fp16 functions Alex Bennée
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 01/20] fpu/softfloat: implement float16_squash_input_denormal Alex Bennée
2018-01-12 13:41   ` Peter Maydell
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 02/20] include/fpu/softfloat: remove USE_SOFTFLOAT_STRUCT_TYPES Alex Bennée
2018-01-09 12:27   ` Laurent Vivier
2018-01-09 14:12     ` Aurelien Jarno
2018-01-09 14:14       ` Peter Maydell
2018-01-09 14:20         ` Laurent Vivier
2018-01-09 14:43           ` Peter Maydell
2018-01-09 16:45             ` Richard Henderson
2018-01-09 15:25           ` Alex Bennée
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 03/20] include/fpu/softfloat: implement float16_abs helper Alex Bennée
2018-01-12 13:42   ` Peter Maydell
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 04/20] include/fpu/softfloat: implement float16_chs helper Alex Bennée
2018-01-12 13:43   ` Peter Maydell
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 05/20] include/fpu/softfloat: implement float16_set_sign helper Alex Bennée
2018-01-12 13:43   ` Peter Maydell
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 06/20] include/fpu/softfloat: add some float16 constants Alex Bennée
2018-01-09 13:27   ` Philippe Mathieu-Daudé
2018-01-09 15:16     ` Alex Bennée
2018-01-12 13:47   ` Peter Maydell
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 07/20] fpu/softfloat: propagate signalling NaNs in MINMAX Alex Bennée
2018-01-12 14:04   ` Peter Maydell
2018-01-16 11:31     ` Alex Bennée
2018-01-16 11:53       ` Alex Bennée
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 08/20] fpu/softfloat: improve comments on ARM NaN propagation Alex Bennée
2018-01-12 14:07   ` Peter Maydell
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 09/20] fpu/softfloat: move the extract functions to the top of the file Alex Bennée
2018-01-12 14:07   ` Peter Maydell
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 10/20] fpu/softfloat: define decompose structures Alex Bennée
2018-01-09 17:01   ` Richard Henderson
2018-01-12 14:22   ` Peter Maydell
2018-01-12 16:21   ` Philippe Mathieu-Daudé
2018-01-18 13:08     ` Alex Bennée
2018-01-18 14:26       ` Philippe Mathieu-Daudé
2018-01-18 14:31         ` Peter Maydell
2018-01-18 14:59           ` Philippe Mathieu-Daudé
2018-01-18 15:17             ` Peter Maydell
2018-01-23 12:00               ` Alex Bennée
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 11/20] fpu/softfloat: re-factor add/sub Alex Bennée
2018-01-12 15:57   ` Peter Maydell
2018-01-12 18:30     ` Richard Henderson
2018-01-18 16:43     ` Alex Bennée [this message]
2018-01-18 16:47       ` Richard Henderson
2018-01-23 20:05     ` Alex Bennée
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 12/20] fpu/softfloat: re-factor mul Alex Bennée
2018-01-09 12:43   ` Philippe Mathieu-Daudé
2018-01-12 16:17   ` Peter Maydell
2018-01-16 10:16     ` Alex Bennée
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 13/20] fpu/softfloat: re-factor div Alex Bennée
2018-01-12 16:22   ` Peter Maydell
2018-01-12 18:35     ` Richard Henderson
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 14/20] fpu/softfloat: re-factor muladd Alex Bennée
2018-02-13 15:15   ` Peter Maydell
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 15/20] fpu/softfloat: re-factor round_to_int Alex Bennée
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 16/20] fpu/softfloat: re-factor float to int/uint Alex Bennée
2018-01-09 17:12   ` Richard Henderson
2018-01-12 16:36   ` Peter Maydell
2018-01-16 17:06   ` Alex Bennée
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 17/20] fpu/softfloat: re-factor int/uint to float Alex Bennée
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 18/20] fpu/softfloat: re-factor scalbn Alex Bennée
2018-01-12 16:31   ` Peter Maydell
2018-01-24 12:03     ` Alex Bennée
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 19/20] fpu/softfloat: re-factor minmax Alex Bennée
2018-01-09 17:16   ` Richard Henderson
2018-01-09 12:22 ` [Qemu-devel] [PATCH v2 20/20] fpu/softfloat: re-factor compare Alex Bennée
2018-01-09 17:18   ` Richard Henderson
2018-01-09 13:07 ` [Qemu-devel] [PATCH v2 00/20] re-factor softfloat and add fp16 functions no-reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87r2qnnmlx.fsf@linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=andrew@andrewdutcher.com \
    --cc=aurelien@aurel32.net \
    --cc=bharata@linux.vnet.ibm.com \
    --cc=laurent@vivier.eu \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).