|
@@ -139,3 +139,106 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m)
|
|
|
z |= remh;
|
|
|
}
|
|
|
return z;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Operations on unpacked elements
|
|
|
+ */
|
|
|
+#define vfp_sign_negate(sign) (sign ^ 0x8000)
|
|
|
+
|
|
|
+/*
|
|
|
+ * Single-precision
|
|
|
+ */
|
|
|
+struct vfp_single {
|
|
|
+ s16 exponent;
|
|
|
+ u16 sign;
|
|
|
+ u32 significand;
|
|
|
+};
|
|
|
+
|
|
|
+extern s32 vfp_get_float(unsigned int reg);
|
|
|
+extern void vfp_put_float(s32 val, unsigned int reg);
|
|
|
+
|
|
|
+/*
|
|
|
+ * VFP_SINGLE_MANTISSA_BITS - number of bits in the mantissa
|
|
|
+ * VFP_SINGLE_EXPONENT_BITS - number of bits in the exponent
|
|
|
+ * VFP_SINGLE_LOW_BITS - number of low bits in the unpacked significand
|
|
|
+ * which are not propagated to the float upon packing.
|
|
|
+ */
|
|
|
+#define VFP_SINGLE_MANTISSA_BITS (23)
|
|
|
+#define VFP_SINGLE_EXPONENT_BITS (8)
|
|
|
+#define VFP_SINGLE_LOW_BITS (32 - VFP_SINGLE_MANTISSA_BITS - 2)
|
|
|
+#define VFP_SINGLE_LOW_BITS_MASK ((1 << VFP_SINGLE_LOW_BITS) - 1)
|
|
|
+
|
|
|
+/*
|
|
|
+ * The bit in an unpacked float which indicates that it is a quiet NaN
|
|
|
+ */
|
|
|
+#define VFP_SINGLE_SIGNIFICAND_QNAN (1 << (VFP_SINGLE_MANTISSA_BITS - 1 + VFP_SINGLE_LOW_BITS))
|
|
|
+
|
|
|
+/*
|
|
|
+ * Operations on packed single-precision numbers
|
|
|
+ */
|
|
|
+#define vfp_single_packed_sign(v) ((v) & 0x80000000)
|
|
|
+#define vfp_single_packed_negate(v) ((v) ^ 0x80000000)
|
|
|
+#define vfp_single_packed_abs(v) ((v) & ~0x80000000)
|
|
|
+#define vfp_single_packed_exponent(v) (((v) >> VFP_SINGLE_MANTISSA_BITS) & ((1 << VFP_SINGLE_EXPONENT_BITS) - 1))
|
|
|
+#define vfp_single_packed_mantissa(v) ((v) & ((1 << VFP_SINGLE_MANTISSA_BITS) - 1))
|
|
|
+
|
|
|
+/*
|
|
|
+ * Unpack a single-precision float. Note that this returns the magnitude
|
|
|
+ * of the single-precision float mantissa with the 1. if necessary,
|
|
|
+ * aligned to bit 30.
|
|
|
+ */
|
|
|
+static inline void vfp_single_unpack(struct vfp_single *s, s32 val)
|
|
|
+{
|
|
|
+ u32 significand;
|
|
|
+
|
|
|
+ s->sign = vfp_single_packed_sign(val) >> 16,
|
|
|
+ s->exponent = vfp_single_packed_exponent(val);
|
|
|
+
|
|
|
+ significand = (u32) val;
|
|
|
+ significand = (significand << (32 - VFP_SINGLE_MANTISSA_BITS)) >> 2;
|
|
|
+ if (s->exponent && s->exponent != 255)
|
|
|
+ significand |= 0x40000000;
|
|
|
+ s->significand = significand;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Re-pack a single-precision float. This assumes that the float is
|
|
|
+ * already normalised such that the MSB is bit 30, _not_ bit 31.
|
|
|
+ */
|
|
|
+static inline s32 vfp_single_pack(struct vfp_single *s)
|
|
|
+{
|
|
|
+ u32 val;
|
|
|
+ val = (s->sign << 16) +
|
|
|
+ (s->exponent << VFP_SINGLE_MANTISSA_BITS) +
|
|
|
+ (s->significand >> VFP_SINGLE_LOW_BITS);
|
|
|
+ return (s32)val;
|
|
|
+}
|
|
|
+
|
|
|
+#define VFP_NUMBER (1<<0)
|
|
|
+#define VFP_ZERO (1<<1)
|
|
|
+#define VFP_DENORMAL (1<<2)
|
|
|
+#define VFP_INFINITY (1<<3)
|
|
|
+#define VFP_NAN (1<<4)
|
|
|
+#define VFP_NAN_SIGNAL (1<<5)
|
|
|
+
|
|
|
+#define VFP_QNAN (VFP_NAN)
|
|
|
+#define VFP_SNAN (VFP_NAN|VFP_NAN_SIGNAL)
|
|
|
+
|
|
|
+static inline int vfp_single_type(struct vfp_single *s)
|
|
|
+{
|
|
|
+ int type = VFP_NUMBER;
|
|
|
+ if (s->exponent == 255) {
|
|
|
+ if (s->significand == 0)
|
|
|
+ type = VFP_INFINITY;
|
|
|
+ else if (s->significand & VFP_SINGLE_SIGNIFICAND_QNAN)
|
|
|
+ type = VFP_QNAN;
|
|
|
+ else
|
|
|
+ type = VFP_SNAN;
|
|
|
+ } else if (s->exponent == 0) {
|
|
|
+ if (s->significand == 0)
|
|
|
+ type |= VFP_ZERO;
|
|
|
+ else
|
|
|
+ type |= VFP_DENORMAL;
|
|
|
+ }
|
|
|
+ return type;
|