arch/sh/kernel/cpu/sh2a/fpu.c

Source file repositories/reference/linux-study-clean/arch/sh/kernel/cpu/sh2a/fpu.c

File Facts

System
Linux kernel
Corpus path
arch/sh/kernel/cpu/sh2a/fpu.c
Extension
.c
Size
13760 bytes
Lines
573
Domain
Architecture Layer
Bucket
arch/sh
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

while (nh) { nh >>= 1; w++;}
		w += 64;
	} else
		while (nl) { nl >>= 1; w++;}

	/* FIXME: use guard bits */
	exp += w - 1022 - 52 * 2;
	if (exp > 0)
		ix = (rshift64(mh, ml, w - 52) & 0x000fffffffffffffLL)
			| ((long long)exp << 52);
	else if (exp + 51 >= 0)
		ix = rshift64(mh, ml, w - 51 - exp) & 0x000fffffffffffffLL;
	else
		ix = 0;

	ix |= (hx ^ hy) & 0x8000000000000000LL;
	return ix;
}

/* ix - iy where iy: denormal and ix, iy >= 0 */
static int denormal_subf1(unsigned int ix, unsigned int iy)
{
	int frac;
	int exp;

	if (ix < 0x00800000)
		return ix - iy;

	exp = (ix & 0x7f800000) >> 23;
	if (exp - 1 > 31)
		return ix;
	iy >>= exp - 1;
	if (iy == 0)
		return ix;

	frac = (ix & 0x007fffff) | 0x00800000;
	frac -= iy;
	while (frac < 0x00800000) {
		if (--exp == 0)
			return frac;
		frac <<= 1;
	}

	return (exp << 23) | (frac & 0x007fffff);
}

/* ix + iy where iy: denormal and ix, iy >= 0 */
static int denormal_addf1(unsigned int ix, unsigned int iy)
{
	int frac;
	int exp;

	if (ix < 0x00800000)
		return ix + iy;

	exp = (ix & 0x7f800000) >> 23;
	if (exp - 1 > 31)
		return ix;
	iy >>= exp - 1;
	if (iy == 0)
	  return ix;

	frac = (ix & 0x007fffff) | 0x00800000;
	frac += iy;
	if (frac >= 0x01000000) {
		frac >>= 1;
		++exp;
	}

	return (exp << 23) | (frac & 0x007fffff);
}

static int denormal_addf(int hx, int hy)
{
	unsigned int ix, iy;
	int sign;

	if ((hx ^ hy) & 0x80000000) {
		sign = hx & 0x80000000;
		ix = hx & 0x7fffffff;
		iy = hy & 0x7fffffff;
		if (iy < 0x00800000) {
			ix = denormal_subf1(ix, iy);
			if ((int) ix < 0) {
				ix = -ix;
				sign ^= 0x80000000;
			}
		} else {
			ix = denormal_subf1(iy, ix);
			sign ^= 0x80000000;

Annotation

Implementation Notes