|
@@ -242,3 +242,69 @@ static inline int vfp_single_type(struct vfp_single *s)
|
|
|
type |= VFP_DENORMAL;
|
|
|
}
|
|
|
return type;
|
|
|
+}
|
|
|
+
|
|
|
+#ifndef DEBUG
|
|
|
+#define vfp_single_normaliseround(sd,vsd,fpscr,except,func) __vfp_single_normaliseround(sd,vsd,fpscr,except)
|
|
|
+u32 __vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions);
|
|
|
+#else
|
|
|
+u32 vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exceptions, const char *func);
|
|
|
+#endif
|
|
|
+
|
|
|
+/*
|
|
|
+ * Double-precision
|
|
|
+ */
|
|
|
+struct vfp_double {
|
|
|
+ s16 exponent;
|
|
|
+ u16 sign;
|
|
|
+ u64 significand;
|
|
|
+};
|
|
|
+
|
|
|
+/*
|
|
|
+ * VFP_REG_ZERO is a special register number for vfp_get_double
|
|
|
+ * which returns (double)0.0. This is useful for the compare with
|
|
|
+ * zero instructions.
|
|
|
+ */
|
|
|
+#ifdef CONFIG_VFPv3
|
|
|
+#define VFP_REG_ZERO 32
|
|
|
+#else
|
|
|
+#define VFP_REG_ZERO 16
|
|
|
+#endif
|
|
|
+extern u64 vfp_get_double(unsigned int reg);
|
|
|
+extern void vfp_put_double(u64 val, unsigned int reg);
|
|
|
+
|
|
|
+#define VFP_DOUBLE_MANTISSA_BITS (52)
|
|
|
+#define VFP_DOUBLE_EXPONENT_BITS (11)
|
|
|
+#define VFP_DOUBLE_LOW_BITS (64 - VFP_DOUBLE_MANTISSA_BITS - 2)
|
|
|
+#define VFP_DOUBLE_LOW_BITS_MASK ((1 << VFP_DOUBLE_LOW_BITS) - 1)
|
|
|
+
|
|
|
+/*
|
|
|
+ * The bit in an unpacked double which indicates that it is a quiet NaN
|
|
|
+ */
|
|
|
+#define VFP_DOUBLE_SIGNIFICAND_QNAN (1ULL << (VFP_DOUBLE_MANTISSA_BITS - 1 + VFP_DOUBLE_LOW_BITS))
|
|
|
+
|
|
|
+/*
|
|
|
+ * Operations on packed single-precision numbers
|
|
|
+ */
|
|
|
+#define vfp_double_packed_sign(v) ((v) & (1ULL << 63))
|
|
|
+#define vfp_double_packed_negate(v) ((v) ^ (1ULL << 63))
|
|
|
+#define vfp_double_packed_abs(v) ((v) & ~(1ULL << 63))
|
|
|
+#define vfp_double_packed_exponent(v) (((v) >> VFP_DOUBLE_MANTISSA_BITS) & ((1 << VFP_DOUBLE_EXPONENT_BITS) - 1))
|
|
|
+#define vfp_double_packed_mantissa(v) ((v) & ((1ULL << VFP_DOUBLE_MANTISSA_BITS) - 1))
|
|
|
+
|
|
|
+/*
|
|
|
+ * Unpack a double-precision float. Note that this returns the magnitude
|
|
|
+ * of the double-precision float mantissa with the 1. if necessary,
|
|
|
+ * aligned to bit 62.
|
|
|
+ */
|
|
|
+static inline void vfp_double_unpack(struct vfp_double *s, s64 val)
|
|
|
+{
|
|
|
+ u64 significand;
|
|
|
+
|
|
|
+ s->sign = vfp_double_packed_sign(val) >> 48;
|
|
|
+ s->exponent = vfp_double_packed_exponent(val);
|
|
|
+
|
|
|
+ significand = (u64) val;
|
|
|
+ significand = (significand << (64 - VFP_DOUBLE_MANTISSA_BITS)) >> 2;
|
|
|
+ if (s->exponent && s->exponent != 2047)
|
|
|
+ significand |= (1ULL << 62);
|