mesa/src/asahi/compiler/agx_minifloat.h

66 lines
1.6 KiB
C
Raw Normal View History

/*
asahi: Convert to SPDX headers Also drop my email address in the copyright lines and fix some "Copyright 208 Alyssa Rosenzweig" lines, I'm not *that* old. Together this drops a lot of boilerplate without losing any meaningful licensing information. SPDX is already in use for the MIT-licensed code in turnip, venus, and a few other scattered parts of the tree, so this should be ok from a Mesa licensing standpoint. This reduces friction to create new files, by parsing the copy/paste boilerplate and being short enough you can easily type it out if you want. It makes new files seem less daunting: 20 lines of header for 30 lines of code is discouraging, but 2 lines of header for 30 lines of code is reasonable for a simple compiler pass. This has technical effects, as lowering the barrier to making new files should encourage people to split code into more modular files with (hopefully positive) effects on project compile time. This helps with consistency between files. Across the tree we have at least a half dozen variants of the MIT license text (probably more), plus code that uses SPDX headers instead. I've already been using SPDX headers in Asahi manually, so you can tell old vs new code based on the headers. Finally, it means less for reviewers to scroll through adding files. Minimal actual cognitive burden for reviewers thanks to banner blindness, but the big headers still bloat diffs that add/delete files. I originally proposed this in December (for much more of the tree) but someone requested I wait until January to discuss. I've been trying to get in touch with them since then. It is now almost April and, with still no response, I'd like to press forward with this. So with a joint sign-off from the major authors of the code in question, let's do this. Signed-off-by: Asahi Lina <lina@asahilina.net> Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Acked-by: Emma Anholt <emma@anholt.net> Acked-by: Daniel Stone <daniels@collabora.com> Reviewed-by: Eric Engestrom <eric@igalia.com> Acked-by: Kenneth Graunke <kenneth@whitecape.org> Acked-by: Rose Hudson <rose@krx.sh> Acked-by: Lyude Paul [over IRC: "yes I'm fine with that"] Meh'd-by: Rob Clark <robdclark@chromium.org> Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22062>
2023-03-15 21:36:17 +00:00
* Copyright 2021 Alyssa Rosenzweig
* SPDX-License-Identifier: MIT
*/
#ifndef __AGX_MINIFLOAT_H_
#define __AGX_MINIFLOAT_H_
#include <math.h>
#include "util/macros.h"
/* AGX includes an 8-bit floating-point format for small dyadic immediates,
* consisting of 3 bits for the exponent, 4 bits for the mantissa, and 1-bit
* for sign, in the usual order. Zero exponent has special handling. */
static inline float
agx_minifloat_decode(uint8_t imm)
{
float sign = (imm & 0x80) ? -1.0 : 1.0;
signed exp = (imm & 0x70) >> 4;
unsigned mantissa = (imm & 0xF);
if (exp)
return ldexpf(sign * (float)(mantissa | 0x10), exp - 7);
else
return ldexpf(sign * ((float)mantissa), -6);
}
/* Encodes a float. Results are only valid if the float can be represented
* exactly, if not the result of this function is UNDEFINED. However, it is
* guaranteed that this function will not crash on out-of-spec inputs, so it is
* safe to call on any input. signbit() is used to ensure -0.0 is handled
* correctly.
*/
static inline uint8_t
agx_minifloat_encode(float f)
{
unsigned sign = signbit(f) ? 0x80 : 0;
f = fabsf(f);
/* frac is in [0.5, 1) and f = frac * 2^exp */
int exp = 0;
float frac = frexpf(f, &exp);
if (f >= 0.25) {
unsigned mantissa = (frac * 32.0);
exp -= 5; /* 2^5 = 32 */
exp = CLAMP(exp + 7, 0, 7);
return sign | (exp << 4) | (mantissa & 0xF);
} else {
unsigned mantissa = (f * 64.0f);
return sign | mantissa;
}
}
static inline bool
agx_minifloat_exact(float f)
{
float f_ = agx_minifloat_decode(agx_minifloat_encode(f));
return memcmp(&f, &f_, sizeof(float)) == 0;
}
#endif