arch/arm/vfp/vfp.h

Source file repositories/reference/linux-study-clean/arch/arm/vfp/vfp.h

File Facts

System
Linux kernel
Corpus path
arch/arm/vfp/vfp.h
Extension
.h
Size
9576 bytes
Lines
379
Domain
Architecture Layer
Bucket
arch/arm
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct vfp_single {
	s16	exponent;
	u16	sign;
	u32	significand;
};

asmlinkage s32 vfp_get_float(unsigned int reg);
asmlinkage 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

Annotation

Implementation Notes